├── .gitignore ├── README.md ├── etc └── config.php ├── examples └── saver.php ├── js ├── asc.gif ├── bg.gif ├── desc.gif ├── jquery.min.js ├── jquery.tablesorter.min.js ├── style.css └── vtip │ ├── css │ └── vtip.css │ ├── images │ └── vtip_arrow.png │ └── vtip-min.js ├── memcache.php └── src ├── display.functions.php ├── functions.php └── graph.functions.php /.gitignore: -------------------------------------------------------------------------------- 1 | etc/config.local.php 2 | bootstrap/ 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # memcache.php 2 | 3 | An APC-like stats/info page for your memcached servers. 4 | 5 | **THIS IS A WORK IN PROGRESS** 6 | 7 | ## Requirements 8 | 9 | * Twitter Bootstrap 2.0.2 10 | 11 | ## Setup 12 | 13 | * git clone this 14 | `wget http://getbootstrap.com/2.3.2/assets/bootstrap.zip && unzip bootstrap.zip` 15 | * make changes to `etc/config.local.php` (copy from `etc/config.php`) 16 | * Profit! 17 | 18 | ## Credit 19 | 20 | * [Harun Yayli](http://livebookmark.net/journal/2008/05/21/memcachephp-stats-like-apcphp/) 21 | * [Arthur Ejsmont](http://artur.ejsmont.org/blog/content/first-version-of-memcache-stats-script-based-on-memcachephp) 22 | -------------------------------------------------------------------------------- /etc/config.php: -------------------------------------------------------------------------------- 1 | connect('localhost', 11211); 5 | 6 | $file = 'big.txt'; 7 | $data = file_get_contents($file); 8 | 9 | for($i=0; $i<5000; $i++){ 10 | $start = rand(0,10000); 11 | $length = rand(50, 5000); 12 | $part = substr($data, $start, $length); 13 | $memcache_obj->set('book_'.md5($part), $part, false, 3600); 14 | } 15 | 16 | echo 'Saved'; 17 | 18 | ?> -------------------------------------------------------------------------------- /js/asc.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lagged/memcache.php/3cd42383db181ae31d0547f8f2a8ced1f27e4abe/js/asc.gif -------------------------------------------------------------------------------- /js/bg.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lagged/memcache.php/3cd42383db181ae31d0547f8f2a8ced1f27e4abe/js/bg.gif -------------------------------------------------------------------------------- /js/desc.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lagged/memcache.php/3cd42383db181ae31d0547f8f2a8ced1f27e4abe/js/desc.gif -------------------------------------------------------------------------------- /js/jquery.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery 1.2.6 - New Wave Javascript 3 | * 4 | * Copyright (c) 2008 John Resig (jquery.com) 5 | * Dual licensed under the MIT (MIT-LICENSE.txt) 6 | * and GPL (GPL-LICENSE.txt) licenses. 7 | * 8 | * $Date: 2008-05-24 14:22:17 -0400 (Sat, 24 May 2008) $ 9 | * $Rev: 5685 $ 10 | */ 11 | (function(){var _jQuery=window.jQuery,_$=window.$;var jQuery=window.jQuery=window.$=function(selector,context){return new jQuery.fn.init(selector,context);};var quickExpr=/^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/,isSimple=/^.[^:#\[\.]*$/,undefined;jQuery.fn=jQuery.prototype={init:function(selector,context){selector=selector||document;if(selector.nodeType){this[0]=selector;this.length=1;return this;}if(typeof selector=="string"){var match=quickExpr.exec(selector);if(match&&(match[1]||!context)){if(match[1])selector=jQuery.clean([match[1]],context);else{var elem=document.getElementById(match[3]);if(elem){if(elem.id!=match[3])return jQuery().find(selector);return jQuery(elem);}selector=[];}}else 12 | return jQuery(context).find(selector);}else if(jQuery.isFunction(selector))return jQuery(document)[jQuery.fn.ready?"ready":"load"](selector);return this.setArray(jQuery.makeArray(selector));},jquery:"1.2.6",size:function(){return this.length;},length:0,get:function(num){return num==undefined?jQuery.makeArray(this):this[num];},pushStack:function(elems){var ret=jQuery(elems);ret.prevObject=this;return ret;},setArray:function(elems){this.length=0;Array.prototype.push.apply(this,elems);return this;},each:function(callback,args){return jQuery.each(this,callback,args);},index:function(elem){var ret=-1;return jQuery.inArray(elem&&elem.jquery?elem[0]:elem,this);},attr:function(name,value,type){var options=name;if(name.constructor==String)if(value===undefined)return this[0]&&jQuery[type||"attr"](this[0],name);else{options={};options[name]=value;}return this.each(function(i){for(name in options)jQuery.attr(type?this.style:this,name,jQuery.prop(this,options[name],type,i,name));});},css:function(key,value){if((key=='width'||key=='height')&&parseFloat(value)<0)value=undefined;return this.attr(key,value,"curCSS");},text:function(text){if(typeof text!="object"&&text!=null)return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(text));var ret="";jQuery.each(text||this,function(){jQuery.each(this.childNodes,function(){if(this.nodeType!=8)ret+=this.nodeType!=1?this.nodeValue:jQuery.fn.text([this]);});});return ret;},wrapAll:function(html){if(this[0])jQuery(html,this[0].ownerDocument).clone().insertBefore(this[0]).map(function(){var elem=this;while(elem.firstChild)elem=elem.firstChild;return elem;}).append(this);return this;},wrapInner:function(html){return this.each(function(){jQuery(this).contents().wrapAll(html);});},wrap:function(html){return this.each(function(){jQuery(this).wrapAll(html);});},append:function(){return this.domManip(arguments,true,false,function(elem){if(this.nodeType==1)this.appendChild(elem);});},prepend:function(){return this.domManip(arguments,true,true,function(elem){if(this.nodeType==1)this.insertBefore(elem,this.firstChild);});},before:function(){return this.domManip(arguments,false,false,function(elem){this.parentNode.insertBefore(elem,this);});},after:function(){return this.domManip(arguments,false,true,function(elem){this.parentNode.insertBefore(elem,this.nextSibling);});},end:function(){return this.prevObject||jQuery([]);},find:function(selector){var elems=jQuery.map(this,function(elem){return jQuery.find(selector,elem);});return this.pushStack(/[^+>] [^+>]/.test(selector)||selector.indexOf("..")>-1?jQuery.unique(elems):elems);},clone:function(events){var ret=this.map(function(){if(jQuery.browser.msie&&!jQuery.isXMLDoc(this)){var clone=this.cloneNode(true),container=document.createElement("div");container.appendChild(clone);return jQuery.clean([container.innerHTML])[0];}else 13 | return this.cloneNode(true);});var clone=ret.find("*").andSelf().each(function(){if(this[expando]!=undefined)this[expando]=null;});if(events===true)this.find("*").andSelf().each(function(i){if(this.nodeType==3)return;var events=jQuery.data(this,"events");for(var type in events)for(var handler in events[type])jQuery.event.add(clone[i],type,events[type][handler],events[type][handler].data);});return ret;},filter:function(selector){return this.pushStack(jQuery.isFunction(selector)&&jQuery.grep(this,function(elem,i){return selector.call(elem,i);})||jQuery.multiFilter(selector,this));},not:function(selector){if(selector.constructor==String)if(isSimple.test(selector))return this.pushStack(jQuery.multiFilter(selector,this,true));else 14 | selector=jQuery.multiFilter(selector,this);var isArrayLike=selector.length&&selector[selector.length-1]!==undefined&&!selector.nodeType;return this.filter(function(){return isArrayLike?jQuery.inArray(this,selector)<0:this!=selector;});},add:function(selector){return this.pushStack(jQuery.unique(jQuery.merge(this.get(),typeof selector=='string'?jQuery(selector):jQuery.makeArray(selector))));},is:function(selector){return!!selector&&jQuery.multiFilter(selector,this).length>0;},hasClass:function(selector){return this.is("."+selector);},val:function(value){if(value==undefined){if(this.length){var elem=this[0];if(jQuery.nodeName(elem,"select")){var index=elem.selectedIndex,values=[],options=elem.options,one=elem.type=="select-one";if(index<0)return null;for(var i=one?index:0,max=one?index+1:options.length;i=0||jQuery.inArray(this.name,value)>=0);else if(jQuery.nodeName(this,"select")){var values=jQuery.makeArray(value);jQuery("option",this).each(function(){this.selected=(jQuery.inArray(this.value,values)>=0||jQuery.inArray(this.text,values)>=0);});if(!values.length)this.selectedIndex=-1;}else 16 | this.value=value;});},html:function(value){return value==undefined?(this[0]?this[0].innerHTML:null):this.empty().append(value);},replaceWith:function(value){return this.after(value).remove();},eq:function(i){return this.slice(i,i+1);},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments));},map:function(callback){return this.pushStack(jQuery.map(this,function(elem,i){return callback.call(elem,i,elem);}));},andSelf:function(){return this.add(this.prevObject);},data:function(key,value){var parts=key.split(".");parts[1]=parts[1]?"."+parts[1]:"";if(value===undefined){var data=this.triggerHandler("getData"+parts[1]+"!",[parts[0]]);if(data===undefined&&this.length)data=jQuery.data(this[0],key);return data===undefined&&parts[1]?this.data(parts[0]):data;}else 17 | return this.trigger("setData"+parts[1]+"!",[parts[0],value]).each(function(){jQuery.data(this,key,value);});},removeData:function(key){return this.each(function(){jQuery.removeData(this,key);});},domManip:function(args,table,reverse,callback){var clone=this.length>1,elems;return this.each(function(){if(!elems){elems=jQuery.clean(args,this.ownerDocument);if(reverse)elems.reverse();}var obj=this;if(table&&jQuery.nodeName(this,"table")&&jQuery.nodeName(elems[0],"tr"))obj=this.getElementsByTagName("tbody")[0]||this.appendChild(this.ownerDocument.createElement("tbody"));var scripts=jQuery([]);jQuery.each(elems,function(){var elem=clone?jQuery(this).clone(true)[0]:this;if(jQuery.nodeName(elem,"script"))scripts=scripts.add(elem);else{if(elem.nodeType==1)scripts=scripts.add(jQuery("script",elem).remove());callback.call(obj,elem);}});scripts.each(evalScript);});}};jQuery.fn.init.prototype=jQuery.fn;function evalScript(i,elem){if(elem.src)jQuery.ajax({url:elem.src,async:false,dataType:"script"});else 18 | jQuery.globalEval(elem.text||elem.textContent||elem.innerHTML||"");if(elem.parentNode)elem.parentNode.removeChild(elem);}function now(){return+new Date;}jQuery.extend=jQuery.fn.extend=function(){var target=arguments[0]||{},i=1,length=arguments.length,deep=false,options;if(target.constructor==Boolean){deep=target;target=arguments[1]||{};i=2;}if(typeof target!="object"&&typeof target!="function")target={};if(length==i){target=this;--i;}for(;i-1;}},swap:function(elem,options,callback){var old={};for(var name in options){old[name]=elem.style[name];elem.style[name]=options[name];}callback.call(elem);for(var name in options)elem.style[name]=old[name];},css:function(elem,name,force){if(name=="width"||name=="height"){var val,props={position:"absolute",visibility:"hidden",display:"block"},which=name=="width"?["Left","Right"]:["Top","Bottom"];function getWH(){val=name=="width"?elem.offsetWidth:elem.offsetHeight;var padding=0,border=0;jQuery.each(which,function(){padding+=parseFloat(jQuery.curCSS(elem,"padding"+this,true))||0;border+=parseFloat(jQuery.curCSS(elem,"border"+this+"Width",true))||0;});val-=Math.round(padding+border);}if(jQuery(elem).is(":visible"))getWH();else 22 | jQuery.swap(elem,props,getWH);return Math.max(0,val);}return jQuery.curCSS(elem,name,force);},curCSS:function(elem,name,force){var ret,style=elem.style;function color(elem){if(!jQuery.browser.safari)return false;var ret=defaultView.getComputedStyle(elem,null);return!ret||ret.getPropertyValue("color")=="";}if(name=="opacity"&&jQuery.browser.msie){ret=jQuery.attr(style,"opacity");return ret==""?"1":ret;}if(jQuery.browser.opera&&name=="display"){var save=style.outline;style.outline="0 solid black";style.outline=save;}if(name.match(/float/i))name=styleFloat;if(!force&&style&&style[name])ret=style[name];else if(defaultView.getComputedStyle){if(name.match(/float/i))name="float";name=name.replace(/([A-Z])/g,"-$1").toLowerCase();var computedStyle=defaultView.getComputedStyle(elem,null);if(computedStyle&&!color(elem))ret=computedStyle.getPropertyValue(name);else{var swap=[],stack=[],a=elem,i=0;for(;a&&color(a);a=a.parentNode)stack.unshift(a);for(;i]*?)\/>/g,function(all,front,tag){return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?all:front+">";});var tags=jQuery.trim(elem).toLowerCase(),div=context.createElement("div");var wrap=!tags.indexOf("",""]||!tags.indexOf("",""]||tags.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"","
"]||!tags.indexOf("",""]||(!tags.indexOf("",""]||!tags.indexOf("",""]||jQuery.browser.msie&&[1,"div
","
"]||[0,"",""];div.innerHTML=wrap[1]+elem+wrap[2];while(wrap[0]--)div=div.lastChild;if(jQuery.browser.msie){var tbody=!tags.indexOf(""&&tags.indexOf("=0;--j)if(jQuery.nodeName(tbody[j],"tbody")&&!tbody[j].childNodes.length)tbody[j].parentNode.removeChild(tbody[j]);if(/^\s/.test(elem))div.insertBefore(context.createTextNode(elem.match(/^\s*/)[0]),div.firstChild);}elem=jQuery.makeArray(div.childNodes);}if(elem.length===0&&(!jQuery.nodeName(elem,"form")&&!jQuery.nodeName(elem,"select")))return;if(elem[0]==undefined||jQuery.nodeName(elem,"form")||elem.options)ret.push(elem);else 23 | ret=jQuery.merge(ret,elem);});return ret;},attr:function(elem,name,value){if(!elem||elem.nodeType==3||elem.nodeType==8)return undefined;var notxml=!jQuery.isXMLDoc(elem),set=value!==undefined,msie=jQuery.browser.msie;name=notxml&&jQuery.props[name]||name;if(elem.tagName){var special=/href|src|style/.test(name);if(name=="selected"&&jQuery.browser.safari)elem.parentNode.selectedIndex;if(name in elem&¬xml&&!special){if(set){if(name=="type"&&jQuery.nodeName(elem,"input")&&elem.parentNode)throw"type property can't be changed";elem[name]=value;}if(jQuery.nodeName(elem,"form")&&elem.getAttributeNode(name))return elem.getAttributeNode(name).nodeValue;return elem[name];}if(msie&¬xml&&name=="style")return jQuery.attr(elem.style,"cssText",value);if(set)elem.setAttribute(name,""+value);var attr=msie&¬xml&&special?elem.getAttribute(name,2):elem.getAttribute(name);return attr===null?undefined:attr;}if(msie&&name=="opacity"){if(set){elem.zoom=1;elem.filter=(elem.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(value)+''=="NaN"?"":"alpha(opacity="+value*100+")");}return elem.filter&&elem.filter.indexOf("opacity=")>=0?(parseFloat(elem.filter.match(/opacity=([^)]*)/)[1])/100)+'':"";}name=name.replace(/-([a-z])/ig,function(all,letter){return letter.toUpperCase();});if(set)elem[name]=value;return elem[name];},trim:function(text){return(text||"").replace(/^\s+|\s+$/g,"");},makeArray:function(array){var ret=[];if(array!=null){var i=array.length;if(i==null||array.split||array.setInterval||array.call)ret[0]=array;else 24 | while(i)ret[--i]=array[i];}return ret;},inArray:function(elem,array){for(var i=0,length=array.length;i*",this).remove();while(this.firstChild)this.removeChild(this.firstChild);}},function(name,fn){jQuery.fn[name]=function(){return this.each(fn,arguments);};});jQuery.each(["Height","Width"],function(i,name){var type=name.toLowerCase();jQuery.fn[type]=function(size){return this[0]==window?jQuery.browser.opera&&document.body["client"+name]||jQuery.browser.safari&&window["inner"+name]||document.compatMode=="CSS1Compat"&&document.documentElement["client"+name]||document.body["client"+name]:this[0]==document?Math.max(Math.max(document.body["scroll"+name],document.documentElement["scroll"+name]),Math.max(document.body["offset"+name],document.documentElement["offset"+name])):size==undefined?(this.length?jQuery.css(this[0],type):null):this.css(type,size.constructor==String?size:size+"px");};});function num(elem,prop){return elem[0]&&parseInt(jQuery.curCSS(elem[0],prop,true),10)||0;}var chars=jQuery.browser.safari&&parseInt(jQuery.browser.version)<417?"(?:[\\w*_-]|\\\\.)":"(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",quickChild=new RegExp("^>\\s*("+chars+"+)"),quickID=new RegExp("^("+chars+"+)(#)("+chars+"+)"),quickClass=new RegExp("^([#.]?)("+chars+"*)");jQuery.extend({expr:{"":function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);},"#":function(a,i,m){return a.getAttribute("id")==m[2];},":":{lt:function(a,i,m){return im[3]-0;},nth:function(a,i,m){return m[3]-0==i;},eq:function(a,i,m){return m[3]-0==i;},first:function(a,i){return i==0;},last:function(a,i,m,r){return i==r.length-1;},even:function(a,i){return i%2==0;},odd:function(a,i){return i%2;},"first-child":function(a){return a.parentNode.getElementsByTagName("*")[0]==a;},"last-child":function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;},"only-child":function(a){return!jQuery.nth(a.parentNode.lastChild,2,"previousSibling");},parent:function(a){return a.firstChild;},empty:function(a){return!a.firstChild;},contains:function(a,i,m){return(a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;},visible:function(a){return"hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";},hidden:function(a){return"hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";},enabled:function(a){return!a.disabled;},disabled:function(a){return a.disabled;},checked:function(a){return a.checked;},selected:function(a){return a.selected||jQuery.attr(a,"selected");},text:function(a){return"text"==a.type;},radio:function(a){return"radio"==a.type;},checkbox:function(a){return"checkbox"==a.type;},file:function(a){return"file"==a.type;},password:function(a){return"password"==a.type;},submit:function(a){return"submit"==a.type;},image:function(a){return"image"==a.type;},reset:function(a){return"reset"==a.type;},button:function(a){return"button"==a.type||jQuery.nodeName(a,"button");},input:function(a){return/input|select|textarea|button/i.test(a.nodeName);},has:function(a,i,m){return jQuery.find(m[3],a).length;},header:function(a){return/h\d/i.test(a.nodeName);},animated:function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length;}}},parse:[/^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,/^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,new RegExp("^([:.#]*)("+chars+"+)")],multiFilter:function(expr,elems,not){var old,cur=[];while(expr&&expr!=old){old=expr;var f=jQuery.filter(expr,elems,not);expr=f.t.replace(/^\s*,\s*/,"");cur=not?elems=f.r:jQuery.merge(cur,f.r);}return cur;},find:function(t,context){if(typeof t!="string")return[t];if(context&&context.nodeType!=1&&context.nodeType!=9)return[];context=context||document;var ret=[context],done=[],last,nodeName;while(t&&last!=t){var r=[];last=t;t=jQuery.trim(t);var foundToken=false,re=quickChild,m=re.exec(t);if(m){nodeName=m[1].toUpperCase();for(var i=0;ret[i];i++)for(var c=ret[i].firstChild;c;c=c.nextSibling)if(c.nodeType==1&&(nodeName=="*"||c.nodeName.toUpperCase()==nodeName))r.push(c);ret=r;t=t.replace(re,"");if(t.indexOf(" ")==0)continue;foundToken=true;}else{re=/^([>+~])\s*(\w*)/i;if((m=re.exec(t))!=null){r=[];var merge={};nodeName=m[2].toUpperCase();m=m[1];for(var j=0,rl=ret.length;j=0;if(!not&&pass||not&&!pass)tmp.push(r[i]);}return tmp;},filter:function(t,r,not){var last;while(t&&t!=last){last=t;var p=jQuery.parse,m;for(var i=0;p[i];i++){m=p[i].exec(t);if(m){t=t.substring(m[0].length);m[2]=m[2].replace(/\\/g,"");break;}}if(!m)break;if(m[1]==":"&&m[2]=="not")r=isSimple.test(m[3])?jQuery.filter(m[3],r,true).r:jQuery(r).not(m[3]);else if(m[1]==".")r=jQuery.classFilter(r,m[2],not);else if(m[1]=="["){var tmp=[],type=m[3];for(var i=0,rl=r.length;i=0)^not)tmp.push(a);}r=tmp;}else if(m[1]==":"&&m[2]=="nth-child"){var merge={},tmp=[],test=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(m[3]=="even"&&"2n"||m[3]=="odd"&&"2n+1"||!/\D/.test(m[3])&&"0n+"+m[3]||m[3]),first=(test[1]+(test[2]||1))-0,last=test[3]-0;for(var i=0,rl=r.length;i=0)add=true;if(add^not)tmp.push(node);}r=tmp;}else{var fn=jQuery.expr[m[1]];if(typeof fn=="object")fn=fn[m[2]];if(typeof fn=="string")fn=eval("false||function(a,i){return "+fn+";}");r=jQuery.grep(r,function(elem,i){return fn(elem,i,m,r);},not);}}return{r:r,t:t};},dir:function(elem,dir){var matched=[],cur=elem[dir];while(cur&&cur!=document){if(cur.nodeType==1)matched.push(cur);cur=cur[dir];}return matched;},nth:function(cur,result,dir,elem){result=result||1;var num=0;for(;cur;cur=cur[dir])if(cur.nodeType==1&&++num==result)break;return cur;},sibling:function(n,elem){var r=[];for(;n;n=n.nextSibling){if(n.nodeType==1&&n!=elem)r.push(n);}return r;}});jQuery.event={add:function(elem,types,handler,data){if(elem.nodeType==3||elem.nodeType==8)return;if(jQuery.browser.msie&&elem.setInterval)elem=window;if(!handler.guid)handler.guid=this.guid++;if(data!=undefined){var fn=handler;handler=this.proxy(fn,function(){return fn.apply(this,arguments);});handler.data=data;}var events=jQuery.data(elem,"events")||jQuery.data(elem,"events",{}),handle=jQuery.data(elem,"handle")||jQuery.data(elem,"handle",function(){if(typeof jQuery!="undefined"&&!jQuery.event.triggered)return jQuery.event.handle.apply(arguments.callee.elem,arguments);});handle.elem=elem;jQuery.each(types.split(/\s+/),function(index,type){var parts=type.split(".");type=parts[0];handler.type=parts[1];var handlers=events[type];if(!handlers){handlers=events[type]={};if(!jQuery.event.special[type]||jQuery.event.special[type].setup.call(elem)===false){if(elem.addEventListener)elem.addEventListener(type,handle,false);else if(elem.attachEvent)elem.attachEvent("on"+type,handle);}}handlers[handler.guid]=handler;jQuery.event.global[type]=true;});elem=null;},guid:1,global:{},remove:function(elem,types,handler){if(elem.nodeType==3||elem.nodeType==8)return;var events=jQuery.data(elem,"events"),ret,index;if(events){if(types==undefined||(typeof types=="string"&&types.charAt(0)=="."))for(var type in events)this.remove(elem,type+(types||""));else{if(types.type){handler=types.handler;types=types.type;}jQuery.each(types.split(/\s+/),function(index,type){var parts=type.split(".");type=parts[0];if(events[type]){if(handler)delete events[type][handler.guid];else 26 | for(handler in events[type])if(!parts[1]||events[type][handler].type==parts[1])delete events[type][handler];for(ret in events[type])break;if(!ret){if(!jQuery.event.special[type]||jQuery.event.special[type].teardown.call(elem)===false){if(elem.removeEventListener)elem.removeEventListener(type,jQuery.data(elem,"handle"),false);else if(elem.detachEvent)elem.detachEvent("on"+type,jQuery.data(elem,"handle"));}ret=null;delete events[type];}}});}for(ret in events)break;if(!ret){var handle=jQuery.data(elem,"handle");if(handle)handle.elem=null;jQuery.removeData(elem,"events");jQuery.removeData(elem,"handle");}}},trigger:function(type,data,elem,donative,extra){data=jQuery.makeArray(data);if(type.indexOf("!")>=0){type=type.slice(0,-1);var exclusive=true;}if(!elem){if(this.global[type])jQuery("*").add([window,document]).trigger(type,data);}else{if(elem.nodeType==3||elem.nodeType==8)return undefined;var val,ret,fn=jQuery.isFunction(elem[type]||null),event=!data[0]||!data[0].preventDefault;if(event){data.unshift({type:type,target:elem,preventDefault:function(){},stopPropagation:function(){},timeStamp:now()});data[0][expando]=true;}data[0].type=type;if(exclusive)data[0].exclusive=true;var handle=jQuery.data(elem,"handle");if(handle)val=handle.apply(elem,data);if((!fn||(jQuery.nodeName(elem,'a')&&type=="click"))&&elem["on"+type]&&elem["on"+type].apply(elem,data)===false)val=false;if(event)data.shift();if(extra&&jQuery.isFunction(extra)){ret=extra.apply(elem,val==null?data:data.concat(val));if(ret!==undefined)val=ret;}if(fn&&donative!==false&&val!==false&&!(jQuery.nodeName(elem,'a')&&type=="click")){this.triggered=true;try{elem[type]();}catch(e){}}this.triggered=false;}return val;},handle:function(event){var val,ret,namespace,all,handlers;event=arguments[0]=jQuery.event.fix(event||window.event);namespace=event.type.split(".");event.type=namespace[0];namespace=namespace[1];all=!namespace&&!event.exclusive;handlers=(jQuery.data(this,"events")||{})[event.type];for(var j in handlers){var handler=handlers[j];if(all||handler.type==namespace){event.handler=handler;event.data=handler.data;ret=handler.apply(this,arguments);if(val!==false)val=ret;if(ret===false){event.preventDefault();event.stopPropagation();}}}return val;},fix:function(event){if(event[expando]==true)return event;var originalEvent=event;event={originalEvent:originalEvent};var props="altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target timeStamp toElement type view wheelDelta which".split(" ");for(var i=props.length;i;i--)event[props[i]]=originalEvent[props[i]];event[expando]=true;event.preventDefault=function(){if(originalEvent.preventDefault)originalEvent.preventDefault();originalEvent.returnValue=false;};event.stopPropagation=function(){if(originalEvent.stopPropagation)originalEvent.stopPropagation();originalEvent.cancelBubble=true;};event.timeStamp=event.timeStamp||now();if(!event.target)event.target=event.srcElement||document;if(event.target.nodeType==3)event.target=event.target.parentNode;if(!event.relatedTarget&&event.fromElement)event.relatedTarget=event.fromElement==event.target?event.toElement:event.fromElement;if(event.pageX==null&&event.clientX!=null){var doc=document.documentElement,body=document.body;event.pageX=event.clientX+(doc&&doc.scrollLeft||body&&body.scrollLeft||0)-(doc.clientLeft||0);event.pageY=event.clientY+(doc&&doc.scrollTop||body&&body.scrollTop||0)-(doc.clientTop||0);}if(!event.which&&((event.charCode||event.charCode===0)?event.charCode:event.keyCode))event.which=event.charCode||event.keyCode;if(!event.metaKey&&event.ctrlKey)event.metaKey=event.ctrlKey;if(!event.which&&event.button)event.which=(event.button&1?1:(event.button&2?3:(event.button&4?2:0)));return event;},proxy:function(fn,proxy){proxy.guid=fn.guid=fn.guid||proxy.guid||this.guid++;return proxy;},special:{ready:{setup:function(){bindReady();return;},teardown:function(){return;}},mouseenter:{setup:function(){if(jQuery.browser.msie)return false;jQuery(this).bind("mouseover",jQuery.event.special.mouseenter.handler);return true;},teardown:function(){if(jQuery.browser.msie)return false;jQuery(this).unbind("mouseover",jQuery.event.special.mouseenter.handler);return true;},handler:function(event){if(withinElement(event,this))return true;event.type="mouseenter";return jQuery.event.handle.apply(this,arguments);}},mouseleave:{setup:function(){if(jQuery.browser.msie)return false;jQuery(this).bind("mouseout",jQuery.event.special.mouseleave.handler);return true;},teardown:function(){if(jQuery.browser.msie)return false;jQuery(this).unbind("mouseout",jQuery.event.special.mouseleave.handler);return true;},handler:function(event){if(withinElement(event,this))return true;event.type="mouseleave";return jQuery.event.handle.apply(this,arguments);}}}};jQuery.fn.extend({bind:function(type,data,fn){return type=="unload"?this.one(type,data,fn):this.each(function(){jQuery.event.add(this,type,fn||data,fn&&data);});},one:function(type,data,fn){var one=jQuery.event.proxy(fn||data,function(event){jQuery(this).unbind(event,one);return(fn||data).apply(this,arguments);});return this.each(function(){jQuery.event.add(this,type,one,fn&&data);});},unbind:function(type,fn){return this.each(function(){jQuery.event.remove(this,type,fn);});},trigger:function(type,data,fn){return this.each(function(){jQuery.event.trigger(type,data,this,true,fn);});},triggerHandler:function(type,data,fn){return this[0]&&jQuery.event.trigger(type,data,this[0],false,fn);},toggle:function(fn){var args=arguments,i=1;while(i=0){var selector=url.slice(off,url.length);url=url.slice(0,off);}callback=callback||function(){};var type="GET";if(params)if(jQuery.isFunction(params)){callback=params;params=null;}else{params=jQuery.param(params);type="POST";}var self=this;jQuery.ajax({url:url,type:type,dataType:"html",data:params,complete:function(res,status){if(status=="success"||status=="notmodified")self.html(selector?jQuery("
").append(res.responseText.replace(//g,"")).find(selector):res.responseText);self.each(callback,[res.responseText,status,res]);}});return this;},serialize:function(){return jQuery.param(this.serializeArray());},serializeArray:function(){return this.map(function(){return jQuery.nodeName(this,"form")?jQuery.makeArray(this.elements):this;}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password/i.test(this.type));}).map(function(i,elem){var val=jQuery(this).val();return val==null?null:val.constructor==Array?jQuery.map(val,function(val,i){return{name:elem.name,value:val};}):{name:elem.name,value:val};}).get();}});jQuery.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(i,o){jQuery.fn[o]=function(f){return this.bind(o,f);};});var jsc=now();jQuery.extend({get:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data=null;}return jQuery.ajax({type:"GET",url:url,data:data,success:callback,dataType:type});},getScript:function(url,callback){return jQuery.get(url,null,callback,"script");},getJSON:function(url,data,callback){return jQuery.get(url,data,callback,"json");},post:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data={};}return jQuery.ajax({type:"POST",url:url,data:data,success:callback,dataType:type});},ajaxSetup:function(settings){jQuery.extend(jQuery.ajaxSettings,settings);},ajaxSettings:{url:location.href,global:true,type:"GET",timeout:0,contentType:"application/x-www-form-urlencoded",processData:true,async:true,data:null,username:null,password:null,accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(s){s=jQuery.extend(true,s,jQuery.extend(true,{},jQuery.ajaxSettings,s));var jsonp,jsre=/=\?(&|$)/g,status,data,type=s.type.toUpperCase();if(s.data&&s.processData&&typeof s.data!="string")s.data=jQuery.param(s.data);if(s.dataType=="jsonp"){if(type=="GET"){if(!s.url.match(jsre))s.url+=(s.url.match(/\?/)?"&":"?")+(s.jsonp||"callback")+"=?";}else if(!s.data||!s.data.match(jsre))s.data=(s.data?s.data+"&":"")+(s.jsonp||"callback")+"=?";s.dataType="json";}if(s.dataType=="json"&&(s.data&&s.data.match(jsre)||s.url.match(jsre))){jsonp="jsonp"+jsc++;if(s.data)s.data=(s.data+"").replace(jsre,"="+jsonp+"$1");s.url=s.url.replace(jsre,"="+jsonp+"$1");s.dataType="script";window[jsonp]=function(tmp){data=tmp;success();complete();window[jsonp]=undefined;try{delete window[jsonp];}catch(e){}if(head)head.removeChild(script);};}if(s.dataType=="script"&&s.cache==null)s.cache=false;if(s.cache===false&&type=="GET"){var ts=now();var ret=s.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+ts+"$2");s.url=ret+((ret==s.url)?(s.url.match(/\?/)?"&":"?")+"_="+ts:"");}if(s.data&&type=="GET"){s.url+=(s.url.match(/\?/)?"&":"?")+s.data;s.data=null;}if(s.global&&!jQuery.active++)jQuery.event.trigger("ajaxStart");var remote=/^(?:\w+:)?\/\/([^\/?#]+)/;if(s.dataType=="script"&&type=="GET"&&remote.test(s.url)&&remote.exec(s.url)[1]!=location.host){var head=document.getElementsByTagName("head")[0];var script=document.createElement("script");script.src=s.url;if(s.scriptCharset)script.charset=s.scriptCharset;if(!jsonp){var done=false;script.onload=script.onreadystatechange=function(){if(!done&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){done=true;success();complete();head.removeChild(script);}};}head.appendChild(script);return undefined;}var requestDone=false;var xhr=window.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest();if(s.username)xhr.open(type,s.url,s.async,s.username,s.password);else 28 | xhr.open(type,s.url,s.async);try{if(s.data)xhr.setRequestHeader("Content-Type",s.contentType);if(s.ifModified)xhr.setRequestHeader("If-Modified-Since",jQuery.lastModified[s.url]||"Thu, 01 Jan 1970 00:00:00 GMT");xhr.setRequestHeader("X-Requested-With","XMLHttpRequest");xhr.setRequestHeader("Accept",s.dataType&&s.accepts[s.dataType]?s.accepts[s.dataType]+", */*":s.accepts._default);}catch(e){}if(s.beforeSend&&s.beforeSend(xhr,s)===false){s.global&&jQuery.active--;xhr.abort();return false;}if(s.global)jQuery.event.trigger("ajaxSend",[xhr,s]);var onreadystatechange=function(isTimeout){if(!requestDone&&xhr&&(xhr.readyState==4||isTimeout=="timeout")){requestDone=true;if(ival){clearInterval(ival);ival=null;}status=isTimeout=="timeout"&&"timeout"||!jQuery.httpSuccess(xhr)&&"error"||s.ifModified&&jQuery.httpNotModified(xhr,s.url)&&"notmodified"||"success";if(status=="success"){try{data=jQuery.httpData(xhr,s.dataType,s.dataFilter);}catch(e){status="parsererror";}}if(status=="success"){var modRes;try{modRes=xhr.getResponseHeader("Last-Modified");}catch(e){}if(s.ifModified&&modRes)jQuery.lastModified[s.url]=modRes;if(!jsonp)success();}else 29 | jQuery.handleError(s,xhr,status);complete();if(s.async)xhr=null;}};if(s.async){var ival=setInterval(onreadystatechange,13);if(s.timeout>0)setTimeout(function(){if(xhr){xhr.abort();if(!requestDone)onreadystatechange("timeout");}},s.timeout);}try{xhr.send(s.data);}catch(e){jQuery.handleError(s,xhr,null,e);}if(!s.async)onreadystatechange();function success(){if(s.success)s.success(data,status);if(s.global)jQuery.event.trigger("ajaxSuccess",[xhr,s]);}function complete(){if(s.complete)s.complete(xhr,status);if(s.global)jQuery.event.trigger("ajaxComplete",[xhr,s]);if(s.global&&!--jQuery.active)jQuery.event.trigger("ajaxStop");}return xhr;},handleError:function(s,xhr,status,e){if(s.error)s.error(xhr,status,e);if(s.global)jQuery.event.trigger("ajaxError",[xhr,s,e]);},active:0,httpSuccess:function(xhr){try{return!xhr.status&&location.protocol=="file:"||(xhr.status>=200&&xhr.status<300)||xhr.status==304||xhr.status==1223||jQuery.browser.safari&&xhr.status==undefined;}catch(e){}return false;},httpNotModified:function(xhr,url){try{var xhrRes=xhr.getResponseHeader("Last-Modified");return xhr.status==304||xhrRes==jQuery.lastModified[url]||jQuery.browser.safari&&xhr.status==undefined;}catch(e){}return false;},httpData:function(xhr,type,filter){var ct=xhr.getResponseHeader("content-type"),xml=type=="xml"||!type&&ct&&ct.indexOf("xml")>=0,data=xml?xhr.responseXML:xhr.responseText;if(xml&&data.documentElement.tagName=="parsererror")throw"parsererror";if(filter)data=filter(data,type);if(type=="script")jQuery.globalEval(data);if(type=="json")data=eval("("+data+")");return data;},param:function(a){var s=[];if(a.constructor==Array||a.jquery)jQuery.each(a,function(){s.push(encodeURIComponent(this.name)+"="+encodeURIComponent(this.value));});else 30 | for(var j in a)if(a[j]&&a[j].constructor==Array)jQuery.each(a[j],function(){s.push(encodeURIComponent(j)+"="+encodeURIComponent(this));});else 31 | s.push(encodeURIComponent(j)+"="+encodeURIComponent(jQuery.isFunction(a[j])?a[j]():a[j]));return s.join("&").replace(/%20/g,"+");}});jQuery.fn.extend({show:function(speed,callback){return speed?this.animate({height:"show",width:"show",opacity:"show"},speed,callback):this.filter(":hidden").each(function(){this.style.display=this.oldblock||"";if(jQuery.css(this,"display")=="none"){var elem=jQuery("<"+this.tagName+" />").appendTo("body");this.style.display=elem.css("display");if(this.style.display=="none")this.style.display="block";elem.remove();}}).end();},hide:function(speed,callback){return speed?this.animate({height:"hide",width:"hide",opacity:"hide"},speed,callback):this.filter(":visible").each(function(){this.oldblock=this.oldblock||jQuery.css(this,"display");this.style.display="none";}).end();},_toggle:jQuery.fn.toggle,toggle:function(fn,fn2){return jQuery.isFunction(fn)&&jQuery.isFunction(fn2)?this._toggle.apply(this,arguments):fn?this.animate({height:"toggle",width:"toggle",opacity:"toggle"},fn,fn2):this.each(function(){jQuery(this)[jQuery(this).is(":hidden")?"show":"hide"]();});},slideDown:function(speed,callback){return this.animate({height:"show"},speed,callback);},slideUp:function(speed,callback){return this.animate({height:"hide"},speed,callback);},slideToggle:function(speed,callback){return this.animate({height:"toggle"},speed,callback);},fadeIn:function(speed,callback){return this.animate({opacity:"show"},speed,callback);},fadeOut:function(speed,callback){return this.animate({opacity:"hide"},speed,callback);},fadeTo:function(speed,to,callback){return this.animate({opacity:to},speed,callback);},animate:function(prop,speed,easing,callback){var optall=jQuery.speed(speed,easing,callback);return this[optall.queue===false?"each":"queue"](function(){if(this.nodeType!=1)return false;var opt=jQuery.extend({},optall),p,hidden=jQuery(this).is(":hidden"),self=this;for(p in prop){if(prop[p]=="hide"&&hidden||prop[p]=="show"&&!hidden)return opt.complete.call(this);if(p=="height"||p=="width"){opt.display=jQuery.css(this,"display");opt.overflow=this.style.overflow;}}if(opt.overflow!=null)this.style.overflow="hidden";opt.curAnim=jQuery.extend({},prop);jQuery.each(prop,function(name,val){var e=new jQuery.fx(self,opt,name);if(/toggle|show|hide/.test(val))e[val=="toggle"?hidden?"show":"hide":val](prop);else{var parts=val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),start=e.cur(true)||0;if(parts){var end=parseFloat(parts[2]),unit=parts[3]||"px";if(unit!="px"){self.style[name]=(end||1)+unit;start=((end||1)/e.cur(true))*start;self.style[name]=start+unit;}if(parts[1])end=((parts[1]=="-="?-1:1)*end)+start;e.custom(start,end,unit);}else 32 | e.custom(start,val,"");}});return true;});},queue:function(type,fn){if(jQuery.isFunction(type)||(type&&type.constructor==Array)){fn=type;type="fx";}if(!type||(typeof type=="string"&&!fn))return queue(this[0],type);return this.each(function(){if(fn.constructor==Array)queue(this,type,fn);else{queue(this,type).push(fn);if(queue(this,type).length==1)fn.call(this);}});},stop:function(clearQueue,gotoEnd){var timers=jQuery.timers;if(clearQueue)this.queue([]);this.each(function(){for(var i=timers.length-1;i>=0;i--)if(timers[i].elem==this){if(gotoEnd)timers[i](true);timers.splice(i,1);}});if(!gotoEnd)this.dequeue();return this;}});var queue=function(elem,type,array){if(elem){type=type||"fx";var q=jQuery.data(elem,type+"queue");if(!q||array)q=jQuery.data(elem,type+"queue",jQuery.makeArray(array));}return q;};jQuery.fn.dequeue=function(type){type=type||"fx";return this.each(function(){var q=queue(this,type);q.shift();if(q.length)q[0].call(this);});};jQuery.extend({speed:function(speed,easing,fn){var opt=speed&&speed.constructor==Object?speed:{complete:fn||!fn&&easing||jQuery.isFunction(speed)&&speed,duration:speed,easing:fn&&easing||easing&&easing.constructor!=Function&&easing};opt.duration=(opt.duration&&opt.duration.constructor==Number?opt.duration:jQuery.fx.speeds[opt.duration])||jQuery.fx.speeds.def;opt.old=opt.complete;opt.complete=function(){if(opt.queue!==false)jQuery(this).dequeue();if(jQuery.isFunction(opt.old))opt.old.call(this);};return opt;},easing:{linear:function(p,n,firstNum,diff){return firstNum+diff*p;},swing:function(p,n,firstNum,diff){return((-Math.cos(p*Math.PI)/2)+0.5)*diff+firstNum;}},timers:[],timerId:null,fx:function(elem,options,prop){this.options=options;this.elem=elem;this.prop=prop;if(!options.orig)options.orig={};}});jQuery.fx.prototype={update:function(){if(this.options.step)this.options.step.call(this.elem,this.now,this);(jQuery.fx.step[this.prop]||jQuery.fx.step._default)(this);if(this.prop=="height"||this.prop=="width")this.elem.style.display="block";},cur:function(force){if(this.elem[this.prop]!=null&&this.elem.style[this.prop]==null)return this.elem[this.prop];var r=parseFloat(jQuery.css(this.elem,this.prop,force));return r&&r>-10000?r:parseFloat(jQuery.curCSS(this.elem,this.prop))||0;},custom:function(from,to,unit){this.startTime=now();this.start=from;this.end=to;this.unit=unit||this.unit||"px";this.now=this.start;this.pos=this.state=0;this.update();var self=this;function t(gotoEnd){return self.step(gotoEnd);}t.elem=this.elem;jQuery.timers.push(t);if(jQuery.timerId==null){jQuery.timerId=setInterval(function(){var timers=jQuery.timers;for(var i=0;ithis.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var done=true;for(var i in this.options.curAnim)if(this.options.curAnim[i]!==true)done=false;if(done){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(jQuery.css(this.elem,"display")=="none")this.elem.style.display="block";}if(this.options.hide)this.elem.style.display="none";if(this.options.hide||this.options.show)for(var p in this.options.curAnim)jQuery.attr(this.elem.style,p,this.options.orig[p]);}if(done)this.options.complete.call(this.elem);return false;}else{var n=t-this.startTime;this.state=n/this.options.duration;this.pos=jQuery.easing[this.options.easing||(jQuery.easing.swing?"swing":"linear")](this.state,n,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update();}return true;}};jQuery.extend(jQuery.fx,{speeds:{slow:600,fast:200,def:400},step:{scrollLeft:function(fx){fx.elem.scrollLeft=fx.now;},scrollTop:function(fx){fx.elem.scrollTop=fx.now;},opacity:function(fx){jQuery.attr(fx.elem.style,"opacity",fx.now);},_default:function(fx){fx.elem.style[fx.prop]=fx.now+fx.unit;}}});jQuery.fn.offset=function(){var left=0,top=0,elem=this[0],results;if(elem)with(jQuery.browser){var parent=elem.parentNode,offsetChild=elem,offsetParent=elem.offsetParent,doc=elem.ownerDocument,safari2=safari&&parseInt(version)<522&&!/adobeair/i.test(userAgent),css=jQuery.curCSS,fixed=css(elem,"position")=="fixed";if(elem.getBoundingClientRect){var box=elem.getBoundingClientRect();add(box.left+Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),box.top+Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));add(-doc.documentElement.clientLeft,-doc.documentElement.clientTop);}else{add(elem.offsetLeft,elem.offsetTop);while(offsetParent){add(offsetParent.offsetLeft,offsetParent.offsetTop);if(mozilla&&!/^t(able|d|h)$/i.test(offsetParent.tagName)||safari&&!safari2)border(offsetParent);if(!fixed&&css(offsetParent,"position")=="fixed")fixed=true;offsetChild=/^body$/i.test(offsetParent.tagName)?offsetChild:offsetParent;offsetParent=offsetParent.offsetParent;}while(parent&&parent.tagName&&!/^body|html$/i.test(parent.tagName)){if(!/^inline|table.*$/i.test(css(parent,"display")))add(-parent.scrollLeft,-parent.scrollTop);if(mozilla&&css(parent,"overflow")!="visible")border(parent);parent=parent.parentNode;}if((safari2&&(fixed||css(offsetChild,"position")=="absolute"))||(mozilla&&css(offsetChild,"position")!="absolute"))add(-doc.body.offsetLeft,-doc.body.offsetTop);if(fixed)add(Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));}results={top:top,left:left};}function border(elem){add(jQuery.curCSS(elem,"borderLeftWidth",true),jQuery.curCSS(elem,"borderTopWidth",true));}function add(l,t){left+=parseInt(l,10)||0;top+=parseInt(t,10)||0;}return results;};jQuery.fn.extend({position:function(){var left=0,top=0,results;if(this[0]){var offsetParent=this.offsetParent(),offset=this.offset(),parentOffset=/^body|html$/i.test(offsetParent[0].tagName)?{top:0,left:0}:offsetParent.offset();offset.top-=num(this,'marginTop');offset.left-=num(this,'marginLeft');parentOffset.top+=num(offsetParent,'borderTopWidth');parentOffset.left+=num(offsetParent,'borderLeftWidth');results={top:offset.top-parentOffset.top,left:offset.left-parentOffset.left};}return results;},offsetParent:function(){var offsetParent=this[0].offsetParent;while(offsetParent&&(!/^body|html$/i.test(offsetParent.tagName)&&jQuery.css(offsetParent,'position')=='static'))offsetParent=offsetParent.offsetParent;return jQuery(offsetParent);}});jQuery.each(['Left','Top'],function(i,name){var method='scroll'+name;jQuery.fn[method]=function(val){if(!this[0])return;return val!=undefined?this.each(function(){this==window||this==document?window.scrollTo(!i?val:jQuery(window).scrollLeft(),i?val:jQuery(window).scrollTop()):this[method]=val;}):this[0]==window||this[0]==document?self[i?'pageYOffset':'pageXOffset']||jQuery.boxModel&&document.documentElement[method]||document.body[method]:this[0][method];};});jQuery.each(["Height","Width"],function(i,name){var tl=i?"Left":"Top",br=i?"Right":"Bottom";jQuery.fn["inner"+name]=function(){return this[name.toLowerCase()]()+num(this,"padding"+tl)+num(this,"padding"+br);};jQuery.fn["outer"+name]=function(margin){return this["inner"+name]()+num(this,"border"+tl+"Width")+num(this,"border"+br+"Width")+(margin?num(this,"margin"+tl)+num(this,"margin"+br):0);};});})(); -------------------------------------------------------------------------------- /js/jquery.tablesorter.min.js: -------------------------------------------------------------------------------- 1 | 2 | (function($){$.extend({tablesorter:new function(){var parsers=[],widgets=[];this.defaults={cssHeader:"header",cssAsc:"headerSortUp",cssDesc:"headerSortDown",sortInitialOrder:"asc",sortMultiSortKey:"shiftKey",sortForce:null,sortAppend:null,textExtraction:"simple",parsers:{},widgets:[],widgetZebra:{css:["even","odd"]},headers:{},widthFixed:false,cancelSelection:true,sortList:[],headerList:[],dateFormat:"us",decimal:'.',debug:false};function benchmark(s,d){log(s+","+(new Date().getTime()-d.getTime())+"ms");}this.benchmark=benchmark;function log(s){if(typeof console!="undefined"&&typeof console.debug!="undefined"){console.log(s);}else{alert(s);}}function buildParserCache(table,$headers){if(table.config.debug){var parsersDebug="";}var rows=table.tBodies[0].rows;if(table.tBodies[0].rows[0]){var list=[],cells=rows[0].cells,l=cells.length;for(var i=0;i1){arr=arr.concat(checkCellColSpan(table,headerArr,row++));}else{if(table.tHead.length==1||(cell.rowSpan>1||!r[row+1])){arr.push(cell);}}}return arr;};function checkHeaderMetadata(cell){if(($.metadata)&&($(cell).metadata().sorter===false)){return true;};return false;}function checkHeaderOptions(table,i){if((table.config.headers[i])&&(table.config.headers[i].sorter===false)){return true;};return false;}function applyWidget(table){var c=table.config.widgets;var l=c.length;for(var i=0;i');$("tr:first td",table.tBodies[0]).each(function(){colgroup.append($('').css('width',$(this).width()));});$(table).prepend(colgroup);};}function updateHeaderSortCount(table,sortList){var c=table.config,l=sortList.length;for(var i=0;ib)?1:0));};function sortTextDesc(a,b){return((ba)?1:0));};function sortNumeric(a,b){return a-b;};function sortNumericDesc(a,b){return b-a;};function getCachedSortType(parsers,i){return parsers[i].type;};this.construct=function(settings){return this.each(function(){if(!this.tHead||!this.tBodies)return;var $this,$document,$headers,cache,config,shiftDown=0,sortOrder;this.config={};config=$.extend(this.config,$.tablesorter.defaults,settings);$this=$(this);$headers=buildHeaders(this);this.config.parsers=buildParserCache(this,$headers);cache=buildCache(this);var sortCSS=[config.cssDesc,config.cssAsc];fixColumnWidth(this);$headers.click(function(e){$this.trigger("sortStart");var totalRows=($this[0].tBodies[0]&&$this[0].tBodies[0].rows.length)||0;if(!this.sortDisabled&&totalRows>0){var $cell=$(this);var i=this.column;this.order=this.count++%2;if(!e[config.sortMultiSortKey]){config.sortList=[];if(config.sortForce!=null){var a=config.sortForce;for(var j=0;j0){$this.trigger("sorton",[config.sortList]);}applyWidget(this);});};this.addParser=function(parser){var l=parsers.length,a=true;for(var i=0;i'+this.t+"

");$("p#vtip #vtipArrow").attr("src","images/vtip_arrow.png");$("p#vtip").css("top",this.top+"px").css("left",this.left+"px").fadeIn("slow")},function(){this.title=this.t;$("p#vtip").fadeOut("slow").remove()}).mousemove(function(a){this.top=(a.pageY+yOffset);this.left=(a.pageX+xOffset);$("p#vtip").css("top",this.top+"px").css("left",this.left+"px")})};jQuery(document).ready(function(a){vtip()}); -------------------------------------------------------------------------------- /memcache.php: -------------------------------------------------------------------------------- 1 | | 17 | | Modifications by: Artur Ejsmont http://artur.ejsmont.org | 18 | | Till Klampaeckel | 19 | +----------------------------------------------------------------------+ 20 | */ 21 | 22 | $VERSION='$Id: modified memcache.php,v 1.1.2.3 2008/08/28 18:07:54 mikl Exp $'; 23 | 24 | /** 25 | * This allows us to override the path to the local configuration before including 26 | * 'memcache.php'. Pretty cool, no? 27 | */ 28 | if (!isset($localConfig) || empty($localConfig)) { 29 | $localConfig = __DIR__ . '/etc/config.local.php'; 30 | } 31 | 32 | if (true === file_exists($localConfig)) { 33 | require_once $localConfig; 34 | } else { 35 | require_once __DIR__ . '/etc/config.php'; 36 | } 37 | 38 | ////////// END OF DEFAULT CONFIG AREA ///////////////////////////////////////////////////////////// 39 | 40 | ///////////////// Password protect //////////////////////////////////////////////////////////////// 41 | if (defined('ADMIN_USERNAME') && ADMIN_USERNAME != '') { 42 | if (!isset($_SERVER['PHP_AUTH_USER']) 43 | || !isset($_SERVER['PHP_AUTH_PW']) 44 | || $_SERVER['PHP_AUTH_USER'] != ADMIN_USERNAME 45 | || $_SERVER['PHP_AUTH_PW'] != ADMIN_PASSWORD 46 | ) { 47 | Header("WWW-Authenticate: Basic realm=\"Memcache Login\""); 48 | Header("HTTP/1.0 401 Unauthorized"); 49 | 50 | echo << 52 |

Rejected!

53 | Wrong Username or Password! 54 | 55 | EOB; 56 | exit(1); 57 | } 58 | } 59 | 60 | // so oldschool :-) 61 | require_once __DIR__ . '/src/functions.php'; 62 | require_once __DIR__ . '/src/display.functions.php'; 63 | 64 | // 65 | // don't cache this page 66 | // 67 | header("Cache-Control: no-store, no-cache, must-revalidate"); // HTTP/1.1 68 | header("Cache-Control: post-check=0, pre-check=0", false); 69 | header("Pragma: no-cache"); // HTTP/1.0 70 | 71 | function duration($ts) { 72 | global $time; 73 | $years = (int)((($time - $ts)/(7*86400))/52.177457); 74 | $rem = (int)(($time-$ts)-($years * 52.177457 * 7 * 86400)); 75 | $weeks = (int)(($rem)/(7*86400)); 76 | $days = (int)(($rem)/86400) - $weeks*7; 77 | $hours = (int)(($rem)/3600) - $days*24 - $weeks*7*24; 78 | $mins = (int)(($rem)/60) - $hours*60 - $days*24*60 - $weeks*7*24*60; 79 | $str = ''; 80 | if($years==1) $str .= "$years year, "; 81 | if($years>1) $str .= "$years years, "; 82 | if($weeks==1) $str .= "$weeks week, "; 83 | if($weeks>1) $str .= "$weeks weeks, "; 84 | if($days==1) $str .= "$days day,"; 85 | if($days>1) $str .= "$days days,"; 86 | if($hours == 1) $str .= " $hours hour and"; 87 | if($hours>1) $str .= " $hours hours and"; 88 | if($mins == 1) $str .= " 1 minute"; 89 | else $str .= " $mins minutes"; 90 | return $str; 91 | } 92 | 93 | // TODO, AUTH 94 | 95 | $PHP_SELF = getUrl(); 96 | 97 | $_GET['op'] = !isset($_GET['op'])? '1':$_GET['op']; 98 | $time = time(); 99 | 100 | $_GET = filter_input_array(INPUT_GET); 101 | 102 | // singleout 103 | // when singleout is set, it only gives details for that server. 104 | if (isset($_GET['singleout']) && $_GET['singleout']>=0 && $_GET['singleout'] $mcs) { 138 | $free = $mcs['STAT']['limit_maxbytes']-$mcs['STAT']['bytes']; 139 | $used = $mcs['STAT']['bytes']; 140 | 141 | 142 | if ($free>0){ 143 | // draw free 144 | $angle_to = ($free*360)/$tsize; 145 | $perc =sprintf("%.2f%%", ($free *100) / $tsize) ; 146 | 147 | fill_arc($image,$x,$y,$size,$angle_from,$angle_from + $angle_to ,$col_black,$col_green,$perc); 148 | $angle_from = $angle_from + $angle_to ; 149 | } 150 | if ($used>0){ 151 | // draw used 152 | $angle_to = ($used*360)/$tsize; 153 | $perc =sprintf("%.2f%%", ($used *100) / $tsize) ; 154 | fill_arc($image,$x,$y,$size,$angle_from,$angle_from + $angle_to ,$col_black,$col_red, '('.$perc.')' ); 155 | $angle_from = $angle_from+ $angle_to ; 156 | } 157 | } 158 | 159 | break; 160 | 161 | case 2: // hit miss 162 | 163 | $hits = ($memcacheStats['get_hits']==0) ? 1:$memcacheStats['get_hits']; 164 | $misses = ($memcacheStats['get_misses']==0) ? 1:$memcacheStats['get_misses']; 165 | $total = $hits + $misses ; 166 | 167 | fill_box($image, 30,$size,50,-$hits*($size-21)/$total,$col_black,$col_green,sprintf("%.1f%%",$hits*100/$total)); 168 | fill_box($image,130,$size,50,-max(4,($total-$hits)*($size-21)/$total),$col_black,$col_red,sprintf("%.1f%%",$misses*100/$total)); 169 | break; 170 | } 171 | header("Content-type: image/png"); 172 | imagepng($image); 173 | exit; 174 | } 175 | 176 | if (RUN_WRAPPED !== true) { 177 | echo getHeader(); 178 | } 179 | echo getMenu(); 180 | 181 | switch ($_GET['op']) { 182 | 183 | default: 184 | case 1: // host stats 185 | $phpversion = phpversion(); 186 | $memcacheStats = getMemcacheStats(); 187 | $memcacheStatsSingle = getMemcacheStats(false); 188 | $memcacheVersion = getMemcacheVersion(); 189 | 190 | $mem_size = $memcacheStats['limit_maxbytes']; 191 | $mem_used = $memcacheStats['bytes']; 192 | $mem_avail= $mem_size-$mem_used; 193 | $startTime = time()-array_sum($memcacheStats['uptime']); 194 | 195 | $curr_items = $memcacheStats['curr_items']; 196 | $total_items = $memcacheStats['total_items']; 197 | $hits = ($memcacheStats['get_hits']==0) ? 1:$memcacheStats['get_hits']; 198 | $misses = ($memcacheStats['get_misses']==0) ? 1:$memcacheStats['get_misses']; 199 | $sets = $memcacheStats['cmd_set']; 200 | 201 | $req_rate = sprintf("%.2f",($hits+$misses)/($time-$startTime)); 202 | $hit_rate = sprintf("%.2f",($hits)/($time-$startTime)); 203 | $miss_rate = sprintf("%.2f",($misses)/($time-$startTime)); 204 | $set_rate = sprintf("%.2f",($sets)/($time-$startTime)); 205 | 206 | echo << 208 |
209 | 210 |

Host Status Diagrams

211 | 212 | EOB; 213 | 214 | $size='width='.(GRAPH_SIZE+50).' height='.(GRAPH_SIZE+10); 215 | echo << 217 | 218 | 219 | 220 | 221 | 222 | EOB; 223 | 224 | echo 225 | graphics_avail() ? 226 | ''. 227 | "". 228 | "\n" 229 | : "", 230 | '', 231 | '\n", 232 | '\n", 233 | '', 234 | '', 235 | '\n", 236 | '\n"; 237 | echo << 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 |
Cache UsageHits & Misses
\"\"\"\"
Free ',bsize($mem_avail).sprintf(" (%.1f%%)",$mem_avail*100/$mem_size),"Hits ',$hits.sprintf(" (%.1f%%)",$hits*100/($hits+$misses)),"
Used ',bsize($mem_used ).sprintf(" (%.1f%%)",$mem_used *100/$mem_size),"Misses ',$misses.sprintf(" (%.1f%%)",$misses*100/($hits+$misses)),"Current Items $curr_itemsReq. Rate (hits, misses) $req_rate rps
Total $total_itemsHit Rate $hit_rate rps
 Miss Rate $miss_rate rps
 Set Rate $set_rate rps
254 |
255 | 256 |
257 |

Cache Information

258 | 259 | EOB; 260 | foreach($GLOBALS['MEMCACHE_SERVERS'] as $server){ 261 | echo ''; 262 | echo ''; 263 | echo ''; 264 | echo ''; 265 | echo ''; 266 | echo ''; 267 | echo ''; 268 | echo ''; 269 | echo ''; 270 | echo ''; 271 | 272 | echo ''; 277 | } 278 | 279 | echo ' 280 |
 '.$server.'
Current Connections Count',(int)($memcacheStatsSingle[$server]['STAT']['curr_connections']),'
Total Connections So Far',(int)($memcacheStatsSingle[$server]['STAT']['total_connections']),'
Flush CMD count',(int)($memcacheStatsSingle[$server]['STAT']['cmd_flush']),'
Get CMD count',(int)($memcacheStatsSingle[$server]['STAT']['cmd_get']),'
Set CMD count',(int)($memcacheStatsSingle[$server]['STAT']['cmd_set']),'
Items Evicted So Far',(int)($memcacheStatsSingle[$server]['STAT']['evictions']),'
Bytes Read So Far',bsize($memcacheStatsSingle[$server]['STAT']['bytes_read']),'
Bytes Written So Far',bsize($memcacheStatsSingle[$server]['STAT']['bytes_written']),'
Uptime',duration($memcacheStatsSingle[$server]['STAT']['time']-$memcacheStatsSingle[$server]['STAT']['uptime']),'
273 | 274 | Reset stats 275 | 276 |
281 |
282 |
283 | 284 | '; 285 | 286 | 287 | 288 | 289 | 290 | echo <<< EOB 291 |
292 |
293 |

General Cache Information

294 | 295 | 296 | EOB; 297 | echo '\n"; 312 | echo '\n"; 313 | 314 | echo <<
PHP Version{$phpversion}
Memcached Host'. ((count($GLOBALS['MEMCACHE_SERVERS'])>1) ? 's':'').""; 298 | 299 | $i=0; 300 | if (!isset($_GET['singleout']) && count($GLOBALS['MEMCACHE_SERVERS'])>1){ 301 | foreach($GLOBALS['MEMCACHE_SERVERS'] as $server){ 302 | echo ($i+1).'. '.$server.'
'; 303 | } 304 | } 305 | else{ 306 | echo '1.'.$GLOBALS['MEMCACHE_SERVERS'][0]; 307 | } 308 | if (isset($_GET['singleout'])){ 309 | echo '(all servers)
'; 310 | } 311 | echo "
Max Memcache Size' . bsize($memcacheStats['limit_maxbytes'])."
316 |
317 |
318 |

Memcache Server Information

319 | EOB; 320 | foreach($GLOBALS['MEMCACHE_SERVERS'] as $server){ 321 | echo ''; 322 | echo ''; 327 | echo '"; 328 | echo ''; 329 | echo ''; 330 | echo ''; 331 | echo ''; 332 | echo ''; 333 | echo '
'.$server.' 323 | 324 | Flush server 325 | 326 |
Memcache Version' . ($memcacheVersion[$server]) . "
Start Time',date(DATE_FORMAT,$memcacheStatsSingle[$server]['STAT']['time']-$memcacheStatsSingle[$server]['STAT']['uptime']),'
Memcached Server Version'.$memcacheStatsSingle[$server]['STAT']['version'].'
Used Cache Size',bsize($memcacheStatsSingle[$server]['STAT']['bytes']),'
Max Cache Size',bsize($memcacheStatsSingle[$server]['STAT']['limit_maxbytes']),'
Threads',(int)($memcacheStatsSingle[$server]['STAT']['threads']),'
'; 334 | } 335 | echo << 337 |
338 | EOB; 339 | 340 | break; 341 | 342 | case 2: // variables 343 | 344 | $m=0; 345 | $cacheItems= getCacheItems(); 346 | $slabInfo= getAllSlabStats(); 347 | $items = $cacheItems['items']; 348 | $totals = $cacheItems['counts']; 349 | $maxDump = MAX_ITEM_DUMP; 350 | foreach($items as $server => $entries) { 351 | 352 | echo <<< EOB 353 | 354 | 355 | 356 | 357 | 358 | 359 | EOB; 360 | 361 | foreach($entries as $slabId => $slab) { 362 | $dumpUrl = $PHP_SELF.'&op=2&server='.(array_search($server,$GLOBALS['MEMCACHE_SERVERS'])).'&dumpslab='.$slabId; 363 | echo 364 | "", 365 | "", 366 | ""; 386 | $m=1-$m; 387 | } 388 | echo <<
$server
Slab IdInfo
",'',$slabId,'',"
367 | Item count: ",$slab['number'],'
368 | Chunk Size (max item size): ',(bsize($slabInfo[$server][$slabId]['chunk_size'])).'
369 | Chunks Per Page (items per 1MB): ',(($slabInfo[$server][$slabId]['chunks_per_page'])).'
370 | Pages Allocated: ',(($slabInfo[$server][$slabId]['total_pages'])).'
371 | Total Chunks (capacity): ',(($slabInfo[$server][$slabId]['total_chunks'])).'
372 | Used Chunks (capacity): ',(($slabInfo[$server][$slabId]['used_chunks'])).'
373 | Free Chunks (free capacity): ',(($slabInfo[$server][$slabId]['total_chunks'] - $slabInfo[$server][$slabId]['used_chunks'])).'
374 | Evicted: '.((int)$slab['evicted']).'
375 | Age: ',duration($time-$slab['age']),'
'; 376 | if ((isset($_GET['dumpslab']) && $_GET['dumpslab']==$slabId) && (isset($_GET['server']) && $_GET['server']==array_search($server,$GLOBALS['MEMCACHE_SERVERS']))){ 377 | echo "
Items: item
"; 378 | $items = dumpCacheSlab($server,$slabId,$slab['number']); 379 | ksort($items['ITEM']); 380 | foreach($items['ITEM'] as $itemKey=>$itemInfo){ 381 | echo ''.$itemKey.'
'; 382 | } 383 | } 384 | 385 | echo "
390 |
391 | EOB; 392 | } 393 | break; 394 | 395 | break; 396 | 397 | case 4: //item dump 398 | if (!isset($_GET['key']) || !isset($_GET['server'])){ 399 | echo "No key set!"; 400 | break; 401 | } 402 | // I'm not doing anything to check the validity of the key string. 403 | // probably an exploit can be written to delete all the files in key=base64_encode("\n\r delete all"). 404 | // somebody has to do a fix to this. 405 | $theKey = htmlentities(base64_decode($_GET['key'])); 406 | 407 | $theserver = $GLOBALS['MEMCACHE_SERVERS'][(int)$_GET['server']]; 408 | list($h,$p) = explode(':',$theserver); 409 | $r = sendMemcacheCommand($h,$p,'get '.$theKey); 410 | echo << 412 | ServerKeyValueDelete 413 | 414 | EOB; 415 | echo "",$theserver,"",$theKey, 416 | "
flag:",$r['VALUE'][$theKey]['stat']['flag'], 417 | "
Size:",bsize($r['VALUE'][$theKey]['stat']['size']), 418 | "",chunk_split($r['VALUE'][$theKey]['value'],40),"", 419 | 'Delete",""; 420 | echo << 422 |
423 | EOB; 424 | break; 425 | case 5: // item delete 426 | if (!isset($_GET['key']) || !isset($_GET['server'])){ 427 | echo "No key set!"; 428 | break; 429 | } 430 | $theKey = htmlentities(base64_decode($_GET['key'])); 431 | $theserver = $GLOBALS['MEMCACHE_SERVERS'][(int)$_GET['server']]; 432 | list($h,$p) = explode(':',$theserver); 433 | $r = sendMemcacheCommand($h,$p,'delete '.$theKey); 434 | echo 'Deleting '.$theKey.' : '.$r; 435 | break; 436 | 437 | case 6: // flush server 438 | $theserver = $GLOBALS['MEMCACHE_SERVERS'][(int)$_GET['server']]; 439 | $r = flushServer($theserver); 440 | echo 'Flush '.$theserver." : ".$r; 441 | break; 442 | case 7: // flush stats 443 | $theserver = $GLOBALS['MEMCACHE_SERVERS'][(int)$_GET['server']]; 444 | $r = flushStats($theserver); 445 | echo 'Stats reset '.$theserver." : ".print_r( $r,true); 446 | break; 447 | case 8: // variables 448 | $m=0; 449 | $cacheItems= getCacheItems(); 450 | $slabInfo = getAllSlabStats(); 451 | $items = $cacheItems['items']; 452 | $totals = $cacheItems['counts']; 453 | $maxDump = MAX_ITEM_DUMP; 454 | foreach($items as $server => $entries) { 455 | 456 | $memcacheStats = getMemcacheStats(); 457 | 458 | 459 | echo <<< EOB 460 | 461 |

$server

462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | EOB; 483 | 484 | foreach($entries as $slabId => $slab) { 485 | $itemsCount = $slab['number']; 486 | $chunkSize = $slabInfo[$server][$slabId]['chunk_size']; 487 | $itemsSpace = round(($itemsCount * $chunkSize * 100) / $memcacheStats['limit_maxbytes'], 3); 488 | 489 | $chunks_total = $slabInfo[$server][$slabId]['total_chunks']; 490 | $chunks_used = $slabInfo[$server][$slabId]['used_chunks']; 491 | 492 | $percentFree = round((($chunks_total - $chunks_used) * 100) / $chunks_total, 2); 493 | 494 | $totalBytes = $chunks_total * $chunkSize; 495 | $usedBytes = $slabInfo[$server][$slabId]['used_chunks'] * $chunkSize; 496 | $unusedBytes = $totalBytes - $usedBytes; 497 | 498 | $dumpUrl = $PHP_SELF.'&op=2&server='.(array_search($server,$GLOBALS['MEMCACHE_SERVERS'])).'&dumpslab='.$slabId; 499 | echo " 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | "; 517 | $m=1-$m; 518 | } 519 | echo <<
IdItemsChunk SizeChunks per pagePagesTotal ChunksUsed ChunksFree ChunksFree Bytes% of spaceEvictedEvicted timeAgeLink
".$slabId."".$itemsCount."".$chunkSize."".(($slabInfo[$server][$slabId]['chunks_per_page']))."".(($slabInfo[$server][$slabId]['total_pages']))."".$chunks_total."".$chunks_used."".($chunks_total - $chunks_used)."".$unusedBytes."".$itemsSpace."".(int)$slab['evicted']."".(int)$slab['evicted_time']."".duration($time-$slab['age'])."
details
521 |
522 | EOB; 523 | } 524 | break; 525 | 526 | break; 527 | 528 | } 529 | if (RUN_WRAPPED !== true) { 530 | echo getFooter(); 531 | } 532 | -------------------------------------------------------------------------------- /src/display.functions.php: -------------------------------------------------------------------------------- 1 | | 17 | | Modifications by: Artur Ejsmont http://artur.ejsmont.org | 18 | | Till Klampaeckel | 19 | +----------------------------------------------------------------------+ 20 | */ 21 | 22 | if (!isset($VERSION)) { 23 | echo "Not allowed."; 24 | exit(1); 25 | } 26 | 27 | // create graphics 28 | // 29 | function graphics_avail() { 30 | return extension_loaded('gd'); 31 | } 32 | 33 | function bsize($s) { 34 | foreach (array('','K','M','G') as $i => $k) { 35 | if ($s < 1024) break; 36 | $s/=1024; 37 | } 38 | return sprintf("%5.1f %sBytes",$s,$k); 39 | } 40 | 41 | /** 42 | * create menu entry 43 | * 44 | * @return string 45 | */ 46 | function menu_entry($ob,$title) { 47 | $PHP_SELF = getUrl(); 48 | if ($ob==$_GET['op']){ 49 | return "
  • {$title}
  • "; 50 | } 51 | return "
  • {$title}
  • "; 52 | } 53 | 54 | /** 55 | * Print the header when we run stand-alone. 56 | * 57 | * @return void 58 | */ 59 | function getHeader() 60 | { 61 | 62 | $jq_core = JQ_CORE; 63 | $jq_ts = JQ_TABLESORT; 64 | $base_url = BASE_URL; 65 | $PHP_SELF = getUrl(); 66 | 67 | $header = << 69 | 70 | MEMCACHE INFO 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 97 | 98 | 99 | 100 |
    101 | 127 | EOT; 128 | 129 | return $header; 130 | } 131 | function getFooter(){ 132 | $footer = ' 133 | 138 |
    139 | 140 | 141 | '; 142 | 143 | return $footer; 144 | 145 | } 146 | function getMenu(){ 147 | 148 | echo << | 17 | | Modifications by: Artur Ejsmont http://artur.ejsmont.org | 18 | | Till Klampaeckel | 19 | +----------------------------------------------------------------------+ 20 | */ 21 | 22 | if (!isset($VERSION)) { 23 | echo "Not allowed."; 24 | exit(1); 25 | } 26 | 27 | ///////////MEMCACHE FUNCTIONS ///////////////////////////////////////////////////////////////////// 28 | 29 | /** 30 | * Return the URL to this script so we can 31 | * adjust it via configuration. 32 | * 33 | * @return string 34 | */ 35 | function getUrl() { 36 | $url = MEMCACHE_SCRIPT; 37 | if (substr($url, -1) != '?') { 38 | $url .= '?'; 39 | } 40 | return $url; 41 | } 42 | 43 | function sendMemcacheCommands($command){ 44 | $result = array(); 45 | 46 | foreach($GLOBALS['MEMCACHE_SERVERS'] as $server){ 47 | if ( strstr($server, 'unix:') === false ){ 48 | list($host, $port) = explode(':', $server); 49 | } else { 50 | $host=$server; 51 | $port=-1; 52 | } 53 | $result[$server] = sendMemcacheCommand($host,$port,$command); 54 | } 55 | return $result; 56 | } 57 | function sendMemcacheCommand($server,$port,$command){ 58 | 59 | $s = @fsockopen($server,$port); 60 | if (!$s){ 61 | die("Cant connect to:".$server.':'.$port); 62 | } 63 | 64 | fwrite($s, $command."\r\n"); 65 | 66 | $buf=''; 67 | while ((!feof($s))) { 68 | $buf .= fgets($s, 256); 69 | if (strpos($buf,"END\r\n")!==false){ // stat says end 70 | break; 71 | } 72 | if (strpos($buf,"DELETED\r\n")!==false || strpos($buf,"NOT_FOUND\r\n")!==false){ // delete says these 73 | break; 74 | } 75 | if (strpos($buf,"OK\r\n")!==false){ // flush_all says ok 76 | break; 77 | } 78 | if (strpos($buf,"RESET\r\n")!==false){ // reset stats ok 79 | break; 80 | } 81 | if (strpos($buf,"VERSION ")!==false){ // version answer 82 | break; 83 | } 84 | } 85 | fclose($s); 86 | return parseMemcacheResults($buf); 87 | } 88 | function parseMemcacheResults($str){ 89 | $res = array(); 90 | $lines = explode("\r\n",$str); 91 | $cnt = count($lines); 92 | for($i=0; $i< $cnt; $i++){ 93 | $line = $lines[$i]; 94 | $l = explode(' ',$line,3); 95 | if (count($l)==3){ 96 | $res[$l[0]][$l[1]]=$l[2]; 97 | if ($l[0]=='VALUE'){ // next line is the value 98 | $res[$l[0]][$l[1]] = array(); 99 | list ($flag,$size)=explode(' ',$l[2]); 100 | $res[$l[0]][$l[1]]['stat']=array('flag'=>$flag,'size'=>$size); 101 | $res[$l[0]][$l[1]]['value']=$lines[++$i]; 102 | } 103 | }elseif( $l[0] == 'VERSION' ){ 104 | return $l[1]; 105 | }elseif($line=='DELETED' || $line=='NOT_FOUND' || $line=='OK' || $line=='RESET'){ 106 | return $line; 107 | } 108 | } 109 | return $res; 110 | } 111 | 112 | function dumpCacheSlab($server,$slabId,$limit){ 113 | list($host,$port) = explode(':', $server); 114 | $resp = sendMemcacheCommand($host,$port,'stats cachedump '.$slabId.' '.$limit); 115 | return $resp; 116 | } 117 | 118 | 119 | function getAllSlabStats(){ 120 | $entries = sendMemcacheCommands('stats slabs'); 121 | $slabs = array(); 122 | foreach($entries as $server => $stats){ 123 | $slabs[$server] = array(); 124 | if( isset($stats['STAT']) ){ 125 | foreach($stats['STAT'] as $keyinfo => $value){ 126 | if (preg_match('/(\d+?)\:(.+?)$/',$keyinfo,$matches)){ 127 | $slabs[$server][ $matches[1] ][ $matches[2] ] = $value; 128 | } 129 | } 130 | } 131 | } 132 | return $slabs; 133 | } 134 | function flushStats($server){ 135 | list($host,$port) = explode(':',$server); 136 | $resp = sendMemcacheCommand($host,$port,'stats reset'); 137 | return $resp; 138 | } 139 | 140 | function getMemcacheVersion(){ 141 | $entries = sendMemcacheCommands('version'); 142 | return $entries; 143 | } 144 | 145 | function flushServer($server){ 146 | return; 147 | 148 | list($host,$port) = explode(':',$server); 149 | $resp = sendMemcacheCommand($host,$port,'flush_all'); 150 | return $resp; 151 | } 152 | function getCacheItems(){ 153 | $items = sendMemcacheCommands('stats items'); 154 | $serverItems = array(); 155 | $totalItems = array(); 156 | foreach ($items as $server=>$itemlist){ 157 | $serverItems[$server] = array(); 158 | $totalItems[$server]=0; 159 | if (!isset($itemlist['STAT'])){ 160 | continue; 161 | } 162 | 163 | $iteminfo = $itemlist['STAT']; 164 | 165 | foreach($iteminfo as $keyinfo=>$value){ 166 | if (preg_match('/items\:(\d+?)\:(.+?)$/',$keyinfo,$matches)){ 167 | $serverItems[$server][$matches[1]][$matches[2]] = $value; 168 | if ($matches[2]=='number'){ 169 | $totalItems[$server] +=$value; 170 | } 171 | } 172 | } 173 | } 174 | return array('items'=>$serverItems,'counts'=>$totalItems); 175 | } 176 | function getMemcacheStats($total=true){ 177 | $resp = sendMemcacheCommands('stats'); 178 | if ($total){ 179 | $res = array(); 180 | foreach($resp as $server=>$r){ 181 | foreach($r['STAT'] as $key=>$row){ 182 | if (!isset($res[$key])){ 183 | $res[$key]=null; 184 | } 185 | switch ($key){ 186 | case 'pid': 187 | $res['pid'][$server]=$row; 188 | break; 189 | case 'uptime': 190 | $res['uptime'][$server]=$row; 191 | break; 192 | case 'time': 193 | $res['time'][$server]=$row; 194 | break; 195 | case 'version': 196 | $res['version'][$server]=$row; 197 | break; 198 | case 'pointer_size': 199 | $res['pointer_size'][$server]=$row; 200 | break; 201 | case 'rusage_user': 202 | $res['rusage_user'][$server]=$row; 203 | break; 204 | case 'rusage_system': 205 | $res['rusage_system'][$server]=$row; 206 | break; 207 | case 'curr_items': 208 | $res['curr_items']+=$row; 209 | break; 210 | case 'total_items': 211 | $res['total_items']+=$row; 212 | break; 213 | case 'bytes': 214 | $res['bytes']+=$row; 215 | break; 216 | case 'curr_connections': 217 | $res['curr_connections']+=$row; 218 | break; 219 | case 'total_connections': 220 | $res['total_connections']+=$row; 221 | break; 222 | case 'connection_structures': 223 | $res['connection_structures']+=$row; 224 | break; 225 | case 'cmd_get': 226 | $res['cmd_get']+=$row; 227 | break; 228 | case 'cmd_set': 229 | $res['cmd_set']+=$row; 230 | break; 231 | case 'get_hits': 232 | $res['get_hits']+=$row; 233 | break; 234 | case 'get_misses': 235 | $res['get_misses']+=$row; 236 | break; 237 | case 'evictions': 238 | $res['evictions']+=$row; 239 | break; 240 | case 'bytes_read': 241 | $res['bytes_read']+=$row; 242 | break; 243 | case 'bytes_written': 244 | $res['bytes_written']+=$row; 245 | break; 246 | case 'limit_maxbytes': 247 | $res['limit_maxbytes']+=$row; 248 | break; 249 | case 'threads': 250 | $res['rusage_system'][$server]=$row; 251 | break; 252 | } 253 | } 254 | } 255 | return $res; 256 | } 257 | return $resp; 258 | } 259 | 260 | ////////////////////////////////////////////////////// 261 | -------------------------------------------------------------------------------- /src/graph.functions.php: -------------------------------------------------------------------------------- 1 | | 17 | | Modifications by: Artur Ejsmont http://artur.ejsmont.org | 18 | | Till Klampaeckel | 19 | +----------------------------------------------------------------------+ 20 | */ 21 | 22 | if (!isset($VERSION)) { 23 | echo "Not allowed."; 24 | exit(1); 25 | } 26 | 27 | function fill_box($im, $x, $y, $w, $h, $color1, $color2,$text='',$placeindex='') { 28 | global $col_black; 29 | $x1=$x+$w-1; 30 | $y1=$y+$h-1; 31 | 32 | imagerectangle($im, $x, $y1, $x1+1, $y+1, $col_black); 33 | if($y1>$y) imagefilledrectangle($im, $x, $y, $x1, $y1, $color2); 34 | else imagefilledrectangle($im, $x, $y1, $x1, $y, $color2); 35 | imagerectangle($im, $x, $y1, $x1, $y, $color1); 36 | if ($text) { 37 | if ($placeindex>0) { 38 | 39 | if ($placeindex<16) 40 | { 41 | $px=5; 42 | $py=$placeindex*12+6; 43 | imagefilledrectangle($im, $px+90, $py+3, $px+90-4, $py-3, $color2); 44 | imageline($im,$x,$y+$h/2,$px+90,$py,$color2); 45 | imagestring($im,2,$px,$py-6,$text,$color1); 46 | 47 | } else { 48 | if ($placeindex<31) { 49 | $px=$x+40*2; 50 | $py=($placeindex-15)*12+6; 51 | } else { 52 | $px=$x+40*2+100*intval(($placeindex-15)/15); 53 | $py=($placeindex%15)*12+6; 54 | } 55 | imagefilledrectangle($im, $px, $py+3, $px-4, $py-3, $color2); 56 | imageline($im,$x+$w,$y+$h/2,$px,$py,$color2); 57 | imagestring($im,2,$px+2,$py-6,$text,$color1); 58 | } 59 | } else { 60 | imagestring($im,4,$x+5,$y1-16,$text,$color1); 61 | } 62 | } 63 | } 64 | 65 | function fill_arc($im, $centerX, $centerY, $diameter, $start, $end, $color1,$color2,$text='',$placeindex=0) { 66 | $r=$diameter/2; 67 | $w=deg2rad((360+$start+($end-$start)/2)%360); 68 | 69 | 70 | if (function_exists("imagefilledarc")) { 71 | // exists only if GD 2.0.1 is avaliable 72 | imagefilledarc($im, $centerX+1, $centerY+1, $diameter, $diameter, $start, $end, $color1, IMG_ARC_PIE); 73 | imagefilledarc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color2, IMG_ARC_PIE); 74 | imagefilledarc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color1, IMG_ARC_NOFILL|IMG_ARC_EDGED); 75 | } else { 76 | imagearc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color2); 77 | imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($start)) * $r, $centerY + sin(deg2rad($start)) * $r, $color2); 78 | imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($start+1)) * $r, $centerY + sin(deg2rad($start)) * $r, $color2); 79 | imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($end-1)) * $r, $centerY + sin(deg2rad($end)) * $r, $color2); 80 | imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($end)) * $r, $centerY + sin(deg2rad($end)) * $r, $color2); 81 | imagefill($im,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2, $color2); 82 | } 83 | if ($text) { 84 | if ($placeindex>0) { 85 | imageline($im,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$diameter, $placeindex*12,$color1); 86 | imagestring($im,4,$diameter, $placeindex*12,$text,$color1); 87 | 88 | } else { 89 | imagestring($im,4,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$text,$color1); 90 | } 91 | } 92 | } --------------------------------------------------------------------------------