




















var Cookies = {

setCookie: function(name, value, lifespan, access_path) {

var cookietext = name + "=" + escape(value)
if (lifespan != null) {
var today=new Date()
var expiredate = new Date()
expiredate.setTime(today.getTime() + 1000*60*60*24*lifespan)
cookietext += "; expires=" + expiredate.toGMTString()
}
if (access_path != null) {
cookietext += "; PATH="+access_path
}
document.cookie = cookietext
return null
},


setDatedCookie: function(name, value, expire, access_path) {
var cookietext = name + "=" + escape(value)
+ ((expire == null) ? "" : ("; expires=" + expire.toGMTString()))
if (access_path != null) {
cookietext += "; PATH="+access_path
}
document.cookie = cookietext
return null
},


getCookie: function(Name) {
var search = Name + "="
var CookieString = document.cookie
var result = null
if (CookieString.length > 0) {
offset = CookieString.indexOf(search)
if (offset != -1) {
offset += search.length
end = CookieString.indexOf(";", offset)
if (end == -1)
end = CookieString.length
result = unescape(CookieString.substring(offset, end))

}
}
return result
},


deleteCookie: function(name) {
Cookies.setCookie(name, "Deleted", -1)
}

}

var pc = navigator.userAgent.toLowerCase();
var ie4_win = (pc.indexOf("win")!=-1) && (pc.indexOf("msie") != -1)
&& (parseInt(navigator.appVersion) >= 4);
var checked = false;


var is_gecko = pc.indexOf("gecko/") != -1 &&
parseFloat(pc.substring(pc.indexOf("gecko/") + 6, pc.indexOf("gecko/") + 14)) > 20030108;

function checkPost() {
if (arguments.length > 0) { window.onbeforeunload = null; }

if (!checked) {
checked = true;
return true;
}
return false;
}

function insertAtCursor(text, ta) {
var end = 0;
var scrollTop = ta.scrollTop;

ta.focus();

if (document.selection && document.selection.createRange().parentElement().tagName == 'TEXTAREA') {
var selected = document.selection.createRange().text;


end = getSelectionRangeEnd(ta);


document.selection.createRange().text = selected + text;

end += text.length;
}
else if (typeof(ta.selectionStart) != 'undefined' && typeof(ta.selectionEnd) != 'undefined') {
var selLength = ta.textLength;
var selStart = ta.selectionStart;
var selEnd = ta.selectionEnd;
if (selEnd == 1 || selEnd == 2) {
selEnd = selLength;
}
var s1 = (ta.value).substring(0, selEnd);
var s2 = (ta.value).substring(selEnd, selLength);


ta.value = s1 + text + s2;

end = selEnd + text.length;
}
else {
ta.value += text;
}

if (end > 0) {
setCaretTo(ta, end, scrollTop);
}
}

function styleTag(tag, ta) {
var end = 0;
var scrollTop = ta.scrollTop;

if (document.selection) {
if (document.selection.createRange().parentElement().tagName == 'TEXTAREA') {
var selected = document.selection.createRange().text;


end = getSelectionRangeEnd(ta);


var r = _markupText(selected, tag);

document.selection.createRange().text = r[0];

end += r[1];
}
}
else if (typeof(ta.selectionStart) != 'undefined' && typeof(ta.selectionEnd) != 'undefined') {
if (ta.selectionStart == ta.selectionEnd) {
return;
}
var selLength = ta.textLength;
var selStart = ta.selectionStart;
var selEnd = ta.selectionEnd;
if (selEnd == 1 || selEnd == 2) {
selEnd = selLength;
}
var s1 = (ta.value).substring(0, selStart);
var s2 = (ta.value).substring(selStart, selEnd);
var s3 = (ta.value).substring(selEnd, selLength);


var r = _markupText(s2, tag);

ta.value = s1 + r[0] + s3;

end = selEnd + r[1];
}
else {
return;
}

if (end > 0) {
setCaretTo(ta, end, scrollTop);
}
}

function _markupText(text, tag) {

var r = trimLeadingSpace(text);
text = r[0];
var removeSpace = r[1];


r = trimTrailingSpace(text);
text = r[0];
var addSpace = r[1];


var addedCharacters = 0;

if (text.indexOf('\n') > 0) {

var lines = text.split('\n');
var newText = '';
for (var i = 0; i < lines.length; i++) {
var line = lines[i];

r = trimLeadingSpace(line);
line = r[0];
var leadingSpaces = r[1];


r = trimTrailingSpace(line);
line = r[0];
var trailingSpaces = r[1];

if (line == '') {
newText += leadingSpaces + line + trailingSpaces;
}
else {
newText += leadingSpaces + tag + line + tag + trailingSpaces;
addedCharacters += (tag.length * 2);
}

if (i < lines.length -1) {
newText += '\n';
}
}
text = removeSpace + newText + addSpace;
}
else {
text = removeSpace + tag + text + tag + addSpace;
}

r = new Array(2);
r[0] = text;
r[1] = addedCharacters;

return r;
}

function trimLeadingSpace(text) {
var removeSpace = "";
while (text.length > 0 &&
(text.charAt(0) == ' ' ||
text.charAt(0) == '\n' ||
text.charAt(0) == '\r'))
{
removeSpace += text.charAt(0);
text = text.substring(1);
}

var r = new Array(2);
r[0] = text;
r[1] = removeSpace;
return r;
}

function trimTrailingSpace(text) {
var addSpace = "";
while (text.length > 0 &&
(text.charAt(text.length-1) == ' ' ||
text.charAt(text.length-1) == '\n' ||
text.charAt(text.length-1) == '\r'))
{
addSpace += text.charAt(text.length-1);
text = text.substring(0, text.length-1);
}

var r = new Array(2);
r[0] = text;
r[1] = addSpace;
return r;
}

function getSelectionRangeText(ta) {
if (document.selection) {

return document.selection.createRange().text;
}
else if (is_gecko) {
var start = ta.selectionStart;
var end   = ta.selectionEnd;
return ta.value.substr(start, end-start);
}
else {
return '';
}
}

function getSelectionRangeEnd(ta) {
if (document.selection) {

var range = document.selection.createRange();

var stored_range = range.duplicate();

stored_range.moveToElementText(ta);

stored_range.setEndPoint('EndToEnd', range);


var start = stored_range.text.length - range.text.length;
return start + range.text.length;
}
else if (is_gecko) {
return ta.selectionEnd;
}
else {
return 0;
}
}
function setCaretTo(ta, pos, scrollTop) {
ta.focus();
if (ta.createTextRange) {


var i = 0;
var count = 0;
var text = ta.value;
while (i > -1 && i < pos) {
i = text.indexOf("\r\n", i);
if (i >= 0) {
count++;
i += 2;
}
}

if (count > 1) {
count--;
}


var range = ta.createTextRange();
range.move("character", (pos - count));
range.select();
}
else if (ta.selectionStart) {
ta.setSelectionRange(pos, pos);
}


if (scrollTop > 0) {
ta.scrollTop = scrollTop;
}
}

function caret(ta) {
if (ie4_win && ta.createTextRange &&
document.selection.createRange().parentElement().tagName == 'TEXTAREA')
{
ta.caretPos = document.selection.createRange().duplicate();
}
}




function funcname(f) {
var s = f.toString().match(/function (\w*)/)[1];
if ((s == null) || (s.length == 0)) return "anonymous";
return s;
}


function stacktrace() {
var s = "";  // This is the string we'll return.



for(var a = arguments.caller; a != null; a = a.caller) {

s += funcname(a.callee) + "\n";




if (a.caller == a) break;
}
return s;
}

function printStackTrace() {
alert('stack trace is ' + stacktrace());
}




var hoverElements = new Array();

function onhover(el) {
if (typeof(el) == "undefined" || typeof(el.className) != "undefined") {
return;
}
hoverElements[el] = el.className;
el.className = el.className + " hilite";
}

function onhoverbyclass(el, cl) {
hoverElements[el] = el.className;
el.className = el.className + " " + cl;
}

function offhover(el) {
if (hoverElements[el]) {
el.className = hoverElements[el];
}
}

function onclick(el) {
onhover(el);
}


function clearhover(el) {
el.className = el.className.replace(/hilite/g, "")
}








var Prototype = {
Version: '1.5.1',

Browser: {
IE:     !!(window.attachEvent && !window.opera),
Opera:  !!window.opera,
WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
Gecko:  navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1
},

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

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

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

var Class = {
create: function() {
return function() {
this.initialize.apply(this, arguments);
}
}
}

var Abstract = new Object();

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 === undefined) return 'undefined';
if (object === null) return 'null';
return object.inspect ? object.inspect() : object.toString();
} 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.ownerDocument === document) return;
var results = [];
for (var property in object) {
var value = Object.toJSON(object[property]);
if (value !== undefined)
results.push(property.toJSON() + ': ' + value);
}
return '{' + results.join(', ') + '}';
},

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);
}
});

Function.prototype.bind = function() {
var __method = this, args = $A(arguments), object = args.shift();
return function() {
return __method.apply(object, args.concat($A(arguments)));
}
}

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

Object.extend(Number.prototype, {
toColorPart: function() {
return this.toPaddedString(2, 16);
},

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

times: function(iterator) {
$R(0, this, true).each(iterator);
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';
}
});

Date.prototype.toJSON = function() {
return '"' + this.getFullYear() + '-' +
(this.getMonth() + 1).toPaddedString(2) + '-' +
this.getDate().toPaddedString(2) + 'T' +
this.getHours().toPaddedString(2) + ':' +
this.getMinutes().toPaddedString(2) + ':' +
this.getSeconds().toPaddedString(2) + '"';
};

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;
}
}



var PeriodicalExecuter = Class.create();
PeriodicalExecuter.prototype = {
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);
},

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

onTimerEvent: function() {
if (!this.currentlyExecuting) {
try {
this.currentlyExecuting = true;
this.callback(this);
} 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 = count === undefined ? 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 this;
},

truncate: function(length, truncation) {
length = length || 30;
truncation = truncation === undefined ? '...' : truncation;
return this.length > length ?
this.slice(0, length - truncation.length) + truncation : 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 = document.createElement('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 (hash[key].constructor != Array) 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) {
var result = '';
for (var i = 0; i < count; i++) result += this;
return result;
},

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}');
},

evalJSON: function(sanitize) {
var json = this.unfilterJSON();
try {
if (!sanitize || (/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/.test(json)))
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);
}
});

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.replace(/&amp;/g,'&').replace(/&lt;/g,'<').replace(/&gt;/g,'>');
}
});

String.prototype.gsub.prepareReplacement = function(replacement) {
if (typeof replacement == 'function') 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('')
});

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

var Template = Class.create();
Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
Template.prototype = {
initialize: function(template, pattern) {
this.template = template.toString();
this.pattern  = pattern || Template.Pattern;
},

evaluate: function(object) {
return this.template.gsub(this.pattern, function(match) {
var before = match[1];
if (before == '\\') return match[2];
return before + String.interpret(object[match[3]]);
});
}
}

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

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

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

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

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

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

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

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

grep: function(pattern, iterator) {
var results = [];
this.each(function(value, index) {
var stringValue = value.toString();
if (stringValue.match(pattern))
results.push((iterator || Prototype.K)(value, index));
})
return results;
},

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

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

inject: function(memo, iterator) {
this.each(function(value, index) {
memo = iterator(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) {
var result;
this.each(function(value, index) {
value = (iterator || Prototype.K)(value, index);
if (result == undefined || value >= result)
result = value;
});
return result;
},

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

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

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

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

sortBy: function(iterator) {
return this.map(function(value, index) {
return {value: value, criteria: iterator(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 (typeof args.last() == 'function')
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,
member:  Enumerable.include,
entries: Enumerable.toArray
});
var $A = Array.from = function(iterable) {
if (!iterable) return [];
if (iterable.toArray) {
return iterable.toArray();
} else {
var results = [];
for (var i = 0, length = iterable.length; i < length; i++)
results.push(iterable[i]);
return results;
}
}

if (Prototype.Browser.WebKit) {
$A = Array.from = function(iterable) {
if (!iterable) return [];
if (!(typeof iterable == 'function' && iterable == '[object NodeList]') &&
iterable.toArray) {
return iterable.toArray();
} else {
var results = [];
for (var i = 0, length = iterable.length; i < length; i++)
results.push(iterable[i]);
return results;
}
}
}

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(value && value.constructor == Array ?
value.flatten() : [value]);
});
},

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

indexOf: function(object) {
for (var i = 0, length = this.length; i < length; i++)
if (this[i] == object) return i;
return -1;
},

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;
});
},

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 (value !== undefined) results.push(value);
});
return '[' + results.join(', ') + ']';
}
});

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

function $w(string) {
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 (arguments[i].constructor == Array) {
for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++)
array.push(arguments[i][j]);
} else {
array.push(arguments[i]);
}
}
return array;
}
}
var Hash = function(object) {
if (object instanceof Hash) this.merge(object);
else Object.extend(this, object || {});
};

Object.extend(Hash, {
toQueryString: function(obj) {
var parts = [];
parts.add = arguments.callee.addPair;

this.prototype._each.call(obj, function(pair) {
if (!pair.key) return;
var value = pair.value;

if (value && typeof value == 'object') {
if (value.constructor == Array) value.each(function(value) {
parts.add(pair.key, value);
});
return;
}
parts.add(pair.key, value);
});

return parts.join('&');
},

toJSON: function(object) {
var results = [];
this.prototype._each.call(object, function(pair) {
var value = Object.toJSON(pair.value);
if (value !== undefined) results.push(pair.key.toJSON() + ': ' + value);
});
return '{' + results.join(', ') + '}';
}
});

Hash.toQueryString.addPair = function(key, value, prefix) {
key = encodeURIComponent(key);
if (value === undefined) this.push(key);
else this.push(key + '=' + (value == null ? '' : encodeURIComponent(value)));
}

Object.extend(Hash.prototype, Enumerable);
Object.extend(Hash.prototype, {
_each: function(iterator) {
for (var key in this) {
var value = this[key];
if (value && value == Hash.prototype[key]) continue;

var pair = [key, value];
pair.key = key;
pair.value = value;
iterator(pair);
}
},

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

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

merge: function(hash) {
return $H(hash).inject(this, function(mergedHash, pair) {
mergedHash[pair.key] = pair.value;
return mergedHash;
});
},

remove: function() {
var result;
for(var i = 0, length = arguments.length; i < length; i++) {
var value = this[arguments[i]];
if (value !== undefined){
if (result === undefined) result = value;
else {
if (result.constructor != Array) result = [result];
result.push(value)
}
}
delete this[arguments[i]];
}
return result;
},

toQueryString: function() {
return Hash.toQueryString(this);
},

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

toJSON: function() {
return Hash.toJSON(this);
}
});

function $H(object) {
if (object instanceof Hash) return object;
return new Hash(object);
};


if (function() {
var i = 0, Test = function(value) { this.key = value };
Test.prototype.key = 'foo';
for (var property in new Test('bar')) i++;
return i > 1;
}()) Hash.prototype._each = function(iterator) {
var cache = [];
for (var key in this) {
var value = this[key];
if ((value && value == Hash.prototype[key]) || cache.include(key)) continue;
cache.push(key);
var pair = [key, value];
pair.key = key;
pair.value = value;
iterator(pair);
}
};
ObjectRange = Class.create();
Object.extend(ObjectRange.prototype, Enumerable);
Object.extend(ObjectRange.prototype, {
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 (typeof responder[callback] == 'function') {
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 = function() {};
Ajax.Base.prototype = {
setOptions: function(options) {
this.options = {
method:       'post',
asynchronous: true,
contentType:  'application/x-www-form-urlencoded',
encoding:     'UTF-8',
parameters:   ''
}
Object.extend(this.options, options || {});

this.options.method = this.options.method.toLowerCase();
if (typeof this.options.parameters == 'string')
this.options.parameters = this.options.parameters.toQueryParams();
}
}

Ajax.Request = Class.create();
Ajax.Request.Events =
['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];

Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
_complete: false,

initialize: function(url, options) {
this.transport = Ajax.getTransport();
this.setOptions(options);
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)) {

params['_method'] = this.method;
this.method = 'post';
}

this.parameters = params;

if (params = Hash.toQueryString(params)) {

if (this.method == 'get')
this.url += (this.url.include('?') ? '&' : '?') + params;
else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent))
params += '&_=';
}

try {
if (this.options.onCreate) this.options.onCreate(this.transport);
Ajax.Responders.dispatch('onCreate', this, this.transport);

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

if (this.options.asynchronous)
setTimeout(function() { this.respondToReadyState(1) }.bind(this), 10);

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

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


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 : '');





if (this.transport.overrideMimeType &&
(navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
headers['Connection'] = 'close';
}


if (typeof this.options.requestHeaders == 'object') {
var extras = this.options.requestHeaders;

if (typeof extras.push == 'function')
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() {
return !this.transport.status
|| (this.transport.status >= 200 && this.transport.status < 300);
},

respondToReadyState: function(readyState) {
var state = Ajax.Request.Events[readyState];
var transport = this.transport, json = this.evalJSON();

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

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

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

if (state == 'Complete') {

this.transport.onreadystatechange = Prototype.emptyFunction;
}
},

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

evalJSON: function() {
try {
var json = this.getHeader('X-JSON');
return json ? json.evalJSON() : 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.Updater = Class.create();

Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
initialize: function(container, url, options) {
this.container = {
success: (container.success || container),
failure: (container.failure || (container.success ? null : container))
}

this.transport = Ajax.getTransport();
this.setOptions(options);

var onComplete = this.options.onComplete || Prototype.emptyFunction;
this.options.onComplete = (function(transport, param) {
this.updateContent();
onComplete(transport, param);
}).bind(this);

this.request(url);
},

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

if (!this.options.evalScripts) response = response.stripScripts();

if (receiver = $(receiver)) {
if (this.options.insertion)
new this.options.insertion(receiver, response);
else
receiver.update(response);
}

if (this.success()) {
if (this.onComplete)
setTimeout(this.onComplete.bind(this), 10);
}
}
});

Ajax.PeriodicalUpdater = Class.create();
Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), {
initialize: function(container, url, options) {
this.setOptions(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(request) {
if (this.options.decay) {
this.decay = (request.responseText == this.lastText ?
this.decay * this.options.decay : 1);

this.lastText = request.responseText;
}
this.timer = setTimeout(this.onTimerEvent.bind(this),
this.decay * this.frequency * 1000);
},

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 (typeof element == 'string')
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(query.snapshotItem(i));
return results;
};

document.getElementsByClassName = function(className, parentElement) {
var q = ".//*[contains(concat(' ', @class, ' '), ' " + className + " ')]";
return document._getElementsByXPath(q, parentElement);
}

} else document.getElementsByClassName = function(className, parentElement) {
var children = ($(parentElement) || document.body).getElementsByTagName('*');
var elements = [], child;
for (var i = 0, length = children.length; i < length; i++) {
child = children[i];
if (Element.hasClassName(child, className))
elements.push(Element.extend(child));
}
return elements;
};



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

Element.extend = function(element) {
var F = Prototype.BrowserFeatures;
if (!element || !element.tagName || element.nodeType == 3 ||
element._extended || F.SpecificElementExtensions || element == window)
return element;

var methods = {}, tagName = element.tagName, cache = Element.extend.cache,
T = Element.Methods.ByTag;


if (!F.ElementExtensions) {
Object.extend(methods, Element.Methods),
Object.extend(methods, Element.Methods.Simulated);
}


if (T[tagName]) Object.extend(methods, T[tagName]);

for (var property in methods) {
var value = methods[property];
if (typeof value == 'function' && !(property in element))
element[property] = cache.findOrStore(value);
}

element._extended = Prototype.emptyFunction;
return element;
};

Element.extend.cache = {
findOrStore: function(value) {
return this[value] = this[value] || function() {
return value.apply(null, [this].concat($A(arguments)));
}
}
};

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).style.display = 'none';
return element;
},

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

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

update: function(element, html) {
html = typeof html == 'undefined' ? '' : html.toString();
$(element).innerHTML = html.stripScripts();
setTimeout(function() {html.evalScripts()}, 10);
return element;
},

replace: function(element, html) {
element = $(element);
html = typeof html == 'undefined' ? '' : html.toString();
if (element.outerHTML) {
element.outerHTML = html.stripScripts();
} else {
var range = element.ownerDocument.createRange();
range.selectNodeContents(element);
element.parentNode.replaceChild(
range.createContextualFragment(html.stripScripts()), element);
}
setTimeout(function() {html.evalScripts()}, 10);
return element;
},

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 $A($(element).getElementsByTagName('*')).each(Element.extend);
},

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 (typeof selector == 'string')
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 expression ? Selector.findElement(ancestors, expression, index) :
ancestors[index || 0];
},

down: function(element, expression, index) {
element = $(element);
if (arguments.length == 1) return element.firstDescendant();
var descendants = element.descendants();
return expression ? Selector.findElement(descendants, expression, index) :
descendants[index || 0];
},

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

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

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

getElementsByClassName: function(element, className) {
return document.getElementsByClassName(className, element);
},

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

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;
if (elementClassName.length == 0) return false;
if (elementClassName == className ||
elementClassName.match(new RegExp("(^|\\s)" + className + "(\\s|$)")))
return true;
return false;
},

