//MooTools, My Object Oriented Javascript Tools. Copyright (c) 2006 Valerio Proietti, , MIT Style License. var Class = function(properties){ var klass = function(){ if (this.initialize && arguments[0] != 'noinit') return this.initialize.apply(this, arguments); else return this; }; for (var property in this) klass[property] = this[property]; klass.prototype = properties; return klass; }; Class.empty = function(){}; Class.prototype = { extend: function(properties){ var pr0t0typ3 = new this('noinit'); var parentize = function(previous, current){ if (!previous.apply || !current.apply) return false; return function(){ this.parent = previous; return current.apply(this, arguments); }; }; for (var property in properties){ var previous = pr0t0typ3[property]; var current = properties[property]; if (previous && previous != current) current = parentize(previous, current) || current; pr0t0typ3[property] = current; } return new Class(pr0t0typ3); }, implement: function(properties){ for (var property in properties) this.prototype[property] = properties[property]; } }; Object.extend = function(){ var args = arguments; args = (args[1]) ? [args[0], args[1]] : [this, args[0]]; for (var property in args[1]) args[0][property] = args[1][property]; return args[0]; }; Object.Native = function(){ for (var i = 0; i < arguments.length; i++) arguments[i].extend = Class.prototype.implement; }; new Object.Native(Function, Array, String, Number, Class); if (typeof HTMLElement == 'undefined'){ var HTMLElement = Class.empty; HTMLElement.prototype = {}; } else { HTMLElement.prototype.htmlElement = true; } window.extend = document.extend = Object.extend; var Window = window; function $type(obj){ if (obj === null || obj === undefined) return false; var type = typeof obj; if (type == 'object'){ if (obj.htmlElement) return 'element'; if (obj.push) return 'array'; if (obj.nodeName){ switch (obj.nodeType){ case 1: return 'element'; case 3: return obj.nodeValue.test(/\S/) ? 'textnode' : 'whitespace'; } } } return type; }; function $chk(obj){ return !!(obj || obj === 0); }; function $pick(obj, picked){ return ($type(obj)) ? obj : picked; }; function $random(min, max){ return Math.floor(Math.random() * (max - min + 1) + min); }; function $clear(timer){ clearTimeout(timer); clearInterval(timer); return null; }; if (window.ActiveXObject) window.ie = window[window.XMLHttpRequest ? 'ie7' : 'ie6'] = true; else if (document.childNodes && !document.all && !navigator.taintEnabled) window.khtml = true; else if (document.getBoxObjectFor != null) window.gecko = true; if (window.ie6) try {document.execCommand("BackgroundImageCache", false, true);} catch (e){}; Array.prototype.forEach = Array.prototype.forEach || function(fn, bind){ for (var i = 0; i < this.length; i++) fn.call(bind, this[i], i, this); }; Array.prototype.filter = Array.prototype.filter || function(fn, bind){ var results = []; for (var i = 0; i < this.length; i++){ if (fn.call(bind, this[i], i, this)) results.push(this[i]); } return results; }; Array.prototype.map = Array.prototype.map || function(fn, bind){ var results = []; for (var i = 0; i < this.length; i++) results[i] = fn.call(bind, this[i], i, this); return results; }; Array.prototype.every = Array.prototype.every || function(fn, bind){ for (var i = 0; i < this.length; i++){ if (!fn.call(bind, this[i], i, this)) return false; } return true; }; Array.prototype.some = Array.prototype.some || function(fn, bind){ for (var i = 0; i < this.length; i++){ if (fn.call(bind, this[i], i, this)) return true; } return false; }; Array.prototype.indexOf = Array.prototype.indexOf || function(item, from){ from = from || 0; if (from < 0) from = Math.max(0, this.length + from); while (from < this.length){ if(this[from] === item) return from; from++; } return -1; }; Array.extend({ each: Array.prototype.forEach, copy: function(start, length){ start = start || 0; if (start < 0) start = this.length + start; length = length || (this.length - start); var newArray = []; for (var i = 0; i < length; i++) newArray[i] = this[start++]; return newArray; }, remove: function(item){ var i = 0; while (i < this.length){ if (this[i] === item) this.splice(i, 1); else i++; } return this; }, test: function(item, from){ return this.indexOf(item, from) != -1; }, extend: function(newArray){ for (var i = 0; i < newArray.length; i++) this.push(newArray[i]); return this; }, associate: function(keys){ var obj = {}, length = Math.min(this.length, keys.length); for (var i = 0; i < length; i++) obj[keys[i]] = this[i]; return obj; } }); function $A(array, start, length){ return Array.prototype.copy.call(array, start, length); }; function $each(iterable, fn, bind){ return Array.prototype.forEach.call(iterable, fn, bind); }; String.extend({ test: function(regex, params){ return ((typeof regex == 'string') ? new RegExp(regex, params) : regex).test(this); }, toInt: function(){ return parseInt(this); }, toFloat: function(){ return parseFloat(this); }, camelCase: function(){ return this.replace(/-\D/g, function(match){ return match.charAt(1).toUpperCase(); }); }, hyphenate: function(){ return this.replace(/\w[A-Z]/g, function(match){ return (match.charAt(0)+'-'+match.charAt(1).toLowerCase()); }); }, capitalize: function(){ return this.toLowerCase().replace(/\b[a-z]/g, function(match){ return match.toUpperCase(); }); }, trim: function(){ return this.replace(/^\s+|\s+$/g, ''); }, clean: function(){ return this.replace(/\s{2,}/g, ' ').trim(); }, rgbToHex: function(array){ var rgb = this.match(/\d{1,3}/g); return (rgb) ? rgb.rgbToHex(array) : false; }, hexToRgb: function(array){ var hex = this.match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/); return (hex) ? hex.slice(1).hexToRgb(array) : false; } }); Array.extend({ rgbToHex: function(array){ if (this.length < 3) return false; if (this[3] && (this[3] == 0) && !array) return 'transparent'; var hex = []; for (var i = 0; i < 3; i++){ var bit = (this[i]-0).toString(16); hex.push((bit.length == 1) ? '0'+bit : bit); } return array ? hex : '#'+hex.join(''); }, hexToRgb: function(array){ if (this.length != 3) return false; var rgb = []; for (var i = 0; i < 3; i++){ rgb.push(parseInt((this[i].length == 1) ? this[i]+this[i] : this[i], 16)); } return array ? rgb : 'rgb('+rgb.join(',')+')'; } }); Number.extend({ toInt: function(){ return parseInt(this); }, toFloat: function(){ return parseFloat(this); } }); Function.extend({ create: function(options){ var fn = this; options = Object.extend({ 'bind': fn, 'event': false, 'arguments': null, 'delay': false, 'periodical': false, 'attempt': false }, options || {}); if ($chk(options.arguments) && $type(options.arguments) != 'array') options.arguments = [options.arguments]; return function(event){ var args; if (options.event){ event = event || window.event; args = [(options.event === true) ? event : new options.event(event)]; if (options.arguments) args = args.concat(options.arguments); } else args = options.arguments || arguments; var returns = function(){ return fn.apply(options.bind, args); }; if (options.delay) return setTimeout(returns, options.delay); if (options.periodical) return setInterval(returns, options.periodical); if (options.attempt){ try { return returns(); } catch(err){ return err; } } return returns(); }; }, pass: function(args, bind){ return this.create({'arguments': args, 'bind': bind}); }, attempt: function(args, bind){ return this.create({'arguments': args, 'bind': bind, 'attempt': true})(); }, bind: function(bind, args){ return this.create({'bind': bind, 'arguments': args}); }, bindAsEventListener: function(bind, args){ return this.create({'bind': bind, 'event': true, 'arguments': args}); }, delay: function(ms, bind, args){ return this.create({'delay': ms, 'bind': bind, 'arguments': args})(); }, periodical: function(ms, bind, args){ return this.create({'periodical': ms, 'bind': bind, 'arguments': args})(); } }); var Element = new Class({ initialize: function(el){ if ($type(el) == 'string') el = document.createElement(el); return $(el); } }); function $(el){ if (!el) return false; if (el._element_extended_ || [window, document].test(el)) return el; if ($type(el) == 'string') el = document.getElementById(el); if ($type(el) != 'element') return false; if (['object', 'embed'].test(el.tagName.toLowerCase()) || el.extend) return el; el._element_extended_ = true; Garbage.collect(el); el.extend = Object.extend; if (!(el.htmlElement)) el.extend(Element.prototype); return el; }; var Elements = new Class({}); new Object.Native(Elements); document.getElementsBySelector = document.getElementsByTagName; function $$(){ if (!arguments) return false; if (arguments.length == 1){ if (!arguments[0]) return false; if (arguments[0]._elements_extended_) return arguments[0]; } var elements = []; $each(arguments, function(selector){ switch ($type(selector)){ case 'element': elements.push($(selector)); break; case 'string': selector = document.getElementsBySelector(selector); default: if (selector.length){ $each(selector, function(el){ if ($(el)) elements.push(el); }); } } }); elements._elements_extended_ = true; return Object.extend(elements, new Elements); }; Elements.Multi = function(property){ return function(){ var args = arguments; var items = []; var elements = true; $each(this, function(el){ var returns = el[property].apply(el, args); if ($type(returns) != 'element') elements = false; items.push(returns); }); if (elements) items = $$(items); return items; }; }; Element.extend = function(properties){ for (var property in properties){ HTMLElement.prototype[property] = properties[property]; Element.prototype[property] = properties[property]; Elements.prototype[property] = Elements.Multi(property); } }; Element.extend({ inject: function(el, where){ el = $(el) || new Element(el); switch (where){ case "before": $(el.parentNode).insertBefore(this, el); break; case "after": if (!el.getNext()) $(el.parentNode).appendChild(this); else $(el.parentNode).insertBefore(this, el.getNext()); break; case "inside": el.appendChild(this); } return this; }, injectBefore: function(el){ return this.inject(el, 'before'); }, injectAfter: function(el){ return this.inject(el, 'after'); }, injectInside: function(el){ return this.inject(el, 'inside'); }, adopt: function(el){ this.appendChild($(el) || new Element(el)); return this; }, remove: function(){ this.parentNode.removeChild(this); return this; }, clone: function(contents){ var el = this.cloneNode(contents !== false); return $(el); }, replaceWith: function(el){ el = $(el) || new Element(el); this.parentNode.replaceChild(el, this); return el; }, appendText: function(text){ if (window.ie){ switch(this.getTag()){ case 'style': this.styleSheet.cssText = text; return this; case 'script': this.setProperty('text', text); return this; } } this.appendChild(document.createTextNode(text)); return this; }, hasClass: function(className){ return this.className.test('(?:^|\\s)'+className+'(?:\\s|$)'); }, addClass: function(className){ if (!this.hasClass(className)) this.className = (this.className+' '+className).clean(); return this; }, removeClass: function(className){ this.className = this.className.replace(new RegExp('(^|\\s)'+className+'(?:\\s|$)'), '$1').clean(); return this; }, toggleClass: function(className){ return this.hasClass(className) ? this.removeClass(className) : this.addClass(className); }, setStyle: function(property, value){ if (property == 'opacity') this.setOpacity(parseFloat(value)); else this.style[property.camelCase()] = (value.push) ? 'rgb('+value.join(',')+')' : value; return this; }, setStyles: function(source){ switch ($type(source)){ case 'object': for (var property in source) this.setStyle(property, source[property]); break; case 'string': this.style.cssText = source; } return this; }, setOpacity: function(opacity){ if (opacity == 0){ if(this.style.visibility != "hidden") this.style.visibility = "hidden"; } else { if(this.style.visibility != "visible") this.style.visibility = "visible"; } if (!this.currentStyle || !this.currentStyle.hasLayout) this.style.zoom = 1; if (window.ie) this.style.filter = "alpha(opacity=" + opacity*100 + ")"; this.style.opacity = this.opacity = opacity; return this; }, getStyle: function(property){ property = property.camelCase(); var style = this.style[property] || false; if (!$chk(style)){ if (property == 'opacity') return $chk(this.opacity) ? this.opacity : 1; if (['margin', 'padding'].test(property)){ return [this.getStyle(property+'-top') || 0, this.getStyle(property+'-right') || 0, this.getStyle(property+'-bottom') || 0, this.getStyle(property+'-left') || 0].join(' '); } if (document.defaultView) style = document.defaultView.getComputedStyle(this, null).getPropertyValue(property.hyphenate()); else if (this.currentStyle) style = this.currentStyle[property]; } if (style == 'auto' && ['height', 'width'].test(property)) return this['offset'+property.capitalize()]+'px'; return (style && property.test(/color/i) && style.test(/rgb/)) ? style.rgbToHex() : style; }, addEvent: function(type, fn){ this.events = this.events || {}; this.events[type] = this.events[type] || {'keys': [], 'values': []}; if (!this.events[type].keys.test(fn)){ this.events[type].keys.push(fn); if (this.addEventListener){ this.addEventListener((type == 'mousewheel' && window.gecko) ? 'DOMMouseScroll' : type, fn, false); } else { fn = fn.bind(this); this.attachEvent('on'+type, fn); this.events[type].values.push(fn); } } return this; }, addEvents: function(source){ if (source){ for (var type in source) this.addEvent(type, source[type]); } return this; }, removeEvent: function(type, fn){ if (this.events && this.events[type]){ var pos = this.events[type].keys.indexOf(fn); if (pos == -1) return this; var key = this.events[type].keys.splice(pos,1)[0]; if (this.removeEventListener){ this.removeEventListener((type == 'mousewheel' && window.gecko) ? 'DOMMouseScroll' : type, key, false); } else { this.detachEvent('on'+type, this.events[type].values.splice(pos,1)[0]); } } return this; }, removeEvents: function(type){ if (this.events){ if (type){ if (this.events[type]){ this.events[type].keys.each(function(fn){ this.removeEvent(type, fn); }, this); this.events[type] = null; } } else { for (var evType in this.events) this.removeEvents(evType); this.events = null; } } return this; }, fireEvent: function(type, args){ if (this.events && this.events[type]){ this.events[type].keys.each(function(fn){ fn.bind(this, args)(); }, this); } }, getBrother: function(what){ var el = this[what+'Sibling']; while ($type(el) == 'whitespace') el = el[what+'Sibling']; return $(el); }, getPrevious: function(){ return this.getBrother('previous'); }, getNext: function(){ return this.getBrother('next'); }, getFirst: function(){ var el = this.firstChild; while ($type(el) == 'whitespace') el = el.nextSibling; return $(el); }, getLast: function(){ var el = this.lastChild; while ($type(el) == 'whitespace') el = el.previousSibling; return $(el); }, getParent: function(){ return $(this.parentNode); }, getChildren: function(){ return $$(this.childNodes); }, setProperty: function(property, value){ switch (property){ case 'class': this.className = value; break; case 'style': this.setStyles(value); break; case 'name': if (window.ie6){ var el = $(document.createElement('<'+this.getTag()+' name="'+value+'" />')); $each(this.attributes, function(attribute){ if (attribute.name != 'name') el.setProperty(attribute.name, attribute.value); }); if (this.parentNode) this.replaceWith(el); return el; } default: this.setAttribute(property, value); } return this; }, setProperties: function(source){ for (var property in source) this.setProperty(property, source[property]); return this; }, setHTML: function(){ this.innerHTML = $A(arguments).join(''); return this; }, getProperty: function(property){ return (property == 'class') ? this.className : this.getAttribute(property); }, getTag: function(){ return this.tagName.toLowerCase(); }, scrollTo: function(x, y){ this.scrollLeft = x; this.scrollTop = y; }, getValue: function(){ switch (this.getTag()){ case 'select': if (this.selectedIndex != -1){ var opt = this.options[this.selectedIndex]; return opt.value || opt.text; } break; case 'input': if (!(this.checked && ['checkbox', 'radio'].test(this.type)) && !['hidden', 'text', 'password'].test(this.type)) break; case 'textarea': return this.value; } return false; }, getSize: function(){ return { 'scroll': {'x': this.scrollLeft, 'y': this.scrollTop}, 'size': {'x': this.offsetWidth, 'y': this.offsetHeight}, 'scrollSize': {'x': this.scrollWidth, 'y': this.scrollHeight} }; }, getPosition: function(overflown){ overflown = overflown || []; var el = this, left = 0, top = 0; do { left += el.offsetLeft || 0; top += el.offsetTop || 0; el = el.offsetParent; } while (el); overflown.each(function(element){ left -= element.scrollLeft || 0; top -= element.scrollTop || 0; }); return {'x': left, 'y': top}; }, getTop: function(){ return this.getPosition().y; }, getLeft: function(){ return this.getPosition().x; }, getCoordinates: function(overflown){ var position = this.getPosition(overflown); var obj = { 'width': this.offsetWidth, 'height': this.offsetHeight, 'left': position.x, 'top': position.y }; obj.right = obj.left + obj.width; obj.bottom = obj.top + obj.height; return obj; } }); window.addEvent = document.addEvent = Element.prototype.addEvent; window.removeEvent = document.removeEvent = Element.prototype.removeEvent; window.removeEvents = document.removeEvents = Element.prototype.removeEvents; var Garbage = { elements: [], collect: function(element){ Garbage.elements.push(element); }, trash: function(){ Garbage.collect(window); Garbage.collect(document); Garbage.elements.each(function(el){ el.removeEvents(); for (var p in Element.prototype) el[p] = null; el.extend = null; }); } }; window.addEvent('unload', Garbage.trash); var Event = new Class({ initialize: function(event){ this.event = event || window.event; this.type = this.event.type; this.target = this.event.target || this.event.srcElement; if (this.target.nodeType == 3) this.target = this.target.parentNode; this.shift = this.event.shiftKey; this.control = this.event.ctrlKey; this.alt = this.event.altKey; this.meta = this.event.metaKey; if (['DOMMouseScroll', 'mousewheel'].test(this.type)){ this.wheel = this.event.wheelDelta ? (this.event.wheelDelta / (window.opera ? -120 : 120)) : -(this.event.detail || 0) / 3; } else if (this.type.test(/key/)){ this.code = this.event.which || this.event.keyCode; for (var name in Event.keys){ if (Event.keys[name] == this.code){ this.key = name; break; } } this.key = this.key || String.fromCharCode(this.code).toLowerCase(); } else if (this.type.test(/mouse/) || (this.type == 'click')){ this.page = { 'x': this.event.pageX || this.event.clientX + document.documentElement.scrollLeft, 'y': this.event.pageY || this.event.clientY + document.documentElement.scrollTop }; this.client = { 'x': this.event.pageX ? this.event.pageX - window.pageXOffset : this.event.clientX, 'y': this.event.pageY ? this.event.pageY - window.pageYOffset : this.event.clientY }; this.rightClick = (this.event.which == 3) || (this.event.button == 2); switch (this.type){ case 'mouseover': this.relatedTarget = this.event.relatedTarget || this.event.fromElement; break; case 'mouseout': this.relatedTarget = this.event.relatedTarget || this.event.toElement; } } }, stop: function() { this.stopPropagation(); this.preventDefault(); return this; }, stopPropagation: function(){ if (this.event.stopPropagation) this.event.stopPropagation(); else this.event.cancelBubble = true; return this; }, preventDefault: function(){ if (this.event.preventDefault) this.event.preventDefault(); else this.event.returnValue = false; return this; } }); Event.keys = { 'enter': 13, 'up': 38, 'down': 40, 'left': 37, 'right': 39, 'esc': 27, 'space': 32, 'backspace': 8, 'delete': 46 }; Function.extend({ bindWithEvent: function(bind, args){ return this.create({'bind': bind, 'arguments': args, 'event': Event}); } }); var Chain = new Class({ chain: function(fn){ this.chains = this.chains || []; this.chains.push(fn); return this; }, callChain: function(){ if (this.chains && this.chains.length) this.chains.shift().delay(10, this); }, clearChain: function(){ this.chains = []; } }); var Events = new Class({ addEvent: function(type, fn){ if (fn != Class.empty){ this.events = this.events || {}; this.events[type] = this.events[type] || []; if (!this.events[type].test(fn)) this.events[type].push(fn); } return this; }, fireEvent: function(type, args, delay){ if (this.events && this.events[type]){ this.events[type].each(function(fn){ fn.create({'bind': this, 'delay': delay, 'arguments': args})(); }, this); } return this; }, removeEvent: function(type, fn){ if (this.events && this.events[type]) this.events[type].remove(fn); return this; } }); var Options = new Class({ setOptions: function(defaults, options){ this.options = Object.extend(defaults, options); if (this.addEvent){ for (var option in this.options){ if (($type(this.options[option]) == 'function') && option.test(/^on[A-Z]/)) this.addEvent(option, this.options[option]); } } return this; } }); var Group = new Class({ initialize: function(){ this.instances = $A(arguments); this.events = {}; this.checker = {}; }, addEvent: function(type, fn){ this.checker[type] = this.checker[type] || {}; this.events[type] = this.events[type] || []; if (this.events[type].test(fn)) return false; else this.events[type].push(fn); this.instances.each(function(instance, i){ instance.addEvent(type, this.check.bind(this, [type, instance, i])); }, this); return this; }, check: function(type, instance, i){ this.checker[type][i] = true; var every = this.instances.every(function(current, j){ return this.checker[type][j] || false; }, this); if (!every) return; this.instances.each(function(current, j){ this.checker[type][j] = false; }, this); this.events[type].each(function(event){ event.call(this, this.instances, instance); }, this); } }); function $E(selector, filter){ return ($(filter) || document).getElement(selector); }; function $ES(selector, filter){ return ($(filter) || document).getElementsBySelector(selector); }; Element.extend({ getElements: function(selector){ var elements = []; selector.clean().split(' ').each(function(sel, i){ var param = sel.match(/^(\w*|\*)(?:#([\w-]+)|\.([\w-]+))?(?:\[(\w+)(?:([*^$]?=)["']?([^"'\]]*)["']?)?])?$/); if (!param) return; Filters.selector = param; param[1] = param[1] || '*'; if (i == 0){ if (param[2]){ var el = this.getElementById(param[2]); if (!el || ((param[1] != '*') && (Element.prototype.getTag.call(el) != param[1]))) return; elements = [el]; } else { elements = $A(this.getElementsByTagName(param[1])); } } else { elements = Elements.prototype.getElementsByTagName.call(elements, param[1], true); if (param[2]) elements = elements.filter(Filters.id); } if (param[3]) elements = elements.filter(Filters.className); if (param[4]) elements = elements.filter(Filters.attribute); }, this); return $$(elements); }, getElementById: function(id){ var el = document.getElementById(id); if (!el) return false; for (var parent = el.parentNode; parent != this; parent = parent.parentNode){ if (!parent) return false; } return el; }, getElement: function(selector){ return this.getElementsBySelector(selector)[0]; }, getElementsBySelector: function(selector){ var els = []; selector.split(',').each(function(sel){ els.extend(this.getElements(sel)); }, this); return $$(els); } }); document.extend({ getElementsByClassName: function(className){ return document.getElements('.'+className); }, getElement: Element.prototype.getElement, getElements: Element.prototype.getElements, getElementsBySelector: Element.prototype.getElementsBySelector }); var Filters = { selector: [], id: function(el){ return (el.id == Filters.selector[2]); }, className: function(el){ return (Element.prototype.hasClass.call(el, Filters.selector[3])); }, attribute: function(el){ var current = el.getAttribute(Filters.selector[4]); if (!current) return false; var operator = Filters.selector[5]; if (!operator) return true; var value = Filters.selector[6]; switch (operator){ case '*=': return (current.test(value)); case '=': return (current == value); case '^=': return (current.test('^'+value)); case '$=': return (current.test(value+'$')); } return false; } }; Elements.extend({ getElementsByTagName: function(tagName){ var found = []; this.each(function(el){ found.extend(el.getElementsByTagName(tagName)); }); return found; } }); var Hash = new Class({ length: 0, obj: {}, initialize: function(obj){ this.extend(obj); }, get: function(key){ return this.obj[key]; }, hasKey: function(key){ return this.obj[key] !== undefined; }, set: function(key, value){ if (value === undefined) return false; if (this.obj[key] === undefined) this.length++; this.obj[key] = value; return this; }, remove: function(key){ if (this.obj[key] === undefined) return this; var obj = {}; this.length--; for (var property in this.obj){ if (property != key) obj[property] = this.obj[property]; } this.obj = obj; return this; }, each: function(fn, bind){ for (var property in this.obj) fn.call(bind || this, property, this.obj[property]); }, extend: function(obj){ for (var property in obj){ if (this.obj[property] === undefined) this.length++; this.obj[property] = obj[property]; } return this; }, empty: function(){ return (this.length == 0); }, keys: function(){ var keys = []; for (var property in this.obj) keys.push(property); return keys; }, values: function(){ var values = []; for (var property in this.obj) values.push(this.obj[property]); return values; } }); function $H(obj){ return new Hash(obj); }; var Color = new Class({ initialize: function(color, type){ if (color.isColor) return color; color.isColor = true; type = type || (color.push ? 'rgb' : 'hex'); var rgb, hsb; switch(type){ case 'rgb': rgb = color; hsb = rgb.rgbToHsb(); break; case 'hsb': rgb = color.hsbToRgb(); hsb = color; break; default: rgb = color.hexToRgb(true); hsb = rgb.rgbToHsb(); } rgb.hsb = hsb; return Object.extend(rgb, Color.prototype); }, mix: function(){ var colors = $A(arguments); var alpha = ($type(colors[colors.length-1]) == 'number') ? colors.pop() : 50; var rgb = this.copy(); colors.each(function(color){ color = new Color(color); for (var i = 0; i < 3; i++) rgb[i] = Math.round((rgb[i] / 100 * (100 - alpha)) + (color[i] / 100 * alpha)); }); return new Color(rgb, 'rgb'); }, invert: function(){ return new Color(this.map(function(value){ return 255 - value; })); }, setHue: function(value){ return new Color([value, this.hsb[1], this.hsb[2]], 'hsb'); }, setSaturation: function(percent){ return new Color([this.hsb[0], percent, this.hsb[2]], 'hsb'); }, setBrightness: function(percent){ return new Color([this.hsb[0], this.hsb[1], percent], 'hsb'); } }); function $RGB(r, g, b){ return new Color([r, g, b], 'rgb'); }; function $HSB(h, s, b){ return new Color([h, s, b], 'hsb'); }; Array.extend({ rgbToHsb: function(){ var red = this[0], green = this[1], blue = this[2]; var hue, saturation, brightness; var max = Math.max(red, green, blue), min = Math.min(red, green, blue); var delta = max - min; brightness = max / 255; saturation = (max != 0) ? delta / max : 0; if (saturation == 0){ hue = 0; } else { var rr = (max - red) / delta; var gr = (max - green) / delta; var br = (max - blue) / delta; if (red == max) hue = br - gr; else if (green == max) hue = 2 + rr - br; else hue = 4 + gr - rr; hue /= 6; if (hue < 0) hue++; } return [Math.round(hue * 360), Math.round(saturation * 100), Math.round(brightness * 100)]; }, hsbToRgb: function(){ var br = Math.round(this[2] / 100 * 255); if (this[1] == 0){ return [br, br, br]; } else { var hue = this[0] % 360; var f = hue % 60; var p = Math.round((this[2] * (100 - this[1])) / 10000 * 255); var q = Math.round((this[2] * (6000 - this[1] * f)) / 600000 * 255); var t = Math.round((this[2] * (6000 - this[1] * (60 - f))) / 600000 * 255); switch (Math.floor(hue / 60)){ case 0: return [br, t, p]; case 1: return [q, br, p]; case 2: return [p, br, t]; case 3: return [p, q, br]; case 4: return [t, p, br]; case 5: return [br, p, q]; } } return false; } }); window.extend({ addEvent: function(type, fn){ if (type == 'domready'){ if (this.loaded) fn(); else if (!this.events || !this.events.domready){ var domReady = function(){ if (this.loaded) return; this.loaded = true; if (this.timer) this.timer = $clear(this.timer); Element.prototype.fireEvent.call(this, 'domready'); this.events.domready = null; }.bind(this); if (document.readyState && this.khtml){ this.timer = function(){ if (['loaded','complete'].test(document.readyState)) domReady(); }.periodical(50); } else if (document.readyState && this.ie){ document.write("