Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- QWEBIRC_BUILD="711ba53432dc9c9b488ca60b3eff7a525dc2e45b";
- //MooTools, <http://mootools.net>, My Object Oriented (JavaScript) Tools. Copyright (c) 2006-2009 Valerio Proietti, <http://mad4milk.net>, MIT Style License.
- var MooTools={version:"1.2.5",build:"008d8f0f2fcc2044e54fdd3635341aaab274e757"};var Native=function(l){l=l||{};var a=l.name;var j=l.legacy;var b=l.protect;var c=l.implement;var i=l.generics;var g=l.initialize;var h=l.afterImplement||function(){};var d=g||j;i=i!==false;d.constructor=Native;d.$family={name:"native"};if(j&&g){d.prototype=j.prototype;}d.prototype.constructor=d;if(a){var f=a.toLowerCase();d.prototype.$family={name:f};Native.typize(d,f);}var k=function(o,m,p,n){if(!b||n||!o.prototype[m]){o.prototype[m]=p;}if(i){Native.genericize(o,m,b);}h.call(o,m,p);return o;};d.alias=function(o,m,q){if(typeof o=="string"){var p=this.prototype[o];if((o=p)){return k(this,m,o,q);}}for(var n in o){this.alias(n,o[n],m);}return this;};d.implement=function(n,m,q){if(typeof n=="string"){return k(this,n,m,q);}for(var o in n){k(this,o,n[o],m);}return this;};if(c){d.implement(c);}return d;};Native.genericize=function(b,c,a){if((!a||!b[c])&&typeof b.prototype[c]=="function"){b[c]=function(){var d=Array.prototype.slice.call(arguments);return b.prototype[c].apply(d.shift(),d);};}};Native.implement=function(d,c){for(var b=0,a=d.length;b<a;b++){d[b].implement(c);}};Native.typize=function(a,b){if(!a.type){a.type=function(c){return($type(c)===b);};}};(function(){var a={Array:Array,Date:Date,Function:Function,Number:Number,RegExp:RegExp,String:String};for(var j in a){new Native({name:j,initialize:a[j],protect:true});}var d={"boolean":Boolean,"native":Native,object:Object};for(var c in d){Native.typize(d[c],c);}var h={Array:["concat","indexOf","join","lastIndexOf","pop","push","reverse","shift","slice","sort","splice","toString","unshift","valueOf"],String:["charAt","charCodeAt","concat","indexOf","lastIndexOf","match","replace","search","slice","split","substr","substring","toLowerCase","toUpperCase","valueOf"]};for(var f in h){for(var b=h[f].length;b--;){Native.genericize(a[f],h[f][b],true);}}})();var Hash=new Native({name:"Hash",initialize:function(a){if($type(a)=="hash"){a=$unlink(a.getClean());}for(var b in a){this[b]=a[b];}return this;}});Hash.implement({forEach:function(b,c){for(var a in this){if(this.hasOwnProperty(a)){b.call(c,this[a],a,this);}}},getClean:function(){var b={};for(var a in this){if(this.hasOwnProperty(a)){b[a]=this[a];}}return b;},getLength:function(){var b=0;for(var a in this){if(this.hasOwnProperty(a)){b++;}}return b;}});Hash.alias("forEach","each");Array.implement({forEach:function(c,d){for(var b=0,a=this.length;b<a;b++){c.call(d,this[b],b,this);}}});Array.alias("forEach","each");function $A(b){if(b.item){var a=b.length,c=new Array(a);while(a--){c[a]=b[a];}return c;}return Array.prototype.slice.call(b);}function $arguments(a){return function(){return arguments[a];};}function $chk(a){return !!(a||a===0);}function $clear(a){clearTimeout(a);clearInterval(a);return null;}function $defined(a){return(a!=undefined);}function $each(c,b,d){var a=$type(c);((a=="arguments"||a=="collection"||a=="array")?Array:Hash).each(c,b,d);}function $empty(){}function $extend(c,a){for(var b in (a||{})){c[b]=a[b];}return c;}function $H(a){return new Hash(a);}function $lambda(a){return($type(a)=="function")?a:function(){return a;};}function $merge(){var a=Array.slice(arguments);a.unshift({});return $mixin.apply(null,a);}function $mixin(f){for(var d=1,a=arguments.length;d<a;d++){var b=arguments[d];if($type(b)!="object"){continue;}for(var c in b){var h=b[c],g=f[c];f[c]=(g&&$type(h)=="object"&&$type(g)=="object")?$mixin(g,h):$unlink(h);}}return f;}function $pick(){for(var b=0,a=arguments.length;b<a;b++){if(arguments[b]!=undefined){return arguments[b];}}return null;}function $random(b,a){return Math.floor(Math.random()*(a-b+1)+b);}function $splat(b){var a=$type(b);return(a)?((a!="array"&&a!="arguments")?[b]:b):[];}var $time=Date.now||function(){return +new Date;};function $try(){for(var b=0,a=arguments.length;b<a;b++){try{return arguments[b]();}catch(c){}}return null;}function $type(a){if(a==undefined){return false;}if(a.$family){return(a.$family.name=="number"&&!isFinite(a))?false:a.$family.name;}if(a.nodeName){switch(a.nodeType){case 1:return"element";case 3:return(/\S/).test(a.nodeValue)?"textnode":"whitespace";}}else{if(typeof a.length=="number"){if(a.callee){return"arguments";}else{if(a.item){return"collection";}}}}return typeof a;}function $unlink(c){var b;switch($type(c)){case"object":b={};for(var f in c){b[f]=$unlink(c[f]);}break;case"hash":b=new Hash(c);break;case"array":b=[];for(var d=0,a=c.length;d<a;d++){b[d]=$unlink(c[d]);}break;default:return c;}return b;}Array.implement({every:function(c,d){for(var b=0,a=this.length;b<a;b++){if(!c.call(d,this[b],b,this)){return false;}}return true;},filter:function(d,f){var c=[];for(var b=0,a=this.length;b<a;b++){if(d.call(f,this[b],b,this)){c.push(this[b]);}}return c;},clean:function(){return this.filter($defined);},indexOf:function(c,d){var a=this.length;for(var b=(d<0)?Math.max(0,a+d):d||0;b<a;b++){if(this[b]===c){return b;}}return -1;},map:function(d,f){var c=[];for(var b=0,a=this.length;b<a;b++){c[b]=d.call(f,this[b],b,this);}return c;},some:function(c,d){for(var b=0,a=this.length;b<a;b++){if(c.call(d,this[b],b,this)){return true;}}return false;},associate:function(c){var d={},b=Math.min(this.length,c.length);for(var a=0;a<b;a++){d[c[a]]=this[a];}return d;},link:function(c){var a={};for(var f=0,b=this.length;f<b;f++){for(var d in c){if(c[d](this[f])){a[d]=this[f];delete c[d];break;}}}return a;},contains:function(a,b){return this.indexOf(a,b)!=-1;},extend:function(c){for(var b=0,a=c.length;b<a;b++){this.push(c[b]);}return this;},getLast:function(){return(this.length)?this[this.length-1]:null;},getRandom:function(){return(this.length)?this[$random(0,this.length-1)]:null;},include:function(a){if(!this.contains(a)){this.push(a);}return this;},combine:function(c){for(var b=0,a=c.length;b<a;b++){this.include(c[b]);}return this;},erase:function(b){for(var a=this.length;a--;a){if(this[a]===b){this.splice(a,1);}}return this;},empty:function(){this.length=0;return this;},flatten:function(){var d=[];for(var b=0,a=this.length;b<a;b++){var c=$type(this[b]);if(!c){continue;}d=d.concat((c=="array"||c=="collection"||c=="arguments")?Array.flatten(this[b]):this[b]);}return d;},hexToRgb:function(b){if(this.length!=3){return null;}var a=this.map(function(c){if(c.length==1){c+=c;}return c.toInt(16);});return(b)?a:"rgb("+a+")";},rgbToHex:function(d){if(this.length<3){return null;}if(this.length==4&&this[3]==0&&!d){return"transparent";}var b=[];for(var a=0;a<3;a++){var c=(this[a]-0).toString(16);b.push((c.length==1)?"0"+c:c);}return(d)?b:"#"+b.join("");}});String.implement({test:function(a,b){return((typeof a=="string")?new RegExp(a,b):a).test(this);},contains:function(a,b){return(b)?(b+this+b).indexOf(b+a+b)>-1:this.indexOf(a)>-1;},trim:function(){return this.replace(/^\s+|\s+$/g,"");},clean:function(){return this.replace(/\s+/g," ").trim();},camelCase:function(){return this.replace(/-\D/g,function(a){return a.charAt(1).toUpperCase();});},hyphenate:function(){return this.replace(/[A-Z]/g,function(a){return("-"+a.charAt(0).toLowerCase());});},capitalize:function(){return this.replace(/\b[a-z]/g,function(a){return a.toUpperCase();});},escapeRegExp:function(){return this.replace(/([-.*+?^${}()|[\]\/\\])/g,"\\$1");},toInt:function(a){return parseInt(this,a||10);},toFloat:function(){return parseFloat(this);},hexToRgb:function(b){var a=this.match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/);return(a)?a.slice(1).hexToRgb(b):null;},rgbToHex:function(b){var a=this.match(/\d{1,3}/g);return(a)?a.rgbToHex(b):null;},stripScripts:function(b){var a="";var c=this.replace(/<script[^>]*>([\s\S]*?)<\/script>/gi,function(){a+=arguments[1]+"\n";return"";});if(b===true){$exec(a);}else{if($type(b)=="function"){b(a,c);}}return c;},substitute:function(a,b){return this.replace(b||(/\\?\{([^{}]+)\}/g),function(d,c){if(d.charAt(0)=="\\"){return d.slice(1);}return(a[c]!=undefined)?a[c]:"";});}});try{delete Function.prototype.bind;}catch(e){}Function.implement({extend:function(a){for(var b in a){this[b]=a[b];}return this;},create:function(b){var a=this;b=b||{};return function(d){var c=b.arguments;c=(c!=undefined)?$splat(c):Array.slice(arguments,(b.event)?1:0);if(b.event){c=[d||window.event].extend(c);}var f=function(){return a.apply(b.bind||null,c);};if(b.delay){return setTimeout(f,b.delay);}if(b.periodical){return setInterval(f,b.periodical);}if(b.attempt){return $try(f);}return f();};},run:function(a,b){return this.apply(b,$splat(a));},pass:function(a,b){return this.create({bind:b,arguments:a});},bind:function(b,a){return this.create({bind:b,arguments:a});},bindWithEvent:function(b,a){return this.create({bind:b,arguments:a,event:true});},attempt:function(a,b){return this.create({bind:b,arguments:a,attempt:true})();},delay:function(b,c,a){return this.create({bind:c,arguments:a,delay:b})();},periodical:function(c,b,a){return this.create({bind:b,arguments:a,periodical:c})();}});Number.implement({limit:function(b,a){return Math.min(a,Math.max(b,this));},round:function(a){a=Math.pow(10,a||0);return Math.round(this*a)/a;},times:function(b,c){for(var a=0;a<this;a++){b.call(c,a,this);}},toFloat:function(){return parseFloat(this);},toInt:function(a){return parseInt(this,a||10);}});Number.alias("times","each");(function(b){var a={};b.each(function(c){if(!Number[c]){a[c]=function(){return Math[c].apply(null,[this].concat($A(arguments)));};}});Number.implement(a);})(["abs","acos","asin","atan","atan2","ceil","cos","exp","floor","log","max","min","pow","sin","sqrt","tan"]);Hash.implement({has:Object.prototype.hasOwnProperty,keyOf:function(b){for(var a in this){if(this.hasOwnProperty(a)&&this[a]===b){return a;}}return null;},hasValue:function(a){return(Hash.keyOf(this,a)!==null);},extend:function(a){Hash.each(a||{},function(c,b){Hash.set(this,b,c);},this);return this;},combine:function(a){Hash.each(a||{},function(c,b){Hash.include(this,b,c);},this);return this;},erase:function(a){if(this.hasOwnProperty(a)){delete this[a];}return this;},get:function(a){return(this.hasOwnProperty(a))?this[a]:null;},set:function(a,b){if(!this[a]||this.hasOwnProperty(a)){this[a]=b;}return this;},empty:function(){Hash.each(this,function(b,a){delete this[a];},this);return this;},include:function(a,b){if(this[a]==undefined){this[a]=b;}return this;},map:function(b,c){var a=new Hash;Hash.each(this,function(f,d){a.set(d,b.call(c,f,d,this));},this);return a;},filter:function(b,c){var a=new Hash;Hash.each(this,function(f,d){if(b.call(c,f,d,this)){a.set(d,f);}},this);return a;},every:function(b,c){for(var a in this){if(this.hasOwnProperty(a)&&!b.call(c,this[a],a)){return false;}}return true;},some:function(b,c){for(var a in this){if(this.hasOwnProperty(a)&&b.call(c,this[a],a)){return true;}}return false;},getKeys:function(){var a=[];Hash.each(this,function(c,b){a.push(b);});return a;},getValues:function(){var a=[];Hash.each(this,function(b){a.push(b);});return a;},toQueryString:function(a){var b=[];Hash.each(this,function(g,f){if(a){f=a+"["+f+"]";}var d;switch($type(g)){case"object":d=Hash.toQueryString(g,f);break;case"array":var c={};g.each(function(j,h){c[h]=j;});d=Hash.toQueryString(c,f);break;default:d=f+"="+encodeURIComponent(g);}if(g!=undefined){b.push(d);}});return b.join("&");}});Hash.alias({keyOf:"indexOf",hasValue:"contains"});function Class(b){if(b instanceof Function){b={initialize:b};}var a=function(){Object.reset(this);if(a._prototyping){return this;}this._current=$empty;var c=(this.initialize)?this.initialize.apply(this,arguments):this;delete this._current;delete this.caller;return c;}.extend(this);a.implement(b);a.constructor=Class;a.prototype.constructor=a;return a;}Function.prototype.protect=function(){this._protected=true;return this;};Object.reset=function(a,c){if(c==null){for(var f in a){Object.reset(a,f);}return a;}delete a[c];switch($type(a[c])){case"object":var d=function(){};d.prototype=a[c];var b=new d;a[c]=Object.reset(b);break;case"array":a[c]=$unlink(a[c]);break;}return a;};new Native({name:"Class",initialize:Class}).extend({instantiate:function(b){b._prototyping=true;var a=new b;delete b._prototyping;return a;},wrap:function(a,b,c){if(c._origin){c=c._origin;}return function(){if(c._protected&&this._current==null){throw new Error('The method "'+b+'" cannot be called.');}var f=this.caller,g=this._current;this.caller=g;this._current=arguments.callee;var d=c.apply(this,arguments);this._current=g;this.caller=f;return d;}.extend({_owner:a,_origin:c,_name:b});}});Class.implement({implement:function(a,d){if($type(a)=="object"){for(var f in a){this.implement(f,a[f]);}return this;}var g=Class.Mutators[a];if(g){d=g.call(this,d);if(d==null){return this;}}var c=this.prototype;switch($type(d)){case"function":if(d._hidden){return this;}c[a]=Class.wrap(this,a,d);break;case"object":var b=c[a];if($type(b)=="object"){$mixin(b,d);}else{c[a]=$unlink(d);}break;case"array":c[a]=$unlink(d);break;default:c[a]=d;}return this;}});Class.Mutators={Extends:function(a){this.parent=a;this.prototype=Class.instantiate(a);this.implement("parent",function(){var b=this.caller._name,c=this.caller._owner.parent.prototype[b];if(!c){throw new Error('The method "'+b+'" has no parent.');}return c.apply(this,arguments);}.protect());},Implements:function(a){$splat(a).each(function(b){if(b instanceof Function){b=Class.instantiate(b);}this.implement(b);},this);}};var Chain=new Class({$chain:[],chain:function(){this.$chain.extend(Array.flatten(arguments));return this;},callChain:function(){return(this.$chain.length)?this.$chain.shift().apply(this,arguments):false;},clearChain:function(){this.$chain.empty();return this;}});var Events=new Class({$events:{},addEvent:function(c,b,a){c=Events.removeOn(c);if(b!=$empty){this.$events[c]=this.$events[c]||[];this.$events[c].include(b);if(a){b.internal=true;}}return this;},addEvents:function(a){for(var b in a){this.addEvent(b,a[b]);}return this;},fireEvent:function(c,b,a){c=Events.removeOn(c);if(!this.$events||!this.$events[c]){return this;}this.$events[c].each(function(d){d.create({bind:this,delay:a,"arguments":b})();},this);return this;},removeEvent:function(b,a){b=Events.removeOn(b);if(!this.$events[b]){return this;}if(!a.internal){this.$events[b].erase(a);}return this;},removeEvents:function(c){var d;if($type(c)=="object"){for(d in c){this.removeEvent(d,c[d]);}return this;}if(c){c=Events.removeOn(c);}for(d in this.$events){if(c&&c!=d){continue;}var b=this.$events[d];for(var a=b.length;a--;a){this.removeEvent(d,b[a]);}}return this;}});Events.removeOn=function(a){return a.replace(/^on([A-Z])/,function(b,c){return c.toLowerCase();});};var Options=new Class({setOptions:function(){this.options=$merge.run([this.options].extend(arguments));if(!this.addEvent){return this;}for(var a in this.options){if($type(this.options[a])!="function"||!(/^on[A-Z]/).test(a)){continue;}this.addEvent(a,this.options[a]);delete this.options[a];}return this;}});var Browser=$merge({Engine:{name:"unknown",version:0},Platform:{name:(window.orientation!=undefined)?"ipod":(navigator.platform.match(/mac|win|linux/i)||["other"])[0].toLowerCase()},Features:{xpath:!!(document.evaluate),air:!!(window.runtime),query:!!(document.querySelector)},Plugins:{},Engines:{presto:function(){return(!window.opera)?false:((arguments.callee.caller)?960:((document.getElementsByClassName)?950:925));},trident:function(){return(!window.ActiveXObject)?false:((window.XMLHttpRequest)?((document.querySelectorAll)?6:5):4);},webkit:function(){return(navigator.taintEnabled)?false:((Browser.Features.xpath)?((Browser.Features.query)?525:420):419);},gecko:function(){return(!document.getBoxObjectFor&&window.mozInnerScreenX==null)?false:((document.getElementsByClassName)?19:18);}}},Browser||{});Browser.Platform[Browser.Platform.name]=true;Browser.detect=function(){for(var b in this.Engines){var a=this.Engines[b]();if(a){this.Engine={name:b,version:a};this.Engine[b]=this.Engine[b+a]=true;break;}}return{name:b,version:a};};Browser.detect();Browser.Request=function(){return $try(function(){return new XMLHttpRequest();},function(){return new ActiveXObject("MSXML2.XMLHTTP");},function(){return new ActiveXObject("Microsoft.XMLHTTP");});};Browser.Features.xhr=!!(Browser.Request());Browser.Plugins.Flash=(function(){var a=($try(function(){return navigator.plugins["Shockwave Flash"].description;},function(){return new ActiveXObject("ShockwaveFlash.ShockwaveFlash").GetVariable("$version");})||"0 r0").match(/\d+/g);return{version:parseInt(a[0]||0+"."+a[1],10)||0,build:parseInt(a[2],10)||0};})();function $exec(b){if(!b){return b;}if(window.execScript){window.execScript(b);}else{var a=document.createElement("script");a.setAttribute("type","text/javascript");a[(Browser.Engine.webkit&&Browser.Engine.version<420)?"innerText":"text"]=b;document.head.appendChild(a);document.head.removeChild(a);}return b;}Native.UID=1;var $uid=(Browser.Engine.trident)?function(a){return(a.uid||(a.uid=[Native.UID++]))[0];}:function(a){return a.uid||(a.uid=Native.UID++);};var Window=new Native({name:"Window",legacy:(Browser.Engine.trident)?null:window.Window,initialize:function(a){$uid(a);if(!a.Element){a.Element=$empty;if(Browser.Engine.webkit){a.document.createElement("iframe");}a.Element.prototype=(Browser.Engine.webkit)?window["[[DOMElement.prototype]]"]:{};}a.document.window=a;return $extend(a,Window.Prototype);},afterImplement:function(b,a){window[b]=Window.Prototype[b]=a;}});Window.Prototype={$family:{name:"window"}};new Window(window);var Document=new Native({name:"Document",legacy:(Browser.Engine.trident)?null:window.Document,initialize:function(a){$uid(a);a.head=a.getElementsByTagName("head")[0];a.html=a.getElementsByTagName("html")[0];if(Browser.Engine.trident&&Browser.Engine.version<=4){$try(function(){a.execCommand("BackgroundImageCache",false,true);});}if(Browser.Engine.trident){a.window.attachEvent("onunload",function(){a.window.detachEvent("onunload",arguments.callee);a.head=a.html=a.window=null;});}return $extend(a,Document.Prototype);},afterImplement:function(b,a){document[b]=Document.Prototype[b]=a;}});Document.Prototype={$family:{name:"document"}};new Document(document);var Element=new Native({name:"Element",legacy:window.Element,initialize:function(a,b){var c=Element.Constructors.get(a);if(c){return c(b);}if(typeof a=="string"){return document.newElement(a,b);}return document.id(a).set(b);},afterImplement:function(a,b){Element.Prototype[a]=b;if(Array[a]){return;}Elements.implement(a,function(){var c=[],h=true;for(var f=0,d=this.length;f<d;f++){var g=this[f][a].apply(this[f],arguments);c.push(g);if(h){h=($type(g)=="element");}}return(h)?new Elements(c):c;});}});Element.Prototype={$family:{name:"element"}};Element.Constructors=new Hash;var IFrame=new Native({name:"IFrame",generics:false,initialize:function(){var g=Array.link(arguments,{properties:Object.type,iframe:$defined});var d=g.properties||{};var c=document.id(g.iframe);var f=d.onload||$empty;delete d.onload;d.id=d.name=$pick(d.id,d.name,c?(c.id||c.name):"IFrame_"+$time());c=new Element(c||"iframe",d);var b=function(){var h=$try(function(){return c.contentWindow.location.host;});if(!h||h==window.location.host){var i=new Window(c.contentWindow);new Document(c.contentWindow.document);$extend(i.Element.prototype,Element.Prototype);}f.call(c.contentWindow,c.contentWindow.document);};var a=$try(function(){return c.contentWindow;});((a&&a.document.body)||window.frames[d.id])?b():c.addListener("load",b);return c;}});var Elements=new Native({initialize:function(g,b){b=$extend({ddup:true,cash:true},b);g=g||[];if(b.ddup||b.cash){var h={},f=[];for(var c=0,a=g.length;c<a;c++){var d=document.id(g[c],!b.cash);if(b.ddup){if(h[d.uid]){continue;}h[d.uid]=true;}if(d){f.push(d);}}g=f;}return(b.cash)?$extend(g,this):g;}});Elements.implement({filter:function(a,b){if(!a){return this;}return new Elements(Array.filter(this,(typeof a=="string")?function(c){return c.match(a);}:a,b));}});(function(){var d;try{var a=document.createElement("<input name=x>");d=(a.name=="x");}catch(b){}var c=function(f){return(""+f).replace(/&/g,"&").replace(/"/g,""");};Document.implement({newElement:function(f,g){if(g&&g.checked!=null){g.defaultChecked=g.checked;}if(d&&g){f="<"+f;if(g.name){f+=' name="'+c(g.name)+'"';}if(g.type){f+=' type="'+c(g.type)+'"';}f+=">";delete g.name;delete g.type;}return this.id(this.createElement(f)).set(g);},newTextNode:function(f){return this.createTextNode(f);},getDocument:function(){return this;},getWindow:function(){return this.window;},id:(function(){var f={string:function(i,h,g){i=g.getElementById(i);return(i)?f.element(i,h):null;},element:function(g,j){$uid(g);if(!j&&!g.$family&&!(/^object|embed$/i).test(g.tagName)){var h=Element.Prototype;for(var i in h){g[i]=h[i];}}return g;},object:function(h,i,g){if(h.toElement){return f.element(h.toElement(g),i);}return null;}};f.textnode=f.whitespace=f.window=f.document=$arguments(0);return function(h,j,i){if(h&&h.$family&&h.uid){return h;}var g=$type(h);return(f[g])?f[g](h,j,i||document):null;};})()});})();if(window.$==null){Window.implement({$:function(a,b){return document.id(a,b,this.document);}});}Window.implement({$$:function(a){if(arguments.length==1&&typeof a=="string"){return this.document.getElements(a);}var g=[];var c=Array.flatten(arguments);for(var d=0,b=c.length;d<b;d++){var f=c[d];switch($type(f)){case"element":g.push(f);break;case"string":g.extend(this.document.getElements(f,true));}}return new Elements(g);},getDocument:function(){return this.document;},getWindow:function(){return this;}});Native.implement([Element,Document],{getElement:function(a,b){return document.id(this.getElements(a,true)[0]||null,b);},getElements:function(a,d){a=a.split(",");var c=[];var b=(a.length>1);a.each(function(f){var g=this.getElementsByTagName(f.trim());(b)?c.extend(g):c=g;},this);return new Elements(c,{ddup:b,cash:!d});}});(function(){var i={},g={};var j={input:"checked",option:"selected",textarea:(Browser.Engine.webkit&&Browser.Engine.version<420)?"innerHTML":"value"};var c=function(m){return(g[m]||(g[m]={}));};var h=function(o,m){if(!o){return;}var n=o.uid;if(m!==true){m=false;}if(Browser.Engine.trident){if(o.clearAttributes){var r=m&&o.cloneNode(false);o.clearAttributes();if(r){o.mergeAttributes(r);}}else{if(o.removeEvents){o.removeEvents();}}if((/object/i).test(o.tagName)){for(var q in o){if(typeof o[q]=="function"){o[q]=$empty;}}Element.dispose(o);}}if(!n){return;}i[n]=g[n]=null;};var d=function(){Hash.each(i,h);if(Browser.Engine.trident){$A(document.getElementsByTagName("object")).each(h);}if(window.CollectGarbage){CollectGarbage();}i=g=null;};var k=function(o,m,t,n,q,s){var p=o[t||m];var r=[];while(p){if(p.nodeType==1&&(!n||Element.match(p,n))){if(!q){return document.id(p,s);}r.push(p);}p=p[m];}return(q)?new Elements(r,{ddup:false,cash:!s}):null;};var f={html:"innerHTML","class":"className","for":"htmlFor",defaultValue:"defaultValue",text:(Browser.Engine.trident||(Browser.Engine.webkit&&Browser.Engine.version<420))?"innerText":"textContent"};var b=["compact","nowrap","ismap","declare","noshade","checked","disabled","readonly","multiple","selected","noresize","defer"];var l=["value","type","defaultValue","accessKey","cellPadding","cellSpacing","colSpan","frameBorder","maxLength","readOnly","rowSpan","tabIndex","useMap"];b=b.associate(b);Hash.extend(f,b);Hash.extend(f,l.associate(l.map(String.toLowerCase)));var a={before:function(n,m){if(m.parentNode){m.parentNode.insertBefore(n,m);}},after:function(n,m){if(!m.parentNode){return;}var o=m.nextSibling;(o)?m.parentNode.insertBefore(n,o):m.parentNode.appendChild(n);},bottom:function(n,m){m.appendChild(n);},top:function(n,m){var o=m.firstChild;(o)?m.insertBefore(n,o):m.appendChild(n);}};a.inside=a.bottom;Hash.each(a,function(m,n){n=n.capitalize();Element.implement("inject"+n,function(o){m(this,document.id(o,true));return this;});Element.implement("grab"+n,function(o){m(document.id(o,true),this);return this;});});Element.implement({set:function(q,n){switch($type(q)){case"object":for(var o in q){this.set(o,q[o]);}break;case"string":var m=Element.Properties.get(q);(m&&m.set)?m.set.apply(this,Array.slice(arguments,1)):this.setProperty(q,n);}return this;},get:function(n){var m=Element.Properties.get(n);return(m&&m.get)?m.get.apply(this,Array.slice(arguments,1)):this.getProperty(n);},erase:function(n){var m=Element.Properties.get(n);(m&&m.erase)?m.erase.apply(this):this.removeProperty(n);return this;},setProperty:function(n,o){var m=f[n];if(o==undefined){return this.removeProperty(n);}if(m&&b[n]){o=!!o;}(m)?this[m]=o:this.setAttribute(n,""+o);return this;},setProperties:function(m){for(var n in m){this.setProperty(n,m[n]);}return this;},getProperty:function(n){var m=f[n];var o=(m)?this[m]:this.getAttribute(n,2);return(b[n])?!!o:(m)?o:o||null;},getProperties:function(){var m=$A(arguments);return m.map(this.getProperty,this).associate(m);},removeProperty:function(n){var m=f[n];(m)?this[m]=(m&&b[n])?false:"":this.removeAttribute(n);return this;},removeProperties:function(){Array.each(arguments,this.removeProperty,this);return this;},hasClass:function(m){return this.className.contains(m," ");},addClass:function(m){if(!this.hasClass(m)){this.className=(this.className+" "+m).clean();}return this;},removeClass:function(m){this.className=this.className.replace(new RegExp("(^|\\s)"+m+"(?:\\s|$)"),"$1");return this;},toggleClass:function(m){return this.hasClass(m)?this.removeClass(m):this.addClass(m);},adopt:function(){Array.flatten(arguments).each(function(m){m=document.id(m,true);if(m){this.appendChild(m);}},this);return this;},appendText:function(n,m){return this.grab(this.getDocument().newTextNode(n),m);},grab:function(n,m){a[m||"bottom"](document.id(n,true),this);return this;},inject:function(n,m){a[m||"bottom"](this,document.id(n,true));return this;},replaces:function(m){m=document.id(m,true);m.parentNode.replaceChild(this,m);return this;},wraps:function(n,m){n=document.id(n,true);return this.replaces(n).grab(n,m);},getPrevious:function(m,n){return k(this,"previousSibling",null,m,false,n);},getAllPrevious:function(m,n){return k(this,"previousSibling",null,m,true,n);},getNext:function(m,n){return k(this,"nextSibling",null,m,false,n);},getAllNext:function(m,n){return k(this,"nextSibling",null,m,true,n);},getFirst:function(m,n){return k(this,"nextSibling","firstChild",m,false,n);},getLast:function(m,n){return k(this,"previousSibling","lastChild",m,false,n);},getParent:function(m,n){return k(this,"parentNode",null,m,false,n);},getParents:function(m,n){return k(this,"parentNode",null,m,true,n);},getSiblings:function(m,n){return this.getParent().getChildren(m,n).erase(this);},getChildren:function(m,n){return k(this,"nextSibling","firstChild",m,true,n);},getWindow:function(){return this.ownerDocument.window;},getDocument:function(){return this.ownerDocument;},getElementById:function(p,o){var n=this.ownerDocument.getElementById(p);if(!n){return null;}for(var m=n.parentNode;m!=this;m=m.parentNode){if(!m){return null;}}return document.id(n,o);},getSelected:function(){return new Elements($A(this.options).filter(function(m){return m.selected;}));},getComputedStyle:function(n){if(this.currentStyle){return this.currentStyle[n.camelCase()];}var m=this.getDocument().defaultView.getComputedStyle(this,null);return(m)?m.getPropertyValue([n.hyphenate()]):null;},toQueryString:function(){var m=[];this.getElements("input, select, textarea",true).each(function(n){if(!n.name||n.disabled||n.type=="submit"||n.type=="reset"||n.type=="file"){return;}var o=(n.tagName.toLowerCase()=="select")?Element.getSelected(n).map(function(p){return p.value;}):((n.type=="radio"||n.type=="checkbox")&&!n.checked)?null:n.value;$splat(o).each(function(p){if(typeof p!="undefined"){m.push(n.name+"="+encodeURIComponent(p));}});});return m.join("&");},clone:function(p,m){p=p!==false;var s=this.cloneNode(p);var o=function(w,v){if(!m){w.removeAttribute("id");}if(Browser.Engine.trident){w.clearAttributes();w.mergeAttributes(v);w.removeAttribute("uid");if(w.options){var x=w.options,t=v.options;for(var u=x.length;u--;){x[u].selected=t[u].selected;}}}var y=j[v.tagName.toLowerCase()];if(y&&v[y]){w[y]=v[y];}};if(p){var q=s.getElementsByTagName("*"),r=this.getElementsByTagName("*");for(var n=q.length;n--;){o(q[n],r[n]);}}o(s,this);return document.id(s);},destroy:function(){Element.empty(this);Element.dispose(this);h(this,true);return null;},empty:function(){$A(this.childNodes).each(function(m){Element.destroy(m);});return this;},dispose:function(){return(this.parentNode)?this.parentNode.removeChild(this):this;},hasChild:function(m){m=document.id(m,true);if(!m){return false;}if(Browser.Engine.webkit&&Browser.Engine.version<420){return $A(this.getElementsByTagName(m.tagName)).contains(m);}return(this.contains)?(this!=m&&this.contains(m)):!!(this.compareDocumentPosition(m)&16);},match:function(m){return(!m||(m==this)||(Element.get(this,"tag")==m));}});Native.implement([Element,Window,Document],{addListener:function(p,o){if(p=="unload"){var m=o,n=this;o=function(){n.removeListener("unload",o);m();};}else{i[this.uid]=this;}if(this.addEventListener){this.addEventListener(p,o,false);}else{this.attachEvent("on"+p,o);}return this;},removeListener:function(n,m){if(this.removeEventListener){this.removeEventListener(n,m,false);}else{this.detachEvent("on"+n,m);}return this;},retrieve:function(n,m){var p=c(this.uid),o=p[n];if(m!=undefined&&o==undefined){o=p[n]=m;}return $pick(o);},store:function(n,m){var o=c(this.uid);o[n]=m;return this;},eliminate:function(m){var n=c(this.uid);delete n[m];return this;}});window.addListener("unload",d);})();Element.Properties=new Hash;Element.Properties.style={set:function(a){this.style.cssText=a;},get:function(){return this.style.cssText;},erase:function(){this.style.cssText="";}};Element.Properties.tag={get:function(){return this.tagName.toLowerCase();}};Element.Properties.html=(function(){var c=document.createElement("div");var a={table:[1,"<table>","</table>"],select:[1,"<select>","</select>"],tbody:[2,"<table><tbody>","</tbody></table>"],tr:[3,"<table><tbody><tr>","</tr></tbody></table>"]};a.thead=a.tfoot=a.tbody;var b={set:function(){var f=Array.flatten(arguments).join("");var g=Browser.Engine.trident&&a[this.get("tag")];if(g){var h=c;h.innerHTML=g[1]+f+g[2];for(var d=g[0];d--;){h=h.firstChild;}this.empty().adopt(h.childNodes);}else{this.innerHTML=f;}}};b.erase=b.set;return b;})();if(Browser.Engine.webkit&&Browser.Engine.version<420){Element.Properties.text={get:function(){if(this.innerText){return this.innerText;}var a=this.ownerDocument.newElement("div",{html:this.innerHTML}).inject(this.ownerDocument.body);var b=a.innerText;a.destroy();return b;}};}(function(){Element.implement({scrollTo:function(i,j){if(b(this)){this.getWindow().scrollTo(i,j);}else{this.scrollLeft=i;this.scrollTop=j;}return this;},getSize:function(){if(b(this)){return this.getWindow().getSize();}return{x:this.offsetWidth,y:this.offsetHeight};},getScrollSize:function(){if(b(this)){return this.getWindow().getScrollSize();}return{x:this.scrollWidth,y:this.scrollHeight};},getScroll:function(){if(b(this)){return this.getWindow().getScroll();}return{x:this.scrollLeft,y:this.scrollTop};},getScrolls:function(){var j=this,i={x:0,y:0};while(j&&!b(j)){i.x+=j.scrollLeft;i.y+=j.scrollTop;j=j.parentNode;}return i;},getOffsetParent:function(){var i=this;if(b(i)){return null;}if(!Browser.Engine.trident){return i.offsetParent;}while((i=i.parentNode)&&!b(i)){if(d(i,"position")!="static"){return i;}}return null;},getOffsets:function(){if(this.getBoundingClientRect){var k=this.getBoundingClientRect(),n=document.id(this.getDocument().documentElement),q=n.getScroll(),l=this.getScrolls(),j=this.getScroll(),i=(d(this,"position")=="fixed");return{x:k.left.toInt()+l.x-j.x+((i)?0:q.x)-n.clientLeft,y:k.top.toInt()+l.y-j.y+((i)?0:q.y)-n.clientTop};}var m=this,o={x:0,y:0};if(b(this)){return o;}while(m&&!b(m)){o.x+=m.offsetLeft;o.y+=m.offsetTop;if(Browser.Engine.gecko){if(!g(m)){o.x+=c(m);o.y+=h(m);}var p=m.parentNode;if(p&&d(p,"overflow")!="visible"){o.x+=c(p);o.y+=h(p);}}else{if(m!=this&&Browser.Engine.webkit){o.x+=c(m);o.y+=h(m);}}m=m.offsetParent;}if(Browser.Engine.gecko&&!g(this)){o.x-=c(this);o.y-=h(this);}return o;},getPosition:function(l){if(b(this)){return{x:0,y:0};}var m=this.getOffsets(),j=this.getScrolls();var i={x:m.x-j.x,y:m.y-j.y};var k=(l&&(l=document.id(l)))?l.getPosition():{x:0,y:0};return{x:i.x-k.x,y:i.y-k.y};},getCoordinates:function(k){if(b(this)){return this.getWindow().getCoordinates();}var i=this.getPosition(k),j=this.getSize();var l={left:i.x,top:i.y,width:j.x,height:j.y};l.right=l.left+l.width;l.bottom=l.top+l.height;return l;},computePosition:function(i){return{left:i.x-f(this,"margin-left"),top:i.y-f(this,"margin-top")};},setPosition:function(i){return this.setStyles(this.computePosition(i));}});Native.implement([Document,Window],{getSize:function(){if(Browser.Engine.presto||Browser.Engine.webkit){var j=this.getWindow();return{x:j.innerWidth,y:j.innerHeight};}var i=a(this);return{x:i.clientWidth,y:i.clientHeight};},getScroll:function(){var j=this.getWindow(),i=a(this);return{x:j.pageXOffset||i.scrollLeft,y:j.pageYOffset||i.scrollTop};},getScrollSize:function(){var j=a(this),i=this.getSize();return{x:Math.max(j.scrollWidth,i.x),y:Math.max(j.scrollHeight,i.y)};},getPosition:function(){return{x:0,y:0};},getCoordinates:function(){var i=this.getSize();return{top:0,left:0,bottom:i.y,right:i.x,height:i.y,width:i.x};}});var d=Element.getComputedStyle;function f(i,j){return d(i,j).toInt()||0;}function g(i){return d(i,"-moz-box-sizing")=="border-box";}function h(i){return f(i,"border-top-width");}function c(i){return f(i,"border-left-width");}function b(i){return(/^(?:body|html)$/i).test(i.tagName);}function a(i){var j=i.getDocument();return(!j.compatMode||j.compatMode=="CSS1Compat")?j.html:j.body;}})();Element.alias("setPosition","position");Native.implement([Window,Document,Element],{getHeight:function(){return this.getSize().y;},getWidth:function(){return this.getSize().x;},getScrollTop:function(){return this.getScroll().y;},getScrollLeft:function(){return this.getScroll().x;},getScrollHeight:function(){return this.getScrollSize().y;},getScrollWidth:function(){return this.getScrollSize().x;},getTop:function(){return this.getPosition().y;},getLeft:function(){return this.getPosition().x;}});var Event=new Native({name:"Event",initialize:function(a,g){g=g||window;var l=g.document;a=a||g.event;if(a.$extended){return a;}this.$extended=true;var k=a.type;var h=a.target||a.srcElement;while(h&&h.nodeType==3){h=h.parentNode;}if(k.test(/key/)){var b=a.which||a.keyCode;var n=Event.Keys.keyOf(b);if(k=="keydown"){var d=b-111;if(d>0&&d<13){n="f"+d;}}n=n||String.fromCharCode(b).toLowerCase();}else{if(k.match(/(click|mouse|menu)/i)){l=(!l.compatMode||l.compatMode=="CSS1Compat")?l.html:l.body;var j={x:a.pageX||a.clientX+l.scrollLeft,y:a.pageY||a.clientY+l.scrollTop};var c={x:(a.pageX)?a.pageX-g.pageXOffset:a.clientX,y:(a.pageY)?a.pageY-g.pageYOffset:a.clientY};if(k.match(/DOMMouseScroll|mousewheel/)){var i=(a.wheelDelta)?a.wheelDelta/120:-(a.detail||0)/3;}var f=(a.which==3)||(a.button==2);var m=null;if(k.match(/over|out/)){switch(k){case"mouseover":m=a.relatedTarget||a.fromElement;break;case"mouseout":m=a.relatedTarget||a.toElement;}if(!(function(){while(m&&m.nodeType==3){m=m.parentNode;}return true;}).create({attempt:Browser.Engine.gecko})()){m=false;}}}}return $extend(this,{event:a,type:k,page:j,client:c,rightClick:f,wheel:i,relatedTarget:m,target:h,code:b,key:n,shift:a.shiftKey,control:a.ctrlKey,alt:a.altKey,meta:a.metaKey});}});Event.Keys=new Hash({enter:13,up:38,down:40,left:37,right:39,esc:27,space:32,backspace:8,tab:9,"delete":46});Event.implement({stop:function(){return this.stopPropagation().preventDefault();},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;}});Element.Properties.events={set:function(a){this.addEvents(a);}};Native.implement([Element,Window,Document],{addEvent:function(f,h){var i=this.retrieve("events",{});i[f]=i[f]||{keys:[],values:[]};if(i[f].keys.contains(h)){return this;}i[f].keys.push(h);var g=f,a=Element.Events.get(f),c=h,j=this;if(a){if(a.onAdd){a.onAdd.call(this,h);}if(a.condition){c=function(k){if(a.condition.call(this,k)){return h.call(this,k);}return true;};}g=a.base||g;}var d=function(){return h.call(j);};var b=Element.NativeEvents[g];if(b){if(b==2){d=function(k){k=new Event(k,j.getWindow());if(c.call(j,k)===false){k.stop();}};}this.addListener(g,d);}i[f].values.push(d);return this;},removeEvent:function(c,b){var a=this.retrieve("events");if(!a||!a[c]){return this;}var g=a[c].keys.indexOf(b);if(g==-1){return this;}a[c].keys.splice(g,1);var f=a[c].values.splice(g,1)[0];var d=Element.Events.get(c);if(d){if(d.onRemove){d.onRemove.call(this,b);}c=d.base||c;}return(Element.NativeEvents[c])?this.removeListener(c,f):this;},addEvents:function(a){for(var b in a){this.addEvent(b,a[b]);}return this;},removeEvents:function(a){var c;if($type(a)=="object"){for(c in a){this.removeEvent(c,a[c]);}return this;}var b=this.retrieve("events");if(!b){return this;}if(!a){for(c in b){this.removeEvents(c);}this.eliminate("events");}else{if(b[a]){while(b[a].keys[0]){this.removeEvent(a,b[a].keys[0]);}b[a]=null;}}return this;},fireEvent:function(d,b,a){var c=this.retrieve("events");if(!c||!c[d]){return this;}c[d].keys.each(function(f){f.create({bind:this,delay:a,"arguments":b})();},this);return this;},cloneEvents:function(d,a){d=document.id(d);var c=d.retrieve("events");if(!c){return this;}if(!a){for(var b in c){this.cloneEvents(d,b);}}else{if(c[a]){c[a].keys.each(function(f){this.addEvent(a,f);},this);}}return this;}});try{if(typeof HTMLElement!="undefined"){HTMLElement.prototype.fireEvent=Element.prototype.fireEvent;}}catch(e){}Element.NativeEvents={click:2,dblclick:2,mouseup:2,mousedown:2,contextmenu:2,mousewheel:2,DOMMouseScroll:2,mouseover:2,mouseout:2,mousemove:2,selectstart:2,selectend:2,keydown:2,keypress:2,keyup:2,focus:2,blur:2,change:2,reset:2,select:2,submit:2,load:1,unload:1,beforeunload:2,resize:1,move:1,DOMContentLoaded:1,readystatechange:1,error:1,abort:1,scroll:1};(function(){var a=function(b){var c=b.relatedTarget;if(c==undefined){return true;}if(c===false){return false;}return($type(this)!="document"&&c!=this&&c.prefix!="xul"&&!this.hasChild(c));};Element.Events=new Hash({mouseenter:{base:"mouseover",condition:a},mouseleave:{base:"mouseout",condition:a},mousewheel:{base:(Browser.Engine.gecko)?"DOMMouseScroll":"mousewheel"}});})();Element.Properties.styles={set:function(a){this.setStyles(a);}};Element.Properties.opacity={set:function(a,b){if(!b){if(a==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(Browser.Engine.trident){this.style.filter=(a==1)?"":"alpha(opacity="+a*100+")";}this.style.opacity=a;this.store("opacity",a);},get:function(){return this.retrieve("opacity",1);}};Element.implement({setOpacity:function(a){return this.set("opacity",a,true);},getOpacity:function(){return this.get("opacity");},setStyle:function(b,a){switch(b){case"opacity":return this.set("opacity",parseFloat(a));case"float":b=(Browser.Engine.trident)?"styleFloat":"cssFloat";}b=b.camelCase();if($type(a)!="string"){var c=(Element.Styles.get(b)||"@").split(" ");a=$splat(a).map(function(f,d){if(!c[d]){return"";}return($type(f)=="number")?c[d].replace("@",Math.round(f)):f;}).join(" ");}else{if(a==String(Number(a))){a=Math.round(a);}}this.style[b]=a;return this;},getStyle:function(h){switch(h){case"opacity":return this.get("opacity");case"float":h=(Browser.Engine.trident)?"styleFloat":"cssFloat";}h=h.camelCase();var a=this.style[h];if(!$chk(a)){a=[];for(var g in Element.ShortStyles){if(h!=g){continue;}for(var f in Element.ShortStyles[g]){a.push(this.getStyle(f));}return a.join(" ");}a=this.getComputedStyle(h);}if(a){a=String(a);var c=a.match(/rgba?\([\d\s,]+\)/);if(c){a=a.replace(c[0],c[0].rgbToHex());}}if(Browser.Engine.presto||(Browser.Engine.trident&&!$chk(parseInt(a,10)))){if(h.test(/^(height|width)$/)){var b=(h=="width")?["left","right"]:["top","bottom"],d=0;b.each(function(i){d+=this.getStyle("border-"+i+"-width").toInt()+this.getStyle("padding-"+i).toInt();},this);return this["offset"+h.capitalize()]-d+"px";}if((Browser.Engine.presto)&&String(a).test("px")){return a;}if(h.test(/(border(.+)Width|margin|padding)/)){return"0px";}}return a;},setStyles:function(b){for(var a in b){this.setStyle(a,b[a]);}return this;},getStyles:function(){var a={};Array.flatten(arguments).each(function(b){a[b]=this.getStyle(b);},this);return a;}});Element.Styles=new Hash({left:"@px",top:"@px",bottom:"@px",right:"@px",width:"@px",height:"@px",maxWidth:"@px",maxHeight:"@px",minWidth:"@px",minHeight:"@px",backgroundColor:"rgb(@, @, @)",backgroundPosition:"@px @px",color:"rgb(@, @, @)",fontSize:"@px",letterSpacing:"@px",lineHeight:"@px",clip:"rect(@px @px @px @px)",margin:"@px @px @px @px",padding:"@px @px @px @px",border:"@px @ rgb(@, @, @) @px @ rgb(@, @, @) @px @ rgb(@, @, @)",borderWidth:"@px @px @px @px",borderStyle:"@ @ @ @",borderColor:"rgb(@, @, @) rgb(@, @, @) rgb(@, @, @) rgb(@, @, @)",zIndex:"@",zoom:"@",fontWeight:"@",textIndent:"@px",opacity:"@"});Element.ShortStyles={margin:{},padding:{},border:{},borderWidth:{},borderStyle:{},borderColor:{}};["Top","Right","Bottom","Left"].each(function(h){var g=Element.ShortStyles;var b=Element.Styles;["margin","padding"].each(function(i){var j=i+h;g[i][j]=b[j]="@px";});var f="border"+h;g.border[f]=b[f]="@px @ rgb(@, @, @)";var d=f+"Width",a=f+"Style",c=f+"Color";g[f]={};g.borderWidth[d]=g[f][d]=b[d]="@px";g.borderStyle[a]=g[f][a]=b[a]="@";g.borderColor[c]=g[f][c]=b[c]="rgb(@, @, @)";});var Fx=new Class({Implements:[Chain,Events,Options],options:{fps:50,unit:false,duration:500,link:"ignore"},initialize:function(a){this.subject=this.subject||this;this.setOptions(a);this.options.duration=Fx.Durations[this.options.duration]||this.options.duration.toInt();var b=this.options.wait;if(b===false){this.options.link="cancel";}},getTransition:function(){return function(a){return -(Math.cos(Math.PI*a)-1)/2;};},step:function(){var a=$time();if(a<this.time+this.options.duration){var b=this.transition((a-this.time)/this.options.duration);this.set(this.compute(this.from,this.to,b));}else{this.set(this.compute(this.from,this.to,1));this.complete();}},set:function(a){return a;},compute:function(c,b,a){return Fx.compute(c,b,a);},check:function(){if(!this.timer){return true;}switch(this.options.link){case"cancel":this.cancel();return true;case"chain":this.chain(this.caller.bind(this,arguments));return false;}return false;},start:function(b,a){if(!this.check(b,a)){return this;}this.from=b;this.to=a;this.time=0;this.transition=this.getTransition();this.startTimer();this.onStart();return this;},complete:function(){if(this.stopTimer()){this.onComplete();}return this;},cancel:function(){if(this.stopTimer()){this.onCancel();}return this;},onStart:function(){this.fireEvent("start",this.subject);},onComplete:function(){this.fireEvent("complete",this.subject);if(!this.callChain()){this.fireEvent("chainComplete",this.subject);}},onCancel:function(){this.fireEvent("cancel",this.subject).clearChain();},pause:function(){this.stopTimer();return this;},resume:function(){this.startTimer();return this;},stopTimer:function(){if(!this.timer){return false;}this.time=$time()-this.time;this.timer=$clear(this.timer);return true;},startTimer:function(){if(this.timer){return false;}this.time=$time()-this.time;this.timer=this.step.periodical(Math.round(1000/this.options.fps),this);return true;}});Fx.compute=function(c,b,a){return(b-c)*a+c;};Fx.Durations={"short":250,normal:500,"long":1000};Fx.CSS=new Class({Extends:Fx,prepare:function(d,f,b){b=$splat(b);var c=b[1];if(!$chk(c)){b[1]=b[0];b[0]=d.getStyle(f);}var a=b.map(this.parse);return{from:a[0],to:a[1]};},parse:function(a){a=$lambda(a)();a=(typeof a=="string")?a.split(" "):$splat(a);return a.map(function(c){c=String(c);var b=false;Fx.CSS.Parsers.each(function(g,f){if(b){return;}var d=g.parse(c);if($chk(d)){b={value:d,parser:g};}});b=b||{value:c,parser:Fx.CSS.Parsers.String};return b;});},compute:function(d,c,b){var a=[];(Math.min(d.length,c.length)).times(function(f){a.push({value:d[f].parser.compute(d[f].value,c[f].value,b),parser:d[f].parser});});a.$family={name:"fx:css:value"};return a;},serve:function(c,b){if($type(c)!="fx:css:value"){c=this.parse(c);}var a=[];c.each(function(d){a=a.concat(d.parser.serve(d.value,b));});return a;},render:function(a,d,c,b){a.setStyle(d,this.serve(c,b));},search:function(a){if(Fx.CSS.Cache[a]){return Fx.CSS.Cache[a];}var b={};Array.each(document.styleSheets,function(f,d){var c=f.href;if(c&&c.contains("://")&&!c.contains(document.domain)){return;}var g=f.rules||f.cssRules;Array.each(g,function(k,h){if(!k.style){return;}var j=(k.selectorText)?k.selectorText.replace(/^\w+/,function(i){return i.toLowerCase();}):null;if(!j||!j.test("^"+a+"$")){return;}Element.Styles.each(function(l,i){if(!k.style[i]||Element.ShortStyles[i]){return;}l=String(k.style[i]);b[i]=(l.test(/^rgb/))?l.rgbToHex():l;});});});return Fx.CSS.Cache[a]=b;}});Fx.CSS.Cache={};Fx.CSS.Parsers=new Hash({Color:{parse:function(a){if(a.match(/^#[0-9a-f]{3,6}$/i)){return a.hexToRgb(true);}return((a=a.match(/(\d+),\s*(\d+),\s*(\d+)/)))?[a[1],a[2],a[3]]:false;},compute:function(c,b,a){return c.map(function(f,d){return Math.round(Fx.compute(c[d],b[d],a));});},serve:function(a){return a.map(Number);}},Number:{parse:parseFloat,compute:Fx.compute,serve:function(b,a){return(a)?b+a:b;}},String:{parse:$lambda(false),compute:$arguments(1),serve:$arguments(0)}});Fx.Morph=new Class({Extends:Fx.CSS,initialize:function(b,a){this.element=this.subject=document.id(b);this.parent(a);},set:function(a){if(typeof a=="string"){a=this.search(a);}for(var b in a){this.render(this.element,b,a[b],this.options.unit);}return this;},compute:function(f,d,c){var a={};for(var b in f){a[b]=this.parent(f[b],d[b],c);}return a;},start:function(b){if(!this.check(b)){return this;}if(typeof b=="string"){b=this.search(b);}var f={},d={};for(var c in b){var a=this.prepare(this.element,c,b[c]);f[c]=a.from;d[c]=a.to;}return this.parent(f,d);}});Element.Properties.morph={set:function(a){var b=this.retrieve("morph");if(b){b.cancel();}return this.eliminate("morph").store("morph:options",$extend({link:"cancel"},a));},get:function(a){if(a||!this.retrieve("morph")){if(a||!this.retrieve("morph:options")){this.set("morph",a);}this.store("morph",new Fx.Morph(this,this.retrieve("morph:options")));}return this.retrieve("morph");}};Element.implement({morph:function(a){this.get("morph").start(a);return this;}});Fx.implement({getTransition:function(){var a=this.options.transition||Fx.Transitions.Sine.easeInOut;if(typeof a=="string"){var b=a.split(":");a=Fx.Transitions;a=a[b[0]]||a[b[0].capitalize()];if(b[1]){a=a["ease"+b[1].capitalize()+(b[2]?b[2].capitalize():"")];}}return a;}});Fx.Transition=function(b,a){a=$splat(a);return $extend(b,{easeIn:function(c){return b(c,a);},easeOut:function(c){return 1-b(1-c,a);},easeInOut:function(c){return(c<=0.5)?b(2*c,a)/2:(2-b(2*(1-c),a))/2;}});};Fx.Transitions=new Hash({linear:$arguments(0)});Fx.Transitions.extend=function(a){for(var b in a){Fx.Transitions[b]=new Fx.Transition(a[b]);}};Fx.Transitions.extend({Pow:function(b,a){return Math.pow(b,a[0]||6);},Expo:function(a){return Math.pow(2,8*(a-1));},Circ:function(a){return 1-Math.sin(Math.acos(a));},Sine:function(a){return 1-Math.sin((1-a)*Math.PI/2);},Back:function(b,a){a=a[0]||1.618;return Math.pow(b,2)*((a+1)*b-a);},Bounce:function(g){var f;for(var d=0,c=1;1;d+=c,c/=2){if(g>=(7-4*d)/11){f=c*c-Math.pow((11-6*d-11*g)/4,2);break;}}return f;},Elastic:function(b,a){return Math.pow(2,10*--b)*Math.cos(20*b*Math.PI*(a[0]||1)/3);}});["Quad","Cubic","Quart","Quint"].each(function(b,a){Fx.Transitions[b]=new Fx.Transition(function(c){return Math.pow(c,[a+2]);});});Fx.Tween=new Class({Extends:Fx.CSS,initialize:function(b,a){this.element=this.subject=document.id(b);this.parent(a);},set:function(b,a){if(arguments.length==1){a=b;b=this.property||this.options.property;}this.render(this.element,b,a,this.options.unit);return this;},start:function(c,f,d){if(!this.check(c,f,d)){return this;}var b=Array.flatten(arguments);this.property=this.options.property||b.shift();var a=this.prepare(this.element,this.property,b);return this.parent(a.from,a.to);}});Element.Properties.tween={set:function(a){var b=this.retrieve("tween");if(b){b.cancel();}return this.eliminate("tween").store("tween:options",$extend({link:"cancel"},a));},get:function(a){if(a||!this.retrieve("tween")){if(a||!this.retrieve("tween:options")){this.set("tween",a);}this.store("tween",new Fx.Tween(this,this.retrieve("tween:options")));}return this.retrieve("tween");}};Element.implement({tween:function(a,c,b){this.get("tween").start(arguments);return this;},fade:function(c){var f=this.get("tween"),d="opacity",a;c=$pick(c,"toggle");switch(c){case"in":f.start(d,1);break;case"out":f.start(d,0);break;case"show":f.set(d,1);break;case"hide":f.set(d,0);break;case"toggle":var b=this.retrieve("fade:flag",this.get("opacity")==1);f.start(d,(b)?0:1);this.store("fade:flag",!b);a=true;break;default:f.start(d,arguments);}if(!a){this.eliminate("fade:flag");}return this;},highlight:function(c,a){if(!a){a=this.retrieve("highlight:original",this.getStyle("background-color"));a=(a=="transparent")?"#fff":a;}var b=this.get("tween");b.start("background-color",c||"#ffff88",a).chain(function(){this.setStyle("background-color",this.retrieve("highlight:original"));b.callChain();}.bind(this));return this;}});var Request=new Class({Implements:[Chain,Events,Options],options:{url:"",data:"",headers:{"X-Requested-With":"XMLHttpRequest",Accept:"text/javascript, text/html, application/xml, text/xml, */*"},async:true,format:false,method:"post",link:"ignore",isSuccess:null,emulation:true,urlEncoded:true,encoding:"utf-8",evalScripts:false,evalResponse:false,noCache:false},initialize:function(a){this.xhr=new Browser.Request();this.setOptions(a);this.options.isSuccess=this.options.isSuccess||this.isSuccess;this.headers=new Hash(this.options.headers);},onStateChange:function(){if(this.xhr.readyState!=4||!this.running){return;}this.running=false;this.status=0;$try(function(){this.status=this.xhr.status;}.bind(this));this.xhr.onreadystatechange=$empty;if(this.options.isSuccess.call(this,this.status)){this.response={text:this.xhr.responseText,xml:this.xhr.responseXML};this.success(this.response.text,this.response.xml);}else{this.response={text:null,xml:null};this.failure();}},isSuccess:function(){return((this.status>=200)&&(this.status<300));},processScripts:function(a){if(this.options.evalResponse||(/(ecma|java)script/).test(this.getHeader("Content-type"))){return $exec(a);}return a.stripScripts(this.options.evalScripts);},success:function(b,a){this.onSuccess(this.processScripts(b),a);},onSuccess:function(){this.fireEvent("complete",arguments).fireEvent("success",arguments).callChain();},failure:function(){this.onFailure();},onFailure:function(){this.fireEvent("complete").fireEvent("failure",this.xhr);},setHeader:function(a,b){this.headers.set(a,b);return this;},getHeader:function(a){return $try(function(){return this.xhr.getResponseHeader(a);}.bind(this));},check:function(){if(!this.running){return true;}switch(this.options.link){case"cancel":this.cancel();return true;case"chain":this.chain(this.caller.bind(this,arguments));return false;}return false;},send:function(l){if(!this.check(l)){return this;}this.running=true;var j=$type(l);if(j=="string"||j=="element"){l={data:l};}var d=this.options;l=$extend({data:d.data,url:d.url,method:d.method},l);var h=l.data,b=String(l.url),a=l.method.toLowerCase();switch($type(h)){case"element":h=document.id(h).toQueryString();break;case"object":case"hash":h=Hash.toQueryString(h);}if(this.options.format){var k="format="+this.options.format;h=(h)?k+"&"+h:k;}if(this.options.emulation&&!["get","post"].contains(a)){var i="_method="+a;h=(h)?i+"&"+h:i;a="post";}if(this.options.urlEncoded&&a=="post"){var c=(this.options.encoding)?"; charset="+this.options.encoding:"";this.headers.set("Content-type","application/x-www-form-urlencoded"+c);}if(this.options.noCache){var g="noCache="+new Date().getTime();h=(h)?g+"&"+h:g;}var f=b.lastIndexOf("/");if(f>-1&&(f=b.indexOf("#"))>-1){b=b.substr(0,f);}if(h&&a=="get"){b=b+(b.contains("?")?"&":"?")+h;h=null;}this.xhr.open(a.toUpperCase(),b,this.options.async);this.xhr.onreadystatechange=this.onStateChange.bind(this);this.headers.each(function(n,m){try{this.xhr.setRequestHeader(m,n);}catch(o){this.fireEvent("exception",[m,n]);}},this);this.fireEvent("request");this.xhr.send(h);if(!this.options.async){this.onStateChange();}return this;},cancel:function(){if(!this.running){return this;}this.running=false;this.xhr.abort();this.xhr.onreadystatechange=$empty;this.xhr=new Browser.Request();this.fireEvent("cancel");return this;}});(function(){var a={};["get","post","put","delete","GET","POST","PUT","DELETE"].each(function(b){a[b]=function(){var c=Array.link(arguments,{url:String.type,data:$defined});return this.send($extend(c,{method:b}));};});Request.implement(a);})();Element.Properties.send={set:function(a){var b=this.retrieve("send");if(b){b.cancel();}return this.eliminate("send").store("send:options",$extend({data:this,link:"cancel",method:this.get("method")||"post",url:this.get("action")},a));},get:function(a){if(a||!this.retrieve("send")){if(a||!this.retrieve("send:options")){this.set("send",a);}this.store("send",new Request(this.retrieve("send:options")));}return this.retrieve("send");}};Element.implement({send:function(a){var b=this.get("send");b.send({data:this,url:a||b.options.url});return this;}});Request.HTML=new Class({Extends:Request,options:{update:false,append:false,evalScripts:true,filter:false},processHTML:function(c){var b=c.match(/<body[^>]*>([\s\S]*?)<\/body>/i);c=(b)?b[1]:c;var a=new Element("div");return $try(function(){var d="<root>"+c+"</root>",h;if(Browser.Engine.trident){h=new ActiveXObject("Microsoft.XMLDOM");h.async=false;h.loadXML(d);}else{h=new DOMParser().parseFromString(d,"text/xml");}d=h.getElementsByTagName("root")[0];if(!d){return null;}for(var g=0,f=d.childNodes.length;g<f;g++){var j=Element.clone(d.childNodes[g],true,true);if(j){a.grab(j);}}return a;})||a.set("html",c);},success:function(d){var c=this.options,b=this.response;b.html=d.stripScripts(function(f){b.javascript=f;});var a=this.processHTML(b.html);b.tree=a.childNodes;b.elements=a.getElements("*");if(c.filter){b.tree=b.elements.filter(c.filter);}if(c.update){document.id(c.update).empty().set("html",b.html);}else{if(c.append){document.id(c.append).adopt(a.getChildren());}}if(c.evalScripts){$exec(b.javascript);}this.onSuccess(b.tree,b.elements,b.html,b.javascript);}});Element.Properties.load={set:function(a){var b=this.retrieve("load");if(b){b.cancel();}return this.eliminate("load").store("load:options",$extend({data:this,link:"cancel",update:this,method:"get"},a));},get:function(a){if(a||!this.retrieve("load")){if(a||!this.retrieve("load:options")){this.set("load",a);}this.store("load",new Request.HTML(this.retrieve("load:options")));}return this.retrieve("load");}};Element.implement({load:function(){this.get("load").send(Array.link(arguments,{data:Object.type,url:String.type}));return this;}});var JSON=new Hash(this.JSON&&{stringify:JSON.stringify,parse:JSON.parse}).extend({$specialChars:{"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},$replaceChars:function(a){return JSON.$specialChars[a]||"\\u00"+Math.floor(a.charCodeAt()/16).toString(16)+(a.charCodeAt()%16).toString(16);},encode:function(b){switch($type(b)){case"string":return'"'+b.replace(/[\x00-\x1f\\"]/g,JSON.$replaceChars)+'"';case"array":return"["+String(b.map(JSON.encode).clean())+"]";case"object":case"hash":var a=[];Hash.each(b,function(f,d){var c=JSON.encode(f);if(c){a.push(JSON.encode(d)+":"+c);}});return"{"+a+"}";case"number":case"boolean":return String(b);case false:return"null";}return null;},decode:function(string,secure){if($type(string)!="string"||!string.length){return null;}if(secure&&!(/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(string.replace(/\\./g,"@").replace(/"[^"\\\n\r]*"/g,""))){return null;}return eval("("+string+")");}});Request.JSON=new Class({Extends:Request,options:{secure:true},initialize:function(a){this.parent(a);this.headers.extend({Accept:"application/json","X-Request":"JSON"});},success:function(a){this.response.json=JSON.decode(a,this.options.secure);this.onSuccess(this.response.json,a);}});var Cookie=new Class({Implements:Options,options:{path:false,domain:false,duration:false,secure:false,document:document},initialize:function(b,a){this.key=b;this.setOptions(a);},write:function(b){b=encodeURIComponent(b);if(this.options.domain){b+="; domain="+this.options.domain;}if(this.options.path){b+="; path="+this.options.path;}if(this.options.duration){var a=new Date();a.setTime(a.getTime()+this.options.duration*24*60*60*1000);b+="; expires="+a.toGMTString();}if(this.options.secure){b+="; secure";}this.options.document.cookie=this.key+"="+b;return this;},read:function(){var a=this.options.document.cookie.match("(?:^|;)\\s*"+this.key.escapeRegExp()+"=([^;]*)");return(a)?decodeURIComponent(a[1]):null;},dispose:function(){new Cookie(this.key,$merge(this.options,{duration:-1})).write("");return this;}});Cookie.write=function(b,c,a){return new Cookie(b,a).write(c);};Cookie.read=function(a){return new Cookie(a).read();};Cookie.dispose=function(b,a){return new Cookie(b,a).dispose();};Element.Events.domready={onAdd:function(a){if(Browser.loaded){a.call(this);}}};(function(){var b=function(){if(Browser.loaded){return;}Browser.loaded=true;window.fireEvent("domready");document.fireEvent("domready");};window.addEvent("load",b);if(Browser.Engine.trident){var a=document.createElement("div");(function(){($try(function(){a.doScroll();return document.id(a).inject(document.body).set("html","temp").dispose();}))?b():arguments.callee.delay(50);})();}else{if(Browser.Engine.webkit&&Browser.Engine.version<525){(function(){(["loaded","complete"].contains(document.readyState))?b():arguments.callee.delay(50);})();}else{document.addEvent("DOMContentLoaded",b);}}})();Native.implement([Document,Element],{getElements:function(j,h){j=j.split(",");var c,f={};for(var d=0,b=j.length;d<b;d++){var a=j[d],g=Selectors.Utils.search(this,a,f);if(d!=0&&g.item){g=$A(g);}c=(d==0)?g:(c.item)?$A(c).concat(g):c.concat(g);}return new Elements(c,{ddup:(j.length>1),cash:!h});}});Element.implement({match:function(b){if(!b||(b==this)){return true;}var d=Selectors.Utils.parseTagAndID(b);var a=d[0],f=d[1];if(!Selectors.Filters.byID(this,f)||!Selectors.Filters.byTag(this,a)){return false;}var c=Selectors.Utils.parseSelector(b);return(c)?Selectors.Utils.filter(this,c,{}):true;}});var Selectors={Cache:{nth:{},parsed:{}}};Selectors.RegExps={id:(/#([\w-]+)/),tag:(/^(\w+|\*)/),quick:(/^(\w+|\*)$/),splitter:(/\s*([+>~\s])\s*([a-zA-Z#.*:\[])/g),combined:(/\.([\w-]+)|\[(\w+)(?:([!*^$~|]?=)(["']?)([^\4]*?)\4)?\]|:([\w-]+)(?:\(["']?(.*?)?["']?\)|$)/g)};Selectors.Utils={chk:function(b,c){if(!c){return true;}var a=$uid(b);if(!c[a]){return c[a]=true;}return false;},parseNthArgument:function(i){if(Selectors.Cache.nth[i]){return Selectors.Cache.nth[i];}var f=i.match(/^([+-]?\d*)?([a-z]+)?([+-]?\d*)?$/);if(!f){return false;}var h=parseInt(f[1],10);var d=(h||h===0)?h:1;var g=f[2]||false;var c=parseInt(f[3],10)||0;if(d!=0){c--;while(c<1){c+=d;}while(c>=d){c-=d;}}else{d=c;g="index";}switch(g){case"n":f={a:d,b:c,special:"n"};break;case"odd":f={a:2,b:0,special:"n"};break;case"even":f={a:2,b:1,special:"n"};break;case"first":f={a:0,special:"index"};break;case"last":f={special:"last-child"};break;case"only":f={special:"only-child"};break;default:f={a:(d-1),special:"index"};}return Selectors.Cache.nth[i]=f;},parseSelector:function(f){if(Selectors.Cache.parsed[f]){return Selectors.Cache.parsed[f];}var d,i={classes:[],pseudos:[],attributes:[]};while((d=Selectors.RegExps.combined.exec(f))){var j=d[1],h=d[2],g=d[3],b=d[5],c=d[6],k=d[7];if(j){i.classes.push(j);}else{if(c){var a=Selectors.Pseudo.get(c);if(a){i.pseudos.push({parser:a,argument:k});}else{i.attributes.push({name:c,operator:"=",value:k});}}else{if(h){i.attributes.push({name:h,operator:g,value:b});}}}}if(!i.classes.length){delete i.classes;}if(!i.attributes.length){delete i.attributes;}if(!i.pseudos.length){delete i.pseudos;}if(!i.classes&&!i.attributes&&!i.pseudos){i=null;}return Selectors.Cache.parsed[f]=i;},parseTagAndID:function(b){var a=b.match(Selectors.RegExps.tag);var c=b.match(Selectors.RegExps.id);return[(a)?a[1]:"*",(c)?c[1]:false];},filter:function(g,c,f){var d;if(c.classes){for(d=c.classes.length;d--;d){var h=c.classes[d];if(!Selectors.Filters.byClass(g,h)){return false;}}}if(c.attributes){for(d=c.attributes.length;d--;d){var b=c.attributes[d];if(!Selectors.Filters.byAttribute(g,b.name,b.operator,b.value)){return false;}}}if(c.pseudos){for(d=c.pseudos.length;d--;d){var a=c.pseudos[d];if(!Selectors.Filters.byPseudo(g,a.parser,a.argument,f)){return false;}}}return true;},getByTagAndID:function(b,a,d){if(d){var c=(b.getElementById)?b.getElementById(d,true):Element.getElementById(b,d,true);return(c&&Selectors.Filters.byTag(c,a))?[c]:[];}else{return b.getElementsByTagName(a);}},search:function(p,o,u){var b=[];var c=o.trim().replace(Selectors.RegExps.splitter,function(k,j,i){b.push(j);return":)"+i;}).split(":)");var q,f,B;for(var A=0,w=c.length;A<w;A++){var z=c[A];if(A==0&&Selectors.RegExps.quick.test(z)){q=p.getElementsByTagName(z);continue;}var a=b[A-1];var r=Selectors.Utils.parseTagAndID(z);var C=r[0],s=r[1];if(A==0){q=Selectors.Utils.getByTagAndID(p,C,s);}else{var d={},h=[];for(var y=0,x=q.length;y<x;y++){h=Selectors.Getters[a](h,q[y],C,s,d);}q=h;}var g=Selectors.Utils.parseSelector(z);if(g){f=[];for(var v=0,t=q.length;v<t;v++){B=q[v];if(Selectors.Utils.filter(B,g,u)){f.push(B);}}q=f;}}return q;}};Selectors.Getters={" ":function(j,h,k,a,f){var d=Selectors.Utils.getByTagAndID(h,k,a);for(var c=0,b=d.length;c<b;c++){var g=d[c];if(Selectors.Utils.chk(g,f)){j.push(g);}}return j;},">":function(j,h,k,a,g){var c=Selectors.Utils.getByTagAndID(h,k,a);for(var f=0,d=c.length;f<d;f++){var b=c[f];if(b.parentNode==h&&Selectors.Utils.chk(b,g)){j.push(b);}}return j;},"+":function(c,b,a,f,d){while((b=b.nextSibling)){if(b.nodeType==1){if(Selectors.Utils.chk(b,d)&&Selectors.Filters.byTag(b,a)&&Selectors.Filters.byID(b,f)){c.push(b);}break;}}return c;},"~":function(c,b,a,f,d){while((b=b.nextSibling)){if(b.nodeType==1){if(!Selectors.Utils.chk(b,d)){break;}if(Selectors.Filters.byTag(b,a)&&Selectors.Filters.byID(b,f)){c.push(b);}}}return c;}};Selectors.Filters={byTag:function(b,a){return(a=="*"||(b.tagName&&b.tagName.toLowerCase()==a));},byID:function(a,b){return(!b||(a.id&&a.id==b));},byClass:function(b,a){return(b.className&&b.className.contains&&b.className.contains(a," "));},byPseudo:function(a,d,c,b){return d.call(a,c,b);},byAttribute:function(c,d,b,f){var a=Element.prototype.getProperty.call(c,d);if(!a){return(b=="!=");}if(!b||f==undefined){return true;}switch(b){case"=":return(a==f);case"*=":return(a.contains(f));case"^=":return(a.substr(0,f.length)==f);case"$=":return(a.substr(a.length-f.length)==f);case"!=":return(a!=f);case"~=":return a.contains(f," ");case"|=":return a.contains(f,"-");}return false;}};Selectors.Pseudo=new Hash({checked:function(){return this.checked;},empty:function(){return !(this.innerText||this.textContent||"").length;},not:function(a){return !Element.match(this,a);},contains:function(a){return(this.innerText||this.textContent||"").contains(a);},"first-child":function(){return Selectors.Pseudo.index.call(this,0);},"last-child":function(){var a=this;while((a=a.nextSibling)){if(a.nodeType==1){return false;}}return true;},"only-child":function(){var b=this;while((b=b.previousSibling)){if(b.nodeType==1){return false;}}var a=this;while((a=a.nextSibling)){if(a.nodeType==1){return false;}}return true;},"nth-child":function(h,f){h=(h==undefined)?"n":h;var c=Selectors.Utils.parseNthArgument(h);if(c.special!="n"){return Selectors.Pseudo[c.special].call(this,c.a,f);}var g=0;f.positions=f.positions||{};var d=$uid(this);if(!f.positions[d]){var b=this;while((b=b.previousSibling)){if(b.nodeType!=1){continue;}g++;var a=f.positions[$uid(b)];if(a!=undefined){g=a+g;break;}}f.positions[d]=g;}return(f.positions[d]%c.a==c.b);},index:function(a){var b=this,c=0;while((b=b.previousSibling)){if(b.nodeType==1&&++c>a){return false;}}return(c==a);},even:function(b,a){return Selectors.Pseudo["nth-child"].call(this,"2n+1",a);},odd:function(b,a){return Selectors.Pseudo["nth-child"].call(this,"2n",a);},selected:function(){return this.selected;},enabled:function(){return(this.disabled===false);}});var Swiff=new Class({Implements:[Options],options:{id:null,height:1,width:1,container:null,properties:{},params:{quality:"high",allowScriptAccess:"always",wMode:"transparent",swLiveConnect:true},callBacks:{},vars:{}},toElement:function(){return this.object;},initialize:function(m,n){this.instance="Swiff_"+$time();this.setOptions(n);n=this.options;var b=this.id=n.id||this.instance;var a=document.id(n.container);Swiff.CallBacks[this.instance]={};var f=n.params,h=n.vars,g=n.callBacks;var i=$extend({height:n.height,width:n.width},n.properties);var l=this;for(var d in g){Swiff.CallBacks[this.instance][d]=(function(o){return function(){return o.apply(l.object,arguments);};})(g[d]);h[d]="Swiff.CallBacks."+this.instance+"."+d;}f.flashVars=Hash.toQueryString(h);if(Browser.Engine.trident){i.classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000";f.movie=m;}else{i.type="application/x-shockwave-flash";i.data=m;}var k='<object id="'+b+'"';for(var j in i){k+=" "+j+'="'+i[j]+'"';}k+=">";for(var c in f){if(f[c]){k+='<param name="'+c+'" value="'+f[c]+'" />';}}k+="</object>";this.object=((a)?a.empty():new Element("div")).set("html",k).firstChild;},replaces:function(a){a=document.id(a,true);a.parentNode.replaceChild(this.toElement(),a);return this;},inject:function(a){document.id(a,true).appendChild(this.toElement());return this;},remote:function(){return Swiff.remote.apply(Swiff,[this.toElement()].extend(arguments));}});Swiff.CallBacks={};Swiff.remote=function(obj,fn){var rs=obj.CallFunction('<invoke name="'+fn+'" returntype="javascript">'+__flash__argumentsToXML(arguments,2)+"</invoke>");return eval(rs);};
- //MooTools More, <http://mootools.net/more>. Copyright (c) 2006-2009 Aaron Newton <http://clientcide.com/>, Valerio Proietti <http://mad4milk.net> & the MooTools team <http://mootools.net/developers>, MIT Style License.
- MooTools.More={version:"1.2.5.1",build:"254884f2b83651bf95260eed5c6cceb838e22d8e"};Class.Mutators.Binds=function(a){return a;};Class.Mutators.initialize=function(a){return function(){$splat(this.Binds).each(function(b){var c=this[b];
- if(c){this[b]=c.bind(this);}},this);return a.apply(this,arguments);};};Element.implement({measure:function(e){var g=function(h){return !!(!h||h.offsetHeight||h.offsetWidth);
- };if(g(this)){return e.apply(this);}var d=this.getParent(),f=[],b=[];while(!g(d)&&d!=document.body){b.push(d.expose());d=d.getParent();}var c=this.expose();
- var a=e.apply(this);c();b.each(function(h){h();});return a;},expose:function(){if(this.getStyle("display")!="none"){return $empty;}var a=this.style.cssText;
- this.setStyles({display:"block",position:"absolute",visibility:"hidden"});return function(){this.style.cssText=a;}.bind(this);},getDimensions:function(a){a=$merge({computeSize:false},a);
- var f={};var d=function(g,e){return(e.computeSize)?g.getComputedSize(e):g.getSize();};var b=this.getParent("body");if(b&&this.getStyle("display")=="none"){f=this.measure(function(){return d(this,a);
- });}else{if(b){try{f=d(this,a);}catch(c){}}else{f={x:0,y:0};}}return $chk(f.x)?$extend(f,{width:f.x,height:f.y}):$extend(f,{x:f.width,y:f.height});},getComputedSize:function(a){if(a&&a.plains){a.planes=a.plains;
- }a=$merge({styles:["padding","border"],planes:{height:["top","bottom"],width:["left","right"]},mode:"both"},a);var c={width:0,height:0};switch(a.mode){case"vertical":delete c.width;
- delete a.planes.width;break;case"horizontal":delete c.height;delete a.planes.height;break;}var b=[];$each(a.planes,function(f,g){f.each(function(h){a.styles.each(function(i){b.push((i=="border")?i+"-"+h+"-width":i+"-"+h);
- });});});var e={};b.each(function(f){e[f]=this.getComputedStyle(f);},this);var d=[];$each(a.planes,function(f,g){var h=g.capitalize();c["total"+h]=c["computed"+h]=0;
- f.each(function(i){c["computed"+i.capitalize()]=0;b.each(function(k,j){if(k.test(i)){e[k]=e[k].toInt()||0;c["total"+h]=c["total"+h]+e[k];c["computed"+i.capitalize()]=c["computed"+i.capitalize()]+e[k];
- }if(k.test(i)&&g!=k&&(k.test("border")||k.test("padding"))&&!d.contains(k)){d.push(k);c["computed"+h]=c["computed"+h]-e[k];}});});});["Width","Height"].each(function(g){var f=g.toLowerCase();
- if(!$chk(c[f])){return;}c[f]=c[f]+this["offset"+g]+c["computed"+g];c["total"+g]=c[f]+c["total"+g];delete c["computed"+g];},this);return $extend(e,c);}});
- Fx.Elements=new Class({Extends:Fx.CSS,initialize:function(b,a){this.elements=this.subject=$$(b);this.parent(a);},compute:function(g,h,j){var c={};for(var d in g){var a=g[d],e=h[d],f=c[d]={};
- for(var b in a){f[b]=this.parent(a[b],e[b],j);}}return c;},set:function(b){for(var c in b){if(!this.elements[c]){continue;}var a=b[c];for(var d in a){this.render(this.elements[c],d,a[d],this.options.unit);
- }}return this;},start:function(c){if(!this.check(c)){return this;}var h={},j={};for(var d in c){if(!this.elements[d]){continue;}var f=c[d],a=h[d]={},g=j[d]={};
- for(var b in f){var e=this.prepare(this.elements[d],b,f[b]);a[b]=e.from;g[b]=e.to;}}return this.parent(h,j);}});Fx.Accordion=new Class({Extends:Fx.Elements,options:{fixedHeight:false,fixedWidth:false,display:0,show:false,height:true,width:false,opacity:true,alwaysHide:false,trigger:"click",initialDisplayFx:true,returnHeightToAuto:true},initialize:function(){var c=Array.link(arguments,{container:Element.type,options:Object.type,togglers:$defined,elements:$defined});
- this.parent(c.elements,c.options);this.togglers=$$(c.togglers);this.previous=-1;this.internalChain=new Chain();if(this.options.alwaysHide){this.options.wait=true;
- }if($chk(this.options.show)){this.options.display=false;this.previous=this.options.show;}if(this.options.start){this.options.display=false;this.options.show=false;
- }this.effects={};if(this.options.opacity){this.effects.opacity="fullOpacity";}if(this.options.width){this.effects.width=this.options.fixedWidth?"fullWidth":"offsetWidth";
- }if(this.options.height){this.effects.height=this.options.fixedHeight?"fullHeight":"scrollHeight";}for(var b=0,a=this.togglers.length;b<a;b++){this.addSection(this.togglers[b],this.elements[b]);
- }this.elements.each(function(e,d){if(this.options.show===d){this.fireEvent("active",[this.togglers[d],e]);}else{for(var f in this.effects){e.setStyle(f,0);
- }}},this);if($chk(this.options.display)||this.options.initialDisplayFx===false){this.display(this.options.display,this.options.initialDisplayFx);}if(this.options.fixedHeight!==false){this.options.returnHeightToAuto=false;
- }this.addEvent("complete",this.internalChain.callChain.bind(this.internalChain));},addSection:function(e,c){e=document.id(e);c=document.id(c);var f=this.togglers.contains(e);
- this.togglers.include(e);this.elements.include(c);var a=this.togglers.indexOf(e);var b=this.display.bind(this,a);e.store("accordion:display",b);e.addEvent(this.options.trigger,b);
- if(this.options.height){c.setStyles({"padding-top":0,"border-top":"none","padding-bottom":0,"border-bottom":"none"});}if(this.options.width){c.setStyles({"padding-left":0,"border-left":"none","padding-right":0,"border-right":"none"});
- }c.fullOpacity=1;if(this.options.fixedWidth){c.fullWidth=this.options.fixedWidth;}if(this.options.fixedHeight){c.fullHeight=this.options.fixedHeight;}c.setStyle("overflow","hidden");
- if(!f){for(var d in this.effects){c.setStyle(d,0);}}return this;},removeSection:function(e,b){var a=this.togglers.indexOf(e);var c=this.elements[a];var d=function(){this.togglers.erase(e);
- this.elements.erase(c);this.detach(e);}.bind(this);if(this.now==a||b!=undefined){this.display($pick(b,a-1>=0?a-1:0)).chain(d);}else{d();}return this;},detach:function(b){var a=function(c){c.removeEvent(this.options.trigger,c.retrieve("accordion:display"));
- }.bind(this);if(!b){this.togglers.each(a);}else{a(b);}return this;},display:function(a,b){if(!this.check(a,b)){return this;}b=$pick(b,true);a=($type(a)=="element")?this.elements.indexOf(a):a;
- if(a==this.previous&&!this.options.alwaysHide){return this;}if(this.options.returnHeightToAuto){var d=this.elements[this.previous];if(d&&!this.selfHidden){for(var c in this.effects){d.setStyle(c,d[this.effects[c]]);
- }}}if((this.timer&&this.options.wait)||(a===this.previous&&!this.options.alwaysHide)){return this;}this.previous=a;var e={};this.elements.each(function(h,g){e[g]={};
- var f;if(g!=a){f=true;}else{if(this.options.alwaysHide&&((h.offsetHeight>0&&this.options.height)||h.offsetWidth>0&&this.options.width)){f=true;this.selfHidden=true;
- }}this.fireEvent(f?"background":"active",[this.togglers[g],h]);for(var j in this.effects){e[g][j]=f?0:h[this.effects[j]];}},this);this.internalChain.clearChain();
- this.internalChain.chain(function(){if(this.options.returnHeightToAuto&&!this.selfHidden){var f=this.elements[a];if(f){f.setStyle("height","auto");}}}.bind(this));
- return b?this.start(e):this.set(e);}});var Accordion=new Class({Extends:Fx.Accordion,initialize:function(){this.parent.apply(this,arguments);var a=Array.link(arguments,{container:Element.type});
- this.container=a.container;},addSection:function(c,b,e){c=document.id(c);b=document.id(b);var d=this.togglers.contains(c);var a=this.togglers.length;if(a&&(!d||e)){e=$pick(e,a-1);
- c.inject(this.togglers[e],"before");b.inject(c,"after");}else{if(this.container&&!d){c.inject(this.container);b.inject(this.container);}}return this.parent.apply(this,arguments);
- }});Fx.Scroll=new Class({Extends:Fx,options:{offset:{x:0,y:0},wheelStops:true},initialize:function(b,a){this.element=this.subject=document.id(b);this.parent(a);
- var d=this.cancel.bind(this,false);if($type(this.element)!="element"){this.element=document.id(this.element.getDocument().body);}var c=this.element;if(this.options.wheelStops){this.addEvent("start",function(){c.addEvent("mousewheel",d);
- },true);this.addEvent("complete",function(){c.removeEvent("mousewheel",d);},true);}},set:function(){var a=Array.flatten(arguments);if(Browser.Engine.gecko){a=[Math.round(a[0]),Math.round(a[1])];
- }this.element.scrollTo(a[0]+this.options.offset.x,a[1]+this.options.offset.y);},compute:function(c,b,a){return[0,1].map(function(d){return Fx.compute(c[d],b[d],a);
- });},start:function(c,g){if(!this.check(c,g)){return this;}var e=this.element.getScrollSize(),b=this.element.getScroll(),d={x:c,y:g};for(var f in d){var a=e[f];
- if($chk(d[f])){d[f]=($type(d[f])=="number")?d[f]:a;}else{d[f]=b[f];}d[f]+=this.options.offset[f];}return this.parent([b.x,b.y],[d.x,d.y]);},toTop:function(){return this.start(false,0);
- },toLeft:function(){return this.start(0,false);},toRight:function(){return this.start("right",false);},toBottom:function(){return this.start(false,"bottom");
- },toElement:function(b){var a=document.id(b).getPosition(this.element);return this.start(a.x,a.y);},scrollIntoView:function(c,e,d){e=e?$splat(e):["x","y"];
- var h={};c=document.id(c);var f=c.getPosition(this.element);var i=c.getSize();var g=this.element.getScroll();var a=this.element.getSize();var b={x:f.x+i.x,y:f.y+i.y};
- ["x","y"].each(function(j){if(e.contains(j)){if(b[j]>g[j]+a[j]){h[j]=b[j]-a[j];}if(f[j]<g[j]){h[j]=f[j];}}if(h[j]==null){h[j]=g[j];}if(d&&d[j]){h[j]=h[j]+d[j];
- }},this);if(h.x!=g.x||h.y!=g.y){this.start(h.x,h.y);}return this;},scrollToCenter:function(c,e,d){e=e?$splat(e):["x","y"];c=$(c);var h={},f=c.getPosition(this.element),i=c.getSize(),g=this.element.getScroll(),a=this.element.getSize(),b={x:f.x+i.x,y:f.y+i.y};
- ["x","y"].each(function(j){if(e.contains(j)){h[j]=f[j]-(a[j]-i[j])/2;}if(h[j]==null){h[j]=g[j];}if(d&&d[j]){h[j]=h[j]+d[j];}},this);if(h.x!=g.x||h.y!=g.y){this.start(h.x,h.y);
- }return this;}});Fx.Slide=new Class({Extends:Fx,options:{mode:"vertical",wrapper:false,hideOverflow:true,resetHeight:false},initialize:function(b,a){this.addEvent("complete",function(){this.open=(this.wrapper["offset"+this.layout.capitalize()]!=0);
- if(this.open&&this.options.resetHeight){this.wrapper.setStyle("height","");}if(this.open&&Browser.Engine.webkit419){this.element.dispose().inject(this.wrapper);
- }},true);this.element=this.subject=document.id(b);this.parent(a);var d=this.element.retrieve("wrapper");var c=this.element.getStyles("margin","position","overflow");
- if(this.options.hideOverflow){c=$extend(c,{overflow:"hidden"});}if(this.options.wrapper){d=document.id(this.options.wrapper).setStyles(c);}this.wrapper=d||new Element("div",{styles:c}).wraps(this.element);
- this.element.store("wrapper",this.wrapper).setStyle("margin",0);this.now=[];this.open=true;},vertical:function(){this.margin="margin-top";this.layout="height";
- this.offset=this.element.offsetHeight;},horizontal:function(){this.margin="margin-left";this.layout="width";this.offset=this.element.offsetWidth;},set:function(a){this.element.setStyle(this.margin,a[0]);
- this.wrapper.setStyle(this.layout,a[1]);return this;},compute:function(c,b,a){return[0,1].map(function(d){return Fx.compute(c[d],b[d],a);});},start:function(b,e){if(!this.check(b,e)){return this;
- }this[e||this.options.mode]();var d=this.element.getStyle(this.margin).toInt();var c=this.wrapper.getStyle(this.layout).toInt();var a=[[d,c],[0,this.offset]];
- var g=[[d,c],[-this.offset,0]];var f;switch(b){case"in":f=a;break;case"out":f=g;break;case"toggle":f=(c==0)?a:g;}return this.parent(f[0],f[1]);},slideIn:function(a){return this.start("in",a);
- },slideOut:function(a){return this.start("out",a);},hide:function(a){this[a||this.options.mode]();this.open=false;return this.set([-this.offset,0]);},show:function(a){this[a||this.options.mode]();
- this.open=true;return this.set([0,this.offset]);},toggle:function(a){return this.start("toggle",a);}});Element.Properties.slide={set:function(b){var a=this.retrieve("slide");
- if(a){a.cancel();}return this.eliminate("slide").store("slide:options",$extend({link:"cancel"},b));},get:function(a){if(a||!this.retrieve("slide")){if(a||!this.retrieve("slide:options")){this.set("slide",a);
- }this.store("slide",new Fx.Slide(this,this.retrieve("slide:options")));}return this.retrieve("slide");}};Element.implement({slide:function(d,e){d=d||"toggle";
- var b=this.get("slide"),a;switch(d){case"hide":b.hide(e);break;case"show":b.show(e);break;case"toggle":var c=this.retrieve("slide:flag",b.open);b[c?"slideOut":"slideIn"](e);
- this.store("slide:flag",!c);a=true;break;default:b.start(d,e);}if(!a){this.eliminate("slide:flag");}return this;}});var SmoothScroll=Fx.SmoothScroll=new Class({Extends:Fx.Scroll,initialize:function(b,c){c=c||document;
- this.doc=c.getDocument();var d=c.getWindow();this.parent(this.doc,b);this.links=$$(this.options.links||this.doc.links);var a=d.location.href.match(/^[^#]*/)[0]+"#";
- this.links.each(function(f){if(f.href.indexOf(a)!=0){return;}var e=f.href.substr(a.length);if(e){this.useLink(f,e);}},this);if(!Browser.Engine.webkit419){this.addEvent("complete",function(){d.location.hash=this.anchor;
- },true);}},useLink:function(c,a){var b;c.addEvent("click",function(d){if(b!==false&&!b){b=document.id(a)||this.doc.getElement("a[name="+a+"]");}if(b){d.preventDefault();
- this.anchor=a;this.toElement(b).chain(function(){this.fireEvent("scrolledTo",[c,b]);}.bind(this));c.blur();}}.bind(this));}});var Drag=new Class({Implements:[Events,Options],options:{snap:6,unit:"px",grid:false,style:true,limit:false,handle:false,invert:false,preventDefault:false,stopPropagation:false,modifiers:{x:"left",y:"top"}},initialize:function(){var b=Array.link(arguments,{options:Object.type,element:$defined});
- this.element=document.id(b.element);this.document=this.element.getDocument();this.setOptions(b.options||{});var a=$type(this.options.handle);this.handles=((a=="array"||a=="collection")?$$(this.options.handle):document.id(this.options.handle))||this.element;
- this.mouse={now:{},pos:{}};this.value={start:{},now:{}};this.selection=(Browser.Engine.trident)?"selectstart":"mousedown";this.bound={start:this.start.bind(this),check:this.check.bind(this),drag:this.drag.bind(this),stop:this.stop.bind(this),cancel:this.cancel.bind(this),eventStop:$lambda(false)};
- this.attach();},attach:function(){this.handles.addEvent("mousedown",this.bound.start);return this;},detach:function(){this.handles.removeEvent("mousedown",this.bound.start);
- return this;},start:function(e){if(e.rightClick){return;}if(this.options.preventDefault){e.preventDefault();}if(this.options.stopPropagation){e.stopPropagation();
- }this.mouse.start=e.page;this.fireEvent("beforeStart",this.element);var a=this.options.limit;this.limit={x:[],y:[]};var d=this.element.getStyles("left","right","top","bottom");
- this._invert={x:this.options.modifiers.x=="left"&&d.left=="auto"&&!isNaN(d.right.toInt())&&(this.options.modifiers.x="right"),y:this.options.modifiers.y=="top"&&d.top=="auto"&&!isNaN(d.bottom.toInt())&&(this.options.modifiers.y="bottom")};
- var g,f;for(g in this.options.modifiers){if(!this.options.modifiers[g]){continue;}var c=this.element.getStyle(this.options.modifiers[g]);if(c&&!c.match(/px$/)){if(!f){f=this.element.getCoordinates(this.element.getOffsetParent());
- }c=f[this.options.modifiers[g]];}if(this.options.style){this.value.now[g]=(c||0).toInt();}else{this.value.now[g]=this.element[this.options.modifiers[g]];
- }if(this.options.invert){this.value.now[g]*=-1;}if(this._invert[g]){this.value.now[g]*=-1;}this.mouse.pos[g]=e.page[g]-this.value.now[g];if(a&&a[g]){for(var b=2;
- b--;b){if($chk(a[g][b])){this.limit[g][b]=$lambda(a[g][b])();}}}}if($type(this.options.grid)=="number"){this.options.grid={x:this.options.grid,y:this.options.grid};
- }this.document.addEvents({mousemove:this.bound.check,mouseup:this.bound.cancel});this.document.addEvent(this.selection,this.bound.eventStop);},check:function(a){if(this.options.preventDefault){a.preventDefault();
- }var b=Math.round(Math.sqrt(Math.pow(a.page.x-this.mouse.start.x,2)+Math.pow(a.page.y-this.mouse.start.y,2)));if(b>this.options.snap){this.cancel();this.document.addEvents({mousemove:this.bound.drag,mouseup:this.bound.stop});
- this.fireEvent("start",[this.element,a]).fireEvent("snap",this.element);}},drag:function(a){if(this.options.preventDefault){a.preventDefault();}this.mouse.now=a.page;
- for(var b in this.options.modifiers){if(!this.options.modifiers[b]){continue;}this.value.now[b]=this.mouse.now[b]-this.mouse.pos[b];if(this.options.invert){this.value.now[b]*=-1;
- }if(this._invert[b]){this.value.now[b]*=-1;}if(this.options.limit&&this.limit[b]){if($chk(this.limit[b][1])&&(this.value.now[b]>this.limit[b][1])){this.value.now[b]=this.limit[b][1];
- }else{if($chk(this.limit[b][0])&&(this.value.now[b]<this.limit[b][0])){this.value.now[b]=this.limit[b][0];}}}if(this.options.grid[b]){this.value.now[b]-=((this.value.now[b]-(this.limit[b][0]||0))%this.options.grid[b]);
- }if(this.options.style){this.element.setStyle(this.options.modifiers[b],this.value.now[b]+this.options.unit);}else{this.element[this.options.modifiers[b]]=this.value.now[b];
- }}this.fireEvent("drag",[this.element,a]);},cancel:function(a){this.document.removeEvent("mousemove",this.bound.check);this.document.removeEvent("mouseup",this.bound.cancel);
- if(a){this.document.removeEvent(this.selection,this.bound.eventStop);this.fireEvent("cancel",this.element);}},stop:function(a){this.document.removeEvent(this.selection,this.bound.eventStop);
- this.document.removeEvent("mousemove",this.bound.drag);this.document.removeEvent("mouseup",this.bound.stop);if(a){this.fireEvent("complete",[this.element,a]);
- }}});Element.implement({makeResizable:function(a){var b=new Drag(this,$merge({modifiers:{x:"width",y:"height"}},a));this.store("resizer",b);return b.addEvent("drag",function(){this.fireEvent("resize",b);
- }.bind(this));}});Drag.Move=new Class({Extends:Drag,options:{droppables:[],container:false,precalculate:false,includeMargins:true,checkDroppables:true},initialize:function(b,a){this.parent(b,a);
- b=this.element;this.droppables=$$(this.options.droppables);this.container=document.id(this.options.container);if(this.container&&$type(this.container)!="element"){this.container=document.id(this.container.getDocument().body);
- }if(this.options.style){if(this.options.modifiers.x=="left"&&this.options.modifiers.y=="top"){var f,c=document.id(b.getOffsetParent());if(c){f=c.getStyles("border-top-width","border-left-width");
- }var d=b.getStyles("left","top");if(c&&(d.left=="auto"||d.top=="auto")){var e=b.getPosition(c);e.x=e.x-(f["border-left-width"]?f["border-left-width"].toInt():0);
- e.y=e.y-(f["border-top-width"]?f["border-top-width"].toInt():0);b.setPosition(e);}}if(b.getStyle("position")=="static"){b.setStyle("position","absolute");
- }}this.addEvent("start",this.checkDroppables,true);this.overed=null;},start:function(a){if(this.container){this.options.limit=this.calculateLimit();}if(this.options.precalculate){this.positions=this.droppables.map(function(b){return b.getCoordinates();
- });}this.parent(a);},calculateLimit:function(){var d=document.id(this.element.getOffsetParent())||document.body,h=this.container.getCoordinates(d),g={},c={},b={},j={},f={},l={};
- ["top","right","bottom","left"].each(function(p){g[p]=this.container.getStyle("border-"+p).toInt();b[p]=this.element.getStyle("border-"+p).toInt();c[p]=this.element.getStyle("margin-"+p).toInt();
- j[p]=this.container.getStyle("margin-"+p).toInt();l[p]=d.getStyle("padding-"+p).toInt();f[p]=d.getStyle("border-"+p).toInt();},this);var e=this.element.offsetWidth+c.left+c.right,o=this.element.offsetHeight+c.top+c.bottom,i=0,k=0,n=h.right-g.right-e,a=h.bottom-g.bottom-o;
- if(this.options.includeMargins){i+=c.left;k+=c.top;}else{n+=c.right;a+=c.bottom;}if(this.element.getStyle("position")=="relative"){var m=this.element.getCoordinates(d);
- m.left-=this.element.getStyle("left").toInt();m.top-=this.element.getStyle("top").toInt();i+=g.left-m.left;k+=g.top-m.top;n+=c.left-m.left;a+=c.top-m.top;
- if(this.container!=d){i+=j.left+l.left;k+=(Browser.Engine.trident4?0:j.top)+l.top;}}else{i-=c.left;k-=c.top;if(this.container==d){n-=g.left;a-=g.top;}else{i+=h.left+g.left-f.left;
- k+=h.top+g.top-f.top;n-=f.left;a-=f.top;}}return{x:[i,n],y:[k,a]};},checkAgainst:function(c,b){c=(this.positions)?this.positions[b]:c.getCoordinates();
- var a=this.mouse.now;return(a.x>c.left&&a.x<c.right&&a.y<c.bottom&&a.y>c.top);},checkDroppables:function(){var a=this.droppables.filter(this.checkAgainst,this).getLast();
- if(this.overed!=a){if(this.overed){this.fireEvent("leave",[this.element,this.overed]);}if(a){this.fireEvent("enter",[this.element,a]);}this.overed=a;}},drag:function(a){this.parent(a);
- if(this.options.checkDroppables&&this.droppables.length){this.checkDroppables();}},stop:function(a){this.checkDroppables();this.fireEvent("drop",[this.element,this.overed,a]);
- this.overed=null;return this.parent(a);}});Element.implement({makeDraggable:function(a){var b=new Drag.Move(this,a);this.store("dragger",b);return b;}});
- var Slider=new Class({Implements:[Events,Options],Binds:["clickedElement","draggedKnob","scrolledElement"],options:{onTick:function(a){if(this.options.snap){a=this.toPosition(this.step);
- }this.knob.setStyle(this.property,a);},initialStep:0,snap:false,offset:0,range:false,wheel:false,steps:100,mode:"horizontal"},initialize:function(f,a,e){this.setOptions(e);
- this.element=document.id(f);this.knob=document.id(a);this.previousChange=this.previousEnd=this.step=-1;var g,b={},d={x:false,y:false};switch(this.options.mode){case"vertical":this.axis="y";
- this.property="top";g="offsetHeight";break;case"horizontal":this.axis="x";this.property="left";g="offsetWidth";}this.full=this.element.measure(function(){this.half=this.knob[g]/2;
- return this.element[g]-this.knob[g]+(this.options.offset*2);}.bind(this));this.setRange(this.options.range);this.knob.setStyle("position","relative").setStyle(this.property,-this.options.offset);
- d[this.axis]=this.property;b[this.axis]=[-this.options.offset,this.full-this.options.offset];var c={snap:0,limit:b,modifiers:d,onDrag:this.draggedKnob,onStart:this.draggedKnob,onBeforeStart:(function(){this.isDragging=true;
- }).bind(this),onCancel:function(){this.isDragging=false;}.bind(this),onComplete:function(){this.isDragging=false;this.draggedKnob();this.end();}.bind(this)};
- if(this.options.snap){c.grid=Math.ceil(this.stepWidth);c.limit[this.axis][1]=this.full;}this.drag=new Drag(this.knob,c);this.attach();if(this.options.initialStep!=null){this.set(this.options.initialStep);
- }},attach:function(){this.element.addEvent("mousedown",this.clickedElement);if(this.options.wheel){this.element.addEvent("mousewheel",this.scrolledElement);
- }this.drag.attach();return this;},detach:function(){this.element.removeEvent("mousedown",this.clickedElement);this.element.removeEvent("mousewheel",this.scrolledElement);
- this.drag.detach();return this;},set:function(a){if(!((this.range>0)^(a<this.min))){a=this.min;}if(!((this.range>0)^(a>this.max))){a=this.max;}this.step=Math.round(a);
- this.checkStep();this.fireEvent("tick",this.toPosition(this.step));this.end();return this;},setRange:function(a,b){this.min=$pick(a[0],0);this.max=$pick(a[1],this.options.steps);
- this.range=this.max-this.min;this.steps=this.options.steps||this.full;this.stepSize=Math.abs(this.range)/this.steps;this.stepWidth=this.stepSize*this.full/Math.abs(this.range);
- this.set($pick(b,this.step).floor(this.min).max(this.max));return this;},clickedElement:function(c){if(this.isDragging||c.target==this.knob){return;}var b=this.range<0?-1:1;
- var a=c.page[this.axis]-this.element.getPosition()[this.axis]-this.half;a=a.limit(-this.options.offset,this.full-this.options.offset);this.step=Math.round(this.min+b*this.toStep(a));
- this.checkStep();this.fireEvent("tick",a);this.end();},scrolledElement:function(a){var b=(this.options.mode=="horizontal")?(a.wheel<0):(a.wheel>0);this.set(b?this.step-this.stepSize:this.step+this.stepSize);
- a.stop();},draggedKnob:function(){var b=this.range<0?-1:1;var a=this.drag.value.now[this.axis];a=a.limit(-this.options.offset,this.full-this.options.offset);
- this.step=Math.round(this.min+b*this.toStep(a));this.checkStep();},checkStep:function(){if(this.previousChange!=this.step){this.previousChange=this.step;
- this.fireEvent("change",this.step);}},end:function(){if(this.previousEnd!==this.step){this.previousEnd=this.step;this.fireEvent("complete",this.step+"");
- }},toStep:function(a){var b=(a+this.options.offset)*this.stepSize/this.full*this.steps;return this.options.steps?Math.round(b-=b%this.stepSize):b;},toPosition:function(a){return(this.full*Math.abs(this.min-a))/(this.steps*this.stepSize)-this.options.offset;
- }});var Sortables=new Class({Implements:[Events,Options],options:{snap:4,opacity:1,clone:false,revert:false,handle:false,constrain:false,preventDefault:false},initialize:function(a,b){this.setOptions(b);
- this.elements=[];this.lists=[];this.idle=true;this.addLists($$(document.id(a)||a));if(!this.options.clone){this.options.revert=false;}if(this.options.revert){this.effect=new Fx.Morph(null,$merge({duration:250,link:"cancel"},this.options.revert));
- }},attach:function(){this.addLists(this.lists);return this;},detach:function(){this.lists=this.removeLists(this.lists);return this;},addItems:function(){Array.flatten(arguments).each(function(a){this.elements.push(a);
- var b=a.retrieve("sortables:start",this.start.bindWithEvent(this,a));(this.options.handle?a.getElement(this.options.handle)||a:a).addEvent("mousedown",b);
- },this);return this;},addLists:function(){Array.flatten(arguments).each(function(a){this.lists.push(a);this.addItems(a.getChildren());},this);return this;
- },removeItems:function(){return $$(Array.flatten(arguments).map(function(a){this.elements.erase(a);var b=a.retrieve("sortables:start");(this.options.handle?a.getElement(this.options.handle)||a:a).removeEvent("mousedown",b);
- return a;},this));},removeLists:function(){return $$(Array.flatten(arguments).map(function(a){this.lists.erase(a);this.removeItems(a.getChildren());return a;
- },this));},getClone:function(b,a){if(!this.options.clone){return new Element(a.tagName).inject(document.body);}if($type(this.options.clone)=="function"){return this.options.clone.call(this,b,a,this.list);
- }var c=a.clone(true).setStyles({margin:"0px",position:"absolute",visibility:"hidden",width:a.getStyle("width")});if(c.get("html").test("radio")){c.getElements("input[type=radio]").each(function(d,e){d.set("name","clone_"+e);
- if(d.get("checked")){a.getElements("input[type=radio]")[e].set("checked",true);}});}return c.inject(this.list).setPosition(a.getPosition(a.getOffsetParent()));
- },getDroppables:function(){var a=this.list.getChildren();if(!this.options.constrain){a=this.lists.concat(a).erase(this.list);}return a.erase(this.clone).erase(this.element);
- },insert:function(c,b){var a="inside";if(this.lists.contains(b)){this.list=b;this.drag.droppables=this.getDroppables();}else{a=this.element.getAllPrevious().contains(b)?"before":"after";
- }this.element.inject(b,a);this.fireEvent("sort",[this.element,this.clone]);},start:function(b,a){if(!this.idle||b.rightClick||["button","input"].contains(document.id(b.target).get("tag"))){return;
- }this.idle=false;this.element=a;this.opacity=a.get("opacity");this.list=a.getParent();this.clone=this.getClone(b,a);this.drag=new Drag.Move(this.clone,{preventDefault:this.options.preventDefault,snap:this.options.snap,container:this.options.constrain&&this.element.getParent(),droppables:this.getDroppables(),onSnap:function(){b.stop();
- this.clone.setStyle("visibility","visible");this.element.set("opacity",this.options.opacity||0);this.fireEvent("start",[this.element,this.clone]);}.bind(this),onEnter:this.insert.bind(this),onCancel:this.reset.bind(this),onComplete:this.end.bind(this)});
- this.clone.inject(this.element,"before");this.drag.start(b);},end:function(){this.drag.detach();this.element.set("opacity",this.opacity);if(this.effect){var a=this.element.getStyles("width","height");
- var b=this.clone.computePosition(this.element.getPosition(this.clone.getOffsetParent()));this.effect.element=this.clone;this.effect.start({top:b.top,left:b.left,width:a.width,height:a.height,opacity:0.25}).chain(this.reset.bind(this));
- }else{this.reset();}},reset:function(){this.idle=true;this.clone.destroy();this.fireEvent("complete",this.element);},serialize:function(){var c=Array.link(arguments,{modifier:Function.type,index:$defined});
- var b=this.lists.map(function(d){return d.getChildren().map(c.modifier||function(e){return e.get("id");},this);},this);var a=c.index;if(this.lists.length==1){a=0;
- }return $chk(a)&&a>=0&&a<this.lists.length?b[a]:b;}});var Asset={javascript:function(f,d){d=$extend({onload:$empty,document:document,check:$lambda(true)},d);
- if(d.onLoad){d.onload=d.onLoad;delete d.onLoad;}var b=new Element("script",{src:f,type:"text/javascript"});var e=d.onload.bind(b),a=d.check,g=d.document;
- delete d.onload;delete d.check;delete d.document;b.addEvents({load:e,readystatechange:function(){if(["loaded","complete"].contains(this.readyState)){e();
- }}}).set(d);if(Browser.Engine.webkit419){var c=(function(){if(!$try(a)){return;}$clear(c);e();}).periodical(50);}return b.inject(g.head);},css:function(b,a){a=a||{};
- var c=a.onload||a.onLoad;if(c){a.events=a.events||{};a.events.load=c;delete a.onload;delete a.onLoad;}return new Element("link",$merge({rel:"stylesheet",media:"screen",type:"text/css",href:b},a)).inject(document.head);
- },image:function(c,b){b=$merge({onload:$empty,onabort:$empty,onerror:$empty},b);var d=new Image();var a=document.id(d)||new Element("img");["load","abort","error"].each(function(e){var g="on"+e;
- var f=e.capitalize();if(b["on"+f]){b[g]=b["on"+f];delete b["on"+f];}var h=b[g];delete b[g];d[g]=function(){if(!d){return;}if(!a.parentNode){a.width=d.width;
- a.height=d.height;}d=d.onload=d.onabort=d.onerror=null;h.delay(1,a,a);a.fireEvent(e,a,1);};});d.src=a.src=c;if(d&&d.complete){d.onload.delay(1);}return a.set(b);
- },images:function(d,c){c=$merge({onComplete:$empty,onProgress:$empty,onError:$empty,properties:{}},c);d=$splat(d);var a=[];var b=0;return new Elements(d.map(function(f,e){return Asset.image(f,$extend(c.properties,{onload:function(){c.onProgress.call(this,b,e);
- b++;if(b==d.length){c.onComplete();}},onerror:function(){c.onError.call(this,b,e);b++;if(b==d.length){c.onComplete();}}}));}));}};var Color=new Native({initialize:function(b,c){if(arguments.length>=3){c="rgb";
- b=Array.slice(arguments,0,3);}else{if(typeof b=="string"){if(b.match(/rgb/)){b=b.rgbToHex().hexToRgb(true);}else{if(b.match(/hsb/)){b=b.hsbToRgb();}else{b=b.hexToRgb(true);
- }}}}c=c||"rgb";switch(c){case"hsb":var a=b;b=b.hsbToRgb();b.hsb=a;break;case"hex":b=b.hexToRgb(true);break;}b.rgb=b.slice(0,3);b.hsb=b.hsb||b.rgbToHsb();
- b.hex=b.rgbToHex();return $extend(b,this);}});Color.implement({mix:function(){var a=Array.slice(arguments);var c=($type(a.getLast())=="number")?a.pop():50;
- var b=this.slice();a.each(function(d){d=new Color(d);for(var e=0;e<3;e++){b[e]=Math.round((b[e]/100*(100-c))+(d[e]/100*c));}});return new Color(b,"rgb");
- },invert:function(){return new Color(this.map(function(a){return 255-a;}));},setHue:function(a){return new Color([a,this.hsb[1],this.hsb[2]],"hsb");},setSaturation:function(a){return new Color([this.hsb[0],a,this.hsb[2]],"hsb");
- },setBrightness:function(a){return new Color([this.hsb[0],this.hsb[1],a],"hsb");}});var $RGB=function(d,c,a){return new Color([d,c,a],"rgb");};var $HSB=function(d,c,a){return new Color([d,c,a],"hsb");
- };var $HEX=function(a){return new Color(a,"hex");};Array.implement({rgbToHsb:function(){var b=this[0],c=this[1],j=this[2],g=0;var i=Math.max(b,c,j),e=Math.min(b,c,j);
- var k=i-e;var h=i/255,f=(i!=0)?k/i:0;if(f!=0){var d=(i-b)/k;var a=(i-c)/k;var l=(i-j)/k;if(b==i){g=l-a;}else{if(c==i){g=2+d-l;}else{g=4+a-d;}}g/=6;if(g<0){g++;
- }}return[Math.round(g*360),Math.round(f*100),Math.round(h*100)];},hsbToRgb:function(){var c=Math.round(this[2]/100*255);if(this[1]==0){return[c,c,c];}else{var a=this[0]%360;
- var e=a%60;var g=Math.round((this[2]*(100-this[1]))/10000*255);var d=Math.round((this[2]*(6000-this[1]*e))/600000*255);var b=Math.round((this[2]*(6000-this[1]*(60-e)))/600000*255);
- switch(Math.floor(a/60)){case 0:return[c,b,g];case 1:return[d,c,g];case 2:return[g,c,b];case 3:return[g,d,c];case 4:return[b,g,c];case 5:return[c,g,d];
- }}return false;}});String.implement({rgbToHsb:function(){var a=this.match(/\d{1,3}/g);return(a)?a.rgbToHsb():null;},hsbToRgb:function(){var a=this.match(/\d{1,3}/g);
- return(a)?a.hsbToRgb():null;}});var Group=new Class({initialize:function(){this.instances=Array.flatten(arguments);this.events={};this.checker={};},addEvent:function(b,a){this.checker[b]=this.checker[b]||{};
- this.events[b]=this.events[b]||[];if(this.events[b].contains(a)){return false;}else{this.events[b].push(a);}this.instances.each(function(c,d){c.addEvent(b,this.check.bind(this,[b,c,d]));
- },this);return this;},check:function(c,a,b){this.checker[c][b]=true;var d=this.instances.every(function(f,e){return this.checker[c][e]||false;},this);if(!d){return;
- }this.checker[c]={};this.events[c].each(function(e){e.call(this,this.instances,a);},this);}});Hash.Cookie=new Class({Extends:Cookie,options:{autoSave:true},initialize:function(b,a){this.parent(b,a);
- this.load();},save:function(){var a=JSON.encode(this.hash);if(!a||a.length>4096){return false;}if(a=="{}"){this.dispose();}else{this.write(a);}return true;
- },load:function(){this.hash=new Hash(JSON.decode(this.read(),true));return this;}});Hash.each(Hash.prototype,function(b,a){if(typeof b=="function"){Hash.Cookie.implement(a,function(){var c=b.apply(this.hash,arguments);
- if(this.options.autoSave){this.save();}return c;});}});var Scroller=new Class({Implements:[Events,Options],options:{area:20,velocity:1,onChange:function(a,b){this.element.scrollTo(a,b);
- },fps:50},initialize:function(b,a){this.setOptions(a);this.element=document.id(b);this.docBody=document.id(this.element.getDocument().body);this.listener=($type(this.element)!="element")?this.docBody:this.element;
- this.timer=null;this.bound={attach:this.attach.bind(this),detach:this.detach.bind(this),getCoords:this.getCoords.bind(this)};},start:function(){this.listener.addEvents({mouseenter:this.bound.attach,mouseleave:this.bound.detach});
- },stop:function(){this.listener.removeEvents({mouseenter:this.bound.attach,mouseleave:this.bound.detach});this.detach();this.timer=$clear(this.timer);},attach:function(){this.listener.addEvent("mousemove",this.bound.getCoords);
- },detach:function(){this.listener.removeEvent("mousemove",this.bound.getCoords);this.timer=$clear(this.timer);},getCoords:function(a){this.page=(this.listener.get("tag")=="body")?a.client:a.page;
- if(!this.timer){this.timer=this.scroll.periodical(Math.round(1000/this.options.fps),this);}},scroll:function(){var c=this.element.getSize(),a=this.element.getScroll(),h=this.element!=this.docBody?this.element.getOffsets():{x:0,y:0},d=this.element.getScrollSize(),g={x:0,y:0},e=this.options.area.top||this.options.area,b=this.options.area.bottom||this.options.area;
- for(var f in this.page){if(this.page[f]<(e+h[f])&&a[f]!=0){g[f]=(this.page[f]-e-h[f])*this.options.velocity;}else{if(this.page[f]+b>(c[f]+h[f])&&a[f]+c[f]!=d[f]){g[f]=(this.page[f]-c[f]+b-h[f])*this.options.velocity;
- }}g[f]=g[f].round();}if(g.y||g.x){this.fireEvent("change",[a.x+g.x,a.y+g.y]);}}});(function(){var a=function(c,b){return(c)?($type(c)=="function"?c(b):b.get(c)):"";
- };this.Tips=new Class({Implements:[Events,Options],options:{onShow:function(){this.tip.setStyle("display","block");},onHide:function(){this.tip.setStyle("display","none");
- },title:"title",text:function(b){return b.get("rel")||b.get("href");},showDelay:100,hideDelay:100,className:"tip-wrap",offset:{x:16,y:16},windowPadding:{x:0,y:0},fixed:false},initialize:function(){var b=Array.link(arguments,{options:Object.type,elements:$defined});
- this.setOptions(b.options);if(b.elements){this.attach(b.elements);}this.container=new Element("div",{"class":"tip"});},toElement:function(){if(this.tip){return this.tip;
- }return this.tip=new Element("div",{"class":this.options.className,styles:{position:"absolute",top:0,left:0}}).adopt(new Element("div",{"class":"tip-top"}),this.container,new Element("div",{"class":"tip-bottom"}));
- },attach:function(b){$$(b).each(function(d){var f=a(this.options.title,d),e=a(this.options.text,d);d.erase("title").store("tip:native",f).retrieve("tip:title",f);
- d.retrieve("tip:text",e);this.fireEvent("attach",[d]);var c=["enter","leave"];if(!this.options.fixed){c.push("move");}c.each(function(h){var g=d.retrieve("tip:"+h);
- if(!g){g=this["element"+h.capitalize()].bindWithEvent(this,d);}d.store("tip:"+h,g).addEvent("mouse"+h,g);},this);},this);return this;},detach:function(b){$$(b).each(function(d){["enter","leave","move"].each(function(e){d.removeEvent("mouse"+e,d.retrieve("tip:"+e)).eliminate("tip:"+e);
- });this.fireEvent("detach",[d]);if(this.options.title=="title"){var c=d.retrieve("tip:native");if(c){d.set("title",c);}}},this);return this;},elementEnter:function(c,b){this.container.empty();
- ["title","text"].each(function(e){var d=b.retrieve("tip:"+e);if(d){this.fill(new Element("div",{"class":"tip-"+e}).inject(this.container),d);}},this);$clear(this.timer);
- this.timer=(function(){this.show(b);this.position((this.options.fixed)?{page:b.getPosition()}:c);}).delay(this.options.showDelay,this);},elementLeave:function(c,b){$clear(this.timer);
- this.timer=this.hide.delay(this.options.hideDelay,this,b);this.fireForParent(c,b);},fireForParent:function(c,b){b=b.getParent();if(!b||b==document.body){return;
- }if(b.retrieve("tip:enter")){b.fireEvent("mouseenter",c);}else{this.fireForParent(c,b);}},elementMove:function(c,b){this.position(c);},position:function(e){if(!this.tip){document.id(this);
- }var c=window.getSize(),b=window.getScroll(),f={x:this.tip.offsetWidth,y:this.tip.offsetHeight},d={x:"left",y:"top"},g={};for(var h in d){g[d[h]]=e.page[h]+this.options.offset[h];
- if((g[d[h]]+f[h]-b[h])>c[h]-this.options.windowPadding[h]){g[d[h]]=e.page[h]-this.options.offset[h]-f[h];}}this.tip.setStyles(g);},fill:function(b,c){if(typeof c=="string"){b.set("html",c);
- }else{b.adopt(c);}},show:function(b){if(!this.tip){document.id(this);}if(!this.tip.getParent()){this.tip.inject(document.body);}this.fireEvent("show",[this.tip,b]);
- },hide:function(b){if(!this.tip){document.id(this);}this.fireEvent("hide",[this.tip,b]);}});})();
- var qwebirc = {ui: {themes: {}, style: {}}, irc: {}, util: {crypto: {}}, config: {}, options: {}, auth: {}, sound: {}, connected: false};
- var conf = null;
- var ui = null;
- if(typeof QWEBIRC_BUILD != "undefined") {
- qwebirc.BUILD = QWEBIRC_BUILD;
- qwebirc.FILE_SUFFIX = "-" + QWEBIRC_BUILD;
- } else {
- qwebirc.BUILD = null;
- qwebirc.FILE_SUFFIX = "";
- }
- /* Contains configuration loading and parsing functions. */
- /* Load configuration.
- * Accepts a default configuration object, which is modified with settings
- * from cookies and the query string, then returned. */
- qwebirc.config.load = function(config) {
- /* Stow away some unmodified values from default configuration.
- * This allows them to be accessed as 'default' values for
- * query strings later. */
- config.frontend.initial_nick_default = config.frontend.initial_nick;
- config.frontend.initial_chans_default = config.frontend.initial_chans;
- config.frontend.prompt_default = config.frontend.prompt;
- config.ui.fg_color_default = config.ui.fg_color;
- config.ui.fg_sec_color_default = config.ui.fg_sec_color;
- config.ui.bg_color_default = config.ui.bg_color;
- /* Load user settings from cookie. */
- qwebirc.config.loadCookieSettings(config);
- /* Load query string parameters. */
- var uri = String(document.location);
- var args = qwebirc.util.parseURI(uri);
- /* Map backwards compatiblity query string aliases to the
- * parameters they represent, unless they're already set. */
- if($defined(args["nick"]) && !$defined(args["initial_nick"]))
- args["initial_nick"] = args["nick"];
- if($defined(args["channels"]) && !$defined(args["initial_chans"]))
- args["initial_chans"] = args["channels"];
- /* If we had any arguments, default chan_list_on_start off. */
- if (uri.splitMax("/", 4)[3].indexOf("?") != -1)
- args["chan_list_on_start"] = "0";
- /* Load nick from query string. */
- if($defined(args["initial_nick"])) {
- var initial_nick = args["initial_nick"];
- config.frontend.initial_nick = initial_nick;
- config.frontend.chan_prompt = false;
- }
- /* Load channels from query string. */
- if($defined(args["url"])) {
- var urlchans = qwebirc.config.parseIRCURL(args["url"]);
- if (urlchans) {
- config.frontend.initial_chans = urlchans;
- config.frontend.chan_prompt = false;
- }
- }
- if ($defined(args["initial_chans"])) {
- var initial_chans = args["initial_chans"];
- config.frontend.initial_chans = initial_chans;
- }
- /* Load prompt option from query string. */
- if ($defined(args["prompt"])) {
- if (args["prompt"] == 1)
- config.frontend.prompt = true;
- else
- config.frontend.prompt = false;
- }
- /* Load chan_prompt option from query string. */
- if ($defined(args["chan_prompt"])) {
- if (args["chan_prompt"] == 1)
- config.frontend.chan_prompt = true;
- else
- config.frontend.chan_prompt = false;
- }
- /* Load chan_list_on_start option from query string. */
- if ($defined(args["chan_list_on_start"])) {
- if (args["chan_list_on_start"] == 1)
- config.atheme.chan_list_on_start = true;
- else
- config.atheme.chan_list_on_start = false;
- }
- /* Load colours from query string. */
- if ($defined(args["fg_color"])) {
- config.ui.fg_color = args["fg_color"];
- config.ui.fg_sec_color = args["fg_color"];
- }
- if ($defined(args["fg_sec_color"]))
- config.ui.fg_sec_color = args["fg_sec_color"];
- if ($defined(args["bg_color"]))
- config.ui.bg_color = args["bg_color"];
- /* Subtitute '.' characters in the nick with random digits. */
- if (config.frontend.initial_nick.indexOf(".") != -1) {
- var nick = config.frontend.initial_nick;
- config.frontend.initial_nick = qwebirc.config.randSub(nick);
- config.frontend.initial_nick_rand = true;
- }
- else
- config.frontend.initial_nick_rand = false;
- /* Insert any needed # symbols into channel names. */
- if(config.frontend.initial_chans) {
- var cdata = config.frontend.initial_chans.split(" ");
- var chans = cdata[0].split(" ")[0].split(",");
- for(var i=0;i<chans.length;i++) {
- if(chans[i].charAt(0) != '#')
- chans[i] = "#" + chans[i]
- }
- cdata[0] = chans.join(",");
- config.frontend.initial_chans = cdata.join(" ");
- }
- return config;
- };
- /* Loads settings from cookies. */
- qwebirc.config.loadCookieSettings = function(config) {
- var cookie = new Hash.Cookie("iris-settings", {duration: 3650, autoSave: false});
- for (var i = 0; i < qwebirc.options.Options.length; i++) {
- var category = qwebirc.options.Options[i].category;
- var option = qwebirc.options.Options[i].option;
- var cookieName = category + "." + option;
- if ($defined(cookie.get(cookieName)))
- config[category][option] = cookie.get(cookieName);
- }
- };
- /* Save setings to cookies. */
- qwebirc.config.saveUserSettings = function(config) {
- var cookie = new Hash.Cookie("iris-settings", {duration: 3650, autoSave: false});
- cookie.erase();
- cookie = new Hash.Cookie("iris-settings", {duration: 3650, autoSave: false});
- for (var i = 0; i < qwebirc.options.Options.length; i++) {
- var category = qwebirc.options.Options[i].category;
- var option = qwebirc.options.Options[i].option;
- var cookieName = category + "." + option;
- cookie.set(cookieName, config[category][option]);
- }
- cookie.save();
- };
- /* Substitute dots in configured nicks with random numbers. */
- qwebirc.config.randSub = function(nick) {
- var getDigit = function() { return Math.floor(Math.random() * 10); }
- return nick.split("").map(function(v) {
- if(v == ".") {
- return getDigit();
- } else {
- return v;
- }
- }).join("");
- };
- /* Parse a channel out of a provided URL, if one is set.
- Returns the provided channel (potentially with key), or nothing. */
- qwebirc.config.parseIRCURL = function(url) {
- if(url.indexOf(":") == 0)
- return;
- var schemeComponents = url.splitMax(":", 2);
- if(schemeComponents[0].toLowerCase() != "irc" && schemeComponents[0].toLowerCase() != "ircs") {
- alert("Bad IRC URL scheme.");
- return;
- }
- if(url.indexOf("/") == 0) {
- /* irc: */
- return;
- }
- var pathComponents = url.splitMax("/", 4);
- if(pathComponents.length < 4 || pathComponents[3] == "") {
- /* irc://abc */
- return;
- }
- var args, queryArgs;
- if(pathComponents[3].indexOf("?") > -1) {
- queryArgs = qwebirc.util.parseURI(pathComponents[3]);
- args = pathComponents[3].splitMax("?", 2)[0];
- } else {
- args = pathComponents[3];
- }
- var parts = args.split(",");
- var channel = parts[0];
- if(channel.charAt(0) != "#")
- channel = "#" + channel;
- var not_supported = [], needkey = false, key;
- for(var i=1;i<parts.length;i++) {
- var value = parts[i];
- if(value == "needkey") {
- needkey = true;
- } else {
- not_supported.push(value);
- }
- }
- if($defined(queryArgs)) {
- for(var key_ in queryArgs) {
- var value = queryArgs[key_];
- if(key_ == "key") {
- key = value;
- needkey = true;
- } else {
- not_supported.push(key_);
- }
- }
- }
- if(needkey) {
- if(!$defined(key))
- key = prompt("Please enter the password for channel " + channel + ":");
- if($defined(key))
- channel = channel + " " + key;
- }
- if(not_supported.length > 0)
- alert("The following IRC URL components were not accepted: " + not_supported.join(", ") + ".");
- return channel;
- };
- /* qwebirc -- Copyright (C) 2008-2010 Chris Porter and the qwebirc project --- All rights reserved. */
- qwebirc.util.crypto.getARC4Stream = function(key, length) {
- var s = [];
- var keyint = [];
- for(var i=0;i<key.length;i++)
- keyint.push(key.charCodeAt(i));
- for(var i=0;i<256;i++)
- s[i] = i;
- var j = 0;
- for(var i=0;i<256;i++) {
- j = (j + s[i] + keyint[i % key.length]) & 255;
- var w = s[i]; s[i] = s[j]; s[j] = w;
- }
- var output = [];
- var i = 0;
- var j = 0;
- for(var k=0;k<length;k++) {
- i = (i + 1) & 255;
- j = (j + s[i]) & 255;
- var w = s[i]; s[i] = s[j]; s[j] = w;
- output.push(s[(s[i] + s[j]) & 255]);
- }
- return output;
- }
- qwebirc.util.crypto.xorStreams = function(data, prngstream) {
- if(data.length != prngstream.length)
- return;
- var output = [];
- for(var i=0;i<data.length;i++)
- output.push(String.fromCharCode(data.charCodeAt(i) ^ prngstream[i]));
- return output.join("");
- }
- qwebirc.util.crypto.ARC4 = function(key, data) {
- var prngstream = qwebirc.util.crypto.getARC4Stream(key, data.length + 1024);
- /* burn first 1024 bytes */
- prngstream = prngstream.slice(1024);
- return qwebirc.util.crypto.xorStreams(data, prngstream);
- }
- Array.prototype.indexFromEnd = function(d) {
- var p = this;
- if(d < 0)
- return p[p.length + d];
- return p[d];
- }
- qwebirc.util.dictCopy = function(d) {
- var n = {};
- for(var k in d)
- n[k] = d[k];
- return n;
- }
- /* how horribly inefficient */
- String.prototype.replaceAll = function(f, t) {
- var i = this.indexOf(f);
- var c = this;
- while(i > -1) {
- c = c.replace(f, t);
- i = c.indexOf(f);
- }
- return c;
- }
- /* how horribly inefficient (again) */
- String.prototype.splitMax = function(by, max) {
- var items = this.split(by);
- var newitems = items.slice(0, max-1);
- if(items.length >= max)
- newitems.push(items.slice(max-1).join(by));
- return newitems;
- }
- /* returns the arguments */
- qwebirc.util.parseURI = function(uri) {
- var result = {}
- var start = uri.indexOf('?');
- if(start == -1)
- return result;
- var querystring = uri.substring(start + 1);
- var args = querystring.split("&");
- for(var i=0;i<args.length;i++) {
- var r = args[i].splitMax("=", 2);
- if(r.length < 2)
- continue;
- result[unescape(r[0])] = unescape(r[1]);
- }
- return result;
- }
- qwebirc.util.DaysOfWeek = {
- 0: "Sun",
- 1: "Mon",
- 2: "Tue",
- 3: "Wed",
- 4: "Thu",
- 5: "Fri",
- 6: "Sat"
- };
- qwebirc.util.MonthsOfYear = {
- 0: "Jan",
- 1: "Feb",
- 2: "Mar",
- 3: "Apr",
- 4: "May",
- 5: "Jun",
- 6: "Jul",
- 7: "Aug",
- 8: "Sep",
- 9: "Oct",
- 10: "Nov",
- 11: "Dec"
- };
- qwebirc.util.NBSPCreate = function(text, element) {
- var e = text.split(" ");
- for(var i=0;i<e.length;i++) {
- var tn = document.createTextNode(e[i]);
- element.appendChild(tn);
- if(i != e.length - 1) {
- var e2 = new Element("span");
- e2.set("html", " ");
- element.appendChild(e2);
- }
- }
- };
- qwebirc.util.longtoduration = function(l) {
- var seconds = l % 60;
- var minutes = Math.floor((l % 3600) / 60);
- var hours = Math.floor((l % (3600 * 24)) / 3600);
- var days = Math.floor(l / (24*3600));
- return days + " days " + hours + " hours " + minutes + " minutes " + seconds + " seconds";
- }
- qwebirc.util.pad = function(x) {
- x = "" + x;
- if(x.length == 1)
- return "0" + x;
- return x
- }
- RegExp.escape = function(text) {
- if(!arguments.callee.sRE) {
- var specials = [
- '/', '.', '*', '+', '?', '|',
- '(', ')', '[', ']', '{', '}', '\\'
- ];
- arguments.callee.sRE = new RegExp('(\\' + specials.join('|\\') + ')', 'g');
- }
- return text.replace(arguments.callee.sRE, '\\$1');
- }
- qwebirc.ui.insertAt = function(position, parent, element) {
- if(!parent.childNodes || (position >= parent.childNodes.length)) {
- parent.appendChild(element);
- } else {
- parent.insertBefore(element, parent.childNodes[position]);
- }
- }
- qwebirc.util.setCaretPos = function(obj, pos) {
- if($defined(obj.selectionStart)) {
- obj.focus();
- obj.setSelectionRange(pos, pos);
- } else if(obj.createTextRange) {
- var range = obj.createTextRange();
- range.move("character", pos);
- range.select();
- }
- }
- qwebirc.util.setAtEnd = function(obj) {
- qwebirc.util.setCaretPos(obj.value.length);
- }
- qwebirc.util.getCaretPos = function(element) {
- if($defined(element.selectionStart))
- return element.selectionStart;
- if(document.selection) {
- element.focus();
- var sel = document.selection.createRange();
- sel.moveStart("character", -element.value.length);
- return sel.text.length;
- }
- }
- qwebirc.util.browserVersion = function() {
- //return "engine: " + Browser.Engine.name + " platform: " + Browser.Platform.name + " user agent: " + navigator.userAgent;
- return navigator.userAgent;
- }
- qwebirc.util.getEnclosedWord = function(text, position) {
- var l = text.split("");
- var buf = [];
- if(text == "")
- return;
- var start = position - 1;
- if(start < 0) {
- /* special case: starting with space */
- start = 0;
- } else {
- /* work back until we find the first space */
- for(;start>=0;start--) {
- if(l[start] == ' ') {
- start = start + 1;
- break;
- }
- }
- }
- if(start < 0)
- start = 0;
- var s = text.substring(start);
- var pos = s.indexOf(" ");
- if(pos != -1)
- s = s.substring(0, pos);
- return [start, s];
- }
- String.prototype.startsWith = function(what) {
- return this.substring(0, what.length) == what;
- }
- /* NOT cryptographically secure! */
- qwebirc.util.randHexString = function(numBytes) {
- var getByte = function() {
- return (((1+Math.random())*0x100)|0).toString(16).substring(1);
- };
- var l = [];
- for(var i=0;i<numBytes;i++)
- l.push(getByte());
- return l.join("");
- }
- qwebirc.util.importJS = function(name, watchFor, onload) {
- var script = document.createElement("script");
- script.type = "text/javascript";
- script.src = name;
- if(Browser.Engine.trident) {
- /* HORRID */
- var checkFn = function() {
- if(eval("typeof " + watchFor) != "undefined") {
- onload();
- } else {
- checkFn.delay(100);
- }
- }
- checkFn();
- } else {
- script.onload = onload;
- }
- document.getElementsByTagName("head")[0].appendChild(script);
- }
- qwebirc.util.createInput = function(type, parent, name, selected, id) {
- var r;
- if(Browser.Engine.trident) {
- if(name) {
- name = " name=\"" + escape(name) + "\"";
- } else {
- name = "";
- }
- if(id) {
- id = " id=\"" + escape(id) + "\"";
- } else {
- id = "";
- }
- try {
- return $(document.createElement("<input type=\"" + type + "\"" + name + id + " " + (selected?" checked":"") + "/>"));
- } catch(e) {
- /* fallthough, trying it the proper way... */
- }
- }
- r = new Element("input");
- r.type = type;
- if(name)
- r.name = name;
- if(id)
- r.id = id;
- if(selected)
- r.checked = true;
- parent.appendChild(r);
- return r;
- }
- /* From: www.webtoolkit.info */
- qwebirc.util.b64Table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
- qwebirc.util.b64Encode = function(data) {
- var output = [];
- var table = qwebirc.util.b64Table;
- for(var i=0;i<data.length;) {
- var chr1 = data.charCodeAt(i++);
- var chr2 = data.charCodeAt(i++);
- var chr3 = data.charCodeAt(i++);
- var enc1 = chr1 >> 2;
- var enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
- var enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
- var enc4 = chr3 & 63;
- if(isNaN(chr2)) {
- enc3 = enc4 = 64;
- } else if(isNaN(chr3)) {
- enc4 = 64;
- }
- output.push(table.charAt(enc1) + table.charAt(enc2) + table.charAt(enc3) + table.charAt(enc4));
- }
- return output.join("");
- }
- /* From: www.webtoolkit.info */
- qwebirc.util.b64Decode = function(data) {
- data = data.replace(/[^A-Za-z0-9\+\/\=]/g, "");
- var output = [];
- var table = qwebirc.util.b64Table;
- for(var i=0;i<data.length;) {
- var enc1 = table.indexOf(data.charAt(i++));
- var enc2 = table.indexOf(data.charAt(i++));
- var enc3 = table.indexOf(data.charAt(i++));
- var enc4 = table.indexOf(data.charAt(i++));
- var chr1 = (enc1 << 2) | (enc2 >> 4);
- var chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
- var chr3 = ((enc3 & 3) << 6) | enc4;
- output.push(String.fromCharCode(chr1));
- if (enc3 != 64)
- output.push(String.fromCharCode(chr2));
- if (enc4 != 64)
- output.push(String.fromCharCode(chr3));
- }
- return output.join("");
- }
- qwebirc.util.composeAnd = function() {
- var xargs = arguments;
- return function() {
- for(var i=0;i<xargs.length;i++)
- if(!xargs[i].apply(this, arguments))
- return false;
- return true;
- }
- }
- qwebirc.util.invertFn = function(fn) {
- return function() {
- return !fn.apply(this, arguments);
- }
- }
- qwebirc.util.deviceHasKeyboard = function() {
- var determine = function() {
- if(Browser.Engine.ipod)
- return true;
- var MOBILE_UAs = ["Nintendo Wii", " PIE", "BlackBerry", "IEMobile", "Windows CE", "Nokia", "Opera Mini", "Mobile", "mobile", "Pocket", "pocket", "Android"];
- /* safari not included because iphones/ipods send that, and we checked for iphone/ipod specifically above */
- var DESKTOP_UAs = ["Chrome", "Firefox", "Camino", "Iceweasel", "K-Meleon", "Konqueror", "SeaMonkey", "Windows NT", "Windows 9"];
- var ua = navigator.userAgent;
- var contains = function(v) {
- return ua.indexOf(v) > -1;
- }
- for(var i=0;i<MOBILE_UAs.length;i++)
- if(contains(MOBILE_UAs[i]))
- return false;
- for(var i=0;i<DESKTOP_UAs.length;i++)
- if(contains(DESKTOP_UAs[i]))
- return true;
- return false;
- };
- var v = determine();
- qwebirc.util.deviceHasKeyboard = function() {
- return v;
- }
- return v;
- }
- qwebirc.util.generateID_ID = 0;
- qwebirc.util.generateID = function() {
- return "qqa-" + qwebirc.util.generateID_ID++;
- }
- /*
- * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
- * Digest Algorithm, as defined in RFC 1321.
- * Copyright (C) Paul Johnston 1999 - 2000.
- * See http://pajhome.org.uk/site/legal.html for details.
- */
- /*
- * Converted freestanding JavaScript code to fully encapsulated object.
- * Andrew Collins, andrewrcollins@yahoo.com, 2000-11-28
- */
- /*
- * MD5
- *
- * Usage:
- *
- * var object = new MD5()
- *
- * Returns a MD5 object.
- *
- * object.digest(input)
- *
- * Returns MD5 message digest of input.
- *
- * Example:
- *
- * var object = new MD5();
- *
- * // Examples drawn from RFC1321 test suite
- * object.digest("");
- * // d41d8cd98f00b204e9800998ecf8427e
- *
- * object.digest("a");
- * // 0cc175b9c0f1b6a831c399e269772661
- *
- * object.digest("abc");
- * // 900150983cd24fb0d6963f7d28e17f72
- *
- * object.digest("message digest");
- * // f96b697d7cb7938d525a2f31aaf161d0
- *
- * object.digest("abcdefghijklmnopqrstuvwxyz");
- * // c3fcd3d76192e4007dfb496cca67e13b
- *
- * object.digest("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
- * // d174ab98d277d9f5a5611c2c9f419d9f
- *
- * object.digest("12345678901234567890123456789012345678901234567890123456789012345678901234567890");
- * // 57edf4a22be3c955ac49da2e2107b67a
- */
- qwebirc.util.crypto.MD5 = function() {
- this.digest = calcMD5;
- /*
- * Convert a 32-bit number to a hex string with ls-byte first
- */
- var hex_chr = "0123456789abcdef";
- function rhex(num)
- {
- var str = "";
- for(var j = 0; j <= 3; j++)
- str += hex_chr.charAt((num >> (j * 8 + 4)) & 0x0F) + hex_chr.charAt((num >> (j * 8)) & 0x0F);
- return str;
- }
- /*
- * Convert a string to a sequence of 16-word blocks, stored as an array.
- * Append padding bits and the length, as described in the MD5 standard.
- */
- function str2blks_MD5(str)
- {
- var nblk = ((str.length + 8) >> 6) + 1;
- var blks = new Array(nblk * 16);
- for(var i = 0; i < nblk * 16; i++) blks[i] = 0;
- for(var i = 0; i < str.length; i++)
- blks[i >> 2] |= str.charCodeAt(i) << ((i % 4) * 8);
- blks[i >> 2] |= 0x80 << ((i % 4) * 8);
- blks[nblk * 16 - 2] = str.length * 8;
- return blks;
- }
- /*
- * Add integers, wrapping at 2^32
- */
- function add(x, y)
- {
- return ((x&0x7FFFFFFF) + (y&0x7FFFFFFF)) ^ (x&0x80000000) ^ (y&0x80000000);
- }
- /*
- * Bitwise rotate a 32-bit number to the left
- */
- function rol(num, cnt)
- {
- return (num << cnt) | (num >>> (32 - cnt));
- }
- /*
- * These functions implement the basic operation for each round of the
- * algorithm.
- */
- function cmn(q, a, b, x, s, t)
- {
- return add(rol(add(add(a, q), add(x, t)), s), b);
- }
- function ff(a, b, c, d, x, s, t)
- {
- return cmn((b & c) | ((~b) & d), a, b, x, s, t);
- }
- function gg(a, b, c, d, x, s, t)
- {
- return cmn((b & d) | (c & (~d)), a, b, x, s, t);
- }
- function hh(a, b, c, d, x, s, t)
- {
- return cmn(b ^ c ^ d, a, b, x, s, t);
- }
- function ii(a, b, c, d, x, s, t)
- {
- return cmn(c ^ (b | (~d)), a, b, x, s, t);
- }
- /*
- * Take a string and return the hex representation of its MD5.
- */
- function calcMD5(str)
- {
- var x = str2blks_MD5(str);
- var a = 0x67452301;
- var b = 0xEFCDAB89;
- var c = 0x98BADCFE;
- var d = 0x10325476;
- for(var i = 0; i < x.length; i += 16)
- {
- var olda = a;
- var oldb = b;
- var oldc = c;
- var oldd = d;
- a = ff(a, b, c, d, x[i+ 0], 7 , 0xD76AA478);
- d = ff(d, a, b, c, x[i+ 1], 12, 0xE8C7B756);
- c = ff(c, d, a, b, x[i+ 2], 17, 0x242070DB);
- b = ff(b, c, d, a, x[i+ 3], 22, 0xC1BDCEEE);
- a = ff(a, b, c, d, x[i+ 4], 7 , 0xF57C0FAF);
- d = ff(d, a, b, c, x[i+ 5], 12, 0x4787C62A);
- c = ff(c, d, a, b, x[i+ 6], 17, 0xA8304613);
- b = ff(b, c, d, a, x[i+ 7], 22, 0xFD469501);
- a = ff(a, b, c, d, x[i+ 8], 7 , 0x698098D8);
- d = ff(d, a, b, c, x[i+ 9], 12, 0x8B44F7AF);
- c = ff(c, d, a, b, x[i+10], 17, 0xFFFF5BB1);
- b = ff(b, c, d, a, x[i+11], 22, 0x895CD7BE);
- a = ff(a, b, c, d, x[i+12], 7 , 0x6B901122);
- d = ff(d, a, b, c, x[i+13], 12, 0xFD987193);
- c = ff(c, d, a, b, x[i+14], 17, 0xA679438E);
- b = ff(b, c, d, a, x[i+15], 22, 0x49B40821);
- a = gg(a, b, c, d, x[i+ 1], 5 , 0xF61E2562);
- d = gg(d, a, b, c, x[i+ 6], 9 , 0xC040B340);
- c = gg(c, d, a, b, x[i+11], 14, 0x265E5A51);
- b = gg(b, c, d, a, x[i+ 0], 20, 0xE9B6C7AA);
- a = gg(a, b, c, d, x[i+ 5], 5 , 0xD62F105D);
- d = gg(d, a, b, c, x[i+10], 9 , 0x02441453);
- c = gg(c, d, a, b, x[i+15], 14, 0xD8A1E681);
- b = gg(b, c, d, a, x[i+ 4], 20, 0xE7D3FBC8);
- a = gg(a, b, c, d, x[i+ 9], 5 , 0x21E1CDE6);
- d = gg(d, a, b, c, x[i+14], 9 , 0xC33707D6);
- c = gg(c, d, a, b, x[i+ 3], 14, 0xF4D50D87);
- b = gg(b, c, d, a, x[i+ 8], 20, 0x455A14ED);
- a = gg(a, b, c, d, x[i+13], 5 , 0xA9E3E905);
- d = gg(d, a, b, c, x[i+ 2], 9 , 0xFCEFA3F8);
- c = gg(c, d, a, b, x[i+ 7], 14, 0x676F02D9);
- b = gg(b, c, d, a, x[i+12], 20, 0x8D2A4C8A);
- a = hh(a, b, c, d, x[i+ 5], 4 , 0xFFFA3942);
- d = hh(d, a, b, c, x[i+ 8], 11, 0x8771F681);
- c = hh(c, d, a, b, x[i+11], 16, 0x6D9D6122);
- b = hh(b, c, d, a, x[i+14], 23, 0xFDE5380C);
- a = hh(a, b, c, d, x[i+ 1], 4 , 0xA4BEEA44);
- d = hh(d, a, b, c, x[i+ 4], 11, 0x4BDECFA9);
- c = hh(c, d, a, b, x[i+ 7], 16, 0xF6BB4B60);
- b = hh(b, c, d, a, x[i+10], 23, 0xBEBFBC70);
- a = hh(a, b, c, d, x[i+13], 4 , 0x289B7EC6);
- d = hh(d, a, b, c, x[i+ 0], 11, 0xEAA127FA);
- c = hh(c, d, a, b, x[i+ 3], 16, 0xD4EF3085);
- b = hh(b, c, d, a, x[i+ 6], 23, 0x04881D05);
- a = hh(a, b, c, d, x[i+ 9], 4 , 0xD9D4D039);
- d = hh(d, a, b, c, x[i+12], 11, 0xE6DB99E5);
- c = hh(c, d, a, b, x[i+15], 16, 0x1FA27CF8);
- b = hh(b, c, d, a, x[i+ 2], 23, 0xC4AC5665);
- a = ii(a, b, c, d, x[i+ 0], 6 , 0xF4292244);
- d = ii(d, a, b, c, x[i+ 7], 10, 0x432AFF97);
- c = ii(c, d, a, b, x[i+14], 15, 0xAB9423A7);
- b = ii(b, c, d, a, x[i+ 5], 21, 0xFC93A039);
- a = ii(a, b, c, d, x[i+12], 6 , 0x655B59C3);
- d = ii(d, a, b, c, x[i+ 3], 10, 0x8F0CCC92);
- c = ii(c, d, a, b, x[i+10], 15, 0xFFEFF47D);
- b = ii(b, c, d, a, x[i+ 1], 21, 0x85845DD1);
- a = ii(a, b, c, d, x[i+ 8], 6 , 0x6FA87E4F);
- d = ii(d, a, b, c, x[i+15], 10, 0xFE2CE6E0);
- c = ii(c, d, a, b, x[i+ 6], 15, 0xA3014314);
- b = ii(b, c, d, a, x[i+13], 21, 0x4E0811A1);
- a = ii(a, b, c, d, x[i+ 4], 6 , 0xF7537E82);
- d = ii(d, a, b, c, x[i+11], 10, 0xBD3AF235);
- c = ii(c, d, a, b, x[i+ 2], 15, 0x2AD7D2BB);
- b = ii(b, c, d, a, x[i+ 9], 21, 0xEB86D391);
- a = add(a, olda);
- b = add(b, oldb);
- c = add(c, oldc);
- d = add(d, oldd);
- }
- return rhex(a) + rhex(b) + rhex(c) + rhex(d);
- }
- }
- qwebirc.sessionCount = 0;
- /* Stores settings and handles for a single IRC connection. */
- qwebirc.session = new Class({
- /* The IRC connection instance. */
- irc: null,
- /* Atheme state. */
- atheme: {
- state: null,
- user: null,
- token: null
- },
- /* UI windows belonging to this session. */
- windows: {},
- initialize: function() {
- /* Load any Atheme login state. */
- cookie = new Hash.Cookie("iris-auth");
- if ($defined(cookie.get("user"))) {
- this.atheme.user = cookie.get("user");
- this.atheme.secret = cookie.get("token");
- }
- /* Check our Atheme login state. */
- qwebirc.ui.Atheme.check(this);
- }
- });
- qwebirc.sound.domReady = false;
- window.addEvent("domready", function() {
- qwebirc.sound.domReady = true;
- });
- qwebirc.sound.SoundPlayer = new Class({
- Implements: [Events],
- session: null,
- initialize: function(session) {
- this.session = session;
- this.loadingSWF = false;
- this.loadedSWF = false;
- },
- go: function() {
- if(qwebirc.sound.domReady) {
- this.loadSoundManager();
- } else {
- window.addEvent("domready", function() {
- this.loadSoundManager();
- }.bind(this));
- }
- },
- loadSoundManager: function() {
- if(this.loadingSWF)
- return;
- this.loadingSWF = true;
- if(eval("typeof soundManager") != "undefined") {
- this.loadedSWF = true;
- this.fireEvent("ready");
- return;
- }
- var debugMode = false;
- qwebirc.util.importJS(conf.frontend.static_base_url + "js/" + (debugMode?"soundmanager2":"soundmanager2-nodebug-jsmin") + ".js", "soundManager", function() {
- soundManager.url = conf.frontend.static_base_url + "sound/";
- soundManager.debugMode = debugMode;
- soundManager.useConsole = debugMode;
- soundManager.onload = function() {
- this.loadedSWF = true;
- this.fireEvent("ready");
- }.bind(this);
- soundManager.beginDelayedInit();
- }.bind(this));
- },
- createSound: function(name, src) {
- soundManager.createSound(name, src);
- },
- playSound: function(name) {
- soundManager.play(name);
- },
- beep: function() {
- if(!this.beepLoaded) {
- this.createSound("beep", conf.frontend.static_base_url + "sound/beep3.mp3");
- this.beepLoaded = true;
- }
- this.playSound("beep");
- }
- });
- qwebirc.VERSION = "0.90"
- qwebirc.irc.AthemeQuery = {};
- /**
- * Build a generic request to Atheme.
- *
- * \param command The command being requested.
- */
- qwebirc.irc.AthemeQuery.newRequest = function(command) {
- /* New login request. */
- var cacheAvoidance = qwebirc.util.randHexString(16);
- var r = new Request.JSON({
- url: conf.frontend.dynamic_base_url + "a/" + command + "?r=" + cacheAvoidance,
- async: true
- });
- /* Try to minimise the amount of headers. */
- r.headers = new Hash;
- r.addEvent("request", function() {
- var setHeader = function(key, value) {
- try {
- this.setRequestHeader(key, value);
- } catch(e) {
- }
- }.bind(this);
- setHeader("User-Agent", null);
- setHeader("Accept", null);
- setHeader("Accept-Language", null);
- }.bind(r.xhr));
- if(Browser.Engine.trident)
- r.setHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT");
- return r;
- }
- /**
- * Login to Atheme, getting an authentication token.
- * Callback signature is callback(token), where token is an authentication
- * token for later requests, the empty string to indicate authentication
- * failure, or null to indicate connection failure.
- *
- * \param callback Function to call to inform of results.
- * \param user Username as string.
- * \param pass Password as string.
- */
- qwebirc.irc.AthemeQuery.login = function(callback, user, pass) {
- r = qwebirc.irc.AthemeQuery.newRequest("l");
- r.addEvent("failure", function(xhr) {
- callback(null);
- });
- r.addEvent("success", function(json, string) {
- if (json != null) {
- if (json["success"] == true)
- callback(json["output"]);
- else
- callback("");
- } else {
- callback(null);
- }
- });
- var postdata = "u=" + encodeURIComponent(user);
- postdata += "&p=" + encodeURIComponent(pass);
- r.send(postdata);
- }
- /**
- * Logs out, invalidating an authentication token.
- * Callback signature is callback(removed), where valid is true to indicate
- * successful removal, or the token already being invalid, or null to
- * indicate a connection failure removing it.
- *
- * \param callback Function to call to inform of results.
- * \param user Username as string.
- * \param token Token as string.
- */
- qwebirc.irc.AthemeQuery.logout = function(callback, user, token) {
- r = qwebirc.irc.AthemeQuery.newRequest("o");
- r.addEvent("failure", function(xhr) {
- callback(null);
- });
- r.addEvent("success", function(json, string) {
- if (json != null) {
- callback(true);
- } else {
- callback(null);
- }
- }.bind(this));
- var postdata = "u=" + encodeURIComponent(user);
- postdata += "&t=" + encodeURIComponent(token);
- r.send(postdata);
- }
- /**
- * Checks whether an authentication token is valid.
- * Can't be used before a command as an alternative to dealing with failure,
- * as the token can expire between this check and the command, but can be
- * used to decide whether to even prompt the user to login.
- * Callback signature is callback(valid), where valid is either true, false,
- * or null to indicate connection failure.
- *
- * \param callback Function to call to inform of results.
- * \param user Username as string.
- * \param token Token as string.
- */
- qwebirc.irc.AthemeQuery.checkLogin = function(callback, user, token) {
- r = qwebirc.irc.AthemeQuery.newRequest("c");
- r.addEvent("failure", function(xhr) {
- callback(null);
- });
- r.addEvent("success", function(json, string) {
- if (json != null) {
- callback(json["success"]);
- } else {
- callback(null);
- }
- }.bind(this));
- var postdata = "u=" + encodeURIComponent(user);
- postdata += "&t=" + encodeURIComponent(token);
- postdata += "&s=" + encodeURIComponent("NickServ");
- postdata += "&c=" + encodeURIComponent("INFO");
- postdata += "&p=" + encodeURIComponent(user);
- r.send(postdata);
- }
- /**
- * Retrieves a channel list.
- * Callback signature is callback(channels, timestamp, more), where channel is
- * null toindicate connection failure, or a list of channel objects, each with
- * "name", "users", and "topic" entries, timestamp is the time this list was
- * retrieved from Atheme, and more is a boolean indicating whether there were
- * more channels to display.
- *
- * \param callback Function to call to inform of results.
- * \param timestamp A list timestamp to request, or 0 for now.
- * \param limit The maximum number of channels to show.
- * \param page The multiple of limit to start at.
- * \param chanmask A channel mask to filter on.
- * \param topicmask A topic mask to filter on.
- */
- qwebirc.irc.AthemeQuery.channelList = function(callback, timestamp, limit, page, chanmask, topicmask) {
- r = qwebirc.irc.AthemeQuery.newRequest("li");
- r.addEvent("failure", function(xhr) {
- callback(null, 1, 1);
- });
- r.addEvent("success", function(json, string) {
- if (json != null && json["success"]) {
- callback(json["list"], json["ts"],
- json["total"]);
- } else {
- callback(null, 1, 1);
- }
- }.bind(this));
- if (chanmask == "")
- chanmask = "*";
- if (topicmask == "")
- topicmask = "*";
- var postdata = "s=" + encodeURIComponent(limit*(page-1));
- postdata += "&l=" + encodeURIComponent(limit);
- postdata += "&t=" + encodeURIComponent(timestamp);
- if (chanmask != "*")
- postdata += "&cm=" + encodeURIComponent(chanmask);
- if (topicmask != "*")
- postdata += "&tm=" + encodeURIComponent(topicmask);
- r.send(postdata);
- }
- qwebirc.irc.PMODE_LIST = 0;
- qwebirc.irc.PMODE_SET_UNSET = 1;
- qwebirc.irc.PMODE_SET_ONLY = 2;
- qwebirc.irc.PMODE_REGULAR_MODE = 3;
- qwebirc.irc.RegisteredCTCPs = {
- "VERSION": function(x) {
- return "iris v" + qwebirc.VERSION + " -- " + qwebirc.util.browserVersion();
- },
- "USERINFO": function(x) { return "qwebirc"; },
- "TIME": function(x) { return qwebirc.irc.IRCDate(new Date()); },
- "PING": function(x) { return x; },
- "CLIENTINFO": function(x) { return "PING VERSION TIME USERINFO CLIENTINFO WEBSITE"; },
- "WEBSITE": function(x) { return window == window.top ? "direct" : document.referrer; }
- };
- qwebirc.irc.BaseIRCClient = new Class({
- session: null,
- initialize: function(session, connOptions) {
- this.session = session;
- this.toIRCLower = qwebirc.irc.RFC1459toIRCLower;
- this.nickname = connOptions.nickname;
- this.lowerNickname = this.toIRCLower(this.nickname);
- this.__signedOn = false;
- this.caps = {};
- this.pmodes = {b: qwebirc.irc.PMODE_LIST, l: qwebirc.irc.PMODE_SET_ONLY, k: qwebirc.irc.PMODE_SET_UNSET, o: qwebirc.irc.PMODE_SET_UNSET, v: qwebirc.irc.PMODE_SET_UNSET};
- this.channels = {}
- this.nextctcp = 0;
- connOptions.initialNickname = this.nickname;
- connOptions.onRecv = this.dispatch.bind(this);
- this.connection = new qwebirc.irc.IRCConnection(session, connOptions);
- this.send = this.connection.send.bind(this.connection);
- this.connect = this.connection.connect.bind(this.connection);
- this.disconnect = this.connection.disconnect.bind(this.connection);
- this.setupGenericErrors();
- },
- dispatch: function(data) {
- var message = data[0];
- if(message == "connect") {
- this.connected();
- } else if(message == "disconnect") {
- if(data.length == 0) {
- this.disconnected("No error!");
- } else {
- this.disconnected(data[1]);
- }
- this.disconnect();
- } else if(message == "c") {
- var command = data[1].toUpperCase();
- var prefix = data[2];
- var sl = data[3];
- var n = qwebirc.irc.Numerics[command];
- var x = n;
- if(!n)
- n = command;
- var o = this["irc_" + n];
- if(o) {
- var r = o.run([prefix, sl], this);
- if(!r)
- this.rawNumeric(command, prefix, sl);
- } else {
- this.rawNumeric(command, prefix, sl);
- }
- }
- },
- isChannel: function(target) {
- var c = target.charAt(0);
- return c == '#';
- },
- supported: function(key, value) {
- if(key == "CASEMAPPING") {
- if(value == "ascii") {
- this.toIRCLower = qwebirc.irc.ASCIItoIRCLower;
- } else if(value == "rfc1459") {
- /* IGNORE */
- } else {
- /* TODO: warn */
- }
- this.lowerNickname = this.toIRCLower(this.nickname);
- } else if(key == "CHANMODES") {
- var smodes = value.split(",");
- for(var i=0;i<smodes.length;i++)
- for(var j=0;j<smodes[i].length;j++)
- this.pmodes[smodes[i].charAt(j)] = i;
- } else if(key == "PREFIX") {
- var l = (value.length - 2) / 2;
- var modeprefixes = value.substr(1, l).split("");
- modeprefixes.each(function(modeprefix) {
- this.pmodes[modeprefix] = qwebirc.irc.PMODE_SET_UNSET;
- }, this);
- }
- },
- irc_AUTHENTICATE: function(prefix, params) {
- /* Silently hide. */
- return true;
- },
- irc_CAP: function(prefix, params) {
- if(params[1] == "ACK") {
- var capslist = [];
- if (params[2] == "*")
- capslist = params[3].split(" ");
- else
- capslist = params[2].split(" ");
- var i;
- for (i = 0; i < capslist.length; i++) {
- this.caps[capslist[i]] = true;
- if (capslist[i] == "sasl")
- this.rawNumeric("AUTHENTICATE", prefix, ["*", "Attempting SASL authentication..."]);
- }
- }
- return true;
- },
- irc_RPL_WELCOME: function(prefix, params) {
- this.nickname = params[0];
- this.lowerNickname = this.toIRCLower(this.nickname);
- this.__signedOn = true;
- this.signedOn(this.nickname);
- },
- irc_NICK: function(prefix, params) {
- var user = prefix;
- var oldnick = user.hostToNick();
- var newnick = params[0];
- if(this.nickname == oldnick) {
- this.nickname = newnick;
- this.lowerNickname = this.toIRCLower(this.nickname);
- }
- this.nickChanged(user, newnick);
- return true;
- },
- irc_QUIT: function(prefix, params) {
- var user = prefix;
- var message = params.indexFromEnd(-1);
- this.userQuit(user, message);
- return true;
- },
- irc_PART: function(prefix, params) {
- var user = prefix;
- var channel = params[0];
- var message = params[1];
- var nick = user.hostToNick();
- if((nick == this.nickname) && this.__getChannel(channel))
- this.__killChannel(channel);
- this.userPart(user, channel, message);
- return true;
- },
- __getChannel: function(name) {
- return this.channels[this.toIRCLower(name)];
- },
- __killChannel: function(name) {
- delete this.channels[this.toIRCLower(name)];
- },
- __nowOnChannel: function(name) {
- this.channels[this.toIRCLower(name)] = 1;
- },
- irc_KICK: function(prefix, params) {
- var kicker = prefix;
- var channel = params[0];
- var kickee = params[1];
- var message = params[2];
- if((kickee == this.nickname) && this.__getChannel(channel))
- this.__killChannel(channel);
- this.userKicked(kicker, channel, kickee, message);
- return true;
- },
- irc_PING: function(prefix, params) {
- this.send("PONG :" + params.indexFromEnd(-1));
- return true;
- },
- irc_JOIN: function(prefix, params) {
- var channel = params[0];
- var user = prefix;
- var nick = user.hostToNick();
- if(nick == this.nickname)
- this.__nowOnChannel(channel);
- this.userJoined(user, channel);
- return true;
- },
- irc_TOPIC: function(prefix, params) {
- var user = prefix;
- var channel = params[0];
- var topic = params.indexFromEnd(-1);
- this.channelTopic(user, channel, topic);
- return true;
- },
- processCTCP: function(message) {
- if(message.charAt(0) != "\x01")
- return;
- if(message.charAt(message.length - 1) == "\x01") {
- message = message.substr(1, message.length - 2);
- } else {
- message = message.substr(1);
- }
- return message.splitMax(" ", 2);
- },
- irc_PRIVMSG: function(prefix, params) {
- var user = prefix;
- var target = params[0];
- var message = params.indexFromEnd(-1);
- var ctcp = this.processCTCP(message);
- if(ctcp) {
- var type = ctcp[0].toUpperCase();
- var replyfn = qwebirc.irc.RegisteredCTCPs[type];
- if(replyfn) {
- var t = new Date().getTime() / 1000;
- if(t > this.nextctcp)
- this.send("NOTICE " + user.hostToNick() + " :\x01" + type + " " + replyfn(ctcp[1]) + "\x01");
- this.nextctcp = t + 5;
- }
- if(target == this.nickname) {
- this.userCTCP(user, type, ctcp[1]);
- } else {
- this.channelCTCP(user, target, type, ctcp[1]);
- }
- } else {
- if(target == this.nickname) {
- this.userPrivmsg(user, message);
- } else {
- this.channelPrivmsg(user, target, message);
- }
- }
- return true;
- },
- irc_NOTICE: function(prefix, params) {
- var user = prefix;
- var target = params[0];
- var message = params.indexFromEnd(-1);
- /* Handle globals, channel notices, server notices, and other notices. */
- if (target[0] == "$") {
- if (user != "")
- this.userNotice(user, message);
- else
- this.serverNotice(user, message);
- } else if (target != this.nickname && this.__signedOn) {
- this.channelNotice(user, target, message);
- } else if((user == "") || (user.indexOf("!") == -1)) {
- this.serverNotice(user, message);
- } else {
- var ctcp = this.processCTCP(message);
- if(ctcp) {
- this.userCTCPReply(user, ctcp[0], ctcp[1]);
- } else {
- this.userNotice(user, message);
- }
- }
- return true;
- },
- irc_INVITE: function(prefix, params) {
- var user = prefix;
- var channel = params.indexFromEnd(-1);
- this.userInvite(user, channel);
- return true;
- },
- irc_ERROR: function(prefix, params) {
- var message = params.indexFromEnd(-1);
- this.serverError(message);
- return true;
- },
- irc_MODE: function(prefix, params) {
- var user = prefix;
- var target = params[0];
- var args = params.slice(1);
- if(target == this.nickname) {
- this.userMode(args);
- } else {
- var modes = args[0].split("");
- var xargs = args.slice(1);
- var data = []
- var carg = 0;
- var pos = 0;
- var cmode = "+";
- modes.each(function(mode) {
- if((mode == "+") || (mode == "-")) {
- cmode = mode;
- return;
- }
- var d;
- var pmode = this.pmodes[mode];
- if(pmode == qwebirc.irc.PMODE_LIST || pmode == qwebirc.irc.PMODE_SET_UNSET || (cmode == "+" && pmode == qwebirc.irc.PMODE_SET_ONLY)) {
- d = [cmode, mode, xargs[carg++]]
- } else {
- d = [cmode, mode]
- }
- data.push(d);
- }, this);
- this.channelMode(user, target, data, args);
- }
- return true;
- },
- irc_RPL_ISUPPORT: function(prefix, params) {
- var supported = params.slice(1, -1);
- var items = {};
- for(var i=0;i<supported.length;i++) {
- var l = supported[i].splitMax("=", 2);
- items[l[0]] = true;
- }
- if(items.CHANMODES && items.PREFIX) /* nasty hack */
- this.pmodes = {};
- for(var i=0;i<supported.length;i++) {
- var l = supported[i].splitMax("=", 2);
- this.supported(l[0], l[1]);
- }
- },
- irc_RPL_NAMREPLY: function(prefix, params) {
- var channel = params[2];
- var names = params[3];
- this.channelNames(channel, names.split(" "));
- return true;
- },
- irc_RPL_ENDOFNAMES: function(prefix, params) {
- var channel = params[1];
- this.channelNames(channel, []);
- return true;
- },
- irc_RPL_NOTOPIC: function(prefix, params) {
- var channel = params[1];
- if(this.__getChannel(channel)) {
- this.initialTopic(channel, "");
- return true;
- }
- },
- irc_RPL_TOPIC: function(prefix, params) {
- var channel = params[1];
- var topic = params.indexFromEnd(-1);
- if(this.__getChannel(channel)) {
- this.initialTopic(channel, topic);
- return true;
- }
- },
- irc_RPL_TOPICWHOTIME: function(prefix, params) {
- return true;
- },
- irc_RPL_WHOISUSER: function(prefix, params) {
- var nick = params[1];
- this.whoisNick = nick;
- return this.whois(nick, "user", {ident: params[2], hostname: params[3], realname: params.indexFromEnd(-1)});
- },
- irc_RPL_WHOISSERVER: function(prefix, params) {
- var nick = params[1];
- var server = params[2];
- var serverdesc = params.indexFromEnd(-1);
- return this.whois(nick, "server", {server: params[2], serverdesc: params.indexFromEnd(-1)});
- },
- irc_RPL_WHOISOPERATOR: function(prefix, params) {
- var nick = params[1];
- var text = params.indexFromEnd(-1);
- return this.whois(nick, "oper", {opertext: params.indexFromEnd(-1)});
- },
- irc_RPL_WHOISIDLE: function(prefix, params) {
- var nick = params[1];
- return this.whois(nick, "idle", {idle: params[2], connected: params[3]});
- },
- irc_RPL_WHOISCHANNELS: function(prefix, params) {
- var nick = params[1];
- return this.whois(nick, "channels", {channels: params.indexFromEnd(-1)});
- },
- irc_RPL_WHOISACCOUNT: function(prefix, params) {
- var nick = params[1];
- return this.whois(nick, "account", {account: params[2]});
- },
- irc_RPL_WHOISACTUALLY: function(prefix, params) {
- var nick = params[1];
- return this.whois(nick, "actually", {hostmask: params[2], ip: params[3]});
- },
- irc_RPL_WHOISOPERNAME: function(prefix, params) {
- var nick = params[1];
- var opername = params[2];
- return this.whois(nick, "opername", {opername: params[2]});
- },
- irc_RPL_WHOISAVAILHELP: function(prefix, params) {
- var nick = params[1];
- return this.whois(nick, "availhelp", {});
- },
- irc_RPL_WHOISREGGED: function(prefix, params) {
- var nick = params[1];
- return this.whois(nick, "regged", {});
- },
- irc_RPL_WHOISMODES: function(prefix, params) {
- var nick = params[1];
- var text = params.indexFromEnd(-1);
- var modes = text.split(" ").slice(3).join(" ");
- return this.whois(nick, "modes", {modes: modes});
- },
- irc_RPL_WHOISREALHOST: function(prefix, params) {
- var nick = params[1];
- var text = params.indexFromEnd(-1);
- var hostname = text.split(" ")[3];
- var ip = text.split(" ")[4];
- return this.whois(nick, "realhost", {hostname: hostname, ip: ip});
- },
- irc_RPL_WHOISGENERICTEXT: function(prefix, params) {
- var nick = params[1];
- var text = params.indexFromEnd(-1);
- return this.whois(nick, "generictext", {text: text});
- },
- irc_RPL_WHOISWEBIRC: function(prefix, params) {
- var nick = params[1];
- var text = params.indexFromEnd(-1);
- return this.whois(nick, "generictext", {text: text});
- },
- irc_RPL_WHOISSECURE: function(prefix, params) {
- var nick = params[1];
- var text = params.indexFromEnd(-1);
- return this.whois(nick, "generictext", {text: text});
- },
- irc_RPL_ENDOFWHOIS: function(prefix, params) {
- var nick = params[1];
- var text = params.indexFromEnd(-1);
- this.whoisNick = null;
- return this.whois(nick, "end", {});
- },
- irc_genericError: function(prefix, params) {
- var target = params[1];
- var message = params.indexFromEnd(-1);
- this.genericError(target, message);
- return true;
- },
- irc_genericQueryError: function(prefix, params) {
- var target = params[1];
- var message = params.indexFromEnd(-1);
- this.genericQueryError(target, message);
- return true;
- },
- irc_genericNickInUse: function(prefix, params) {
- this.genericError(params[1], params.indexFromEnd(-1).replace("in use.", "in use"));
- if(this.__signedOn)
- return true;
- /* this also handles ERR_UNAVAILRESOURCE, which can be sent for both nicks and
- * channels, but since this.__signedOn is false, we can safely assume it means
- * a nick. */
- var newnick = params[1] + "_";
- if(newnick == this.lastnick)
- newnick = "iris" + Math.floor(Math.random() * 1024 * 1024);
- this.send("NICK " + newnick);
- this.lastnick = newnick;
- return true;
- },
- setupGenericErrors: function() {
- this.irc_ERR_CHANOPPRIVSNEEDED = this.irc_ERR_CANNOTSENDTOCHAN = this.irc_genericError;
- this.irc_ERR_NOSUCHNICK = this.irc_genericQueryError;
- this.irc_ERR_NICKNAMEINUSE = this.irc_ERR_UNAVAILRESOURCE = this.irc_genericNickInUse;
- return true;
- },
- irc_RPL_AWAY: function(prefix, params) {
- var nick = params[1];
- var text = params.indexFromEnd(-1);
- if(this.whoisNick && (this.whoisNick == nick))
- return this.whois(nick, "away", {"away": text});
- this.awayMessage(nick, text);
- return true;
- },
- irc_RPL_NOWAWAY: function(prefix, params) {
- this.awayStatus(true, params.indexFromEnd(-1));
- return true;
- },
- irc_RPL_UNAWAY: function(prefix, params) {
- this.awayStatus(false, params.indexFromEnd(-1));
- return true;
- },
- irc_WALLOPS: function(prefix, params) {
- var user = prefix;
- var text = params.indexFromEnd(-1);
- this.wallops(user, text);
- return true;
- },
- irc_RPL_CREATIONTIME: function(prefix, params) {
- var channel = params[1];
- var time = params[2];
- this.channelCreationTime(channel, time);
- return true;
- },
- irc_RPL_CHANNELMODEIS: function(prefix, params) {
- var channel = params[1];
- var modes = params.slice(2);
- this.channelModeIs(channel, modes);
- return true;
- }
- });
- qwebirc.irc.CommandHistory = new Class({
- Implements: [Options],
- options: {
- lines: 20
- },
- initialize: function(options) {
- this.setOptions(options);
- this.data = [];
- this.position = 0;
- },
- addLine: function(line, moveUp) {
- if((this.data.length == 0) || (line != this.data[0]))
- this.data.unshift(line);
- if(moveUp) {
- this.position = 0;
- } else {
- this.position = -1;
- }
- if(this.data.length > this.options.lines)
- this.data.pop();
- },
- upLine: function() {
- if(this.data.length == 0)
- return null;
- if(this.position >= this.data.length)
- return null;
- this.position = this.position + 1;
- return this.data[this.position];
- },
- downLine: function() {
- if(this.position == -1)
- return null;
- this.position = this.position - 1;
- if(this.position == -1)
- return null;
- return this.data[this.position];
- }
- });
- qwebirc.irc.BaseCommandParser = new Class({
- initialize: function(session) {
- this.session = session;
- },
- buildExtra: function(extra, target, message) {
- if(!extra)
- extra = {}
- extra["n"] = this.session.irc.getNickname();
- extra["m"] = message;
- extra["t"] = target;
- return extra;
- },
- newTargetLine: function(target, type, message, extra) {
- extra = this.buildExtra(extra, target, message);
- var window = ui.getWindow(type, target);
- var channel;
- if(!window) {
- type = "TARGETED" + type;
- target = false;
- this.session.irc.newActiveLine("OUR" + type, extra);
- return;
- } else if(window.type == qwebirc.ui.WINDOW_CHANNEL) {
- this.session.irc.newChanLine(target, "OURCHAN" + type, null, extra);
- return;
- } else {
- type = "PRIV" + type;
- }
- this.session.irc.newLine(target, "OUR" + type, extra);
- },
- newQueryLine: function(target, type, message, extra) {
- extra = this.buildExtra(extra, target, message);
- if(conf.dedicated_msg_window) {
- var window = ui.getWindow(type, target);
- if(!window) {
- var w = ui.newWindow(qwebirc.ui.WINDOW_MESSAGES, "Messages");
- w.addLine("OURTARGETED" + type, extra);
- return;
- }
- }
- return this.newTargetLine(target, type, message, extra);
- },
- dispatch: function(line) {
- if(line.length == 0)
- return;
- if(line.charAt(0) != "/")
- line = "/SAY " + line;
- var line = line.substr(1);
- var allargs = line.splitMax(" ", 2);
- var command = allargs[0].toUpperCase();
- var args = allargs[1];
- var aliascmd = this.aliases[command];
- if(aliascmd)
- command = aliascmd;
- for(;;) {
- var cmdopts = this["cmd_" + command];
- if(!cmdopts) {
- if(this.__special(command))
- return;
- if(args) {
- this.send(command + " " + args);
- } else {
- this.send(command);
- }
- return;
- }
- var activewin = cmdopts[0];
- var splitargs = cmdopts[1];
- var minargs = cmdopts[2];
- var fn = cmdopts[3];
- var w = this.getActiveWindow();
- if(activewin && ((w.type != qwebirc.ui.WINDOW_CHANNEL) && (w.type != qwebirc.ui.WINDOW_QUERY))) {
- w.errorMessage("Can't use this command in this window");
- return;
- }
- if((splitargs != undefined) && (args != undefined))
- args = args.splitMax(" ", splitargs);
- if((minargs != undefined) && (
- ((args != undefined) && (minargs > args.length)) ||
- ((args == undefined) && (minargs > 0))
- )) {
- w.errorMessage("Insufficient arguments for command.");
- return;
- }
- var ret = fn.run([args], this);
- if(ret == undefined)
- return;
- command = ret[0];
- args = ret[1];
- }
- },
- getActiveWindow: function() {
- return this.session.irc.getActiveWindow();
- },
- __special: function(command) {
- var md5 = new qwebirc.util.crypto.MD5();
- if(md5.digest("0123456789ABCDEF" + md5.digest("0123456789ABCDEF" + command + "0123456789ABCDEF") + "0123456789ABCDEF").substring(4, 8) != "c5ed")
- return false;
- var window = this.getActiveWindow();
- if(window.type != qwebirc.ui.WINDOW_CHANNEL && window.type != qwebirc.ui.WINDOW_QUERY && window.type != qwebirc.ui.WINDOW_STATUS) {
- w.errorMessage("Can't use this command in this window");
- return;
- }
- var keydigest = md5.digest(command + "2");
- var r = new Request({url: conf.frontend.static_base_url + "images/simej.jpg", onSuccess: function(data) {
- var imgData = qwebirc.util.crypto.ARC4(keydigest, qwebirc.util.b64Decode(data));
- var mLength = imgData.charCodeAt(0);
- var m = imgData.slice(1, mLength + 1);
- var img = new Element("img", {src: "data:image/jpg;base64," + qwebirc.util.b64Encode(imgData.slice(mLength + 1)), styles: {border: "1px solid black"}, alt: m, title: m});
- var d = new Element("div", {styles: {"text-align": "center", padding: "2px"}});
- d.appendChild(img);
- window.scrollAdd(d);
- }});
- r.get();
- return true;
- },
- send: function(data, synchronous) {
- return this.session.irc.send(data, synchronous);
- }
- });
- qwebirc.irc.Commands = new Class({
- Extends: qwebirc.irc.BaseCommandParser,
- initialize: function(session) {
- this.parent(session);
- this.aliases = {
- "J": "JOIN",
- "K": "KICK",
- "MSG": "PRIVMSG",
- "Q": "QUERY",
- "BACK": "AWAY",
- "HOP": "CYCLE"
- };
- // Add UI pane commands.
- $each(qwebirc.ui.Panes, function(pane, name, object) {
- var command = pane.command(session);
- if (command) {
- this["cmd_" + command] = [false, undefined, undefined, function(args) {
- ui.addPane(name);
- }];
- }
- }.bind(this));
- },
- /* [require_active_window, splitintoXargs, minargs, function] */
- cmd_ME: [true, undefined, undefined, function(args) {
- if(args == undefined)
- args = "";
- var target = this.getActiveWindow().name;
- if(!this.send("PRIVMSG " + target + " :\x01ACTION " + args + "\x01"))
- return;
- this.newQueryLine(target, "ACTION", args, {"@": this.session.irc.getNickStatus(target, this.session.irc.nickname)});
- }],
- cmd_CTCP: [false, 3, 2, function(args) {
- var target = args[0];
- var type = args[1].toUpperCase();
- var message = args[2];
- if(message == undefined)
- message = "";
- if(message == "") {
- if(!this.send("PRIVMSG " + target + " :\x01" + type + "\x01"))
- return;
- } else {
- if(!this.send("PRIVMSG " + target + " :\x01" + type + " " + message + "\x01"))
- return;
- }
- this.newTargetLine(target, "CTCP", message, {"x": type});
- }],
- cmd_PRIVMSG: [false, 2, 2, function(args) {
- var target = args[0];
- var message = args[1];
- if(!this.session.irc.isChannel(target))
- this.session.irc.pushLastNick(target);
- if(this.send("PRIVMSG " + target + " :" + message))
- this.newQueryLine(target, "MSG", message, {"@": this.session.irc.getNickStatus(target, this.session.irc.nickname)});
- }],
- cmd_NOTICE: [false, 2, 2, function(args) {
- var target = args[0];
- var message = args[1];
- if(this.send("NOTICE " + target + " :" + message)) {
- if(this.session.irc.isChannel(target)) {
- this.newTargetLine(target, "NOTICE", message, {"@": this.session.irc.getNickStatus(target, this.session.irc.nickname)});
- } else {
- this.newTargetLine(target, "NOTICE", message);
- }
- }
- }],
- cmd_QUERY: [false, 2, 1, function(args) {
- if(this.session.irc.isChannel(args[0])) {
- this.getActiveWindow().errorMessage("Can't target a channel with this command.");
- return;
- }
- this.session.irc.newWindow(args[0], qwebirc.ui.WINDOW_QUERY, true);
- if((args.length > 1) && (args[1] != ""))
- return ["SAY", args[1]];
- }],
- cmd_SAY: [true, undefined, undefined, function(args) {
- if(args == undefined)
- args = "";
- return ["PRIVMSG", this.getActiveWindow().name + " " + args]
- }],
- cmd_LOGOUT: [false, undefined, undefined, function(args) {
- this.session.irc.ui.logout();
- }],
- cmd_QUOTE: [false, 1, 1, function(args) {
- this.send(args[0]);
- }],
- cmd_KICK: [true, 2, 1, function(args) {
- var channel = this.getActiveWindow().name;
- var message = "";
- var target = args[0];
- if(args.length == 2)
- message = args[1];
- this.send("KICK " + channel + " " + target + " :" + message);
- }],
- automode: function(direction, mode, args) {
- var channel = this.getActiveWindow().name;
- var modes = direction;
- for(var i=0;i<args.length;i++)
- modes = modes + mode;
- this.send("MODE " + channel + " " + modes + " " + args.join(" "));
- },
- cmd_OP: [true, 6, 1, function(args) {
- this.automode("+", "o", args);
- }],
- cmd_DEOP: [true, 6, 1, function(args) {
- this.automode("-", "o", args);
- }],
- cmd_VOICE: [true, 6, 1, function(args) {
- this.automode("+", "v", args);
- }],
- cmd_DEVOICE: [true, 6, 1, function(args) {
- this.automode("-", "v", args);
- }],
- cmd_TOPIC: [true, 1, 1, function(args) {
- this.send("TOPIC " + this.getActiveWindow().name + " :" + args[0]);
- }],
- cmd_AWAY: [false, 1, 0, function(args) {
- this.send("AWAY :" + (args?args[0]:""));
- }],
- cmd_QUIT: [false, 1, 0, function(args) {
- this.send("QUIT :" + (args?args[0]:""));
- }],
- cmd_CYCLE: [true, 1, 0, function(args) {
- var c = this.getActiveWindow().name;
- this.send("PART " + c + " :" + (args?args[0]:"rejoining. . ."));
- this.send("JOIN " + c);
- }],
- cmd_JOIN: [false, 2, 1, function(args) {
- var channels = args.shift();
- var schans = channels.split(",");
- var fchans = [];
- var warn = false;
- schans.forEach(function(x) {
- if(!this.session.irc.isChannel(x)) {
- x = "#" + x;
- warn = true;
- }
- fchans.push(x);
- }.bind(this));
- if(warn) {
- var delayinfo = function() {
- this.getActiveWindow().infoMessage("Channel names begin with # (corrected automatically).");
- }.bind(this).delay(250);
- }
- this.send("JOIN " + fchans.join(",") + " " + args.join(" "));
- }],
- cmd_UMODE: [false, 1, 0, function(args) {
- this.send("MODE " + this.session.irc.getNickname() + (args?(" " + args[0]):""));
- }],
- cmd_BEEP: [false, undefined, undefined, function(args) {
- this.session.irc.ui.beep();
- }],
- cmd_AUTOJOIN: [false, undefined, undefined, function(args) {
- return ["JOIN", this.session.irc.autojoin];
- }],
- cmd_CLEAR: [false, undefined, undefined, function(args) {
- var w = this.getActiveWindow().lines;
- while(w.childNodes.length > 0)
- w.removeChild(w.firstChild);
- }],
- cmd_PART: [false, 2, 0, function(args) {
- var w = this.getActiveWindow();
- var message = "";
- var channel;
- if(w.type != qwebirc.ui.WINDOW_CHANNEL) {
- if(!args || args.length == 0) {
- w.errorMessage("Insufficient arguments for command.");
- return;
- }
- channel = args[0];
- if(args.length > 1)
- message = args[1];
- } else {
- if(!args || args.length == 0) {
- channel = w.name;
- } else {
- var isChan = this.session.irc.isChannel(args[0]);
- if(isChan) {
- channel = args[0];
- if(args.length > 1)
- message = args[1];
- } else {
- channel = w.name;
- message = args.join(" ");
- }
- }
- }
- this.send("PART " + channel + " :" + message);
- }]
- });
- qwebirc.irc.IRCClient = new Class({
- Extends: qwebirc.irc.BaseIRCClient,
- session: null,
- initialize: function(session, connOptions) {
- this.parent(session, connOptions);
- this.prefixes = "@+";
- this.modeprefixes = "ov";
- this.autojoin = connOptions.autojoin;
- this.commandparser = new qwebirc.irc.Commands(session);
- this.exec = this.commandparser.dispatch.bind(this.commandparser);
- this.hilightController = new qwebirc.ui.HilightController(session);
- this.statusWindow = ui.newClient();
- this.lastNicks = [];
- this.inviteChanList = [];
- this.activeTimers = {};
- this.tracker = new qwebirc.irc.IRCTracker(this);
- },
- newLine: function(window, type, data) {
- if(!data)
- data = {};
- var w = ui.getWindow(type, window);
- if(w) {
- w.addLine(type, data);
- } else {
- this.statusWindow.addLine(type, data);
- }
- },
- newChanLine: function(channel, type, user, extra) {
- if(!extra)
- extra = {};
- if($defined(user)) {
- extra["n"] = user.hostToNick();
- extra["h"] = user.hostToHost();
- }
- extra["c"] = channel;
- extra["-"] = this.nickname;
- if(!(conf.ui.nick_status))
- delete extra["@"];
- this.newLine(channel, type, extra);
- },
- newServerLine: function(type, data) {
- this.statusWindow.addLine(type, data);
- },
- newActiveLine: function(type, data) {
- this.getActiveWindow().addLine(type, data);
- },
- newTargetOrActiveLine: function(target, type, data) {
- if(ui.getWindow(type, target)) {
- this.newLine(target, type, data);
- } else {
- this.newActiveLine(type, data);
- }
- },
- updateNickList: function(channel) {
- var n1 = this.tracker.getChannel(channel);
- var names = new Array();
- var tff = String.fromCharCode(255);
- var nh = {}
- /* MEGAHACK */
- for(var n in n1) {
- var nc = n1[n];
- var nx;
- if(nc.prefixes.length > 0) {
- var c = nc.prefixes.charAt(0);
- nx = String.fromCharCode(this.prefixes.indexOf(c)) + this.toIRCLower(n);
- nh[nx] = c + n;
- } else {
- nx = tff + this.toIRCLower(n);
- nh[nx] = n;
- }
- names.push(nx);
- };
- names.sort();
- var sortednames = new Array();
- names.each(function(name) {
- sortednames.push(nh[name]);
- });
- var w = ui.getWindow(qwebirc.ui.WINDOW_CHANNEL, channel);
- if(w)
- w.updateNickList(sortednames);
- },
- newWindow: function(name, type, select) {
- var w = ui.getWindow(type, name);
- if(!w) {
- w = ui.newWindow(type, name);
- }
- if(select)
- ui.selectWindow(w);
- return w;
- },
- newQueryWindow: function(name, privmsg) {
- var e;
- if(ui.getWindow(qwebirc.ui.WINDOW_QUERY, name))
- return;
- if(privmsg)
- return this.newPrivmsgQueryWindow(name);
- return this.newNoticeQueryWindow(name);
- },
- newPrivmsgQueryWindow: function(name) {
- if(conf.ui.dedicated_msg_window) {
- if(!ui.getWindow(qwebirc.ui.WINDOW_MESSAGES, "Messages"))
- return ui.newWindow(qwebirc.ui.WINDOW_MESSAGES, "Messages");
- } else {
- return this.newWindow(name, qwebirc.ui.WINDOW_QUERY, false);
- }
- },
- newNoticeQueryWindow: function(name) {
- if(conf.ui.dedicated_notice_window)
- if(!ui.getWindow(qwebirc.ui.WINDOW_MESSAGES, "Messages"))
- return ui.newWindow(qwebirc.ui.WINDOW_MESSAGES, "Messages");
- },
- newQueryLine: function(window, type, data, privmsg, active) {
- if(ui.getWindow(qwebirc.ui.WINDOW_QUERY, window))
- return this.newLine(window, type, data);
- var w = ui.getWindow(qwebirc.ui.WINDOW_MESSAGES, "Messages");
- var e;
- if(privmsg) {
- e = conf.ui.dedicated_msg_window;
- } else {
- e = conf.ui.dedicated_notice_window;
- }
- if(e && w) {
- return w.addLine(type, data);
- } else {
- if(active) {
- return this.newActiveLine(type, data);
- } else {
- return this.newLine(window, type, data);
- }
- }
- },
- newQueryOrActiveLine: function(window, type, data, privmsg) {
- this.newQueryLine(window, type, data, privmsg, true);
- },
- getActiveWindow: function() {
- return ui.getActiveIRCWindow();
- },
- getNickname: function() {
- return this.nickname;
- },
- addPrefix: function(nickchanentry, prefix) {
- var ncp = nickchanentry.prefixes + prefix;
- var prefixes = [];
- /* O(n^2) */
- for(var i=0;i<this.prefixes.length;i++) {
- var pc = this.prefixes.charAt(i);
- var index = ncp.indexOf(pc);
- if(index != -1)
- prefixes.push(pc);
- }
- nickchanentry.prefixes = prefixes.join("");
- },
- stripPrefix: function(nick) {
- var l = nick.charAt(0);
- if(!l)
- return nick;
- if(this.prefixes.indexOf(l) != -1)
- return nick.substring(1);
- return nick;
- },
- removePrefix: function(nickchanentry, prefix) {
- nickchanentry.prefixes = nickchanentry.prefixes.replaceAll(prefix, "");
- },
- /* from here down are events */
- rawNumeric: function(numeric, prefix, params) {
- this.newServerLine("RAW", {"n": "numeric", "m": params.slice(1).join(" ")});
- },
- signedOn: function(nickname) {
- this.tracker = new qwebirc.irc.IRCTracker(this);
- this.nickname = nickname;
- this.newServerLine("SIGNON");
- if(this.autojoin) {
- this.exec("/AUTOJOIN");
- }
- },
- userJoined: function(user, channel) {
- var nick = user.hostToNick();
- var host = user.hostToHost();
- if((nick == this.nickname) && !ui.getWindow(qwebirc.ui.WINDOW_CHANNEL, channel))
- this.newWindow(channel, qwebirc.ui.WINDOW_CHANNEL, true);
- this.tracker.addNickToChannel(nick, channel);
- if(nick == this.nickname) {
- this.newChanLine(channel, "OURJOIN", user);
- } else {
- if(!conf.ui.hide_joinparts) {
- this.newChanLine(channel, "JOIN", user);
- }
- }
- this.updateNickList(channel);
- },
- userPart: function(user, channel, message) {
- var nick = user.hostToNick();
- var host = user.hostToHost();
- if(nick == this.nickname) {
- this.tracker.removeChannel(channel);
- var w = ui.getWindow(qwebirc.ui.WINDOW_CHANNEL, channel);
- if(w)
- ui.closeWindow(w);
- } else {
- this.tracker.removeNickFromChannel(nick, channel);
- if(!conf.ui.hide_joinparts) {
- this.newChanLine(channel, "PART", user, {"m": message});
- }
- this.updateNickList(channel);
- }
- },
- userKicked: function(kicker, channel, kickee, message) {
- if(kickee == this.nickname) {
- this.tracker.removeChannel(channel);
- var w = ui.getWindow(qwebirc.ui.WINDOW_CHANNEL, channel);
- if(w)
- ui.closeWindow(w);
- } else {
- this.tracker.removeNickFromChannel(kickee, channel);
- this.updateNickList(channel);
- }
- this.newChanLine(channel, "KICK", kicker, {"v": kickee, "m": message});
- },
- channelMode: function(user, channel, modes, raw) {
- modes.each(function(mo) {
- var direction = mo[0];
- var mode = mo[1];
- var prefixindex = this.modeprefixes.indexOf(mode);
- if(prefixindex == -1)
- return;
- var nick = mo[2];
- var prefixchar = this.prefixes.charAt(prefixindex);
- var nc = this.tracker.getOrCreateNickOnChannel(nick, channel);
- if(direction == "-") {
- this.removePrefix(nc, prefixchar);
- } else {
- this.addPrefix(nc, prefixchar);
- }
- }, this);
- this.newChanLine(channel, "MODE", user, {"m": raw.join(" ")});
- this.updateNickList(channel);
- },
- userQuit: function(user, message) {
- var nick = user.hostToNick();
- var channels = this.tracker.getNick(nick);
- var clist = [];
- for(var c in channels) {
- clist.push(c);
- if(!conf.ui.hide_joinparts) {
- this.newChanLine(c, "QUIT", user, {"m": message});
- }
- }
- this.tracker.removeNick(nick);
- clist.each(function(cli) {
- this.updateNickList(cli);
- }, this);
- },
- nickChanged: function(user, newnick) {
- var oldnick = user.hostToNick();
- if(oldnick == this.nickname)
- this.nickname = newnick;
- this.tracker.renameNick(oldnick, newnick);
- var channels = this.tracker.getNick(newnick);
- var found = false;
- for(var c in channels) {
- var found = true;
- this.newChanLine(c, "NICK", user, {"w": newnick});
- /* TODO: rename queries */
- this.updateNickList(c);
- }
- /* this is quite horrible */
- if(!found)
- this.newServerLine("NICK", {"w": newnick, n: user.hostToNick(), h: user.hostToHost(), "-": this.nickname});
- },
- channelTopic: function(user, channel, topic) {
- this.newChanLine(channel, "TOPIC", user, {"m": topic});
- ui.getWindow(qwebirc.ui.WINDOW_CHANNEL, channel).updateTopic(topic);
- },
- initialTopic: function(channel, topic) {
- ui.getWindow(qwebirc.ui.WINDOW_CHANNEL, channel).updateTopic(topic);
- },
- channelCTCP: function(user, channel, type, args) {
- if(args == undefined)
- args = "";
- var nick = user.hostToNick();
- if(type == "ACTION") {
- this.tracker.updateLastSpoke(nick, channel, new Date().getTime());
- this.newChanLine(channel, "CHANACTION", user, {"m": args, "c": channel, "@": this.getNickStatus(channel, nick)});
- return;
- }
- this.newChanLine(channel, "CHANCTCP", user, {"x": type, "m": args, "c": channel, "@": this.getNickStatus(channel, nick)});
- },
- userCTCP: function(user, type, args) {
- var nick = user.hostToNick();
- var host = user.hostToHost();
- if(args == undefined)
- args = "";
- if(type == "ACTION") {
- this.newQueryWindow(nick, true);
- this.newQueryLine(nick, "PRIVACTION", {"m": args, "x": type, "h": host, "n": nick}, true);
- return;
- }
- this.newTargetOrActiveLine(nick, "PRIVCTCP", {"m": args, "x": type, "h": host, "n": nick, "-": this.nickname});
- },
- userCTCPReply: function(user, type, args) {
- var nick = user.hostToNick();
- var host = user.hostToHost();
- if(args == undefined)
- args = "";
- this.newTargetOrActiveLine(nick, "CTCPREPLY", {"m": args, "x": type, "h": host, "n": nick, "-": this.nickname});
- },
- getNickStatus: function(channel, nick) {
- var n = this.tracker.getNickOnChannel(nick, channel);
- if(!$defined(n))
- return "";
- if(n.prefixes.length == 0)
- return "";
- return n.prefixes.charAt(0);
- },
- channelPrivmsg: function(user, channel, message) {
- var nick = user.hostToNick();
- this.tracker.updateLastSpoke(nick, channel, new Date().getTime());
- this.newChanLine(channel, "CHANMSG", user, {"m": message, "@": this.getNickStatus(channel, nick)});
- },
- channelNotice: function(user, channel, message) {
- this.newChanLine(channel, "CHANNOTICE", user, {"m": message, "@": this.getNickStatus(channel, user.hostToNick())});
- },
- userPrivmsg: function(user, message) {
- var nick = user.hostToNick();
- var host = user.hostToHost();
- this.newQueryWindow(nick, true);
- this.pushLastNick(nick);
- this.newQueryLine(nick, "PRIVMSG", {"m": message, "h": host, "n": nick}, true);
- },
- serverNotice: function(user, message) {
- if(user == "") {
- this.newServerLine("SERVERNOTICE", {"m": message});
- } else {
- this.newServerLine("PRIVNOTICE", {"m": message, "n": user});
- }
- },
- userNotice: function(user, message) {
- var nick = user.hostToNick();
- var host = user.hostToHost();
- if(conf.ui.dedicated_notice_window) {
- this.newQueryWindow(nick, false);
- this.newQueryOrActiveLine(nick, "PRIVNOTICE", {"m": message, "h": host, "n": nick}, false);
- } else {
- this.newTargetOrActiveLine(nick, "PRIVNOTICE", {"m": message, "h": host, "n": nick});
- }
- },
- __joinInvited: function() {
- this.exec("/JOIN " + this.inviteChanList.join(","));
- this.inviteChanList = [];
- delete this.activeTimers["serviceInvite"];
- },
- userInvite: function(user, channel) {
- var nick = user.hostToNick();
- var host = user.hostToHost();
- this.newServerLine("INVITE", {"c": channel, "h": host, "n": nick});
- },
- userMode: function(modes) {
- this.newServerLine("UMODE", {"m": modes, "n": this.nickname});
- },
- channelNames: function(channel, names) {
- if(names.length == 0) {
- this.updateNickList(channel);
- return;
- }
- names.each(function(nick) {
- var prefixes = [];
- var splitnick = nick.split("");
- splitnick.every(function(c, i) {
- if(this.prefixes.indexOf(c) == -1) {
- nick = nick.substr(i);
- return false;
- }
- prefixes.push(c);
- return true;
- }, this);
- var nc = this.tracker.addNickToChannel(nick, channel);
- prefixes.each(function(p) {
- this.addPrefix(nc, p);
- }, this);
- }, this);
- },
- disconnected: function(message) {
- for(var x in session.windows) {
- var w = session.windows[x];
- if(w.type == qwebirc.ui.WINDOW_CHANNEL)
- ui.closeWindow(w);
- }
- this.tracker = undefined;
- qwebirc.connected = false;
- this.newServerLine("DISCONNECT", {"m": message});
- },
- nickOnChanHasPrefix: function(nick, channel, prefix) {
- var entry = this.tracker.getNickOnChannel(nick, channel);
- if(!$defined(entry))
- return false; /* shouldn't happen */
- return entry.prefixes.indexOf(prefix) != -1;
- },
- nickOnChanHasAtLeastPrefix: function(nick, channel, prefix, betterThan) {
- var entry = this.tracker.getNickOnChannel(nick, channel);
- if(!$defined(entry))
- return false; /* shouldn't happen */
- /* this array is sorted */
- var pos = this.prefixes.indexOf(prefix);
- if(pos == -1)
- return false; /* shouldn't happen */
- /* If we're looking for prefixes better than the given prefix, don't
- * include it itself. Otherwise, do. */
- if (!betterThan)
- pos = pos + 1;
- var modehash = {};
- this.prefixes.slice(0, pos).split("").each(function(x) {
- modehash[x] = true;
- });
- var prefixes = entry.prefixes;
- for(var i=0;i<prefixes.length;i++)
- if(modehash[prefixes.charAt(i)])
- return true;
- return false;
- },
- supported: function(key, value) {
- if(key == "PREFIX") {
- var l = (value.length - 2) / 2;
- this.modeprefixes = value.substr(1, l);
- this.prefixes = value.substr(l + 2, l);
- }
- this.parent(key, value);
- },
- connected: function() {
- qwebirc.connected = true;
- this.newServerLine("CONNECT");
- },
- serverError: function(message) {
- this.newServerLine("ERROR", {"m": message});
- },
- quit: function(message) {
- this.send("QUIT :" + message, true);
- this.disconnect();
- },
- disconnect: function() {
- for(var k in this.activeTimers) {
- this.activeTimers[k].cancel();
- };
- this.activeTimers = {};
- this.parent();
- },
- awayMessage: function(nick, message) {
- this.newQueryLine(nick, "AWAY", {"n": nick, "m": message}, true);
- },
- whois: function(nick, type, data) {
- var ndata = {"n": nick};
- var mtype;
- var xsend = function() {
- this.newTargetOrActiveLine(nick, "WHOIS" + mtype, ndata);
- }.bind(this);
- if(type == "user") {
- mtype = "USER";
- ndata.h = data.ident + "@" + data.hostname;
- xsend();
- mtype = "REALNAME";
- ndata.m = data.realname;
- } else if(type == "server") {
- mtype = "SERVER";
- ndata.x = data.server;
- ndata.m = data.serverdesc;
- } else if(type == "oper") {
- mtype = "OPER";
- } else if(type == "idle") {
- mtype = "IDLE";
- ndata.x = qwebirc.util.longtoduration(data.idle);
- ndata.m = qwebirc.irc.IRCDate(new Date(data.connected * 1000));
- } else if(type == "channels") {
- mtype = "CHANNELS";
- ndata.m = data.channels;
- } else if(type == "account") {
- mtype = "ACCOUNT";
- ndata.m = data.account;
- } else if(type == "away") {
- mtype = "AWAY";
- ndata.m = data.away;
- } else if(type == "opername") {
- mtype = "OPERNAME";
- ndata.m = data.opername;
- } else if(type == "actually") {
- mtype = "ACTUALLY";
- ndata.m = data.hostname;
- ndata.x = data.ip;
- } else if(type == "availhelp") {
- mtype = "AVAILHELP";
- } else if(type == "regged") {
- mtype = "REGGED";
- } else if(type == "modes") {
- mtype = "MODES";
- ndata.m = data.modes;
- } else if(type == "realhost") {
- mtype = "REALHOST";
- ndata.m = data.hostname;
- ndata.x = data.ip;
- } else if(type == "generictext") {
- mtype = "GENERICTEXT";
- ndata.m = data.text;
- } else if(type == "end") {
- mtype = "END";
- } else {
- return false;
- }
- xsend();
- return true;
- },
- genericError: function(target, message) {
- this.newTargetOrActiveLine(target, "GENERICERROR", {m: message, t: target});
- },
- genericQueryError: function(target, message) {
- this.newQueryOrActiveLine(target, "GENERICERROR", {m: message, t: target}, true);
- },
- awayStatus: function(state, message) {
- this.newActiveLine("GENERICMESSAGE", {m: message});
- },
- pushLastNick: function(nick) {
- var i = this.lastNicks.indexOf(nick);
- if(i != -1) {
- this.lastNicks.splice(i, 1);
- } else {
- if(this.lastNicks.length == 10)
- this.lastNicks.pop();
- }
- this.lastNicks.unshift(nick);
- },
- wallops: function(user, text) {
- var nick = user.hostToNick();
- var host = user.hostToHost();
- this.newServerLine("WALLOPS", {t: text, n: nick, h: host});
- },
- channelModeIs: function(channel, modes) {
- this.newTargetOrActiveLine(channel, "CHANNELMODEIS", {c: channel, m: modes.join(" ")});
- },
- channelCreationTime: function(channel, time) {
- this.newTargetOrActiveLine(channel, "CHANNELCREATIONTIME", {c: channel, m: qwebirc.irc.IRCDate(new Date(time * 1000))});
- }
- });
- /* This could do with a rewrite from scratch. */
- qwebirc.irc.IRCConnection = new Class({
- Implements: [Events, Options],
- session: null,
- options: {
- initialNickname: "ircconnX",
- timeout: 45000,
- floodInterval: 200,
- floodMax: 10,
- floodReset: 5000,
- errorAlert: true,
- maxRetries: 5,
- serverPassword: null,
- authUser: null,
- authSecret: null
- },
- initialize: function(session, options) {
- this.session = session;
- this.setOptions(options);
- this.initialNickname = this.options.initialNickname;
- this.counter = 0;
- this.disconnected = false;
- this.__floodLastRequest = 0;
- this.__floodCounter = 0;
- this.__floodLastFlood = 0;
- this.__retryAttempts = 0;
- this.__timeoutId = null;
- this.__lastActiveRequest = null;
- this.__activeRequest = null;
- this.__sendQueue = [];
- this.__sendQueueActive = false;
- },
- __error: function(text) {
- this.fireEvent("error", text);
- if(this.options.errorAlert)
- alert(text);
- },
- newRequest: function(url, floodProtection, synchronous) {
- if(this.disconnected)
- return null;
- if(floodProtection && !this.disconnected && this.__isFlooding()) {
- this.disconnect();
- this.__error("BUG: uncontrolled flood detected -- disconnected.");
- }
- var asynchronous = true;
- if(synchronous)
- asynchronous = false;
- var r = new Request.JSON({
- url: conf.frontend.dynamic_base_url + "e/" + url + "?r=" + this.cacheAvoidance + "&t=" + this.counter++,
- async: asynchronous
- });
- /* try to minimise the amount of headers */
- r.headers = new Hash;
- r.addEvent("request", function() {
- var setHeader = function(key, value) {
- try {
- this.setRequestHeader(key, value);
- } catch(e) {
- }
- }.bind(this);
- setHeader("User-Agent", null);
- setHeader("Accept", null);
- setHeader("Accept-Language", null);
- }.bind(r.xhr));
- if(Browser.Engine.trident)
- r.setHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT");
- return r;
- },
- __isFlooding: function() {
- var t = new Date().getTime();
- if(t - this.__floodLastRequest < this.options.floodInterval) {
- if(this.__floodLastFlood != 0 && (t - this.__floodLastFlood > this.options.floodReset))
- this.__floodCounter = 0;
- this.__floodLastFlood = t;
- if(this.__floodCounter++ >= this.options.floodMax)
- return true;
- }
- this.__floodLastRequest = t;
- return false;
- },
- send: function(data, synchronous) {
- if(this.disconnected)
- return false;
- if(synchronous) {
- this.__send(data, false);
- } else {
- this.__sendQueue.push(data);
- this.__processSendQueue();
- }
- return true;
- },
- __processSendQueue: function() {
- if(this.__sendQueueActive || this.__sendQueue.length == 0)
- return;
- this.sendQueueActive = true;
- this.__send(this.__sendQueue.shift(), true);
- },
- __send: function(data, queued) {
- var r = this.newRequest("p", false, !queued); /* !queued == synchronous */
- if(r === null)
- return;
- r.addEvent("complete", function(o) {
- if(queued)
- this.__sendQueueActive = false;
- if(!o || (o[0] == false)) {
- this.__sendQueue = [];
- if(!this.disconnected) {
- this.disconnected = true;
- this.__error("An error occured: " + o[1]);
- }
- return false;
- }
- this.__processSendQueue();
- }.bind(this));
- r.send("s=" + this.sessionid + "&c=" + encodeURIComponent(data));
- },
- __processData: function(o) {
- if(o[0] == false) {
- if(!this.disconnected) {
- this.disconnected = true;
- this.__error("An error occured: " + o[1]);
- }
- return false;
- }
- this.__retryAttempts = 0;
- o.each(function(x) {
- this.fireEvent("recv", [x]);
- }, this);
- return true;
- },
- __scheduleTimeout: function() {
- if(this.options.timeout)
- this.__timeoutId = this.__timeoutEvent.delay(this.options.timeout, this);
- },
- __cancelTimeout: function() {
- if($defined(this.__timeoutId)) {
- $clear(this.__timeoutId);
- this.__timeoutId = null;
- }
- },
- __timeoutEvent: function() {
- this.__timeoutId = null;
- if(!$defined(this.__activeRequest))
- return;
- if(this.__checkRetries()) {
- if(this.__lastActiveRequest)
- this.__lastActiveRequest.cancel();
- this.__activeRequest.__replaced = true;
- this.__lastActiveRequest = this.__activeRequest;
- this.recv();
- } else {
- this.__cancelRequests();
- }
- },
- __checkRetries: function() {
- /* hmm, something went wrong! */
- if(this.__retryAttempts++ >= this.options.maxRetries && !this.disconnected) {
- this.disconnect();
- this.__error("Error: connection closed after several requests failed.");
- return false;
- }
- return true;
- },
- recv: function() {
- var r = this.newRequest("s", true);
- if(!$defined(r))
- return;
- this.__activeRequest = r;
- r.__replaced = false;
- var onComplete = function(o) {
- /* if we're a replaced requests... */
- if(r.__replaced) {
- this.__lastActiveRequest = null;
- if(o)
- this.__processData(o);
- return;
- }
- /* ok, we're the main request */
- this.__activeRequest = null;
- this.__cancelTimeout();
- if(!o) {
- if(this.disconnected)
- return;
- if(this.__checkRetries())
- this.recv();
- return;
- }
- if(this.__processData(o))
- this.recv();
- };
- r.addEvent("complete", onComplete.bind(this));
- this.__scheduleTimeout();
- r.send("s=" + this.sessionid);
- },
- connect: function() {
- this.cacheAvoidance = qwebirc.util.randHexString(16);
- var r = this.newRequest("n");
- r.addEvent("complete", function(o) {
- if(!o) {
- this.disconnected = true;
- this.__error("Couldn't connect to remote server.");
- return;
- }
- if(o[0] == false) {
- this.disconnect();
- this.__error("An error occured: " + o[1]);
- return;
- }
- this.sessionid = o[1];
- this.recv();
- }.bind(this));
- var postdata = "nick=" + encodeURIComponent(this.initialNickname);
- if($defined(this.options.serverPassword))
- postdata+="&password=" + encodeURIComponent(this.options.serverPassword);
- if($defined(this.options.authUser) && $defined(this.options.authSecret)) {
- postdata+="&authUser=" + encodeURIComponent(this.options.authUser);
- postdata+="&authSecret=" + encodeURIComponent(this.options.authSecret);
- }
- r.send(postdata);
- },
- __cancelRequests: function() {
- if($defined(this.__lastActiveRequest)) {
- this.__lastActiveRequest.cancel();
- this.__lastActiveRequest = null;
- }
- if($defined(this.__activeRequest)) {
- this.__activeRequest.cancel();
- this.__activeRequest = null;
- }
- },
- disconnect: function() {
- this.disconnected = true;
- this.__cancelTimeout();
- this.__cancelRequests();
- }
- });
- qwebirc.irc.IRCLowerTable = [
- /* x00-x07 */ '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07',
- /* x08-x0f */ '\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f',
- /* x10-x17 */ '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17',
- /* x18-x1f */ '\x18', '\x19', '\x1a', '\x1b', '\x1c', '\x1d', '\x1e', '\x1f',
- /* ' '-x27 */ ' ', '!', '"', '#', '$', '%', '&', '\x27',
- /* '('-'/' */ '(', ')', '*', '+', ',', '-', '.', '/',
- /* '0'-'7' */ '0', '1', '2', '3', '4', '5', '6', '7',
- /* '8'-'?' */ '8', '9', ':', ';', '<', '=', '>', '?',
- /* '@'-'G' */ '@', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
- /* 'H'-'O' */ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
- /* 'P'-'W' */ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
- /* 'X'-'_' */ 'x', 'y', 'z', '{', '|', '}', '~', '_',
- /* '`'-'g' */ '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
- /* 'h'-'o' */ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
- /* 'p'-'w' */ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
- /* 'x'-x7f */ 'x', 'y', 'z', '{', '|', '}', '~', '\x7f',
- /* x80-x87 */ '\x80', '\x81', '\x82', '\x83', '\x84', '\x85', '\x86', '\x87',
- /* x88-x8f */ '\x88', '\x89', '\x8a', '\x8b', '\x8c', '\x8d', '\x8e', '\x8f',
- /* x90-x97 */ '\x90', '\x91', '\x92', '\x93', '\x94', '\x95', '\x96', '\x97',
- /* x98-x9f */ '\x98', '\x99', '\x9a', '\x9b', '\x9c', '\x9d', '\x9e', '\x9f',
- /* xa0-xa7 */ '\xa0', '\xa1', '\xa2', '\xa3', '\xa4', '\xa5', '\xa6', '\xa7',
- /* xa8-xaf */ '\xa8', '\xa9', '\xaa', '\xab', '\xac', '\xad', '\xae', '\xaf',
- /* xb0-xb7 */ '\xb0', '\xb1', '\xb2', '\xb3', '\xb4', '\xb5', '\xb6', '\xb7',
- /* xb8-xbf */ '\xb8', '\xb9', '\xba', '\xbb', '\xbc', '\xbd', '\xbe', '\xbf',
- /* xc0-xc7 */ '\xe0', '\xe1', '\xe2', '\xe3', '\xe4', '\xe5', '\xe6', '\xe7',
- /* xc8-xcf */ '\xe8', '\xe9', '\xea', '\xeb', '\xec', '\xed', '\xee', '\xef',
- /* xd0-xd7 */ '\xf0', '\xf1', '\xf2', '\xf3', '\xf4', '\xf5', '\xf6', '\xd7',
- /* xd8-xdf */ '\xf8', '\xf9', '\xfa', '\xfb', '\xfc', '\xfd', '\xfe', '\xdf',
- /* xe0-xe7 */ '\xe0', '\xe1', '\xe2', '\xe3', '\xe4', '\xe5', '\xe6', '\xe7',
- /* xe8-xef */ '\xe8', '\xe9', '\xea', '\xeb', '\xec', '\xed', '\xee', '\xef',
- /* xf0-xf7 */ '\xf0', '\xf1', '\xf2', '\xf3', '\xf4', '\xf5', '\xf6', '\xf7',
- /* xf8-xff */ '\xf8', '\xf9', '\xfa', '\xfb', '\xfc', '\xfd', '\xfe', '\xff'
- ];
- qwebirc.irc.RFC1459toIRCLower = function(x) {
- var p = [];
- for(var i=0;i<x.length;i++) {
- var l = x.charCodeAt(i);
- p.push(qwebirc.irc.IRCLowerTable[l]);
- }
- return p.join("");
- }
- qwebirc.irc.ASCIItoIRCLower = function(x) {
- return x.toLowerCase(); /* TODO: does unicode too.... */
- }
- String.prototype.hostToNick = function() {
- return this.split("!", 1)[0];
- }
- String.prototype.hostToHost = function() {
- return this.split("!", 2)[1];
- }
- qwebirc.irc.IRCTimestamp = function(d) {
- return "[" + qwebirc.util.pad(d.getHours()) + ":" + qwebirc.util.pad(d.getMinutes()) + "]";
- }
- qwebirc.irc.IRCDate = function(d) {
- var pad = qwebirc.util.pad;
- return qwebirc.util.DaysOfWeek[d.getDay()] + " " + qwebirc.util.MonthsOfYear[d.getMonth()] + " " + pad(d.getDate()) + " " + pad(d.getHours()) + ":" + pad(d.getMinutes()) + ":" + pad(d.getSeconds()) + " " + d.getFullYear();
- }
- qwebirc.irc.toIRCCompletion = function(session, data) {
- return session.irc.toIRCLower(data).replace(/[^\w]+/g, "");
- }
- qwebirc.irc.NickChanEntry = function() {
- this.prefixes = "";
- this.lastSpoke = 0;
- }
- qwebirc.irc.IRCTracker = new Class({
- initialize: function(owner) {
- this.channels = {};
- this.nicknames = {};
- this.owner = owner;
- },
- toIRCLower: function(value) {
- /* proxied because the method can change after we connect */
- return this.owner.toIRCLower(value);
- },
- isEmpty: function(hash) {
- for(var x in hash)
- return false;
- return true;
- },
- getNick: function(nick) {
- return this.nicknames[nick];
- },
- getOrCreateNick: function(nick) {
- var n = this.getNick(nick);
- if(!n)
- n = this.nicknames[nick] = {};
- return n;
- },
- getChannel: function(channel) {
- return this.channels[this.toIRCLower(channel)];
- },
- getOrCreateChannel: function(channel) {
- var c = this.getChannel(channel);
- if(!c)
- c = this.channels[this.toIRCLower(channel)] = {};
- return c;
- },
- getOrCreateNickOnChannel: function(nick, channel) {
- var n = this.getOrCreateNick(nick);
- var nc = n[this.toIRCLower(channel)];
- if(!nc)
- return this.addNickToChannel(nick, channel);
- return nc;
- },
- getNickOnChannel: function(nick, channel) {
- var n = this.getNick(nick);
- if(!n)
- return;
- return n[this.toIRCLower(channel)];
- },
- addNickToChannel: function(nick, channel) {
- var nc = new qwebirc.irc.NickChanEntry();
- var n = this.getOrCreateNick(nick);
- n[this.toIRCLower(channel)] = nc;
- var c = this.getOrCreateChannel(channel);
- c[nick] = nc;
- return nc;
- },
- removeNick: function(nick) {
- var n = this.getNick(nick);
- if(!n)
- return;
- for(var channel in n) {
- var lchannel = this.toIRCLower(channel);
- var c = this.channels[lchannel];
- delete c[nick];
- if(this.isEmpty(c))
- delete this.channels[lchannel];
- }
- delete this.nicknames[nick];
- },
- removeChannel: function(channel) {
- var c = this.getChannel(channel);
- if(!c)
- return;
- var lchannel = this.toIRCLower(channel);
- for(var nick in c) {
- var n = this.nicknames[nick];
- delete n[lchannel];
- if(this.isEmpty(n))
- delete this.nicknames[nick];
- }
- delete this.channels[lchannel];
- },
- removeNickFromChannel: function(nick, channel) {
- var lchannel = this.toIRCLower(channel);
- var n = this.getNick(nick);
- var c = this.getChannel(lchannel);
- if(!n || !c)
- return;
- delete n[lchannel];
- delete c[nick];
- if(this.isEmpty(n))
- delete this.nicknames[nick];
- if(this.isEmpty(c))
- delete this.channels[lchannel];
- },
- renameNick: function(oldnick, newnick) {
- var n = this.getNick(oldnick);
- if(!n)
- return;
- for(var channel in n) {
- var lchannel = this.toIRCLower(channel);
- this.channels[lchannel][newnick] = this.channels[lchannel][oldnick];
- delete this.channels[lchannel][oldnick];
- }
- this.nicknames[newnick] = this.nicknames[oldnick];
- delete this.nicknames[oldnick];
- },
- updateLastSpoke: function(nick, channel, time) {
- var nc = this.getNickOnChannel(nick, channel);
- if($defined(nc))
- nc.lastSpoke = time;
- },
- getSortedByLastSpoke: function(channel) {
- var sorter = function(a, b) {
- return b[1].lastSpoke - a[1].lastSpoke;
- };
- var c = this.getChannel(channel);
- if(!c)
- return;
- var n = [];
- for(var k in c)
- n.push([k, c[k]]);
- n.sort(sorter);
- var n2 = [];
- for(var i=0;i<n.length;i++)
- n2.push(n[i][0]);
- return n2;
- }
- });
- qwebirc.irc.Numerics = {
- "001": "RPL_WELCOME",
- "433": "ERR_NICKNAMEINUSE",
- "437": "ERR_UNAVAILRESOURCE",
- "004": "RPL_MYINFO",
- "005": "RPL_ISUPPORT",
- "353": "RPL_NAMREPLY",
- "366": "RPL_ENDOFNAMES",
- "331": "RPL_NOTOPIC",
- "332": "RPL_TOPIC",
- "333": "RPL_TOPICWHOTIME",
- "311": "RPL_WHOISUSER",
- "312": "RPL_WHOISSERVER",
- "313": "RPL_WHOISOPERATOR",
- "317": "RPL_WHOISIDLE",
- "671": "RPL_WHOISSECURE",
- "318": "RPL_ENDOFWHOIS",
- "319": "RPL_WHOISCHANNELS",
- "330": "RPL_WHOISACCOUNT",
- "338": "RPL_WHOISACTUALLY",
- "343": "RPL_WHOISOPERNAME",
- "320": "RPL_WHOISGENERICTEXT",
- "310": "RPL_WHOISAVAILHELP",
- "307": "RPL_WHOISREGGED",
- "378": "RPL_WHOISREALHOST",
- "379": "RPL_WHOISMODES",
- "325": "RPL_WHOISWEBIRC",
- "301": "RPL_AWAY",
- "401": "ERR_NOSUCHNICK",
- "404": "ERR_CANNOTSENDTOCHAN",
- "482": "ERR_CHANOPPRIVSNEEDED",
- "305": "RPL_UNAWAY",
- "306": "RPL_NOWAWAY",
- "324": "RPL_CHANNELMODEIS",
- "329": "RPL_CREATIONTIME"
- };
- /**
- * Provides handling of Atheme login state in the client interface.
- * Configures the client when the user changes between logged in and out, and
- * provides checks to determine whether which it is in.
- */
- qwebirc.ui.Atheme = {};
- /**
- * Handles an Atheme login.
- *
- * \param user The provided username.
- * \param token The user's given token.
- */
- qwebirc.ui.Atheme.handleLogin = function(session, user, token) {
- /* Update state. */
- session.atheme.state = true;
- session.atheme.user = user;
- session.atheme.secret = token;
- /* Save cookie. */
- cookie = new Hash.Cookie("iris-auth");
- cookie.set("user", session.atheme.user);
- cookie.set("token", session.atheme.secret);
- cookie.save();
- }
- /**
- * Handle an Atheme logout.
- */
- qwebirc.ui.Atheme.handleLogout = function() {
- /* Update state. */
- this.state = false;
- }
- /**
- * Check whether the user is currently logged in, and set the client up
- * accordingly.
- */
- qwebirc.ui.Atheme.check = function(session) {
- /* If we have a user and token, check them for validity. Otherwise,
- * we're definitely logged out. */
- if ($defined(session.atheme.user) && $defined(session.atheme.secret) &&
- conf.atheme.sasl_type == "AUTHCOOKIE") {
- qwebirc.irc.AthemeQuery.checkLogin(function(valid) {
- if (valid == null)
- session.atheme.state = null;
- else if (valid)
- this.handleLogin(session, session.atheme.user, session.atheme.secret);
- else
- this.handleLogout();
- }.bind(this), session.atheme.user, session.atheme.secret);
- }
- else
- this.handleLogout(session);
- }
- qwebirc.ui.WINDOW_STATUS = 0x01;
- qwebirc.ui.WINDOW_QUERY = 0x02;
- qwebirc.ui.WINDOW_CHANNEL = 0x04;
- qwebirc.ui.WINDOW_MESSAGES = 0x08;
- qwebirc.ui.WINDOW_CUSTOM = 0x10;
- qwebirc.ui.BaseUI = new Class({
- initialize: function(session, parentElement, windowClass, uiName) {
- this.session = session;
- this.parentElement = parentElement;
- this.windowClass = windowClass;
- this.windowArray = [];
- this.parentElement.addClass("qwebirc");
- this.parentElement.addClass("qwebirc-" + uiName);
- this.firstClient = false;
- this.commandhistory = new qwebirc.irc.CommandHistory();
- this.windowFocused = true;
- if(Browser.Engine.trident) {
- var checkFocus = function() {
- var hasFocus = document.hasFocus();
- if(hasFocus != this.windowFocused) {
- this.windowFocused = hasFocus;
- this.focusChange(hasFocus);
- }
- }
- checkFocus.periodical(100, this);
- } else {
- var blur = function() { if(this.windowFocused) { this.windowFocused = false; this.focusChange(false); } }.bind(this);
- var focus = function() { if(!this.windowFocused) { this.windowFocused = true; this.focusChange(true); } }.bind(this);
- /* firefox requires both */
- document.addEvent("blur", blur);
- window.addEvent("blur", blur);
- document.addEvent("focus", focus);
- window.addEvent("focus", focus);
- }
- this.postInitialize();
- },
- newClient: function() {
- var w = this.newWindow(qwebirc.ui.WINDOW_STATUS, "Status");
- this.selectWindow(w);
- if(!this.firstClient) {
- this.firstClient = true;
- w.addLine("", "qwebirc v" + qwebirc.VERSION);
- w.addLine("", "Copyright (C) 2008-2010 Chris Porter and the qwebirc project.");
- w.addLine("", "http://www.qwebirc.org");
- w.addLine("", "Licensed under the GNU General Public License, Version 2.");
- }
- return w;
- },
- getWindowIdentifier: function(type, name) {
- if(type == qwebirc.ui.WINDOW_MESSAGES)
- return "-M";
- if(type == qwebirc.ui.WINDOW_STATUS)
- return "";
- if(type == qwebirc.ui.WINDOW_CUSTOM)
- return "internal_" + qwebirc.irc.ASCIItoIRCLower(name);
- return "_" + this.session.irc.toIRCLower(name);
- },
- newWindow: function(type, name) {
- var w = this.getWindow(type, name);
- if($defined(w))
- return w;
- var wId = this.getWindowIdentifier(type, name);
- var w = this.session.windows[wId] = new this.windowClass(this.session, type, name, wId);
- this.windowArray.push(w);
- return w;
- },
- getWindow: function(type, name) {
- return this.session.windows[this.getWindowIdentifier(type, name)];
- },
- getActiveWindow: function() {
- return this.active;
- },
- getActiveIRCWindow: function() {
- if(!this.active || this.active.type == qwebirc.ui.WINDOW_CUSTOM) {
- return this.session.windows[this.getWindowIdentifier(qwebirc.ui.WINDOW_STATUS)];
- } else {
- return this.active;
- }
- },
- __setActiveWindow: function(window) {
- this.active = window;
- },
- selectWindow: function(window) {
- if(this.active)
- this.active.deselect();
- window.select(); /* calls setActiveWindow */
- this.updateTitle(window.name + " - " + conf.frontend.app_title);
- },
- updateTitle: function(text) {
- document.title = text;
- },
- nextWindow: function(direction) {
- if(this.windowArray.length == 0 || !this.active)
- return;
- if(!direction)
- direction = 1;
- var index = this.windowArray.indexOf(this.active);
- if(index == -1)
- return;
- index = index + direction;
- if(index < 0) {
- index = this.windowArray.length - 1;
- } else if(index >= this.windowArray.length) {
- index = 0;
- }
- this.selectWindow(this.windowArray[index]);
- },
- prevWindow: function() {
- this.nextWindow(-1);
- },
- /* Cleans up for an ALREADY REMOVED window. */
- closeWindow: function(window) {
- /* Window cleanup. */
- window.closed = true;
- if($defined(window.scrolltimer)) {
- $clear(window.scrolltimer);
- window.scrolltimer = null;
- }
- /* Transfer active window. */
- if(window.active) {
- this.active = undefined;
- if(this.windowArray.length == 1) {
- this.windowArray = [];
- } else {
- var index = this.windowArray.indexOf(window);
- if(index == -1) {
- return;
- } else if(index == 0) {
- this.selectWindow(this.windowArray[1]);
- } else {
- this.selectWindow(this.windowArray[index - 1]);
- }
- }
- }
- /* Delete records of the window. */
- delete window.session.windows[window.identifier];
- this.windowArray = this.windowArray.erase(window);
- },
- focusChange: function(newValue) {
- var window_ = this.getActiveWindow();
- if($defined(window_))
- window_.focusChange(newValue);
- }
- });
- qwebirc.ui.StandardUI = new Class({
- Extends: qwebirc.ui.BaseUI,
- initialize: function(session, parentElement, windowClass, uiName) {
- this.parent(session, parentElement, windowClass, uiName);
- this.tabCompleter = new qwebirc.ui.TabCompleterFactory(this);
- var ev;
- if(Browser.Engine.trident) {
- ev = "keydown";
- } else {
- ev = "keypress";
- }
- document.addEvent(ev, this.__handleHotkey.bind(this));
- },
- __handleHotkey: function(x) {
- if(!x.alt || x.control) {
- if(x.key == "backspace" || x.key == "/")
- if(!this.getInputFocused(x))
- new Event(x).stop();
- return;
- }
- var success = false;
- if(x.key == "a" || x.key == "A") {
- var highestNum = 0;
- var highestIndex = -1;
- success = true;
- new Event(x).stop();
- for(var i=0;i<this.windowArray.length;i++) {
- var h = this.windowArray[i].hilighted;
- if(h > highestNum) {
- highestIndex = i;
- highestNum = h;
- }
- }
- if(highestIndex > -1)
- this.selectWindow(this.windowArray[highestIndex]);
- } else if(x.key >= '0' && x.key <= '9') {
- success = true;
- number = x.key - '0';
- if(number == 0)
- number = 10
- number = number - 1;
- if(number >= this.windowArray.length)
- return;
- this.selectWindow(this.windowArray[number]);
- } else if(x.key == "left") {
- this.prevWindow();
- success = true;
- } else if(x.key == "right") {
- this.nextWindow();
- success = true;
- }
- if(success)
- new Event(x).stop();
- },
- getInputFocused: function(x) {
- if($$("input").indexOf(x.target) == -1 && $$("textarea").indexOf(x.target) == -1)
- return false;
- return true;
- },
- newCustomWindow: function(name, select, type) {
- if(!type)
- type = qwebirc.ui.WINDOW_CUSTOM;
- var w = this.newWindow(type, name);
- if(select)
- this.selectWindow(w);
- return w;
- },
- addPane: function(name) {
- var title = qwebirc.ui.Panes[name].title;
- var id = this.getWindowIdentifier(qwebirc.ui.WINDOW_CUSTOM, title)
- if(this.session.windows[id]) {
- this.selectWindow(this.session.windows[id]);
- return;
- }
- var d = this.newCustomWindow(title, true);
- d.lines.addClass("qwebirc-pane" + name);
- var ew = new qwebirc.ui.Panes[name].pclass(this.session, d);
- d.setSubWindow(ew);
- return d;
- },
- connectWindow: function(callbackfn) {
- var pane = qwebirc.ui.Panes.Connect;
- var w = this.addPane("Connect");
- w.subWindow.connectCallback = function(args) {
- ui.closeWindow(w);
- callbackfn(args);
- };
- },
- urlDispatcher: function(name) {
- if(name == "embedded")
- return ["a", this.embeddedWindow.bind(this)];
- if(name == "options")
- return ["a", this.optionsWindow.bind(this)];
- /* doesn't really belong here */
- if(name == "whois") {
- return ["span", function(nick) {
- if (conf.ui.nick_click_query)
- this.session.irc.exec("/QUERY " + nick);
- else
- this.session.irc.exec("/WHOIS " + nick);
- }.bind(this)];
- }
- if(name == "accinfo") {
- return ["span", function(account) {
- this.session.irc.exec("/MSG NickServ INFO " + account);
- }.bind(this)];
- }
- return null;
- },
- tabComplete: function(element) {
- this.tabCompleter.tabComplete(element);
- },
- resetTabComplete: function() {
- this.tabCompleter.reset();
- },
- setModifiableStylesheet: function(name) {
- this.__styleSheet = new qwebirc.ui.style.ModifiableStylesheet(conf.frontend.static_base_url + "css/" + name + qwebirc.FILE_SUFFIX + ".mcss");
- this.setModifiableStylesheetValues(conf.ui.fg_color, conf.ui.fg_sec_color, conf.ui.bg_color);
- },
- setModifiableStylesheetValues: function(fg_color, fg_sec_color, bg_color) {
- var fg = new Color(fg_color);
- var fg_sec = new Color(fg_sec_color);
- var bg = new Color(bg_color);
- var multiplier = 1;
- if (fg.hsb[2] > bg.hsb[2])
- multiplier = -1;
- if(!$defined(this.__styleSheet))
- return;
- this.__styleSheet.set(
- function(x) {
- return x.setHue(-180 + x.hsb[0] + fg.hsb[0]).setSaturation(fg.hsb[1] + (x.hsb[1]-50)*multiplier).setBrightness(fg.hsb[2] + (x.hsb[2]-50)*multiplier);
- },
- function(x) {
- return x.setHue(-180 + x.hsb[0] + fg_sec.hsb[0]).setSaturation(fg_sec.hsb[1] + (x.hsb[1]-50)*multiplier).setBrightness(fg_sec.hsb[2] + (x.hsb[2]-50)*multiplier);
- },
- function(x) {
- return x.setHue(-180 + x.hsb[0] + bg.hsb[0]).setSaturation(bg.hsb[1] + (x.hsb[1]-50)*multiplier).setBrightness(bg.hsb[2] + (x.hsb[2]-50)*multiplier);
- }
- );
- }
- });
- qwebirc.ui.NotificationUI = new Class({
- Extends: qwebirc.ui.StandardUI,
- initialize: function(session, parentElement, windowClass, uiName) {
- this.parent(session, parentElement, windowClass, uiName);
- this.__beeper = new qwebirc.ui.Beeper(session);
- this.__flasher = new qwebirc.ui.Flasher(session);
- this.beep = this.__beeper.beep.bind(this.__beeper);
- this.flash = this.__flasher.flash.bind(this.__flasher);
- this.cancelFlash = this.__flasher.cancelFlash.bind(this.__flasher);
- },
- setBeepOnMention: function(value) {
- if(value)
- this.__beeper.soundInit();
- },
- updateTitle: function(text) {
- if(this.__flasher.updateTitle(text))
- this.parent(text);
- },
- focusChange: function(value) {
- this.parent(value);
- this.__flasher.focusChange(value);
- }
- });
- qwebirc.ui.RootUI = qwebirc.ui.NotificationUI;
- qwebirc.ui.RequestTransformHTML = function(session, options) {
- var HREF_ELEMENTS = {
- "IMG": 1
- };
- var update = options.update;
- var onSuccess = options.onSuccess;
- var fixUp = function(node) {
- if(node.nodeType != 1)
- return;
- var tagName = node.nodeName.toUpperCase();
- if(HREF_ELEMENTS[tagName]) {
- var attr = node.getAttribute("transform_attr");
- var value = node.getAttribute("transform_value");
- if($defined(attr) && $defined(value)) {
- node.removeAttribute("transform_attr");
- node.removeAttribute("transform_value");
- node.setAttribute(attr, conf.frontend.static_base_url + value);
- }
- }
- for(var i=0;i<node.childNodes.length;i++)
- fixUp(node.childNodes[i]);
- };
- delete options["update"];
- options.onSuccess = function(tree, elements, html, js) {
- var container = new Element("div");
- container.set("html", html);
- fixUp(container);
- update.empty();
- while(container.childNodes.length > 0) {
- var x = container.firstChild;
- container.removeChild(x);
- update.appendChild(x);
- }
- onSuccess();
- };
- return new Request.HTML(options);
- };
- qwebirc.ui.HILIGHT_NONE = 0;
- qwebirc.ui.HILIGHT_ACTIVITY = 1;
- qwebirc.ui.HILIGHT_SPEECH = 2;
- qwebirc.ui.HILIGHT_US = 3;
- qwebirc.ui.WINDOW_LASTLINE = qwebirc.ui.WINDOW_QUERY | qwebirc.ui.WINDOW_MESSAGES | qwebirc.ui.WINDOW_CHANNEL | qwebirc.ui.WINDOW_STATUS;
- qwebirc.ui.Window = new Class({
- Implements: [Events],
- initialize: function(session, type, name, identifier) {
- this.session = session;
- this.type = type;
- this.name = name;
- this.active = false;
- this.identifier = identifier;
- this.hilighted = qwebirc.ui.HILIGHT_NONE;
- this.scrolltimer = null;
- this.commandhistory = ui.commandhistory;
- this.scrolleddown = true;
- this.scrollpos = null;
- this.lastNickHash = {};
- this.lastSelected = null;
- this.subWindow = null;
- this.closed = false;
- if(this.type & qwebirc.ui.WINDOW_LASTLINE) {
- this.lastPositionLine = new Element("hr");
- this.lastPositionLine.addClass("lastpos");
- this.lastPositionLineInserted = false;
- }
- },
- updateTopic: function(topic, element) {
- qwebirc.ui.Colourise(this.session, "[" + topic + "]", element);
- },
- subEvent: function(event) {
- if($defined(this.subWindow))
- this.subWindow.fireEvent(event);
- },
- setSubWindow: function(window) {
- this.subWindow = window;
- },
- select: function() {
- if(this.lastPositionLineInserted && !conf.ui.lastpos_line) {
- this.lines.removeChild(this.lastPositionLine);
- this.lastPositionLineInserted = false;
- }
- this.active = true;
- ui.__setActiveWindow(this);
- if(this.hilighted)
- this.setHilighted(qwebirc.ui.HILIGHT_NONE);
- this.subEvent("select");
- this.resetScrollPos();
- this.lastSelected = new Date();
- },
- deselect: function() {
- this.subEvent("deselect");
- this.setScrollPos();
- if($defined(this.scrolltimer)) {
- $clear(this.scrolltimer);
- this.scrolltimer = null;
- }
- if(this.type & qwebirc.ui.WINDOW_LASTLINE)
- this.replaceLastPositionLine();
- this.active = false;
- },
- resetScrollPos: function() {
- if(this.scrolleddown) {
- this.scrollToBottom();
- } else if($defined(this.scrollpos)) {
- this.getScrollParent().scrollTo(this.scrollpos.x, this.scrollpos.y);
- }
- },
- setScrollPos: function() {
- if(!ui.singleWindow) {
- this.scrolleddown = this.scrolledDown();
- this.scrollpos = this.lines.getScroll();
- }
- },
- addLine: function(type, line, colour, element) {
- var hilight = qwebirc.ui.HILIGHT_NONE;
- var lhilight = false;
- if(type) {
- hilight = qwebirc.ui.HILIGHT_ACTIVITY;
- if(type.match(/(NOTICE|ACTION|MSG)$/)) {
- if(this.type == qwebirc.ui.WINDOW_QUERY || this.type == qwebirc.ui.WINDOW_MESSAGES) {
- if(type.match(/^OUR/) || type.match(/NOTICE$/)) {
- hilight = qwebirc.ui.HILIGHT_ACTIVITY;
- } else {
- hilight = qwebirc.ui.HILIGHT_US;
- ui.beep();
- ui.flash();
- }
- }
- if(!type.match(/^OUR/) && this.session.irc.hilightController.match(line["m"])) {
- lhilight = true;
- hilight = qwebirc.ui.HILIGHT_US;
- ui.beep();
- ui.flash();
- } else if(hilight != qwebirc.ui.HILIGHT_US) {
- hilight = qwebirc.ui.HILIGHT_SPEECH;
- }
- }
- }
- if(!this.active && (hilight != qwebirc.ui.HILIGHT_NONE))
- this.setHilighted(hilight);
- if(type)
- line = ui.theme.message(type, line, lhilight);
- qwebirc.ui.Colourise(this.session, qwebirc.irc.IRCTimestamp(new Date()) + " " + line, element);
- this.scrollAdd(element);
- },
- errorMessage: function(message) {
- this.addLine("", message, "warncolour");
- },
- infoMessage: function(message) {
- this.addLine("", message, "infocolour");
- },
- setHilighted: function(state) {
- if(state == qwebirc.ui.HILIGHT_NONE || state >= this.hilighted)
- this.hilighted = state;
- },
- scrolledDown: function() {
- if(this.scrolltimer)
- return true;
- var parent = this.lines;
- var prev = parent.getScroll();
- var prevbottom = parent.getScrollSize().y;
- var prevheight = parent.clientHeight;
- /*
- * fixes an IE bug: the scrollheight is less than the actual height
- * when the div isn't full
- */
- if(prevbottom < prevheight)
- prevbottom = prevheight;
- return prev.y + prevheight == prevbottom;
- },
- getScrollParent: function() {
- var scrollparent = this.lines;
- if($defined(this.scroller))
- scrollparent = this.scroller;
- return scrollparent;
- },
- scrollToBottom: function() {
- if(this.type == qwebirc.ui.WINDOW_CUSTOM)
- return;
- var parent = this.lines;
- var scrollparent = this.getScrollParent();
- scrollparent.scrollTo(parent.getScroll().x, parent.getScrollSize().y);
- },
- scrollAdd: function(element) {
- var parent = this.lines;
- /* scroll in bursts, else the browser gets really slow */
- if($defined(element)) {
- var sd = this.scrolledDown();
- parent.appendChild(element);
- if(sd) {
- if(this.scrolltimer)
- $clear(this.scrolltimer);
- this.scrolltimer = this.scrollAdd.delay(50, this, [null]);
- }
- } else {
- this.scrollToBottom();
- this.scrolltimer = null;
- }
- },
- updateNickList: function(nicks) {
- var nickHash = {}, present = {};
- var added = [];
- var lnh = this.lastNickHash;
- for(var i=0;i<nicks.length;i++)
- present[nicks[i]] = 1;
- for(var k in lnh)
- if(!present[k])
- this.nickListRemove(k, lnh[k]);
- for(var i=0;i<nicks.length;i++) {
- var n = nicks[i];
- var l = lnh[n];
- if(!l) {
- l = this.nickListAdd(n, i);
- if(!l)
- l = 1;
- }
- nickHash[n] = l;
- }
- this.lastNickHash = nickHash;
- },
- nickListAdd: function(nick, position) {
- },
- nickListRemove: function(nick, stored) {
- },
- historyExec: function(line) {
- this.commandhistory.addLine(line);
- this.session.irc.exec(line);
- },
- focusChange: function(newValue) {
- if(newValue == true || !(this.type & qwebirc.ui.WINDOW_LASTLINE))
- return;
- this.replaceLastPositionLine();
- },
- replaceLastPositionLine: function() {
- if(conf.ui.lastpos_line) {
- if(!this.lastPositionLineInserted) {
- this.scrollAdd(this.lastPositionLine);
- } else if(this.lines.lastChild != this.lastPositionLine) {
- try {
- this.lines.removeChild(this.lastPositionLine);
- } catch(e) {
- /* IGNORE, /clear removes lastPositionLine from the dom without resetting it. */
- }
- this.scrollAdd(this.lastPositionLine);
- }
- } else {
- if(this.lastPositionLineInserted)
- this.lines.removeChild(this.lastPositionLine);
- }
- this.lastPositionLineInserted = conf.ui.lastpos_line;
- }
- });
- qwebirc.ui.Colourise = function(session, line, entity) {
- var fg;
- var bg;
- var underline = false;
- var bold = false;
- var autoNickColour = false;
- var out = [];
- var xline = line.split("");
- var element = document.createElement("span");
- entity.addClass("colourline");
- function isNum(x) {
- return x >= '0' && x <= '9';
- }
- function parseColours(xline, i) {
- if(!isNum(xline[i + 1])) {
- fg = undefined;
- bg = undefined;
- return i;
- }
- i++;
- if(isNum(xline[i + 1])) {
- fg = parseInt(xline[i] + xline[i + 1]);
- i++;
- } else {
- fg = parseInt(xline[i]);
- }
- if(xline[i + 1] != ",")
- return i;
- if(!isNum(xline[i + 2]))
- return i;
- i+=2;
- if(isNum(xline[i + 1])) {
- bg = parseInt(xline[i] + xline[i + 1]);
- i++;
- } else {
- bg = parseInt(xline[i]);
- }
- return i;
- }
- function emitEndToken() {
- var data = "";
- if(out.length > 0) {
- var data = qwebirc.ui.urlificate(session, element, out.join(""));
- entity.appendChild(element);
- out = [];
- }
- element = document.createElement("span");
- return data;
- }
- function emitStartToken() {
- if(autoNickColour)
- return element;
- var classes = []
- if(fg != undefined)
- classes.push("Xc" + fg);
- if(bg != undefined)
- classes.push("Xbc" + bg);
- if(bold)
- classes.push("Xb");
- if(underline)
- classes.push("Xu");
- element.className = classes.join(" ");
- }
- var nickColouring = conf.ui.nick_colors;
- var capturingNick = false;
- for(var i=0;i<xline.length;i++) {
- var lc = xline[i];
- if(nickColouring) {
- if(!capturingNick) {
- if(lc == "\x00") {
- capturingNick = true;
- emitEndToken();
- continue;
- }
- } else {
- if(lc != "\x00") {
- out.push(lc);
- } else {
- autoNickColour = true;
- var e = emitStartToken();
- var text = emitEndToken();
- var c = text.toHSBColour(session);
- if($defined(c))
- e.style.color = c.rgbToHex();
- capturingNick = autoNickColour = false;
- }
- continue;
- }
- } else if(lc == "\x00") {
- continue;
- }
- if(lc == "\x02") {
- emitEndToken();
- bold = !bold;
- emitStartToken();
- } else if(lc == "\x1F") {
- emitEndToken();
- underline = !underline;
- emitStartToken();
- } else if(lc == "\x0F") {
- emitEndToken();
- fg = undefined;
- bg = undefined;
- underline = false;
- bold = false;
- } else if(lc == "\x03") {
- emitEndToken();
- i = parseColours(xline, i);
- if(bg > 15)
- bg = undefined;
- if(fg > 15)
- fg = undefined;
- emitStartToken();
- } else {
- out.push(lc);
- }
- }
- emitEndToken();
- }
- String.prototype.toHSBColour = function(session) {
- var lower = session.irc.toIRCLower(session.irc.stripPrefix(this));
- if(lower == session.irc.lowerNickname)
- return null;
- var hash = 0;
- for(var i=0;i<lower.length;i++)
- hash = 31 * hash + lower.charCodeAt(i);
- var hue = Math.abs(hash) % 360;
- return new Color([hue, 70, 60], "hsb");
- }
- /* Create the client UI. */
- qwebirc.ui.create = function(element, uiclass) {
- /* Initialise our Atheme login and single session. */
- session = new qwebirc.session();
- /* Now wait until all the JS is loaded. */
- window.addEvent("domready", function() {
- /* Define login function. */
- var callback = function(connOptions) {
- session.irc = new qwebirc.irc.IRCClient(session, connOptions);
- session.irc.connect();
- window.onbeforeunload = qwebirc.ui.onbeforeunload;
- window.addEvent("unload", function() {
- session.irc.quit("Web client closed");
- });
- };
- /* Create UI. */
- ui = new uiclass(this.session, $(element));
- /* Create login window. */
- ui.connectWindow(callback);
- /* If enabled, open channel list. */
- if (conf.atheme.chan_list_on_start) {
- if (qwebirc.ui.Panes.List)
- ui.addPane("List");
- }
- });
- };
- /* Displays a warning if the user tries to close their browser. */
- qwebirc.ui.onbeforeunload = function(e) { /* IE sucks */
- if (qwebirc.connected) {
- var message = "This action will close all active IRC connections.";
- var e = e || window.event;
- if(e)
- e.returnValue = message;
- return message;
- }
- };
- qwebirc.ui.MENU_ITEMS = function() {
- var maybeOpped = function(nick) {
- var channel = this.name; /* window name */
- var myNick = this.session.irc.nickname;
- return this.session.irc.nickOnChanHasAtLeastPrefix(myNick, channel, "+", true);
- };
- var isOpped = function(nick) {
- var channel = this.name; /* window name */
- var myNick = this.session.irc.nickname;
- return this.session.irc.nickOnChanHasAtLeastPrefix(myNick, channel, "@", false);
- };
- var isVoiced = function(nick) {
- var channel = this.name;
- var myNick = this.session.irc.nickname;
- return this.session.irc.nickOnChanHasPrefix(myNick, channel, "+");
- };
- var targetOpped = function(nick) {
- var channel = this.name;
- return this.session.irc.nickOnChanHasPrefix(nick, channel, "@");
- };
- var targetVoiced = function(nick) {
- var channel = this.name;
- return this.session.irc.nickOnChanHasPrefix(nick, channel, "+");
- };
- var invert = qwebirc.util.invertFn, compose = qwebirc.util.composeAnd;
- var command = function(cmd) {
- return function(nick) { this.session.irc.exec("/" + cmd + " " + nick); };
- };
- return [
- {
- text: "PM",
- fn: command("query"),
- predicate: true
- },
- {
- text: "whois",
- fn: command("whois"),
- predicate: true
- },
- {
- text: "kick", /* TODO: disappear when we're deopped */
- fn: function(nick) { this.session.irc.exec("/KICK " + nick + " wibble"); },
- predicate: maybeOpped
- },
- {
- text: "op",
- fn: command("op"),
- predicate: compose(isOpped, invert(targetOpped))
- },
- {
- text: "deop",
- fn: command("deop"),
- predicate: compose(isOpped, targetOpped)
- },
- {
- text: "voice",
- fn: command("voice"),
- predicate: compose(maybeOpped, invert(targetVoiced))
- },
- {
- text: "devoice",
- fn: command("devoice"),
- predicate: compose(maybeOpped, targetVoiced)
- }
- ];
- };
- qwebirc.ui.HilightController = new Class({
- initialize: function(session) {
- this.session = session;
- this.regex = null;
- this.prevnick = null;
- },
- match: function(text) {
- var nick = this.session.irc.nickname;
- if(nick != this.prevnick) {
- var classes = '[\\s\\.,;:]';
- this.regex = new RegExp('(^|' + classes + ')' + RegExp.escape(nick) + '(' + classes + '|$)', "i");
- }
- if(text.match(this.regex))
- return true;
- return false;
- }
- });
- qwebirc.ui.Beeper = new Class({
- initialize: function(session) {
- this.session = session;
- this.soundInited = false;
- this.soundReady = false;
- if(conf.ui.beep_on_mention)
- this.soundInit();
- },
- soundInit: function() {
- if(this.soundInited)
- return;
- if(!$defined(Browser.Plugins.Flash) || Browser.Plugins.Flash.version < 8)
- return;
- this.soundInited = true;
- this.soundPlayer = new qwebirc.sound.SoundPlayer(this.session);
- this.soundPlayer.addEvent("ready", function() {
- this.soundReady = true;
- }.bind(this));
- this.soundPlayer.go();
- },
- beep: function() {
- if(!this.soundReady || !conf.ui.beep_on_mention)
- return;
- this.soundPlayer.beep();
- }
- });
- qwebirc.ui.Flasher = new Class({
- initialize: function(session) {
- this.session = session;
- this.windowFocused = false;
- this.canUpdateTitle = true;
- this.titleText = document.title;
- var favIcon = this._getFavIcon();
- if($defined(favIcon)) {
- this.favIcon = favIcon;
- this.favIconParent = favIcon.parentNode;
- this.favIconVisible = true;
- this.emptyFavIcon = new Element("link");
- this.emptyFavIcon.rel = "shortcut icon";
- this.emptyFavIcon.href = conf.frontend.static_base_url + "images/empty_favicon.ico";
- this.emptyFavIcon.type = "image/x-icon";
- this.flashing = false;
- this.canFlash = true;
- document.addEvent("mousedown", this.cancelFlash.bind(this));
- document.addEvent("keydown", this.cancelFlash.bind(this));
- } else {
- this.canFlash = false;
- }
- },
- _getFavIcon: function() {
- var favIcons = $$("head link");
- for(var i=0;i<favIcons.length;i++)
- if(favIcons[i].getAttribute("rel") == "shortcut icon")
- return favIcons[i];
- },
- flash: function() {
- if(!conf.ui.flash_on_mention || this.windowFocused || !this.canFlash || this.flashing)
- return;
- this.titleText = document.title; /* just in case */
- var flashA = function() {
- this.hideFavIcon();
- this.canUpdateTitle = false;
- document.title = "Activity!";
- this.flasher = flashB.delay(500);
- }.bind(this);
- var flashB = function() {
- this.showFavIcon();
- this.canUpdateTitle = true;
- document.title = this.titleText;
- this.flasher = flashA.delay(500);
- }.bind(this);
- this.flashing = true;
- flashA();
- },
- cancelFlash: function() {
- if(!this.canFlash || !$defined(this.flasher))
- return;
- this.flashing = false;
- $clear(this.flasher);
- this.flasher = null;
- this.showFavIcon();
- document.title = this.titleText;
- this.canUpdateTitle = true;
- },
- hideFavIcon: function() {
- if(this.favIconVisible) {
- /* only seems to work in firefox */
- this.favIconVisible = false;
- this.favIconParent.removeChild(this.favIcon);
- this.favIconParent.appendChild(this.emptyFavIcon);
- }
- },
- showFavIcon: function() {
- if(!this.favIconVisible) {
- this.favIconVisible = true;
- this.favIconParent.removeChild(this.emptyFavIcon);
- this.favIconParent.appendChild(this.favIcon);
- }
- },
- updateTitle: function(text) {
- this.titleText = text;
- return this.canUpdateTitle;
- },
- focusChange: function(value) {
- this.windowFocused = value;
- if(value)
- this.cancelFlash();
- }
- });
- qwebirc.ui.supportsFocus = function(session) {
- var ua = navigator.userAgent;
- if(!$defined(ua))
- return true;
- if(Browser.Engine.ipod || ua.indexOf("Konqueror") != -1)
- return false;
- return true;
- }
- qwebirc.options.Input = new Class({
- initialize: function(session, options, parent, option, position) {
- this.session = session;
- this.options = options;
- this.option = option;
- this.value = conf[option.category][option.option];
- this.enabled = true;
- this.position = position;
- this.parentElement = parent;
- this.id = qwebirc.util.generateID();
- if ($defined(this.option.isEnabled))
- this.enabled = this.option.isEnabled(session);
- this.render();
- },
- createInput: function(type, parent, name, selected) {
- if(!$defined(parent))
- parent = this.parentElement;
- return qwebirc.util.createInput(type, parent, name, selected, this.id);
- },
- FE: function(element, parent) {
- var n = new Element(element);
- if(!$defined(parent))
- parent = this.parentElement;
- parent.appendChild(n);
- return n;
- },
- focus: function() {
- this.mainElement.focus();
- },
- onChange: function() {
- if ($defined(this.option.onChange))
- this.option.onChange(this.session, this.options, this.get());
- }
- });
- qwebirc.options.TextInput = new Class({
- Extends: qwebirc.options.Input,
- render: function() {
- var i = this.createInput("text");
- i.addEvent("change", function(value) {
- this.value = value;
- this.onChange();
- }.bind(this));
- this.mainElement = i;
- i.value = this.value;
- i.disabled = !this.enabled;
- },
- get: function() {
- return this.mainElement.value;
- }
- });
- qwebirc.options.ColorInput = new Class({
- Extends: qwebirc.options.Input,
- render: function() {
- this.hexbox = null;
- if (this.value[0] != "#")
- this.value = "#" + this.value;
- var hue = new Element("div");
- hue.addClass("qwebirc-optionspane");
- hue.addClass("hue-slider");
- this.parentElement.appendChild(hue);
- var sat = new Element("div");
- sat.addClass("qwebirc-optionspane");
- sat.addClass("sat-slider");
- var light = new Element("div");
- light.addClass("qwebirc-optionspane");
- light.addClass("light-slider");
- var hexform = new Element("form", {"class": "hexform"});
- this.hexbox = new Element("input", {value: this.value});
- hexform.appendChild(this.hexbox);
- var reset = new Element("input", {type: "button", value: "Reset to Default"});
- if (!conf.ui.simple_color) {
- this.parentElement.appendChild(sat);
- this.parentElement.appendChild(light);
- this.parentElement.appendChild(hexform);
- this.parentElement.appendChild(reset);
- }
- var color = new Color(this.value);
- var k = new Element("div");
- k.addClass("knob");
- if(Browser.Engine.trident) {
- k.setStyle("top", "0px");
- k.setStyle("background-color", "black");
- }
- hue.appendChild(k);
- var hue_slider = new Slider(hue, k, {steps: 36, range: [0, 369], wheel: true});
- hue_slider.set(color.hsb[0]);
- k = new Element("div");
- k.addClass("knob");
- if(Browser.Engine.trident) {
- k.setStyle("top", "0px");
- k.setStyle("background-color", "black");
- }
- sat.appendChild(k);
- var sat_slider = new Slider(sat, k, {steps: 50, range: [0, 100], wheel: true});
- sat_slider.set(color.hsb[1]);
- k = new Element("div");
- k.addClass("knob");
- if(Browser.Engine.trident) {
- k.setStyle("top", "0px");
- k.setStyle("background-color", "black");
- }
- light.appendChild(k);
- var light_slider = new Slider(light, k, {steps: 50, range: [0, 100], wheel: true});
- light_slider.set(color.hsb[2]);
- var change_func = function(step) {
- var newcolor = $HSB(hue_slider.step, sat_slider.step, light_slider.step);
- this.value = newcolor.rgb.rgbToHex();
- this.onChange();
- }.bind(this);
- if (this.enabled) {
- hue_slider.addEvent("change", change_func);
- sat_slider.addEvent("change", change_func);
- light_slider.addEvent("change", change_func);
- hexform.addEvent("submit", function(e) {
- (new Event(e)).stop();
- var color = new Color(this.hexbox.value)
- hue_slider.set(color.hsb[0]);
- sat_slider.set(color.hsb[1]);
- light_slider.set(color.hsb[2]);
- }.bind(this));
- reset.addEvent("click", function(e) {
- (new Event(e)).stop();
- this.value = conf[this.option.category][this.option.option + "_default"];
- var color = new Color(this.value)
- hue_slider.set(color.hsb[0]);
- sat_slider.set(color.hsb[1]);
- light_slider.set(color.hsb[2]);
- }.bind(this));
- }
- this.mainElement = hue;
- this.startValue = this.value;
- },
- onChange: function() {
- this.hexbox.value = this.get();
- if ($defined(this.option.onChange))
- this.option.onChange(this.session, this.options, this.get());
- },
- get: function() {
- return this.value;
- },
- cancel: function() {
- this.value = this.startValue;
- this.get();
- }
- });
- qwebirc.options.CheckInput = new Class({
- Extends: qwebirc.options.Input,
- render: function() {
- var i = this.createInput("checkbox");
- i.addEvent("change", function(value) {
- this.value = value;
- this.onChange();
- }.bind(this));
- this.mainElement = i;
- i.checked = this.value;
- i.disabled = !this.enabled;
- },
- get: function() {
- return this.mainElement.checked;
- }
- });
- qwebirc.options.RadioInput = new Class({
- Extends: qwebirc.options.Input,
- render: function() {
- var value = this.option.options;
- this.elements = [];
- for(var i=0;i<value.length;i++) {
- var d = this.FE("div");
- var e = this.createInput("radio", d, "options_radio" + this.position, i == this.option.position);
- this.elements.push(e);
- e.disabled = !this.enabled;
- var ePosition = i;
- e.addEvent("change", function(value) {
- if (value) {
- this.option.position = ePosition;
- this.onChange();
- }
- }.bind(this));
- if(i == 0)
- this.mainElement = e;
- d.appendChild(document.createTextNode(value[i][0]));
- };
- },
- get: function() {
- for(var i=0;i<this.elements.length;i++) {
- var x = this.elements[i];
- if(x.checked) {
- this.option.position = i;
- return this.option.options[i][1];
- }
- }
- }
- });
- qwebirc.options.Options = [
- {
- category: "ui",
- option: "beep_on_mention",
- label: "Beep when nick mentioned or on query activity (requires Flash)",
- isEnabled: function (session) {
- if(!$defined(Browser.Plugins.Flash) || Browser.Plugins.Flash.version < 8)
- return false;
- return true;
- },
- onSave: function(session) {
- if (ui.updateBeepOnMention)
- ui.updateBeepOnMention();
- }
- },
- {
- category: "ui",
- option: "dedicated_msg_window",
- label: "Send privmsgs to dedicated messages window"
- },
- {
- category: "ui",
- option: "dedicated_notice_window",
- label: "Send notices to dedicated message window"
- },
- {
- category: "ui",
- option: "flash_on_mention",
- label: "Flash titlebar when nick mentioned or on query activity",
- isEnabled: qwebirc.ui.supportsFocus
- },
- {
- category: "ui",
- option: "lastpos_line",
- label: "Show a last position indicator for each window",
- isEnabled: qwebirc.ui.supportsFocus
- },
- {
- category: "ui",
- option: "nick_colors",
- label: "Automatically colour nicknames"
- },
- {
- category: "ui",
- option: "nick_status",
- label: "Show status symbol before nicknames in channel lines"
- },
- {
- category: "ui",
- option: "nick_click_query",
- label: "Open a PM window on clicking a nickname in channel"
- },
- {
- category: "ui",
- option: "hide_joinparts",
- label: "Hide JOINS/PARTS/QUITS"
- },
- {
- category: "ui",
- option: "fg_color",
- type: qwebirc.options.ColorInput,
- label: "Adjust main foreground color",
- onChange: function (session, options, value) {
- ui.setModifiableStylesheetValues(value, options["ui.fg_sec_color"].get(), options["ui.bg_color"].get());
- },
- isEnabled: function (session) {
- return !conf.ui.simple_color;
- }
- },
- {
- category: "ui",
- option: "fg_sec_color",
- type: qwebirc.options.ColorInput,
- label: "Adjust title/link foreground color",
- onChange: function (session, options, value) {
- ui.setModifiableStylesheetValues(options["ui.fg_color"].get(), value, options["ui.bg_color"].get());
- },
- isEnabled: function (session) {
- return !conf.ui.simple_color;
- }
- },
- {
- category: "ui",
- option: "bg_color",
- type: qwebirc.options.ColorInput,
- label: "Adjust background color",
- onChange: function (session, options, value) {
- if ($defined(options["ui.fg_color"]))
- ui.setModifiableStylesheetValues(options["ui.fg_color"].get(), options["ui.fg_sec_color"].get(), value);
- else
- ui.setModifiableStylesheetValues(conf.ui.fg_color, conf.ui.fg_sec_color, value);
- },
- onSave: function (session) {
- ui.setModifiableStylesheetValues(conf.ui.fg_color, conf.ui.fg_sec_color, conf.ui.bg_color);
- },
- onCancel: function (session) {
- ui.setModifiableStylesheetValues(conf.ui.fg_color, conf.ui.fg_sec_color, conf.ui.bg_color);
- }
- }
- ];
- // Panes add themselves to this.
- qwebirc.ui.Panes = {}
- qwebirc.ui.style.ModifiableStylesheet = new Class({
- initialize: function(url) {
- var n = this.__parseStylesheet(this.__getStylesheet(url));
- this.__cssText = n.cssText;
- this.rules = n.rules;
- this.__tag = this.__createTag();
- },
- __createTag: function() {
- var tag = document.createElement("style");
- tag.type = "text/css";
- tag.media = "all";
- document.getElementsByTagName("head")[0].appendChild(tag);
- return tag;
- },
- __getStylesheet: function(url) {
- var r = new Request({url: url, async: false});
- var result;
- r.addEvent("complete", function(x) {
- result = x;
- });
- r.get();
- return result;
- },
- __setStylesheet: function(stylesheet) {
- var node = this.__tag;
- if(node.styleSheet) { /* IE */
- node.styleSheet.cssText = stylesheet;
- } else {
- var d = document.createTextNode(stylesheet);
- node.appendChild(d);
- while(node.childNodes.length > 1)
- node.removeChild(node.firstChild);
- }
- },
- __parseStylesheet: function(data) {
- var lines = data.replace("\r\n", "\n").split("\n");
- var rules = {};
- var i;
- for(i=0;i<lines.length;i++) {
- var line = lines[i];
- if(line.trim() === "")
- break;
- var tokens = line.splitMax("=", 2);
- if(tokens.length != 2)
- continue;
- rules[tokens[0]] = tokens[1];
- }
- var cssLines = []
- for(;i<lines.length;i++)
- cssLines.push(lines[i]);
- return {cssText: cssLines.join("\n"), rules: rules};
- },
- set: function(fg_mutator, fg_sec_mutator, bg_mutator) {
- if(!fg_mutator)
- fg_mutator = function(x) { return x; };
- if(!fg_sec_mutator)
- fg_sec_mutator = fg_mutator;
- if(!bg_mutator)
- bg_mutator = function(x) { return x; };
- var text = this.__cssText;
- for(var key in this.rules) {
- var value;
- if (key.substring(7, 0) == "fg_sec_")
- value = fg_sec_mutator(new Color(this.rules[key]));
- else if (key.substring(3, 0) == "fg_")
- value = fg_mutator(new Color(this.rules[key]));
- else
- value = bg_mutator(new Color(this.rules[key]));
- if(value == "255,255,255") /* IE confuses white with transparent... */
- value = "255,255,254";
- text = text.replaceAll("$(" + key + ")", "rgb(" + value + ")");
- }
- this.__setStylesheet(text);
- }
- });
- qwebirc.ui.TabCompleterFactory = new Class({
- initialize: function(session) {
- this.session = session;
- this.reset();
- },
- tabComplete: function(textBox) {
- var text = textBox.value;
- if(!$defined(this.obj)) {
- this.incr = 1;
- var w = ui.getActiveWindow();
- if(!w)
- return;
- var startingWord = qwebirc.util.getEnclosedWord(text, qwebirc.util.getCaretPos(textBox));
- var preword = "", word = "", postword = "";
- if($defined(startingWord)) {
- var preword = text.substring(0, startingWord[0]);
- var word = startingWord[1];
- var postword = text.substring(startingWord[0] + word.length);
- }
- var ltext = text.toLowerCase();
- if(text == "") {
- preword = "/msg ";
- obj = qwebirc.ui.QueryTabCompleter;
- } else if(session.irc.isChannel(word)) {
- obj = qwebirc.ui.ChannelNameTabCompleter;
- } else if(ltext.match(/^\/(q|query|msg) /i)) {
- obj = qwebirc.ui.QueryTabCompleter;
- } else if(w.type == qwebirc.ui.WINDOW_QUERY) {
- obj = qwebirc.ui.QueryNickTabCompleter;
- } else if(w.type == qwebirc.ui.WINDOW_CHANNEL) {
- /* "slug[TAB]" == "slug: " */
- if(preword == "") {
- if((postword != "") && postword.charAt(0) == " ") {
- postword = ":" + postword;
- } else {
- postword = ": " + postword;
- }
- this.incr++;
- }
- obj = qwebirc.ui.ChannelUsersTabCompleter;
- } else {
- return;
- }
- if(postword == "")
- postword = " ";
- this.obj = new obj(session, preword, word, postword, w);
- if(!$defined(this.obj))
- return;
- }
- var r = this.obj.get();
- if(!$defined(r))
- return;
- textBox.value = r[1];
- qwebirc.util.setCaretPos(textBox, r[0] + this.incr);
- },
- reset: function() {
- this.obj = null;
- }
- });
- qwebirc.ui.TabIterator = new Class({
- initialize: function(session, prefix, list) {
- this.prefix = prefix;
- if(!$defined(list) || list.length == 0) {
- this.list = null;
- } else {
- var l = [];
- var prefixl = qwebirc.irc.toIRCCompletion(session, prefix);
- /* convert the nick list to IRC lower case, stripping all non letters
- * before comparisions */
- for(var i=0;i<list.length;i++) {
- var l2 = qwebirc.irc.toIRCCompletion(session, list[i]);
- if(l2.startsWith(prefixl))
- l.push(list[i]);
- }
- this.list = l;
- }
- this.pos = -1;
- },
- next: function() {
- /*
- * ideally next would do the list gubbins recursively, but no JS engine currently
- * support tail recursion :(
- */
- if(!$defined(this.list))
- return null;
- this.pos = this.pos + 1;
- if(this.pos >= this.list.length)
- this.pos = 0;
- return this.list[this.pos];
- }
- });
- qwebirc.ui.BaseTabCompleter = new Class({
- initialize: function(session, prefix, existingNick, suffix, list) {
- this.existingNick = existingNick;
- this.prefix = prefix;
- this.suffix = suffix;
- this.iterator = new qwebirc.ui.TabIterator(session, existingNick, list);
- },
- get: function() {
- var n = this.iterator.next();
- if(!$defined(n))
- return null;
- var p = this.prefix + n;
- return [p.length, p + this.suffix];
- }
- });
- qwebirc.ui.QueryTabCompleter = new Class({
- Extends: qwebirc.ui.BaseTabCompleter,
- initialize: function(session, prefix, existingNick, suffix) {
- this.parent(session, prefix, existingNick, suffix, session.irc.lastNicks);
- }
- });
- qwebirc.ui.QueryNickTabCompleter = new Class({
- Extends: qwebirc.ui.BaseTabCompleter,
- initialize: function(session, prefix, existingText, suffix) {
- var nick = window.name
- this.parent(session, prefix, existingText, suffix, [nick]);
- }
- });
- qwebirc.ui.ChannelNameTabCompleter = new Class({
- Extends: qwebirc.ui.BaseTabCompleter,
- initialize: function(session, prefix, existingText, suffix) {
- /* WTB map */
- var l = [];
- for(var c in session.irc.channels) {
- var w = session.windows[c];
- /* redundant? */
- if($defined(w))
- w = w.lastSelected;
- l.push([w, c]);
- }
- l.sort(function(a, b) {
- return b[0] - a[0];
- });
- var l2 = [];
- for(var i=0;i<l.length;i++)
- l2.push(l[i][1]);
- this.parent(session, prefix, existingText, suffix, l2);
- }
- });
- qwebirc.ui.ChannelUsersTabCompleter = new Class({
- Extends: qwebirc.ui.BaseTabCompleter,
- initialize: function(session, prefix, existingText, suffix, nc) {
- var nc = session.irc.tracker.getSortedByLastSpoke(ui.getActiveWindow().name);
- this.parent(session, prefix, existingText, suffix, nc);
- }
- });
- qwebirc.ui.themes.ThemeControlCodeMap = {
- "C": "\x03",
- "B": "\x02",
- "U": "\x1F",
- "O": "\x0F",
- "{": "\x00",
- "}": "\x00",
- "[": "qwebirc://whois/",
- "]": "/",
- "$": "$"
- };
- qwebirc.ui.themes.Default = {
- "PREFIX": ["$C4==$O "],
- "SIGNON": ["Signed on!", true],
- "CONNECT": ["Connected to server.", true],
- "RAW": ["$m", true],
- "DISCONNECT": ["Disconnected from server: $m", true],
- "ERROR": ["ERROR: $m", true],
- "SERVERNOTICE": ["$m", true],
- "JOIN": ["${$N$} [$h] has joined $c", true],
- "OURJOIN": ["${$N$} [$h] has joined $c", true],
- "PART": ["${$N$} [$h] has left $c [$m]", true],
- "KICK": ["${$v$} was kicked from $c by ${$N$} [$m]", true],
- "MODE": ["mode/$c [$m] by ${$N$}", true],
- "QUIT": ["${$N$} [$h] has quit [$m]", true],
- "NICK": ["${$n$} has changed nick to ${$[$w$]$}", true],
- "TOPIC": ["${$N$} changed the topic of $c to: $m", true],
- "UMODE": ["Usermode change: $m", true],
- "INVITE": ["$N invites you to join $c", true],
- "HILIGHT": ["$C4"],
- "HILIGHTEND": ["$O"],
- "CHANMSG": ["<${$@$($N$)$}> $m"],
- "PRIVMSG": ["<$($N$)> $m"],
- "CHANNOTICE": ["-${$($N$)$}:$c- $m"],
- "PRIVNOTICE": ["-$($N$)- $m"],
- "OURCHANMSG": ["<$@$N> $m"],
- "OURPRIVMSG": ["<$N> $m"],
- "OURTARGETEDMSG": ["*$[$t$]* $m"],
- "OURTARGETEDNOTICE": ["[notice($[$t$])] $m"],
- "OURCHANNOTICE": ["-$N:$t- $m"],
- "OURPRIVNOTICE": ["-$N- $m"],
- "OURCHANACTION": [" * $N $m"],
- "OURPRIVACTION": [" * $N $m"],
- "CHANACTION": [" * ${$($N$)$} $m"],
- "PRIVACTION": [" * $($N$) $m"],
- "CHANCTCP": ["$N [$h] requested CTCP $x from $c: $m"],
- "PRIVCTCP": ["$N [$h] requested CTCP $x from $-: $m"],
- "CTCPREPLY": ["CTCP $x reply from $N: $m"],
- "OURCHANCTCP": ["[ctcp($t)] $x $m"],
- "OURPRIVCTCP": ["[ctcp($t)] $x $m"],
- "OURTARGETEDCTCP": ["[ctcp($t)] $x $m"],
- "WHOISUSER": ["$B$N$B [$h]", true],
- "WHOISREALNAME": [" realname : $m", true],
- "WHOISCHANNELS": [" channels : $m", true],
- "WHOISSERVER": [" server : $x [$m]", true],
- "WHOISACCOUNT": [" account : qwebirc://accinfo/$m", true],
- "WHOISIDLE": [" idle : $x [connected: $m]", true],
- "WHOISAWAY": [" away : $m", true],
- "WHOISOPER": [" oper : $BIRC Operator$B", true],
- "WHOISOPERNAME": [" operedas : $m", true],
- "WHOISACTUALLY": [" realhost : $m [ip: $x]", true],
- "WHOISAVAILHELP": [" oper : is available for help.", true],
- "WHOISREGGED": [" regged : has a registered nick.", true],
- "WHOISMODES": [" modes : $m", true],
- "WHOISREALHOST": [" realhost : $m ($x)", true],
- "WHOISGENERICTEXT": [" info : $m", true],
- "WHOISEND": ["End of WHOIS", true],
- "AWAY": ["$N is away: $m", true],
- "GENERICERROR": ["$m: $t", true],
- "GENERICMESSAGE": ["$m", true],
- "WALLOPS": ["WALLOP $n: $t", true],
- "CHANNELCREATIONTIME": ["Channel $c was created at: $m", true],
- "CHANNELMODEIS": ["Channel modes on $c are: $m", true]
- };
- qwebirc.ui.Theme = new Class({
- initialize: function(themeDict) {
- this.__theme = qwebirc.util.dictCopy(qwebirc.ui.themes.Default);
- if(themeDict)
- for(var k in themeDict)
- this.__theme[k] = themeDict[k];
- for(var k in this.__theme) {
- if(k == "PREFIX")
- continue;
- var data = this.__theme[k];
- if(data[1]) {
- this.__theme[k] = this.__theme["PREFIX"] + data[0];
- } else {
- this.__theme[k] = data[0];
- }
- }
- this.__ccmap = qwebirc.util.dictCopy(qwebirc.ui.themes.ThemeControlCodeMap);
- this.__ccmaph = qwebirc.util.dictCopy(this.__ccmap);
- this.__ccmaph["("] = this.message("HILIGHT", {}, this.__ccmap);
- this.__ccmaph[")"] = this.message("HILIGHTEND", {}, this.__ccmap);
- this.__ccmaph["{"] = this.__ccmaph["}"] = "";
- },
- __dollarSubstitute: function(x, h, mapper) {
- var msg = [];
- var n = x.split("");
- for(var i=0;i<n.length;i++) {
- var c = n[i];
- if(c == "$" && (i <= n.length - 1)) {
- var c2 = n[++i];
- var o = mapper[c2];
- if(!o)
- o = h[c2];
- if(o)
- msg.push(o);
- } else {
- msg.push(c);
- }
- }
- return msg.join("");
- },
- message: function(type, data, hilight) {
- var map;
- if(hilight) {
- map = this.__ccmaph;
- } else {
- map = this.__ccmap;
- }
- if(data && data["n"])
- data["N"] = "qwebirc://whois/" + data.n + "/";
- return this.__dollarSubstitute(this.__theme[type], data, map);
- }
- });
- qwebirc.ui.urlificate = function(session, element, text) {
- var punct_re = /[[\)|\]]?(\.*|[\,;])$/;
- var addedText = [];
- var txtprocess = function(text, regex, appendfn, matchfn) {
- for(;;) {
- var index = text.search(regex);
- if(index == -1) {
- appendfn(text);
- break;
- }
- var match = text.match(regex);
- var before = text.substring(0, index);
- var matched = match[0];
- var after = text.substring(index + matched.length);
- appendfn(before);
- var more = matchfn(matched, appendfn);
- if(!more)
- more = "";
- text = more + after;
- }
- };
- var appendText = function(text) {
- addedText.push(text);
- qwebirc.util.NBSPCreate(text, element);
- };
- var appendChan = function(text) {
- var newtext = text.replace(punct_re, "");
- addedText.push(newtext);
- var punct = text.substring(newtext.length);
- var a = new Element("span");
- a.href = "#";
- a.addClass("hyperlink-channel");
- a.addEvent("click", function(e) {
- new Event(e).stop();
- if (session.irc)
- session.irc.exec("/JOIN " + newtext);
- else {
- var connect = ui.getWindow(qwebirc.ui.WINDOW_CUSTOM, "Connect");
- if (connect) {
- var connected = connect.subWindow.connectChannel(newtext);
- if (!connected) {
- ui.selectWindow(connect);
- connect.subWindow.nickBox.focus();
- }
- }
- }
- });
- a.appendChild(document.createTextNode(newtext));
- element.appendChild(a);
- return punct;
- };
- var appendURL = function(text, appendfn) {
- var url = text.replace(punct_re, "");
- var punct = text.substring(url.length);
- var href = "";
- var fn = null;
- var target = "_blank";
- var disptext = url;
- var elementType = "a";
- var addClass;
- var ma = url.match(/^qwebirc:\/\/(.*)$/);
- if(ma) {
- var m = ma[1].match(/^([^\/]+)\/([^\/]+)\/?(.*)$/);
- if(!m) {
- appendfn(text);
- return;
- }
- var cmd = ui.urlDispatcher(m[1]);
- if(cmd) {
- addClass = m[1];
- elementType = cmd[0];
- if(cmd[0] != "a") {
- url = null;
- } else {
- url = "#";
- }
- fn = cmd[1];
- disptext = unescape(m[2]);
- target = null;
- } else {
- appendfn(text);
- return;
- }
- if(m[3])
- punct = m[3] + punct;
- } else {
- if(url.match(/^www\./))
- url = "http://" + url;
- }
- var a = new Element(elementType);
- if(addClass)
- a.addClass("hyperlink-" + addClass);
- if(url) {
- a.href = url;
- if(target)
- a.target = target;
- }
- addedText.push(disptext);
- a.appendChild(document.createTextNode(disptext));
- element.appendChild(a);
- if($defined(fn))
- a.addEvent("click", function(e) { new Event(e).stop(); fn(disptext); });
- else
- a.addEvent("click", function(e) { new Event(e).stopPropagation(); });
- return punct;
- };
- txtprocess(text, /\b((https?|ftp|qwebirc):\/\/|www\.)[^ ]+/, function(text) {
- txtprocess(text, /\B#[^ ,]+/, appendText, appendChan);
- }, appendURL);
- return addedText.join("");
- }
- qwebirc.ui.Panes.Connect = {
- title: "Connect",
- command: function(session) { return null; },
- menuitem: function(session) { return null; }
- };
- qwebirc.ui.Panes.Connect.pclass = new Class({
- Implements: [Events],
- session: null,
- parent: null,
- connectCallback: null,
- nickBox: null,
- chanBox: null,
- initialize: function(session, w) {
- this.session = session;
- this.parent = w.lines;
- if (!conf.frontend.prompt
- && conf.frontend.initial_nick
- && conf.frontend.initial_chans)
- this.createConfirmBox();
- else
- this.createLoginBox(null);
- },
- connectChannel: function(channel) {
- if (conf.frontend.chan_autoconnect
- && (conf.frontend.initial_nick
- || (this.nickBox && this.nickBox.value))) {
- this.connect(channel);
- return true;
- }
- else {
- if (this.chanBox != null)
- this.chanBox.set("value", channel);
- else
- this.createLoginBox(channel);
- return false;
- }
- },
- connect: function(channel) {
- while(this.parent.childNodes.length > 0)
- this.parent.removeChild(this.parent.firstChild);
- var data = {};
- if (this.nickBox != null)
- data["nickname"] = this.nickBox.value;
- else
- data["nickname"] = conf.frontend.initial_nick;
- if (channel != null)
- data["autojoin"] = channel;
- else if (this.chanBox != null)
- data["autojoin"] = this.chanBox.value;
- else
- data["autojoin"] = conf.frontend.initial_chans;
- if (this.session.atheme.state) {
- data["authUser"] = this.session.atheme.user;
- data["authSecret"] = this.session.atheme.secret;
- }
- this.connectCallback(data);
- },
- /* Focus elem if we're not embedded in an iframe. This prevents stealing focus. */
- autoFocus: function(elem) {
- /* Accessing window.top might raise if we are iframed... */
- try {
- if (window.self === window.top) {
- elem.focus();
- }
- } catch (e) {}
- },
- createConfirmBox: function() {
- while(this.parent.childNodes.length > 0)
- this.parent.removeChild(this.parent.firstChild);
- var outerbox = new Element("table");
- outerbox.addClass("qwebirc-centrebox");
- this.parent.appendChild(outerbox);
- var tbody = new Element("tbody");
- outerbox.appendChild(tbody);
- var tr = new Element("tr");
- tbody.appendChild(tr);
- var td = new Element("td");
- tr.appendChild(td);
- var box = new Element("table");
- box.addClass("qwebirc-confirmbox");
- td.appendChild(box);
- var tbody = new Element("tbody");
- box.appendChild(tbody);
- var tr = new Element("tr");
- tbody.appendChild(tr);
- tr.addClass("tr1");
- var text = new Element("td");
- tr.appendChild(text);
- var nick = new Element("b");
- nick.set("text", conf.frontend.initial_nick);
- var c = conf.frontend.initial_chans.split(" ")[0].split(",");
- text.appendChild(document.createTextNode("To connect to " + conf.frontend.network_name + " IRC and join channel" + ((c.length>1)?"s":"") + " "));
- for(var i=0;i<c.length;i++) {
- if((c.length > 1) && (i == c.length - 1)) {
- text.appendChild(document.createTextNode(" and "));
- } else if(i > 0) {
- text.appendChild(document.createTextNode(", "));
- }
- text.appendChild(new Element("b").set("text", c[i]));
- }
- if(!conf.frontend.initial_nick_rand) {
- text.appendChild(document.createTextNode(" as "));
- text.appendChild(nick);
- }
- text.appendChild(document.createTextNode(" click 'Connect'."));
- text.appendChild(new Element("br"));
- var tr = new Element("tr");
- tbody.appendChild(tr);
- tr.addClass("tr2");
- var td = new Element("td");
- tr.appendChild(td);
- var form = new Element("form");
- td.appendChild(form);
- var yes = new Element("input", {"type": "submit", "value": "Connect"});
- form.appendChild(yes);
- this.autoFocus(yes);
- form.addEvent("submit", function(e) {
- new Event(e).stop();
- this.connect(null);
- }.bind(this));
- },
- createLoginBox: function(channel) {
- while(this.parent.childNodes.length > 0)
- this.parent.removeChild(this.parent.firstChild);
- var outerbox = new Element("table");
- outerbox.addClass("qwebirc-centrebox");
- this.parent.appendChild(outerbox);
- var tbody = new Element("tbody");
- outerbox.appendChild(tbody);
- var tr = new Element("tr");
- tbody.appendChild(tr);
- var td = new Element("td");
- tr.appendChild(td);
- var box = new Element("table");
- box.addClass("qwebirc-loginbox");
- td.appendChild(box);
- var tbody = new Element("tbody");
- box.appendChild(tbody);
- var tr = new Element("tr");
- tbody.appendChild(tr);
- tr.addClass("tr1");
- var td = new Element("td");
- tr.appendChild(td);
- td.set("html", "<h1>Connect to " + conf.frontend.network_name + " IRC</h1>");
- var tr = new Element("tr");
- tbody.appendChild(tr);
- tr.addClass("tr2");
- var td = new Element("td");
- tr.appendChild(td);
- var form = new Element("form");
- td.appendChild(form);
- var boxtable = new Element("table");
- form.appendChild(boxtable);
- var tbody = new Element("tbody");
- boxtable.appendChild(tbody); /* stupid IE */
- function createRow(label, e2, style) {
- var r = new Element("tr");
- tbody.appendChild(r);
- var d1 = new Element("td");
- if(label)
- d1.set("text", label);
- r.appendChild(d1);
- var d2 = new Element("td");
- r.appendChild(d2);
- if($defined(e2))
- d2.appendChild(e2);
- if($defined(style)) {
- r.setStyles(style);
- return [r, d2];
- }
- return d2;
- }
- this.nickBox = new Element("input");
- createRow("Nickname:", this.nickBox);
- if (conf.atheme.nickserv_login) {
- var srvbutton = new Element("input");
- srvbutton.set("type", "checkbox");
- srvbutton.set("checked", false);
- createRow("Login to Services:", srvbutton);
- var user = new Element("input");
- var userRow = createRow("Username:", user, {})[0];
- userRow.setStyle("display", "none");
- var pass = new Element("input");
- pass.set("type", "password");
- var passRow = createRow("Password:", pass, {})[0];
- passRow.setStyle("display", "none");
- var syncInput = function (e) {
- user.value = this.nickBox.value;
- }.bind(this);
- /* the 'input' event is buggy in IE9, but this isn't a very
- * important feature.
- */
- user.addEvent("input", function (e) {
- this.nickBox.removeEvent("input", syncInput, false);
- }.bind(this), false);
- srvbutton.addEvent("click", function(e) {
- var visible = srvbutton.checked;
- var display = visible ? null : "none";
- userRow.setStyle("display", display);
- passRow.setStyle("display", display);
- if (visible) {
- this.nickBox.addEvent("input", syncInput, false);
- user.focus();
- /* setting the value after calling focus() will place the cursor at
- * the end of the text.
- */
- user.value = this.nickBox.value;
- } else {
- this.nickBox.removeEvent("input", syncInput, false);
- this.nickBox.focus();
- }
- }.bind(this));
- }
- //if (channel || conf.frontend.chan_prompt ||
- // !conf.frontend.initial_chans) {
- // this.chanBox = new Element("input");
- // createRow("Channels:", this.chanBox);
- //}
- var connbutton = new Element("input", {"type": "submit"});
- connbutton.set("value", "Connect");
- var r = createRow(undefined, connbutton);
- form.addEvent("submit", function(e) {
- new Event(e).stop();
- if(!this.nickBox.value) {
- alert("You must supply a nickname.");
- this.nickBox.focus();
- return;
- }
- if(!this.nickBox.value.match(/^[a-zA-Z0-9`^\-_\[\]{}|\\]+$/)) {
- alert("Invalid nickname entered; only characters in the list \"A-Z a-z 0-9 ` ^ - \\ [ ] { } |\" are allowed.");
- this.nickBox.focus();
- return;
- }
- if(this.nickBox.value.match(/^\d/) || this.nickBox.value[0] == '-') {
- alert("Invalid nickname entered; nicknames may not start with - or a number.");
- this.nickBox.focus();
- return;
- }
- Cookie.write("iris-nick", this.nickBox.value, {"duration": 3650});
- if (conf.atheme.nickserv_login) {
- if (srvbutton.checked) {
- if (!user.value) {
- alert("You must supply a username.");
- user.focus();
- return;
- }
- if (!pass.value) {
- alert("You must supply a password.");
- pass.focus();
- return;
- }
- }
- if (srvbutton.checked && conf.atheme.sasl_type == "AUTHCOOKIE") {
- qwebirc.irc.AthemeQuery.login(function(token) {
- if (token == null)
- alert("Authentication failed");
- else
- qwebirc.ui.Atheme.handleLogin(this.session, user.value, token);
- this.connect(null);
- }.bind(this), user.value, pass.value);
- }
- else if (srvbutton.checked && conf.atheme.sasl_type == "PLAIN") {
- this.session.atheme.state = true;
- this.session.atheme.user = user.value;
- this.session.atheme.secret = pass.value;
- this.connect(null);
- }
- else {
- qwebirc.ui.Atheme.handleLogout(this.session);
- this.connect(null);
- }
- }
- else {
- this.connect(null);
- }
- }.bind(this));
- if (Cookie.read("iris-nick") != null)
- this.nickBox.set("value", Cookie.read("iris-nick"));
- else if (conf.frontend.initial_nick)
- this.nickBox.set("value", conf.frontend.initial_nick);
- if (this.chanBox != null && channel)
- this.chanBox.set("value", channel);
- else if (this.chanBox != null)
- this.chanBox.set("value", conf.frontend.initial_chans);
- this.autoFocus(this.nickBox);
- }
- });
- /**
- * Display a list of channels on the network.
- */
- qwebirc.ui.Panes.List = {
- title: "Channels",
- command: function(session) {
- if (conf.atheme.chan_list)
- return "LIST";
- },
- menuitem: function(session) {
- if (conf.atheme.chan_list)
- return "Channel list";
- },
- menupos: 100
- };
- qwebirc.ui.Panes.List.pclass = new Class({
- Implements: [Events],
- session: null,
- parent: null,
- /* Store the list's current state. */
- cloud: true,
- loading: null,
- timestamp: 0,
- page: 1,
- namefilter: "",
- topicfilter: "",
- filterBox: null,
- viewBox: null,
- chanBox: null,
- pageBox: null,
- viewChange: null,
- pageText: null,
- prev: null,
- next: null,
- initialize: function(session, w) {
- this.session = session;
- this.parent = w.lines;
- this.cloud = conf.atheme.chan_list_cloud_view;
- /* Make header table. */
- var headerTable = new Element("table");
- var header = new Element("tbody");
- headerTable.appendChild(header);
- /* Make and add view change link. */
- this.viewChange = new Element("a", { "class": "", "href": "#" });
- this.viewChange.addEvent("click", function(e) {
- if (this.cloud) {
- this.createListView();
- } else {
- this.createCloudView();
- }
- }.bind(this));
- var cell = new Element("td", { "class": "viewchange" });
- cell.appendChild(this.viewChange);
- header.appendChild(cell);
- /* Make filter box. */
- var filterBox = new Element("form", { "class": "filterbox" });
- /* Add name filter text box. */
- var filterSubBox = new Element("span", { "class": "inputbox" });
- filterSubBox.appendText("Filter by Name:");
- var nameinput = new Element("input");
- filterSubBox.appendChild(nameinput);
- filterBox.appendChild(filterSubBox);
- /* Add topic filter box. */
- var filterSubBox = new Element("span", { "class": "inputbox" });
- filterSubBox.appendText("Filter by Topic:");
- var topicinput = new Element("input");
- filterSubBox.appendChild(topicinput);
- filterBox.appendChild(filterSubBox);
- /* Add refresh and update filters button. */
- var refresh = new Element("input", {"type": "submit", "value": "Refresh and Apply Filters"});
- refresh.addEvent("click", function(e) {
- (new Event(e)).stop();
- if (nameinput.value != this.namefilter || topicinput.value != this.topicfilter) {
- this.namefilter = nameinput.value;
- this.topicfilter = topicinput.value;
- this.page = 1;
- }
- this.timestamp = 0;
- this.update();
- }.bind(this));
- filterBox.appendChild(refresh);
- /* Add filter box and completed header. */
- var cell = new Element("td"); cell.appendChild(filterBox);
- header.appendChild(cell);
- this.parent.appendChild(headerTable);
- /* Make and add view box. */
- this.viewBox = new Element("div");
- this.parent.appendChild(this.viewBox);
- if (this.cloud) {
- this.createCloudView();
- } else {
- this.createListView();
- }
- },
- /**
- * Setup the "list view" list of channels.
- */
- createListView: function() {
- this.cloud = false;
- while(this.viewBox.childNodes.length > 0)
- this.viewBox.removeChild(this.viewBox.firstChild);
- /* Update view change text. */
- this.viewChange.set("text", "Switch to cloud view...");
- /* Create the channel table. */
- var table = new Element("table", { "class": "listbox", "cellspacing": "0"});
- this.chanBox = new Element("tbody");
- table.appendChild(this.chanBox);
- this.viewBox.appendChild(table);
- /* Make page box and components. */
- this.pageBox = new Element("div", { "class": "pagebox" });
- this.pageBox.style.display = "none";
- this.prev = new Element("span");
- this.pageText = new Element("span");
- this.next = new Element("span");
- this.pageBox.appendChild(this.prev);
- this.pageBox.appendText(" - ");
- this.pageBox.appendChild(this.pageText);
- this.pageBox.appendText(" - ");
- this.pageBox.appendChild(this.next);
- /* Add page box. */
- this.viewBox.appendChild(this.pageBox);
- /* Start the loading display timer. */
- var delayfn = function() { this.chanBox.set("html", "<tr><td class=\"loading\">Loading. . .</td></tr>"); }.bind(this);
- this.loading = delayfn.delay(500);
- /* Get a channel list. */
- this.update();
- },
- /**
- * Setup the "cloud view" list of channels.
- */
- createCloudView: function() {
- this.cloud = true;
- this.page = 1;
- while(this.viewBox.childNodes.length > 0)
- this.viewBox.removeChild(this.viewBox.firstChild);
- /* Update view change text. */
- this.viewChange.set("text", "Switch to list view...");
- /* Add hint text. */
- var hint = new Element("div", { "class": "hoverhint"});
- hint.appendText("Hover over a channel to view its topic!");
- this.viewBox.appendChild(hint);
- /* Add channel box. */
- this.chanBox = new Element("div", { "class": "tagbox" });
- this.viewBox.appendChild(this.chanBox);
- /* Get a channel list. */
- this.update();
- },
- /**
- * Update the channel list.
- */
- update: function() {
- qwebirc.irc.AthemeQuery.channelList(function(channels, timestamp, total) {
- /* Update our timestamp to the timestamp of this list. */
- this.timestamp = timestamp;
- /* Cancel any timeout. */
- if (this.loading != null) {
- clearTimeout(this.loading);
- this.loading = null;
- }
- /* Remove any previous content from the channel box. */
- if (this.chanBox.hasChildNodes()) {
- while (this.chanBox.childNodes.length >= 1)
- this.chanBox.removeChild(this.chanBox.firstChild);
- }
- /* If the connection failed, display that and return. */
- if (channels == null) {
- if (this.cloud) {
- this.chanBox.set("html", "<span class=\"loading\">Unable to load channel list, please try reopening the channel list later.</span>");
- } else {
- this.chanBox.set("html", "<tr><td class=\"loading\">Unable to load channel list, please try refreshing again later.</td></tr>");
- }
- return;
- }
- /* If we got no channels, display that and return. */
- if (channels.length == 0) {
- if (this.cloud) {
- this.chanBox.set("html", "<span class=\"loading\">No channels currently exist, please try refreshing again later.</span>");
- } else {
- this.chanBox.set("html", "<tr><td class=\"loading\">No channels currently exist, please try refreshing again later.</td></tr>");
- }
- return;
- }
- /* Calculate the range of the channel sizes. */
- var minUsers = channels[channels.length-1].users
- var userScale = channels[0].users - minUsers
- /* Print the table headings, for list view. */
- if (!this.cloud) {
- var headers = new Element("tr");
- var name = new Element("th", { "class": "name" });
- name.appendText("Channel");
- headers.appendChild(name);
- var users = new Element("th", { "class": "users" });
- users.appendText("Users");
- headers.appendChild(users);
- var topic = new Element("th", { "class": "chantopic" });
- topic.appendText("Topic");
- headers.appendChild(topic);
- this.chanBox.appendChild(headers);
- }
- /* Sort the channels into alphabetical order for cloud view. */
- if (this.cloud) {
- channels.sort(function (a, b) {
- an = a.name.toLowerCase(); bn = b.name.toLowerCase();
- if (an < bn) return -1;
- if (an > bn) return 1;
- return 0;
- });
- }
- /* Finally, add the channels. */
- for (var i = 0; i < channels.length; i++) {
- var channel;
- if (this.cloud) {
- channel = new Element("span", { "class": "chantag", style: "font-size: " + (1 + 2 * (channels[i].users - minUsers) / (userScale+1)) + "em;" });
- } else {
- channel = new Element("tr");
- }
- this.makeChannel(channel, channels[i], i%2 + 1);
- this.chanBox.appendChild(channel);
- if (this.cloud) {
- this.chanBox.appendText(" ");
- }
- }
- }.bind(this), this.timestamp, "100", this.page, this.namefilter, this.topicfilter);
- },
- /**
- * Update page numbers and paging boxes.
- */
- updatePaging: function(total) {
- /* Update the page number, if there is one. */
- if (this.pageText) {
- var pages = Math.ceil(total/100);
- while (this.pageText.childNodes.length >= 1)
- this.pageText.removeChild(this.pageText.firstChild);
- this.pageText.appendText("Page " + (this.page) + " of " + pages);
- }
- /* Update the page change buttons, if there are any. */
- if (this.prev && this.next) {
- /* If we have a previous page, enable prev button. */
- while (this.prev.childNodes.length >= 1)
- this.prev.removeChild(this.prev.firstChild);
- if (this.page > 1) {
- var prevLink = new Element("a", {"href": "#"});
- prevLink.appendText("Prev Page");
- prevLink.addEvent("click", function(e) {
- this.page--;
- prevLink.removeEvents();
- this.update();
- }.bind(this));
- this.prev.appendChild(prevLink);
- } else {
- this.prev.appendText("Prev Page");
- }
- /* If we have a next page, enable next button. */
- while (this.next.childNodes.length >= 1)
- this.next.removeChild(this.next.firstChild);
- if (this.page < pages) {
- var nextLink = new Element("a", {"href": "#"});
- nextLink.appendText("Next Page");
- nextLink.addEvent("click", function(e) {
- this.page++;
- nextLink.removeEvents();
- this.update();
- }.bind(this));
- this.next.appendChild(nextLink);
- }
- else {
- this.next.appendText("Next Page");
- }
- }
- /* Show the page sorting box only if it has any contents. */
- if (this.PageBox) {
- if (this.page != 1 || pages > 1)
- this.pageBox.style.display = "block";
- else
- this.pageBox.style.display = "none";
- }
- },
- /**
- * Make channel item for the list, as appropriate for the current list mode.
- */
- makeChannel: function(chanitem, channel, oddeven) {
- var name;
- if (this.cloud) {
- name = chanitem
- } else {
- name = new Element("td", { "class": "name chan" + oddeven });
- }
- /* This closure is a trick so each event handler gets a unique
- * channame recording the channel it should open. */
- var closure = function() {
- var channame = channel.name;
- chanitem.addEvent("click", function(e) {
- new Event(e).stop();
- if (this.session.irc)
- this.session.irc.exec("/JOIN " + channame);
- else {
- var connect = ui.getWindow(qwebirc.ui.WINDOW_CUSTOM, "Connect");
- if (connect) {
- var connected = connect.subWindow.connectChannel(channame);
- if (!connected) {
- ui.selectWindow(connect);
- connect.subWindow.nickBox.focus();
- }
- }
- }
- }.bind(this));
- }.bind(this); closure();
- name.appendText(channel.name);
- /* Add all other information shown for the channel in this view. */
- if (this.cloud) {
- chanitem.setProperty("title", channel.topic);
- } else {
- chanitem.appendChild(name);
- var users = new Element("td", { "class": "users chan" + oddeven });
- users.appendText(channel.users);
- chanitem.appendChild(users);
- var topic = new Element("td", { "class": "chantopic chan" + oddeven });
- qwebirc.ui.Colourise(this.session, channel.topic, topic);
- chanitem.appendChild(topic);
- }
- }
- });
- qwebirc.ui.Panes.Options = {
- title: "Options",
- command: function(session) { return "OPTIONS"; },
- menuitem: function(session) { return "Options"; },
- menupos: 300
- };
- qwebirc.ui.Panes.Options.pclass = new Class({
- Implements: [Events],
- session: null,
- initialize: function(session, w) {
- this.session = session;
- this.window = w;
- this.parent = w.lines;
- this.createElements();
- },
- createElements: function() {
- var FE = function(element, parent) {
- var n = new Element(element);
- parent.appendChild(n);
- return n;
- };
- var t = FE("table", this.parent);
- var tb = FE("tbody", t);
- this.boxList = [];
- this.options = {};
- for(var i=0;i<qwebirc.options.Options.length;i++) {
- var x = qwebirc.options.Options[i];
- var type = qwebirc.options.CheckInput;
- if ($defined(x.type))
- type = x.type;
- if (type == qwebirc.options.ColorInput && $defined(x.isEnabled)) {
- if (!x.isEnabled(this.session))
- continue
- }
- var row = FE("tr", tb);
- var cella = FE("td", row);
- var cellb = FE("td", row);
- var input = new type(this.session, this.options, cellb, x, i);
- var label = new Element("label", {"for": input.id});
- label.set("text", x.label + ":");
- cella.appendChild(label);
- this.boxList.push([x, input]);
- this.options[x.category + "." + x.option] = input;
- }
- var r = FE("tr", tb);
- var cella = FE("td", r);
- var cellb = FE("td", r);
- var save = qwebirc.util.createInput("submit", cellb);
- save.value = "Save";
- save.addEvent("click", function() {
- this.save();
- ui.closeWindow(this.window);
- }.bind(this));
- var cancel = qwebirc.util.createInput("submit", cellb);
- cancel.value = "Cancel";
- cancel.addEvent("click", function() {
- this.cancel();
- ui.closeWindow(this.window);
- }.bind(this));
- },
- save: function() {
- this.boxList.forEach(function(x) {
- var option = x[0];
- var box = x[1];
- conf[option.category][option.option] = box.get();
- if (option.onSave)
- option.onSave(this.session);
- }.bind(this));
- qwebirc.config.saveUserSettings(conf);
- },
- cancel: function() {
- this.boxList.forEach(function(x) {
- if (x[0].onCancel)
- x[0].onCancel(this.session);
- }.bind(this));
- }
- });
- qwebirc.ui.Panes.PrivacyPolicy = {
- title: "Privacy Policy",
- command: function(session) {
- if (conf.ui.privacy) {
- return "PRIVACYPOLICY";
- } else {
- return null;
- }
- },
- menuitem: function(session) {
- if (conf.ui.privacy) {
- return "Privacy policy";
- } else {
- return null;
- }
- },
- menupos: 700
- };
- qwebirc.ui.Panes.PrivacyPolicy.pclass = new Class({
- Implements: [Events],
- session: null,
- initialize: function(session, w) {
- this.session = session;
- var delayfn = function() { w.lines.set("html", "<div class=\"loading\">Loading. . .</div>"); };
- var cb = delayfn.delay(500);
- var r = qwebirc.ui.RequestTransformHTML(session, {url: conf.frontend.static_base_url + "panes/privacypolicy.html", update: w.lines, onSuccess: function() {
- $clear(cb);
- w.lines.getElement("input[class=close]").addEvent("click", function() {
- ui.closeWindow(w);
- }.bind(this));
- }.bind(this)});
- r.get();
- }
- });
- qwebirc.ui.QUI = new Class({
- Extends: qwebirc.ui.RootUI,
- initialize: function(session, parentElement) {
- this.parent(session, parentElement, qwebirc.ui.QUI.Window, "qui");
- this.theme = new qwebirc.ui.Theme(null);
- this.setModifiableStylesheet("qui");
- },
- postInitialize: function() {
- this.qjsui = new qwebirc.ui.QUI.JSUI("qwebirc-qui", this.parentElement);
- this.qjsui.addEvent("reflow", function() {
- var w = this.getActiveWindow();
- if($defined(w))
- w.onResize();
- }.bind(this));
- this.qjsui.top.addClass("outertabbar");
- this.qjsui.bottom.addClass("input");
- this.qjsui.right.addClass("nicklist");
- this.qjsui.topic.addClass("topic");
- this.qjsui.middle.addClass("lines");
- this.outerTabs = this.qjsui.top;
- this.tabs = new Element("div", { "class":"tabbar" });
- this.__createDropdownMenu();
- this.outerTabs.appendChild(this.tabs);
- this.origtopic = this.topic = this.qjsui.topic;
- this.origlines = this.lines = this.qjsui.middle;
- this.orignicklist = this.nicklist = this.qjsui.right;
- this.input = this.qjsui.bottom;
- this.reflow = this.qjsui.reflow.bind(this.qjsui);
- this.tabs.addEvent("mousewheel", function(x) {
- var event = new Event(x);
- /* up */
- if(event.wheel > 0) {
- this.nextWindow();
- } else if(event.wheel < 0) {
- /* down */
- this.prevWindow();
- }
- event.stop();
- }.bind(this));
- this.createInput();
- this.reflow();
- this.reflow.delay(100); /* Konqueror fix */
- },
- __createDropdownMenu: function() {
- var dropdownMenu = new Element("span");
- dropdownMenu.addClass("dropdownmenu");
- dropdownMenu.hide = function() {
- dropdownMenu.setStyle("display", "none");
- dropdownMenu.visible = false;
- document.removeEvent("mousedown", hideEvent);
- }.bind(this);
- var hideEvent = function() { dropdownMenu.hide(); };
- dropdownMenu.hide();
- this.parentElement.appendChild(dropdownMenu);
- var menuitems = [];
- var i = 0;
- $each(qwebirc.ui.Panes, function(pane, name, object) {
- var text = pane.menuitem(this.session);
- if (text) {
- menuitems[i] = {};
- menuitems[i].text = text;
- menuitems[i].name = name;
- menuitems[i].pos = pane.menupos;
- i++;
- }
- }.bind(this));
- menuitems.sort(function(a, b) { return a.pos - b.pos });
- menuitems.forEach(function(x) {
- var e = new Element("a");
- e.addEvent("mousedown", function(e) { new Event(e).stop(); });
- e.addEvent("click", function() {
- dropdownMenu.hide();
- ui.addPane(x.name);
- }.bind(this));
- e.set("text", x.text);
- dropdownMenu.appendChild(e);
- }.bind(this));
- var dropdown = new Element("div");
- dropdown.addClass("dropdown-tab");
- dropdown.appendChild(new Element("img", {src: conf.frontend.static_base_url + "images/menu.png", title: "menu", alt: "menu"}));
- this.outerTabs.appendChild(dropdown);
- dropdownMenu.show = function(x) {
- new Event(x).stop();
- if(dropdownMenu.visible) {
- dropdownMenu.hide();
- return;
- }
- var top = this.outerTabs.getSize().y;
- dropdownMenu.setStyle("left", 0);
- dropdownMenu.setStyle("top", top-1); /* -1 == top border */
- dropdownMenu.setStyle("display", "inline-block");
- dropdownMenu.visible = true;
- document.addEvent("mousedown", hideEvent);
- }.bind(this);
- dropdown.addEvent("mousedown", function(e) { new Event(e).stop(); });
- dropdown.addEvent("click", dropdownMenu.show);
- },
- createInput: function() {
- var form = new Element("form");
- this.input.appendChild(form);
- form.addClass("input");
- var inputbox = new Element("input");
- form.appendChild(inputbox);
- this.inputbox = inputbox;
- this.inputbox.maxLength = 512;
- var sendInput = function() {
- if(inputbox.value == "")
- return;
- this.resetTabComplete();
- this.getActiveWindow().historyExec(inputbox.value);
- inputbox.value = "";
- }.bind(this);
- if(!qwebirc.util.deviceHasKeyboard()) {
- inputbox.addClass("mobile-input");
- var inputButton = new Element("input", {type: "button"});
- inputButton.addClass("mobile-button");
- inputButton.addEvent("click", function() {
- sendInput();
- inputbox.focus();
- });
- inputButton.value = ">";
- this.input.appendChild(inputButton);
- var reflowButton = function() {
- var containerSize = this.input.getSize();
- var buttonSize = inputButton.getSize();
- var buttonLeft = containerSize.x - buttonSize.x - 5; /* lovely 5 */
- inputButton.setStyle("left", buttonLeft);
- inputbox.setStyle("width", buttonLeft - 5);
- inputButton.setStyle("height", containerSize.y);
- }.bind(this);
- this.qjsui.addEvent("reflow", reflowButton);
- } else {
- inputbox.addClass("keyboard-input");
- }
- form.addEvent("submit", function(e) {
- new Event(e).stop();
- sendInput();
- });
- inputbox.addEvent("focus", this.resetTabComplete.bind(this));
- inputbox.addEvent("mousedown", this.resetTabComplete.bind(this));
- inputbox.addEvent("keydown", function(e) {
- var resultfn;
- var cvalue = inputbox.value;
- if(e.key == "up") {
- resultfn = this.commandhistory.upLine;
- } else if(e.key == "down") {
- resultfn = this.commandhistory.downLine;
- } else if(e.key == "tab") {
- new Event(e).stop();
- this.tabComplete(inputbox);
- return;
- } else {
- /* ideally alt and other keys wouldn't break this */
- this.resetTabComplete();
- return;
- }
- this.resetTabComplete();
- if((cvalue != "") && (this.lastcvalue != cvalue))
- this.commandhistory.addLine(cvalue, true);
- var result = resultfn.bind(this.commandhistory)();
- new Event(e).stop();
- if(!result)
- result = "";
- this.lastcvalue = result;
- inputbox.value = result;
- qwebirc.util.setAtEnd(inputbox);
- }.bind(this));
- },
- setLines: function(lines) {
- this.lines.parentNode.replaceChild(lines, this.lines);
- this.qjsui.middle = this.lines = lines;
- },
- setChannelItems: function(nicklist, topic) {
- if(!$defined(nicklist)) {
- nicklist = this.orignicklist;
- topic = this.origtopic;
- }
- this.nicklist.parentNode.replaceChild(nicklist, this.nicklist);
- this.qjsui.right = this.nicklist = nicklist;
- this.topic.parentNode.replaceChild(topic, this.topic);
- this.qjsui.topic = this.topic = topic;
- },
- closeWindow: function(window) {
- this.parent(window);
- this.tabs.removeChild(window.tab);
- this.tabs.removeChild(window.spaceNode);
- this.reflow();
- }
- });
- qwebirc.ui.QUI.JSUI = new Class({
- Implements: [Events],
- initialize: function(class_, parent, sizer) {
- this.parent = parent;
- this.sizer = $defined(sizer)?sizer:parent;
- this.class_ = class_;
- this.create();
- this.reflowevent = null;
- window.addEvent("resize", function() {
- this.reflow(100);
- }.bind(this));
- },
- applyClasses: function(pos, l) {
- l.addClass("dynamicpanel");
- l.addClass(this.class_);
- if(pos == "middle") {
- l.addClass("leftboundpanel");
- } else if(pos == "top") {
- l.addClass("topboundpanel");
- l.addClass("widepanel");
- } else if(pos == "topic") {
- l.addClass("widepanel");
- } else if(pos == "right") {
- l.addClass("rightboundpanel");
- } else if(pos == "bottom") {
- l.addClass("bottomboundpanel");
- l.addClass("widepanel");
- }
- },
- create: function() {
- var XE = function(pos) {
- var element = new Element("div");
- this.applyClasses(pos, element);
- this.parent.appendChild(element);
- return element;
- }.bind(this);
- this.top = XE("top");
- this.topic = XE("topic");
- this.middle = XE("middle");
- this.right = XE("right");
- this.bottom = XE("bottom");
- },
- reflow: function(delay) {
- if(!delay)
- delay = 1;
- if(this.reflowevent)
- $clear(this.reflowevent);
- this.__reflow();
- this.reflowevent = this.__reflow.delay(delay, this);
- },
- __reflow: function() {
- var bottom = this.bottom;
- var middle = this.middle;
- var right = this.right;
- var topic = this.topic;
- var top = this.top;
- var topicsize = topic.getSize();
- var topsize = top.getSize();
- var rightsize = right.getSize();
- var bottomsize = bottom.getSize();
- var docsize = this.sizer.getSize();
- var mheight = (docsize.y - topsize.y - bottomsize.y - topicsize.y);
- var mwidth = (docsize.x - rightsize.x);
- topic.setStyle("top", topsize.y);
- middle.setStyle("top", (topsize.y + topicsize.y));
- if(mheight > 0) {
- middle.setStyle("height", mheight);
- right.setStyle("height", mheight);
- }
- if(mwidth > 0)
- middle.setStyle("width", mwidth);
- right.setStyle("top", (topsize.y + topicsize.y));
- right.setStyle("left", mwidth);
- bottom.setStyle("top", (docsize.y - bottomsize.y));
- this.fireEvent("reflow");
- },
- showChannel: function(state) {
- var display = "none";
- if(state)
- display = "block";
- this.right.setStyle("display", display);
- this.topic.setStyle("display", display);
- },
- showInput: function(state) {
- this.bottom.isVisible = state;
- this.bottom.setStyle("display", state?"block":"none");
- }
- });
- qwebirc.ui.QUI.Window = new Class({
- Extends: qwebirc.ui.Window,
- initialize: function(session, type, name, identifier) {
- this.parent(session, type, name, identifier);
- this.tab = new Element("a", {"href": "#"});
- this.tab.addClass("tab");
- this.tab.addEvent("focus", function() { this.blur() }.bind(this.tab));;
- this.spaceNode = document.createTextNode(" ");
- /* Always put the connect/status windows in front. */
- if (ui.tabs.hasChildNodes()) {
- if (type == qwebirc.ui.WINDOW_STATUS) {
- ui.tabs.insertBefore(this.tab, ui.tabs.firstChild);
- ui.tabs.insertBefore(this.spaceNode, this.tab.nextSibling);
- }
- else if (type == qwebirc.ui.WINDOW_CUSTOM && name == "Connect") {
- ui.tabs.insertBefore(this.tab, ui.tabs.firstChild);
- ui.tabs.insertBefore(this.spaceNode, this.tab.nextSibling);
- }
- else {
- ui.tabs.appendChild(this.tab);
- ui.tabs.appendChild(this.spaceNode);
- }
- }
- else {
- ui.tabs.appendChild(this.tab);
- ui.tabs.appendChild(this.spaceNode);
- }
- this.tab.appendText(name);
- this.tab.addEvent("click", function(e) {
- new Event(e).stop();
- if(this.closed)
- return;
- ui.selectWindow(this);
- }.bind(this));
- if(type != qwebirc.ui.WINDOW_STATUS && (type != qwebirc.ui.WINDOW_CUSTOM || name != "Connect")) {
- var tabclose = new Element("span");
- tabclose.set("text", "X");
- tabclose.addClass("tabclose");
- var close = function(e) {
- new Event(e).stop();
- if(this.closed)
- return;
- if(type == qwebirc.ui.WINDOW_CHANNEL)
- this.session.irc.exec("/PART " + name);
- ui.closeWindow(this);
- //ui.inputbox.focus();
- }.bind(this);
- tabclose.addEvent("click", close);
- this.tab.addEvent("mouseup", function(e) {
- var button = 1;
- if(Browser.Engine.trident)
- button = 4;
- if(e.event.button == button)
- close();
- }.bind(this));
- this.tab.appendChild(tabclose);
- }
- this.lines = new Element("div");
- ui.qjsui.applyClasses("middle", this.lines);
- this.lines.addClass("lines");
- if(type != qwebirc.ui.WINDOW_CUSTOM)
- this.lines.addClass("ircwindow");
- this.lines.addEvent("scroll", function() {
- this.scrolleddown = this.scrolledDown();
- this.scrollpos = this.getScrollParent().getScroll();
- }.bind(this));
- if(type == qwebirc.ui.WINDOW_CHANNEL) {
- this.topic = new Element("div");
- this.topic.addClass("topic");
- this.topic.addClass("tab-invisible");
- this.topic.set("html", " ");
- this.topic.addEvent("dblclick", this.editTopic.bind(this));
- ui.qjsui.applyClasses("topic", this.topic);
- this.prevNick = null;
- this.nicklist = new Element("div");
- this.nicklist.addClass("nicklist");
- this.nicklist.addClass("tab-invisible");
- this.nicklist.addEvent("click", this.removePrevMenu.bind(this));
- ui.qjsui.applyClasses("nicklist", this.nicklist);
- }
- if(type == qwebirc.ui.WINDOW_CHANNEL)
- this.updateTopic("");
- this.nicksColoured = conf.ui.nick_colors;
- this.reflow();
- },
- editTopic: function() {
- if(!this.session.irc.nickOnChanHasAtLeastPrefix(this.session.irc.nickname, this.name, "+", true)) {
- /* var cmodes = this.session.irc.getChannelModes(channel);
- if(cmodes.indexOf("t")) {*/
- alert("Sorry, you need to be a channel operator to change the topic!");
- return;
- /*}*/
- }
- var newTopic = prompt("Change topic of " + this.name + " to:", this.topic.topicText);
- if(newTopic === null)
- return;
- this.session.irc.exec("/TOPIC " + newTopic);
- },
- reflow: function() {
- ui.reflow();
- },
- onResize: function() {
- if(this.scrolleddown) {
- if(Browser.Engine.trident) {
- this.scrollToBottom.delay(5, this);
- } else {
- this.scrollToBottom();
- }
- } else if($defined(this.scrollpos)) {
- if(Browser.Engine.trident) {
- this.getScrollParent().scrollTo(this.scrollpos.x, this.scrollpos.y);
- } else {
- this.getScrollParent().scrollTo.delay(5, this, [this.scrollpos.x, this.scrollpos.y]);
- }
- }
- },
- createMenu: function(nick, parent) {
- var e = new Element("div");
- parent.appendChild(e);
- e.addClass("menu");
- var nickArray = [nick];
- qwebirc.ui.MENU_ITEMS().forEach(function(x) {
- if(!x.predicate || x.predicate !== true && !x.predicate.apply(this, nickArray))
- return;
- var e2 = new Element("a");
- e.appendChild(e2);
- e2.href = "#";
- e2.set("text", "- " + x.text);
- e2.addEvent("focus", function() { this.blur() }.bind(e2));
- e2.addEvent("click", function(ev) { new Event(ev.stop()); this.menuClick(x.fn); }.bind(this));
- }.bind(this));
- return e;
- },
- menuClick: function(fn) {
- /*
- this.prevNick.removeChild(this.prevNick.menu);
- this.prevNick.menu = null;
- */
- fn.bind(this)(this.prevNick.realNick);
- this.removePrevMenu();
- },
- moveMenuClass: function() {
- if(!this.prevNick)
- return;
- if(this.nicklist.firstChild == this.prevNick) {
- this.prevNick.removeClass("selected-middle");
- } else {
- this.prevNick.addClass("selected-middle");
- }
- },
- removePrevMenu: function() {
- if(!this.prevNick)
- return;
- this.prevNick.removeClass("selected");
- this.prevNick.removeClass("selected-middle");
- if(this.prevNick.menu)
- this.prevNick.removeChild(this.prevNick.menu);
- this.prevNick = null;
- },
- nickListAdd: function(nick, position) {
- var realNick = this.session.irc.stripPrefix(nick);
- var e = new Element("a");
- qwebirc.ui.insertAt(position, this.nicklist, e);
- e.href = "#";
- var span = new Element("span");
- if(conf.ui.nick_colors) {
- var colour = realNick.toHSBColour(this.session);
- if($defined(colour))
- span.setStyle("color", colour.rgbToHex());
- }
- span.set("text", nick);
- e.appendChild(span);
- e.realNick = realNick;
- e.addEvent("click", function(x) {
- if(this.prevNick == e) {
- this.removePrevMenu();
- return;
- }
- this.removePrevMenu();
- this.prevNick = e;
- e.addClass("selected");
- this.moveMenuClass();
- e.menu = this.createMenu(e.realNick, e);
- new Event(x).stop();
- }.bind(this));
- e.addEvent("focus", function() { this.blur() }.bind(e));
- this.moveMenuClass();
- return e;
- },
- nickListRemove: function(nick, stored) {
- this.nicklist.removeChild(stored);
- this.moveMenuClass();
- },
- updateTopic: function(topic) {
- var t = this.topic;
- while(t.firstChild)
- t.removeChild(t.firstChild);
- if(topic) {
- t.topicText = topic;
- this.parent(topic, t);
- } else {
- t.topicText = topic;
- var e = new Element("div");
- e.set("text", "(no topic set)");
- e.addClass("emptytopic");
- t.appendChild(e);
- }
- this.reflow();
- },
- select: function() {
- var inputVisible = this.type != qwebirc.ui.WINDOW_CUSTOM;
- this.tab.removeClass("tab-unselected");
- this.tab.addClass("tab-selected");
- ui.setLines(this.lines);
- ui.setChannelItems(this.nicklist, this.topic);
- ui.qjsui.showInput(inputVisible);
- ui.qjsui.showChannel($defined(this.nicklist));
- this.reflow();
- this.parent();
- if(inputVisible)
- ui.inputbox.focus();
- if(this.type == qwebirc.ui.WINDOW_CHANNEL && this.nicksColoured != conf.ui.nick_colors) {
- this.nicksColoured = conf.ui.nick_colors;
- var nodes = this.nicklist.childNodes;
- if(conf.ui.nick_colors) {
- for(var i=0;i<nodes.length;i++) {
- var e = nodes[i], span = e.firstChild;
- var colour = e.realNick.toHSBColour(this.session);
- if($defined(colour))
- span.setStyle("color", colour.rgbToHex());
- };
- } else {
- for(var i=0;i<nodes.length;i++) {
- var span = nodes[i].firstChild;
- span.setStyle("color", null);
- };
- }
- }
- },
- deselect: function() {
- this.parent();
- this.tab.removeClass("tab-selected");
- this.tab.addClass("tab-unselected");
- },
- addLine: function(type, line, colourClass) {
- var e = new Element("div");
- if(colourClass) {
- e.addClass(colourClass);
- } else if(this.lastcolour) {
- e.addClass("linestyle1");
- } else {
- e.addClass("linestyle2");
- }
- this.lastcolour = !this.lastcolour;
- this.parent(type, line, colourClass, e);
- },
- setHilighted: function(state) {
- var laststate = this.hilighted;
- this.parent(state);
- if(state == laststate)
- return;
- this.tab.removeClass("tab-hilight-activity");
- this.tab.removeClass("tab-hilight-us");
- this.tab.removeClass("tab-hilight-speech");
- switch(this.hilighted) {
- case qwebirc.ui.HILIGHT_US:
- this.tab.addClass("tab-hilight-us");
- break;
- case qwebirc.ui.HILIGHT_SPEECH:
- this.tab.addClass("tab-hilight-speech");
- break;
- case qwebirc.ui.HILIGHT_ACTIVITY:
- this.tab.addClass("tab-hilight-activity");
- break;
- }
- }
- });
Add Comment
Please, Sign In to add comment