var log=(function(){var getTree=function(data){var toStr=Object.prototype.toString,_=arguments,json=[],x=[],type=toStr.call(data).replace(/[\[\] ]|object/ig,'').toLowerCase()||(data?'object':data===null?'null':'undefined'),br='\n',iv=_[2]==void(0)?'':_[2]+'    ';if(iv.length>4*64){return json.push(k+'[ stack overflow > 32 ] ...')}var k=iv+(_[1]!==void(0)?'"'+_[1]+'":':'');if(type=='array'){var N=data.length;json.push(k+'['+(N?br:''));for(var i=0;i<N;i++){x.push(getTree(data[i],void(0),iv))}json.push(x.join(','+br),(N?br+iv:'')+']')}else if(type=='object'&&data instanceof Object){var N=0;for(var u in data){N++}json.push(k+'{'+(N?br:''));for(var u in data){if(u.indexOf('__')!=0&&data.hasOwnProperty(u)){var sub=data[u]&&data[u].Type?'YClass->'+data[u].Type:data[u];x.push(getTree(sub,u,iv))}}json.push(x.join(','+br),(N?br+iv:'')+'}')}else{data=data===void(0)||data===null?data:(type=='object'&&!(data instanceof Object))?'[Native object]':(type=='function'?'@Func':data.Type?'YClass->'+data.Type:data);json.push(k+(type=='string'?'"'+data+'"':data))}return json.join('')};var html=[],ie=!!window.ActiveXObject,ie6=!window.XMLHttpRequest,i=0,timer,ay=true;return function(){var dd=document.documentElement,db=document.body;if(!db){return}if(!log.outputBox){own=log.outputBox=document.body.appendChild(document.createElement('TEXTAREA'));own.oldStyle=own.style.cssText='width: 50%;height: 250px;overflow: auto;right: 0;bottom: 0;position: '+(ie6?'absolute':'fixed')+';border: none;background: #000;color: #aaa;font: 12px/1.5 verdana;z-index:99999999';own.onkeydown=function(e){e=e||window.event;if(ay){if(e.keyCode===27||e.keyCode===18){own.style.display='none'}else if(e.shiftKey){if(own.isMax){own.style.cssText=own.oldStyle}else{own.style.width='100%';own.style.height=ie6?Math.max(dd.clientHeight,db.clientHeight)+'px':'100%'}own.isMax=!own.isMax}}ay=false;setTimeout(function(){ay=true},36)}}else{own=log.outputBox}var data=getTree(arguments.length>1?[].slice.call(arguments):arguments[0]),time=new Date().toLocaleTimeString();html.push('( '+(++i)+' ) '+time+' \n'+data+'\n\n');clearTimeout(timer);timer=setTimeout(function(){own.value+=html.join('');html=[];own.scrollTop=own.scrollHeight;own.style.display='block'},10)}})();
(function() {
	var Tools, browser, Copy, __YOBJECT__, toStr, isType, YCLASS_TMP_DIV, DISPLAY_VALUE, tmpNodes;
    Tools= {};
	browser = {};
	isType = {};
	DISPLAY_VALUE = {};
	toStr = Object.prototype.toString;
    Copy = Array.prototype.slice;
	YCLASS_TMP_DIV = document.createElement('DIV');
	Tools.create = (function() {
		var temp = function() {};
		return function(obj) {
			temp.prototype = obj;
			return new temp
		}
	})();
    Tools.getObj = function (){
        var A, l, o;
        A= arguments;
        l = A.length;
        o = {};
        for (var i = 1; i < l; i += 2) {
            o[A[i-1]] = A[i]
        }
        return o
    };
	Tools.Try = function(text, where, returnValue) {
		if (arguments.length === 1 || where) {
			throw new Error('YCLASS > ' + (this.Type || 'object') + ' > error: \n' + text)
		}
		return returnValue
	};
	Tools.mix = function(o, f, v, ks) {
		var w, i;
        if (o && f) {
            v = v === void(0) || v;
            if (ks) {
                ks = isType.isString(ks) ? ks.replace(/\s/g,'').split(',') : ks;
                for (i = ks.length; i--;) {
                    w = ks[i];
                    if (w in f && (v || !(w in o))) {
                        o[w] = f[w]
                    }
                }
            } else {
                for (w in f) {
                    if (v || !(w in o)) {
                        o[w] = f[w]
                    }
                }
           }
		}
		return o
	};
	Tools.aop = function() {
		var fnArr = Copy.call(arguments).filter(function(el, i) {
			return el instanceof Function
		});
		return function() {
			var argsArr, rMix;
            argsArr = Copy.call(arguments);
            for (var i = 0, j = fnArr.length; i < j; i++) {
                rMix = fnArr[i].apply(this, argsArr.concat(rMix));
                if(false===rMix){
                    break
                }
            }
			return rMix
		}
	};
    function getInt(val, def){
        var d = parseInt(val, 10);
        return isNaN(d) ? (def || 0) : d
    };
	Tools.Point = function(x, y, z) {
		this.x = x || 0;
		this.y = y || 0;
		this.z = z || 0
	};
	Tools.Point.prototype = {
        offset: function (x,y,z){
            return new Tools.Point(this.x+~~x, this.y+~~y,this.z+~~z)
        },
		distance: function(pt) { 
			return Math.sqrt(Math.pow((this.x - pt.x), 2) + Math.pow((this.y - pt.y), 2));
		},
		polar: function(dis, angle) {
			var arc = -angle * Math.PI / 180;
			return new Tools.Point(this.x + ~~ (Math.cos(arc) * dis), this.y + ~~ (Math.sin(arc) * dis))
		}
	};
	Tools.Rect = function(x, y, width, height, z) {
		this.x = x || 0;
		this.y = y || 0;
        this.z = z || 0;
		this.width = width || 0;
		this.height = height || 0
	};
	Tools.Rect.prototype = {
        toPoint:function (x, y, z){
           return new Tools.Point(this.x+~~x, this.y+~~y,this.z+~~z)
        },
        offset: function (x,y,w, h, z){
            return new Tools.Rect(this.x+~~x, this.y+~~y,this.width+~~w, this.height+~~h, this.z+~~z)
        },
		getXArea: function(r2) {
			var d, x;
            d= Math.max;
			x = Math.min;
			return d(0, d(0, x(this.x + this.width, r2.x + r2.width) - d(this.x, r2.x)) * d(0, x(this.y + this.height, r2.y + r2.height) - d(this.y, r2.y)))
		}
	};
	Tools.mix(Function.prototype, {
		proxy: function(proxy) {
			var fn, a;
            fn = this;
			a = Copy.call(arguments, 1);
			return function() {
				return fn.apply(proxy, a.concat(Copy.call(arguments)))
			}
		},
		slow: function(time) {// not define arguments
			var timer, fn;
            fn = this;
			return function() {
				var A, obj;
                A = Copy.call(arguments);
			    obj = this;
				clearTimeout(timer);
				return timer = setTimeout(function() {
					fn.apply(obj, A)
				}, ~~time || 16);
			}
		}
	}, false);
	Tools.mix(Array.prototype, {
        each: function (fn, bind){
            for (var i = 0, j = this.length; i < j; i++) {
                if (fn.call(bind, this[i], i, this) === false) {
                    break
                }
            }
            return bind || this
        },
		random: function() {
			var copy, n, t;
            copy = this.slice();
			for (var i = copy.length; i--;) {
				n = parseInt(Math.random() * i);
				t = copy[i];
				copy[i] = copy[n];
				copy[n] = t
			}
			return copy.slice.apply(copy, arguments)
		},
		remove: function(el, check, bind) {
            if (!(check instanceof Function)) {
                el = el instanceof Array ? el : [el];
                check = function (item){
                    return el.indexOf(item) > -1
                }
            }
			for (var i = 0, n = 0, j = this.length; i < j; i++) {
				if (!check.call(bind, this[i])) {
					this[n++] = this[i]
				}
			}
			this.length = n;// slice
			return this
		},
		indexOf: function(el, start) {
			var len = this.length;
			start = isNaN(start) ? 0 : (start < 0 ? (start + len) : start);
			for (; start < len; start++) {
				if (start in this && this[start] === el){
                    return start
                }
			}
			return - 1
		},
        map: function(fn, bind) {
            var len, res;
            len = ~~this.length;
            res = new Array(len);
            for (var i = 0; i < len; i++) {
                if (i in this) {
                    res[i] = fn.call(bind, this[i], i, this)
                }
            }
            return res
        },
        filter: function(fn, bind) {
            var len, re, val;
            len = this.length;
            res = [];
            for (var i = 0; i < len; i++) {
                if (i in this) {
                    val = this[i];
                    if (fn.call(bind, val, i, this)) {
                        res.push(val)
                    }
                }
            }
            return res;
        },
        reduce: function(fn) {
            var arr, len, k, init;
            arr = this;
            len = arr.length;
            if (len == 0 && arguments.length == 1) {
                throw new TypeError()
            }
            k = 0;
            if (arguments.length > 1) {
                init = arguments[1];
            } else {
                do {
                    if (k in arr) {
                        init = arr[k++];
                        break;
                    }
                    if (++k >= len) {
                        throw new TypeError()
                    }
                } while (true)
            }
            while (k < len) {
                if (k in arr) {
                    init = fn.call(undefined, init, arr[k], k, arr)
                }
                k++
            }
            return init;
        }
	}, false);
	Tools.mix(String.prototype, {
		trim: function() {
			return this.replace(/^\s+|\s+$/g, '')
		},
		tpl: function(data, def) {
            var ns, perp;
			def = def === void(0) ? '': def;
			return this.replace(/\{\$([\w.]*?)\}/g, function(all, ns) {
				ns = ns.trim().split('.');
				perp = data;
				try {
					while (ns.length){
                        perp = perp[ns.shift()]
                    }
				} catch(e) {
					perp = def
				}
				return perp === void(0) ? def: perp
			})
		},
		format: function() {
			var A = arguments;
			return this.replace(/\{(\d+)\}/g, function(a, b) {
				return A[b - 1] === void(0) ? '': A[b - 1]
			})
		}
	}, false);
	Tools.mix(Date.prototype, {
		format: function(tpl) {
			var strs, newProperty, keys, year, val;
            strs= [];
            tpl = tpl || 'YY\u5e74MM\u6708DD\u65e5 \u661f\u671fdd';
            newProperty = 'FullYear,Month,Date,Hours,Minutes,Seconds,Day'.split(',');
            keys = [/YY/g, /Y/g, /MM/g, /M/g, /DD/g, /D/g, /hh/g, /h/g, /mm/g, /m/g, /ss/g, /s/g, /dd/g, /d/g];
			for (var i = 0; i < 7; i++) {
				val = this['get' + newProperty[i]]() + (newProperty[i] === 'Month' ? 1 : 0);
				strs.push(('0' + val).slice(-2), val)
			}
			year = [strs[1], strs[0]].concat(strs.slice(2, -2));
			year.push('\u65e5\u4e00\u4e8c\u4e09\u56db\u4e94\u516d'.substr(strs.slice(-1), 1), strs.slice(-1));
			for (var i = 0; i < 14; i++) {
				tpl = tpl.replace(keys[i], year[i])
			}
			return tpl
		},
		diff: function(d, ch) {
			return ((isType.isString(d) ? new Date(d.replace(/-/g, '/')) : new Date(d)) - this).toTimeDiff(ch)
		}
	});
	Tools.mix(Number.prototype, {
		rmb: function(prevfix) {
			return (prevfix === false ? '' : '\uffe5') + this.toFixed(2).toString().replace(/(\d)(?=(\d{3})+($|\.))/g, '$1,')
		},
		toTimeDiff: function(ch) {
			var unit, date, chDate, diff, words;
            unit = [86400000, 3600000, 60000, 1000, 1];
            date = [];
            chDate = [];
            diff = this;
            words = '\u5929,\u65f6,\u5206,\u79d2,\u6beb\u79d2'.split(',');
			for (var i = 0, l = unit.length; i < l; i++) {
				date[i] = parseInt(diff / unit[i]);
				chDate[i] = date[i] + words[i];
				diff %= unit[i]
			}
			return ch ? chDate: date
		},
		range: function(a, b) {
			b = arguments.length == 1 ? 0 : b;
			return Math.min(max = Math.max(a, b), Math.max(Math.min(a, b), this))
		}
	}); 
    (function(x, bName, y) {
        bName = /msie/.test(x) && !/opera/.test(x) ? 'ie': (/firefox/.test(x) ? 'firefox': (/webkit/.test(x) && !/chrome/.test(x) ? 'safari': (/opera/.test(x) ? 'opera': (/chrome/.test(x)) ? 'chrome': 'unknown')));
		y = bName == "safari" ? "version": bName;
		browser[bName] = parseInt(y && RegExp("(?:" + y + ")[\\/: ]([ \\d.]+)").test(x) ? RegExp.$1: "0");
        browser.browserName = bName;
	})(navigator.userAgent.toLowerCase());
	Tools.mix(Math, {
		c: function(len, m) {
			var n1, n2, j, n;
            n1 = n2 = j = 1;
            n = len;
			for (var i = n; j <= m;) {
				n2 *= j++;
				n1 *= i--
			}
			return n1 / n2
		},
		cl: function(arr, n) {
			var r = []; 
            fn([], arr, n);
			return r;
            function fn(t, a, n) {
				if (n === 0){
                    return r.push(t)
                }
				for (var i = 0, l = a.length - n; i <= l; i++){
                    fn(t.concat(a[i]), a.slice(i + 1), n - 1)
                }
			}
		},
		p: function(n, m) {
			var c = 1;
			for (var i = n - m; i < n;) { 
                c *= ++i
            }
			return c
		},
		pl: function(arr, n) {
			var r = [];
            fn([], arr, n);
			return r;
            function fn(t, a, n) {
				if (n === 0){
                    return r.push(t)
                }
				for (var i = 0, l = a.length; i < l; i++){
                    fn(t.concat(a[i]), a.slice(0, i).concat(a.slice(i + 1)), n - 1)
                }
			}
		},
		dt: function(d, t, m) {
			if (d >= m){
                return 0
            }
			var n1, n2, j, n, m;
            n1 = n2 = j = 1;
            n = t;
            m -= d;
			for (var i = n; j <= m;) {
				n2 *= j++;
				n1 *= i--
			}
			return n1 / n2
		},
		dtl: function(d, t, n) {
			var r = [];
			if (d.length <= n){
                fn([], t, n - d.length);
                for (var i = r.length; i--;){
                    r[i] = d.concat(r[i])
                }
            }
			return r;
            function fn(t, a, n) {
                if (n === 0) {
                    return r.push(t)
                }
                for (var i = 0, l = a.length - n; i <= l; i++) {
                    fn(t.concat(a[i]), a.slice(i + 1), n - 1)
                }
            }
		}
	});
	['String', 'Number', 'Boolean', 'Array', 'Object', 'RegExp', 'Date', 'Function'].each(function (prop){
		isType['is'+prop] = function (val){
			return toStr.call(val).indexOf(prop) > -1
		}
	});
	Tools.fn = {
		empty: new Function('n','return n'),
		mix: Tools.mix,
		aop: Tools.aop,
        getObj: Tools.getObj,
		Try: function() {
			return Tools.Try.apply(this, arguments)
		},
        getInt: getInt,
        dejson: function (data){
            try{
                return (new Function('return (' + data + ')'))()
            }catch(e){}
        },
        getMapPath:function (url, isjs){
            if (url.indexOf('.') == -1 && isjs) {
                url = "@" + (url.indexOf('/') > -1 ? '' : 'lib/') + url + '/' + url.slice(url.lastIndexOf('/')+1) + '.js';
            }
            return url.replace(/@(\/)?/,Class.config('basePath')).replace(/([^:])\/+/g,'$1/').trim()
        },
		getGuid: (function() {
			var guid = +new Date;
			return function(el) {
				var newId = '_' + (++guid).toString(36);
				if (el) {
					el = this.one(el);
                    if (el['data-yclass-unique'] === undefined) {
                        el['data-yclass-unique'] = (el.nodeName || (el.Type ? el.Type: typeof el)) + newId
                    }
                    return el['data-yclass-unique'];
				}
				return 'guid' + newId
			}
		})(),
        ns: function (path, root, value){
            var has = arguments.length > 2;
            return this.isString(path) ? path.split('.').reduce(function (a,b,i,arr){
                return a[b] = arr.length - 1 === i && has ? value : Object(a[b])
            }, this.ns(root) || window) : path
        },
		Point: function(x, y) {
			return new Tools.Point(x, y)
		},
		Rect: function(x, y, w, h) {
			return new Tools.Rect(x, y, w, h)
		},
		nodeReady: function (id, fn){
			var node, count;
			count = 500;
			id = id.replace('#', '');
			function reTry(){
				if (node = document.getElementById(id)) {
					fn(node)
				}else if(--count){
					return setTimeout(reTry, 0)
				}	    
			}
			return reTry()
		},
        get: function (selector, contains, one){
            var nodes, group, query, wrap, matcher, check, uq, uqArr, opts, guid, lowermost, html, range;
            nodes = [];
            if (!this.isString(selector)) {
                if (selector instanceof Array) {
                    nodes = selector
                }else if (contains === 'toArray' || 'length' in Object(selector) && !selector.alert && !selector.nodeType) {// nodeList, childNodes, no-window, no-select
                    for (var i =  selector.length; i--;) {
                        nodes[i] = selector[i]
                    }      
                }else if(!selector){// empty, null, undefined
                    nodes = []
                }else{// element
                    nodes = [selector]
                }
            } else if(/<\w+[^>]*>/.test(selector)){// HTML string
                YCLASS_TMP_DIV.innerHTML = /^<\w+>$/.test(selector) ? selector.replace(/<(\w+)>/,'<$1></$1>') : selector;
                return this.get(YCLASS_TMP_DIV.childNodes, 'toArray')
            } else{
                group = selector.split(/\s*,\s*/);// selector, selector2
                contains = contains ? this.one(contains) : document;
                for (var g =  group.length; g--;) {
                    query = Object(group[g].replace(/[>+~]/g,' $& ').replace(/^.+(?=#)/,'').match(/\S+/g));// single query
                    range = contains;// exact range
                    if (query.length && query[0].indexOf('#')>-1 && '~+'.indexOf(query[1]) == -1) {// if has id and not sibling, get a exact scope
                        range = document.getElementById((query.length == 1 ? query.pop() : query[0]).slice(1))// only form id/ nodes in id
                    }
                    if (query.length && range !== null) {
                        check = query.pop();// last query fragment
                        matcher = [];
                        opts = {};
                        check.replace(/(^|:|.|#)([\w-]+)/g,function (a,b,c){opts[b] = c});// parse match key
                        lowermost = range.getElementsByTagName(opts[':'] ? 'input' : opts[''] ? opts[''] : '*');// get base tag
                        for (var i = 0, j = lowermost.length; i < j; i++) {
                            if (this.isTagClassTypeID(lowermost[i], opts[''], opts['.'],opts[':'], opts['#'])) {
                                matcher.push(lowermost[i])
                            }
                        }
                        if (matcher.length && query.length) {
                            matcher = this.selectFromParents(matcher, query, contains, one)// filter from parent
                        }
                    }else{// only get-id or document
                        matcher = (range === document || !range) ? [] : range
                    }
                    nodes = nodes.concat(matcher)
                }
                if (group.length>1 && !one) {// group uniquelize 
                    uq = {};
                    uqArr = [];
                    for (var i = 0, n = 0, j = nodes.length; i < j; i++) {
                        guid = Y.getGuid(nodes[i]);
                        if (!(guid in uq)) {
                            uq[guid] = true;
                            uqArr[n++] = nodes[i]
                        }
                    }
                    nodes = uqArr                    
                }
            }
            return nodes
        },
        selectFromParents: function (all_nodes, arr_selector, contains, one){// arr
            var arr = [];
            for (var i = 0, j = all_nodes.length; i < j; i++) {// every node, [#id tag .className vs node]
                if (this.upMatchSelector(all_nodes[i], arr_selector.slice(), contains)) {
                    arr.push(all_nodes[i]);
                    if (one) {
                        break // only get one
                    }                    
                }
            }
            return arr
        },
        upMatchSelector: function (node, selector, contains){
            var check, absParent, sibling, opts;
            while(check = selector.pop()){
                if (check == '>') {
                    absParent = true;
                    continue
                }else if(check == '+' || check == '~'){
                    sibling = check == '+' ? 'getPrev' : 'getNext';
                    continue
                }
                opts = {};
                check.replace(/(^|:|.|#)([\w-]+)/g,function (a,b,c){opts[b] = c});
                do{
                    node = sibling ? this[sibling](node) : node.parentNode;
                    if (!node || node === contains) {
                        return false
                    }else if (this.isTagClassTypeID(node, opts[''], opts['.'], opts[':'], opts['#'])) {
                        break// end current fragment match
                    }else if (absParent || sibling){// stop find more up
                        return false
                    }                        
                }while(true)
                absParent = sibling = false 
            }
            return true
        },
        isTagClassTypeID: function (el, tag, className, type, id){// is match tag & className & type
            return (!tag ||  el.nodeName.toLowerCase() == tag.toLowerCase()) &&
                (!className || (' ' + el.className + ' ').indexOf(' '+className+' ')>-1) &&
                (!type || el.type && el.type.toLowerCase() == type.toLowerCase()) && (!id || el.id == id)
        },
		one: function (selector, contains, clearError){
            var node = this.get(selector,contains, true)[0];
            return this.Try(this.Type+'.one("'+selector+'"): is not found \nuse CSS selector, pls', !clearError && !node, node)
        },
		on: function(selector, type, fn, one) {
            return this.get(selector).each(function (el, i){
                var domEvents, domGuid, Y, post, _fn;
                if (this.isObject(type)) {// single obj mulit event
                    for (var k in type) {
                        this.on(el, k, type[k], one)
                    }
                    return this
                }
                this.Try('.on(selector, type, '+fn+', one):\nhandler not a function', !this.isFunction(fn));
                if (type == 'wheel') {
                    return this.wheel(el, fn)
                } else if (el.nodeName && el.nodeName.toLowerCase() == 'iframe' && type == 'load') {
                    return this.loadIframe(el, fn)
                }
                domGuid = this.getGuid(el);
                if (this.__INSTANCE_EVENTS__[domGuid] === void(0)) {
                    this.__INSTANCE_EVENTS__[domGuid] = []
                }
                domEvents = this.__INSTANCE_EVENTS__[domGuid];
                Y = this;
                post = false;
                if (type.match('^focusin|focusout$') && !this.ie) {
                    type = type == 'focusin' ? 'focus': 'blur';
                    post = true
                }
                if (type.match('^mouseenter|mouseleave$') && !this.ie) {
                    type = type == 'mouseenter' ? 'mouseover': 'mouseout';
                    _fn = function(e) {
                        if (!el.contains(e.relatedTarget)) {
                            fn.call(el, Y.fixEvent(e), Y)
                        }
                    }
                } else {
                    _fn = function(e) {
                        fn.call(el, Y.fixEvent(e), Y);
                        if (one) {
                            Y.__removeEvent__(el, type, _fn)
                        }
                    }
                }
                domEvents.push([el, type, _fn, fn]);
                this.__addEvent__(el, type, _fn, post)
            }, this)
		},
		un: function(selector, type, fn) {
           return arguments.length == 0 ? this.clearEvents() : this.get(selector).each(function (el){
                var domEvents, f1, f2, t1, t2;
                domEvents  = this.__INSTANCE_EVENTS__[this.getGuid(el)];
                f1 = Function('return true');
                f2 = Function('a, b','return a === b');
                t1 = type === void(0) ? f1: f2;
                t2 = fn === void(0) ? f1: f2;
                if (domEvents) {
                    domEvents.remove(null, function(data) {
                        if (t1(data[1], type) && t2(data[3], fn)) {
                            this.__removeEvent__.apply(this, data);
                            return true
                        }
                    }, this)
                }                
            },this)
		},
		live: function(selector, type, fn, test) {
			var test = test instanceof Function ? test: Function('return true');
            type = type == 'focus' ? 'focusin' : type == 'blur' ? 'focusout' : type;
			return this.on(selector, type, function(e, o) {
				var target;
				if (target = getParent.call(this, e.target)) {
					fn.call(target, e, o)
				}
			});
			function getParent(target) {
				do {
					if (test(target)) {
						return target
					}
					target = target.parentNode;
				} while ( target && this.contains && this.contains (target))
			}
		},
		clearEvents: function() {
			var events, domEvents, guid;
            events = this.__INSTANCE_EVENTS__;
			for (guid in events) {
				domEvents = events[guid];
				for (var i = 0, j = domEvents.length; i < j; i++) {
					this.__removeEvent__.apply(this, domEvents[i])
				}
				delete events[guid]
			}
			return this
		},
        createEvent: function (eStrs, over, noTry){// add costom event
            return eStrs.split(/\s*,\s*/).each(function (e){
                e = 'on' + e.trim().toLowerCase();
                if ((e in this) && over !== true) {
                    return this.Try(this.Type+'.createEvent("'+e+'"): name exists', !noTry)
                }
                this[e] = Function()
            },this)
        },
		__addEvent__: (function(w3c) {
			return w3c ? function(el, type, fn, post) {
				return el.addEventListener(type, fn, !!post)
			}: function(el, type, fn) {
				return el.attachEvent('on' + type, fn)
			}
		})( !!window.addEventListener),
		__removeEvent__: (function(w3c) {
			return w3c ? function(el, type, fn) {
				return el.removeEventListener(type, fn, false)
			}: function(el, type, fn) {
				return el.detachEvent('on' + type, fn)
			}
		})( !!window.addEventListener),
		fixEvent: function(e) {
			e = e || window.event;
			if (!e.stopPropagation) {
				e.target = e.srcElement;
				e.stopPropagation = function() {
					e.cancelBubble = true
				};
				e.preventDefault = function() {
					e.returnValue = false
				}
			}
			e.stop = e.stopPropagation;
			e.end = e.preventDefault;
            e.isEvent = true;
			return e
		},
		clearRange: function() {
			try{
                window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty()
            }catch(e){}
			return this
		},
		fireEvent: function(el, type, data) {
			el = this.one(el);
			if (document.createEventObject) {
				return el.fireEvent('on' + type, this.mix(document.createEventObject(), data))
			} else {
				var e = document.createEvent("HTMLEvents");
				e.initEvent(type, true, true);
				return !el.dispatchEvent(this.mix(e, data))
			}
		},
		attr: function(el, key, value) {
			var guid, o;
            guid = this.getGuid(this.one(el));
			o = this.GLOBAL_DOM_DATAS[guid];
			if (arguments.length > 2) {// set
				if (!o) {
					o = this.GLOBAL_DOM_DATAS[guid] = {}
				}
				o[key] = value
			} else {// get all or one
				return o ? (key === void(0) ? this.mix({},o): o[key]) : void(0)
			}
			return this
		},
        Super: (function (){// call super method
            var curParent, target;
            return function (name){
                if (this[name]) {// has method 
                    curParent = curParent || this.__YPROTOTYPE__;// start parent
                    if (target = curParent[name]) {
                        curParent = curParent.__YPROTOTYPE__;// move curParent
                        target.apply(this, Copy.call(arguments,1))
                    }
                }
                curParent = false;// clear 
                return this
            }
        })(),
        base: function (){
            return this.Super.apply(this, ['index'].concat(Copy.call(arguments)))  
        },
		nav: function(ref, dir, filter) {// get one
			var map, d, test;
            map= {
				'getParent': 'parentNode',
				'getNext': 'nextSibling',
				'getChild': 'childNodes',
				'getPrev': 'previousSibling'
			};
			d = map[dir] || 'nextSibling';
            test = filter || Function('return true');
			if (d == 'childNodes') {
				ref = ref.firstChild;
				while (ref && (ref.nodeType != 1 || (''+ref.nodeName).toLowerCase() == 'br' || test(ref) !== true)) {
					ref = ref.nextSibling
				}
			} else {
				do {
					ref = ref[d]
				} while (ref && (/script|br/i. test (ref.nodeName) || ref.nodeType != 1 || test(ref) !== true))
			}
			return ref
		},
        setStyle: function (el, style, value){
           return this.get(el).each(function (el){
               var css, a, uk, uf, i;
               css = [];
               a = 'filter:progid:DXImageTransform.Microsoft.Alpha(opacity=';
               uk = /[A-Z]/g;
               uf = Function('i','return "-"+i.toLowerCase()');
               i = 0;
               if (value === void 0) {// 'color:red;font-size:0' or {color:red}
                   if (!this.isString(style)) {
                       for(var k in style){
                           css[i++] = k.replace(uk, uf) + ':' + style[k] + (k == 'opacity' ? (style[k] ==1 ? ';filter:' :(';'+a+style[k]*100+')')) : '');
                       }
                       style=css.join(';')
                   }
                   el.style.cssText += ';' + style;
               }else{// opacity, .5
                    el.style[style] = value;
                    if (style === 'opacity' && this.ie) {
                        el.style.filter = value < 1 ? 'progid:DXImageTransform.Microsoft.Alpha(opacity=' + this.getInt(value*100)+')' : '';
                        el.style.zoom = 1;
                    }
               }           
            },this)
        },
		getStyle: function(el, s) {
			el = this.one(el);
            return el.style[s] == '' ? (el.currentStyle || document.defaultView.getComputedStyle(el, null))[s] : el.style[s]
		},
		getBgXY: (function() {
			return browser.ie ? function(el) {
				return this.Point.apply(this, [this.getStyle(el, 'backgroundPositionX'),this.getStyle(el, 'backgroundPositionY')])
			}: function(el) {
				return this.Point.apply(this, this.getStyle(el, 'backgroundPosition').split(' '));
			}
		})(),
		setTopmost: function(el, offset) {
			var z = Class.config('TOP-Z-INDEX');			
            offset = ~~offset || 1;
			if (!z) {
                Class.config('TOP-Z-INDEX', z = 50*10000)
			}
			if (arguments.length == 0) {
				return z
			}
			z += offset;
			this.setStyle(el, 'zIndex', z);
			if (offset > 0) {
				Class.config('TOP-Z-INDEX', z)
			}
			return this
		},
        fitWinHeight: function (min){
            if (top != self) {
                if (this.windowloaded) {
                    try{
                        this.get('IFRAME',parent.document).each(function (w){
                           if (w.contentWindow == self) {
                                return this.setStyle(w, 'height', (min || 360) + 'px').setStyle(w, 'height',  this.getSize().scrollHeight+18+'px').empty(false)
                            }
                        }, this)                
                    }catch(e){}
                }else{
                    this.on(window, 'load', function (e, Y){
                        Y.windowloaded = true;
                        Y.fitWinHeight(min)
                    })
                }
            }
        },
		__fixClass__: function(s) {
			return s.replace(/^\s+|\s+$/g, '').replace(/\s+/g, ' ')
		},
		hasClass: function(el, x) {// x == live false, and is true
			return !x || (' ' + el.className + ' ').indexOf(' ' + x + ' ') != -1
		},
		removeClass: function(el, x) {
            return this.get(el).each(function (el){
                if (this.hasClass(el, x)) {
                    el.className = this.__fixClass__((' ' + el.className + ' ').replace(RegExp(' ' + x + '(?= )', 'g'), ''))
                }                
            },this)
		},
		addClass: function(el, x) {
            return this.get(el).each(function (el){
                if (!this.hasClass(el, x)) {
                    el.className = this.__fixClass__(el.className + ' ' + x)
                }                
            },this)
		},
		swapClass: function(el, x, y) {
            return this.get(el).each(function (el){
                var cls = el.className;
                cls = (x && this.hasClass(el, x)) ? cls.replace(RegExp(x, 'g'), '') : cls;
                cls += (y && !this.hasClass(el, y)) ? ' ' + y : '';
                el.className = this.__fixClass__(cls);
            },this)
		},
        toggleClass: function (el, c){
            return this.get(el).each(function (el){
                this[this.hasClass(el, c) ? 'removeClass' : 'addClass'](el, c)
            },this)
        },
		createNodes: function(config, doc) {
			var doc, node, used;
            doc = doc || document;
            if (this.isString(config)) {
                if (config === 'frag') {
                    return doc.createDocumentFragment()
                }else{
                    config = this.getObj('tagName', config)
                }
            }
            used = /^(tagName|attrs|style|childNodes|parentNode|key|init|unload)$/i;
			if (config.tagName == '#text') {
				node = doc.createTextNode(config.value || '')
			}else{
                node = doc.createElement(config.tagName || 'DIV');
                if (config.attrs) {// add Attributes
                    for (var k in config.attrs) {
                        node.setAttribute(k, config.attrs[k])
                    }
                }
                if (config.style) {// add style
                    this.setStyle(node, config.style);
                }
                for (var k in config) {// add other 
                    if (config[k] != void(0) && !used.test(k)) {
                        node[k] = config[k]
                    }
                }
                if (config.childNodes) {// childNodes
                    for (var i = 0, j = config.childNodes.length; i < j; i++) {
                        node.appendChild(this.createNodes(config.childNodes[i]))
                    }
                }
                if (config.tagName && config.tagName.toLowerCase() == 'a' && !config.href) {// link
                    node.href = this.ie == 6 ? '#1' : 'javascript:void(0)';
                    if (this.ie) {
                        node.setAttribute('hideFocus','true')
                    }
                }
                if (config.unload) {
                    this.addRemove(node)
                }
                if (config.key) {// add property
                    this[config.key] = this.Try(this.Type+'.createNodes({Key:"' + config.key + '"}): key exists', config.key in this, node);
                }
                if (config.init instanceof Function) {// init
                    config.init.call(this, node)
                }
            }
            if (config.parentNode) {// append
                this.one(config.parentNode).appendChild(node)
            }
			return node
		},
        addRemove: function (node){
            return Copy.call(arguments).each(function (node, i){
                 this.__DELETENODES__[this.getGuid(node)] = node         
            }, this)
        },
		removeNode: function(el) {
			el = this.one(el);
			if (el && el.nodeType == 1) {
				var sub = el.childNodes;
				if (sub && sub.length > 0) {
					for (var i = sub.length; i--;) {
						this.removeNode(sub[i]) ? 1 : 0
					}
				}
				delete this.GLOBAL_DOM_DATAS[el['data-yclass-unique']];
				el.removeAttribute('data-yclass-unique');
				if (el.parentNode) {
					YCLASS_TMP_DIV.appendChild(el.parentNode.removeChild(el));
					YCLASS_TMP_DIV.innerHTML = ''
				}
			}
		},
		moveNode: function (a, b, c, l, Y){// mover("<strong>html</strong>"), ref, pos
            b = b === void 0 ? document.body : this.one(b);
            l = b.childNodes.length;
            Y = this;
            return this.get(a).each(function (node, i){// return nodes Array
                switch(c){
                case 'wrap':
                    b.parentNode.insertBefore(node,b);
                    return node.appendChild(b)
                case 'inwrap':
                    Y.moveNode(b.childNodes, node);
                    return b.appendChild(node)
                case 'prev':
                    return b.parentNode.insertBefore(node,b)
                case 'next':
                    return b.parentNode.insertBefore(b, b.parentNode.insertBefore(node,b))
                }
                return (c == void 0 || l == 0 || c == -1 || c >= l) ? b.appendChild(node)// child
                 : b.insertBefore(node, b.childNodes[~~c])// child           
            })
		},
		addStyle: (function() {
			var loaded = {};
			return function(cssText, doc) {
				var tmp, head, styles, o, doc = doc || document;
				head = doc.getElementsByTagName("head")[0];
				if (/\.css$/i.test(cssText)) {
					if (!loaded[cssText]) {
						this.createNodes({
							tagName: 'link',
							parentNode: head,
							attrs: {
								rel: 'stylesheet',
								type: 'text/css',
								href: this.getMapPath(cssText)
							}
						});
						loaded[cssText] = true
					}
				}else{
                    styles = head.getElementsByTagName("style");
                    if (styles.length == 0) {
                        this.ie ? doc.createStyleSheet() : this.createNodes({
                            tagName: 'style',
                            parentNode: head,
                            attrs: {
                                type: 'text/css'
                            }
                        });
                    }
                    o = styles[0];
                    if (o.styleSheet) {
                        o.styleSheet.cssText += cssText
                    }else{
                        o.appendChild(doc.createTextNode(cssText))
                    }                    
                }
				return this
			}
		})(),
		setNodeDisplay: function (selector, where, isshow){
			var nn, cssVal, vals;
			return this.get(selector).each(function (el){
				nn = el.nodeName;
				cssVal = DISPLAY_VALUE[nn];
				if (!cssVal) {
					YCLASS_TMP_DIV.innerHTML = '<' + nn + '></' + nn + '>';
					DISPLAY_VALUE[nn] = cssVal =  this.getStyle(YCLASS_TMP_DIV.firstChild, 'display')
				}
				vals = isshow ? [cssVal, 'none'] : ['none', cssVal];
				this.setStyle(el, 'display', where ? vals[0] : vals[1])
			},this)
		},
		showNode: function(selector, where) {
			where = arguments.length === 1 || where;
            return this.setNodeDisplay(selector, where, true)
		},
		hideNode: function(selector, where) {
			where = arguments.length === 1 || where;
            return this.setNodeDisplay(selector, where)
		},
		setXY: function(el, pt, isget) {
            var oriXY, o;
            oriXY = pt.origin ? this.getXY(pt.origin) : this.Point(0,0);
            o = {
                left: oriXY.x + ~~pt.x + 'px',
                top: oriXY.y + ~~pt.y + 'px'
            };
            return isget ? o : this.setStyle(el, o)
		},
		getXY: function(el) {// return point
			var orig, xy, xy2, doc;
            orig = this.$_origin || this.global.$_origin;
			xy = this.one(el).getBoundingClientRect();
			if (orig) {
			    xy2 = orig.getBoundingClientRect();
				return this.Point(xy2.left - xy.left, xy2.top - xy.top)
			}else{
				doc = this.getSize();
				return this.Point(xy.left + doc.scrollLeft, xy.top + doc.scrollTop)	
			}
		},
		getCursorXY: function(e, isClient) {// default abs pos
            var orig, doc, b;
            orig = this.$_origin || this.global.$_origin;
			if (!orig && isClient) {
				return this.Point(e.clientX, e.clientY)
			}
			doc = this.getSize();// scroll offset
            b = orig ? this.getXY(orig, true) :  (this.ie ? this.Point(-~~document.body.offsetLeft, -~~document.body.offsetTop) : this.Point(0, 0));// relative
			return this.Point(e.clientX + doc.scrollLeft - b.x, e.clientY + doc.scrollTop - b.y)
		},
		getRect: function(el, free) {
            var dr, pt, s, oldCss;
			if (arguments.length == 0) {// body-client
				dr = this.getSize();
                return this.Rect(dr.scrollLeft, dr.scrollTop, dr.scrollLeft + dr.offsetWidth, dr.scrollTop + dr.offsetHeight)
			} else {
				s = this.one(el).style;
                oldCss = s.cssText;
				s.cssText += ';display:block;'+(free ? 'height:auto;float:left' : '');
                pt = free ? {} : this.getXY(el);
                rect = this.Rect(pt.x, pt.y, el.offsetWidth, el.offsetHeight, pt.z);
                s.cssText = oldCss;
                return rect
			}
		},
		getSize: function(el) {
            var dd, db, M, doc;
            dd = document.documentElement;
            db = document.body;
            M = Math.max;
            doc = document.compatMode == "CSS1Compat" ? dd: db;
			if (el == void(0) || el == dd || el == db) { 
				return {
					scrollLeft: M(dd.scrollLeft, db.scrollLeft),
					scrollTop: M(dd.scrollTop, db.scrollTop),
					scrollWidth: doc.scrollWidth,
					scrollHeight: M(doc.clientHeight, doc.scrollHeight),
					offsetWidth: doc.clientWidth,
					offsetHeight: doc.clientHeight
				}
			}
			return this.one(el)
		},
		setCenter: function(selector, isGet, equal) {// default is gold scale
            var el, css, x, w, h, pt;
            el = this.one(selector);
            this.setStyle(el, 'position:absolute');
            x = this.getSize(el.offsetParent);
            w = el.offsetWidth;
            h = el.offsetHeight;
            pt = this.Point(this.getInt((x.offsetWidth - w) / 2 + x.scrollLeft), Math.max(0, this.getInt((x.offsetHeight - h) *(equal ? .5 : .382) + x.scrollTop)));
            return isGet ? pt: this.setXY(el, pt)
		},
		wheel: function(el, fn) {
			var Aop, type;
			type = 'onmousewheel' in document ? 'mousewheel': 'DOMMouseScroll';
			return this.on(el, type, Aop);
            function Aop(e, Y) {
				var delta, fix;
  				delta = e.wheelDelta ? e.wheelDelta / 120 : -(e.detail || 0) / 3;
				fix = window.opera && window.opera.version() < 10 ? -1 : 1;
				e.end();
				e.offset = Math.round(delta) * fix;
				fn.call(e.target, e, Y);
			}
		},
		loadIframe: function(win, fn) {
			win = this.one(win);
			win.attachEvent ? win.attachEvent("onload", _load) : (win.onload = _load);
			return this;
			function _load() {
				fn.call(win.contentWindow);
				win.detachEvent ? win.detachEvent("onload", _load) : (win.onload = null)
			}
		},
		fx: function (fn, config){
		    var start, mutex, timer, tween, useTime, Y, end, pos, mutex, over, totalTime;
			Y = this;
			config = Object(config);
			totalTime = this.getInt(config.time, 480);
		    start = new Date;
			mutex = config.mx;
			over = config.over;
            tween = config.tween instanceof Function ? config.tween : function(x) {
                return.5 - Math.cos(x * Math.PI) / 2
            };
			end = config.end || this.empty;
			if (!config.init || false !== config.init.call(Y)) {
                if (mutex && mutex in this.__instanceMutex__) {
                     if (over || over === void 0) {
                         this.endFx(this.__instanceMutex__[mutex])
                     }else{
                        return	  
                     }
                }
				timer = setInterval(function() {
					if (Y.$_pause || Y.global.$_pause) {
					    start = new Date - useTime;// pause
					}else{
						useTime = new Date - start;
						pos = Math.min(1, useTime/totalTime);
						if (false === fn.call(Y, pos2val, pos) || pos === 1) {
							Y.endFx(timer)
						}					
					}
				}, this.getInt(this.$_hz,10));
				this.addTimer(timer, end, mutex);			    
			}
			return timer;
			function pos2val(f, t, f2, x) {
				var n = +f + (t - f) * Math.min(1,(f2||tween)(pos));// mulit tween
				return x ? n.toFixed(2) : ~~n
			}
		},
        addTimer: function (timer, end, mutex){
            this.__instanceTimers__[timer] = this.getObj('end', end,'mutex', mutex);
            if (mutex) {
                this.__instanceMutex__[mutex] = timer;
            }
			return timer
        },
		endFx: function(timer) { //stop instance fx and run end
            if (this.__instanceTimers__) {
                if (timer) {// has pass timer
                    var o = Object(this.__instanceTimers__[timer]);
					if (o.end) {
						o.end.call(this);
						delete this.__instanceMutex__[o.mutex];// mutex
					}
					delete this.__instanceTimers__[timer];// timer
					clearInterval(timer);
                    clearTimeout(timer)
                } else {
                    for (var k in this.__instanceTimers__) {// all fx
                        this.endFx(k)
                    }
                }                
            }
			return this
		},        
		fade: function(selector, val) {
            if (arguments.length === 1) {
                var opy = this.getStyle(selector, 'opacity');
                return this.ie ? opy === void(0) ? 1 : opy : opy;
            }
            return  this.get(selector).each(function (el){
                   this.setStyle(el, 'opacity', val)
            }, this)
		},
		fadeTo: function(selector, to, end, time) {
            return this.get(selector).each(function (el){
                var x = this.fade(el);
                x = x === 1 ? 0 : x;// fadeIn 
                this.fx(function(f, i) {
                    this.fade(el, f(x, to, void 0, true))
                },this.getObj('end', end,'time', time, 'mx', this.getGuid(el), 'tween', this.empty))
            },this)
		},
		fadeIn: function(selector, end, time) {
			return this.fadeTo(selector, 1, end, time)
		},
		fadeOut: function(selector, end, time) {
			return this.fadeTo(selector, 0, end, time)
		},
		getColor: function(x, y, s) {
			return x.replace(/[^#]{2}/g, function(m, i) {
				return ('0' + parseInt(parseInt(m, 16) * (1 - s) + parseInt(y.slice(i, i + 2), 16) * s).toString(16)).slice( - 2)
			})
		},
		cookie: function(key, val, attr) {
			var n, m, more;
            n = arguments.length;
			if (n == 0){
                return log(decodeURI(document.cookie).replace(/; */g, '\n\r\n\r'))
            } else if (n == 1) {
				m = document.cookie.match('(?:^| )' + key + '(?:(?:=([^;]*))|;|$)');
				return m ? decodeURI(m[1]) : void 0
			}
            more = [encodeURI(key.trim()) + '=' + encodeURI(val.toString().trim())];
			for (var k in attr) {
				more.push(k == 'timeout' ? 'expires=' + new Date( + new Date() + 1000 * attr.timeout).toUTCString() : (k + '=' + attr[k]))
			}
			document.cookie = more.join(';')
		},
		qSearch: function(url) {
            var o = {};
			url = new String(url || location.search);
			url.replace(/\b([^?=&]+)=([^=&]+)/g, function(a, k, v) {
				o[k] = v
			});
			return o
		},
        toSearch: function (obj, url){
            var s, o, arr;
            if (!this.isString(obj)) {
                s=[];
                for(var k in obj){
                    o = obj[k];
                    if (o instanceof Array) {//array to key[]=value
                        for (var i =  o.length; i--;) {
                            s.push(k+'[]='+o[i])
                        }                        
                    }else{
                        s.push(k + '=' +obj[k])
                    }                    
                }                     
                obj = s.join('&')
            }
            if (this.isString(url)) {// meger param and url
                arr = url.split('?');
                obj = obj ? (arr[0] + '?' + (obj + (arr[1] && arr[1].indexOf('#')!=0 ? '&' : '')) + url.slice(arr[0].length + 1)) : url
            }
            return obj.replace(/&+/g,'&').replace(/\?&+/,'?')
        },
		qUrl: function(url) {
            var obj, parse, res, keys;
            obj = location;
            if (url) {
                obj = {};
                parse = /^([^:]+):\/\/(?:([^:@]+):?([^@]*)@)?(?:([^/?#:]+):?(\d*))([^?#]*)(?:\?([^#]+))?(?:#(.+))?$/;
                res = url.match(parse);
                keys = 'protocol,user,pass,host,port,pathname,search,hash'.split(',');
                if (res) {
                    res.slice(1).each(function (val, i){
                        obj[keys[i]] = val                    
                    })
                }
            }
			return obj
		},
		qForm: function(form, encode) {
			var f, fe, o, el, val;
            f = this.one(form);
            fe = f.elements;
            o = {};
			for (var i = 0, l = fe.length; i < l; i++) {
				el = fe[i];
				val = false;
				if (el.name){
                    if (/select/i.test(el.type)) {
                        val = el.selectedIndex > -1 ? el.value : false
                    } else if (/checkbox|radio/i.test(el.type)) {
                        val = el.checked !== false ? el.value : false         
                    } else{
                       val = el.value
                    }
                    if (false !== val) {
                        o[el.name] = encode ? encodeURIComponent(val) : val;
                    }                    
                }
			}
			return o
		},
		uploadForm: function(config) {// form, end, url
			var sentTo, d, win, tmp, fn, form;
            sentTo = 'UpFileWindow';
            win = frames[sentTo] || document.getElementById(sentTo);
			if (!win) {
				tmp = document.body.appendChild(document.createElement('DIV'));
				tmp.style.cssText = "position:absolute;left:-9999px";
				tmp.innerHTML = '<iframe id="' + sentTo + '" name="' + sentTo + '" width="100" height="100" ></frame>';
				win = tmp.getElementsByTagName('IFRAME')[0]
			}
			if (config.end) {
                fn = function() {
                    config.end.call(win.contentWindow)//.document.XMLDocument#firefox
                };
				win.attachEvent ? win.attachEvent("onload", fn) : win.onload = fn;
			}
			form = Y.one(config.form);
			form.target = sentTo;
            if (config.url) {
                form.action = config.url
            }
			form.submit()
		},
		submitObj: function(config) {//url, data, method, blank
			var html, div;
            html = ['<form method="' + (config.type || 'POST') + '" action="' + config.url + '" id="tempPostForm" ' + (config.blank ? 'target="_blank"': '') + '>'];
			for (var k in config.data) {
				html.push('<input type="hidden" name="' + k + '" value="' + config.data[k] + '" />')
			}
			div = document.body.appendChild(document.createElement('DIV'));
			div.innerHTML = html.join('') + '</form>';
			div.style.cssText = 'position:absolute; left:-99999px';
			document.getElementById('tempPostForm').submit();
			this.removeNode(div)
		},
		gethttp: (function() {
			var http;            
			return window.ActiveXObject ? function() {
				var xhr, mxs, i;
				if (http) {
					return new ActiveXObject(http)
				}
                mxs = ['Msxml2.XMLHTTP.6.0', 'Msxml2.XMLHTTP.4.0', 'Msxml2.XMLHTTP.3.0', 'Msxml2.XMLHTTP', 'Microsoft.XMLHTTP'];
                for (i =  mxs.length; i--;) {
                    http = mxs[i];
					try {
						return new ActiveXObject(http)
					} catch(e) {}                  
                }
			} : function() {
				return new XMLHttpRequest
			}
		})(),
		ajaxQuery: function(config) {
			var xhr, query, isPost, param, url, lastModify, Y, reData;
            xhr = this.gethttp();
            query = {
                type: 'GET',
                data: null,
                encode: 'UTF-8',
                end: this.empty,
                __redirect__: this.empty,
                time: 0,
                cache: false,
                retry: 3,
                retime: 200
            };
			this.mix(query, config);
			query.url = config.url || location.href;
			query.async = !!config.end; // config.end to async
			isPost = query.type.toUpperCase() == 'POST';
            param = isPost ? this.toSearch(query.data) : null;
            url = isPost ? query.url : this.toSearch(query.data, query.url);
			xhr.open(query.type, url, query.async);
			
			xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
			
			if (isPost) {
				xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=' + query.encode)
			}
			lastModify = query.cache ? (this.ajaxQuery[query.url] || 0) : 0;
			xhr.setRequestHeader('If-Modified-Since', lastModify);
			if (this.ajaxQuery[query.url + 'ETag']) {
				xhr.setRequestHeader('If-None-Match', this.ajaxQuery[query.url + 'ETag'])
			}
			Y = this;
			if (query.async) {
				xhr.onreadystatechange = function() {
                    var ok, reData;
					if (xhr.readyState == 4) {
						clearTimeout(query.timer);
						ok = xhr.status == 200;
						if (ok && query.cache) {
							self.ajaxQuery[query.url] = xhr.getResponseHeader('Last-Modified');
							self.ajaxQuery[query.url + 'ETag'] = xhr.getResponseHeader('ETag');
						}
						reData = {
							url: config.url,
							text: xhr.responseText,
							xml: xhr.responseXML,
							status: xhr.status,
							error: xhr.status != 200 ? xhr.status: false,
							date: Date.parse(xhr.getResponseHeader('Date')),
                            type: query.type,
							returnValue: query.returnValue
						};
						xhr.status != 200 && xhr.status != 304 && (--query.retry) > 0 ? setTimeout(function() {
							Y.ajaxQuery(query)
						}, query.retime) : query.__redirect__(query.end.call(Y, reData, config));
						stop();
					}
				};
				if (query.time > 0) {
					query.timer = setTimeout(function() {
						stop();
						query.__redirect__(query.end.call(Y, {
							error: 'timeout'
						}))
					}, query.time)
				}
				function stop() {
					xhr.onreadystatechange = function(){};
					xhr.abort();
					xhr = null
				}
			}
			xhr.send(param);
			if (!query.async) {
				reData = {
					xml: xhr.responseXML,
					text: xhr.responseText,
					date: Date.parse(xhr.getResponseHeader('Date')),
					error: xhr.status != 200 ? xhr.status: false,
					status: xhr.status
				};
				xhr.abort();
				xhr = null
			}
			return query.async ? this : reData
		},
		ajax: (function() {
			var count, wait;
            count = 0;
			wait = [];
			return function() {
				var A, querys, Y;
                querys = A = Copy.call(arguments);
                Y = this;
				if (this.isString(A[0])) {
                    querys = [this.getObj('url', A[0], 'end', A[1], 'data', Object(A[2]), 'type', A[3] || 'GET')]
                }
				if (count >= Y.ajaxQuery.max){
                    return wait.push(querys)
                }
				for (var i = 0, l = querys.length; i < l; i++) {
					querys[i].__redirect__ = function(prev) {
						var next, nextQuee;
                        next = querys.shift();
						if (next && prev !== false) {
							next.returnValue = prev;
							Y.ajaxQuery(next)
						} else {
							count--;
							if (nextQuee = wait.shift()){
                                Y.ajax.apply(Y, nextQuee)
                            }
						}
					}
				}
				count += querys.end ? 1 : 0; // only async add count
				return this.ajaxQuery(querys.shift())
			}
		})(),
		getServerTime: function() {
			return new Date(this.ajax(false, 0, false, 'HEAD').date)
		},
		XMLNode: function(node, tag_text) {
			var text, o, attrs, n, s, subs; 
            text = '';
            o = {};
            attrs = {};
			if (node && node.nodeType == 1) {
                if (tag_text) {// get childNodes text list: {nodeName: text}
                    subs = node.childNodes;
                    for (var i =  subs.length; i--;) {
                        s = subs[i];
                        if (s.nodeType == 1) {
                            o[s.nodeName] = s.text || s.textContent || ''
                        }
                    }
                    text = node.text || node.textContent || ''
                }else{
                    attrs = node.attributes;
                    for (var j = 0, n = attrs.length; j < n; j++) {
                        o[attrs[j].nodeName] = attrs[j].nodeValue
                    }
                    text = node.text || node.textContent || ''            
                }
			}
			return {
				node: node,
				items: o,
				text: text
			}
		},
		qXml: function(find, doc, each, sub) {
			var sub, find, arr, n, q, qTag; 
            sub = sub || doc;
            arr = [];
            qTag =  this.qXml.tagMode;
			if (doc) {
				if ('selectNodes' in sub) {
					arr = sub.selectNodes(find)
				} else {
					if (q = doc.evaluate(find, sub, doc.createNSResolver(doc.documentElement), XPathResult.ORDERED_NODE_ITERATOR_TYPE, null)) {
						for (n = q.iterateNext(); n; n = q.iterateNext()) {
							arr.push(n)
						}
					}
				}
				if (each) {
					for (var i = 0, l = arr.length; i < l; i++) {
						if (false === each.call(this, this.XMLNode(arr[i], qTag), i)) {
							break
						}
					}
				}
			}
            this.qXml.tagMode = false;
			return arr
		},
		loadScript: (function() {
			var allScript, n, loading;
            allScript = {};
            n = 1;
            loading = {};
			return function(url, fn) {
                var runList, h, script, Y, config;
                url = this.getMapPath(url, true);// fix url
				if (allScript[url]) {// loaded
					return fn && fn.call(this)
				}
				runList = loading[url];// mulit load one
				if (runList && runList instanceof Array) {
					return runList.push(fn)// wait
				}
				runList = loading[url] = [fn]; // first
				h = this.one("head");
                Y = this;
                config = {
                    type: "text/javascript",
                    src: url
                };
				script = document.createElement("SCRIPT");
				this.ie ? this.on(script, 'readystatechange', _onload) : (script.onload = _onload);
				this.mix(script, config); // set src --> add to tree --> loaded or complete is ok
				h.firstChild ? h.insertBefore(script, h.firstChild) : h.appendChild(script);
				function _onload(e) {
					if (!this.readyState || 'loaded|complete'.indexOf(this.readyState) > -1) {
                        if (this.ie) {
                            Y.un(script)
                        } else {
                            script.onload = null
                        }
                        allScript[url] = true;
                        for (var i = 0, j = runList.length; i < j; i++) {
                            if (Y.isFunction(runList[i])) {
                                runList[i].call(Y)
                            }
                        }
                        delete loading[url];// delete wait queue
                        h.removeChild(script)
					}
				}
			}
		})(),
		use: function(mods, fn) {
            var l, n, Y;
			if (this.isString(mods)) {
				mods = mods.replace(/\s+/g,'').split(',')
			}
			l = n = mods.length;
            Y = this;
			for (var i = 0; i < l; i++) {
				this.loadScript(this.getMapPath(mods[i], true), ok)
			}
			return this;
			function ok() {
				if (--n == 0 && fn) {
					fn.call(Y)
				}
			}
		},
		loadImages: function(srcList, callback) {
			var count, complete, imgs, badImgs, Y, last, len;
            count = complete = 0;
            imgs = [];
            badImgs = [];
            Y = this,
            callback = callback || this.empty;
            last = last || this.empty;
			if (this.isString(srcList)) {
				srcList = srcList.split(',')
			}
			len = this.Try(this.Type+'.loadImages("'+srcList+'"): list is empty', !srcList, srcList).length;
			srcList.each(function(src, i) {
				var img, src;
                img = new Image;
                src = this.getMapPath(src);
				img.onload = img.onerror = img.onabort = aop;
				img.timeout = setTimeout(function() {
					aop.call(img, {
						type: 'timeout'
					})
				}, 10 * 1000);
				img.src = src
			}, this);
			function aop(e) {
				e = e || window.event;
				clearTimeout(this.timeout);
				this.onload = this.onerror = this.onabort = null;
                complete += e.type == 'load' ? 1 : 0;
				callback.call(Y, {
                    total: len,
					loaded: ++count,
					complete: complete,
					img: this,
                    step: (count/len).toFixed(2),
					isLoaded: count === len
				})
			}
		},
		addChild: function(obj, name, group) {
			this.Try(this.Type+'.addChild('+obj+'):not YClass object', !obj || !obj.Type || obj === this);
			if (obj.owner && obj.owner !== this) {
				this.Try('addChild('+obj+'): ' + obj.Type + ' reged in ' + obj.owner.Type);
			}
            if (name) {// add to property
                if (this[name] === obj) {
                    return obj
                }
                this[name] = this.Try('addChild("'+name+'"): name is exists ', name in this,obj);
                obj.__childPropertyName__ = name
            }
            if (group) {// add to group
                if (!this.__HASH_GROUPS__[group]) {
                    this.__HASH_GROUPS__[group] = []
                }
                 this.__HASH_GROUPS__[group].push( obj);
                 obj.__childGroupName__ = group
            }
			var guid = this.getGuid(obj);
			if (!this.__HASH_CHILDS__[guid]) {// save ref
				this.__HASH_CHILDS__[guid] = obj;
				obj.owner = this;
			}
            this.onaddchild(obj, name, group);// Write
			return obj
		},
        getChilds: function (gname){// find a group or all
            var g, cms;
            if (gname) {
                g = this.__HASH_GROUPS__[gname];
                return g ? g.slice() : []                
            }else{
                cms = [];
                for(var k in this.__HASH_CHILDS__){
                    cms.push(this.__HASH_CHILDS__[k])
                }
                return cms
            }
        },
        remove: function (){
            this.owner ? this.owner.removeChild(this) : this.__unload__();
        },
		removeChild: function(obj) {
			var childs, attrs;
            childs = this.__HASH_CHILDS__;
			if (obj) {
                attrs = [obj.__childPropertyName__, obj.__childGroupName__, obj.Type, this.getGuid(obj)];
                if(false === obj.__unload__()){
                    return this // stop unload itself
                }
				delete childs[attrs[3]];// del by save
                if (attrs[0]) {
                    delete this[attrs[0]]// del by property
                }
                if (attrs[1]) {
                    this.__HASH_GROUPS__[attrs[1]].remove(obj)// del by group
                }
                this.onremovechild(attrs[2])
			} else {
				for (var k in childs) {
					this.removeChild(childs[k]);
                    delete childs[k]
				}
			}            
			return this
		}
	};
	Tools.mix(Tools.fn, browser);
	Tools.mix(Tools.fn, isType);
	if (window.Node && Node.prototype && !Node.prototype.contains) {
		Node.prototype.contains = function(arg) {
             do{if(arg==this){return true}}while(arg && (arg=arg.parentNode));
             return false
		}
	}
    (function() {
		var queue, doScroll, loaded, fn, w3cReady, ieReady, begin;
        queue = [];
        doScroll = document.documentElement.doScroll;
		begin = function() {
			queue.reverse();
			while (fn = queue.pop()) {
				fn()
			}
			loaded = true
		};
		if (document.readyState === 'complete') {
			begin()
		}
		if (document.addEventListener) {
			w3cReady = function() {
				document.removeEventListener('DOMContentLoaded', w3cReady, false);
				begin()
			};
			document.addEventListener('DOMContentLoaded', w3cReady, false);
			window.addEventListener('load', begin, false)
		} else {
			ieReady = function() {
				if (document.readyState === 'complete') {
					begin();
					document.detachEvent('onreadystatechange', ieReady)
				}
			};
			document.attachEvent('onreadystatechange', ieReady);
			window.attachEvent('onload', begin);
			if (window == window.top) {
				function readyScroll() {
					try {
						doScroll('left');
						begin()
					} catch(e) {
						setTimeout(readyScroll, 1)
					}
				}
				readyScroll()
			}
		}
		Tools.fn.ready = function(fn) {
			loaded ? fn.call(this) : queue.push(fn.proxy(this))
		}
	})();
	if (browser.ie == 6) {
		document.execCommand("BackgroundImageCache", false, true)
	}
	if (browser.ie) { //for VML and HTML5
		document.writeln('<'+'?import namespace="v" urn="urn:schemas-microsoft-com:vml" implementation="#default#VML" declareNamespace />');
    }
	/* @ Class
   ---------------------------------------------------------------------------------------------------------------------------*/
	var Class = (function(BASE) {
        var iniKeys = /^(use|style|ready|single)$/;
		'getNext,getPrev,getChild,getParent'.split(',').each(function(type, i) {// noden nav
			this[type] = function(el, fn) {
				return this.nav(this.one(el), type, fn)
			}
		}, BASE);
        ("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover "+
            "mouseout mouseenter mouseleave change select submit keydown keypress keyup error losecapture").split(" ").each(function (type){
            this[type] = function (selector, fn, config){
                return this.on.call(this, selector, type, fn, config)
            }
        }, BASE);
        BASE.hover = function (selector,enter,leave){
            return this.on(selector, this.getObj('mouseenter', enter, 'mouseleave', leave))
        };// event split
		YCLASS_TMP_DIV.innerHTML ='<table><caption></caption><thead></thead><tbody><colgroup></colgroup><tr><td></td>'+
			'<th><strong></strong><select><option></option></select><div></div><span><span><em></em><p></p>'+
			'<input type="text"/><button></button><a href="#1"></a><ul><li></li></ul><dl><dt></dt><dd></dd></dl>'+
			'<ol><li></li></ol><textarea></textarea<label></label>><h1></h1></th></tr></tbody><tfoot></tfoot></table>';
		tmpNodes = YCLASS_TMP_DIV.getElementsByTagName('*');
		for (var i =  tmpNodes.length; i--;) {// save display show-value
			DISPLAY_VALUE[tmpNodes[i].nodeName] = BASE.getStyle(tmpNodes[i], 'display')	
		}
		BASE = Tools.create(BASE);// space out
		BASE.ajaxQuery.max = 2;
		BASE.index = function() {};
        BASE.onaddchild = function() {};
        BASE.onremovechild = function() {};
        BASE.onunload = function() {};
        BASE.indexBefore = function() {};
		BASE.GLOBAL_DOM_DATAS = {};// attr box
		BASE.global = {};
		var MASSAGE_WATCHER = {},
		    ALL_CLASS = [];
		BASE.showListen = function() {
			log(MASSAGE_WATCHER)
		};
        BASE.onMsg = function (type, fn){
            var msgSet = MASSAGE_WATCHER;
            type = this.msgGroup ? (this.msgGroup + '>'  + type) : type;
            if (!(type in msgSet)) {
                msgSet[type] = {}
            }
            msgSet[type][this.getGuid(this)] = fn.proxy(this)// bind content
        };
        BASE.postMsg = function (type){
            var msgSet, args, fnSet, reValue, k;
            msgSet = MASSAGE_WATCHER;
            args = Copy.call(arguments, 1);
            type = this.msgGroup ? (this.msgGroup + '>'  + type) : type;
            if (type in msgSet) {
                fnSet = msgSet[type];
                for(k in fnSet){
                    if (void(0) !== (reValue=fnSet[k].apply(null, args))) {
                        return reValue
                    }
                }
            }
        };
        BASE.unMsg = function (type){
             var msgSet, guid, msg;
             msgSet = MASSAGE_WATCHER;
             guid=this.getGuid(this);
             type = arguments.length>0 ? (this.groupName ? (this.groupName + '/'  + type) : type) : false;
             if (type && (type in msgSet)) {
                  msg = msgSet[type];
                  delete msg[guid]
             }else{
                 for( type in msgSet){
                      msg = msgSet[type];
                      delete msg[guid]
                 }                    
             }
             return this
        };
		BASE.__iterationAllClass__ = function(fn, bind) {
			ALL_CLASS.each(fn, bind)
		};
        BASE.toString = new Function('return "YClass > " + this.Type + " > instance"');
		return function(Extends,config) {
            var instances, subClass, parentClass, Super, superObj, superObjCopy, name, newProperty, classConfig, len;
            len = arguments.length;
			if (len === 0) {
				return new (Class({})) //* new Class or Class()
			}else if(len === 1){
                config = Extends
            }
            if(config instanceof Function){
                config = Tools.getObj('index',config)//* to Class(fn)
            }
            classConfig = {};
            newProperty = {};
            for(var k in config){// Divided into two parts, config and newProperty
                if (iniKeys.test(k)) {
                    classConfig[k] = config[k]
                }else{
                    newProperty[k] = config[k]
                }
            }
            name = newProperty.Type || 'None';
            Tools.Try('Class(extends, config): lib.name exists', name.trim() == '' || name in Class.lib);
			instances = [];
			subClass = (function() {
				var styleloaded, _subClass;
                return _subClass;
                function _subClass(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z) {
                        var args = Copy.call(arguments);
                        if (args.length < 20) {
                            return new _subClass(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z)
                        }
                        if (classConfig.single && instances.length > 0) {
                            return instances[0]
                        }
                        instances.push(this);
                        this.Class = _subClass; //*
                        this.lib = Class.lib; //*
                        this.Type = name;
                        this.__INSTANCE_EVENTS__ = {};
                        this.__DELETENODES__={};
                        this.__HASH_CHILDS__ = {};
                        this.__HASH_GROUPS__ = {};
                        this.__instanceTimers__ = {};
                        this.__instanceMutex__ = {};
                        if (classConfig.use && (this.isString(classConfig.use) || this.isArray(classConfig.use))) { //*
                            this.use(classConfig.use, function() {
                                this.index.apply(this, args);
                                this.indexBefore()//*
                            })
                        } else {
                            this.index.apply(this, args)
                        }
                    }
			})();
            Super = len == 1 ? false : (typeof Extends == 'string' ? Class.lib[Extends] : Extends);
			Tools.Try('Class(' + Super  + ', newProperty): Extends not\'s a Function', Super && !(Super instanceof Function));
            superObj = Super ? Super.prototype :  BASE;
            superObjCopy = Tools.create(superObj);// space out on super
            superObjCopy.__unload__ = function (){// unload only deleting an instance of the process of creating something
                if ('__INSTANCE_EVENTS__' in this) {
                    if (false !== this.onunload()) {
                        this.endFx().un().unMsg().removeChild();
                        if (this.__yclassguid__) {// del attr
                            delete this.GLOBAL_DOM_DATAS[this.__yclassguid__]
                        }
                        for(var k in this.__DELETENODES__){// del dom node
                            this.removeNode(this.__DELETENODES__[k])
                        }
                        for(k in this){
                            delete this[k]
                        }
                        instances.remove(this)
                    }
                }
            };
            subClass.prototype = Tools.mix(superObjCopy, Tools.mix({__YPROTOTYPE__: superObj}, newProperty));
            subClass.getObjs=function (){
                return instances.slice()
            };
            subClass.each=function (fn, bind){
                instances.each(fn, bind || window)
            };
            ALL_CLASS.push(subClass);
            if (classConfig.ready) {
                classConfig.single = true;
                BASE.ready(subClass)//* auto run on dom ready
            }else if (name != 'None') {
                Class.lib[name] = subClass
            }
            if (classConfig.style) {//add styleSheet on Class define (not on instace)
                Tools.fn.addStyle(classConfig.style);
            }
            return subClass
        }
    })(Tools.fn);
	Class.lib = {};
    (function (){
        var scripts, __SYSINI__, __initClass__, coreScript;
        scripts = document.getElementsByTagName('script');
        coreScript = scripts[scripts.length - 1];
        __SYSINI__={// get yclass.js base path and not use src property, ff return abs path, load css bg error.
            basePath: coreScript.getAttribute('src').replace(/^(.*)(?=yclass\.js).*$/i,'$1')
        };
        __initClass__ =  Class({
            single: true,
            Type: 'DefaultSystem',
            unload: function (){
                try{
                    this.removeChild();// All registration of objects is not in the class in the record
                    this.__iterationAllClass__(function (_class, i){//Remove all the components is not registered
                        _class.each(function (obj, i){
                            obj.__unload__()
                        })
                    })                        
                }catch(e){}
            }
        });
        Y = leyou = Yobj =  __YOBJECT__ = new __initClass__;// prev default obj
        __YOBJECT__.on(window,'load',function (){
            Tools.fn.windowloaded = true// save a window onloaded flag
        });
        __YOBJECT__.on(window,'unload',__YOBJECT__.unload.proxy(__YOBJECT__));
        Class.config=function (a,b){
            switch(arguments.length){
                case 0: return log(__SYSINI__);
                case 1: return __SYSINI__[a];
                default: __SYSINI__[a] = b
            }
        };
        Class.extend= Tools.fn.extend = function (key, value){
            Tools.fn[key] = Tools.Try((this.Type || 'Class')+'.extend("'+key+'"): key exists', key in Tools.fn, value)
        }
    })();
    window.Class = yclass = YClass = Def =  Class
})();