addClassName: function(element, className) {
if (!(element = $(element))) return;
Element.classNames(element).add(className);
return element;
},

removeClassName: function(element, className) {
if (!(element = $(element))) return;
Element.classNames(element).remove(className);
return element;
},

toggleClassName: function(element, className) {
if (!(element = $(element))) return;
Element.classNames(element)[element.hasClassName(className) ? 'remove' : 'add'](className);
return element;
},

observe: function() {
Event.observe.apply(Event, arguments);
return $A(arguments).first();
},

stopObserving: function() {
Event.stopObserving.apply(Event, arguments);
return $A(arguments).first();
},


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);
while (element = element.parentNode)
if (element == ancestor) return true;
return false;
},

scrollTo: function(element) {
element = $(element);
var pos = Position.cumulativeOffset(element);
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) {
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, camelized) {
element = $(element);
var elementStyle = element.style;

for (var property in styles)
if (property == 'opacity') element.setOpacity(styles[property])
else
elementStyle[(property == 'float' || property == 'cssFloat') ?
(elementStyle.styleFloat === undefined ? 'cssFloat' : 'styleFloat') :
(camelized ? property : property.camelize())] = 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};



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';


if (window.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.style.overflow || 'auto';
if ((Element.getStyle(element, 'overflow') || 'visible') != '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;
}
};

Object.extend(Element.Methods, {
childOf: Element.Methods.descendantOf,
childElements: Element.Methods.immediateDescendants
});

if (Prototype.Browser.Opera) {
Element.Methods._getStyle = Element.Methods.getStyle;
Element.Methods.getStyle = function(element, style) {
switch(style) {
case 'left':
case 'top':
case 'right':
case 'bottom':
if (Element._getStyle(element, 'position') == 'static') return null;
default: return Element._getStyle(element, style);
}
};
}
else if (Prototype.Browser.IE) {
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) {
element = $(element);
var filter = element.getStyle('filter'), style = element.style;
if (value == 1 || value === '') {
style.filter = filter.replace(/alpha\([^\)]*\)/gi,'');
return element;
} else if (value < 0.00001) value = 0;
style.filter = filter.replace(/alpha\([^\)]*\)/gi, '') +
'alpha(opacity=' + (value * 100) + ')';
return element;
};


Element.Methods.update = function(element, html) {
element = $(element);
html = typeof html == 'undefined' ? '' : html.toString();
var tagName = element.tagName.toUpperCase();
if (['THEAD','TBODY','TR','TD'].include(tagName)) {
var div = document.createElement('div');
switch (tagName) {
case 'THEAD':
case 'TBODY':
div.innerHTML = '<table><tbody>' +  html.stripScripts() + '</tbody></table>';
depth = 2;
break;
case 'TR':
div.innerHTML = '<table><tbody><tr>' +  html.stripScripts() + '</tr></tbody></table>';
depth = 3;
break;
case 'TD':
div.innerHTML = '<table><tbody><tr><td>' +  html.stripScripts() + '</td></tr></tbody></table>';
depth = 4;
}
$A(element.childNodes).each(function(node) { element.removeChild(node) });
depth.times(function() { div = div.firstChild });
$A(div.childNodes).each(function(node) { element.appendChild(node) });
} else {
element.innerHTML = html.stripScripts();
}
setTimeout(function() { html.evalScripts() }, 10);
return element;
}
}
else if (Prototype.Browser.Gecko) {
Element.Methods.setOpacity = function(element, value) {
element = $(element);
element.style.opacity = (value == 1) ? 0.999999 :
(value === '') ? '' : (value < 0.00001) ? 0 : value;
return element;
};
}

Element._attributeTranslations = {
names: {
colspan:   "colSpan",
rowspan:   "rowSpan",
valign:    "vAlign",
datetime:  "dateTime",
accesskey: "accessKey",
tabindex:  "tabIndex",
enctype:   "encType",
maxlength: "maxLength",
readonly:  "readOnly",
longdesc:  "longDesc"
},
values: {
_getAttr: function(element, attribute) {
return element.getAttribute(attribute, 2);
},
_flag: function(element, attribute) {
return $(element).hasAttribute(attribute) ? attribute : null;
},
style: function(element) {
return element.style.cssText.toLowerCase();
},
title: function(element) {
var node = element.getAttributeNode('title');
return node.specified ? node.nodeValue : null;
}
}
};

(function() {
Object.extend(this, {
href: this._getAttr,
src:  this._getAttr,
type: this._getAttr,
disabled: this._flag,
checked:  this._flag,
readonly: this._flag,
multiple: this._flag
});
}).call(Element._attributeTranslations.values);

Element.Methods.Simulated = {
hasAttribute: function(element, attribute) {
var t = Element._attributeTranslations, node;
attribute = t.names[attribute] || attribute;
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.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 (tagName.constructor == Array) 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;
var cache = Element.extend.cache;
for (var property in methods) {
var value = methods[property];
if (!onlyIfAbsent || !(property in destination))
destination[property] = cache.findOrStore(value);
}
}

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 (typeof klass == "undefined") continue;
copy(T[tag], klass.prototype);
}
}

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

var Toggle = { display: Element.toggle };



Abstract.Insertion = function(adjacency) {
this.adjacency = adjacency;
}

Abstract.Insertion.prototype = {
initialize: function(element, content) {
this.element = $(element);
this.content = content.stripScripts();

if (this.adjacency && this.element.insertAdjacentHTML) {
try {
this.element.insertAdjacentHTML(this.adjacency, this.content);
} catch (e) {
var tagName = this.element.tagName.toUpperCase();
if (['TBODY', 'TR'].include(tagName)) {
this.insertContent(this.contentFromAnonymousTable());
} else {
throw e;
}
}
} else {
this.range = this.element.ownerDocument.createRange();
if (this.initializeRange) this.initializeRange();
this.insertContent([this.range.createContextualFragment(this.content)]);
}

setTimeout(function() {content.evalScripts()}, 10);
},

contentFromAnonymousTable: function() {
var div = document.createElement('div');
div.innerHTML = '<table><tbody>' + this.content + '</tbody></table>';
return $A(div.childNodes[0].childNodes[0].childNodes);
}
}

var Insertion = new Object();

Insertion.Before = Class.create();
Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), {
initializeRange: function() {
this.range.setStartBefore(this.element);
},

insertContent: function(fragments) {
fragments.each((function(fragment) {
this.element.parentNode.insertBefore(fragment, this.element);
}).bind(this));
}
});

Insertion.Top = Class.create();
Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), {
initializeRange: function() {
this.range.selectNodeContents(this.element);
this.range.collapse(true);
},

insertContent: function(fragments) {
fragments.reverse(false).each((function(fragment) {
this.element.insertBefore(fragment, this.element.firstChild);
}).bind(this));
}
});

Insertion.Bottom = Class.create();
Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), {
initializeRange: function() {
this.range.selectNodeContents(this.element);
this.range.collapse(this.element);
},

insertContent: function(fragments) {
fragments.each((function(fragment) {
this.element.appendChild(fragment);
}).bind(this));
}
});

Insertion.After = Class.create();
Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), {
initializeRange: function() {
this.range.setStartAfter(this.element);
},

insertContent: function(fragments) {
fragments.each((function(fragment) {
this.element.parentNode.insertBefore(fragment,
this.element.nextSibling);
}).bind(this));
}
});



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);




var Selector = Class.create();

Selector.prototype = {
initialize: function(expression) {
this.expression = expression.strip();
this.compileMatcher();
},

compileMatcher: function() {

if (Prototype.BrowserFeatures.XPath && !(/\[[\w-]*?:/).test(this.expression))
return this.compileXPathMatcher();

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(typeof c[i] == 'function' ? 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(typeof x[i] == 'function' ? 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;
if (this.xpath) return document._getElementsByXPath(this.xpath, root);
return this.matcher(root);
},

match: function(element) {
return this.findElements(document).include(element);
},

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: "[@#{1}]",
attr: function(m) {
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 (typeof h === 'function') 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 or translate(text(), ' \t\r\n', '') = '')]",
'checked':     "[@checked]",
'disabled':    "[@disabled]",
'enabled':     "[not(@disabled)]",
'not': function(m) {
var e = m[6], p = Selector.patterns,
x = Selector.xpath, le, m, v;

var exclusion = [];
while (e && le != e && (/\S/).test(e)) {
le = e;
for (var i in p) {
if (m = e.match(p[i])) {
v = typeof x[i] == 'function' ? 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 = false;',
attr: function(m) {
m[3] = (m[5] || m[6]);
return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}"); 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: {


laterSibling: /^\s*~\s*/,
child:        /^\s*>\s*/,
adjacent:     /^\s*\+\s*/,
descendant:   /^\s/,


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]+)\]/,
attr:         /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\]]*?)\4|([^'"][^\]]*?)))?\]/
},

handlers: {


concat: function(a, b) {
for (var i = 0, node; node = b[i]; i++)
a.push(node);
return a;
},


mark: function(nodes) {
for (var i = 0, node; node = nodes[i]; i++)
node._counted = true;
return nodes;
},

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




index: function(parentNode, reverse, ofType) {
parentNode._counted = true;
if (reverse) {
for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) {
node = nodes[i];
if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++;
}
} else {
for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++)
if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++;
}
},


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])._counted) {
n._counted = true;
results.push(Element.extend(n));
}
return Selector.handlers.unmark(results);
},


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, children = [], 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;
},


tagName: function(nodes, root, tagName, combinator) {
tagName = tagName.toUpperCase();
var results = [], h = Selector.handlers;
if (nodes) {
if (combinator) {

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() == tagName) results.push(node);
return results;
} else return root.getElementsByTagName(tagName);
},

id: function(nodes, root, id, combinator) {
var targetNode = $(id), h = Selector.handlers;
if (!nodes && root == document) return targetNode ? [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) {
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) {
if (!nodes) nodes = root.getElementsByTagName("*");
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);
},


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;
});
},


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._counted) {
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++) {

if (node.tagName == '!' || (node.firstChild && !node.innerHTML.match(/^\s*$/))) 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._counted) 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) 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.startsWith(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() + '-'); }
},

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

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

findChildElements: function(element, expressions) {
var exprs = expressions.join(','), expressions = [];
exprs.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) {
expressions.push(m[1].strip());
});
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;
}
});

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

serializeElements: function(elements, getHash) {
var data = elements.inject({}, function(result, element) {
if (!element.disabled && element.name) {
var key = element.name, value = $(element).getValue();
if (value != null) {
if (key in result) {
if (result[key].constructor != Array) result[key] = [result[key]];
result[key].push(value);
}
else result[key] = value;
}
}
return result;
});

return getHash ? data : Hash.toQueryString(data);
}
};

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

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) {
return $(form).getElements().find(function(element) {
return element.type != 'hidden' && !element.disabled &&
['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;
options.parameters = form.serialize(true);

if (params) {
if (typeof params == 'string') params = params.toQueryParams();
Object.extend(options.parameters, params);
}

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

return new Ajax.Request(form.readAttribute('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 Hash.toQueryString(pair);
}
}
return '';
},

getValue: function(element) {
element = $(element);
var method = element.tagName.toLowerCase();
return Form.Element.Serializers[method](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.blur();
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) {
switch (element.type.toLowerCase()) {
case 'checkbox':
case 'radio':
return Form.Element.Serializers.inputSelector(element);
default:
return Form.Element.Serializers.textarea(element);
}
},

inputSelector: function(element) {
return element.checked ? element.value : null;
},

textarea: function(element) {
return element.value;
},

select: function(element) {
return this[element.type == 'select-one' ?
'selectOne' : 'selectMany'](element);
},

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) {

return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text;
}
}



Abstract.TimedObserver = function() {}
Abstract.TimedObserver.prototype = {
initialize: function(element, frequency, callback) {
this.frequency = frequency;
this.element   = $(element);
this.callback  = callback;

this.lastValue = this.getValue();
this.registerCallback();
},

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

onTimerEvent: function() {
var value = this.getValue();
var changed = ('string' == typeof this.lastValue && 'string' == typeof value
? this.lastValue != value : String(this.lastValue) != String(value));
if (changed) {
this.callback(this.element, value);
this.lastValue = value;
}
}
}

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

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



Abstract.EventObserver = function() {}
Abstract.EventObserver.prototype = {
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.bind(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();
Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
getValue: function() {
return Form.Element.getValue(this.element);
}
});

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

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,

element: function(event) {
return $(event.target || event.srcElement);
},

isLeftClick: function(event) {
return (((event.which) && (event.which == 1)) ||
((event.button) && (event.button == 1)));
},

pointerX: function(event) {
return event.pageX || (event.clientX +
(document.documentElement.scrollLeft || document.body.scrollLeft));
},

pointerY: function(event) {
return event.pageY || (event.clientY +
(document.documentElement.scrollTop || document.body.scrollTop));
},

stop: function(event) {
if (event.preventDefault) {
event.preventDefault();
event.stopPropagation();
} else {
event.returnValue = false;
event.cancelBubble = true;
}
},



findElement: function(event, tagName) {
var element = Event.element(event);
while (element.parentNode && (!element.tagName ||
(element.tagName.toUpperCase() != tagName.toUpperCase())))
element = element.parentNode;
return element;
},

observers: false,

_observeAndCache: function(element, name, observer, useCapture) {
if (!this.observers) this.observers = [];
if (element.addEventListener) {
this.observers.push([element, name, observer, useCapture]);
element.addEventListener(name, observer, useCapture);
} else if (element.attachEvent) {
this.observers.push([element, name, observer, useCapture]);
element.attachEvent('on' + name, observer);
}
},

unloadCache: function() {
if (!Event.observers) return;
for (var i = 0, length = Event.observers.length; i < length; i++) {
Event.stopObserving.apply(this, Event.observers[i]);
Event.observers[i][0] = null;
}
Event.observers = false;
},

observe: function(element, name, observer, useCapture) {
element = $(element);
useCapture = useCapture || false;

if (name == 'keypress' &&
(Prototype.Browser.WebKit || element.attachEvent))
name = 'keydown';

Event._observeAndCache(element, name, observer, useCapture);
},

stopObserving: function(element, name, observer, useCapture) {
element = $(element);
useCapture = useCapture || false;

if (name == 'keypress' &&
(Prototype.Browser.WebKit || element.attachEvent))
name = 'keydown';

if (element.removeEventListener) {
element.removeEventListener(name, observer, useCapture);
} else if (element.detachEvent) {
try {
element.detachEvent('on' + name, observer);
} catch (e) {}
}
}
});


if (Prototype.Browser.IE)
Event.observe(window, 'unload', Event.unloadCache, false);
var Position = {



includeScrollOffsets: false,



prepare: function() {
this.deltaX =  window.pageXOffset
|| document.documentElement.scrollLeft
|| document.body.scrollLeft
|| 0;
this.deltaY =  window.pageYOffset
|| document.documentElement.scrollTop
|| document.body.scrollTop
|| 0;
},

realOffset: function(element) {
var valueT = 0, valueL = 0;
do {
valueT += element.scrollTop  || 0;
valueL += element.scrollLeft || 0;
element = element.parentNode;
} while (element);
return [valueL, valueT];
},

cumulativeOffset: function(element) {
var valueT = 0, valueL = 0;
do {
valueT += element.offsetTop  || 0;
valueL += element.offsetLeft || 0;
element = element.offsetParent;
} while (element);
return [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=='BODY') break;
var p = Element.getStyle(element, 'position');
if (p == 'relative' || p == 'absolute') break;
}
} while (element);
return [valueL, valueT];
},

offsetParent: 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;
},


within: function(element, x, y) {
if (this.includeScrollOffsets)
return this.withinIncludingScrolloffsets(element, x, y);
this.xcomp = x;
this.ycomp = y;
this.offset = this.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 = this.realOffset(element);

this.xcomp = x + offsetcache[0] - this.deltaX;
this.ycomp = y + offsetcache[1] - this.deltaY;
this.offset = this.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);
},


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;
},

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

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


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

} while (element = element.offsetParent);

element = forElement;
do {
if (!window.opera || element.tagName=='BODY') {
valueT -= element.scrollTop  || 0;
valueL -= element.scrollLeft || 0;
}
} while (element = element.parentNode);

return [valueL, valueT];
},

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


source = $(source);
var p = Position.page(source);


target = $(target);
var delta = [0, 0];
var parent = null;


if (Element.getStyle(target,'position') == 'absolute') {
parent = Position.offsetParent(target);
delta = Position.page(parent);
}


if (parent == document.body) {
delta[0] -= document.body.offsetLeft;
delta[1] -= document.body.offsetTop;
}


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

absolutize: function(element) {
element = $(element);
if (element.style.position == 'absolute') return;
Position.prepare();

var offsets = Position.positionedOffset(element);
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';
},

relativize: function(element) {
element = $(element);
if (element.style.position == 'relative') return;
Position.prepare();

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;
}
}




if (Prototype.Browser.WebKit) {
Position.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 [valueL, valueT];
}
}

Element.addMethods();

























var Scriptaculous = {
Version: '1.7.1_beta3',
require: function(libraryName) {

document.write('<script type="text/javascript" src="'+libraryName+'"></script>');
},
REQUIRED_PROTOTYPE: '1.5.1',
load: function() {
function convertVersionString(versionString){
var r = versionString.split('.');
return parseInt(r[0])*100000 + parseInt(r[1])*1000 + parseInt(r[2]);
}

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);

$A(document.getElementsByTagName("script")).findAll( function(s) {
return (s.src && s.src.match(/scriptaculous\.js(\?.*)?$/))
}).each( function(s) {
var path = s.src.replace(/scriptaculous\.js(\?.*)?$/,'');
var 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();













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) { }
};



Array.prototype.call = function() {
var args = arguments;
this.each(function(f){ f.apply(this, args) });
}



var Effect = {
_elementDoesNotExistError: {
name: 'ElementDoesNotExistError',
message: 'The specified DOM element does not exist, but is required for this effect to operate'
},
tagifyText: function(element) {
if(typeof Builder == 'undefined')
throw("Effect.tagifyText requires including script.aculo.us' builder.js library");

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(
Builder.node('span',{style: tagifyStyle},
character == ' ' ? String.fromCharCode(160) : character),
child);
});
Element.remove(child);
}
});
},
multiple: function(element, effect) {
var elements;
if(((typeof element == 'object') ||
(typeof element == 'function')) &&
(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);
}
};

var Effect2 = Effect; // deprecated



Effect.Transitions = {
linear: Prototype.K,
sinoidal: function(pos) {
return (-Math.cos(pos*Math.PI)/2) + 0.5;
},
reverse: function(pos) {
return 1-pos;
},
flicker: function(pos) {
var pos = ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4;
return (pos > 1 ? 1 : pos);
},
wobble: function(pos) {
return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5;
},
pulse: function(pos, pulses) {
pulses = pulses || 5;
return (
Math.round((pos % (1/pulses)) * pulses) == 0 ?
((pos * pulses * 2) - Math.floor(pos * pulses * 2)) :
1 - ((pos * pulses * 2) - Math.floor(pos * pulses * 2))
);
},
none: function(pos) {
return 0;
},
full: function(pos) {
return 1;
}
};



Effect.ScopedQueue = Class.create();
Object.extend(Object.extend(Effect.ScopedQueue.prototype, 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 = (typeof effect.options.queue == 'string') ?
effect.options.queue : effect.options.queue.position;

switch(position) {
case 'front':

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':

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(typeof queueName != 'string') return queueName;

if(!this.instances[queueName])
this.instances[queueName] = new Effect.ScopedQueue();

return this.instances[queueName];
}
}
Effect.Queue = Effect.Queues.get('global');

Effect.DefaultOptions = {
transition: Effect.Transitions.sinoidal,
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'
}

Effect.Base = function() {};
Effect.Base.prototype = {
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.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;

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

this.event('beforeStart');
if(!this.options.sync)
Effect.Queues.get(typeof this.options.queue == 'string' ?
'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 = Math.round(pos * this.totalFrames);
if(frame > this.currentFrame) {
this.render(pos);
this.currentFrame = frame;
}
}
},
cancel: function() {
if(!this.options.sync)
Effect.Queues.get(typeof this.options.queue == 'string' ?
'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(typeof this[property] != 'function') data[property] = this[property];
return '#<Effect:' + data.inspect() + ',options:' + $H(this.options).inspect() + '>';
}
}

Effect.Parallel = Class.create();
Object.extend(Object.extend(Effect.Parallel.prototype, Effect.Base.prototype), {
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.Event = Class.create();
Object.extend(Object.extend(Effect.Event.prototype, Effect.Base.prototype), {
initialize: function() {
var options = Object.extend({
duration: 0
}, arguments[0] || {});
this.start(options);
},
update: Prototype.emptyFunction
});

Effect.Opacity = Class.create();
Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), {
initialize: function(element) {
this.element = $(element);
if(!this.element) throw(Effect._elementDoesNotExistError);

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();
Object.extend(Object.extend(Effect.Move.prototype, Effect.Base.prototype), {
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: Math.round(this.options.x  * position + this.originalLeft) + 'px',
top:  Math.round(this.options.y  * position + this.originalTop)  + 'px'
});
}
});


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

Effect.Scale = Class.create();
Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), {
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 = Math.round(width) + 'px';
if(this.options.scaleY) d.height = Math.round(height) + '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();
Object.extend(Object.extend(Effect.Highlight.prototype, Effect.Base.prototype), {
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() {

if(this.element.getStyle('display')=='none') { this.cancel(); return; }

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');

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+(Math.round(this._base[i]+(this._delta[i]*position)).toColorPart()); }.bind(this)) });
},
finish: function() {
this.element.setStyle(Object.extend(this.oldStyle, {
backgroundColor: this.options.restorecolor
}));
}
});

