﻿var Prototype = { Version: '1.4.0', ScriptFragment: '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)', emptyFunction: function() { }, K: function(a) { return a } }; var Class = { create: function() { return function() { this.initialize.apply(this, arguments) } } }; var Abstract = new Object(); Object.extend = function(a, b) { for (property in b) { a[property] = b[property] } return a }; Object.inspect = function(a) { try { if (a == undefined) return 'undefined'; if (a == null) return 'null'; return a.inspect ? a.inspect() : a.toString() } catch (e) { if (e instanceof RangeError) return '...'; throw e; } }; Function.prototype.bind = function() { var a = this, args = $A(arguments), object = args.shift(); return function() { return a.apply(object, args.concat($A(arguments))) } }; Function.prototype.bindAsEventListener = function(b) { var c = this; return function(a) { return c.call(b, a || window.event) } }; Object.extend(Number.prototype, { toColorPart: function() { var a = this.toString(16); if (this < 16) return '0' + a; return a }, succ: function() { return this + 1 }, times: function(a) { $R(0, this, true).each(a); return this } }); var Try = { these: function() { var a; for (var i = 0; i < arguments.length; i++) { var b = arguments[i]; try { a = b(); break } catch (e) { } } return a } }; var PeriodicalExecuter = Class.create(); PeriodicalExecuter.prototype = { initialize: function(a, b) { this.callback = a; this.frequency = b; this.currentlyExecuting = false; this.registerCallback() }, registerCallback: function() { setInterval(this.onTimerEvent.bind(this), this.frequency * 1000) }, onTimerEvent: function() { if (!this.currentlyExecuting) { try { this.currentlyExecuting = true; this.callback() } finally { this.currentlyExecuting = false } } } }; function $() { var a = new Array(); for (var i = 0; i < arguments.length; i++) { var b = arguments[i]; if (typeof b == 'string') b = document.getElementById(b); if (arguments.length == 1) return b; a.push(b) } return a } Object.extend(String.prototype, { stripTags: function() { return this.replace(/<\/?[^>]+>/gi, '') }, stripScripts: function() { return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '') }, extractScripts: function() { var b = new RegExp(Prototype.ScriptFragment, 'img'); var c = new RegExp(Prototype.ScriptFragment, 'im'); return (this.match(b) || []).map(function(a) { return (a.match(c) || ['', ''])[1] }) }, evalScripts: function() { return this.extractScripts().map(eval) }, escapeHTML: function() { var a = document.createElement('div'); var b = document.createTextNode(this); a.appendChild(b); return a.innerHTML }, unescapeHTML: function() { var a = document.createElement('div'); a.innerHTML = this.stripTags(); return a.childNodes[0] ? a.childNodes[0].nodeValue : '' }, toQueryParams: function() { var d = this.match(/^\??(.*)$/)[1].split('&'); return d.inject({}, function(a, b) { var c = b.split('='); a[c[0]] = c[1]; return a }) }, toArray: function() { return this.split('') }, camelize: function() { var a = this.split('-'); if (a.length == 1) return a[0]; var b = this.indexOf('-') == 0 ? a[0].charAt(0).toUpperCase() + a[0].substring(1) : a[0]; for (var i = 1, len = a.length; i < len; i++) { var s = a[i]; b += s.charAt(0).toUpperCase() + s.substring(1) } return b }, inspect: function() { return "'" + this.replace('\\', '\\\\').replace("'", '\\\'') + "'" } }); String.prototype.parseQuery = String.prototype.toQueryParams; var $break = new Object(); var $continue = new Object(); var Enumerable = { each: function(b) { var c = 0; try { this._each(function(a) { try { b(a, c++) } catch (e) { if (e != $continue) throw e; } }) } catch (e) { if (e != $break) throw e; } }, all: function(c) { var d = true; this.each(function(a, b) { d = d && !!(c || Prototype.K)(a, b); if (!d) throw $break; }); return d }, any: function(c) { var d = true; this.each(function(a, b) { if (d = !!(c || Prototype.K)(a, b)) throw $break; }); return d }, collect: function(c) { var d = []; this.each(function(a, b) { d.push(c(a, b)) }); return d }, detect: function(c) { var d; this.each(function(a, b) { if (c(a, b)) { d = a; throw $break; } }); return d }, findAll: function(c) { var d = []; this.each(function(a, b) { if (c(a, b)) d.push(a) }); return d }, grep: function(d, e) { var f = []; this.each(function(a, b) { var c = a.toString(); if (c.match(d)) f.push((e || Prototype.K)(a, b)) }); return f }, include: function(b) { var c = false; this.each(function(a) { if (a == b) { c = true; throw $break; } }); return c }, inject: function(c, d) { this.each(function(a, b) { c = d(c, a, b) }); return c }, invoke: function(b) { var c = $A(arguments).slice(1); return this.collect(function(a) { return a[b].apply(a, c) }) }, max: function(c) { var d; this.each(function(a, b) { a = (c || Prototype.K)(a, b); if (a >= (d || a)) d = a }); return d }, min: function(c) { var d; this.each(function(a, b) { a = (c || Prototype.K)(a, b); if (a <= (d || a)) d = a }); return d }, partition: function(c) { var d = [], falses = []; this.each(function(a, b) { ((c || Prototype.K)(a, b) ? d : falses).push(a) }); return [d, falses] }, pluck: function(c) { var d = []; this.each(function(a, b) { d.push(a[c]) }); return d }, reject: function(c) { var d = []; this.each(function(a, b) { if (!c(a, b)) d.push(a) }); return d }, sortBy: function(e) { return this.collect(function(a, b) { return { value: a, criteria: e(a, b)} }).sort(function(c, d) { var a = c.criteria, b = d.criteria; return a < b ? -1 : a > b ? 1 : 0 }).pluck('value') }, toArray: function() { return this.collect(Prototype.K) }, zip: function() { var c = Prototype.K, args = $A(arguments); if (typeof args.last() == 'function') c = args.pop(); var d = [this].concat(args).map($A); return this.map(function(a, b) { c(a = d.pluck(b)); return a }) }, 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(a) { if (!a) return []; if (a.toArray) { return a.toArray() } else { var b = []; for (var i = 0; i < a.length; i++) b.push(a[i]); return b } }; Object.extend(Array.prototype, Enumerable); Array.prototype._reverse = Array.prototype.reverse; Object.extend(Array.prototype, { _each: function(a) { for (var i = 0; i < this.length; i++) a(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(a) { return a != undefined || a != null }) }, flatten: function() { return this.inject([], function(a, b) { return a.concat(b.constructor == Array ? b.flatten() : [b]) }) }, without: function() { var b = $A(arguments); return this.select(function(a) { return !b.include(a) }) }, indexOf: function(a) { for (var i = 0; i < this.length; i++) if (this[i] == a) return i; return -1 }, reverse: function(a) { return (a !== false ? this : this.toArray())._reverse() }, shift: function() { var a = this[0]; for (var i = 0; i < this.length - 1; i++) this[i] = this[i + 1]; this.length--; return a }, inspect: function() { return '[' + this.map(Object.inspect).join(', ') + ']' } }); var Hash = { _each: function(a) { for (key in this) { var b = this[key]; if (typeof b == 'function') continue; var c = [key, b]; c.key = key; c.value = b; a(c) } }, keys: function() { return this.pluck('key') }, values: function() { return this.pluck('value') }, merge: function(c) { return $H(c).inject($H(this), function(a, b) { a[b.key] = b.value; return a }) }, toQueryString: function() { return this.map(function(a) { return a.map(encodeURIComponent).join('=') }).join('&') }, inspect: function() { return '#<Hash:{' + this.map(function(a) { return a.map(Object.inspect).join(': ') }).join(', ') + '}>' } }; function $H(a) { var b = Object.extend({}, a || {}); Object.extend(b, Enumerable); Object.extend(b, Hash); return b } ObjectRange = Class.create(); Object.extend(ObjectRange.prototype, Enumerable); Object.extend(ObjectRange.prototype, { initialize: function(a, b, c) { this.start = a; this.end = b; this.exclusive = c }, _each: function(a) { var b = this.start; do { a(b); b = b.succ() } while (this.include(b)) }, include: function(a) { if (a < this.start) return false; if (this.exclusive) return a < this.end; return a <= this.end } }); var $R = function(a, b, c) { return new ObjectRange(a, b, c) }; var Ajax = { getTransport: function() { return Try.these(function() { return new ActiveXObject('Msxml2.XMLHTTP') }, function() { return new ActiveXObject('Microsoft.XMLHTTP') }, function() { return new XMLHttpRequest() }) || false }, activeRequestCount: 0 }; Ajax.Responders = { responders: [], _each: function(a) { this.responders._each(a) }, register: function(a) { if (!this.include(a)) this.responders.push(a) }, unregister: function(a) { this.responders = this.responders.without(a) }, dispatch: function(b, c, d, f) { this.each(function(a) { if (a[b] && typeof a[b] == 'function') { try { a[b].apply(a, [c, d, f]) } 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(a) { this.options = { method: 'post', asynchronous: true, parameters: '' }; Object.extend(this.options, a || {}) }, responseIsSuccess: function() { return this.transport.status == undefined || this.transport.status == 0 || (this.transport.status >= 200 && this.transport.status < 300) }, responseIsFailure: function() { return !this.responseIsSuccess() } }; Ajax.Request = Class.create(); Ajax.Request.Events = ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; Ajax.Request.prototype = Object.extend(new Ajax.Base(), { initialize: function(a, b) { this.transport = Ajax.getTransport(); this.setOptions(b); this.request(a) }, request: function(a) { var b = this.options.parameters || ''; if (b.length > 0) b += '&_='; try { this.url = a; if (this.options.method == 'get' && b.length > 0) this.url += (this.url.match(/\?/) ? '&' : '?') + b; Ajax.Responders.dispatch('onCreate', this, this.transport); this.transport.open(this.options.method, this.url, this.options.asynchronous); if (this.options.asynchronous) { this.transport.onreadystatechange = this.onStateChange.bind(this); setTimeout((function() { this.respondToReadyState(1) }).bind(this), 10) } this.setRequestHeaders(); var c = this.options.postBody ? this.options.postBody : b; this.transport.send(this.options.method == 'post' ? c : null) } catch (e) { this.dispatchException(e) } }, setRequestHeaders: function() { var a = ['X-Requested-With', 'XMLHttpRequest', 'X-Prototype-Version', Prototype.Version]; if (this.options.method == 'post') { a.push('Content-type', 'application/x-www-form-urlencoded'); if (this.transport.overrideMimeType) a.push('Connection', 'close') } if (this.options.requestHeaders) a.push.apply(a, this.options.requestHeaders); for (var i = 0; i < a.length; i += 2) this.transport.setRequestHeader(a[i], a[i + 1]) }, onStateChange: function() { var a = this.transport.readyState; if (a != 1) this.respondToReadyState(this.transport.readyState) }, header: function(a) { try { return this.transport.getResponseHeader(a) } catch (e) { } }, evalJSON: function() { try { return eval(this.header('X-JSON')) } catch (e) { } }, evalResponse: function() { try { return eval(this.transport.responseText) } catch (e) { this.dispatchException(e) } }, respondToReadyState: function(a) { var b = Ajax.Request.Events[a]; var c = this.transport, json = this.evalJSON(); if (b == 'Complete') { try { (this.options['on' + this.transport.status] || this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')] || Prototype.emptyFunction)(c, json) } catch (e) { this.dispatchException(e) } if ((this.header('Content-type') || '').match(/^text\/javascript/i)) this.evalResponse() } try { (this.options['on' + b] || Prototype.emptyFunction)(c, json); Ajax.Responders.dispatch('on' + b, this, c, json) } catch (e) { this.dispatchException(e) } if (b == 'Complete') this.transport.onreadystatechange = Prototype.emptyFunction }, dispatchException: function(a) { (this.options.onException || Prototype.emptyFunction)(this, a); Ajax.Responders.dispatch('onException', this, a) } }); Ajax.Updater = Class.create(); Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), { initialize: function(c, d, e) { this.containers = { success: c.success ? $(c.success) : $(c), failure: c.failure ? $(c.failure) : (c.success ? null : $(c)) }; this.transport = Ajax.getTransport(); this.setOptions(e); var f = this.options.onComplete || Prototype.emptyFunction; this.options.onComplete = (function(a, b) { this.updateContent(); f(a, b) }).bind(this); this.request(d) }, updateContent: function() { var a = this.responseIsSuccess() ? this.containers.success : this.containers.failure; var b = this.transport.responseText; if (!this.options.evalScripts) b = b.stripScripts(); if (a) { if (this.options.insertion) { new this.options.insertion(a, b) } else { Element.update(a, b) } } if (this.responseIsSuccess()) { if (this.onComplete) setTimeout(this.onComplete.bind(this), 10) } } }); Ajax.PeriodicalUpdater = Class.create(); Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), { initialize: function(a, b, c) { this.setOptions(c); this.onComplete = this.options.onComplete; this.frequency = (this.options.frequency || 2); this.decay = (this.options.decay || 1); this.updater = {}; this.container = a; this.url = b; this.start() }, start: function() { this.options.onComplete = this.updateComplete.bind(this); this.onTimerEvent() }, stop: function() { this.updater.onComplete = undefined; clearTimeout(this.timer); (this.onComplete || Prototype.emptyFunction).apply(this, arguments) }, updateComplete: function(a) { if (this.options.decay) { this.decay = (a.responseText == this.lastText ? this.decay * this.options.decay : 1); this.lastText = a.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) } }); document.getElementsByClassName = function(c, d) { var e = ($(d) || document.body).getElementsByTagName('*'); return $A(e).inject([], function(a, b) { if (b.className.match(new RegExp("(^|\\s)" + c + "(\\s|$)"))) a.push(b); return a }) }; if (!window.Element) { var Element = new Object() } Object.extend(Element, { visible: function(a) { return $(a).style.display != 'none' }, toggle: function() { for (var i = 0; i < arguments.length; i++) { var a = $(arguments[i]); Element[Element.visible(a) ? 'hide' : 'show'](a) } }, hide: function() { for (var i = 0; i < arguments.length; i++) { var a = $(arguments[i]); a.style.display = 'none' } }, show: function() { for (var i = 0; i < arguments.length; i++) { var a = $(arguments[i]); a.style.display = '' } }, remove: function(a) { a = $(a); a.parentNode.removeChild(a) }, update: function(a, b) { $(a).innerHTML = b.stripScripts(); setTimeout(function() { b.evalScripts() }, 10) }, getHeight: function(a) { a = $(a); return a.offsetHeight }, classNames: function(a) { return new Element.ClassNames(a) }, hasClassName: function(a, b) { if (!(a = $(a))) return; return Element.classNames(a).include(b) }, addClassName: function(a, b) { if (!(a = $(a))) return; return Element.classNames(a).add(b) }, removeClassName: function(a, b) { if (!(a = $(a))) return; return Element.classNames(a).remove(b) }, cleanWhitespace: function(a) { a = $(a); for (var i = 0; i < a.childNodes.length; i++) { var b = a.childNodes[i]; if (b.nodeType == 3 && !/\S/.test(b.nodeValue)) Element.remove(b) } }, empty: function(a) { return $(a).innerHTML.match(/^\s*$/) }, scrollTo: function(a) { a = $(a); var x = a.x ? a.x : a.offsetLeft, y = a.y ? a.y : a.offsetTop; window.scrollTo(x, y) }, getStyle: function(a, b) { a = $(a); var c = a.style[b.camelize()]; if (!c) { if (document.defaultView && document.defaultView.getComputedStyle) { var d = document.defaultView.getComputedStyle(a, null); c = d ? d.getPropertyValue(b) : null } else if (a.currentStyle) { c = a.currentStyle[b.camelize()] } } if (window.opera && ['left', 'top', 'right', 'bottom'].include(b)) if (Element.getStyle(a, 'position') == 'static') c = 'auto'; return c == 'auto' ? null : c }, setStyle: function(a, b) { a = $(a); for (name in b) a.style[name.camelize()] = b[name] }, getDimensions: function(a) { a = $(a); if (Element.getStyle(a, 'display') != 'none') return { width: a.offsetWidth, height: a.offsetHeight }; var b = a.style; var c = b.visibility; var d = b.position; b.visibility = 'hidden'; b.position = 'absolute'; b.display = ''; var e = a.clientWidth; var f = a.clientHeight; b.display = 'none'; b.position = d; b.visibility = c; return { width: e, height: f} }, makePositioned: function(a) { a = $(a); var b = Element.getStyle(a, 'position'); if (b == 'static' || !b) { a._madePositioned = true; a.style.position = 'relative'; if (window.opera) { a.style.top = 0; a.style.left = 0 } } }, undoPositioned: function(a) { a = $(a); if (a._madePositioned) { a._madePositioned = undefined; a.style.position = a.style.top = a.style.left = a.style.bottom = a.style.right = '' } }, makeClipping: function(a) { a = $(a); if (a._overflow) return; a._overflow = a.style.overflow; if ((Element.getStyle(a, 'overflow') || 'visible') != 'hidden') a.style.overflow = 'hidden' }, undoClipping: function(a) { a = $(a); if (a._overflow) return; a.style.overflow = a._overflow; a._overflow = undefined } }); var Toggle = new Object(); Toggle.display = Element.toggle; Abstract.Insertion = function(a) { this.adjacency = a }; Abstract.Insertion.prototype = { initialize: function(a, b) { this.element = $(a); this.content = b.stripScripts(); if (this.adjacency && this.element.insertAdjacentHTML) { try { this.element.insertAdjacentHTML(this.adjacency, this.content) } catch (e) { if (this.element.tagName.toLowerCase() == 'tbody') { 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() { b.evalScripts() }, 10) }, contentFromAnonymousTable: function() { var a = document.createElement('div'); a.innerHTML = '<table><tbody>' + this.content + '</tbody></table>'; return $A(a.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(b) { b.each((function(a) { this.element.parentNode.insertBefore(a, 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(b) { b.reverse(false).each((function(a) { this.element.insertBefore(a, 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(b) { b.each((function(a) { this.element.appendChild(a) }).bind(this)) } }); Insertion.After = Class.create(); Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), { initializeRange: function() { this.range.setStartAfter(this.element) }, insertContent: function(b) { b.each((function(a) { this.element.parentNode.insertBefore(a, this.element.nextSibling) }).bind(this)) } }); Element.ClassNames = Class.create(); Element.ClassNames.prototype = { initialize: function(a) { this.element = $(a) }, _each: function(b) { this.element.className.split(/\s+/).select(function(a) { return a.length > 0 })._each(b) }, set: function(a) { this.element.className = a }, add: function(a) { if (this.include(a)) return; this.set(this.toArray().concat(a).join(' ')) }, remove: function(b) { if (!this.include(b)) return; this.set(this.select(function(a) { return a != b }).join(' ')) }, toString: function() { return this.toArray().join(' ') } }; Object.extend(Element.ClassNames.prototype, Enumerable); var Field = { clear: function() { for (var i = 0; i < arguments.length; i++) $(arguments[i]).value = '' }, focus: function(a) { $(a).focus() }, present: function() { for (var i = 0; i < arguments.length; i++) if ($(arguments[i]).value == '') return false; return true }, select: function(a) { $(a).select() }, activate: function(a) { a = $(a); a.focus(); if (a.select) a.select() } }; var Form = { serialize: function(a) { var b = Form.getElements($(a)); var c = new Array(); for (var i = 0; i < b.length; i++) { var d = Form.Element.serialize(b[i]); if (d) c.push(d) } return c.join('&') }, getElements: function(a) { a = $(a); var b = new Array(); for (tagName in Form.Element.Serializers) { var c = a.getElementsByTagName(tagName); for (var j = 0; j < c.length; j++) b.push(c[j]) } return b }, getInputs: function(a, b, c) { a = $(a); var d = a.getElementsByTagName('input'); if (!b && !c) return d; var e = new Array(); for (var i = 0; i < d.length; i++) { var f = d[i]; if ((b && f.type != b) || (c && f.name != c)) continue; e.push(f) } return e }, disable: function(a) { var b = Form.getElements(a); for (var i = 0; i < b.length; i++) { var c = b[i]; c.blur(); c.disabled = 'true' } }, enable: function(a) { var b = Form.getElements(a); for (var i = 0; i < b.length; i++) { var c = b[i]; c.disabled = '' } }, findFirstElement: function(b) { return Form.getElements(b).find(function(a) { return a.type != 'hidden' && !a.disabled && ['input', 'select', 'textarea'].include(a.tagName.toLowerCase()) }) }, focusFirstElement: function(a) { Field.activate(Form.findFirstElement(a)) }, reset: function(a) { $(a).reset() } }; Form.Element = { serialize: function(b) { b = $(b); var c = b.tagName.toLowerCase(); var d = Form.Element.Serializers[c](b); if (d) { var e = encodeURIComponent(d[0]); if (e.length == 0) return; if (d[1].constructor != Array) d[1] = [d[1]]; return d[1].map(function(a) { return e + '=' + encodeURIComponent(a) }).join('&') } }, getValue: function(a) { a = $(a); var b = a.tagName.toLowerCase(); var c = Form.Element.Serializers[b](a); if (c) return c[1] } }; Form.Element.Serializers = { input: function(a) { switch (a.type.toLowerCase()) { case 'submit': case 'hidden': case 'password': case 'text': return Form.Element.Serializers.textarea(a); case 'checkbox': case 'radio': return Form.Element.Serializers.inputSelector(a) } return false }, inputSelector: function(a) { if (a.checked) return [a.name, a.value] }, textarea: function(a) { return [a.name, a.value] }, select: function(a) { return Form.Element.Serializers[a.type == 'select-one' ? 'selectOne' : 'selectMany'](a) }, selectOne: function(a) { var b = '', opt, index = a.selectedIndex; if (index >= 0) { opt = a.options[index]; b = opt.value; if (!b && !('value' in opt)) b = opt.text } return [a.name, b] }, selectMany: function(a) { var b = new Array(); for (var i = 0; i < a.length; i++) { var c = a.options[i]; if (c.selected) { var d = c.value; if (!d && !('value' in c)) d = c.text; b.push(d) } } return [a.name, b] } }; var $F = Form.Element.getValue; Abstract.TimedObserver = function() { }; Abstract.TimedObserver.prototype = { initialize: function(a, b, c) { this.frequency = b; this.element = $(a); this.callback = c; this.lastValue = this.getValue(); this.registerCallback() }, registerCallback: function() { setInterval(this.onTimerEvent.bind(this), this.frequency * 1000) }, onTimerEvent: function() { var a = this.getValue(); if (this.lastValue != a) { this.callback(this.element, a); this.lastValue = a } } }; 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(a, b) { this.element = $(a); this.callback = b; this.lastValue = this.getValue(); if (this.element.tagName.toLowerCase() == 'form') this.registerFormCallbacks(); else this.registerCallback(this.element) }, onElementEvent: function() { var a = this.getValue(); if (this.lastValue != a) { this.callback(this.element, a); this.lastValue = a } }, registerFormCallbacks: function() { var a = Form.getElements(this.element); for (var i = 0; i < a.length; i++) this.registerCallback(a[i]) }, registerCallback: function(a) { if (a.type) { switch (a.type.toLowerCase()) { case 'checkbox': case 'radio': Event.observe(a, 'click', this.onElementEvent.bind(this)); break; case 'password': case 'text': case 'textarea': case 'select-one': case 'select-multiple': Event.observe(a, '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, element: function(a) { return a.target || a.srcElement }, isLeftClick: function(a) { return (((a.which) && (a.which == 1)) || ((a.button) && (a.button == 1))) }, pointerX: function(a) { return a.pageX || (a.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft)) }, pointerY: function(a) { return a.pageY || (a.clientY + (document.documentElement.scrollTop || document.body.scrollTop)) }, stop: function(a) { if (a.preventDefault) { a.preventDefault(); a.stopPropagation() } else { a.returnValue = false; a.cancelBubble = true } }, findElement: function(a, b) { var c = Event.element(a); while (c.parentNode && (!c.tagName || (c.tagName.toUpperCase() != b.toUpperCase()))) c = c.parentNode; return c }, observers: false, _observeAndCache: function(a, b, c, d) { if (!this.observers) this.observers = []; if (a.addEventListener) { this.observers.push([a, b, c, d]); a.addEventListener(b, c, d) } else if (a.attachEvent) { this.observers.push([a, b, c, d]); a.attachEvent('on' + b, c) } }, unloadCache: function() { if (!Event.observers) return; for (var i = 0; i < Event.observers.length; i++) { Event.stopObserving.apply(this, Event.observers[i]); Event.observers[i][0] = null } Event.observers = false }, observe: function(a, b, c, d) { var a = $(a); d = d || false; if (b == 'keypress' && (navigator.appVersion.match(/Konqueror|Safari|KHTML/) || a.attachEvent)) b = 'keydown'; this._observeAndCache(a, b, c, d) }, stopObserving: function(a, b, c, d) { var a = $(a); d = d || false; if (b == 'keypress' && (navigator.appVersion.match(/Konqueror|Safari|KHTML/) || a.detachEvent)) b = 'keydown'; if (a.removeEventListener) { a.removeEventListener(b, c, d) } else if (a.detachEvent) { a.detachEvent('on' + b, c) } } }); 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(a) { var b = 0, valueL = 0; do { b += a.scrollTop || 0; valueL += a.scrollLeft || 0; a = a.parentNode } while (a); return [valueL, b] }, cumulativeOffset: function(a) { var b = 0, valueL = 0; do { b += a.offsetTop || 0; valueL += a.offsetLeft || 0; a = a.offsetParent } while (a); return [valueL, b] }, positionedOffset: function(a) { var b = 0, valueL = 0; do { b += a.offsetTop || 0; valueL += a.offsetLeft || 0; a = a.offsetParent; if (a) { p = Element.getStyle(a, 'position'); if (p == 'relative' || p == 'absolute') break } } while (a); return [valueL, b] }, offsetParent: function(a) { if (a.offsetParent) return a.offsetParent; if (a == document.body) return a; while ((a = a.parentNode) && a != document.body) if (Element.getStyle(a, 'position') != 'static') return a; return document.body }, within: function(a, b, c) { if (this.includeScrollOffsets) return this.withinIncludingScrolloffsets(a, b, c); this.xcomp = b; this.ycomp = c; this.offset = this.cumulativeOffset(a); return (c >= this.offset[1] && c < this.offset[1] + a.offsetHeight && b >= this.offset[0] && b < this.offset[0] + a.offsetWidth) }, withinIncludingScrolloffsets: function(a, b, c) { var d = this.realOffset(a); this.xcomp = b + d[0] - this.deltaX; this.ycomp = c + d[1] - this.deltaY; this.offset = this.cumulativeOffset(a); return (this.ycomp >= this.offset[1] && this.ycomp < this.offset[1] + a.offsetHeight && this.xcomp >= this.offset[0] && this.xcomp < this.offset[0] + a.offsetWidth) }, overlap: function(a, b) { if (!a) return 0; if (a == 'vertical') return ((this.offset[1] + b.offsetHeight) - this.ycomp) / b.offsetHeight; if (a == 'horizontal') return ((this.offset[0] + b.offsetWidth) - this.xcomp) / b.offsetWidth }, clone: function(a, b) { a = $(a); b = $(b); b.style.position = 'absolute'; var c = this.cumulativeOffset(a); b.style.top = c[1] + 'px'; b.style.left = c[0] + 'px'; b.style.width = a.offsetWidth + 'px'; b.style.height = a.offsetHeight + 'px' }, page: function(a) { var b = 0, valueL = 0; var c = a; do { b += c.offsetTop || 0; valueL += c.offsetLeft || 0; if (c.offsetParent == document.body) if (Element.getStyle(c, 'position') == 'absolute') break } while (c = c.offsetParent); c = a; do { b -= c.scrollTop || 0; valueL -= c.scrollLeft || 0 } while (c = c.parentNode); return [valueL, b] }, clone: function(a, b) { var c = Object.extend({ setLeft: true, setTop: true, setWidth: true, setHeight: true, offsetTop: 0, offsetLeft: 0 }, arguments[2] || {}); a = $(a); var p = Position.page(a); b = $(b); var d = [0, 0]; var e = null; if (Element.getStyle(b, 'position') == 'absolute') { e = Position.offsetParent(b); d = Position.page(e) } if (e == document.body) { d[0] -= document.body.offsetLeft; d[1] -= document.body.offsetTop } if (c.setLeft) b.style.left = (p[0] - d[0] + c.offsetLeft) + 'px'; if (c.setTop) b.style.top = (p[1] - d[1] + c.offsetTop) + 'px'; if (c.setWidth) b.style.width = a.offsetWidth + 'px'; if (c.setHeight) b.style.height = a.offsetHeight + 'px' }, absolutize: function(a) { a = $(a); if (a.style.position == 'absolute') return; Position.prepare(); var b = Position.positionedOffset(a); var c = b[1]; var d = b[0]; var e = a.clientWidth; var f = a.clientHeight; a._originalLeft = d - parseFloat(a.style.left || 0); a._originalTop = c - parseFloat(a.style.top || 0); a._originalWidth = a.style.width; a._originalHeight = a.style.height; a.style.position = 'absolute'; a.style.top = c + 'px'; a.style.left = d + 'px'; a.style.width = e + 'px'; a.style.height = f + 'px' }, relativize: function(a) { a = $(a); if (a.style.position == 'relative') return; Position.prepare(); a.style.position = 'relative'; var b = parseFloat(a.style.top || 0) - (a._originalTop || 0); var c = parseFloat(a.style.left || 0) - (a._originalLeft || 0); a.style.top = b + 'px'; a.style.left = c + 'px'; a.style.height = a._originalHeight; a.style.width = a._originalWidth } }; if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) { Position.cumulativeOffset = function(a) { var b = 0, valueL = 0; do { b += a.offsetTop || 0; valueL += a.offsetLeft || 0; if (a.offsetParent == document.body) if (Element.getStyle(a, 'position') == 'absolute') break; a = a.offsetParent } while (a); return [valueL, b] } }

/*
moo.fx, simple effects library built with prototype.js (http://prototype.conio.net).
by Valerio Proietti (http://mad4milk.net) MIT-style LICENSE.
for more info (http://moofx.mad4milk.net).
Sunday, March 05, 2006
v 1.2.3
*/

var fx = new Object();
//base
fx.Base = function() { };
fx.Base.prototype = {
    setOptions: function(options) {
        this.options = {
            duration: 500,
            onComplete: '',
            transition: fx.sinoidal
        }
        Object.extend(this.options, options || {});
    },

    step: function() {
        var time = (new Date).getTime();
        if (time >= this.options.duration + this.startTime) {
            this.now = this.to;
            clearInterval(this.timer);
            this.timer = null;
            if (this.options.onComplete) setTimeout(this.options.onComplete.bind(this), 10);
        }
        else {
            var Tpos = (time - this.startTime) / (this.options.duration);
            this.now = this.options.transition(Tpos) * (this.to - this.from) + this.from;
        }
        this.increase();
    },

    custom: function(from, to) {
        if (this.timer != null) return;
        this.from = from;
        this.to = to;
        this.startTime = (new Date).getTime();
        this.timer = setInterval(this.step.bind(this), 13);
    },

    hide: function() {
        this.now = 0;
        this.increase();
    },

    clearTimer: function() {
        clearInterval(this.timer);
        this.timer = null;
    }
}

//stretchers
fx.Layout = Class.create();
fx.Layout.prototype = Object.extend(new fx.Base(), {
    initialize: function(el, options) {
        this.el = $(el);
        this.el.style.overflow = "hidden";
        this.iniWidth = this.el.offsetWidth;
        this.iniHeight = this.el.offsetHeight;
        this.setOptions(options);
    }
});

fx.Height = Class.create();
Object.extend(Object.extend(fx.Height.prototype, fx.Layout.prototype), {
    increase: function() {
        this.el.style.height = this.now + "px";
    },

    toggle: function() {
        if (this.el.offsetHeight > 0) this.custom(this.el.offsetHeight, 0);
        else this.custom(0, this.el.scrollHeight);
    }
});

fx.Width = Class.create();
Object.extend(Object.extend(fx.Width.prototype, fx.Layout.prototype), {
    increase: function() {
        this.el.style.width = this.now + "px";
    },

    toggle: function() {
        if (this.el.offsetWidth > 0) this.custom(this.el.offsetWidth, 0);
        else this.custom(0, this.iniWidth);
    }
});

//fader
fx.Opacity = Class.create();
fx.Opacity.prototype = Object.extend(new fx.Base(), {
    initialize: function(el, options) {
        this.el = $(el);
        this.now = 1;
        this.increase();
        this.setOptions(options);
    },

    increase: function() {
        if (this.now == 1 && (/Firefox/.test(navigator.userAgent))) this.now = 0.9999;
        this.setOpacity(this.now);
    },

    setOpacity: function(opacity) {
        if (opacity == 0 && this.el.style.visibility != "hidden") this.el.style.visibility = "hidden";
        else if (this.el.style.visibility != "visible") this.el.style.visibility = "visible";
        if (window.ActiveXObject) this.el.style.filter = "alpha(opacity=" + opacity * 100 + ")";
        this.el.style.opacity = opacity;
    },

    toggle: function() {
        if (this.now > 0) this.custom(1, 0);
        else this.custom(0, 1);
    }
});

//transitions
fx.sinoidal = function(pos) {
    return ((-Math.cos(pos * Math.PI) / 2) + 0.5);
    //this transition is from script.aculo.us
}
fx.linear = function(pos) {
    return pos;
}
fx.cubic = function(pos) {
    return Math.pow(pos, 3);
}
fx.circ = function(pos) {
    return Math.sqrt(pos);
}

/*
moo.fx pack, effects extensions for moo.fx.
by Valerio Proietti (http://mad4milk.net) MIT-style LICENSE
for more info visit (http://moofx.mad4milk.net).
Friday, April 14, 2006
v 1.2.4
*/

//smooth scroll
fx.Scroll = Class.create();
fx.Scroll.prototype = Object.extend(new fx.Base(), {
    initialize: function(options) {
        this.setOptions(options);
    },

    scrollTo: function(el) {
        var dest = Position.cumulativeOffset($(el))[1];
        var client = window.innerHeight || document.documentElement.clientHeight;
        var full = document.documentElement.scrollHeight;
        var top = window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop;
        if (dest + client > full) this.custom(top, dest - client + (full - dest));
        else this.custom(top, dest);
    },

    increase: function() {
        window.scrollTo(0, this.now);
    }
});

//text size modify, now works with pixels too.
fx.Text = Class.create();
fx.Text.prototype = Object.extend(new fx.Base(), {
    initialize: function(el, options) {
        this.el = $(el);
        this.setOptions(options);
        if (!this.options.unit) this.options.unit = "em";
    },

    increase: function() {
        this.el.style.fontSize = this.now + this.options.unit;
    }
});

//composition effect: widht/height/opacity
fx.Combo = Class.create();
fx.Combo.prototype = {
    setOptions: function(options) {
        this.options = {
            opacity: true,
            height: true,
            width: false
        }
        Object.extend(this.options, options || {});
    },

    initialize: function(el, options) {
        this.el = $(el);
        this.setOptions(options);
        if (this.options.opacity) {
            this.o = new fx.Opacity(el, options);
            options.onComplete = null;
        }
        if (this.options.height) {
            this.h = new fx.Height(el, options);
            options.onComplete = null;
        }
        if (this.options.width) this.w = new fx.Width(el, options);
    },

    toggle: function() { this.checkExec('toggle'); },

    hide: function() { this.checkExec('hide'); },

    clearTimer: function() { this.checkExec('clearTimer'); },

    checkExec: function(func) {
        if (this.o) this.o[func]();
        if (this.h) this.h[func]();
        if (this.w) this.w[func]();
    },

    //only if width+height
    resizeTo: function(hto, wto) {
        if (this.h && this.w) {
            this.h.custom(this.el.offsetHeight, this.el.offsetHeight + hto);
            this.w.custom(this.el.offsetWidth, this.el.offsetWidth + wto);
        }
    },

    customSize: function(hto, wto) {
        if (this.h && this.w) {
            this.h.custom(this.el.offsetHeight, hto);
            this.w.custom(this.el.offsetWidth, wto);
        }
    }
}

fx.Accordion = Class.create();
fx.Accordion.prototype = {
    setOptions: function(options) {
        this.options = {
            delay: 100,
            opacity: false
        }
        Object.extend(this.options, options || {});
    },

    initialize: function(togglers, elements, options) {
        this.elements = elements;
        this.setOptions(options);
        var options = options || '';
        this.fxa = [];
        if (options && options.onComplete) options.onFinish = options.onComplete;
        elements.each(function(el, i) {
            options.onComplete = function() {
                if (el.offsetHeight > 0) el.style.height = '1%';
                if (options.onFinish) options.onFinish(el);
            }
            this.fxa[i] = new fx.Combo(el, options);
            this.fxa[i].hide();
        } .bind(this));

        togglers.each(function(tog, i) {
            if (typeof tog.onclick == 'function') var exClick = tog.onclick;
            tog.onclick = function() {
                if (exClick) exClick();
                this.showThisHideOpen(elements[i]);
            } .bind(this);
        } .bind(this));
    },

    showThisHideOpen: function(toShow) {
        this.elements.each(function(el, j) {
            if (el.offsetHeight > 0 && el != toShow) this.clearAndToggle(el, j);
            if (el == toShow && toShow.offsetHeight == 0) setTimeout(function() { this.clearAndToggle(toShow, j); } .bind(this), this.options.delay);
        } .bind(this));
    },

    clearAndToggle: function(el, i) {
        this.fxa[i].clearTimer();
        this.fxa[i].toggle();
    }
}

var Remember = new Object();
Remember = function() { };
Remember.prototype = {
    initialize: function(el, options) {
        this.el = $(el);
        this.days = 365;
        this.options = options;
        this.effect();
        var cookie = this.readCookie();
        if (cookie) {
            this.fx.now = cookie;
            this.fx.increase();
        }
    },

    //cookie functions based on code by Peter-Paul Koch
    setCookie: function(value) {
        var date = new Date();
        date.setTime(date.getTime() + (this.days * 24 * 60 * 60 * 1000));
        var expires = "; expires=" + date.toGMTString();
        document.cookie = this.el + this.el.id + this.prefix + "=" + value + expires + "; path=/";
    },

    readCookie: function() {
        var nameEQ = this.el + this.el.id + this.prefix + "=";
        var ca = document.cookie.split(';');
        for (var i = 0; c = ca[i]; i++) {
            while (c.charAt(0) == ' ') c = c.substring(1, c.length);
            if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
        }
        return false;
    },

    custom: function(from, to) {
        if (this.fx.now != to) {
            this.setCookie(to);
            this.fx.custom(from, to);
        }
    }
}

fx.RememberHeight = Class.create();
fx.RememberHeight.prototype = Object.extend(new Remember(), {
    effect: function() {
        this.fx = new fx.Height(this.el, this.options);
        this.prefix = 'height';
    },

    toggle: function() {
        if (this.el.offsetHeight == 0) this.setCookie(this.el.scrollHeight);
        else this.setCookie(0);
        this.fx.toggle();
    },

    resize: function(to) {
        this.setCookie(this.el.offsetHeight + to);
        this.fx.custom(this.el.offsetHeight, this.el.offsetHeight + to);
    },

    hide: function() {
        if (!this.readCookie()) {
            this.fx.hide();
        }
    }
});

fx.RememberText = Class.create();
fx.RememberText.prototype = Object.extend(new Remember(), {
    effect: function() {
        this.fx = new fx.Text(this.el, this.options);
        this.prefix = 'text';
    }
});

//useful for-replacement
Array.prototype.iterate = function(func) {
    for (var i = 0; i < this.length; i++) func(this[i], i);
}
if (!Array.prototype.each) Array.prototype.each = Array.prototype.iterate;

//Easing Equations (c) 2003 Robert Penner, all rights reserved.
//This work is subject to the terms in http://www.robertpenner.com/easing_terms_of_use.html.

//expo
fx.expoIn = function(pos) {
    return Math.pow(2, 10 * (pos - 1));
}
fx.expoOut = function(pos) {
    return (-Math.pow(2, -10 * pos) + 1);
}

//quad
fx.quadIn = function(pos) {
    return Math.pow(pos, 2);
}
fx.quadOut = function(pos) {
    return -(pos) * (pos - 2);
}

//circ
fx.circOut = function(pos) {
    return Math.sqrt(1 - Math.pow(pos - 1, 2));
}
fx.circIn = function(pos) {
    return -(Math.sqrt(1 - Math.pow(pos, 2)) - 1);
}

//back
fx.backIn = function(pos) {
    return (pos) * pos * ((2.7) * pos - 1.7);
}
fx.backOut = function(pos) {
    return ((pos - 1) * (pos - 1) * ((2.7) * (pos - 1) + 1.7) + 1);
}

//sine
fx.sineOut = function(pos) {
    return Math.sin(pos * (Math.PI / 2));
}
fx.sineIn = function(pos) {
    return -Math.cos(pos * (Math.PI / 2)) + 1;
}
fx.sineInOut = function(pos) {
    return -(Math.cos(Math.PI * pos) - 1) / 2;
}

var scroller = new fx.Scroll(window, { duration: 900 });
var m3_u = (location.protocol == 'https:' ? 'https://d1.openx.org/ajs.php' : 'http://d1.openx.org/ajs.php');
var m3_r = Math.floor(Math.random() * 99999999999);

function redirectTo(headingUrl) {
    location.href = headingUrl;
}

function validateSearchAction() {
    if ($F('select-location') == '' || $F('select-location') == null) {
        return false;
    }
}

function initAnalytics() {
    _uacct = "UA-1020066-1";
    _uff = 0;
    _udn = "munchpunch.com";
    urchinTracker();

    _uacct = "UA-1020066-4";

    try {
        var featuredElements = document.getElementsByClassName('result-premium');
    
        for(j = 0; j < featuredElements.length; j++) {   
            _uff = 0;     
            urchinTracker('/paid/featured/' + featuredElements[j].id); 
        }
    } catch (err) { }  

    try {
        var dealItemElements = document.getElementsByClassName('item-deal');

        for(i = 0; i < dealItemElements.length; i++) {
            _uff = 0;
            urchinTracker('/paid/deals/' + dealItemElements[i].id);
        }
    } catch (err) { }

    try {
        reinvigorate.track("cm10g-150i400ary");
    } catch (err) { }

    clicky.init(247445);
}

function logClick(clickId) {
    _uacct = "UA-1020066-4";
    _uff = 0;
    urchinTracker('/paid/click/' + clickId);
}