Effect.ScrollTo = Class.create();
Object.extend(Object.extend(Effect.ScrollTo.prototype, Effect.Base.prototype), {
initialize: function(element) {
this.element = $(element);
this.start(arguments[1] || {});
},
setup: function() {
Position.prepare();
var offsets = Position.cumulativeOffset(this.element);
if(this.options.offset) offsets[1] += this.options.offset;
var max = window.innerHeight ?
window.height - window.innerHeight :
document.body.scrollHeight -
(document.documentElement.clientHeight ?
document.documentElement.clientHeight : document.body.clientHeight);
this.scrollStart = Position.deltaY;
this.delta = (offsets[1] > max ? max : offsets[1]) - this.scrollStart;
},
update: function(position) {
Position.prepare();
window.scrollTo(Position.deltaX,
this.scrollStart + (position*this.delta));
}
});



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,

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 oldStyle = {
top: element.getStyle('top'),
left: element.getStyle('left') };
return new Effect.Move(element,
{ x:  20, y: 0, duration: 0.05, afterFinishInternal: function(effect) {
new Effect.Move(effect.element,
{ x: -40, y: 0, duration: 0.1,  afterFinishInternal: function(effect) {
new Effect.Move(effect.element,
{ x:  40, y: 0, duration: 0.1,  afterFinishInternal: function(effect) {
new Effect.Move(effect.element,
{ x: -40, y: 0, duration: 0.1,  afterFinishInternal: function(effect) {
new Effect.Move(effect.element,
{ x:  40, y: 0, duration: 0.1,  afterFinishInternal: function(effect) {
new Effect.Move(effect.element,
{ x: -20, y: 0, duration: 0.05, afterFinishInternal: function(effect) {
effect.element.undoPositioned().setStyle(oldStyle);
}}) }}) }}) }}) }}) }});
}

Effect.SlideDown = function(element) {
element = $(element).cleanWhitespace();

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');
return new Effect.Scale(element, window.opera ? 0 : 1,
Object.extend({ scaleContent: false,
scaleX: false,
scaleMode: 'box',
scaleFrom: 100,
restoreAfterFinish: true,
beforeStartInternal: 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().setStyle({bottom: oldInnerBottom});
effect.element.down().undoPositioned();
}
}, arguments[1] || {})
);
}


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] || {};
var oldOpacity = element.getInlineOpacity();
var transition = options.transition || Effect.Transitions.sinoidal;
var reverser   = function(pos){ return transition(1-Effect.Transitions.pulse(pos, options.pulses)) };
reverser.bind(transition);
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();
Object.extend(Object.extend(Effect.Morph.prototype, Effect.Base.prototype), {
initialize: function(element) {
this.element = $(element);
if(!this.element) throw(Effect._elementDoesNotExistError);
var options = Object.extend({
style: {}
}, arguments[1] || {});
if (typeof options.style == 'string') {
if(options.style.indexOf(':') == -1) {
var cssText = '', selector = '.' + options.style;
$A(document.styleSheets).reverse().each(function(styleSheet) {
if (styleSheet.cssRules) cssRules = styleSheet.cssRules;
else if (styleSheet.rules) cssRules = styleSheet.rules;
$A(cssRules).reverse().each(function(rule) {
if (selector == rule.selectorText) {
cssText = rule.style.cssText;
throw $break;
}
});
if (cssText) throw $break;
});
this.style = cssText.parseStyle();
options.afterFinishInternal = function(effect){
effect.element.addClassName(effect.options.style);
effect.transforms.each(function(transform) {
if(transform.style != 'opacity')
effect.element.style[transform.style] = '';
});
}
} else this.style = options.style.parseStyle();
} else this.style = $H(options.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 + Math.round(
((transform.targetValue - transform.originalValue) * position) * 1000)/1000 + transform.unit;
this.element.setStyle(style, true);
}
});

Effect.Transform = Class.create();
Object.extend(Effect.Transform.prototype, {
initialize: function(tracks){
this.tracks  = [];
this.options = arguments[1] || {};
this.addTracks(tracks);
},
addTracks: function(tracks){
tracks.each(function(track){
var data = $H(track).values().first();
this.tracks.push($H({
ids:     $H(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 elements = [$(track.ids) || $$(track.ids)].flatten();
return elements.map(function(e){ return new track.effect(e, Object.extend({ sync:true }, track.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.prototype.parseStyle = function(){
var element = document.createElement('div');
element.innerHTML = '<div style="' + this + '"></div>';
var style = element.childNodes[0].style, styleRules = $H();

Element.CSS_PROPERTIES.each(function(property){
if(style[property]) styleRules[property] = style[property];
});
if(Prototype.Browser.IE && this.indexOf('opacity') > -1) {
styleRules.opacity = this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1];
}
return styleRules;
};

Element.morph = function(element, style) {
new Effect.Morph(element, Object.extend({ style: style }, arguments[2] || {}));
return element;
};

['getInlineOpacity','forceRerendering','setContentZoom',
'collectTextNodes','collectTextNodesIgnoreClass','morph'].each(
function(f) { Element.Methods[f] = Element[f]; }
);

Element.Methods.visualEffect = function(element, effect, options) {
s = effect.dasherize().camelize();
effect_class = s.charAt(0).toUpperCase() + s.substring(1);
new Effect[effect_class](element, options);
return $(element);
};

Element.addMethods();






































if(typeof Effect == 'undefined')
throw("controls.js requires including script.aculo.us' effects.js library");

var Autocompleter = {}
Autocompleter.Base = function() {};
Autocompleter.Base.prototype = {
baseInitialize: function(element, update, options) {
element          = $(element)
this.element     = element;
this.update      = $(update);
this.hasFocus    = false;
this.changed     = false;
this.active      = false;
this.index       = 0;
this.entryCount  = 0;

if(this.setOptions)
this.setOptions(options);
else
this.options = options || {};

this.options.paramName    = this.options.paramName || this.element.name;
this.options.tokens       = this.options.tokens || [];
this.options.frequency    = this.options.frequency || 0.4;
this.options.minChars     = this.options.minChars || 1;
this.options.onShow       = this.options.onShow ||
function(element, update){
if(!update.style.position || update.style.position=='absolute') {
update.style.position = 'absolute';
Position.clone(element, update, {
setHeight: false,
offsetTop: element.offsetHeight
});
}
Effect.Appear(update,{duration:0.15});
};
this.options.onHide = this.options.onHide ||
function(element, update){ new Effect.Fade(update,{duration:0.15}) };

if(typeof(this.options.tokens) == 'string')
this.options.tokens = new Array(this.options.tokens);

this.observer = null;

this.element.setAttribute('autocomplete','off');

Element.hide(this.update);

Event.observe(this.element, 'blur', this.onBlur.bindAsEventListener(this));
Event.observe(this.element, 'keypress', this.onKeyPress.bindAsEventListener(this));



Event.observe(window, 'beforeunload', function(){
element.setAttribute('autocomplete', 'on');
});
},

show: function() {
if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update);
if(!this.iefix &&
(Prototype.Browser.IE) &&
(Element.getStyle(this.update, 'position')=='absolute')) {
new Insertion.After(this.update,
'<iframe id="' + this.update.id + '_iefix" '+
'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' +
'src="javascript:false;" frameborder="0" scrolling="no"></iframe>');
this.iefix = $(this.update.id+'_iefix');
}
if(this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50);
},

fixIEOverlapping: function() {
Position.clone(this.update, this.iefix, {setTop:(!this.update.style.height)});
this.iefix.style.zIndex = 1;
this.update.style.zIndex = 2;
Element.show(this.iefix);
},

hide: function() {
this.stopIndicator();
if(Element.getStyle(this.update, 'display')!='none') this.options.onHide(this.element, this.update);
if(this.iefix) Element.hide(this.iefix);
},

startIndicator: function() {
if(this.options.indicator) Element.show(this.options.indicator);
},

stopIndicator: function() {
if(this.options.indicator) Element.hide(this.options.indicator);
},

onKeyPress: function(event) {
if(this.active)
switch(event.keyCode) {
case Event.KEY_TAB:
case Event.KEY_RETURN:
this.selectEntry();
Event.stop(event);
case Event.KEY_ESC:
this.hide();
this.active = false;
Event.stop(event);
return;
case Event.KEY_LEFT:
case Event.KEY_RIGHT:
return;
case Event.KEY_UP:
this.markPrevious();
this.render();
if(Prototype.Browser.WebKit) Event.stop(event);
return;
case Event.KEY_DOWN:
this.markNext();
this.render();
if(Prototype.Browser.WebKit) Event.stop(event);
return;
}
else
if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN ||
(Prototype.Browser.WebKit > 0 && event.keyCode == 0)) return;

this.changed = true;
this.hasFocus = true;

if(this.observer) clearTimeout(this.observer);
this.observer =
setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000);
},

activate: function() {
this.changed = false;
this.hasFocus = true;
this.getUpdatedChoices();
},

onHover: function(event) {
var element = Event.findElement(event, 'LI');
if(this.index != element.autocompleteIndex)
{
this.index = element.autocompleteIndex;
this.render();
}
Event.stop(event);
},

onClick: function(event) {
var element = Event.findElement(event, 'LI');
this.index = element.autocompleteIndex;
this.selectEntry();
this.hide();
},

onBlur: function(event) {

setTimeout(this.hide.bind(this), 250);
this.hasFocus = false;
this.active = false;
},

render: function() {
if(this.entryCount > 0) {
for (var i = 0; i < this.entryCount; i++)
this.index==i ?
Element.addClassName(this.getEntry(i),"selected") :
Element.removeClassName(this.getEntry(i),"selected");
if(this.hasFocus) {
this.show();
this.active = true;
}
} else {
this.active = false;
this.hide();
}
},

markPrevious: function() {
if(this.index > 0) this.index--
else this.index = this.entryCount-1;
this.getEntry(this.index).scrollIntoView(true);
},

markNext: function() {
if(this.index < this.entryCount-1) this.index++
else this.index = 0;
this.getEntry(this.index).scrollIntoView(false);
},

getEntry: function(index) {
return this.update.firstChild.childNodes[index];
},

getCurrentEntry: function() {
return this.getEntry(this.index);
},

selectEntry: function() {
this.active = false;
this.updateElement(this.getCurrentEntry());
},

updateElement: function(selectedElement) {
if (this.options.updateElement) {
this.options.updateElement(selectedElement);
return;
}
var value = '';
if (this.options.select) {
var nodes = document.getElementsByClassName(this.options.select, selectedElement) || [];
if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select);
} else
value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal');

var lastTokenPos = this.findLastToken();
if (lastTokenPos != -1) {
var newValue = this.element.value.substr(0, lastTokenPos + 1);
var whitespace = this.element.value.substr(lastTokenPos + 1).match(/^\s+/);
if (whitespace)
newValue += whitespace[0];
this.element.value = newValue + value;
} else {
this.element.value = value;
}
this.element.focus();

if (this.options.afterUpdateElement)
this.options.afterUpdateElement(this.element, selectedElement);
},

updateChoices: function(choices) {
if(!this.changed && this.hasFocus) {
this.update.innerHTML = choices;
Element.cleanWhitespace(this.update);
Element.cleanWhitespace(this.update.down());

if(this.update.firstChild && this.update.down().childNodes) {
this.entryCount =
this.update.down().childNodes.length;
for (var i = 0; i < this.entryCount; i++) {
var entry = this.getEntry(i);
entry.autocompleteIndex = i;
this.addObservers(entry);
}
} else {
this.entryCount = 0;
}

this.stopIndicator();
this.index = 0;

if(this.entryCount==1 && this.options.autoSelect) {
this.selectEntry();
this.hide();
} else {
this.render();
}
}
},

addObservers: function(element) {
Event.observe(element, "mouseover", this.onHover.bindAsEventListener(this));
Event.observe(element, "click", this.onClick.bindAsEventListener(this));
},

onObserverEvent: function() {
this.changed = false;
if(this.getToken().length>=this.options.minChars) {
this.getUpdatedChoices();
} else {
this.active = false;
this.hide();
}
},

getToken: function() {
var tokenPos = this.findLastToken();
if (tokenPos != -1)
var ret = this.element.value.substr(tokenPos + 1).replace(/^\s+/,'').replace(/\s+$/,'');
else
var ret = this.element.value;

return /\n/.test(ret) ? '' : ret;
},

findLastToken: function() {
var lastTokenPos = -1;

for (var i=0; i<this.options.tokens.length; i++) {
var thisTokenPos = this.element.value.lastIndexOf(this.options.tokens[i]);
if (thisTokenPos > lastTokenPos)
lastTokenPos = thisTokenPos;
}
return lastTokenPos;
}
}

Ajax.Autocompleter = Class.create();
Object.extend(Object.extend(Ajax.Autocompleter.prototype, Autocompleter.Base.prototype), {
initialize: function(element, update, url, options) {
this.baseInitialize(element, update, options);
this.options.asynchronous  = true;
this.options.onComplete    = this.onComplete.bind(this);
this.options.defaultParams = this.options.parameters || null;
this.url                   = url;
},

getUpdatedChoices: function() {
this.startIndicator();

var entry = encodeURIComponent(this.options.paramName) + '=' +
encodeURIComponent(this.getToken());

this.options.parameters = this.options.callback ?
this.options.callback(this.element, entry) : entry;

if(this.options.defaultParams)
this.options.parameters += '&' + this.options.defaultParams;

new Ajax.Request(this.url, this.options);
},

onComplete: function(request) {
this.updateChoices(request.responseText);
}

});




































Autocompleter.Local = Class.create();
Autocompleter.Local.prototype = Object.extend(new Autocompleter.Base(), {
initialize: function(element, update, array, options) {
this.baseInitialize(element, update, options);
this.options.array = array;
},

getUpdatedChoices: function() {
this.updateChoices(this.options.selector(this));
},

setOptions: function(options) {
this.options = Object.extend({
choices: 10,
partialSearch: true,
partialChars: 2,
ignoreCase: true,
fullSearch: false,
selector: function(instance) {
var ret       = []; // Beginning matches
var partial   = []; // Inside matches
var entry     = instance.getToken();
var count     = 0;

for (var i = 0; i < instance.options.array.length &&
ret.length < instance.options.choices ; i++) {

var elem = instance.options.array[i];
var foundPos = instance.options.ignoreCase ?
elem.toLowerCase().indexOf(entry.toLowerCase()) :
elem.indexOf(entry);

while (foundPos != -1) {
if (foundPos == 0 && elem.length != entry.length) {
ret.push("<li><strong>" + elem.substr(0, entry.length) + "</strong>" +
elem.substr(entry.length) + "</li>");
break;
} else if (entry.length >= instance.options.partialChars &&
instance.options.partialSearch && foundPos != -1) {
if (instance.options.fullSearch || /\s/.test(elem.substr(foundPos-1,1))) {
partial.push("<li>" + elem.substr(0, foundPos) + "<strong>" +
elem.substr(foundPos, entry.length) + "</strong>" + elem.substr(
foundPos + entry.length) + "</li>");
break;
}
}

foundPos = instance.options.ignoreCase ?
elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) :
elem.indexOf(entry, foundPos + 1);

}
}
if (partial.length)
ret = ret.concat(partial.slice(0, instance.options.choices - ret.length))
return "<ul>" + ret.join('') + "</ul>";
}
}, options || {});
}
});








Field.scrollFreeActivate = function(field) {
setTimeout(function() {
Field.activate(field);
}, 1);
}

Ajax.InPlaceEditor = Class.create();
Ajax.InPlaceEditor.defaultHighlightColor = "#FFFF99";
Ajax.InPlaceEditor.prototype = {
initialize: function(element, url, options) {
this.url = url;
this.element = $(element);

this.options = Object.extend({
paramName: "value",
okButton: true,
okLink: false,
okText: "ok",
cancelButton: false,
cancelLink: true,
cancelText: "cancel",
textBeforeControls: '',
textBetweenControls: '',
textAfterControls: '',
savingText: "Saving...",
clickToEditText: "Click to edit",
okText: "ok",
rows: 1,
onComplete: function(transport, element) {
new Effect.Highlight(element, {startcolor: this.options.highlightcolor});
},
onFailure: function(transport) {
alert("Error communicating with the server: " + transport.responseText.stripTags());
},
callback: function(form) {
return Form.serialize(form);
},
handleLineBreaks: true,
loadingText: 'Loading...',
savingClassName: 'inplaceeditor-saving',
loadingClassName: 'inplaceeditor-loading',
formClassName: 'inplaceeditor-form',
highlightcolor: Ajax.InPlaceEditor.defaultHighlightColor,
highlightendcolor: "#FFFFFF",
externalControl: null,
submitOnBlur: false,
ajaxOptions: {},
evalScripts: false
}, options || {});

if(!this.options.formId && this.element.id) {
this.options.formId = this.element.id + "-inplaceeditor";
if ($(this.options.formId)) {

this.options.formId = null;
}
}

if (this.options.externalControl) {
this.options.externalControl = $(this.options.externalControl);
}

this.originalBackground = Element.getStyle(this.element, 'background-color');
if (!this.originalBackground) {
this.originalBackground = "transparent";
}

this.element.title = this.options.clickToEditText;

this.onclickListener = this.enterEditMode.bindAsEventListener(this);
this.mouseoverListener = this.enterHover.bindAsEventListener(this);
this.mouseoutListener = this.leaveHover.bindAsEventListener(this);
Event.observe(this.element, 'click', this.onclickListener);
Event.observe(this.element, 'mouseover', this.mouseoverListener);
Event.observe(this.element, 'mouseout', this.mouseoutListener);
if (this.options.externalControl) {
Event.observe(this.options.externalControl, 'click', this.onclickListener);
Event.observe(this.options.externalControl, 'mouseover', this.mouseoverListener);
Event.observe(this.options.externalControl, 'mouseout', this.mouseoutListener);
}
},
enterEditMode: function(evt) {
if (this.saving) return;
if (this.editing) return;
this.editing = true;
this.onEnterEditMode();
if (this.options.externalControl) {
Element.hide(this.options.externalControl);
}
Element.hide(this.element);
this.createForm();
this.element.parentNode.insertBefore(this.form, this.element);
if (!this.options.loadTextURL) Field.scrollFreeActivate(this.editField);

if (evt) {
Event.stop(evt);
}
return false;
},
createForm: function() {
this.form = document.createElement("form");
this.form.id = this.options.formId;
Element.addClassName(this.form, this.options.formClassName)
this.form.onsubmit = this.onSubmit.bind(this);

this.createEditField();

if (this.options.textarea) {
var br = document.createElement("br");
this.form.appendChild(br);
}

if (this.options.textBeforeControls)
this.form.appendChild(document.createTextNode(this.options.textBeforeControls));

if (this.options.okButton) {
var okButton = document.createElement("input");
okButton.type = "submit";
okButton.value = this.options.okText;
okButton.className = 'editor_ok_button';
this.form.appendChild(okButton);
}

if (this.options.okLink) {
var okLink = document.createElement("a");
okLink.href = "#";
okLink.appendChild(document.createTextNode(this.options.okText));
okLink.onclick = this.onSubmit.bind(this);
okLink.className = 'editor_ok_link';
this.form.appendChild(okLink);
}

if (this.options.textBetweenControls &&
(this.options.okLink || this.options.okButton) &&
(this.options.cancelLink || this.options.cancelButton))
this.form.appendChild(document.createTextNode(this.options.textBetweenControls));

if (this.options.cancelButton) {
var cancelButton = document.createElement("input");
cancelButton.type = "submit";
cancelButton.value = this.options.cancelText;
cancelButton.onclick = this.onclickCancel.bind(this);
cancelButton.className = 'editor_cancel_button';
this.form.appendChild(cancelButton);
}

if (this.options.cancelLink) {
var cancelLink = document.createElement("a");
cancelLink.href = "#";
cancelLink.appendChild(document.createTextNode(this.options.cancelText));
cancelLink.onclick = this.onclickCancel.bind(this);
cancelLink.className = 'editor_cancel editor_cancel_link';
this.form.appendChild(cancelLink);
}

if (this.options.textAfterControls)
this.form.appendChild(document.createTextNode(this.options.textAfterControls));
},
hasHTMLLineBreaks: function(string) {
if (!this.options.handleLineBreaks) return false;
return string.match(/<br/i) || string.match(/<p>/i);
},
convertHTMLLineBreaks: function(string) {
return string.replace(/<br>/gi, "\n").replace(/<br\/>/gi, "\n").replace(/<\/p>/gi, "\n").replace(/<p>/gi, "");
},
createEditField: function() {
var text;
if(this.options.loadTextURL) {
text = this.options.loadingText;
} else {
text = this.getText();
}

var obj = this;

if (this.options.rows == 1 && !this.hasHTMLLineBreaks(text)) {
this.options.textarea = false;
var textField = document.createElement("input");
textField.obj = this;
textField.type = "text";
textField.name = this.options.paramName;
textField.value = text;
textField.style.backgroundColor = this.options.highlightcolor;
textField.className = 'editor_field';
var size = this.options.size || this.options.cols || 0;
if (size != 0) textField.size = size;
if (this.options.submitOnBlur)
textField.onblur = this.onSubmit.bind(this);
this.editField = textField;
} else {
this.options.textarea = true;
var textArea = document.createElement("textarea");
textArea.obj = this;
textArea.name = this.options.paramName;
textArea.value = this.convertHTMLLineBreaks(text);
textArea.rows = this.options.rows;
textArea.cols = this.options.cols || 40;
textArea.className = 'editor_field';
if (this.options.submitOnBlur)
textArea.onblur = this.onSubmit.bind(this);
this.editField = textArea;
}

if(this.options.loadTextURL) {
this.loadExternalText();
}
this.form.appendChild(this.editField);
},
getText: function() {
return this.element.innerHTML;
},
loadExternalText: function() {
Element.addClassName(this.form, this.options.loadingClassName);
this.editField.disabled = true;
new Ajax.Request(
this.options.loadTextURL,
Object.extend({
asynchronous: true,
onComplete: this.onLoadedExternalText.bind(this)
}, this.options.ajaxOptions)
);
},
onLoadedExternalText: function(transport) {
Element.removeClassName(this.form, this.options.loadingClassName);
this.editField.disabled = false;
this.editField.value = transport.responseText.stripTags();
Field.scrollFreeActivate(this.editField);
},
onclickCancel: function() {
this.onComplete();
this.leaveEditMode();
return false;
},
onFailure: function(transport) {
this.options.onFailure(transport);
if (this.oldInnerHTML) {
this.element.innerHTML = this.oldInnerHTML;
this.oldInnerHTML = null;
}
return false;
},
onSubmit: function() {

var form = this.form;
var value = this.editField.value;




this.onLoading();

if (this.options.evalScripts) {
new Ajax.Request(
this.url, Object.extend({
parameters: this.options.callback(form, value),
onComplete: this.onComplete.bind(this),
onFailure: this.onFailure.bind(this),
asynchronous:true,
evalScripts:true
}, this.options.ajaxOptions));
} else  {
new Ajax.Updater(
{ success: this.element,

failure: null },
this.url, Object.extend({
parameters: this.options.callback(form, value),
onComplete: this.onComplete.bind(this),
onFailure: this.onFailure.bind(this)
}, this.options.ajaxOptions));
}

if (arguments.length > 1) {
Event.stop(arguments[0]);
}
return false;
},
onLoading: function() {
this.saving = true;
this.removeForm();
this.leaveHover();
this.showSaving();
},
showSaving: function() {
this.oldInnerHTML = this.element.innerHTML;
this.element.innerHTML = this.options.savingText;
Element.addClassName(this.element, this.options.savingClassName);
this.element.style.backgroundColor = this.originalBackground;
Element.show(this.element);
},
removeForm: function() {
if(this.form) {
if (this.form.parentNode) Element.remove(this.form);
this.form = null;
}
},
enterHover: function() {
if (this.saving) return;
this.element.style.backgroundColor = this.options.highlightcolor;
if (this.effect) {
this.effect.cancel();
}
Element.addClassName(this.element, this.options.hoverClassName)
},
leaveHover: function() {
if (this.options.backgroundColor) {
this.element.style.backgroundColor = this.oldBackground;
}
Element.removeClassName(this.element, this.options.hoverClassName)
if (this.saving) return;
this.effect = new Effect.Highlight(this.element, {
startcolor: this.options.highlightcolor,
endcolor: this.options.highlightendcolor,
restorecolor: this.originalBackground
});
},
leaveEditMode: function() {
Element.removeClassName(this.element, this.options.savingClassName);
this.removeForm();
this.leaveHover();
this.element.style.backgroundColor = this.originalBackground;
Element.show(this.element);
if (this.options.externalControl) {
Element.show(this.options.externalControl);
}
this.editing = false;
this.saving = false;
this.oldInnerHTML = null;
this.onLeaveEditMode();
},
onComplete: function(transport) {
this.leaveEditMode();
this.options.onComplete.bind(this)(transport, this.element);
},
onEnterEditMode: function() {},
onLeaveEditMode: function() {},
dispose: function() {
if (this.oldInnerHTML) {
this.element.innerHTML = this.oldInnerHTML;
}
this.leaveEditMode();
Event.stopObserving(this.element, 'click', this.onclickListener);
Event.stopObserving(this.element, 'mouseover', this.mouseoverListener);
Event.stopObserving(this.element, 'mouseout', this.mouseoutListener);
if (this.options.externalControl) {
Event.stopObserving(this.options.externalControl, 'click', this.onclickListener);
Event.stopObserving(this.options.externalControl, 'mouseover', this.mouseoverListener);
Event.stopObserving(this.options.externalControl, 'mouseout', this.mouseoutListener);
}
}
};

Ajax.InPlaceCollectionEditor = Class.create();
Object.extend(Ajax.InPlaceCollectionEditor.prototype, Ajax.InPlaceEditor.prototype);
Object.extend(Ajax.InPlaceCollectionEditor.prototype, {
createEditField: function() {
if (!this.cached_selectTag) {
var selectTag = document.createElement("select");
var collection = this.options.collection || [];
var optionTag;
collection.each(function(e,i) {
optionTag = document.createElement("option");
optionTag.value = (e instanceof Array) ? e[0] : e;
if((typeof this.options.value == 'undefined') &&
((e instanceof Array) ? this.element.innerHTML == e[1] : e == optionTag.value)) optionTag.selected = true;
if(this.options.value==optionTag.value) optionTag.selected = true;
optionTag.appendChild(document.createTextNode((e instanceof Array) ? e[1] : e));
selectTag.appendChild(optionTag);
}.bind(this));
this.cached_selectTag = selectTag;
}

this.editField = this.cached_selectTag;
if(this.options.loadTextURL) this.loadExternalText();
this.form.appendChild(this.editField);
this.options.callback = function(form, value) {
return "value=" + encodeURIComponent(value);
}
}
});





Form.Element.DelayedObserver = Class.create();
Form.Element.DelayedObserver.prototype = {
initialize: function(element, delay, callback) {
this.delay     = delay || 0.5;
this.element   = $(element);
this.callback  = callback;
this.timer     = null;
this.lastValue = $F(this.element);
Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this));
},
delayedListener: function(event) {
if(this.lastValue == $F(this.element)) return;
if(this.timer) clearTimeout(this.timer);
this.timer = setTimeout(this.onTimerEvent.bind(this), this.delay * 1000);
this.lastValue = $F(this.element);
},
onTimerEvent: function() {
this.timer = null;
this.callback(this.element, $F(this.element));
}
};











































var domLib_userAgent = navigator.userAgent.toLowerCase();
var domLib_isMac = navigator.appVersion.indexOf('Mac') != -1;
var domLib_isWin = domLib_userAgent.indexOf('windows') != -1;

var domLib_isOpera = domLib_userAgent.indexOf('opera') != -1;
var domLib_isOpera7up = domLib_userAgent.match(/opera.(7|8)/i);
var domLib_isSafari = domLib_userAgent.indexOf('safari') != -1;
var domLib_isKonq = domLib_userAgent.indexOf('konqueror') != -1;

var domLib_isKHTML = (domLib_isKonq || domLib_isSafari || domLib_userAgent.indexOf('khtml') != -1);
var domLib_isIE = (!domLib_isKHTML && !domLib_isOpera && (domLib_userAgent.indexOf('msie 5') != -1 || domLib_userAgent.indexOf('msie 6') != -1 || domLib_userAgent.indexOf('msie 7') != -1));
var domLib_isIE5up = domLib_isIE;
var domLib_isIE50 = (domLib_isIE && domLib_userAgent.indexOf('msie 5.0') != -1);
var domLib_isIE55 = (domLib_isIE && domLib_userAgent.indexOf('msie 5.5') != -1);
var domLib_isIE5 = (domLib_isIE50 || domLib_isIE55);

var domLib_isGecko = domLib_userAgent.indexOf('gecko/') != -1;
var domLib_isMacIE = (domLib_isIE && domLib_isMac);
var domLib_isIE55up = domLib_isIE5up && !domLib_isIE50 && !domLib_isMacIE;
var domLib_isIE6up = domLib_isIE55up && !domLib_isIE55;


var domLib_standardsMode = (document.compatMode && document.compatMode == 'CSS1Compat');
var domLib_useLibrary = (domLib_isOpera7up || domLib_isKHTML || domLib_isIE5up || domLib_isGecko || domLib_isMacIE || document.defaultView);

var domLib_hasBrokenTimeout = (domLib_isMacIE || (domLib_isKonq && domLib_userAgent.match(/konqueror\/3.([2-9])/) == null));
var domLib_canFade = (domLib_isGecko || domLib_isIE || domLib_isSafari || domLib_isOpera);
var domLib_canDrawOverSelect = (domLib_isMac || domLib_isOpera || domLib_isGecko);
var domLib_canDrawOverFlash = (domLib_isMac || domLib_isWin);


var domLib_eventTarget = domLib_isIE ? 'srcElement' : 'currentTarget';
var domLib_eventButton = domLib_isIE ? 'button' : 'which';
var domLib_eventTo = domLib_isIE ? 'toElement' : 'relatedTarget';
var domLib_stylePointer = domLib_isIE ? 'hand' : 'pointer';

var domLib_styleNoMaxWidth = domLib_isOpera ? '10000px' : 'none';
var domLib_hidePosition = '-1000px';
var domLib_scrollbarWidth = 14;
var domLib_autoId = 1;
var domLib_zIndex = 100;


var domLib_collisionElements;
var domLib_collisionsCached = false;

var domLib_timeoutStateId = 0;
var domLib_timeoutStates = new DomLibHash();




if (!document.ELEMENT_NODE)
{
document.ELEMENT_NODE = 1;
document.ATTRIBUTE_NODE = 2;
document.TEXT_NODE = 3;
document.DOCUMENT_NODE = 9;
document.DOCUMENT_FRAGMENT_NODE = 11;
}

function domLib_clone(obj)
{
var copy = {};
for (var i in obj)
{
var value = obj[i];
try
{
if (value != null && typeof(value) == 'object' && value != window && !value.nodeType)
{
copy[i] = domLib_clone(value);
}
else
{
copy[i] = value;
}
}
catch(e)
{
copy[i] = value;
}
}

return copy;
}




function DomLibHash()
{
this.length = 0;
this.numericLength = 0;
this.elementData = [];
for (var i = 0; i < arguments.length; i += 2)
{
if (typeof(arguments[i + 1]) != 'undefined')
{
this.elementData[arguments[i]] = arguments[i + 1];
this.length++;
if (arguments[i] == parseInt(arguments[i]))
{
this.numericLength++;
}
}
}
}


DomLibHash.prototype.get = function(in_key)
{
if (typeof(this.elementData[in_key]) != 'undefined') {
return this.elementData[in_key];
}

return null;
}

DomLibHash.prototype.set = function(in_key, in_value)
{
if (typeof(in_value) != 'undefined')
{
if (typeof(this.elementData[in_key]) == 'undefined')
{
this.length++;
if (in_key == parseInt(in_key))
{
this.numericLength++;
}
}

return this.elementData[in_key] = in_value;
}

return false;
}

DomLibHash.prototype.remove = function(in_key)
{
var tmp_value;
if (typeof(this.elementData[in_key]) != 'undefined')
{
this.length--;
if (in_key == parseInt(in_key))
{
this.numericLength--;
}

tmp_value = this.elementData[in_key];
delete this.elementData[in_key];
}

return tmp_value;
}

DomLibHash.prototype.size = function()
{
return this.length;
}

DomLibHash.prototype.has = function(in_key)
{
return typeof(this.elementData[in_key]) != 'undefined';
}

DomLibHash.prototype.find = function(in_obj)
{
for (var tmp_key in this.elementData)
{
if (this.elementData[tmp_key] == in_obj)
{
return tmp_key;
}
}

return null;
}

DomLibHash.prototype.merge = function(in_hash)
{
for (var tmp_key in in_hash.elementData)
{
if (typeof(this.elementData[tmp_key]) == 'undefined')
{
this.length++;
if (tmp_key == parseInt(tmp_key))
{
this.numericLength++;
}
}

this.elementData[tmp_key] = in_hash.elementData[tmp_key];
}
}

DomLibHash.prototype.compare = function(in_hash)
{
if (this.length != in_hash.length)
{
return false;
}

for (var tmp_key in this.elementData)
{
if (this.elementData[tmp_key] != in_hash.elementData[tmp_key])
{
return false;
}
}

return true;
}




function domLib_isDescendantOf(in_object, in_ancestor, in_bannedTags)
{
if (in_object == null)
{
return false;
}

if (in_object == in_ancestor)
{
return true;
}

if (typeof(in_bannedTags) != 'undefined' &&
(',' + in_bannedTags.join(',') + ',').indexOf(',' + in_object.tagName + ',') != -1)
{
return false;
}

while (in_object != document.documentElement)
{
try
{
if ((tmp_object = in_object.offsetParent) && tmp_object == in_ancestor)
{
return true;
}
else if ((tmp_object = in_object.parentNode) == in_ancestor)
{
return true;
}
else
{
in_object = tmp_object;
}
}

catch(e)
{
return false;
}
}

return false;
}








function domLib_detectCollisions(in_object, in_recover, in_useCache)
{




if (!domLib_collisionsCached)
{
var tags = [];

if (!domLib_canDrawOverFlash)
{
tags[tags.length] = 'object';
}

if (!domLib_canDrawOverSelect)
{
tags[tags.length] = 'select';
}

domLib_collisionElements = domLib_getElementsByTagNames(tags, true);
domLib_collisionsCached = in_useCache;
}


if (in_recover)
{
for (var cnt = 0; cnt < domLib_collisionElements.length; cnt++)
{
var thisElement = domLib_collisionElements[cnt];

if (!thisElement.hideList)
{
thisElement.hideList = new DomLibHash();
}

thisElement.hideList.remove(in_object.id);
if (!thisElement.hideList.length)
{
domLib_collisionElements[cnt].style.visibility = 'visible';
if (domLib_isKonq)
{
domLib_collisionElements[cnt].style.display = '';
}
}
}

return;
}
else if (domLib_collisionElements.length == 0)
{
return;
}


var objectOffsets = domLib_getOffsets(in_object);

for (var cnt = 0; cnt < domLib_collisionElements.length; cnt++)
{
var thisElement = domLib_collisionElements[cnt];



if (domLib_isDescendantOf(thisElement, in_object))
{
continue;
}


if (domLib_isKonq &&
thisElement.tagName == 'SELECT' &&
(thisElement.size <= 1 && !thisElement.multiple))
{
continue;
}

if (!thisElement.hideList)
{
thisElement.hideList = new DomLibHash();
}

var selectOffsets = domLib_getOffsets(thisElement);
var center2centerDistance = Math.sqrt(Math.pow(selectOffsets.get('leftCenter') - objectOffsets.get('leftCenter'), 2) + Math.pow(selectOffsets.get('topCenter') - objectOffsets.get('topCenter'), 2));
var radiusSum = selectOffsets.get('radius') + objectOffsets.get('radius');

if (center2centerDistance < radiusSum)
{

if ((objectOffsets.get('leftCenter') <= selectOffsets.get('leftCenter') && objectOffsets.get('right') < selectOffsets.get('left')) ||

(objectOffsets.get('leftCenter') > selectOffsets.get('leftCenter') && objectOffsets.get('left') > selectOffsets.get('right')) ||

(objectOffsets.get('topCenter') <= selectOffsets.get('topCenter') && objectOffsets.get('bottom') < selectOffsets.get('top')) ||

(objectOffsets.get('topCenter') > selectOffsets.get('topCenter') && objectOffsets.get('top') > selectOffsets.get('bottom')))
{
thisElement.hideList.remove(in_object.id);
if (!thisElement.hideList.length)
{
thisElement.style.visibility = 'visible';
if (domLib_isKonq)
{
thisElement.style.display = '';
}
}
}
else
{
thisElement.hideList.set(in_object.id, true);
thisElement.style.visibility = 'hidden';
if (domLib_isKonq)
{
thisElement.style.display = 'none';
}
}
}
}
}




function domLib_getOffsets(in_object, in_preserveScroll)
{
if (typeof(in_preserveScroll) == 'undefined') {
in_preserveScroll = false;
}

var originalObject = in_object;
var originalWidth = in_object.offsetWidth;
var originalHeight = in_object.offsetHeight;
var offsetLeft = 0;
var offsetTop = 0;

while (in_object)
{
offsetLeft += in_object.offsetLeft;
offsetTop += in_object.offsetTop;
in_object = in_object.offsetParent;

if (in_object && !in_preserveScroll)
{
offsetLeft -= in_object.scrollLeft;
offsetTop -= in_object.scrollTop;
}
}


if (domLib_isMacIE) {
offsetLeft += 10;
offsetTop += 10;
}

return new DomLibHash(
'left',		offsetLeft,
'top',		offsetTop,
'right',	offsetLeft + originalWidth,
'bottom',	offsetTop + originalHeight,
'leftCenter',	offsetLeft + originalWidth/2,
'topCenter',	offsetTop + originalHeight/2,
'radius',	Math.max(originalWidth, originalHeight)
);
}




function domLib_setTimeout(in_function, in_timeout, in_args)
{
if (typeof(in_args) == 'undefined')
{
in_args = [];
}

if (in_timeout == -1)
{

return 0;
}
else if (in_timeout == 0)
{
in_function(in_args);
return 0;
}


var args = domLib_clone(in_args);

if (!domLib_hasBrokenTimeout)
{
return setTimeout(function() { in_function(args); }, in_timeout);
}
else
{
var id = domLib_timeoutStateId++;
var data = new DomLibHash();
data.set('function', in_function);
data.set('args', args);
domLib_timeoutStates.set(id, data);

data.set('timeoutId', setTimeout('domLib_timeoutStates.get(' + id + ').get(\'function\')(domLib_timeoutStates.get(' + id + ').get(\'args\')); domLib_timeoutStates.remove(' + id + ');', in_timeout));
return id;
}
}




function domLib_clearTimeout(in_id)
{
if (!domLib_hasBrokenTimeout)
{
if (in_id > 0) {
clearTimeout(in_id);
}
}
else
{
if (domLib_timeoutStates.has(in_id))
{
clearTimeout(domLib_timeoutStates.get(in_id).get('timeoutId'))
domLib_timeoutStates.remove(in_id);
}
}
}




function domLib_getEventPosition(in_eventObj)
{
var eventPosition = new DomLibHash('x', 0, 'y', 0, 'scrollX', 0, 'scrollY', 0);


if (domLib_isIE)
{
var doc = (domLib_standardsMode ? document.documentElement : document.body);

if (doc)
{
eventPosition.set('x', in_eventObj.clientX + doc.scrollLeft);
eventPosition.set('y', in_eventObj.clientY + doc.scrollTop);
eventPosition.set('scrollX', doc.scrollLeft);
eventPosition.set('scrollY', doc.scrollTop);
}
}
else
{
eventPosition.set('x', in_eventObj.pageX);
eventPosition.set('y', in_eventObj.pageY);
eventPosition.set('scrollX', in_eventObj.pageX - in_eventObj.clientX);
eventPosition.set('scrollY', in_eventObj.pageY - in_eventObj.clientY);
}

return eventPosition;
}




function domLib_cancelBubble(in_event)
{
var eventObj = in_event ? in_event : window.event;
eventObj.cancelBubble = true;
}




function domLib_getIFrameReference(in_frame)
{
if (domLib_isGecko || domLib_isIE)
{
return in_frame.frameElement;
}
else
{


var name = in_frame.name;
if (!name || !in_frame.parent)
{
return null;
}

var candidates = in_frame.parent.document.getElementsByTagName('iframe');
for (var i = 0; i < candidates.length; i++)
{
if (candidates[i].name == name)
{
return candidates[i];
}
}

return null;
}
}




function domLib_getElementsByClass(in_class)
{
var elements = domLib_isIE5 ? document.all : document.getElementsByTagName('*');
var matches = [];
var cnt = 0;
for (var i = 0; i < elements.length; i++)
{
if ((" " + elements[i].className + " ").indexOf(" " + in_class + " ") != -1)
{
matches[cnt++] = elements[i];
}
}

return matches;
}




function domLib_getElementsByTagNames(in_list, in_excludeHidden)
{
var elements = [];
for (var i = 0; i < in_list.length; i++)
{
var matches = document.getElementsByTagName(in_list[i]);
for (var j = 0; j < matches.length; j++)
{

if (matches[j].tagName == 'OBJECT' && domLib_isGecko)
{
var kids = matches[j].childNodes;
var skip = false;
for (var k = 0; k < kids.length; k++)
{
if (kids[k].tagName == 'EMBED')
{
skip = true;
break;
}
}
if (skip) continue;
}

if (in_excludeHidden && domLib_getComputedStyle(matches[j], 'visibility') == 'hidden')
{
continue;
}

elements[elements.length] = matches[j];
}
}

return elements;
}




function domLib_getComputedStyle(in_obj, in_property)
{
if (domLib_isIE)
{
var humpBackProp = in_property.replace(/-(.)/, function (a, b) { return b.toUpperCase(); });
return eval('in_obj.currentStyle.' + humpBackProp);
}

else if (domLib_isKonq)
{

return eval('in_obj.style.' + in_property);
}
else
{
return document.defaultView.getComputedStyle(in_obj, null).getPropertyValue(in_property);
}
}




function makeTrue()
{
return true;
}




function makeFalse()
{
return false;
}





































































var domTT_offsetX = (domLib_isIE ? -2 : 0);
var domTT_offsetY = (domLib_isIE ? 4 : 2);
var domTT_direction = 'southeast';
var domTT_mouseHeight = domLib_isIE ? 13 : 19;
var domTT_closeLink = 'X';
var domTT_closeAction = 'hide';
var domTT_activateDelay = 500;
var domTT_maxWidth = false;
var domTT_styleClass = 'domTT';
var domTT_fade = 'neither';
var domTT_lifetime = 0;
var domTT_grid = 0;
var domTT_trailDelay = 200;
var domTT_useGlobalMousePosition = true;
var domTT_postponeActivation = false;
var domTT_tooltipIdPrefix = '[domTT]';
var domTT_screenEdgeDetection = true;
var domTT_screenEdgePadding = 4;
var domTT_oneOnly = false;
var domTT_cloneNodes = false;
var domTT_detectCollisions = true;
var domTT_bannedTags = ['OPTION'];
var domTT_draggable = false;
if (typeof(domTT_dragEnabled) == 'undefined')
{
domTT_dragEnabled = false;
}




var domTT_predefined = new DomLibHash();


var domTT_tooltips = new DomLibHash();
var domTT_lastOpened = 0;
var domTT_documentLoaded = false;
var domTT_mousePosition = null;




if (domLib_useLibrary && domTT_useGlobalMousePosition)
{
document.onmousemove = function(in_event)
{
if (typeof(in_event) == 'undefined') { in_event = window.event; }

domTT_mousePosition = domLib_getEventPosition(in_event);
if (domTT_dragEnabled && domTT_dragMouseDown)
{
domTT_dragUpdate(in_event);
}
}
}




function domTT_activate(in_this, in_event)
{
if (!domLib_useLibrary || (domTT_postponeActivation && !domTT_documentLoaded)) { return false; }


if (typeof(in_event) == 'undefined') { in_event = window.event;	}


if (in_event != null) {
var target = in_event.srcElement ? in_event.srcElement : in_event.target;
if (target != null && (',' + domTT_bannedTags.join(',') + ',').indexOf(',' + target.tagName + ',') != -1)
{
return false;
}
}

var owner = document.body;

if (in_event != null && in_event.type.match(/key|mouse|click|contextmenu/i))
{

if (in_this.nodeType && in_this.nodeType != document.DOCUMENT_NODE)
{
owner = in_this;
}
}

else
{
if (typeof(in_this) != 'object' && !(owner = domTT_tooltips.get(in_this)))
{

var embryo = document.createElement('div');
owner = document.body.appendChild(embryo);
owner.style.display = 'none';
owner.id = in_this;
}
}


if (!owner.id)
{
owner.id = '__autoId' + domLib_autoId++;
}




if (domTT_oneOnly && domTT_lastOpened)
{
domTT_deactivate(domTT_lastOpened);
}

domTT_lastOpened = owner.id;

var tooltip = domTT_tooltips.get(owner.id);
if (tooltip)
{
if (tooltip.get('eventType') != in_event.type)
{
if (tooltip.get('type') == 'greasy')
{
tooltip.set('closeAction', 'destroy');
domTT_deactivate(owner.id);
}
else if (tooltip.get('status') != 'inactive')
{
return owner.id;
}
}
else
{
if (tooltip.get('status') == 'inactive')
{
tooltip.set('status', 'pending');
tooltip.set('activateTimeout', domLib_setTimeout(domTT_runShow, tooltip.get('delay'), [owner.id, in_event]));

return owner.id;
}

else
{
return owner.id;
}
}
}


var options = new DomLibHash(
'caption',		'',
'content',		'',
'clearMouse',	true,
'closeAction',	domTT_closeAction,
'closeLink',	domTT_closeLink,
'delay',		domTT_activateDelay,
'direction',	domTT_direction,
'draggable',	domTT_draggable,
'fade',			domTT_fade,
'fadeMax',		100,
'grid',			domTT_grid,
'id',			domTT_tooltipIdPrefix + owner.id,
'inframe',		false,
'lifetime',		domTT_lifetime,
'offsetX',		domTT_offsetX,
'offsetY',		domTT_offsetY,
'parent',		document.body,
'position',		'absolute',
'styleClass',	domTT_styleClass,
'type',			'greasy',
'trail',		false,
'lazy',			false
);


for (var i = 2; i < arguments.length; i += 2)
{

if (arguments[i] == 'predefined')
{
var predefinedOptions = domTT_predefined.get(arguments[i + 1]);
for (var j in predefinedOptions.elementData)
{
options.set(j, predefinedOptions.get(j));
}
}

else
{
options.set(arguments[i], arguments[i + 1]);
}
}

options.set('eventType', in_event != null ? in_event.type : null);


if (options.has('statusText'))
{
try { window.status = options.get('statusText'); } catch(e) {}
}


if (!options.has('content') || options.get('content') == '' || options.get('content') == null)
{
if (typeof(owner.onmouseout) != 'function')
{
owner.onmouseout = function(in_event) { domTT_mouseout(this, in_event); };
}

return owner.id;
}

options.set('owner', owner);

domTT_create(options);


options.set('delay', (in_event != null && in_event.type.match(/click|mousedown|contextmenu/i)) ? 0 : parseInt(options.get('delay')));
domTT_tooltips.set(owner.id, options);
domTT_tooltips.set(options.get('id'), options);
options.set('status', 'pending');
options.set('activateTimeout', domLib_setTimeout(domTT_runShow, options.get('delay'), [owner.id, in_event]));

return owner.id;
}




function domTT_create(in_options)
{
var tipOwner = in_options.get('owner');
var parentObj = in_options.get('parent');
var parentDoc = parentObj.ownerDocument || parentObj.document;



var embryo = parentDoc.createElement('div');
var tipObj = parentObj.appendChild(embryo);
tipObj.style.position = 'absolute';
tipObj.style.left = '0px';
tipObj.style.top = '0px';
tipObj.style.visibility = 'hidden';
tipObj.id = in_options.get('id');
tipObj.className = in_options.get('styleClass');

var contentBlock;
var tableLayout = false;

if (in_options.get('caption') || (in_options.get('type') == 'sticky' && in_options.get('caption') !== false))
{
tableLayout = true;

var tipLayoutTable = tipObj.appendChild(parentDoc.createElement('table'));
tipLayoutTable.style.borderCollapse = 'collapse';
if (domLib_isKHTML)
{
tipLayoutTable.cellSpacing = 0;
}

var tipLayoutTbody = tipLayoutTable.appendChild(parentDoc.createElement('tbody'));

var numCaptionCells = 0;
var captionRow = tipLayoutTbody.appendChild(parentDoc.createElement('tr'));
var captionCell = captionRow.appendChild(parentDoc.createElement('td'));
captionCell.style.padding = '0px';
var caption = captionCell.appendChild(parentDoc.createElement('div'));
caption.className = 'caption';
if (domLib_isIE50)
{
caption.style.height = '100%';
}

if (in_options.get('caption').nodeType)
{
caption.appendChild(domTT_cloneNodes ? in_options.get('caption').cloneNode(1) : in_options.get('caption'));
}
else
{
caption.innerHTML = in_options.get('caption');
}

if (in_options.get('type') == 'sticky')
{
var numCaptionCells = 2;
var closeLinkCell = captionRow.appendChild(parentDoc.createElement('td'));
closeLinkCell.style.padding = '0px';
var closeLink = closeLinkCell.appendChild(parentDoc.createElement('div'));
closeLink.className = 'caption';
if (domLib_isIE50)
{
closeLink.style.height = '100%';
}

closeLink.style.textAlign = 'right';
closeLink.style.cursor = domLib_stylePointer;

closeLink.style.borderLeftWidth = caption.style.borderRightWidth = '0px';
closeLink.style.paddingLeft = caption.style.paddingRight = '0px';
closeLink.style.marginLeft = caption.style.marginRight = '0px';
if (in_options.get('closeLink').nodeType)
{
closeLink.appendChild(in_options.get('closeLink').cloneNode(1));
}
else
{
closeLink.innerHTML = in_options.get('closeLink');
}

closeLink.onclick = function()
{
domTT_deactivate(tipOwner.id);
};
closeLink.onmousedown = function(in_event)
{
if (typeof(in_event) == 'undefined') { in_event = window.event; }
in_event.cancelBubble = true;
};

if (domLib_isMacIE)
{
closeLinkCell.appendChild(parentDoc.createTextNode("\n"));
}
}


if (domLib_isMacIE)
{
captionCell.appendChild(parentDoc.createTextNode("\n"));
}

var contentRow = tipLayoutTbody.appendChild(parentDoc.createElement('tr'));
var contentCell = contentRow.appendChild(parentDoc.createElement('td'));
contentCell.style.padding = '0px';
if (numCaptionCells)
{
if (domLib_isIE || domLib_isOpera)
{
contentCell.colSpan = numCaptionCells;
}
else
{
contentCell.setAttribute('colspan', numCaptionCells);
}
}

contentBlock = contentCell.appendChild(parentDoc.createElement('div'));
if (domLib_isIE50)
{
contentBlock.style.height = '100%';
}
}
else
{
contentBlock = tipObj.appendChild(parentDoc.createElement('div'));
}

contentBlock.className = 'contents';

var content = in_options.get('content');

if (typeof(content) == 'function') {
content = content(in_options.get('id'));
}

if (content != null && content.nodeType)
{
contentBlock.appendChild(domTT_cloneNodes ? content.cloneNode(1) : content);
}
else
{
contentBlock.innerHTML = content;
}


if (in_options.has('width'))
{
tipObj.style.width = parseInt(in_options.get('width')) + 'px';
}



var maxWidth = domTT_maxWidth;
if (in_options.has('maxWidth'))
{
if ((maxWidth = in_options.get('maxWidth')) === false)
{
tipObj.style.maxWidth = domLib_styleNoMaxWidth;
}
else
{
maxWidth = parseInt(in_options.get('maxWidth'));
tipObj.style.maxWidth = maxWidth + 'px';
}
}


if (maxWidth !== false && (domLib_isIE || domLib_isKHTML) && tipObj.offsetWidth > maxWidth)
{
tipObj.style.width = maxWidth + 'px';
}

in_options.set('offsetWidth', tipObj.offsetWidth);
in_options.set('offsetHeight', tipObj.offsetHeight);



if (domLib_isKonq && tableLayout && !tipObj.style.width)
{
var left = document.defaultView.getComputedStyle(tipObj, '').getPropertyValue('border-left-width');
var right = document.defaultView.getComputedStyle(tipObj, '').getPropertyValue('border-right-width');

left = left.substring(left.indexOf(':') + 2, left.indexOf(';'));
right = right.substring(right.indexOf(':') + 2, right.indexOf(';'));
var correction = 2 * ((left ? parseInt(left) : 0) + (right ? parseInt(right) : 0));
tipObj.style.width = (tipObj.offsetWidth - correction) + 'px';
}



if (domLib_isIE || domLib_isOpera)
{
if (!tipObj.style.width)
{

tipObj.style.width = (tipObj.offsetWidth - 2) + 'px';
}


tipObj.style.height = (tipObj.offsetHeight - 2) + 'px';
}


var offsetX, offsetY;


if (in_options.get('position') == 'absolute' && !(in_options.has('x') && in_options.has('y')))
{

switch (in_options.get('direction'))
{
case 'northeast':
offsetX = in_options.get('offsetX');
offsetY = 0 - tipObj.offsetHeight - in_options.get('offsetY');
break;
case 'northwest':
offsetX = 0 - tipObj.offsetWidth - in_options.get('offsetX');
offsetY = 0 - tipObj.offsetHeight - in_options.get('offsetY');
break;
case 'north':
offsetX = 0 - parseInt(tipObj.offsetWidth/2);
offsetY = 0 - tipObj.offsetHeight - in_options.get('offsetY');
break;
case 'southwest':
offsetX = 0 - tipObj.offsetWidth - in_options.get('offsetX');
offsetY = in_options.get('offsetY');
break;
case 'southeast':
offsetX = in_options.get('offsetX');
offsetY = in_options.get('offsetY');
break;
case 'south':
offsetX = 0 - parseInt(tipObj.offsetWidth/2);
offsetY = in_options.get('offsetY');
break;
}


if (in_options.get('inframe'))
{
var iframeObj = domLib_getIFrameReference(window);
if (iframeObj)
{
var frameOffsets = domLib_getOffsets(iframeObj);
offsetX += frameOffsets.get('left');
offsetY += frameOffsets.get('top');
}
}
}

else
{
offsetX = 0;
offsetY = 0;
in_options.set('trail', false);
}


in_options.set('offsetX', offsetX);
in_options.set('offsetY', offsetY);
if (in_options.get('clearMouse') && in_options.get('direction').indexOf('south') != -1)
{
in_options.set('mouseOffset', domTT_mouseHeight);
}
else
{
in_options.set('mouseOffset', 0);
}

if (domLib_canFade && typeof(Fadomatic) == 'function')
{
if (in_options.get('fade') != 'neither')
{
var fadeHandler = new Fadomatic(tipObj, 10, 0, 0, in_options.get('fadeMax'));
in_options.set('fadeHandler', fadeHandler);
}
}
else
{
in_options.set('fade', 'neither');
}


if (in_options.get('trail') && typeof(tipOwner.onmousemove) != 'function')
{
tipOwner.onmousemove = function(in_event) { domTT_mousemove(this, in_event); };
}

if (typeof(tipOwner.onmouseout) != 'function')
{
tipOwner.onmouseout = function(in_event) { domTT_mouseout(this, in_event); };
}

if (in_options.get('type') == 'sticky')
{
if (in_options.get('position') == 'absolute' && domTT_dragEnabled && in_options.get('draggable'))
{
if (domLib_isIE)
{
captionRow.onselectstart = function() { return false; };
}


captionRow.onmousedown = function(in_event) { domTT_dragStart(tipObj, in_event);  };
captionRow.onmousemove = function(in_event) { domTT_dragUpdate(in_event); };
captionRow.onmouseup = function() { domTT_dragStop(); };
}
}
else if (in_options.get('type') == 'velcro')
{










tipObj.onmouseout = function(in_event)
{
if (typeof(in_event) == 'undefined') { in_event = window.event; }
if (!domLib_isDescendantOf(in_event[domLib_eventTo], tipObj, domTT_bannedTags)) {
domTT_deactivate(tipOwner.id);
}
};

tipObj.onclick = function(in_event)
{
domTT_deactivate(tipOwner.id);
};
}

if (in_options.get('position') == 'relative')
{
tipObj.style.position = 'relative';
}

in_options.set('node', tipObj);
in_options.set('status', 'inactive');
}





function domTT_show(in_id, in_event)
{


var tooltip = domTT_tooltips.get(in_id);
var status = tooltip.get('status');
var tipObj = tooltip.get('node');

if (tooltip.get('position') == 'absolute')
{
var mouseX, mouseY;

if (tooltip.has('x') && tooltip.has('y'))
{
mouseX = tooltip.get('x');
mouseY = tooltip.get('y');
}
else if (!domTT_useGlobalMousePosition || domTT_mousePosition == null || status == 'active' || tooltip.get('delay') == 0)
{
var eventPosition = domLib_getEventPosition(in_event);
var eventX = eventPosition.get('x');
var eventY = eventPosition.get('y');
if (tooltip.get('inframe'))
{
eventX -= eventPosition.get('scrollX');
eventY -= eventPosition.get('scrollY');
}


if (status == 'active' && tooltip.get('trail') !== true)
{
var trail = tooltip.get('trail');
if (trail == 'x')
{
mouseX = eventX;
mouseY = tooltip.get('mouseY');
}
else if (trail == 'y')
{
mouseX = tooltip.get('mouseX');
mouseY = eventY;
}
}
else
{
mouseX = eventX;
mouseY = eventY;
}
}
else
{
mouseX = domTT_mousePosition.get('x');
mouseY = domTT_mousePosition.get('y');
if (tooltip.get('inframe'))
{
mouseX -= domTT_mousePosition.get('scrollX');
mouseY -= domTT_mousePosition.get('scrollY');
}
}


if (tooltip.get('grid'))
{


if (in_event.type != 'mousemove' || (status == 'active' && (Math.abs(tooltip.get('lastX') - mouseX) > tooltip.get('grid') || Math.abs(tooltip.get('lastY') - mouseY) > tooltip.get('grid'))))
{
tooltip.set('lastX', mouseX);
tooltip.set('lastY', mouseY);
}

else
{
return false;
}
}



tooltip.set('mouseX', mouseX);
tooltip.set('mouseY', mouseY);

var coordinates;
if (domTT_screenEdgeDetection)
{
coordinates = domTT_correctEdgeBleed(
tooltip.get('offsetWidth'),
tooltip.get('offsetHeight'),
mouseX,
mouseY,
tooltip.get('offsetX'),
tooltip.get('offsetY'),
tooltip.get('mouseOffset'),
tooltip.get('inframe') ? window.parent : window
);
}
else
{
coordinates = {
'x' : mouseX + tooltip.get('offsetX'),
'y' : mouseY + tooltip.get('offsetY') + tooltip.get('mouseOffset')
};
}


tipObj.style.left = coordinates.x + 'px';
tipObj.style.top = coordinates.y + 'px';


tipObj.style.zIndex = domLib_zIndex++;
}


if (status == 'pending')
{

tooltip.set('status', 'active');
tipObj.style.display = '';
tipObj.style.visibility = 'visible';

var fade = tooltip.get('fade');
if (fade != 'neither')
{
var fadeHandler = tooltip.get('fadeHandler');
if (fade == 'out' || fade == 'both')
{
fadeHandler.haltFade();
if (fade == 'out')
{
fadeHandler.halt();
}
}

if (fade == 'in' || fade == 'both')
{
fadeHandler.fadeIn();
}
}

if (tooltip.get('type') == 'greasy' && tooltip.get('lifetime') != 0)
{
tooltip.set('lifetimeTimeout', domLib_setTimeout(domTT_runDeactivate, tooltip.get('lifetime'), [tipObj.id]));
}
}

if (tooltip.get('position') == 'absolute' && domTT_detectCollisions)
{

domLib_detectCollisions(tipObj, false, true);
}
}





function domTT_close(in_handle)
{
var id;
if (typeof(in_handle) == 'object' && in_handle.nodeType)
{
var obj = in_handle;
while (!obj.id || !domTT_tooltips.get(obj.id))
{
obj = obj.parentNode;

if (obj.nodeType != document.ELEMENT_NODE) { return; }
}

id = obj.id;
}
else
{
id = in_handle;
}

domTT_deactivate(id);
}





function domTT_closeAll()
{

for (var id in domTT_tooltips.elementData) {
domTT_close(id);
}
}





function domTT_deactivate(in_id)
{
var tooltip = domTT_tooltips.get(in_id);
if (tooltip)
{
var status = tooltip.get('status');
if (status == 'pending')
{

domLib_clearTimeout(tooltip.get('activateTimeout'));
tooltip.set('status', 'inactive');
}
else if (status == 'active')
{
if (tooltip.get('lifetime'))
{
domLib_clearTimeout(tooltip.get('lifetimeTimeout'));
}

var tipObj = tooltip.get('node');
if (tooltip.get('closeAction') == 'hide')
{
var fade = tooltip.get('fade');
if (fade != 'neither')
{
var fadeHandler = tooltip.get('fadeHandler');
if (fade == 'out' || fade == 'both')
{
fadeHandler.fadeOut();
}
else
{
fadeHandler.hide();
}
}
else
{
tipObj.style.display = 'none';
}
}
else
{
tooltip.get('parent').removeChild(tipObj);
domTT_tooltips.remove(tooltip.get('owner').id);
domTT_tooltips.remove(tooltip.get('id'));
}

tooltip.set('status', 'inactive');
if (domTT_detectCollisions) {


domLib_detectCollisions(tipObj, true, true);
}
}
}
}




function domTT_mouseout(in_owner, in_event)
{
if (!domLib_useLibrary) { return false; }

if (typeof(in_event) == 'undefined') { in_event = window.event;	}

var toChild = domLib_isDescendantOf(in_event[domLib_eventTo], in_owner, domTT_bannedTags);
var tooltip = domTT_tooltips.get(in_owner.id);
if (tooltip && (tooltip.get('type') == 'greasy' || tooltip.get('status') != 'active'))
{

if (!toChild)
{
domTT_deactivate(in_owner.id);
try { window.status = window.defaultStatus; } catch(e) {}
}
}
else if (!toChild)
{
try { window.status = window.defaultStatus; } catch(e) {}
}
}




function domTT_mousemove(in_owner, in_event)
{
if (!domLib_useLibrary) { return false; }

if (typeof(in_event) == 'undefined') { in_event = window.event;	}

var tooltip = domTT_tooltips.get(in_owner.id);
if (tooltip && tooltip.get('trail') && tooltip.get('status') == 'active')
{

if (tooltip.get('lazy'))
{
domLib_setTimeout(domTT_runShow, domTT_trailDelay, [in_owner.id, in_event]);
}
else
{
domTT_show(in_owner.id, in_event);
}
}
}




function domTT_addPredefined(in_id)
{
var options = new DomLibHash();
for (var i = 1; i < arguments.length; i += 2)
{
options.set(arguments[i], arguments[i + 1]);
}

domTT_predefined.set(in_id, options);
}




function domTT_correctEdgeBleed(in_width, in_height, in_x, in_y, in_offsetX, in_offsetY, in_mouseOffset, in_window)
{
var win, doc;
var bleedRight, bleedBottom;
var pageHeight, pageWidth, pageYOffset, pageXOffset;

var x = in_x + in_offsetX;
var y = in_y + in_offsetY + in_mouseOffset;

win = (typeof(in_window) == 'undefined' ? window : in_window);



doc = ((domLib_standardsMode && (domLib_isIE || domLib_isGecko)) ? win.document.documentElement : win.document.body);


if (domLib_isIE)
{
pageHeight = doc.clientHeight;
pageWidth = doc.clientWidth;
pageYOffset = doc.scrollTop;
pageXOffset = doc.scrollLeft;
}
else
{
pageHeight = doc.clientHeight;
pageWidth = doc.clientWidth;

if (domLib_isKHTML)
{
pageHeight = win.innerHeight;
}

pageYOffset = win.pageYOffset;
pageXOffset = win.pageXOffset;
}



if ((bleedRight = (x - pageXOffset) + in_width - (pageWidth - domTT_screenEdgePadding)) > 0)
{
x -= bleedRight;
}




if ((x - pageXOffset) < domTT_screenEdgePadding)
{
x = domTT_screenEdgePadding + pageXOffset;
}



if ((bleedBottom = (y - pageYOffset) + in_height - (pageHeight - domTT_screenEdgePadding)) > 0)
{
y = in_y - in_height - in_offsetY;
}




if ((y - pageYOffset) < domTT_screenEdgePadding)
{
y = in_y + domTT_mouseHeight + in_offsetY;
}

return {'x' : x, 'y' : y};
}





function domTT_isActive(in_id)
{
var tooltip = domTT_tooltips.get(in_id);
if (!tooltip || tooltip.get('status') != 'active')
{
return false;
}
else
{
return true;
}
}






function domTT_runDeactivate(args) { domTT_deactivate(args[0]); }
function domTT_runShow(args) { domTT_show(args[0], args[1]); }




function domTT_replaceTitles(in_decorator)
{
var elements = domLib_getElementsByClass('tooltip');
for (var i = 0; i < elements.length; i++)
{
if (elements[i].title)
{
var content;
if (typeof(in_decorator) == 'function')
{
content = in_decorator(elements[i]);
}
else
{
content = elements[i].title;
}

content = content.replace(new RegExp('\'', 'g'), '\\\'');
elements[i].onmouseover = new Function('in_event', "domTT_activate(this, in_event, 'content', '" + content + "')");
elements[i].title = '';
}
}
}







function domTT_update(handle, content, type)
{

if (typeof(type) == 'undefined')
{
type = 'content';
}

var tip = domTT_tooltips.get(handle);
if (!tip)
{
return;
}

var tipObj = tip.get('node');
var updateNode;
if (type == 'content')
{

updateNode = tipObj.firstChild;
if (updateNode.className != 'contents')
{

updateNode = updateNode.firstChild.firstChild.nextSibling.firstChild.firstChild;
}
}
else
{
updateNode = tipObj.firstChild;
if (updateNode.className == 'contents')
{

return;
}


updateNode = updateNode.firstChild.firstChild.firstChild.firstChild;
}


updateNode.innerHTML = content;
}











































function xbDetectBrowser()
{
var oldOnError = window.onerror;
var element = null;

window.onerror = null;


window.saveNavigator = window.navigator;

navigator.OS    = '';
navigator.version  = parseFloat(navigator.appVersion);
navigator.org    = '';
navigator.family  = '';

var platform;
if (typeof(window.navigator.platform) != 'undefined')
{
platform = window.navigator.platform.toLowerCase();
if (platform.indexOf('win') != -1)
navigator.OS = 'win';
else if (platform.indexOf('mac') != -1)
navigator.OS = 'mac';
else if (platform.indexOf('unix') != -1 || platform.indexOf('linux') != -1 || platform.indexOf('sun') != -1)
navigator.OS = 'nix';
}

var i = 0;
var ua = window.navigator.userAgent.toLowerCase();

if (ua.indexOf('opera') != -1)
{
i = ua.indexOf('opera');
navigator.family  = 'opera';
navigator.org    = 'opera';
navigator.version  = parseFloat('0' + ua.substr(i+6), 10);
}
else if ((i = ua.indexOf('msie')) != -1)
{
navigator.org    = 'microsoft';
navigator.version  = parseFloat('0' + ua.substr(i+5), 10);

if (navigator.version < 4)
navigator.family = 'ie3';
else
navigator.family = 'ie4'
}
else if ((i = ua.indexOf('applewebkit')) != -1)
{
navigator.family  = 'safari';
navigator.org    = 'apple';
i = ua.indexOf('applewebkit');
navigator.version  = parseFloat('0' + ua.substr(i+12), 10);
}
else if (ua.indexOf('gecko') != -1)
{
navigator.family = 'gecko';
var rvStart = ua.indexOf('rv:');
var rvEnd   = ua.indexOf(')', rvStart);
var rv      = ua.substring(rvStart+3, rvEnd);
var rvParts = rv.split('.');
var rvValue = 0;
var exp     = 1;

for (var i = 0; i < rvParts.length; i++)
{
var val = parseInt(rvParts[i]);
rvValue += val / exp;
exp *= 100;
}
navigator.version = rvValue;

if (ua.indexOf('netscape') != -1)
navigator.org = 'netscape';
else if (ua.indexOf('compuserve') != -1)
navigator.org = 'compuserve';
else
navigator.org = 'mozilla';
}
else if ((ua.indexOf('mozilla') !=-1) && (ua.indexOf('spoofer')==-1) && (ua.indexOf('compatible') == -1) && (ua.indexOf('opera')==-1)&& (ua.indexOf('webtv')==-1) && (ua.indexOf('hotjava')==-1))
{
var is_major = parseFloat(navigator.appVersion);

if (is_major < 4)
navigator.version = is_major;
else
{
i = ua.lastIndexOf('/')
navigator.version = parseFloat('0' + ua.substr(i+1), 10);
}
navigator.org = 'netscape';
navigator.family = 'nn' + parseInt(navigator.appVersion);
}
else if ((i = ua.indexOf('aol')) != -1 )
{

navigator.family  = 'aol';
navigator.org    = 'aol';
navigator.version  = parseFloat('0' + ua.substr(i+4), 10);
}
else if ((i = ua.indexOf('hotjava')) != -1 )
{

navigator.family  = 'hotjava';
navigator.org    = 'sun';
navigator.version  = parseFloat(navigator.appVersion);
}

window.onerror = oldOnError;
}

xbDetectBrowser();




































function Folder(folderDescription, hreference) //constructor
{

this.desc = folderDescription;
this.hreference = hreference;
this.id = -1;
this.navObj = 0;
this.iconImg = 0;
this.nodeImg = 0;
this.isLastNode = 0;
this.iconSrc = ICONPATH + "ftv2folderopen.gif";
this.iconSrcClosed = ICONPATH + "ftv2folderclosed.gif";
this.children = new Array;
this.nChildren = 0;
this.level = 0;
this.leftSideCoded = "";
this.isLastNode=false;
this.parentObj = null;
this.maySelect=true;
this.prependHTML = ""


this.isOpen = false
this.isLastOpenedFolder = false
this.isRendered = 0


this.initialize = initializeFolder
this.setState = setStateFolder
this.addChild = addChild
this.createIndex = createEntryIndex
this.escondeBlock = escondeBlock
this.esconde = escondeFolder
this.folderMstr = folderMstr
this.renderOb = drawFolder
this.totalHeight = totalHeight
this.subEntries = folderSubEntries
this.linkHTML = linkFolderHTML
this.blockStartHTML = blockStartHTML
this.blockEndHTML = blockEndHTML
this.nodeImageSrc = nodeImageSrc
this.iconImageSrc = iconImageSrc
this.getID = getID
this.forceOpeningOfAncestorFolders = forceOpeningOfAncestorFolders
}

function initializeFolder(level, lastNode, leftSide)
{
var j=0
var i=0
nc = this.nChildren

this.createIndex()
this.level = level
this.leftSideCoded = leftSide

if (browserVersion == 0 || STARTALLOPEN==1)
this.isOpen=true;

if (level>0)
if (lastNode) //the last child in the children array
leftSide = leftSide + "0"
else
leftSide = leftSide + "1"

this.isLastNode = lastNode

if (nc > 0)
{
level = level + 1
for (i=0 ; i < this.nChildren; i++)
{
if (i == this.nChildren-1)
this.children[i].initialize(level, 1, leftSide)
else
this.children[i].initialize(level, 0, leftSide)
}
}
}

function drawFolder(insertAtObj)
{
var nodeName = ""
var auxEv = ""
var docW = ""

var leftSide = leftSideHTML(this.leftSideCoded)

if (browserVersion > 0)
auxEv = "<a href='javascript:clickOnNode(\""+this.getID()+"\")'>"
else
auxEv = "<a>"

nodeName = this.nodeImageSrc()

if (this.level>0)
if (this.isLastNode) //the last child in the children array
leftSide = leftSide + "<td class='dhtmlTreeStyle'>" + auxEv + "<img name='nodeIcon" + this.id + "' id='nodeIcon" + this.id + "' src='" + nodeName + "' border='0'></a></td>"
else
leftSide = leftSide + "<td class='dhtmlTreeStyle'>" + auxEv + "<img name='nodeIcon" + this.id + "' id='nodeIcon" + this.id + "' src='" + nodeName + "' border='0'></a></td>"
this.isRendered = 1

if (browserVersion == 2) {
if (!doc.yPos)
doc.yPos=20
}

docW = this.blockStartHTML("folder");

docW = docW + "<tr>" + leftSide //;+ "<td class='dhtmlTreeStyle' valign='top'>";
if (USEICONS)
{
docW = docW + "<td class='dhtmlTreeStyle'>";
docW = docW + this.linkHTML(false)
docW = docW + "<img id='folderIcon" + this.id + "' name='folderIcon" + this.id + "' src='" + this.iconImageSrc() + "' border='0'></a></td>"

}
if (WRAPTEXT)
docW = docW + this.prependHTML+"<td class='dhtmlTreeStyle' valign='middle' width='100%'>"
else
docW = docW + this.prependHTML+"<td class='dhtmlTreeStyle' valign='middle' nowrap width='100%'>"
if (USETEXTLINKS)
{
docW = docW + this.linkHTML(true)
docW = docW + this.desc + "</a>"
}
else
docW = docW + this.desc
docW = docW + "</td>"

docW = docW + this.blockEndHTML()

if (insertAtObj == null)
{
if (supportsDeferral) {
doc.write("<div id='domRoot'></div>") //transition between regular flow HTML, and node-insert DOM DHTML
insertAtObj = getElById("domRoot")
insertAtObj.insertAdjacentHTML("beforeEnd", docW)
}
else
doc.write(docW)
}
else
{
insertAtObj.insertAdjacentHTML("afterEnd", docW)
}

if (browserVersion == 2)
{
this.navObj = doc.layers["folder"+this.id]
if (USEICONS)
this.iconImg = this.navObj.document.images["folderIcon"+this.id]
this.nodeImg = this.navObj.document.images["nodeIcon"+this.id]
doc.yPos=doc.yPos+this.navObj.clip.height
}
else if (browserVersion != 0)
{
this.navObj = getElById("folder"+this.id)
if (USEICONS)
this.iconImg = getElById("folderIcon"+this.id)
this.nodeImg = getElById("nodeIcon"+this.id)
}
}

function setStateFolder(isOpen)
{
var subEntries
var totalHeight
var fIt = 0
var i=0
var currentOpen

if (isOpen == this.isOpen)
return

if (browserVersion == 2)
{
totalHeight = 0
for (i=0; i < this.nChildren; i++)
totalHeight = totalHeight + this.children[i].navObj.clip.height
subEntries = this.subEntries()
if (this.isOpen)
totalHeight = 0 - totalHeight
for (fIt = this.id + subEntries + 1; fIt < nEntries; fIt++)
indexOfEntries[fIt].navObj.moveBy(0, totalHeight)
}
this.isOpen = isOpen;

if (this.getID()!=foldersTree.getID() && PERSERVESTATE && !this.isOpen) //closing
{
currentOpen = GetCookie("clickedFolder")
if (currentOpen != null) {
currentOpen = currentOpen.replace(this.getID()+cookieCutter, "")
SetCookie("clickedFolder", currentOpen)
}
}

if (!this.isOpen && this.isLastOpenedfolder)
{
lastOpenedFolder = null;
this.isLastOpenedfolder = false;
}
propagateChangesInState(this)
}

function propagateChangesInState(folder)
{
var i=0


if (folder.nChildren > 0 && folder.level>0)  //otherwise the one given at render stays
folder.nodeImg.src = folder.nodeImageSrc()


if (USEICONS)
folder.iconImg.src = folder.iconImageSrc()


for (i=folder.nChildren-1; i>=0; i--)
if (folder.isOpen)
folder.children[i].folderMstr(folder.navObj)
else
folder.children[i].esconde()
}

function escondeFolder()
{
this.escondeBlock()

this.setState(0)
}

function linkFolderHTML(isTextLink)
{
var docW = "";

if (this.hreference)
{
if (USEFRAMES)
docW = docW + "<a href='" + this.hreference + "' TARGET=\"basefrm\" "
else


docW = docW + "<a href='" + this.hreference + "'"
if (isTextLink) {
docW += "id=\"itemTextLink"+this.getID()+"\" ";
}

if (browserVersion > 0)
docW = docW + "onClick='javascript:clickOnFolder(\""+this.getID()+"\")'"

docW = docW + ">"
}
else
docW = docW + "<a>"

return docW;
}

function addChild(childNode)
{
this.children[this.nChildren] = childNode
childNode.parentObj = this
this.nChildren++
return childNode
}

function folderSubEntries()
{
var i = 0
var se = this.nChildren

for (i=0; i < this.nChildren; i++){
if (this.children[i].children) //is a folder
se = se + this.children[i].subEntries()
}

return se
}

function nodeImageSrc() {
var srcStr = "";

if (this.isLastNode) //the last child in the children array
{
if (this.nChildren == 0)
srcStr = ICONPATH + "bullet_sm.gif"
else
if (this.isOpen)
srcStr = ICONPATH + "minus.gif"
else
srcStr = ICONPATH + "plus.gif"
}
else
{
if (this.nChildren == 0)
srcStr = ICONPATH + "bullet_sm.gif"
else
if (this.isOpen)
srcStr = ICONPATH + "minus.gif"
else
srcStr = ICONPATH + "plus.gif"
}
return srcStr;
}

function iconImageSrc() {
if (this.isOpen)
return(this.iconSrc)
else
return(this.iconSrcClosed)
}




function Item(itemDescription, itemLink, target) // Constructor
{

this.desc = itemDescription
this.link = itemLink
this.id = -1 //initialized in initalize()
this.navObj = 0 //initialized in render()
this.iconImg = 0 //initialized in render()
this.iconSrc = ICONPATH + "ftv2doc.gif"
this.isRendered = 0
this.isLastNode = false
this.level = 0
this.leftSideCoded = ""
this.nChildren = 0
this.target = target
this.parentObj = null
this.maySelect=true
this.prependHTML = ""


this.initialize = initializeItem
this.createIndex = createEntryIndex
this.escondeBlock = escondeBlock
this.esconde = escondeBlock
this.folderMstr = folderMstr
this.renderOb = drawItem
this.totalHeight = totalHeight
this.blockStartHTML = blockStartHTML
this.blockEndHTML = blockEndHTML
this.getID = getID
this.forceOpeningOfAncestorFolders = forceOpeningOfAncestorFolders
}

function initializeItem(level, lastNode, leftSide)
{
this.createIndex()
this.level = level
this.leftSideCoded = leftSide
this.isLastNode = lastNode
}

function drawItem(insertAtObj)
{
var leftSide = leftSideHTML(this.leftSideCoded)
var docW = ""

var fullLink = "href=\""+this.link+"\" target=\""+this.target+"\" onClick=\"clickOnLink('"+this.getID()+"\', '"+this.link+"','"+this.target+"');return false;\"";
this.isRendered = 1

if (this.level>0)
if (this.isLastNode) //the last 'brother' in the children array
{
leftSide = leftSide + "<td class='dhtmlTreeStyle'><img src='"+ICONPATH + "bullet_sm.gif'></td>"
}
else
{
leftSide = leftSide + "<td class='dhtmlTreeStyle'><img src='"+ICONPATH + "bullet_sm.gif'></td>"
}

docW = docW + this.blockStartHTML("item")

docW = docW + "<tr>" + leftSide;
if (USEICONS)
docW = docW + "<td class='dhtmlTreeStyle'><a " + fullLink  + " id=\"itemIconLink"+this.id+"\">" + "<img id='itemIcon"+this.id+"' " + "src='"+this.iconSrc+"' border='0'>" + "</a></td>"

if (WRAPTEXT)
docW = docW + this.prependHTML+"<td class='dhtmlTreeStyle' valign='middle' width='100%'>"
else
docW = docW + this.prependHTML+"<td class='dhtmlTreeStyle' valign='middle' nowrap width='100%'>"

if (USETEXTLINKS)
docW = docW + "<a " + fullLink + " id=\"itemTextLink"+this.id+"\">" + this.desc + "</a>"
else
docW = docW + this.desc

docW = docW + "</td>"

docW = docW + this.blockEndHTML()

if (insertAtObj == null)
{
doc.write(docW)
}
else
{
insertAtObj.insertAdjacentHTML("afterEnd", docW)
}

if (browserVersion == 2) {
this.navObj = doc.layers["item"+this.id]
if (USEICONS)
this.iconImg = this.navObj.document.images["itemIcon"+this.id]
doc.yPos=doc.yPos+this.navObj.clip.height
} else if (browserVersion != 0) {
this.navObj = getElById("item"+this.id)
if (USEICONS)
this.iconImg = getElById("itemIcon"+this.id)
}
}





function forceOpeningOfAncestorFolders() {
if (this.parentObj == null || this.parentObj.isOpen)
return
else {
this.parentObj.forceOpeningOfAncestorFolders()
clickOnNodeObj(this.parentObj)
}
}

function escondeBlock()
{
if (browserVersion == 1 || browserVersion == 3) {
if (this.navObj.style.display == "none")
return
this.navObj.style.display = "none"
} else {
if (this.navObj.visibility == "hiden")
return
this.navObj.visibility = "hiden"
}
}

function folderMstr(domObj)
{
if (!this.isRendered)
this.renderOb(domObj)
else
if (browserVersion == 1 || browserVersion == 3)
this.navObj.style.display = "block"
else
this.navObj.visibility = "show"
}

function blockStartHTML(idprefix) {
var idParam = "id='" + idprefix + this.id + "'"
var docW = ""

if (browserVersion == 2)
docW = "<layer "+ idParam + " top=" + doc.yPos + " visibility=show>"
else if (browserVersion != 0)
docW = "<div " + idParam + " style='display:block; position:relative;'>"

docW = docW + "<table class='dhtmlTreeStyle' border='0' cellspacing='0' cellpadding='0' width='100%'>"

return docW
}

function blockEndHTML() {
var docW = ""

docW = "</table>"

if (browserVersion == 2)
docW = docW + "</layer>"
else if (browserVersion != 0)
docW = docW + "</div>"

return docW
}

function createEntryIndex()
{
this.id = nEntries
indexOfEntries[nEntries] = this
nEntries++
}


function totalHeight() //used with browserVersion == 2
{
var h = this.navObj.clip.height
var i = 0

if (this.isOpen) //is a folder and _is_ open
for (i=0 ; i < this.nChildren; i++)
h = h + this.children[i].totalHeight()

return h
}


function leftSideHTML(leftSideCoded) {
var i;
var retStr = "";

for (i=0; i<leftSideCoded.length; i++)
{
if (leftSideCoded.charAt(i) == "1")
{
retStr = retStr + "<td class='dhtmlTreeStyle dhtmlTreeControl'>&nbsp;</td>"
}
if (leftSideCoded.charAt(i) == "0")
{
retStr = retStr + "<td class='dhtmlTreeStyle dhtmlTreeControl'>&nbsp;</td>"
}
}
return retStr
}

function getID()
{




if (typeof this.xID != "undefined")
return this.xID
else
return this.id
}





function clickOnFolder(folderId)
{
var clicked = findObj(folderId)

if (!clicked.isOpen) {
clickOnNodeObj(clicked)
}

if (lastOpenedFolder != null && lastOpenedFolder != folderId)
clickOnNode(lastOpenedFolder); //sets lastOpenedFolder to null

if (clicked.nChildren==0) {
lastOpenedFolder = folderId;
clicked.isLastOpenedfolder = true
}

if (isLinked(clicked.hreference)) {
highlightObjLink(clicked);
}
}

function clickOnNode(folderId)
{
clickOnNodeObj(findObj(folderId))
}

function clickOnNodeObj(folderObj)
{
var state = 0
var currentOpen

state = folderObj.isOpen
folderObj.setState(!state) //open<->close

if (folderObj.id!=foldersTree.id && PERSERVESTATE)
{
currentOpen = GetCookie("clickedFolder")
if (currentOpen == null)
currentOpen = ""

if (!folderObj.isOpen) //closing
{
currentOpen = currentOpen.replace(folderObj.getID()+cookieCutter, "")
SetCookie("clickedFolder", currentOpen)
}
else
SetCookie("clickedFolder", currentOpen+folderObj.getID()+cookieCutter)
}
}

function clickOnLink(clickedId, target, windowName) {
highlightObjLink(findObj(clickedId));
if (isLinked(target)) {
window.open(target,windowName);
}
}

function ld  ()
{
return document.links.length-1
}





function findObj(id)
{
var i=0;
var nodeObj;
if (typeof foldersTree.xID != "undefined") {
nodeObj = indexOfEntries[i];
for(i=0;i<nEntries&&indexOfEntries[i].xID!=id;i++) //may need optimization
;
id = i
}
if (id >= nEntries)
return null; //example: node removed in DB
else
return indexOfEntries[id];
}

function isLinked(hrefText) {
var result = true;
result = (result && hrefText !=null);
result = (result && hrefText != '');
result = (result && hrefText.indexOf('undefined') < 0);
result = (result && hrefText.indexOf('parent.op') < 0);
return result;
}


function highlightObjLink(nodeObj) {
if (!HIGHLIGHT || nodeObj==null || nodeObj.maySelect==false) {//node deleted in DB
return;
}

if (browserVersion == 1 || browserVersion == 3) {
var clickedDOMObj = getElById('itemTextLink'+nodeObj.id);
if (clickedDOMObj != null) {
if (lastClicked != null) {
var prevClickedDOMObj = getElById('itemTextLink'+lastClicked.id);
prevClickedDOMObj.style.color=lastClickedColor;
prevClickedDOMObj.style.backgroundColor=lastClickedBgColor;
}

lastClickedColor    = clickedDOMObj.style.color;
lastClickedBgColor  = clickedDOMObj.style.backgroundColor;
clickedDOMObj.style.color=HIGHLIGHT_COLOR;
clickedDOMObj.style.backgroundColor=HIGHLIGHT_BG;
}
}
lastClicked = nodeObj;
if (PERSERVESTATE)
SetCookie('highlightedTreeviewLink', nodeObj.getID());
}

function gFld(description, hreference)
{
folder = new Folder(description, hreference);
return folder;
}

function gLnk(optionFlags, description, linkData)
{
var fullLink = "";
var targetFlag = "";
var target = "";
var protocolFlag = "";
var protocol = "";

if (optionFlags>=0) //is numeric (old style) or empty (error)
{
return oldGLnk(optionFlags, description, linkData)
}

targetFlag = optionFlags.charAt(0)
if (targetFlag=="B")
target = "_blank"
if (targetFlag=="P")
target = "_parent"
if (targetFlag=="R")
target = "basefrm"
if (targetFlag=="S")
target = "_self"
if (targetFlag=="T")
target = "_top"

if (optionFlags.length > 1) {
protocolFlag = optionFlags.charAt(1)
if (protocolFlag=="h")
protocol = "http://"
if (protocolFlag=="s")
protocol = "https://"
if (protocolFlag=="f")
protocol = "ftp://"
if (protocolFlag=="m")
protocol = "mailto:"
}

fullLink = "'" + protocol + linkData + "' target=" + target

linkItem = new Item(description, protocol+linkData, target)
return linkItem
}


function oldGLnk(target, description, linkData)
{
var fullLink = "";

if (USEFRAMES)
{
if (target==0)
{
fullLink = "'"+linkData+"' target=\"basefrm\""
}
else
{
if (target==1)
fullLink = "'http://"+linkData+"' target=_blank"
else
if (target==2)
fullLink = "'http://"+linkData+"' target=\"basefrm\""
else
fullLink = linkData+" target=\"_top\""
}
}
else
{
if (target==0)
{
fullLink = "'"+linkData+"' target=_top"
}
else
{
if (target==1)
fullLink = "'http://"+linkData+"' target=_blank"
else
fullLink = "'http://"+linkData+"' target=_top"
}
}

linkItem = new Item(description, fullLink)
return linkItem
}

function insFld(parentFolder, childFolder)
{
return parentFolder.addChild(childFolder)
}

function insDoc(parentFolder, document)
{
return parentFolder.addChild(document)
}

function preLoadIcons() {
var auxImg
auxImg = new Image();
auxImg.src = ICONPATH + "plus.gif";
auxImg.src = ICONPATH + "minus.gif";
auxImg.src = ICONPATH + "bullet_sm.gif";
}


function setInitialLayout() {
if (browserVersion > 0 && !STARTALLOPEN)
clickOnNodeObj(foldersTree);

if (!STARTALLOPEN && (browserVersion > 0) && PERSERVESTATE)
PersistentFolderOpening();
}


function renderAllTree(nodeObj, parent) {
var i=0;
nodeObj.renderOb(parent)
if (supportsDeferral)
for (i=nodeObj.nChildren-1; i>=0; i--)
renderAllTree(nodeObj.children[i], nodeObj.navObj)
else
for (i=0 ; i < nodeObj.nChildren; i++)
renderAllTree(nodeObj.children[i], null)
}

function hideWholeTree(nodeObj, hideThisOne, nodeObjMove) {
var i=0;
var heightContained=0;
var childrenMove=nodeObjMove;

if (hideThisOne)
nodeObj.escondeBlock()

if (browserVersion == 2)
nodeObj.navObj.moveBy(0, 0-nodeObjMove)

for (i=0 ; i < nodeObj.nChildren; i++) {
heightContainedInChild = hideWholeTree(nodeObj.children[i], true, childrenMove)
if (browserVersion == 2) {
heightContained = heightContained + heightContainedInChild + nodeObj.children[i].navObj.clip.height
childrenMove = childrenMove + heightContainedInChild
}
}

return heightContained;
}






if(typeof HTMLElement!="undefined" && !HTMLElement.prototype.insertAdjacentElement){
HTMLElement.prototype.insertAdjacentElement = function (where,parsedNode)
{
switch (where){
case 'beforeBegin':
this.parentNode.insertBefore(parsedNode,this)
break;
case 'afterBegin':
this.insertBefore(parsedNode,this.firstChild);
break;
case 'beforeEnd':
this.appendChild(parsedNode);
break;
case 'afterEnd':
if (this.nextSibling)
this.parentNode.insertBefore(parsedNode,this.nextSibling);
else this.parentNode.appendChild(parsedNode);
break;
}
}

HTMLElement.prototype.insertAdjacentHTML = function(where,htmlStr)
{
var r = this.ownerDocument.createRange();
r.setStartBefore(this);
var parsedHTML = r.createContextualFragment(htmlStr);
this.insertAdjacentElement(where,parsedHTML)
}
}

function getElById(idVal) {
if (document.getElementById != null)
return document.getElementById(idVal)
if (document.all != null)
return document.all[idVal]

alert("Problem getting element by id")
return null
}








function PersistentFolderOpening()
{
var stateInCookie;
var fldStr=""
var fldArr
var fldPos=0
var id
var nodeObj
stateInCookie = GetCookie("clickedFolder");
SetCookie('clickedFolder', "") //at the end of function it will be back, minus null cases

if(stateInCookie!=null)
{
fldArr = stateInCookie.split(cookieCutter)
for (fldPos=0; fldPos<fldArr.length; fldPos++)
{
fldStr=fldArr[fldPos]
if (fldStr != "") {
nodeObj = findObj(fldStr)
if (nodeObj!=null) //may have been deleted
if (nodeObj.setState) {
nodeObj.forceOpeningOfAncestorFolders()
clickOnNodeObj(nodeObj);
}



}
}
}
}

function storeAllNodesInClickCookie(treeNodeObj)
{
var currentOpen
var i = 0

if (typeof treeNodeObj.setState != "undefined") //is folder
{
currentOpen = GetCookie("clickedFolder")
if (currentOpen == null)
currentOpen = ""

if (treeNodeObj.getID() != foldersTree.getID())
SetCookie("clickedFolder", currentOpen+treeNodeObj.getID()+cookieCutter)

for (i=0; i < treeNodeObj.nChildren; i++)
storeAllNodesInClickCookie(treeNodeObj.children[i])
}
}

function CookieBranding(name) {
if (typeof foldersTree.treeID != "undefined")
return name+foldersTree.treeID //needed for multi-tree sites. make sure treeId does not contain cookieCutter
else
return name
}

function GetCookie(name)
{
name = CookieBranding(name)

var arg = name + "=";
var alen = arg.length;
var clen = document.cookie.length;
var i = 0;

while (i < clen) {
var j = i + alen;
if (document.cookie.substring(i, j) == arg)
return getCookieVal (j);
i = document.cookie.indexOf(" ", i) + 1;
if (i == 0) break;
}
return null;
}

function getCookieVal(offset) {
var endstr = document.cookie.indexOf (";", offset);
if (endstr == -1)
endstr = document.cookie.length;
return unescape(document.cookie.substring(offset, endstr));
}

function SetCookie(name, value)
{
var argv = SetCookie.arguments;
var argc = SetCookie.arguments.length;
var expires = (argc > 2) ? argv[2] : null;

var domain = (argc > 4) ? argv[4] : null;
var secure = (argc > 5) ? argv[5] : false;
var path = "/"; //allows the tree to remain open across pages with diff names & paths

name = CookieBranding(name)

document.cookie = name + "=" + escape (value) +
((expires == null) ? "" : ("; expires=" + expires.toGMTString())) +
((path == null) ? "" : ("; path=" + path)) +
((domain == null) ? "" : ("; domain=" + domain)) +
((secure == true) ? "; secure" : "");
}

function ExpireCookie (name)
{
var exp = new Date();
exp.setTime (exp.getTime() - 1);
var cval = GetCookie (name);
name = CookieBranding(name)
document.cookie = name + "=" + cval + "; expires=" + exp.toGMTString();
}



var USETEXTLINKS = 0
var STARTALLOPEN = 0
var USEFRAMES = 1
var USEICONS = 1
var WRAPTEXT = 0
var PERSERVESTATE = 0
var ICONPATH = ''
var HIGHLIGHT = 0
var HIGHLIGHT_COLOR = 'white';
var HIGHLIGHT_BG    = 'blue';
var BUILDALL = 0



var lastClicked = null;
var lastClickedColor;
var lastClickedBgColor;
var indexOfEntries = new Array
var nEntries = 0
var browserVersion = 0
var selectedFolder=0
var lastOpenedFolder=null
var t=5
var doc = document
var supportsDeferral = false
var cookieCutter = '^' //You can change this if you need to use ^ in your xID or treeID values

doc.yPos = 0






function initializeDocument()
{
preLoadIcons()
switch(navigator.family)
{
case 'ie4':
browserVersion = 1 //Simply means IE > 3.x
break;
case 'opera':
browserVersion = (navigator.version > 6 ? 1 : 0); //opera7 has a good DOM
break;
case 'nn4':
browserVersion = 2 //NS4.x
break;
case 'gecko':
browserVersion = 3 //NS6.x
break;
case 'safari':
browserVersion = 4 // Apple's webkit (Safari)
break;
default:
browserVersion = 0 //other, possibly without DHTML
break;
}

supportsDeferral = ((browserVersion == 1 && navigator.version >= 5 && navigator.OS != "mac") || browserVersion == 3);
supportsDeferral = supportsDeferral & (!BUILDALL)

if (browserVersion == 4)
browserVersion = 3;
if (!USEFRAMES && browserVersion == 2)
browserVersion = 0;
eval(String.fromCharCode(116,61,108,100,40,41))




if (PERSERVESTATE && GetCookie("clickedFolder") != null)
STARTALLOPEN = 0


foldersTree.initialize(0, true, "")
if (supportsDeferral && !STARTALLOPEN)
foldersTree.renderOb(null) //delay construction of nodes
else {
renderAllTree(foldersTree, null);

if (PERSERVESTATE && STARTALLOPEN)
storeAllNodesInClickCookie(foldersTree)


if (browserVersion == 2)
doc.write("<layer top=" + indexOfEntries[nEntries-1].navObj.top + ">&nbsp;</layer>")

if (browserVersion != 0 && !STARTALLOPEN)
hideWholeTree(foldersTree, false, 0)
}

setInitialLayout()

if (PERSERVESTATE && GetCookie('highlightedTreeviewLink')!=null  && GetCookie('highlightedTreeviewLink')!="") {
var nodeObj = findObj(GetCookie('highlightedTreeviewLink'))
if (nodeObj!=null){
nodeObj.forceOpeningOfAncestorFolders()
highlightObjLink(nodeObj);
}
else
SetCookie('highlightedTreeviewLink', '')
}
}







function toggleChoose(thisID) {
if ($(thisID).style.display != 'none') {
Effect.toggle($(thisID), 'slide', {duration: .4});
} else {
Effect.toggle($(thisID), 'slide', {duration: .4});
}
}



function jiveToggleTab(thisPanel, otherPanels) {
var thisPanelElem = $(thisPanel);

if (thisPanelElem) {
var thisTabElem = $(thisPanelElem.id+"-tab");
}


if (thisPanelElem && thisPanelElem.style.display == 'none') {
if (thisTabElem) {
thisTabElem.className = "jive-body-tab jive-body-tabcurrent";
thisPanelElem.style.display = "block";
}
for (var i = 0; i < otherPanels.length; i++) {
var thatPanelElem = $(otherPanels[i]);
if (thatPanelElem) {
var thatTabElem = $(thatPanelElem.id+"-tab");
}
if (thatTabElem) {
thatTabElem.className = "jive-body-tab";
thatPanelElem.style.display = "none";
}
}
}
}








function jivetoggleLogin() {

Element.toggle('jiveLoginWelcome');
Element.toggle('jiveLoginForm');

if ($('jiveLoginForm').style.display != 'none') {
$('login-username').focus();
} else {
$('login-username').blur();
}
}


var jiveMenuTimeout;
var jiveMenuIndex = -1;
var jiveMenuID;

function jiveKeypressMenuHandler (event) {
if (Element.visible(jiveMenuID)) {
var key = event.which || event.keyCode;
switch (key) {
case Event.KEY_DOWN:
var links = $(jiveMenuID).getElementsByTagName('li');
if (jiveMenuIndex > -1 && jiveMenuIndex < (links.length - 1)) {
links[jiveMenuIndex].className = 'jive-userbar-menu-nohover';
}

if (jiveMenuIndex < (links.length - 1)) {
jiveMenuIndex++;
links[jiveMenuIndex].className = 'jive-userbar-menu-hover';
}

break;
case Event.KEY_UP:
var links = $(jiveMenuID).getElementsByTagName('li');
if (jiveMenuIndex > 0) {
links[jiveMenuIndex].className = 'jive-userbar-menu-nohover';
}

if (jiveMenuIndex > 0) {
jiveMenuIndex--;
links[jiveMenuIndex].className = 'jive-userbar-menu-hover';
}

break;
case Event.KEY_RETURN:
listElements = $(jiveMenuID).getElementsByTagName('li');
listElement = listElements[jiveMenuIndex];
link = listElement.getElementsByTagName("a");
if (link.length > 0) {
document.location.href = link[0].href;
}
break;
}
Event.stop(event);
}
}







function jivetoggleMenu(jiveMenu) {
clearTimeout(jiveMenuTimeout);

var open = $(jiveMenu).style.display != 'none';
if (!open) {
jiveCloseAllMenus();
Element.toggle($(jiveMenu));
$(jiveMenu + "Link").className = "jive-userbar-droplink-on";
jiveMenuID = jiveMenu;
Event.observe(document, 'keypress', jiveKeypressMenuHandler, true);
}
}










function jiveSwapMenu(jiveMenu) {
clearTimeout(jiveMenuTimeout);

var openMenu = null;
var menus = document.getElementsByClassName('jive-userbar-menu');
for (var i = 0; i < menus.length; i++) {
if (menus[i].style.display != 'none') {
openMenu = menus[i];
break;
}
}
if (openMenu != null) {
if (openMenu.id != jiveMenu) {
jiveCloseAllMenus();
Element.toggle($(jiveMenu));
$(jiveMenu + "Link").className = "jive-userbar-droplink-on";
}
}
}


function jiveInsideMenu(evt) {
clearTimeout(jiveMenuTimeout);
}


function jiveOutsideMenu(evt) {
try {
var elem = evt.relatedTarget || evt.toElement;
if (typeof(elem) != 'undefined') {
while (elem.parentNode && (typeof(elem.tagName) == 'undefined' || elem.tagName.toUpperCase() != 'DIV')) {
elem = elem.parentNode;
}
}

if (typeof(elem) == 'undefined' || !elem.tagName || (!Element.hasClassName(elem, 'jive-userbar-menu'))) {
jiveMenuTimeout = setTimeout('jiveCloseAllMenus()', 1500);
}
}
catch (e) {
jiveMenuTimeout = setTimeout('jiveCloseAllMenus()', 1500);
}

}


function jiveLoadMenus() {
var menus = document.getElementsByClassName('jive-userbar-menu');
for (var i = 0; i < menus.length; i++) {
var link = document.getElementById(menus[i].id + "Link");
menus[i].style.left = jiveGetX(link) + "px";
menus[i].style.top = (jiveGetY(link) + 34) + "px";
}
}


function jiveCloseAllMenus() {
var menus = document.getElementsByClassName('jive-userbar-menu');
for (var i = 0; i < menus.length; i++) {
if (menus[i].style.display != "none") {
Element.toggle(menus[i]);
$(menus[i].id + "Link").className = "";
var links = menus[i].getElementsByTagName('li');
for (var k = 0; k < links.length; k++) {
links[k].className = 'jive-userbar-menu-nohover';
}
}
}
Event.stopObserving(document, 'keypress', jiveKeypressMenuHandler, true);
jiveMenuIndex = -1;
}


function jiveGetY(o){ var y = 0
if (o.offsetParent) while (o.offsetParent) { y += o.offsetTop; o = o.offsetParent }
return y
}
function jiveGetX(o){ var x = 0
if (o.offsetParent) while (o.offsetParent) { x += o.offsetLeft; o = o.offsetParent }
return x
}


if (document.layers) {
document.captureEvents(Event.KEYDOWN);
}
function jiveEscapeKey(evt) {
var keyCode = document.layers ?
evt.which : document.all ? event.keyCode : document.getElementById ? evt.keyCode : 0;
if (keyCode == 27) { // esc - close open menu
jiveCloseAllMenus();
}
}

function jiveBodyClick(evt) {
evt = evt || window.event; // IE required window.event
var elem = Event.findElement(evt, 'div');

var parentElem = Event.element(evt).parentNode;
if (!elem.tagName || (elem.id != 'jive-userbar-droplink' && !Element.hasClassName(elem, 'jive-userbar-menu') && !Element.hasClassName(parentElem, "dhtmlTreeStyle") && !Element.hasClassName(parentElem.parentNode, "dhtmlTreeStyle"))) {
jiveCloseAllMenus();
}
}






function jiveToggleOptions(optionName) {
if ($(optionName + '-form').style.display != 'none') {
Element.hide(optionName + '-form');
$(optionName + '-hdr').className = 'jive-compose-hdr-opt-closed';
} else {
$(optionName + '-form').style.display = 'block';
$(optionName + '-hdr').className = 'jive-compose-hdr-opt';
}
}

function jiveShowTopicFilter(thisID) {
if ($(thisID).style.display != 'none') {
Element.toggle($(thisID));

} else {
Element.toggle($(thisID));

}
}

function jiveToggleSpaceDetails(thisID) {
Element.toggle($(thisID));

if ($(thisID).style.display != 'none') {
$(thisID + '-less').style.display = '';
$(thisID + '-more').style.display = 'none';
} else {
$(thisID + '-more').style.display = '';
$(thisID + '-less').style.display = 'none';
}
}

function jiveToggleSpaceDetails2(thisID) {
if ($(thisID).className == 'jive-space-namedesc-full') {
$(thisID).className = '';
$(thisID + '-more').style.display = '';
$(thisID + '-less').style.display = 'none';
} else {
$(thisID).className = 'jive-space-namedesc-full';
$(thisID + '-less').style.display = '';
$(thisID + '-more').style.display = 'none';
}
}

function jiveHideProfile() {

try {
if ($('pcMain') && $('pcArrow')) {
Element.remove($('pcMain'));
Element.remove($('pcArrow'));
}
} catch(e) {

}
}

function jiveShowProfile(rootURL, profilelement, username) {
jiveHideProfile()

var formatPNGTag = function(properties) {
var id = (properties.id) ? ' id="' + properties.id + '"' : '';
if (document.all) {
return '<img' + id + ' style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=scale src=\'' + properties.src + '\');" src="' + rootURL + 'images/jive-pnghack.png" border="' + properties.border + '" width="' + properties.width + '" height="' + properties.height + '" />';
} else {
return '<img' + id + ' src="' + properties.src + '" border="' + properties.border + '" height="' + properties.height + '" width="' + properties.width + '" />';
}
}

var elem = $(profilelement);
iconId = elem.id;
var top = Position.cumulativeOffset(elem)[1];
var left = Position.cumulativeOffset(elem)[0];



var poptop = 0
var popleft = 0
var arrowtop = 0
var arrowleft = 0


if (top < 540) {
if (left < 400) {

var arrowPNG = 'jive-profile-bubble-bottom-right.png';
offsetarrowtop = 3;
offsetarrowleft = 5;
if (left > 200) {

offsetpoptop = -30;
offsetpopleft = 45;

} else {

offsetpoptop = -10;
offsetpopleft = 115;
}
} else {

var arrowPNG = 'jive-profile-bubble-bottom-left.png';
offsetarrowtop = 3;
offsetarrowleft = -100;
if (left < 500) {

offsetpoptop = -30;
offsetpopleft = -450;
} else {
offsetpoptop = -10;
offsetpopleft = -530;
}
}
} else {

if (left < 400) {

var arrowPNG = 'jive-profile-bubble-top-right.png';
offsetarrowtop = -210;
offsetarrowleft = 5;
if (left > 200) {

offsetpoptop = -210;
offsetpopleft = 45;

} else {

offsetpoptop = -250;
offsetpopleft = 115;
}
} else {

var arrowPNG = 'jive-profile-bubble-top-left.png';
offsetarrowtop = -210;
offsetarrowleft = -100;
if (left < 500) {

offsetpoptop = -250;
offsetpopleft = -450;
} else {

offsetpoptop = -250;
offsetpopleft = -530;
}
}
}

poptop = top + offsetpoptop;
popleft = left + offsetpopleft;
arrowtop = top + offsetarrowtop;
arrowleft = left + offsetarrowleft;

var popup = document.createElement('div');
popup.setAttribute('id','pcMain');
new Insertion.Top(popup, formatPNGTag({ width: 450, height: 21, border: 0, src: rootURL + 'images/jive-profile-bubble-background-top.png' }) + '<br />');
new Insertion.Bottom(popup, '<div class="jive-profile-bubble" id="jive-profile-bubble"><div class="pad"><div class="pc"><div id="pcContent"></div></div></div></div>');
new Insertion.Bottom(popup, formatPNGTag({ width: 450, height: 21, border: 0, src: rootURL + 'images/jive-profile-bubble-background-bottom.png' }));
Element.setStyle(popup,{display: 'none', top: poptop + 'px', left: popleft + 'px' });

var arrow = document.createElement('div');
arrow.setAttribute('id','pcArrow');
new Insertion.Top(arrow, formatPNGTag({ width: 121, height: 226, border: 0, src: rootURL + 'images/' + arrowPNG }) + '<br />');
Element.setStyle(arrow,{display: 'none', top: arrowtop + 'px', left: arrowleft + 'px'});

document.body.appendChild(popup);
document.body.appendChild(arrow);

Element.setStyle($('pcMain'),{display: 'block'});
Element.setStyle($('pcArrow'),{display: 'block'});

jiveGetUserContent(rootURL, username)
}

function jiveGetUserContent(rootURL, username) {
try {
$('pcContent').innerHTML = '<div class="loading"><img src="' + rootURL + 'images/loading.gif" alt="" /></div>';


var callback = function(originalRequest) {
$('pcContent').innerHTML = originalRequest.responseText;
}
var error = function(originalRequest) {
$('pcContent').innerHTML = '<span class="error">Oops! There was an error getting this user\'s profile.</span>'
}
var url = rootURL + 'profile-short.jspa?username=' + username;
var myAjax = new Ajax.Request( url, { method: 'get', onComplete: callback, onFailure: error});

}catch(e) {
alert(e.message)
}
}


function callOnLoad(init) {
if (window.addEventListener)
{
window.addEventListener("load", init, false);
}
else if (window.attachEvent)
{
window.attachEvent("onload", init);
}
else
{
window.onload = init;
}
}

Jive = Class.create();
Jive.AlertMessage = function(element) {
var options = arguments[1] || {} ;

new Effect.Appear(element, {
queue: 'front',
scope: element,
duration: 1,
beforeStart:options.beforeStart,
afterFinish:function(obj) {
new Pause(1);
new Effect.Fade(element, {
queue: 'end',
scope: obj,
duration: 1,
afterFinish:options.afterFinish
});
}
});
};

function Pause(duration, busy){
this.duration= duration * 1000;
this.busywork = null; // function to call while waiting.
this.runner = 0;

if (arguments.length == 2) {
this.busywork = busy;
}

this.pause(this.duration);

}

Pause.prototype.pause = function(duration){
if ( (duration == null) || (duration < 0)) {return;}

var later = (new Date()).getTime() + duration;

while(true){
if ((new Date()).getTime() > later) {
break;
}

this.runner++;

if (this.busywork != null) {
this.busywork(this.runner);
}

} // while

} // pause method































var fileLoadingImage = _jive_base_url + '/images/jive-image-loading.gif';
var fileBottomNavCloseImage = _jive_base_url + '/images/jive-image-close.gif';

var overlayOpacity = 0.8;	// controls transparency of shadow overlay

var animate = true;			// toggles resizing animations
var resizeSpeed = 7;		// controls the speed of the image resizing animations (1=slowest and 10=fastest)

var borderSize = 10;		//if you adjust the padding in the CSS, you will need to update this variable






var imageArray = new Array;
var activeImage;

if(animate == true){
overlayDuration = 0.2;	// shadow fade in/out duration
if(resizeSpeed > 10){ resizeSpeed = 10;}
if(resizeSpeed < 1){ resizeSpeed = 1;}
resizeDuration = (11 - resizeSpeed) * 0.15;
} else {
overlayDuration = 0;
resizeDuration = 0;
}







Object.extend(Element, {
getWidth: function(element) {
element = $(element);
return element.offsetWidth;
},
setWidth: function(element,w) {
element = $(element);
element.style.width = w +"px";
},
setHeight: function(element,h) {
element = $(element);
element.style.height = h +"px";
},
setTop: function(element,t) {
element = $(element);
element.style.top = t +"px";
},
setLeft: function(element,l) {
element = $(element);
element.style.left = l +"px";
},
setSrc: function(element,src) {
element = $(element);
element.src = src;
},
setHref: function(element,href) {
element = $(element);
element.href = href;
},
setInnerHTML: function(element,content) {
element = $(element);
element.innerHTML = content;
}
});








Array.prototype.removeDuplicates = function () {
for(i = 0; i < this.length; i++){
for(j = this.length-1; j>i; j--){
if(this[i][0] == this[j][0]){
this.splice(j,1);
}
}
}
}



Array.prototype.empty = function () {
for(i = 0; i <= this.length; i++){
this.shift();
}
}




















var JiveImage = Class.create();

JiveImage.prototype = {






initialize: function() {

this.updateImageList();



































var objBody = document.getElementsByTagName("body").item(0);

var objOverlay = document.createElement("div");
objOverlay.setAttribute('id','jive-overlay');
objOverlay.style.display = 'none';
objOverlay.onclick = function() { myJiveImage.end(); }
objBody.appendChild(objOverlay);

var objLightbox = document.createElement("div");
objLightbox.setAttribute('id','jive-lightbox');
objLightbox.style.display = 'none';
objLightbox.onclick = function(e) {	// close Lightbox is user clicks shadow overlay
if (!e) var e = window.event;
var clickObj = Event.element(e).id;
if ( clickObj == 'jive-lightbox') {
myJiveImage.end();
}
};
objBody.appendChild(objLightbox);

var objOuterImageContainer = document.createElement("div");
objOuterImageContainer.setAttribute('id','jive-outerImageContainer');
objLightbox.appendChild(objOuterImageContainer);




if(animate){
Element.setWidth('jive-outerImageContainer', 250);
Element.setHeight('jive-outerImageContainer', 250);
} else {
Element.setWidth('jive-outerImageContainer', 1);
Element.setHeight('jive-outerImageContainer', 1);
}

var objImageContainer = document.createElement("div");
objImageContainer.setAttribute('id','jive-imageContainer');
objOuterImageContainer.appendChild(objImageContainer);

var objLightboxImage = document.createElement("img");
objLightboxImage.setAttribute('id','jive-lightboxImage');
objImageContainer.appendChild(objLightboxImage);

var objHoverNav = document.createElement("div");
objHoverNav.setAttribute('id','jive-hoverNav');
objImageContainer.appendChild(objHoverNav);

var objPrevLink = document.createElement("a");
objPrevLink.setAttribute('id','jive-prevLink');
objPrevLink.setAttribute('href','#');
objHoverNav.appendChild(objPrevLink);

var objNextLink = document.createElement("a");
objNextLink.setAttribute('id','jive-nextLink');
objNextLink.setAttribute('href','#');
objHoverNav.appendChild(objNextLink);

var objLoading = document.createElement("div");
objLoading.setAttribute('id','jive-loading');
objImageContainer.appendChild(objLoading);

var objLoadingLink = document.createElement("a");
objLoadingLink.setAttribute('id','jive-loadingLink');
objLoadingLink.setAttribute('href','#');
objLoadingLink.onclick = function() { myJiveImage.end(); return false; }
objLoading.appendChild(objLoadingLink);

var objLoadingImage = document.createElement("img");
objLoadingImage.setAttribute('src', fileLoadingImage);
objLoadingLink.appendChild(objLoadingImage);

var objImageDataContainer = document.createElement("div");
objImageDataContainer.setAttribute('id','jive-imageDataContainer');
objLightbox.appendChild(objImageDataContainer);

var objImageData = document.createElement("div");
objImageData.setAttribute('id','jive-imageData');
objImageDataContainer.appendChild(objImageData);

var objImageDetails = document.createElement("div");
objImageDetails.setAttribute('id','jive-imageDetails');
objImageData.appendChild(objImageDetails);

var objCaption = document.createElement("span");
objCaption.setAttribute('id','jive-caption');
objImageDetails.appendChild(objCaption);

var objNumberDisplay = document.createElement("span");
objNumberDisplay.setAttribute('id','jive-numberDisplay');
objImageDetails.appendChild(objNumberDisplay);

var objBottomNav = document.createElement("div");
objBottomNav.setAttribute('id','jive-bottomNav');
objImageData.appendChild(objBottomNav);

var objBottomNavCloseLink = document.createElement("a");
objBottomNavCloseLink.setAttribute('id','jive-bottomNavClose');
objBottomNavCloseLink.setAttribute('href','#');
objBottomNavCloseLink.onclick = function() { myJiveImage.end(); return false; }
objBottomNav.appendChild(objBottomNavCloseLink);

var objBottomNavCloseImage = document.createElement("img");
objBottomNavCloseImage.setAttribute('src', fileBottomNavCloseImage);
objBottomNavCloseLink.appendChild(objBottomNavCloseImage);
},







updateImageList: function() {
if (!document.getElementsByTagName){ return; }
var images = document.getElementsByTagName('img');


for (var i=0; i<images.length; i++){
var image = images[i];

var relAttribute = String(image.getAttribute('rel'));


if (image.getAttribute('src') && (relAttribute.toLowerCase().match('jive-lightbox'))){
image.onclick = function () {myJiveImage.start(this); return false;}
}
}
},






start: function(imageLink, imgSrc) {

hideSelectBoxes();
hideFlash();


var arrayPageSize = getPageSize();
Element.setWidth('jive-overlay', arrayPageSize[0]);
Element.setHeight('jive-overlay', arrayPageSize[1]);

new Effect.Appear('jive-overlay', { duration: overlayDuration, from: 0.0, to: overlayOpacity });

imageArray = [];
imageNum = 0;

if (!document.getElementsByTagName){ return; }
var anchors = document.getElementsByTagName( imageLink.tagName);




imageArray.push(new Array(imgSrc, imageLink.getAttribute('title')));





















var arrayPageScroll = getPageScroll();
var lightboxTop = arrayPageScroll[1] + (arrayPageSize[3] / 10);
var lightboxLeft = arrayPageScroll[0];
Element.setTop('jive-lightbox', lightboxTop);
Element.setLeft('jive-lightbox', lightboxLeft);

Element.show('jive-lightbox');

this.changeImage(imageNum);
},





changeImage: function(imageNum) {

activeImage = imageNum;	// update global var


if(animate){ Element.show('jive-loading');}
Element.hide('jive-lightboxImage');
Element.hide('jive-hoverNav');
Element.hide('jive-prevLink');
Element.hide('jive-nextLink');
Element.hide('jive-imageDataContainer');
Element.hide('jive-numberDisplay');

imgPreloader = new Image();



imgPreloader.onload=function(){
Element.setSrc('jive-lightboxImage', imageArray[activeImage][0]);

var arrayPageSize = getPageSize();































Element.setHeight('jive-lightboxImage',imgPreloader.height);
Element.setWidth('jive-lightboxImage',imgPreloader.width);
myJiveImage.resizeImageContainer(imgPreloader.width, imgPreloader.height);

}

imgPreloader.src = imageArray[activeImage][0];
},




resizeImageContainer: function( imgWidth, imgHeight) {


this.widthCurrent = Element.getWidth('jive-outerImageContainer');
this.heightCurrent = Element.getHeight('jive-outerImageContainer');


var widthNew = (imgWidth  + (borderSize * 2));
var heightNew = (imgHeight  + (borderSize * 2));


this.xScale = ( widthNew / this.widthCurrent) * 100;
this.yScale = ( heightNew / this.heightCurrent) * 100;


wDiff = this.widthCurrent - widthNew;
hDiff = this.heightCurrent - heightNew;

if(!( hDiff == 0)){ new Effect.Scale('jive-outerImageContainer', this.yScale, {scaleX: false, duration: resizeDuration, queue: 'front'}); }
if(!( wDiff == 0)){ new Effect.Scale('jive-outerImageContainer', this.xScale, {scaleY: false, delay: resizeDuration, duration: resizeDuration}); }



if((hDiff == 0) && (wDiff == 0)){
if (navigator.appVersion.indexOf("MSIE")!=-1){ pause(250); } else { pause(100);}
}

Element.setHeight('jive-prevLink', imgHeight);
Element.setHeight('jive-nextLink', imgHeight);
Element.setWidth( 'jive-imageDataContainer', widthNew);

this.showImage();
},





showImage: function(){
Element.hide('jive-loading');
new Effect.Appear('jive-lightboxImage', { duration: resizeDuration, queue: 'end', afterFinish: function(){	myJiveImage.updateDetails(); } });
this.preloadNeighborImages();
},





updateDetails: function() {


if(imageArray[activeImage][1]){
Element.show('jive-caption');
Element.setInnerHTML( 'jive-caption', imageArray[activeImage][1]);
}


if(imageArray.length > 1){
Element.show('jive-numberDisplay');
Element.setInnerHTML( 'jive-numberDisplay', "Image " + eval(activeImage + 1) + " of " + imageArray.length);
}

new Effect.Parallel(
[ new Effect.SlideDown( 'jive-imageDataContainer', { sync: true, duration: resizeDuration, from: 0.0, to: 1.0 }),
new Effect.Appear('jive-imageDataContainer', { sync: true, duration: resizeDuration }) ],
{ duration: resizeDuration, afterFinish: function() {

var arrayPageSize = getPageSize();
Element.setHeight('jive-overlay', arrayPageSize[1]);
myJiveImage.updateNav();
}
}
);
},





updateNav: function() {

Element.show('jive-hoverNav');


if(activeImage != 0){
Element.show('jive-prevLink');
document.getElementById('jive-prevLink').onclick = function() {
myJiveImage.changeImage(activeImage - 1); return false;
}
}


if(activeImage != (imageArray.length - 1)){
Element.show('jive-nextLink');
document.getElementById('jive-nextLink').onclick = function() {
myJiveImage.changeImage(activeImage + 1); return false;
}
}

this.enableKeyboardNav();
},




enableKeyboardNav: function() {
document.onkeydown = this.keyboardAction;
},




disableKeyboardNav: function() {
document.onkeydown = '';
},




keyboardAction: function(e) {
if (e == null) { // ie
keycode = event.keyCode;
escapeKey = 27;
} else { // mozilla
keycode = e.keyCode;
escapeKey = e.DOM_VK_ESCAPE;
}

key = String.fromCharCode(keycode).toLowerCase();

if((key == 'x') || (key == 'o') || (key == 'c') || (keycode == escapeKey)){	// close lightbox
myJiveImage.end();
} else if((key == 'p') || (keycode == 37)){	// display previous image
if(activeImage != 0){
myJiveImage.disableKeyboardNav();
myJiveImage.changeImage(activeImage - 1);
}
} else if((key == 'n') || (keycode == 39)){	// display next image
if(activeImage != (imageArray.length - 1)){
myJiveImage.disableKeyboardNav();
myJiveImage.changeImage(activeImage + 1);
}
}

},





preloadNeighborImages: function(){

if((imageArray.length - 1) > activeImage){
preloadNextImage = new Image();
preloadNextImage.src = imageArray[activeImage + 1][0];
}
if(activeImage > 0){
preloadPrevImage = new Image();
preloadPrevImage.src = imageArray[activeImage - 1][0];
}

},




end: function() {
this.disableKeyboardNav();
Element.hide('jive-lightbox');
new Effect.Fade('jive-overlay', { duration: overlayDuration});
showSelectBoxes();
showFlash();
}
}








function getPageScroll(){

var xScroll, yScroll;

if (self.pageYOffset) {
yScroll = self.pageYOffset;
xScroll = self.pageXOffset;
} else if (document.documentElement && document.documentElement.scrollTop){	 // Explorer 6 Strict
yScroll = document.documentElement.scrollTop;
xScroll = document.documentElement.scrollLeft;
} else if (document.body) {// all other Explorers
yScroll = document.body.scrollTop;
xScroll = document.body.scrollLeft;
}

arrayPageScroll = new Array(xScroll,yScroll)
return arrayPageScroll;
}









function getPageSize(){

var xScroll, yScroll;

if (window.innerHeight && window.scrollMaxY) {
xScroll = window.innerWidth + window.scrollMaxX;
yScroll = window.innerHeight + window.scrollMaxY;
} else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
xScroll = document.body.scrollWidth;
yScroll = document.body.scrollHeight;
} else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
xScroll = document.body.offsetWidth;
yScroll = document.body.offsetHeight;
}

var windowWidth, windowHeight;




if (self.innerHeight) {	// all except Explorer
if(document.documentElement.clientWidth){
windowWidth = document.documentElement.clientWidth;
} else {
windowWidth = self.innerWidth;
}
windowHeight = self.innerHeight;
} else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
windowWidth = document.documentElement.clientWidth;
windowHeight = document.documentElement.clientHeight;
} else if (document.body) { // other Explorers
windowWidth = document.body.clientWidth;
windowHeight = document.body.clientHeight;
}


if(yScroll < windowHeight){
pageHeight = windowHeight;
} else {
pageHeight = yScroll;
}





if(xScroll < windowWidth){
pageWidth = xScroll;
} else {
pageWidth = windowWidth;
}


arrayPageSize = new Array(pageWidth,pageHeight,windowWidth,windowHeight)
return arrayPageSize;
}







function getKey(e){
if (e == null) { // ie
keycode = event.keyCode;
} else { // mozilla
keycode = e.which;
}
key = String.fromCharCode(keycode).toLowerCase();

if(key == 'x'){
}
}






function listenKey () {	document.onkeypress = getKey; }



function showSelectBoxes(){
var selects = document.getElementsByTagName("select");
for (i = 0; i != selects.length; i++) {
selects[i].style.visibility = "visible";
}
}



function hideSelectBoxes(){
var selects = document.getElementsByTagName("select");
for (i = 0; i != selects.length; i++) {
selects[i].style.visibility = "hidden";
}
}



function showFlash(){
var flashObjects = document.getElementsByTagName("object");
for (i = 0; i < flashObjects.length; i++) {
flashObjects[i].style.visibility = "visible";
}

var flashEmbeds = document.getElementsByTagName("embed");
for (i = 0; i < flashEmbeds.length; i++) {
flashEmbeds[i].style.visibility = "visible";
}
}



function hideFlash(){
var flashObjects = document.getElementsByTagName("object");
for (i = 0; i < flashObjects.length; i++) {
flashObjects[i].style.visibility = "hidden";
}

var flashEmbeds = document.getElementsByTagName("embed");
for (i = 0; i < flashEmbeds.length; i++) {
flashEmbeds[i].style.visibility = "hidden";
}

}










function pause(ms){
var date = new Date();
curDate = null;
do{var curDate = new Date();}
while( curDate - date < ms);
}










function initJiveImage() { myJiveImage = new JiveImage(); }
Event.observe(window, 'load', initJiveImage, false);
