精华内容
下载资源
问答
  • 手机淘宝列表页面 的js调用展示

    万次阅读 2016-04-08 01:47:49
    手机淘宝列表页面 的js调用展示 http://www.lxway.com/814960451.htm 手机淘宝列表页面 的js调用展示  ...

    手机淘宝列表页面 的js调用展示


    http://www.lxway.com/814960451.htm

    手机淘宝列表页面 的js调用展示 


    http://api.m.taobao.com/h5/com.taobao.search.api.getshopitemlist/2.0/?v=2.0&api=com.taobao.search.api.getShopItemList&appKey=12574478&t=1438702983589&callback=mtopjsonp1&type=jsonp&sign=d5df66c0389ad26658f44959fc74bdab&data=%7B%22shopId%22%3A%22112980512%22%2C%22currentPage%22%3A1%2C%22pageSize%22%3A%2230%22%2C%22catId%22%3A%221112106335%22%2C%22catTxt%22%3A%22%7B%207%E6%9C%88%E7%A7%8B%E6%AC%BE%E7%AC%AC9%E6%89%B9%7D%22%2C%22sort%22%3A%22oldstarts%22%7D


    手机淘宝列表页面 的js调用展示

    --------------------------------


    列表页面

    http://shop.m.taobao.com/shop/shop_index.htm?spm=0.0.0.0&shop_id=112980512#list?catId=1112106335&catTxt={%207%E6%9C%88%E7%A7%8B%E6%AC%BE%E7%AC%AC9%E6%89%B9}

    // 请求页面数据, 开始解析
    function getPageView() {
        // 从 location 获取页面参数
        var params = [],
        PAGE_QUERY = {},
        VIEW_DATA = {};
        var page = window.G_msp_path?window.G_msp_path:'';//兼容店铺首页
        var search = location.search;
        if(search) {
            //search = decodeURIComponent(search);
            search = search.slice(1).split('&');
            search.forEach(function(param) {
                param = param.split('=');
                var k = param[0];
                var v = param[1];
                try{
                    v=decodeURIComponent(v);
     
                }catch(err) {}
                if(k == 'page') {
                    page = v;
                } else {
                    params.push(k + ':' + v);
                    PAGE_QUERY[k] = v;
                }
            })
        }
        if(!PAGE_QUERY.userId&&window.G_msp_userId){
            PAGE_QUERY.userId=window.G_msp_userId;
            VIEW_DATA.userId=window.G_msp_userId;
            params.push('userId:' + window.G_msp_userId);
            //兼容店铺首页
        };
        if(window.G_msp_shopId){
                params.push('shop_id:' + window.G_msp_shopId);
        };
    
        if(!page) {
            console.error('缺少 page 参数!');
            return;
        }
    
        lib.mtop.request({
            api: "mtop.geb.view.getPageView",
            v: "2.0",
            data: {
                page: page,
                clientVersion: '10000',
                params: params.join(';')
            }
        }, function(resp) {
          var resp=resp;
    
            window.meta = resp.data;
            Object.keys(meta.data).forEach(function(k) {
     
                VIEW_DATA[k] = meta.data[k];
            })
    
            // 单独处理页面 title
            var page_title = meta.title;
            if(page_title) {
                if(String(page_title).indexOf('$') == 0) {
                    page_title = VIEW_DATA[page_title.slice(1)];
                };
                if(page_title) {
                    document.title = decodeURI(page_title);
    
                    if (lib.env.taobaoApp && lib.env.taobaoApp.appname=='TB'&& lib.WindVane) {
     
                        lib.windvane.call('WebAppInterface', 'setCustomPageTitle',decodeURI(page_title));
                    };
                }
            }
            var page = new PageView(resp.data); 
    		var host = document.querySelector('#we-page');
    		host.innerHTML = '';
    		host.appendChild(page.element.root);
    
        }, function(resp) {
            console.log('获取页面数据失败: ', resp);
        });
     }
     
    getPageView(); 
        document.getElementById('we-page').style.height = 'auto';

    另外

    -------------

    http://bbs.125.la/thread-13785103-1-1.html

    相关网址 http://www.cnblogs.com/easyshop/
    http://www.cnblogs.com/easyshop/archive/2011/01/03/1924831.html
    http://www.zuanke8.com/space-uid-183728.html
    http://www.zuanke8.com/thread-1879054-1-1.html


    appkey 12278902对应的appsecret(744e7d*)暴露这么久了,现在才想到封
    封么不封彻底,登陆接口还可以用,就秒杀那禁止......


    然后,既然知道这个暴露了,那么不会更改接口阿,v4sign出来这么久还不用,光封这个appkey有用么?

    21646297,12574478?1478716954?1740881339?这些你不封么
    现在很多软件用21272146 这个appkey 也没见过 不知道哪里来的


    --------------------------------------------


    !
    function(a) {
    	String.prototype.trim === a && (String.prototype.trim = function() {
    		return this.replace(/^\s+|\s+$/g, "")
    	}),
    	Array.prototype.reduce === a && (Array.prototype.reduce = function(b) {
    		if (void 0 === this || null === this) throw new TypeError;
    		var c, d = Object(this),
    		e = d.length >>> 0,
    		f = 0;
    		if ("function" != typeof b) throw new TypeError;
    		if (0 == e && 1 == arguments.length) throw new TypeError;
    		if (arguments.length >= 2) c = arguments[1];
    		else for (;;) {
    			if (f in d) {
    				c = d[f++];
    				break
    			}
    			if (++f >= e) throw new TypeError
    		}
    		for (; e > f;) f in d && (c = b.call(a, c, d[f], f, d)),
    		f++;
    		return c
    	})
    } ();
    var Zepto = function() {
    	function a(a) {
    		return null == a ? String(a) : W[X.call(a)] || "object"
    	}
    	function b(b) {
    		return "function" == a(b)
    	}
    	function c(a) {
    		return null != a && a == a.window
    	}
    	function d(a) {
    		return null != a && a.nodeType == a.DOCUMENT_NODE
    	}
    	function e(b) {
    		return "object" == a(b)
    	}
    	function f(a) {
    		return e(a) && !c(a) && a.__proto__ == Object.prototype
    	}
    	function g(a) {
    		return a instanceof Array
    	}
    	function h(a) {
    		return "number" == typeof a.length
    	}
    	function i(a) {
    		return E.call(a,
    		function(a) {
    			return null != a
    		})
    	}
    	function j(a) {
    		return a.length > 0 ? y.fn.concat.apply([], a) : a
    	}
    	function k(a) {
    		return a.replace(/::/g, "/").replace(/([A-Z]+)([A-Z][a-z])/g, "$1_$2").replace(/([a-z\d])([A-Z])/g, "$1_$2").replace(/_/g, "-").toLowerCase()
    	}
    	function l(a) {
    		return a in H ? H[a] : H[a] = new RegExp("(^|\\s)" + a + "(\\s|$)")
    	}
    	function m(a, b) {
    		return "number" != typeof b || J[k(a)] ? b: b + "px"
    	}
    	function n(a) {
    		var b, c;
    		return G[a] || (b = F.createElement(a), F.body.appendChild(b), c = I(b, "").getPropertyValue("display"), b.parentNode.removeChild(b), "none" == c && (c = "block"), G[a] = c),
    		G[a]
    	}
    	function o(a) {
    		return "children" in a ? D.call(a.children) : y.map(a.childNodes,
    		function(a) {
    			return 1 == a.nodeType ? a: void 0
    		})
    	}
    	function p(a, b, c) {
    		for (x in b) c && (f(b[x]) || g(b[x])) ? (f(b[x]) && !f(a[x]) && (a[x] = {}), g(b[x]) && !g(a[x]) && (a[x] = []), p(a[x], b[x], c)) : b[x] !== w && (a[x] = b[x])
    	}
    	function q(a, b) {
    		return b === w ? y(a) : y(a).filter(b)
    	}
    	function r(a, c, d, e) {
    		return b(c) ? c.call(a, d, e) : c
    	}
    	function s(a, b, c) {
    		null == c ? a.removeAttribute(b) : a.setAttribute(b, c)
    	}
    	function t(a, b) {
    		var c = a.className,
    		d = c && c.baseVal !== w;
    		return b === w ? d ? c.baseVal: c: void(d ? c.baseVal = b: a.className = b)
    	}
    	function u(a) {
    		var b;
    		try {
    			return a ? "true" == a || ("false" == a ? !1 : "null" == a ? null: isNaN(b = Number(a)) ? /^[\[\{]/.test(a) ? y.parseJSON(a) : a: b) : a
    		} catch(c) {
    			return a
    		}
    	}
    	function v(a, b) {
    		b(a);
    		for (var c in a.childNodes) v(a.childNodes[c], b)
    	}
    	var w, x, y, z, A, B, C = [],
    	D = C.slice,
    	E = C.filter,
    	F = window.document,
    	G = {},
    	H = {},
    	I = F.defaultView.getComputedStyle,
    	J = {
    		"column-count": 1,
    		columns: 1,
    		"font-weight": 1,
    		"line-height": 1,
    		opacity: 1,
    		"z-index": 1,
    		zoom: 1
    	},
    	K = /^\s*<(\w+|!)[^>]*>/,
    	L = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
    	M = /^(?:body|html)$/i,
    	N = ["val", "css", "html", "text", "data", "width", "height", "offset"],
    	O = ["after", "prepend", "before", "append"],
    	P = F.createElement("table"),
    	Q = F.createElement("tr"),
    	R = {
    		tr: F.createElement("tbody"),
    		tbody: P,
    		thead: P,
    		tfoot: P,
    		td: Q,
    		th: Q,
    		"*": F.createElement("div")
    	},
    	S = /complete|loaded|interactive/,
    	T = /^\.([\w-]+)$/,
    	U = /^#([\w-]*)$/,
    	V = /^[\w-]+$/,
    	W = {},
    	X = W.toString,
    	Y = {},
    	Z = F.createElement("div");
    	return Y.matches = function(a, b) {
    		if (!a || 1 !== a.nodeType) return ! 1;
    		var c = a.webkitMatchesSelector || a.mozMatchesSelector || a.oMatchesSelector || a.matchesSelector;
    		if (c) return c.call(a, b);
    		var d, e = a.parentNode,
    		f = !e;
    		return f && (e = Z).appendChild(a),
    		d = ~Y.qsa(e, b).indexOf(a),
    		f && Z.removeChild(a),
    		d
    	},
    	A = function(a) {
    		return a.replace(/-+(.)?/g,
    		function(a, b) {
    			return b ? b.toUpperCase() : ""
    		})
    	},
    	B = function(a) {
    		return E.call(a,
    		function(b, c) {
    			return a.indexOf(b) == c
    		})
    	},
    	Y.fragment = function(a, b, c) {
    		a.replace && (a = a.replace(L, "<$1></$2>")),
    		b === w && (b = K.test(a) && RegExp.$1),
    		b in R || (b = "*");
    		var d, e, g = R[b];
    		return g.innerHTML = "" + a,
    		e = y.each(D.call(g.childNodes),
    		function() {
    			g.removeChild(this)
    		}),
    		f(c) && (d = y(e), y.each(c,
    		function(a, b) {
    			N.indexOf(a) > -1 ? d[a](b) : d.attr(a, b)
    		})),
    		e
    	},
    	Y.Z = function(a, b) {
    		return a = a || [],
    		a.__proto__ = y.fn,
    		a.selector = b || "",
    		a
    	},
    	Y.isZ = function(a) {
    		return a instanceof Y.Z
    	},
    	Y.init = function(a, c) {
    		if (a) {
    			if (b(a)) return y(F).ready(a);
    			if (Y.isZ(a)) return a;
    			var d;
    			if (g(a)) d = i(a);
    			else if (e(a)) d = [f(a) ? y.extend({},
    			a) : a],
    			a = null;
    			else if (K.test(a)) d = Y.fragment(a.trim(), RegExp.$1, c),
    			a = null;
    			else {
    				if (c !== w) return y(c).find(a);
    				d = Y.qsa(F, a)
    			}
    			return Y.Z(d, a)
    		}
    		return Y.Z()
    	},
    	y = function(a, b) {
    		return Y.init(a, b)
    	},
    	y.extend = function(a) {
    		var b, c = D.call(arguments, 1);
    		return "boolean" == typeof a && (b = a, a = c.shift()),
    		c.forEach(function(c) {
    			p(a, c, b)
    		}),
    		a
    	},
    	Y.qsa = function(a, b) {
    		var c;
    		return d(a) && U.test(b) ? (c = a.getElementById(RegExp.$1)) ? [c] : [] : 1 !== a.nodeType && 9 !== a.nodeType ? [] : D.call(T.test(b) ? a.getElementsByClassName(RegExp.$1) : V.test(b) ? a.getElementsByTagName(b) : a.querySelectorAll(b))
    	},
    	y.contains = function(a, b) {
    		return a !== b && a.contains(b)
    	},
    	y.type = a,
    	y.isFunction = b,
    	y.isWindow = c,
    	y.isArray = g,
    	y.isPlainObject = f,
    	y.isEmptyObject = function(a) {
    		var b;
    		for (b in a) return ! 1;
    		return ! 0
    	},
    	y.inArray = function(a, b, c) {
    		return C.indexOf.call(b, a, c)
    	},
    	y.camelCase = A,
    	y.trim = function(a) {
    		return a.trim()
    	},
    	y.uuid = 0,
    	y.support = {},
    	y.expr = {},
    	y.map = function(a, b) {
    		var c, d, e, f = [];
    		if (h(a)) for (d = 0; d < a.length; d++) c = b(a[d], d),
    		null != c && f.push(c);
    		else for (e in a) c = b(a[e], e),
    		null != c && f.push(c);
    		return j(f)
    	},
    	y.each = function(a, b) {
    		var c, d;
    		if (h(a)) {
    			for (c = 0; c < a.length; c++) if (b.call(a[c], c, a[c]) === !1) return a
    		} else for (d in a) if (b.call(a[d], d, a[d]) === !1) return a;
    		return a
    	},
    	y.grep = function(a, b) {
    		return E.call(a, b)
    	},
    	window.JSON && (y.parseJSON = JSON.parse),
    	y.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),
    	function(a, b) {
    		W["[object " + b + "]"] = b.toLowerCase()
    	}),
    	y.fn = {
    		forEach: C.forEach,
    		reduce: C.reduce,
    		push: C.push,
    		sort: C.sort,
    		indexOf: C.indexOf,
    		concat: C.concat,
    		map: function(a) {
    			return y(y.map(this,
    			function(b, c) {
    				return a.call(b, c, b)
    			}))
    		},
    		slice: function() {
    			return y(D.apply(this, arguments))
    		},
    		ready: function(a) {
    			return S.test(F.readyState) ? a(y) : F.addEventListener("DOMContentLoaded",
    			function() {
    				a(y)
    			},
    			!1),
    			this
    		},
    		get: function(a) {
    			return a === w ? D.call(this) : this[a >= 0 ? a: a + this.length]
    		},
    		toArray: function() {
    			return this.get()
    		},
    		size: function() {
    			return this.length
    		},
    		remove: function() {
    			return this.each(function() {
    				null != this.parentNode && this.parentNode.removeChild(this)
    			})
    		},
    		each: function(a) {
    			return C.every.call(this,
    			function(b, c) {
    				return a.call(b, c, b) !== !1
    			}),
    			this
    		},
    		filter: function(a) {
    			return b(a) ? this.not(this.not(a)) : y(E.call(this,
    			function(b) {
    				return Y.matches(b, a)
    			}))
    		},
    		add: function(a, b) {
    			return y(B(this.concat(y(a, b))))
    		},
    		is: function(a) {
    			return this.length > 0 && Y.matches(this[0], a)
    		},
    		not: function(a) {
    			var c = [];
    			if (b(a) && a.call !== w) this.each(function(b) {
    				a.call(this, b) || c.push(this)
    			});
    			else {
    				var d = "string" == typeof a ? this.filter(a) : h(a) && b(a.item) ? D.call(a) : y(a);
    				this.forEach(function(a) {
    					d.indexOf(a) < 0 && c.push(a)
    				})
    			}
    			return y(c)
    		},
    		has: function(a) {
    			return this.filter(function() {
    				return e(a) ? y.contains(this, a) : y(this).find(a).size()
    			})
    		},
    		eq: function(a) {
    			return - 1 === a ? this.slice(a) : this.slice(a, +a + 1)
    		},
    		first: function() {
    			var a = this[0];
    			return a && !e(a) ? a: y(a)
    		},
    		last: function() {
    			var a = this[this.length - 1];
    			return a && !e(a) ? a: y(a)
    		},
    		find: function(a) {
    			var b, c = this;
    			return b = "object" == typeof a ? y(a).filter(function() {
    				var a = this;
    				return C.some.call(c,
    				function(b) {
    					return y.contains(b, a)
    				})
    			}) : 1 == this.length ? y(Y.qsa(this[0], a)) : this.map(function() {
    				return Y.qsa(this, a)
    			})
    		},
    		closest: function(a, b) {
    			var c = this[0],
    			e = !1;
    			for ("object" == typeof a && (e = y(a)); c && !(e ? e.indexOf(c) >= 0 : Y.matches(c, a));) c = c !== b && !d(c) && c.parentNode;
    			return y(c)
    		},
    		parents: function(a) {
    			for (var b = [], c = this; c.length > 0;) c = y.map(c,
    			function(a) {
    				return (a = a.parentNode) && !d(a) && b.indexOf(a) < 0 ? (b.push(a), a) : void 0
    			});
    			return q(b, a)
    		},
    		parent: function(a) {
    			return q(B(this.pluck("parentNode")), a)
    		},
    		children: function(a) {
    			return q(this.map(function() {
    				return o(this)
    			}), a)
    		},
    		contents: function() {
    			return this.map(function() {
    				return D.call(this.childNodes)
    			})
    		},
    		siblings: function(a) {
    			return q(this.map(function(a, b) {
    				return E.call(o(b.parentNode),
    				function(a) {
    					return a !== b
    				})
    			}), a)
    		},
    		empty: function() {
    			return this.each(function() {
    				this.innerHTML = ""
    			})
    		},
    		pluck: function(a) {
    			return y.map(this,
    			function(b) {
    				return b[a]
    			})
    		},
    		show: function() {
    			return this.each(function() {
    				"none" == this.style.display && (this.style.display = null),
    				"none" == I(this, "").getPropertyValue("display") && (this.style.display = n(this.nodeName))
    			})
    		},
    		replaceWith: function(a) {
    			return this.before(a).remove()
    		},
    		wrap: function(a) {
    			var c = b(a);
    			if (this[0] && !c) var d = y(a).get(0),
    			e = d.parentNode || this.length > 1;
    			return this.each(function(b) {
    				y(this).wrapAll(c ? a.call(this, b) : e ? d.cloneNode(!0) : d)
    			})
    		},
    		wrapAll: function(a) {
    			if (this[0]) {
    				y(this[0]).before(a = y(a));
    				for (var b; (b = a.children()).length;) a = b.first();
    				y(a).append(this)
    			}
    			return this
    		},
    		wrapInner: function(a) {
    			var c = b(a);
    			return this.each(function(b) {
    				var d = y(this),
    				e = d.contents(),
    				f = c ? a.call(this, b) : a;
    				e.length ? e.wrapAll(f) : d.append(f)
    			})
    		},
    		unwrap: function() {
    			return this.parent().each(function() {
    				y(this).replaceWith(y(this).children())
    			}),
    			this
    		},
    		clone: function() {
    			return this.map(function() {
    				return this.cloneNode(!0)
    			})
    		},
    		hide: function() {
    			return this.css("display", "none")
    		},
    		toggle: function(a) {
    			return this.each(function() {
    				var b = y(this); (a === w ? "none" == b.css("display") : a) ? b.show() : b.hide()
    			})
    		},
    		prev: function(a) {
    			return y(this.pluck("previousElementSibling")).filter(a || "*")
    		},
    		next: function(a) {
    			return y(this.pluck("nextElementSibling")).filter(a || "*")
    		},
    		html: function(a) {
    			return a === w ? this.length > 0 ? this[0].innerHTML: null: this.each(function(b) {
    				var c = this.innerHTML;
    				y(this).empty().append(r(this, a, b, c))
    			})
    		},
    		text: function(a) {
    			return a === w ? this.length > 0 ? this[0].textContent: null: this.each(function() {
    				this.textContent = a
    			})
    		},
    		attr: function(a, b) {
    			var c;
    			return "string" == typeof a && b === w ? 0 == this.length || 1 !== this[0].nodeType ? w: "value" == a && "INPUT" == this[0].nodeName ? this.val() : !(c = this[0].getAttribute(a)) && a in this[0] ? this[0][a] : c: this.each(function(c) {
    				if (1 === this.nodeType) if (e(a)) for (x in a) s(this, x, a[x]);
    				else s(this, a, r(this, b, c, this.getAttribute(a)))
    			})
    		},
    		removeAttr: function(a) {
    			return this.each(function() {
    				1 === this.nodeType && s(this, a)
    			})
    		},
    		prop: function(a, b) {
    			return b === w ? this[0] && this[0][a] : this.each(function(c) {
    				this[a] = r(this, b, c, this[a])
    			})
    		},
    		data: function(a, b) {
    			var c = this.attr("data-" + k(a), b);
    			return null !== c ? u(c) : w
    		},
    		val: function(a) {
    			return a === w ? this[0] && (this[0].multiple ? y(this[0]).find("option").filter(function() {
    				return this.selected
    			}).pluck("value") : this[0].value) : this.each(function(b) {
    				this.value = r(this, a, b, this.value)
    			})
    		},
    		offset: function(a) {
    			if (a) return this.each(function(b) {
    				var c = y(this),
    				d = r(this, a, b, c.offset()),
    				e = c.offsetParent().offset(),
    				f = {
    					top: d.top - e.top,
    					left: d.left - e.left
    				};
    				"static" == c.css("position") && (f.position = "relative"),
    				c.css(f)
    			});
    			if (0 == this.length) return null;
    			var b = this[0].getBoundingClientRect();
    			return {
    				left: b.left + window.pageXOffset,
    				top: b.top + window.pageYOffset,
    				width: Math.round(b.width),
    				height: Math.round(b.height)
    			}
    		},
    		css: function(b, c) {
    			if (arguments.length < 2 && "string" == typeof b) return this[0] && (this[0].style[A(b)] || I(this[0], "").getPropertyValue(b));
    			var d = "";
    			if ("string" == a(b)) c || 0 === c ? d = k(b) + ":" + m(b, c) : this.each(function() {
    				this.style.removeProperty(k(b))
    			});
    			else for (x in b) b[x] || 0 === b[x] ? d += k(x) + ":" + m(x, b[x]) + ";": this.each(function() {
    				this.style.removeProperty(k(x))
    			});
    			return this.each(function() {
    				this.style.cssText += ";" + d
    			})
    		},
    		index: function(a) {
    			return a ? this.indexOf(y(a)[0]) : this.parent().children().indexOf(this[0])
    		},
    		hasClass: function(a) {
    			return C.some.call(this,
    			function(a) {
    				return this.test(t(a))
    			},
    			l(a))
    		},
    		addClass: function(a) {
    			return this.each(function(b) {
    				z = [];
    				var c = t(this),
    				d = r(this, a, b, c);
    				d.split(/\s+/g).forEach(function(a) {
    					y(this).hasClass(a) || z.push(a)
    				},
    				this),
    				z.length && t(this, c + (c ? " ": "") + z.join(" "))
    			})
    		},
    		removeClass: function(a) {
    			return this.each(function(b) {
    				return a === w ? t(this, "") : (z = t(this), r(this, a, b, z).split(/\s+/g).forEach(function(a) {
    					z = z.replace(l(a), " ")
    				}), void t(this, z.trim()))
    			})
    		},
    		toggleClass: function(a, b) {
    			return this.each(function(c) {
    				var d = y(this),
    				e = r(this, a, c, t(this));
    				e.split(/\s+/g).forEach(function(a) { (b === w ? !d.hasClass(a) : b) ? d.addClass(a) : d.removeClass(a)
    				})
    			})
    		},
    		scrollTop: function() {
    			return this.length ? "scrollTop" in this[0] ? this[0].scrollTop: this[0].scrollY: void 0
    		},
    		position: function() {
    			if (this.length) {
    				var a = this[0],
    				b = this.offsetParent(),
    				c = this.offset(),
    				d = M.test(b[0].nodeName) ? {
    					top: 0,
    					left: 0
    				}: b.offset();
    				return c.top -= parseFloat(y(a).css("margin-top")) || 0,
    				c.left -= parseFloat(y(a).css("margin-left")) || 0,
    				d.top += parseFloat(y(b[0]).css("border-top-width")) || 0,
    				d.left += parseFloat(y(b[0]).css("border-left-width")) || 0,
    				{
    					top: c.top - d.top,
    					left: c.left - d.left
    				}
    			}
    		},
    		offsetParent: function() {
    			return this.map(function() {
    				for (var a = this.offsetParent || F.body; a && !M.test(a.nodeName) && "static" == y(a).css("position");) a = a.offsetParent;
    				return a
    			})
    		}
    	},
    	y.fn.detach = y.fn.remove,
    	["width", "height"].forEach(function(a) {
    		y.fn[a] = function(b) {
    			var e, f = this[0],
    			g = a.replace(/./,
    			function(a) {
    				return a[0].toUpperCase()
    			});
    			return b === w ? c(f) ? f["inner" + g] : d(f) ? f.documentElement["offset" + g] : (e = this.offset()) && e[a] : this.each(function(c) {
    				f = y(this),
    				f.css(a, r(this, b, c, f[a]()))
    			})
    		}
    	}),
    	O.forEach(function(b, c) {
    		var d = c % 2;
    		y.fn[b] = function() {
    			var b, e, f = y.map(arguments,
    			function(c) {
    				return b = a(c),
    				"object" == b || "array" == b || null == c ? c: Y.fragment(c)
    			}),
    			g = this.length > 1;
    			return f.length < 1 ? this: this.each(function(a, b) {
    				e = d ? b: b.parentNode,
    				b = 0 == c ? b.nextSibling: 1 == c ? b.firstChild: 2 == c ? b: null,
    				f.forEach(function(a) {
    					if (g) a = a.cloneNode(!0);
    					else if (!e) return y(a).remove();
    					v(e.insertBefore(a, b),
    					function(a) {
    						null == a.nodeName || "SCRIPT" !== a.nodeName.toUpperCase() || a.type && "text/javascript" !== a.type || a.src || window.eval.call(window, a.innerHTML)
    					})
    				})
    			})
    		},
    		y.fn[d ? b + "To": "insert" + (c ? "Before": "After")] = function(a) {
    			return y(a)[b](this),
    			this
    		}
    	}),
    	Y.Z.prototype = y.fn,
    	Y.uniq = B,
    	Y.deserializeValue = u,
    	y.zepto = Y,
    	y
    } ();
    window.Zepto = Zepto,
    "$" in window || (window.$ = Zepto),
    function(a) {
    	function b(a) {
    		var b = this.os = {},
    		c = this.browser = {},
    		d = a.match(/WebKit\/([\d.]+)/),
    		e = a.match(/(Android)\s+([\d.]+)/),
    		f = a.match(/(iPad).*OS\s([\d_]+)/),
    		g = !f && a.match(/(iPhone\sOS)\s([\d_]+)/),
    		h = a.match(/(webOS|hpwOS)[\s\/]([\d.]+)/),
    		i = h && a.match(/TouchPad/),
    		j = a.match(/Kindle\/([\d.]+)/),
    		k = a.match(/Silk\/([\d._]+)/),
    		l = a.match(/(BlackBerry).*Version\/([\d.]+)/),
    		m = a.match(/(BB10).*Version\/([\d.]+)/),
    		n = a.match(/(RIM\sTablet\sOS)\s([\d.]+)/),
    		o = a.match(/PlayBook/),
    		p = a.match(/Chrome\/([\d.]+)/) || a.match(/CriOS\/([\d.]+)/),
    		q = a.match(/Firefox\/([\d.]+)/); (c.webkit = !!d) && (c.version = d[1]),
    		e && (b.android = !0, b.version = e[2]),
    		g && (b.ios = b.iphone = !0, b.version = g[2].replace(/_/g, ".")),
    		f && (b.ios = b.ipad = !0, b.version = f[2].replace(/_/g, ".")),
    		h && (b.webos = !0, b.version = h[2]),
    		i && (b.touchpad = !0),
    		l && (b.blackberry = !0, b.version = l[2]),
    		m && (b.bb10 = !0, b.version = m[2]),
    		n && (b.rimtabletos = !0, b.version = n[2]),
    		o && (c.playbook = !0),
    		j && (b.kindle = !0, b.version = j[1]),
    		k && (c.silk = !0, c.version = k[1]),
    		!k && b.android && a.match(/Kindle Fire/) && (c.silk = !0),
    		p && (c.chrome = !0, c.version = p[1]),
    		q && (c.firefox = !0, c.version = q[1]),
    		b.tablet = !!(f || o || e && !a.match(/Mobile/) || q && a.match(/Tablet/)),
    		b.phone = !(b.tablet || !(e || g || h || l || m || p && a.match(/Android/) || p && a.match(/CriOS\/([\d.]+)/) || q && a.match(/Mobile/)))
    	}
    	b.call(a, navigator.userAgent),
    	a.__detect = b
    } (Zepto),
    function(a) {
    	function b(a) {
    		return a._zid || (a._zid = n++)
    	}
    	function c(a, c, f, g) {
    		if (c = d(c), c.ns) var h = e(c.ns);
    		return (m[b(a)] || []).filter(function(a) {
    			return ! (!a || c.e && a.e != c.e || c.ns && !h.test(a.ns) || f && b(a.fn) !== b(f) || g && a.sel != g)
    		})
    	}
    	function d(a) {
    		var b = ("" + a).split(".");
    		return {
    			e: b[0],
    			ns: b.slice(1).sort().join(" ")
    		}
    	}
    	function e(a) {
    		return new RegExp("(?:^| )" + a.replace(" ", " .* ?") + "(?: |$)")
    	}
    	function f(b, c, d) {
    		"string" != a.type(b) ? a.each(b, d) : b.split(/\s/).forEach(function(a) {
    			d(a, c)
    		})
    	}
    	function g(a, b) {
    		return a.del && ("focus" == a.e || "blur" == a.e) || !!b
    	}
    	function h(a) {
    		return p[a] || a
    	}
    	function i(c, e, i, j, k, l) {
    		var n = b(c),
    		o = m[n] || (m[n] = []);
    		f(e, i,
    		function(b, e) {
    			var f = d(b);
    			f.fn = e,
    			f.sel = j,
    			f.e in p && (e = function(b) {
    				var c = b.relatedTarget;
    				return ! c || c !== this && !a.contains(this, c) ? f.fn.apply(this, arguments) : void 0
    			}),
    			f.del = k && k(e, b);
    			var i = f.del || e;
    			f.proxy = function(a) {
    				var b = i.apply(c, [a].concat(a.data));
    				return b === !1 && (a.preventDefault(), a.stopPropagation()),
    				b
    			},
    			f.i = o.length,
    			o.push(f),
    			c.addEventListener(h(f.e), f.proxy, g(f, l))
    		})
    	}
    	function j(a, d, e, i, j) {
    		var k = b(a);
    		f(d || "", e,
    		function(b, d) {
    			c(a, b, d, i).forEach(function(b) {
    				delete m[k][b.i],
    				a.removeEventListener(h(b.e), b.proxy, g(b, j))
    			})
    		})
    	}
    	function k(b) {
    		var c, d = {
    			originalEvent: b
    		};
    		for (c in b) s.test(c) || void 0 === b[c] || (d[c] = b[c]);
    		return a.each(t,
    		function(a, c) {
    			d[a] = function() {
    				return this[c] = q,
    				b[a].apply(b, arguments)
    			},
    			d[c] = r
    		}),
    		d
    	}
    	function l(a) {
    		if (! ("defaultPrevented" in a)) {
    			a.defaultPrevented = !1;
    			var b = a.preventDefault;
    			a.preventDefault = function() {
    				this.defaultPrevented = !0,
    				b.call(this)
    			}
    		}
    	}
    	var m = (a.zepto.qsa, {}),
    	n = 1,
    	o = {},
    	p = {
    		mouseenter: "mouseover",
    		mouseleave: "mouseout"
    	};
    	o.click = o.mousedown = o.mouseup = o.mousemove = "MouseEvents",
    	a.event = {
    		add: i,
    		remove: j
    	},
    	a.proxy = function(c, d) {
    		if (a.isFunction(c)) {
    			var e = function() {
    				return c.apply(d, arguments)
    			};
    			return e._zid = b(c),
    			e
    		}
    		if ("string" == typeof d) return a.proxy(c[d], c);
    		throw new TypeError("expected function")
    	},
    	a.fn.bind = function(a, b) {
    		return this.each(function() {
    			i(this, a, b)
    		})
    	},
    	a.fn.unbind = function(a, b) {
    		return this.each(function() {
    			j(this, a, b)
    		})
    	},
    	a.fn.one = function(a, b) {
    		return this.each(function(c, d) {
    			i(this, a, b, null,
    			function(a, b) {
    				return function() {
    					var c = a.apply(d, arguments);
    					return j(d, b, a),
    					c
    				}
    			})
    		})
    	};
    	var q = function() {
    		return ! 0
    	},
    	r = function() {
    		return ! 1
    	},
    	s = /^([A-Z]|layer[XY]$)/,
    	t = {
    		preventDefault: "isDefaultPrevented",
    		stopImmediatePropagation: "isImmediatePropagationStopped",
    		stopPropagation: "isPropagationStopped"
    	};
    	a.fn.delegate = function(b, c, d) {
    		return this.each(function(e, f) {
    			i(f, c, d, b,
    			function(c) {
    				return function(d) {
    					var e, g = a(d.target).closest(b, f).get(0);
    					return g ? (e = a.extend(k(d), {
    						currentTarget: g,
    						liveFired: f
    					}), c.apply(g, [e].concat([].slice.call(arguments, 1)))) : void 0
    				}
    			})
    		})
    	},
    	a.fn.undelegate = function(a, b, c) {
    		return this.each(function() {
    			j(this, b, c, a)
    		})
    	},
    	a.fn.live = function(b, c) {
    		return a(document.body).delegate(this.selector, b, c),
    		this
    	},
    	a.fn.die = function(b, c) {
    		return a(document.body).undelegate(this.selector, b, c),
    		this
    	},
    	a.fn.on = function(b, c, d) {
    		return ! c || a.isFunction(c) ? this.bind(b, c || d) : this.delegate(c, b, d)
    	},
    	a.fn.off = function(b, c, d) {
    		return ! c || a.isFunction(c) ? this.unbind(b, c || d) : this.undelegate(c, b, d)
    	},
    	a.fn.trigger = function(b, c) {
    		return ("string" == typeof b || a.isPlainObject(b)) && (b = a.Event(b)),
    		l(b),
    		b.data = c,
    		this.each(function() {
    			"dispatchEvent" in this && this.dispatchEvent(b)
    		})
    	},
    	a.fn.triggerHandler = function(b, d) {
    		var e, f;
    		return this.each(function(g, h) {
    			e = k("string" == typeof b ? a.Event(b) : b),
    			e.data = d,
    			e.target = h,
    			a.each(c(h, b.type || b),
    			function(a, b) {
    				return f = b.proxy(e),
    				e.isImmediatePropagationStopped() ? !1 : void 0
    			})
    		}),
    		f
    	},
    	"focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select keydown keypress keyup error".split(" ").forEach(function(b) {
    		a.fn[b] = function(a) {
    			return a ? this.bind(b, a) : this.trigger(b)
    		}
    	}),
    	["focus", "blur"].forEach(function(b) {
    		a.fn[b] = function(a) {
    			return a ? this.bind(b, a) : this.each(function() {
    				try {
    					this[b]()
    				} catch(a) {}
    			}),
    			this
    		}
    	}),
    	a.Event = function(a, b) {
    		"string" != typeof a && (b = a, a = b.type);
    		var c = document.createEvent(o[a] || "Events"),
    		d = !0;
    		if (b) for (var e in b)"bubbles" == e ? d = !!b[e] : c[e] = b[e];
    		return c.initEvent(a, d, !0, null, null, null, null, null, null, null, null, null, null, null, null),
    		c.isDefaultPrevented = function() {
    			return this.defaultPrevented
    		},
    		c
    	}
    } (Zepto),
    function(a) {
    	function b(b, c, d) {
    		var e = a.Event(c);
    		return a(b).trigger(e, d),
    		!e.defaultPrevented
    	}
    	function c(a, c, d, e) {
    		return a.global ? b(c || s, d, e) : void 0
    	}
    	function d(b) {
    		b.global && 0 === a.active++&&c(b, null, "ajaxStart")
    	}
    	function e(b) {
    		b.global && !--a.active && c(b, null, "ajaxStop")
    	}
    	function f(a, b) {
    		var d = b.context;
    		return b.beforeSend.call(d, a, b) === !1 || c(b, d, "ajaxBeforeSend", [a, b]) === !1 ? !1 : void c(b, d, "ajaxSend", [a, b])
    	}
    	function g(a, b, d) {
    		var e = d.context,
    		f = "success";
    		d.success.call(e, a, f, b),
    		c(d, e, "ajaxSuccess", [b, d, a]),
    		i(f, b, d)
    	}
    	function h(a, b, d, e) {
    		var f = e.context;
    		e.error.call(f, d, b, a),
    		c(e, f, "ajaxError", [d, e, a]),
    		i(b, d, e)
    	}
    	function i(a, b, d) {
    		var f = d.context;
    		d.complete.call(f, b, a),
    		c(d, f, "ajaxComplete", [b, d]),
    		e(d)
    	}
    	function j() {}
    	function k(a) {
    		return a && (a = a.split(";", 2)[0]),
    		a && (a == x ? "html": a == w ? "json": u.test(a) ? "script": v.test(a) && "xml") || "text"
    	}
    	function l(a, b) {
    		return (a + "&" + b).replace(/[&?]{1,2}/, "?")
    	}
    	function m(b) {
    		b.processData && b.data && "string" != a.type(b.data) && (b.data = a.param(b.data, b.traditional)),
    		!b.data || b.type && "GET" != b.type.toUpperCase() || (b.url = l(b.url, b.data))
    	}
    	function n(b, c, d, e) {
    		var f = !a.isFunction(c);
    		return {
    			url: b,
    			data: f ? c: void 0,
    			success: f ? a.isFunction(d) ? d: void 0 : c,
    			dataType: f ? e || d: d
    		}
    	}
    	function o(b, c, d, e) {
    		var f, g = a.isArray(c);
    		a.each(c,
    		function(c, h) {
    			f = a.type(h),
    			e && (c = d ? e: e + "[" + (g ? "": c) + "]"),
    			!e && g ? b.add(h.name, h.value) : "array" == f || !d && "object" == f ? o(b, h, d, c) : b.add(c, h)
    		})
    	}
    	var p, q, r = 0,
    	s = window.document,
    	t = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
    	u = /^(?:text|application)\/javascript/i,
    	v = /^(?:text|application)\/xml/i,
    	w = "application/json",
    	x = "text/html",
    	y = /^\s*$/;
    	a.active = 0,
    	a.ajaxJSONP = function(b) {
    		if (! ("type" in b)) return a.ajax(b);
    		var c, d = "jsonp" + ++r,
    		e = s.createElement("script"),
    		i = function() {
    			clearTimeout(c),
    			a(e).remove(),
    			delete window[d]
    		},
    		k = function(a) {
    			i(),
    			a && "timeout" != a || (window[d] = j),
    			h(null, a || "abort", l, b)
    		},
    		l = {
    			abort: k
    		};
    		return f(l, b) === !1 ? (k("abort"), !1) : (window[d] = function(a) {
    			i(),
    			g(a, l, b)
    		},
    		e.onerror = function() {
    			k("error")
    		},
    		e.src = b.url.replace(/=\?/, "=" + d), a("head").append(e), b.timeout > 0 && (c = setTimeout(function() {
    			k("timeout")
    		},
    		b.timeout)), l)
    	},
    	a.ajaxSettings = {
    		type: "GET",
    		beforeSend: j,
    		success: j,
    		error: j,
    		complete: j,
    		context: null,
    		global: !0,
    		xhr: function() {
    			return new window.XMLHttpRequest
    		},
    		accepts: {
    			script: "text/javascript, application/javascript",
    			json: w,
    			xml: "application/xml, text/xml",
    			html: x,
    			text: "text/plain"
    		},
    		crossDomain: !1,
    		timeout: 0,
    		processData: !0,
    		cache: !0
    	},
    	a.ajax = function(b) {
    		var c = a.extend({},
    		b || {});
    		for (p in a.ajaxSettings) void 0 === c[p] && (c[p] = a.ajaxSettings[p]);
    		d(c),
    		c.crossDomain || (c.crossDomain = /^([\w-]+:)?\/\/([^\/]+)/.test(c.url) && RegExp.$2 != window.location.host),
    		c.url || (c.url = window.location.toString()),
    		m(c),
    		c.cache === !1 && (c.url = l(c.url, "_=" + Date.now()));
    		var e = c.dataType,
    		i = /=\?/.test(c.url);
    		if ("jsonp" == e || i) return i || (c.url = l(c.url, "callback=?")),
    		a.ajaxJSONP(c);
    		var n, o = c.accepts[e],
    		r = {},
    		s = /^([\w-]+:)\/\//.test(c.url) ? RegExp.$1: window.location.protocol,
    		t = c.xhr();
    		c.crossDomain || (r["X-Requested-With"] = "XMLHttpRequest"),
    		o && (r.Accept = o, o.indexOf(",") > -1 && (o = o.split(",", 2)[0]), t.overrideMimeType && t.overrideMimeType(o)),
    		(c.contentType || c.contentType !== !1 && c.data && "GET" != c.type.toUpperCase()) && (r["Content-Type"] = c.contentType || "application/x-www-form-urlencoded"),
    		c.headers = a.extend(r, c.headers || {}),
    		t.onreadystatechange = function() {
    			if (4 == t.readyState) {
    				t.onreadystatechange = j,
    				clearTimeout(n);
    				var b, d = !1;
    				if (t.status >= 200 && t.status < 300 || 304 == t.status || 0 == t.status && "file:" == s) {
    					e = e || k(t.getResponseHeader("content-type")),
    					b = t.responseText;
    					try {
    						"script" == e ? (1, eval)(b) : "xml" == e ? b = t.responseXML: "json" == e && (b = y.test(b) ? null: a.parseJSON(b))
    					} catch(f) {
    						d = f
    					}
    					d ? h(d, "parsererror", t, c) : g(b, t, c)
    				} else h(null, t.status ? "error": "abort", t, c)
    			}
    		};
    		var u = "async" in c ? c.async: !0;
    		t.open(c.type, c.url, u);
    		for (q in c.headers) t.setRequestHeader(q, c.headers[q]);
    		return f(t, c) === !1 ? (t.abort(), !1) : (c.timeout > 0 && (n = setTimeout(function() {
    			t.onreadystatechange = j,
    			t.abort(),
    			h(null, "timeout", t, c)
    		},
    		c.timeout)), t.send(c.data ? c.data: null), t)
    	},
    	a.get = function() {
    		return a.ajax(n.apply(null, arguments))
    	},
    	a.post = function() {
    		var b = n.apply(null, arguments);
    		return b.type = "POST",
    		a.ajax(b)
    	},
    	a.getJSON = function() {
    		var b = n.apply(null, arguments);
    		return b.dataType = "json",
    		a.ajax(b)
    	},
    	a.fn.load = function(b, c, d) {
    		if (!this.length) return this;
    		var e, f = this,
    		g = b.split(/\s/),
    		h = n(b, c, d),
    		i = h.success;
    		return g.length > 1 && (h.url = g[0], e = g[1]),
    		h.success = function(b) {
    			f.html(e ? a("<div>").html(b.replace(t, "")).find(e) : b),
    			i && i.apply(f, arguments)
    		},
    		a.ajax(h),
    		this
    	};
    	var z = encodeURIComponent;
    	a.param = function(a, b) {
    		var c = [];
    		return c.add = function(a, b) {
    			this.push(z(a) + "=" + z(b))
    		},
    		o(c, a, b),
    		c.join("&").replace(/%20/g, "+")
    	}
    } (Zepto),
    function(a) {
    	a.fn.serializeArray = function() {
    		var b, c = [];
    		return a(Array.prototype.slice.call(this.get(0).elements)).each(function() {
    			b = a(this);
    			var d = b.attr("type");
    			"fieldset" != this.nodeName.toLowerCase() && !this.disabled && "submit" != d && "reset" != d && "button" != d && ("radio" != d && "checkbox" != d || this.checked) && c.push({
    				name: b.attr("name"),
    				value: b.val()
    			})
    		}),
    		c
    	},
    	a.fn.serialize = function() {
    		var a = [];
    		return this.serializeArray().forEach(function(b) {
    			a.push(encodeURIComponent(b.name) + "=" + encodeURIComponent(b.value))
    		}),
    		a.join("&")
    	},
    	a.fn.submit = function(b) {
    		if (b) this.bind("submit", b);
    		else if (this.length) {
    			var c = a.Event("submit");
    			this.eq(0).trigger(c),
    			c.defaultPrevented || this.get(0).submit()
    		}
    		return this
    	}
    } (Zepto),
    function(a, b) {
    	function c(a) {
    		return d(a.replace(/([a-z])([A-Z])/, "$1-$2"))
    	}
    	function d(a) {
    		return a.toLowerCase()
    	}
    	function e(a) {
    		return f ? f + a: d(a)
    	}
    	var f, g, h, i, j, k, l, m, n = "",
    	o = {
    		Webkit: "webkit",
    		Moz: "",
    		O: "o",
    		ms: "MS"
    	},
    	p = window.document,
    	q = p.createElement("div"),
    	r = /^((translate|rotate|scale)(X|Y|Z|3d)?|matrix(3d)?|perspective|skew(X|Y)?)$/i,
    	s = {};
    	a.each(o,
    	function(a, c) {
    		return q.style[a + "TransitionProperty"] !== b ? (n = "-" + d(a) + "-", f = c, !1) : void 0
    	}),
    	g = n + "transform",
    	s[h = n + "transition-property"] = s[i = n + "transition-duration"] = s[j = n + "transition-timing-function"] = s[k = n + "animation-name"] = s[l = n + "animation-duration"] = s[m = n + "animation-timing-function"] = "",
    	a.fx = {
    		off: f === b && q.style.transitionProperty === b,
    		speeds: {
    			_default: 400,
    			fast: 200,
    			slow: 600
    		},
    		cssPrefix: n,
    		transitionEnd: e("TransitionEnd"),
    		animationEnd: e("AnimationEnd")
    	},
    	a.fn.animate = function(b, c, d, e) {
    		return a.isPlainObject(c) && (d = c.easing, e = c.complete, c = c.duration),
    		c && (c = ("number" == typeof c ? c: a.fx.speeds[c] || a.fx.speeds._default) / 1e3),
    		this.anim(b, c, d, e)
    	},
    	a.fn.anim = function(d, e, f, n) {
    		var o, p, q, t = {},
    		u = "",
    		v = this,
    		w = a.fx.transitionEnd;
    		if (e === b && (e = .4), a.fx.off && (e = 0), "string" == typeof d) t[k] = d,
    		t[l] = e + "s",
    		t[m] = f || "linear",
    		w = a.fx.animationEnd;
    		else {
    			p = [];
    			for (o in d) r.test(o) ? u += o + "(" + d[o] + ") ": (t[o] = d[o], p.push(c(o)));
    			u && (t[g] = u, p.push(g)),
    			e > 0 && "object" == typeof d && (t[h] = p.join(", "), t[i] = e + "s", t[j] = f || "linear")
    		}
    		return q = function(b) {
    			if ("undefined" != typeof b) {
    				if (b.target !== b.currentTarget) return;
    				a(b.target).unbind(w, q)
    			}
    			a(this).css(s),
    			n && n.call(this)
    		},
    		e > 0 && this.bind(w, q),
    		this.size() && this.get(0).clientLeft,
    		this.css(t),
    		0 >= e && setTimeout(function() {
    			v.each(function() {
    				q.call(this)
    			})
    		},
    		0),
    		this
    	},
    	q = null
    } (Zepto),
    function(a) {
    	if ("undefined" == typeof window.define) {
    		var b = {},
    		c = b.exports = {};
    		result = a(null, c, b) || b.exports
    	} else define(a)
    } (function(a) {
    	function b() {
    		return g.href.toString()
    	}
    	function c() {
    		return ""
    	}
    	function d() {
    		return f.cookie.match(j)
    	}
    	var e = window,
    	f = e.document,
    	g = e.location,
    	h = a ? a("zepto") : e.Zepto || e.$,
    	i = "//log.m.taobao.com/js.do",
    	j = /(?:^|\s)cna=([^;]+)(?:;|$)/;
    	return h.orginAjax = h.ajax,
    	h.ajax = function(a) {
    		function e() {
    			p && p.apply(this, arguments),
    			(n === !0 || 1 === n) && (f = b(), g = d(), j = c(), k = a.apdata || a.ap_data, l = a.apuri || a.ap_uri, f && (o.ap_ref = f), g && (o.ap_cna = g[1]), k && (o.ap_data = k), l && (o.ap_uri = l), j && (o.ap_ip = j), m = {
    				url: i,
    				data: o,
    				type: "GET",
    				dataType: "jsonp"
    			},
    			2 === n || h.orginAjax(m))
    		}
    		var f, g, j, k, l, m, n = null != a.aplus ? a.aplus: h.ajaxSettings.aplus || !1,
    		o = {
    			_aplus: "1"
    		},
    		p = a.complete;
    		a.url ? (a.complete = e, h.orginAjax(a)) : e()
    	},
    	h
    }),
    function(win, undef) {
    	function compareVersion(a, b) {
    		a = a.toString().split("."),
    		b = b.toString().split(".");
    		for (var c = 0; c < a.length || c < b.length; c++) {
    			var d = parseInt(a[c], 10),
    			e = parseInt(b[c], 10);
    			if (window.isNaN(d) && (d = 0), window.isNaN(e) && (e = 0), e > d) return - 1;
    			if (d > e) return 1
    		}
    		return 0
    	}
    	function callback(a, b) {
    		isAndroid && compareVersion(osVersion, "2.4.0") < 0 ? setTimeout(function() {
    			a && a(b.value || b)
    		},
    		1) : a && a(b.value || b)
    	}
    	var doc = win.document,
    	ua = win.navigator.userAgent,
    	isIOS = /iPhone|iPad|iPod/i.test(ua),
    	isAndroid = /Android/i.test(ua),
    	isWindVane = /WindVane/i.test(ua),
    	osVersion = ua.match(/(?:OS|Android)[\/\s](\d+[._]\d+(?:[._]\d+)?)/i),
    	wvVersion = ua.match(/WindVane[\/\s](\d+[._]\d+[._]\d+)/),
    	hasOwnProperty = Object.prototype.hasOwnProperty,
    	WindVane = win.WindVane || (win.WindVane = {}),
    	WindVane_Native = win.WindVane_Native,
    	callbackMap = {},
    	inc = 1,
    	iframePool = [],
    	iframeLimit = 3,
    	LOCAL_PROTOCOL = "hybrid",
    	WV_PROTOCOL = "wv_hybrid",
    	IFRAME_PREFIX = "iframe_",
    	SUCCESS_PREFIX = "suc_",
    	FAILURE_PREFIX = "err_",
    	PARAM_PREFIX = "param_";
    	osVersion = osVersion ? (osVersion[1] || "0.0.0").replace(/\_/g, ".") : "0.0.0",
    	wvVersion = wvVersion ? (wvVersion[1] || "0.0.0").replace(/\_/g, ".") : "0.0.0";
    	var WV_Core = {
    		call: function(a, b, c, d, e, f) {
    			var g;
    			g = f > 0 ? setTimeout(function() {
    				WV_Core.onFailure(g, {
    					ret: "TIMEOUT"
    				})
    			},
    			f) : WV_Private.getSid(),
    			WV_Private.registerCall(g, d, e),
    			isAndroid ? compareVersion(wvVersion, "2.7.0") >= 0 ? WV_Private.callMethodByPrompt(a, b, WV_Private.buildParam(c), g + "") : WindVane_Native && WindVane_Native.callMethod && WindVane_Native.callMethod(a, b, WV_Private.buildParam(c), g + "") : isIOS && WV_Private.callMethodByIframe(a, b, WV_Private.buildParam(c), g + "")
    		},
    		fireEvent: function(a, b) {
    			var c = doc.createEvent("HTMLEvents");
    			c.initEvent(a, !1, !0),
    			c.param = WV_Private.parseParam(b),
    			doc.dispatchEvent(c)
    		},
    		getParam: function(a) {
    			return WV_Private.params[PARAM_PREFIX + a] || ""
    		},
    		onSuccess: function(a, b) {
    			clearTimeout(a);
    			var c = WV_Private.unregisterCall(a).success,
    			d = WV_Private.parseParam(b);
    			callback(c, d),
    			WV_Private.onComplete(a)
    		},
    		onFailure: function(a, b) {
    			clearTimeout(a);
    			var c = WV_Private.unregisterCall(a).failure,
    			d = WV_Private.parseParam(b);
    			callback(c, d),
    			WV_Private.onComplete(a)
    		}
    	},
    	WV_Private = {
    		params: {},
    		buildParam: function(a) {
    			return a && "object" == typeof a ? JSON.stringify(a) : a || ""
    		},
    		parseParam: function(str) {
    			if (str && "string" == typeof str) try {
    				obj = JSON.parse(str)
    			} catch(e) {
    				obj = eval("(" + str + ")")
    			} else obj = str || {};
    			return obj
    		},
    		getSid: function() {
    			return Math.floor(Math.random() * (1 << 50)) + "" + inc++
    		},
    		registerCall: function(a, b, c) {
    			b && (callbackMap[SUCCESS_PREFIX + a] = b),
    			c && (callbackMap[FAILURE_PREFIX + a] = c)
    		},
    		unregisterCall: function(a) {
    			var b = SUCCESS_PREFIX + a,
    			c = FAILURE_PREFIX + a,
    			d = {
    				success: callbackMap[b],
    				failure: callbackMap[c]
    			};
    			return delete callbackMap[b],
    			delete callbackMap[c],
    			d
    		},
    		useIframe: function(a, b) {
    			var c = IFRAME_PREFIX + a,
    			d = iframePool.pop();
    			d || (d = doc.createElement("iframe"), d.setAttribute("frameborder", "0"), d.style.cssText = "width:0;height:0;border:0;display:none;"),
    			d.setAttribute("id", c),
    			d.setAttribute("src", b),
    			d.parentNode || setTimeout(function() {
    				doc.body.appendChild(d)
    			},
    			5)
    		},
    		retrieveIframe: function(a) {
    			var b = IFRAME_PREFIX + a,
    			c = doc.querySelector("#" + b);
    			iframePool.length >= iframeLimit ? doc.body.removeChild(c) : iframePool.push(c)
    		},
    		callMethodByIframe: function(a, b, c, d) {
    			var e = LOCAL_PROTOCOL + "://" + a + ":" + d + "/" + b + "?" + c;
    			this.params[PARAM_PREFIX + d] = c,
    			this.useIframe(d, e)
    		},
    		callMethodByPrompt: function(a, b, c, d) {
    			var e = LOCAL_PROTOCOL + "://" + a + ":" + d + "/" + b + "?" + c,
    			f = WV_PROTOCOL + ":";
    			this.params[PARAM_PREFIX + d] = c,
    			window.prompt(e, f)
    		},
    		onComplete: function(a) {
    			isIOS && this.retrieveIframe(a),
    			delete this.params[PARAM_PREFIX + a]
    		}
    	};
    	for (var key in WV_Core) hasOwnProperty.call(WindVane, key) || (WindVane[key] = WV_Core[key])
    } (window),
    function(a, b) {
    	function c(a) {
    		Object.defineProperty(this, "val", {
    			value: a.toString(),
    			enumerable: !0
    		}),
    		this.gt = function(a) {
    			return c.compare(this, a) > 0
    		},
    		this.gte = function(a) {
    			return c.compare(this, a) >= 0
    		},
    		this.lt = function(a) {
    			return c.compare(this, a) < 0
    		},
    		this.lte = function(a) {
    			return c.compare(this, a) <= 0
    		},
    		this.eq = function(a) {
    			return 0 === c.compare(this, a)
    		}
    	}
    	b.env = b.env || {},
    	c.prototype.toString = function() {
    		return this.val
    	},
    	c.prototype.valueOf = function() {
    		for (var a = this.val.split("."), b = [], c = 0; c < a.length; c++) {
    			var d = parseInt(a[c], 10);
    			isNaN(d) && (d = 0);
    			var e = d.toString();
    			e.length < 5 && (e = Array(6 - e.length).join("0") + e),
    			b.push(e),
    			1 === b.length && b.push(".")
    		}
    		return parseFloat(b.join(""))
    	},
    	c.compare = function(a, b) {
    		a = a.toString().split("."),
    		b = b.toString().split(".");
    		for (var c = 0; c < a.length || c < b.length; c++) {
    			var d = parseInt(a[c], 10),
    			e = parseInt(b[c], 10);
    			if (window.isNaN(d) && (d = 0), window.isNaN(e) && (e = 0), e > d) return - 1;
    			if (d > e) return 1
    		}
    		return 0
    	},
    	b.version = function(a) {
    		return new c(a)
    	}
    } (window, window.lib || (window.lib = {})),
    function(a, b) {
    	b.env = b.env || {};
    	var c = a.location.search.replace(/^\?/, "");
    	if (b.env.params = {},
    	c) for (var d = c.split("&"), e = 0; e < d.length; e++) {
    		d[e] = d[e].split("=");
    		try {
    			b.env.params[d[e][0]] = decodeURIComponent(d[e][1])
    		} catch(f) {
    			b.env.params[d[e][0]] = d[e][1]
    		}
    	}
    } (window, window.lib || (window.lib = {})),
    function(a, b) {
    	b.env = b.env || {};
    	var c, d = a.navigator.userAgent;
    	if (c = d.match(/Windows\sPhone\s(?:OS\s)?([\d\.]+)/)) b.env.os = {
    		name: "Windows Phone",
    		isWindowsPhone: !0,
    		version: c[1]
    	};
    	else if (d.match(/Safari/) && (c = d.match(/Android[\s\/]([\d\.]+)/))) b.env.os = {
    		version: c[1]
    	},
    	d.match(/Mobile\s+Safari/) ? (b.env.os.name = "Android", b.env.os.isAndroid = !0) : (b.env.os.name = "AndroidPad", b.env.os.isAndroidPad = !0);
    	else if (c = d.match(/(iPhone|iPad|iPod)/)) {
    		var e = c[1];
    		c = d.match(/OS ([\d_\.]+) like Mac OS X/),
    		b.env.os = {
    			name: e,
    			isIPhone: "iPhone" === e || "iPod" === e,
    			isIPad: "iPad" === e,
    			isIOS: !0,
    			version: c[1].split("_").join(".")
    		}
    	} else b.env.os = {
    		name: "unknown",
    		version: "0.0.0"
    	};
    	b.version && (b.env.os.version = b.version(b.env.os.version))
    } (window, window.lib || (window.lib = {})),
    function(a, b) {
    	b.env = b.env || {};
    	var c, d = a.navigator.userAgent; (c = d.match(/(?:UCWEB|UCBrowser\/)([\d\.]+)/)) ? b.env.browser = {
    		name: "UC",
    		isUC: !0,
    		version: c[1]
    	}: (c = d.match(/MQQBrowser\/([\d\.]+)/)) ? b.env.browser = {
    		name: "QQ",
    		isQQ: !0,
    		version: c[1]
    	}: (c = d.match(/Firefox\/([\d\.]+)/)) ? b.env.browser = {
    		name: "Firefox",
    		isFirefox: !0,
    		version: c[1]
    	}: (c = d.match(/MSIE\s([\d\.]+)/)) || (c = d.match(/IEMobile\/([\d\.]+)/)) ? (b.env.browser = {
    		version: c[1]
    	},
    	d.match(/IEMobile/) ? (b.env.browser.name = "IEMobile", b.env.browser.isIEMobile = !0) : (b.env.browser.name = "IE", b.env.browser.isIE = !0), d.match(/Android|iPhone/) && (b.env.browser.isIELikeWebkit = !0)) : (c = d.match(/(?:Chrome|CriOS)\/([\d\.]+)/)) ? (b.env.browser = {
    		name: "Chrome",
    		isChrome: !0,
    		version: c[1]
    	},
    	d.match(/Version\/[\d+\.]+\s*Chrome/) && (b.env.browser.name = "Chrome Webview", b.env.browser.isWebview = !0)) : d.match(/Safari/) && (c = d.match(/Android[\s\/]([\d\.]+)/)) ? b.env.browser = {
    		name: "Android",
    		isAndroid: !0,
    		version: c[1]
    	}: d.match(/iPhone|iPad|iPod/) ? d.match(/Safari/) ? (c = d.match(/Version\/([\d\.]+)/), b.env.browser = {
    		name: "Safari",
    		isSafari: !0,
    		version: c[1]
    	}) : (c = d.match(/OS ([\d_\.]+) like Mac OS X/), b.env.browser = {
    		name: "iOS Webview",
    		isWebview: !0,
    		version: c[1].replace(/\_/, ".")
    	}) : b.env.browser = {
    		name: "unknown",
    		version: "0.0.0"
    	},
    	b.version && (b.env.browser.version = b.version(b.env.browser.version))
    } (window, window.lib || (window.lib = {})),
    function(a, b) {
    	b.env = b.env || {};
    	var c = a.navigator.userAgent;
    	b.env.thirdapp = c.match(/Weibo/i) ? {
    		appname: "Weibo",
    		isWeibo: !0
    	}: c.match(/MicroMessenger/i) ? {
    		appname: "Weixin",
    		isWeixin: !0
    	}: !1
    } (window, window.lib || (window.lib = {})),
    function(a, b) {
    	b.env = b.env || {};
    	var c, d, e = a.navigator.userAgent; (d = e.match(/WindVane[\/\s]([\d\.\_]+)/)) && (c = d[1]);
    	var f = !1,
    	g = "",
    	h = "",
    	i = ""; (d = e.match(/AliApp\(([A-Z\-]+)\/([\d\.]+)\)/)) && (f = !0, g = d[1], i = d[2], h = g.indexOf("-PD") > 0 ? b.env.os.isIOS ? "iPad": b.env.os.isAndroid ? "AndroidPad": b.env.os.name: b.env.os.name),
    	!g && e.indexOf("TBIOS") > 0 && (g = "TB"),
    	b.env.aliapp = f ? {
    		windvane: b.version(c || "0.0.0"),
    		appname: g || "unkown",
    		version: b.version(i || "0.0.0"),
    		platform: h || b.env.os.name
    	}: !1,
    	b.env.taobaoApp = b.env.aliapp
    } (window, window.lib || (window.lib = {})),
    function(a, b) {
    	function c(a) {
    		var b = {};
    		Object.defineProperty(this, "params", {
    			set: function(a) {
    				if ("object" == typeof a) {
    					for (var c in b) delete b[c];
    					for (var c in a) b[c] = a[c]
    				}
    			},
    			get: function() {
    				return b
    			},
    			enumerable: !0
    		}),
    		Object.defineProperty(this, "search", {
    			set: function(a) {
    				if ("string" == typeof a) {
    					0 === a.indexOf("?") && (a = a.substr(1));
    					var c = a.split("&");
    					for (var d in b) delete b[d];
    					for (var e = 0; e < c.length; e++) {
    						var f = c[e].split("=");
    						if (f[0]) try {
    							b[decodeURIComponent(f[0])] = decodeURIComponent(f[1] || "")
    						} catch(g) {
    							b[f[0]] = f[1] || ""
    						}
    					}
    				}
    			},
    			get: function() {
    				var a = [];
    				for (var c in b) if (b[c]) try {
    					a.push(encodeURIComponent(c) + "=" + encodeURIComponent(b[c]))
    				} catch(d) {
    					a.push(c + "=" + b[c])
    				} else try {
    					a.push(encodeURIComponent(c))
    				} catch(d) {
    					a.push(c)
    				}
    				return a.length ? "?" + a.join("&") : ""
    			},
    			enumerable: !0
    		});
    		var c;
    		Object.defineProperty(this, "hash", {
    			set: function(a) {
    				a && a.indexOf("#") < 0 && (a = "#" + a),
    				c = a || ""
    			},
    			get: function() {
    				return c
    			},
    			enumerable: !0
    		}),
    		this.set = function(a) {
    			a = a || "";
    			var b;
    			if (! (b = a.match(new RegExp("^([a-z0-9-]+:)?[/]{2}(?:([^@/:?]+)(?::([^@/:]+))?@)?([^:/?#]+)(?:[:]([0-9]+))?([/][^?#;]*)?(?:[?]([^?#]*))?(#[^#]*)?$", "i")))) throw new Error("Wrong uri scheme.");
    			this.protocol = b[1] || location.protocol,
    			this.username = b[2] || "",
    			this.password = b[3] || "",
    			this.hostname = this.host = b[4],
    			this.port = b[5] || "",
    			this.pathname = b[6] || "/",
    			this.search = b[7] || "",
    			this.hash = b[8] || "",
    			this.origin = this.protocol + "//" + this.hostname
    		},
    		this.toString = function() {
    			var a = this.protocol + "//";
    			return this.username && (a += this.username, this.password && (a += ":" + this.password), a += "@"),
    			a += this.host,
    			this.port && "80" !== this.port && (a += ":" + this.port),
    			this.pathname && (a += this.pathname),
    			this.search && (a += this.search),
    			this.hash && (a += this.hash),
    			a
    		},
    		a && this.set(a.toString())
    	}
    	b.httpurl = function(a) {
    		return new c(a)
    	}
    } (window, window.lib || (window.lib = {})),
    function(a, b) {
    	function c(a, b) {
    		var c = new i(location.href),
    		d = g.getElementById("buried"),
    		e = c.params.ttid,
    		f = c.params.ad_id,
    		h = c.params.source_type,
    		j = c.params.refpid,
    		k = c.params.actparam,
    		l = c.params.actname,
    		m = c.params.ali_trackid,
    		n = c.params.pid,
    		o = g.cookie.match(/(?:^|\s)cna=([^;]+)(?:;|$)/);
    		c.search = "",
    		c.hash = "";
    		var p = {};
    		if (d && (e = d.value), p.from = "h5", e && (p.ttid = e), j && (p.refpid = j), k && (p.actparam = k), l && (p.actname = l), p.url = c.toString(), n && (p.pid = n), f && (p.ad_id = f), h && (p.source_type = h), m && (p.ali_trackid = m), o && (p.h5_uid = o[1]), "object" == typeof b) for (var q in b) p[q] = b[q];
    		return a.params.point = JSON.stringify(p),
    		a
    	}
    	function d(a, b) {
    		var c = new i(location.href),
    		d = g.getElementById("buried");
    		for (var e in c.params) a.params.hasOwnProperty(e) || (a.params[e] = c.params[e]);
    		if (d && (a.params.ttid = d.value), "object" == typeof b) for (var e in b) a.params[e] = b[e];
    		return a
    	}
    	function e(a) {
    		n || (n = g.createElement("iframe"), n.id = "callapp_iframe_" + Date.now(), n.frameborder = "0", n.style.cssText = "display:none;border:0;width:0;height:0;", g.body.appendChild(n)),
    		n.src = a
    	}
    	function f(a, b) {
    		b.replace === !1 || !k && b.replace !== !0 ? location.href = a: location.replace(a)
    	}
    	var g = a.document,
    	h = a.navigator.userAgent,
    	i = b.httpurl,
    	j = b.env.os,
    	k = (b.env.params, b.env.aliapp),
    	l = b.env.browser,
    	m = {
    		"taobao:": "com.taobao.taobao",
    		"taobaowebview:": "com.taobao.taobao",
    		"tmall:": "com.tmall.wireless"
    	};
    	b.callapp = b.callapp || {};
    	var n;
    	b.callapp.gotoPage = function(a, b) {
    		b = b || {},
    		"undefined" == typeof b.point && (b.point = !0),
    		"undefined" == typeof b.params && (b.params = !0);
    		var g = new i(a || location.href);
    		if (a = new i(a), ("http:" === a.protocol || "https:" === a.protocol) && (j.isAndroid && k && "TB" === k.appname ? (a = new i("taobaowebview://m.taobao.com/"), a.params.weburl = g.toString()) : a.protocol = "taobao:"), "taobao:" === a.protocol) b.point && c(a, b.point),
    		b.params && d(a, b.params);
    		else if ("taobaowebview:" === a.protocol) {
    			b.point && c(a, b.point);
    			var n = new i(a.params.weburl);
    			b.params && d(n, b.params),
    			b.point && c(n, b.point),
    			a.params.weburl = n.toString()
    		} else "tmall:" !== a.protocol.toLowerCase() && "kddcpublic:" !== a.protocol.toLowerCase() && "mdatadwphone:" !== a.protocol.toLowerCase() && b.params && d(a, b.params);
    		var o = j.isAndroid && j.version.lt("5.0") && l.isChrome && !l.isWebview,
    		p = j.isAndroid && !!h.match(/samsung/i) && j.version.gte("4.3") && j.version.lt("4.5"); (o || p || b.forceIntent) && (a.hash = "Intent;scheme=" + a.protocol.replace(":", "") + ";package=" + (b["package"] || m[a.protocol]) + ";end", a.protocol = "intent:"),
    		k || "intent:" === a.protocol ? setTimeout(function() {
    			f(a.toString(), b)
    		},
    		100) : e(a.toString())
    	},
    	b.callapp.download = function(a, b) {
    		b = b || {},
    		a || (a = j.isIPhone ? "http://itunes.apple.com/cn/app/id387682726?mt=8": j.isIPad ? "https://itunes.apple.com/app/id438865278": j.isAndroid ? "//download.alicdn.com/wireless/taobao4android/latest/taobao4android_703248.apk": ""),
    		a = new i(a),
    		j.isAndroid && a.pathname.match(/\.apk$/) ? (a.search = "", a.hash = "") : b.params && d(a, b.params),
    		a = a.toString(),
    		f(a, b)
    	}
    } (window, window.lib || (window.lib = {}));
    var Hogan = {}; !
    function(a, b) {
    	function c(a) {
    		return String(null === a || void 0 === a ? "": a)
    	}
    	function d(a) {
    		return a = c(a),
    		j.test(a) ? a.replace(e, "&").replace(f, "<").replace(g, ">").replace(h, "'").replace(i, """) : a
    	}
    	a.Template = function(a, c, d, e) {
    		this.r = a || this.r,
    		this.c = d,
    		this.options = e,
    		this.text = c || "",
    		this.buf = b ? [] : ""
    	},
    	a.Template.prototype = {
    		r: function() {
    			return ""
    		},
    		v: d,
    		t: c,
    		render: function(a, b, c) {
    			return this.ri([a], b || {},
    			c)
    		},
    		ri: function(a, b, c) {
    			return this.r(a, b, c)
    		},
    		rp: function(a, b, c, d) {
    			var e = c[a];
    			return e ? (this.c && "string" == typeof e && (e = this.c.compile(e, this.options)), e.ri(b, c, d)) : ""
    		},
    		rs: function(a, b, c) {
    			var d = a[a.length - 1];
    			if (!k(d)) return void c(a, b, this);
    			for (var e = 0; e < d.length; e++) a.push(d[e]),
    			c(a, b, this),
    			a.pop()
    		},
    		s: function(a, b, c, d, e, f, g) {
    			var h;
    			return k(a) && 0 === a.length ? !1 : ("function" == typeof a && (a = this.ls(a, b, c, d, e, f, g)), h = "" === a || !!a, !d && h && b && b.push("object" == typeof a ? a: b[b.length - 1]), h)
    		},
    		d: function(a, b, c, d) {
    			var e = a.split("."),
    			f = this.f(e[0], b, c, d),
    			g = null;
    			if ("." === a && k(b[b.length - 2])) return b[b.length - 1];
    			for (var h = 1; h < e.length; h++) f && "object" == typeof f && e[h] in f ? (g = f, f = f[e[h]]) : f = "";
    			return d && !f ? !1 : (d || "function" != typeof f || (b.push(g), f = this.lv(f, b, c), b.pop()), f)
    		},
    		f: function(a, b, c, d) {
    			for (var e = !1,
    			f = null,
    			g = !1,
    			h = b.length - 1; h >= 0; h--) if (f = b[h], f && "object" == typeof f && a in f) {
    				e = f[a],
    				g = !0;
    				break
    			}
    			return g ? (d || "function" != typeof e || (e = this.lv(e, b, c)), e) : d ? !1 : ""
    		},
    		ho: function(a, b, c, d, e) {
    			var f = this.c,
    			g = this.options;
    			g.delimiters = e;
    			var d = a.call(b, d);
    			return d = null == d ? String(d) : d.toString(),
    			this.b(f.compile(d, g).render(b, c)),
    			!1
    		},
    		b: b ?
    		function(a) {
    			this.buf.push(a)
    		}: function(a) {
    			this.buf += a
    		},
    		fl: b ?
    		function() {
    			var a = this.buf.join("");
    			return this.buf = [],
    			a
    		}: function() {
    			var a = this.buf;
    			return this.buf = "",
    			a
    		},
    		ls: function(a, b, c, d, e, f, g) {
    			var h = b[b.length - 1],
    			i = null;
    			if (!d && this.c && a.length > 0) return this.ho(a, h, c, this.text.substring(e, f), g);
    			if (i = a.call(h), "function" == typeof i) {
    				if (d) return ! 0;
    				if (this.c) return this.ho(i, h, c, this.text.substring(e, f), g)
    			}
    			return i
    		},
    		lv: function(a, b, d) {
    			var e = b[b.length - 1],
    			f = a.call(e);
    			return "function" == typeof f && (f = c(f.call(e)), this.c && ~f.indexOf("{{")) ? this.c.compile(f, this.options).render(e, d) : c(f)
    		}
    	};
    	var e = /&/g,
    	f = /</g,
    	g = />/g,
    	h = /\'/g,
    	i = /\"/g,
    	j = /[&<>\"\']/,
    	k = Array.isArray ||
    	function(a) {
    		return "[object Array]" === Object.prototype.toString.call(a)
    	}
    } ("undefined" != typeof exports ? exports: Hogan),
    function(a, b) {
    	function c() {
    		var a = {},
    		b = location.search;
    		if (b) {
    			var c = b.slice(1).split("&");
    			if (c.length) for (var d = 0; d < c.length; d++) if (c[d] && -1 != c[d].indexOf("=")) {
    				var e = c[d].split("=");
    				a[e[0]] = e[1]
    			}
    		}
    		return a
    	}
    	function d(a) {
    		var b = i.createElement("img");
    		b.style.cssText = "display:none",
    		b.src = a,
    		i.body.appendChild(b)
    	}
    	function e(b) {
    		b = b || {};
    		var c = b.apuri || b.ap_uri,
    		e = {},
    		f = b.sceneType && "fresh" == b.sceneType,
    		g = b.pageType;
    		if (c) {
    			e.apuri = c,
    			f && (e.fresh = 1),
    			g && (e.page = g),
    			e.logtype = 2,
    			e.cache = parseInt((Math.random() + 1) * Date.now());
    			var h = [];
    			for (var i in e) h.push(i + "=" + encodeURIComponent(e[i]));
    			a.goldlog && goldlog.record ? goldlog.record("/sb.1.1", "", h.join("&"), "H1673809") : d("http://wgo.mmstat.com/sb.1.1?" + h.join("&"))
    		}
    	}
    	function f() {
    		var a = c(),
    		b = a.ttid,
    		d = /[^@]+\@taobao\_(iphone|android|apad|ipad)\_[\d.]+/i;
    		return b = b ? decodeURIComponent(b) : "",
    		d.test(b)
    	}
    	function g() {
    		return "TB" === b.env.aliapp.appname
    	}
    	function h() {
    		return "AP" === b.env.aliapp.appname
    	}
    	var i = a.document,
    	j = i.cookie.match(/(?:^|\s)cna=([^;]+)(?:;|$)/);
    	j && (j = j[1]);
    	var k = i.createElement("frame"),
    	l = function(a) {
    		var c = this,
    		d = (navigator.standalone, navigator.userAgent, b.env.os),
    		e = b.env.browser;
    		return this.platform = d.isAndroid && "android" || d.isISO && "ios" || null,
    		this.isIpad = d.isIpad,
    		this.isChrome = e.isChrome,
    		this.invaliable = e.isWebview,
    		this.invaliable ? null: (this.init(a) && (this.create(), window.onblur = function() {
    			clearTimeout(c.timeload),
    			c.timeload = null
    		}), this)
    	};
    	l.prototype = {
    		constructor: l,
    		init: function(a) {
    			var b = this.options = a,
    			d = b.isInstance ||
    			function() {
    				return g() || h()
    			};
    			if (d()) return this.invaliable = !0,
    			null;
    			a.version || (a.version = "v1"),
    			this.cover = b.cover || !1,
    			this.isDownload = b.download || !1,
    			this.timeout = b.timeout || 1e3;
    			var e = b.from || "h5",
    			f = b.crossplat || !1;
    			if ("ios" != this.platform || f) {
    				var k = "http://m.taobao.com/channel/act/sale/tbdl1.html",
    				l = b.url || k;
    				l += -1 == l.indexOf("?") ? "?": "&",
    				l += location.search.slice(1) + "&pageType=" + (b.pageType || "mainIndex") + "&sceneType=" + (b.sceneType || "default"),
    				this.bannerUrl = l
    			} else this.bannerUrl = b.appstoreUrl || (this.isIpad ? "https://itunes.apple.com/app/id438865278": "http://itunes.apple.com/cn/app/id387682726?mt=8");
    			if (b.href) {
    				var m = b.href,
    				n = c(),
    				o = i.getElementById("buried"),
    				p = n.ttid || o && o.value,
    				q = n.refid,
    				r = n.ali_trackid,
    				s = n.pid,
    				t = n.actparam,
    				u = n.actname,
    				v = n.ad_id,
    				w = n.source_type,
    				x = {
    					from: e
    				};
    				if (p && (x.ttid = p), q && (x.refid = q), r && (x.ali_trackid = r), s && (x.pid = s), t && (x.actparam = t), u && (x.actname = u), v && (x.ad_id = v), w && (x.source_type = w), x.url = encodeURIComponent(location.href.split(/[?#]/)[0]), j && (x.h5_uid = j), x.ap_uri = "", b.point) for (var y in b.point) x[y] = b.point[y];
    				x = encodeURIComponent(JSON.stringify(x)),
    				m = m.split("#"),
    				-1 == m[0].indexOf("?") ? m[0] += "?": m[0].indexOf("?") != m.length - 1 && (m[0] += "&"),
    				m[0] += "point=" + x,
    				m = m.join("#"),
    				m = -1 != m.indexOf("://") ? m: "taobao://" + m,
    				this.paramUrl = m
    			}
    			return ! 0
    		},
    		reset: function(a) {
    			this.iClose || (this.init(a), this.resetHtml && this.resetHtml(a))
    		},
    		create: function() {
    			this.iClose || (k.parentNode || (k.setAttribute("id", "J_smartFrame"), k.style.cssText = "display:none", i.body.appendChild(k)), this.frame = k)
    		},
    		download: function(b) {
    			var c = Date.now(); (!b || c - b < this.timeout + 200) && (this.cover ? a.location.replace(this.bannerUrl) : a.location.href = this.bannerUrl)
    		},
    		redirect: function(a) {
    			var c = this.options && this.options.version,
    			d = (this.frame, a ? "click_sb_" + c + "_manual": "click_sb_" + c + "_auto");
    			if (this.paramUrl) {
    				var f = this.options;
    				e({
    					ap_uri: d,
    					pageType: f.pageType
    				}),
    				this.paramUrl = this.paramUrl.replace("%22ap_uri%22%3A%22%22", encodeURIComponent('"ap_uri":"' + d + '"'));
    				var g = this;
    				b.callapp.gotoPage(g.paramUrl)
    			}
    		},
    		install: function(a) {
    			var b = this,
    			c = Date.now();
    			b.isDownload || (b.timeload = setTimeout(function() {
    				b.download(c)
    			},
    			b.timeout)),
    			b.redirect(a)
    		}
    	},
    	b.smartbanner = function(a) {
    		var c = a.type,
    		d = b.smartbanner.BannerUI,
    		e = b.smartbanner.PopUI;
    		if ("banner" !== c && c) {
    			if ("pop" === c) {
    				if (e) return new e(a)
    			} else if ("func" === c) return b.smartbanner.getInstance(a)
    		} else if (d) return new d(a)
    	},
    	b.smartbanner.getInstance = function(a, b) {
    		b || (b = Object.create({}));
    		for (var c in l.prototype) b[c] = l.prototype[c];
    		return l.call(b, a)
    	},
    	b.smartbanner.aplus = e,
    	b.smartbanner.getParam = c,
    	b.smartbanner.ttidInTaobaoApp = f,
    	b.smartbanner.uaInTaobaoApp = g
    } (window, window.lib || (window.lib = {})),
    function(a, b) {
    	function c(a) {
    		var b = document.cookie;
    		if (name = a + "=", start = b.indexOf(name), 0 > start) return null;
    		start += name.length;
    		var c = b.indexOf(";", start);
    		return c = -1 == c ? b.length: c,
    		b.substring(start, c)
    	}
    	function d() {
    		var a = decodeURIComponent(c("imewweoriw"));
    		return a && a.length > 32
    	}
    	function e(a) {
    		var b = window.localStorage;
    		if (b) {
    			var c = b[a],
    			d = !1;
    			if (c) {
    				var c = parseInt(c, 10),
    				e = new Date;
    				e.setHours(0),
    				e.setMinutes(0),
    				e.setSeconds(0),
    				e.setMilliseconds(0),
    				c > e && (d = !0)
    			}
    			return d
    		}
    	}
    	function f(a, e) {
    		a = a || 0;
    		var f = (navigator.userAgent, j.ali_trackid),
    		g = Boolean(f),
    		h = c("tkmb"),
    		i = h ? h.split("&") : null,
    		k = /400000_.*@\w+_(iphone|android)_.*/i,
    		l = /.+@taobao_(iphone|android|apad|ipad)_.+/i,
    		m = j.ttid,
    		n = m ? decodeURIComponent(m) : "",
    		o = "" != n ? !0 : !1,
    		p = j.ut_sk,
    		q = p ? decodeURIComponent(p) : "",
    		r = "" != q ? !0 : !1,
    		s = q.match(/.+_(\d+)_.+/),
    		t = j.iv,
    		u = k.test(n),
    		v = t && 1 == t || i && "iv=1" === i[1],
    		w = "undefined" != typeof t && 1 == t || i && "iv=0" === i[1],
    		x = g && null != f.match(/^1_.+/i) && ("undefined" == typeof e || 1 == e),
    		y = g && null != f.match(/^1_.+/i) && "undefined" != typeof e && 0 == e,
    		z = !0; (o && l.test(n) || "TB" === b.env.aliapp.appname) && (z = !1, !r || null == s || 12278902 != s[1] && 21380790 != s[1] || (z = !0)),
    		"AP" === b.env.aliapp.appname && (z = !1);
    		var A = "000";
    		if (z) {
    			var B = "1",
    			C = "2",
    			D = "1",
    			E = "1",
    			F = "2";
    			u || v || x ? B = "0": (w || y) && (B = "2");
    			var G = b.env.browser,
    			H = b.env.thirdapp;
    			G.isQQ ? C = "0": G.isUC ? C = "1": H.isWeibo && (C = "3"),
    			d() && (D = "0");
    			var I = c("_w_app_lg"),
    			J = 1,
    			K = 2;
    			I && (b.env.os.isIPhone && I & J ? E = "0": b.env.os.isAndroid && I & K && (E = "0"));
    			var L = document.referrer;
    			u || H.isWeixin || null != L.match(/(t\.sina)|(weibo\.com)|(weibo\.cn)|(sina\.com)|(t\.cn)|(sinaurl)|(3g\.sina)|(iask\.cn)/i) ? F = "1": (null != L.match(/(qq|baidu|hao123|google|soso)\.com/i) || null != L.match(/(m|wap)\.taobao\.com/i) || o && null != n.match(/^(12tx0065|b0tx02|eguc01|001001|51uc0003)$/i)) && (F = "0");
    			try {
    				A = window.strategy[a][B + C + D + E + F]
    			} catch(M) {
    				A = "000",
    				console.log(M)
    			}
    		}
    		var N = {};
    		return A && ("1" == A.charAt(0) && (N.isInvoke = !0), "1" == A.charAt(1) && (N.isShow = !0), "1" == A.charAt(2) && (N.isInvokeDay = !0)),
    		N
    	}
    	function g(a, b, c) {
    		if (a) {
    			var d, g = f(b, c);
    			if (g.isInvoke && (d = d || i(a), d && d.redirect()), g.isShow && (d = d || i(a)), g.isInvokeDay && (d = d || i(a), !e("cloudDate"))) {
    				d && d.redirect();
    				try {
    					localStorage.cloudDate = Date.now()
    				} catch(h) {
    					console.log(h)
    				}
    			}
    			return d
    		}
    	}
    	var h = document,
    	i = b.smartbanner,
    	j = (i.aplus, i.getParam()),
    	k = String.fromCharCode(97 + parseInt(24 * Math.random(), 10)),
    	l = k + parseInt(1e7 * Math.random(), 10).toString(16),
    	m = k + parseInt(100 * Math.random(), 10).toString(16),
    	n = m + "dsk",
    	o = function(a) {
    		a.version = "v1",
    		i.getInstance(a, this),
    		this.calClose() || this.invaliable || (this.setParam(a), this.createHtml())
    	};
    	o.prototype = {
    		constructor: o,
    		calClose: function() {
    			var a = window.localStorage;
    			if (a) {
    				var b = a.closeDate;
    				if (b) {
    					var b = parseInt(b, 10),
    					c = new Date;
    					c.setHours(0),
    					c.setMinutes(0),
    					c.setSeconds(0),
    					c.setMilliseconds(0),
    					b > c && (this.iClose = !0)
    				}
    				return this.iClose
    			}
    		},
    		setParam: function(a) {
    			var b = a.color ? "color:" + a.color + ";": "",
    			c = a.bgcolor ? "background-color:" + a.bgcolor + ";": "";
    			this.bodyOrigPT = parseInt(window.getComputedStyle(document.body).paddingTop, 10),
    			this.styles = b + c,
    			this.isHide = a.hide || !1,
    			this.text = a.text || "立即打开",
    			this.title = a.title || "上手机淘宝客户端,保障交易安全",
    			this.icon = a.icon || "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEYAAABGCAYAAABxLuKEAAAKHElEQVR42u2bC1MUVxbH+xvwAayKOAPGV0WlkuxurF2wNlqrYRGNiboa4tsoIqiASkBBEYEy+Fh1TTRqjLgmPmdEjUmpUTEJ6ytirMR3fKMozvRrprun++y5IztuM9O3u4eRUuFf9Ssu3HMf59/dZ26DMlblGeSMQ1KRSsSN1CMNCIfAcwbXvLf65r1WNu89jomVPIOdKYgLURB4wVGac0mJ3pB3HJ0QNwIvKW6Soz1TUh0pSCMCLzmNSIo1U/7uSENkBNoJMpJGNyXNkYLICLQzZCTFyJROSCMC7ZRGJLzmeNMdbgTaOW69KUMdyQh0ECTlqTHDHC4EOgjiemLKu444REGggyAKEsd4hjtSEehARyrjec9RgUBb4M3oQ76+CFQwnve7uBCIBu+4JBAWTwCxKhu4ecPBMyKBGq/euQbq3esg7d8MQtlE8I7uGep7znAxnhHOegTs4B3TK5gcBBT4f2kNN0AonxJxDDd3GLSUJvlBOXMUfBtLgZ38Fol7XqhnPCOdDQhYZlQCKOdqwVCaCkJVVtg46WA10MTlpVpa3zs+Cbjcd4AvGgH8ogzgF48noPHpwE5PAc8/Eklca2kgxnB2BokrZ4GZVM9D8Izu9jSZsb1BE1gwkvzjN2HrsFkpICzNBP+O1aCcPATq7SugiTyYSZP9oF79BS/EVmIY7uPVaIzhGM8oJ9hBrq0BK+IXjAyN8W1cSHFRBXbWQLwLBoPv8xKQ674FzdsEsZL6qAF8m5eAJ6OHrTwZz2gH2EE5fRisSKiY9GRMRlfQ7t8wvsI+HtSm+/Cspd6+DNy8NKt52jdG2v0vMJWm4fPeLxgvfloAMZEiQ+DyzyAd2ga+LUtA/OdM4MvG4uOSgY93Dvi3r4TAxTNAE3kU+eKRFo35wAF2YGf0wwU4oEk+tpvEYqHsCeqDW9Ff5esX8EKsweTHgGdcd0v74xeNoq6psU0kB9N5GG+GA+wiLPkANM4T+cKeOwbspF7BOGnnCvtmXDsP0tdVwOUNIHNEBTfzL2R/lGJfYzoH4/3QAdHATn8TpB3LQak/HrzF5R/2grgiEz+BnKQfE/srOafYf1zO14J/6xLgZvcn80SNv7qMXvCz/kAdz3jHOiDmTEjE5/2kaR0iRhhJrJrUmj1g4m8CTeKqGdTxjHe8A2wxsSvwJcOoMdL+9cZ+CCyeMTbh3TU1eOUiSak/RuZpNWpTAxhJ2rWcOpbxTnCAHaQdVZhQAPzbytEkZ1i/f4vxmUX9/QKwmX2CcYFfThgcDhuBzfkjiWk16s3fjOtM7S7KWJvGcAUDARTp6ZU9/V0oUQJfMtTwLtC8D7HuJAfjxDU5xhs+vhN8G+a1Cu+UbqbGBH6tMzFmogMsMckZsW6od66gYQNCcXxJOgQunQo7pvOlw4P9bFYfUB8/2wMdOyMJ16Ibo927Rs2X8U5ygBV8X8w3XoR7jGeN4U/jJztB/GwWqA/vBt/AhWXjQ33y8R3wrMVmJwXXUm9RjOE91HwZ75QuYIXAtZ8BRT3aC1VjdWPY6T3xThka+l5cPQ3aQuzMJLIe1Rgi79QEo3ytGoNkdgdp7yrqR6wm+YAvfz/ieK5wAGiCN8In0FE0Lz2IfOwroAn7SZwpmLAlY9BAijEfYcMGfPEgrCEnqXcOXzJYN4bN6gHqvavhBfBiHdaDXqE4qWYV0IT9NvZqbgxXkGw4lvFOxYZdpmHN2TIfNJE1eMepJzG6Mf5dS3Ux5NFks3vpYiwYY2Of5sbwCwcbjmW807ARJeycP+GjcCTyouXvhsX7NuaSYhw0jp3dN6xf2kc3Bvtt7U+9bWJMWbrhWIbN7AKtYnoCKGcPQkv5t5eFYvjit0E6spmAppzDl7jdpB0G6aMJ+0mcKVxOD1zX3BhhSbpBXrEwBuHmvKE7+BHJ+1aF+sXlGdCW4nKTYmDMdGzEgMDFn/S3/d7loT5xRRsbk5eE61owpnyIYT4Mm4WNGBC4VKdb1LcpN9QnrmxjY/KTcF1LxhjkEyNjuLze5NivL2ylg2zPI+2nF1/sNxxLkuRyX9P9zLT4LvobxZgZ8dBapEMbWrwiNAGb7XjSn5OINahvZHJ76uc5QDeG9Ifis534iI4G6fAmUB/dBiL/tvm6+UyNKe5vmBPDZmOjFQifDA97o5br9oT6pb1VYCT56Je6uSwYE4r1by2I8JeAX3XzmRnDFbxumBfD5mAjSriPXwe16R60lG/d1FCM/ON2yoFtmW4+6Ru6MdgfiuUX9o9cN6reC8Wod0yMye9pmBvDzsRGNOS+CoErJyO+ErB53UJxyvnDYCT/V0W6OS0Yo4tXH94Ivwt/2hnqpxqj+Kn5MdysLmCb2U5QTtdEXq9upy42QDNmW6EuVjq4GmjC/lCs+Ek6uVsjv8gW9CExVGPUx3dpOUZnjHz0CzCSuHSILlb5zx7Kb+uqbRsjlA3Ex/NrUteM43aWmhtz64KJMbOxYQPp2zVgpMDluvD4Ayspt7ME/up84PISMdbcGE3wgBVp9y7hfHRjAr/VUvNkuFxsWETeVwU0+dZPDhsjrh5jnojIgnr9LGgProEtaSqO9Rr8eWQU1Rjl5B5qrgyXhw0LyPvppqh3L2KVd4SPzU8AtfF3iLW0hsvB5KUj6yInfmoPaNwjSiFfQc2XsW4KXf6t+YbjfRs+iuE/67iJNaQYD4iJT+b+bLzeMD8Pcm01PqKz6Xf32g9NjMnHBgVyRcykNt0Bbm4ifZ5dxRgYgGik+ThQzh0A3+eTcZ0E/dwF3YO1Srt/FaTdC4Ev6hP8uXLGTa1V3Lyu1P0y3BxsGCCUp+BZ4SaYSXKVknhThGVpeIvvBs37wLhmsA/xxHohmJhUUwni2jGYRCJ1XnF5GhrmCH0vuRcDTXixTffKmCZU2AOk79eRq23oPl/Yy2A8fV6+OEkHNy+BOoYveg3UG+dAPoGPyr/zQKh8+2nfgr74Rj8V3/JPAE1oPIm1YMxcbFiAXBX11vlw979bRfrbBN/6cREOdGIQSwooIH46xtJaDF8QzyFgiUInyDVloY1osg+E0jdIX5sgH1kL0UrzseDfOMHqWhwxpsHuBsXKZDwgfQ/yD9WUuNijXj8FtoUlQDnrxnr5ZztrNTD8x/H1CETFgu7ka5vh35IJ8vENoF6twwJ+j1L3HmOtqcVTdyUa0i+ateoZvjDehcALSZEThIq3QFw2EA97Q0Bc2h+ERb1jMbeL4YviKxDoQEcFMSaV7zCiJakMPz8+DlEQ6CCIgsQxRPyCeBcCHQRxMUTNxiTzHYb8D/3/v+aLO7sRaOe4mZYSSjp3QhoRaKc0Eg+YSMKOZERuh6bISApDk7CocxoiI9BOkJE0xoowMBlpbAemNCIpjB0JpZ07IW4EXlLcJEcmWgmLX0lGXIiCwAuO0pxLMhMrCWWvxCGpSAXiQuqRBoRF4DmDbd5bffNeK5r3HsdY1H8BKsNfGepiaRAAAAAASUVORK5CYII=",
    			this.isIpad && (this.title = this.title.replace(/(手机)?淘宝/gi, "淘宝HD")),
    			this.isTop = "top" === a.position ? !0 : !1
    		},
    		template: function() {
    			var a = this.isHide,
    			b = ['<div id="' + l + '" class="' + n + '" ' + (a ? 'style="display:none"': "") + ">", '<a id="' + l + '-close" class="' + m + '-close" href="#"></a>', '<a id="' + l + '-open" class="' + m + '-point" href="#">', '<p class="' + m + '-font">', '<b class="' + m + '-taobao"><img src = "' + this.icon + '"></b>', "<span>" + this.title + "</span>", '<b class="' + m + '-dl" style="' + this.styles + '">' + this.text + "</b>", "</p>", "</a>", "</div>"];
    			return b.join("")
    		},
    		resetHtml: function(a) {
    			this.setParam(a);
    			var b = ['<b class="' + m + '-taobao"></b>', "<span>" + this.title + "</span>", '<b class="' + m + '-dl" style="' + this.styles + '">' + this.text + "</b>"].join("");
    			this.smartDom && (this.smartDom.querySelector("." + m + "-font").innerHTML = b)
    		},
    		createHtml: function() {
    			if (!this.iClose) {
    				var a = this.template(),
    				b = h.createElement("style"),
    				c = h.createElement("div"),
    				d = this.options.dpr || window.dpr || 1,
    				e = this.isTop;
    				c.innerHTML = a,
    				this.smartDom = c.querySelector("#" + l),
    				this.popDom = i({
    					type: "pop",
    					title: this.title,
    					dpr: d
    				}),
    				b.innerHTML = e ? "." + n + "{background-color:#5f646e;position:fixed;top:0;left:0;height:" + 48 * d + "px;width:100%;z-index:1000;;}." + m + "-point{color:#fff;display:block;text-decoration:none;height:100%;}." + m + "-close{position:absolute;left:0;top:0;height:" + 48 * d + "px;line-height:" + 48 * d + "px;width:" + 40 * d + "px;}." + m + '-close::before{content:"\\d7";color:#fff;text-decoration: none;display: inline-block;;width: " + 16 * d + "px;height: " + 16 * d + "px;line-height: " + 16 * d + "px;margin-left: " + 5 * d + "px;border: 1px solid #fff; border-radius: 50%;text-align: center;}." + m + "-font{margin:0 0 0 " + 40 * d + "px;display:-webkit-box;height:100%;overflow:hidden;-webkit-box-align:center;}." + m + "-taobao{margin:0 " + 8 * d + "px 0 0;width:" + 32 * d + "px;height:" + 32 * d + "px;display:inline-block;vertical-align:top;}." + m + "-taobao img{width:100%;height:100%;}." + m + "-font > span{-webkit-box-flex:1;display:block;line-height:120%;}." + m + "-dl{display:-webkit-box;-webkit-box-align: center;color:#fff;background-color:#FF5000;height:100%;;text-align:center;font-weight:normal;;padding:0 " + 8 * d + "px;}": "." + n + "{background-color:rgba(66,66,74,0.96);position:fixed;bottom:0;left:0;height:" + 68 * d + "px;width:100%;}." + m + "-point{color:#fff;display:block;text-decoration:none;height:100%;}." + m + "-close{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA61pVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wUmlnaHRzPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvcmlnaHRzLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcFJpZ2h0czpNYXJrZWQ9IkZhbHNlIiB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6NUY0MDYzNjgzODIwNjgxMUIzQzJGMTE5OTQ3OTlEMzUiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MEVFNkRGMzUxNDdGMTFFMzk0QzNCQ0VGODJBOTdBMTUiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MEVFNkRGMzQxNDdGMTFFMzk0QzNCQ0VGODJBOTdBMTUiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTMyBXaW5kb3dzIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InV1aWQ6QzBFQ0RDNjM1RjEwRTMxMUJBQzZBQjEyRDc5RTUwOEIiIHN0UmVmOmRvY3VtZW50SUQ9InV1aWQ6RDE1N0E1MDlBQTBGRTMxMThCRTc4OEMyQUI0QTU3NzAiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4dUF9zAAADBklEQVR42syYy28ScRDHeQnySgmRaBoCSA+tGqHh0ISoCWcCiQe5efUARzlgCokV/wQInPkjPBgPNjRgND7qK7xiChYwiKTaUoq2iDPJbrL+sssuj9KdZLLZV/LZmfl9Z34rlUgkfomITA6+LCKeE7EBHYsNqCc2oD2xAbXEBrQ7EshqteojkUjY5XKZ8/n8J67nvF7vSjAYfKBWq5vFYvH7FEAVTqDFxUVNOBx+vLCw4DQajdcdDodqa2trm3zO7/df9fl8j1Qq1cWlpaVbcCwWCoXWJCsM/DMnUCwWi+r1+mv0ucFguOJ0OtUA9Y4JA9HZkMlk5/FcKpXK7Xb7zXq9/rzVavXGBPoB3pBx3e10OmXymsViuQ2g9+g0MWFo6/f738AOJohQe6RS53K5jxgRSNkK8zqcL7vdbvPq6updEubo6Gg3mUxGIUKHY8IMwT/wKjWmhw1Ko9FYIT0KEiadTscqlcrPCaKD6aoK6mUIhQWNNcT1DKSpATDRUqm0N+HqwvLYF9xccXWtra1d0ul0l8l7g8HgANIUngLmN5UuTJtEJuQNLGCTyeRmHRfkcn0gELgzhfZ8we8SPH7QOkMWMFnoUOS6bDb7dgLtQRn5KwiI1BlGmnpw7dwMoMpUQfMPaJgmtshgAUPN3DebzQqEIKFI8RxhWMTbgifGUCj0UKlUXiBhUqnUOhYwRgIjwgK10u1289Vq9RcP0GtUC8FAWq22gW0A2wFDZ/5b2mxQzWbzaSaTecYDswNeG2umxgYJAli22Ww3IDLNRCKxziZ6TChQ6CfxeDwtIFVv6GVOmpRv1wE1YWq324fw5SObpcfjsW5ubtYErKosjqpcD/ACzdBwab8kV9VZbYOGlN7wzknzAKI7eV0MG0VMEwplQww71xPwV+BjzdinBYSi+II6nvnefofSmT9n/bNhn2oHNS7RmxcQil0R/D1bbxrXFFO8iympgH+lCngmNglQB7e82EeZk948gY4piA4F0T9NFVUQRTmk6gCbXxd/j9C7gXnZPwEGAGrNPc1RZ9hjAAAAAElFTkSuQmCC) no-repeat;background-size:" + 18 * d + "px;width:" + 20 * d + "px;height:" + 20 * d + "px;position:absolute;left:0;top:0;z-index:10;}." + m + "-font{margin:0;padding:" + 20 * d + "px " + 8 * d + "px 0 " + 8 * d + "px;display:-webkit-box;height:" + 32 * d + "px;overflow:hidden;-webkit-box-align:center;}." + m + "-font > span{-webkit-box-flex:1;display:block;margin:0 " + 12 * d + "px;line-height:120%;}." + m + "-taobao{width:" + 30 * d + "px;height:" + 30 * d + "px;display:inline-block;vertical-align:top;}." + m + "-taobao img{width:100%;height:100%;}." + m + "-dl{display:block;color:#3d4245;background-color:#e5e5e5;border-radius:" + 5 * d + "px;height:" + 30 * d + "px;line-height:" + 30 * d + "px;text-align:center;padding:0 " + 12 * d + "px;font-weight:normal;}",
    				h.body.appendChild(b),
    				h.body.appendChild(this.smartDom),
    				e && (document.body.style.paddingTop = this.bodyOrigPT + this.smartDom.getBoundingClientRect().height + "px"),
    				this.listen()
    			}
    		},
    		show: function() {
    			this.iClose || this.smartDom && (this.smartDom.style.display = "block")
    		},
    		hide: function() {
    			this.iClose || (this.smartDom && (this.smartDom.style.display = "none"), this.isTop && (document.body.style.paddingTop = this.bodyOrigPT + "px"))
    		},
    		pop: function() {
    			this.iClose || this.popDom && this.popDom.open()
    		},
    		listen: function() {
    			if (!this.iClose) {
    				var a = this,
    				b = a.smartDom;
    				b.querySelector("#" + l + "-close").addEventListener("click",
    				function(b) {
    					b.preventDefault(),
    					a.hide();
    					try {
    						localStorage.closeDate = Date.now(),
    						a.calClose()
    					} catch(b) {}
    				},
    				!1),
    				b.querySelector("#" + l + "-open").addEventListener("click",
    				function(b) {
    					b.preventDefault(),
    					a.install(!0)
    				})
    			}
    		}
    	},
    	b.smartbanner.expiresInDay = e,
    	b.smartbanner.smtStatus = f,
    	b.smartbanner.sbLogic = g,
    	b.smartbanner.BannerUI = o
    } (window, window.lib || (window.lib = {})),
    function(a, b) {
    	function c(a) {
    		return a.preventDefault(),
    		!1
    	}
    	var d, e, f, g, h, i = a.document,
    	j = a.localStorage,
    	k = b.smartbanner,
    	l = (k.aplus, !1),
    	m = ['<div class="c-smartpop">', '<section class="header">', '<a href="javascript:void(0)"></a>', "</section>", '<section class="title">', "<span>淘宝客户端不仅可以更流畅地收藏宝贝,还能分享,立刻下载体验!</span>", "</section>", '<section class="banner">', '<img border="0"></img>', "</section>", '<section class="action">', '<a href="javascript:void(0)">立即打开</a>', "</section>", "</div>"].join(""),
    	n = document.createElement("div"),
    	o = document.createElement("style");
    	try {
    		j.setItem("testPrivateModel", "false")
    	} catch(p) {
    		j = null
    	}
    	var q = function(a) {
    		a.version = "v2",
    		k.getInstance(a, this),
    		this.title = a.title,
    		this.isIpad && this.title && (this.title = this.title.replace(/(手机)?淘宝/gi, "淘宝HD")),
    		this.banner = a.banner
    	};
    	q.prototype = {
    		constructor: q,
    		_render: function() {
    			var a = this,
    			b = a.options.dpr || 1,
    			c = [".c-smartpop-wrap {", "width: 100%;height: 100%;top: 0;left: 0;position: absolute;z-index: 999;background: rgba(0,0,0,0);display: -webkit-box;-webkit-box-pack: center;-webkit-box-align: center;", "}", ".c-smartpop {", "width: 252px * @dpr;background-color: rgba(255,255,255,0.9);border: 1px solid rgba(51,51,51,0.18);-webkit-box-shadow: 0px 1px 8px 0px rgba(0,0,0,0.27);box-shadow: 0px 1px 8px 0px rgba(0,0,0,0.27);border-radius: 4px * @dpr;", "}", ".c-smartpop .header {", "width: 100%;height: 34px * @dpr;position: relative;", "}", ".c-smartpop .header a {", "display: inline-block;width: 14px * @dpr;height: 14px * @dpr;position: absolute;", "background: url(data:image/gif;base64,R0lGODlhHAAcAJEAAP///8zMzJmZmWZmZiH5BAAHAP8ALAAAAAAcABwAAAJWjICpyyk2TptMRGAlpdnd3XSKCHra+JVklXJt+C6re6L1NmMxuOalLvH9gMKhbmdEWJDGTFH1edJsSSDrNoVhrzim0vvdWn8+qexl5oarpjE7bHjLAgUAOw==) no-repeat 0 0;", "background-size: contain;top: 8px * @dpr;right: 8px * @dpr;opacity: 0.9;-webkit-tap-highlight-color:rgba(0,0,0,0);", "}", ".c-smartpop .title {", "height: 32px * @dpr;line-height: 16px * @dpr; * @dpr;margin: 0 12px * @dpr 8px * @dpr;padding-left: 36px * @dpr;", "background: url(data:image/gif;base64,R0lGODlhOAA4ALMAAP//zP/MzP/Mmf/MZv+Zmf+ZZv+ZM/+ZAP9mM/9mAP8zAMxmM8xmAAAAAAAAACH5BAAHAP8ALAAAAAA4ADgAAAT/EEgwjGoqY51v3x4nhuRmDFOakF3rvnAsN0kKsHKu79/E8MBgrjYQGo+dwQHJDC6b0Kh0Sq1ar9isdstFGgoGS6cmMKy6L0GqmDGkBBXXIpM4Uws2gDhPKQ8EAXxldkxqNkVuNoZ8fAVQKDaOgYxvAgQFA5MTAk0HeQqQjJZPLombTScSSgqUAI45phKkUYuMhDCRXpxJbwa1YjmHRzUAASuxAAfIJ1/MYBWOtbtCmnoKB4YrrYwKtQFGyNYKBgjd23zmKUfYuRmh36w2MbU3XjZPkJza8jD0nYtFErAzc4CYioIIV/iDcsrTOXQLUUng5PChvIhMIAW8xKxCHmiXpwYUwThsgoVmFc58GqeGDUkjizLck8lPRboJTRbtmhlPHSiTNyVkTLHHZk+ceNR5QxKqWAcbxo5S8vXmSFNxPy0qqjYNyNV6bSwOSBCKHgEhX4GFpQSng4EA0Wzc0hEORoKOzEgVKEiHXlcgZCe8EmKQ0lwgBwLZYytllhNAUAU4RkO5suXLmDNr3mx5MucOB9h8foHiMGeDo1skqGb68uqPnimHThEBADs=) no-repeat 0 center;", "background-size: 28px * @dpr 28px * @dpr;color: #666;", "}", ".c-smartpop .banner {", "height: 88px * @dpr;margin: 0 12px * @dpr 10px * @dpr;overflow: hidden;", "}", ".c-smartpop .banner img {", "border: 0px;width: 100%;height: 100%;", "}", ".c-smartpop .action {", "height: 28px * @dpr;text-align: center;margin: 0 auto 12px * @dpr;", "}", ".c-smartpop .action a {", "display: inline-block;height: 28px * @dpr;line-height: 28px * @dpr;background-color: rgb(255,102,0);", "border-radius: 3px * @dpr;text-align: center;-webkit-box-shadow: 0px 1px 1px 0px rgba(0,0,0,0.05), inset 0px 1px 3px 0px rgba(169,172,175,0.31);", "box-shadow: 0px 1px 1px 0px rgba(0,0,0,0.05), inset 0px 1px 3px 0px rgba(169,172,175,0.31); * @dpr;", "color: #FFF;text-decoration: none;-webkit-tap-highlight-color:rgba(0,0,0,0);margin: 0 10px * @dpr;padding: 0 8px * @dpr;", "}", ".c-smartpop .action a:hover, .c-smartpop .action a.hover {", "background-color: #EF5F00;", "}"].join("").replace(/(\d+)px\s+\*\s+\@dpr/gi,
    			function(a, c) {
    				return parseFloat(c) * b + "px"
    			});
    			n.className = "c-smartpop-wrap",
    			n.innerHTML = m,
    			n.style.cssText = "display:none",
    			d = n.querySelector(".c-smartpop"),
    			e = n.querySelector(".header a"),
    			f = n.querySelector(".title span"),
    			g = n.querySelector(".banner"),
    			e_bannerImg = n.querySelector(".banner img"),
    			h = n.querySelector(".action a"),
    			e.addEventListener("click",
    			function(b) {
    				b.preventDefault(),
    				j && j.setItem("smpopCloseDate", Date.now()),
    				a.close()
    			},
    			!1),
    			h.addEventListener("touchstart",
    			function() {
    				h.className = "hover"
    			},
    			!1),
    			h.addEventListener("touchend",
    			function() {
    				h.className = ""
    			},
    			!1),
    			h.addEventListener("click",
    			function(b) {
    				b.preventDefault(),
    				a.install(!0)
    			},
    			!1),
    			o.innerHTML = c,
    			i.body.appendChild(o),
    			i.body.appendChild(n)
    		},
    		_show: function() {
    			var b = this,
    			d = a.scrollY,
    			e = a.innerHeight;
    			f.innerHTML = b.title,
    			b.banner ? (g.style.display = "", e_bannerImg.setAttribute("src", b.banner)) : g.style.display = "none",
    			n.style.top = d + "px",
    			n.style.height = e + "px",
    			n.style.display = "",
    			n.addEventListener("touchmove", c, !1)
    		},
    		open: function() {
    			if (!this.invaliable) {
    				if (j) {
    					var a = parseInt(localStorage.getItem("smpopCloseDate")),
    					b = new Date;
    					if (b.setHours(0), b.setMinutes(0), b.setSeconds(0), b.setMilliseconds(0), a > b.getTime()) return
    				}
    				l || (l = !0, this._render()),
    				this._show()
    			}
    		},
    		close: function() {
    			this.invaliable || l && (n.style.display = "none", n.removeEventListener("touchmove", c, !1))
    		}
    	},
    	k.PopUI = q
    } (window, window.lib || (window.lib = {})),
    !
    function(a, b) {
    	function c(a) {
    		A.className = "c-smartpop-wrap",
    		A.innerHTML = w,
    		A.style.cssText = "display:none",
    		i = A.querySelector(".c-smartpop"),
    		j = A.querySelector(".header a"),
    		k = A.querySelector(".title span"),
    		l = A.querySelector(".banner img"),
    		m = A.querySelector(".action a"),
    		n = A.querySelector("iframe"),
    		j.addEventListener("click",
    		function(a) {
    			a.preventDefault(),
    			b.smartpop.close()
    		},
    		!1),
    		m.addEventListener("touchstart",
    		function() {
    			m.className = "hover"
    		},
    		!1),
    		m.addEventListener("touchend",
    		function() {
    			m.className = ""
    		},
    		!1),
    		m.addEventListener("click",
    		function(a) {
    			a.preventDefault(),
    			location.href = x
    		},
    		!1),
    		window[z] = function(b) {
    			a(b),
    			delete window[z]
    		},
    		B.async = !0,
    		B.src = y,
    		o.body.appendChild(A),
    		o.body.appendChild(B)
    	}
    	function d() {
    		var b = a.scrollY,
    		c = a.innerHeight;
    		A.style.top = b + "px",
    		A.style.height = c + "px"
    	}
    	function e() {
    		k.innerHTML = h.title,
    		l.setAttribute("src", h.banner),
    		n.setAttribute("src", h.schema),
    		d(),
    		A.style.display = "",
    		A.addEventListener("touchmove", f, !1)
    	}
    	function f(a) {
    		return a.preventDefault(),
    		!1
    	}
    	function g(a) {
    		return u ? a.indexOf("?") > -1 ? a.indexOf("ttid=") > -1 ? a.replace(/ttid=[^&#=]+/, "ttid=" + u) : a.replace("?", "?ttid=" + u + "&") : a.indexOf("#") > -1 ? a.replace("#", "?ttid=" + u + "#") : a += "?ttid=" + u: a
    	}
    	var h, i, j, k, l, m, n, o = a.document,
    	p = window.navigator.userAgent,
    	q = /iPhone|iPod|iTouch|iPad/i.test(p),
    	r = /Android/i.test(p),
    	s = /QQ|QQBrowser/i.test(p),
    	t = /UC|UCBrowser/i.test(p),
    	u = location.href.match(/ttid\=([^&=#]+)/),
    	v = !1,
    	w = ['<div class="c-smartpop">', '<section class="header">', '<a href="javascript:void(0)"></a>', "</section>", '<section class="title">', "<span>淘宝客户端不仅可以更流畅地收藏宝贝,还能分享,立刻下载体验!</span>", "</section>", '<section class="banner">', '<img src="assets/images/banner.jpg" />', "</section>", '<section class="action">', '<a href="javascript:void(0)">点此下载</a>', "</section>", "</div>", '<iframe style="display:none" frameborder="0"></iframe>'].join(""),
    	x = q ? "http://itunes.apple.com/cn/app/id387682726?mt=8": "http://m.taobao.com/channel/act/sale/tbdl1.html",
    	y = "http://wap.taobao.com/go/rgn/h5smart/smartpop.html",
    	z = "smartpop_jsonp",
    	A = document.createElement("div"),
    	B = document.createElement("script");
    	u && (u = u[1]),
    	b.smartpop = {
    		ua: {
    			isIOS: q,
    			isAndroid: r,
    			isQQ: s,
    			isUC: t
    		},
    		open: function(a, b) {
    			u && /[^@]*\@taobao_(?:android|iphone)/i.test(u) || (v ? e() : (v = !0, c(function(c) {
    				h = c[a],
    				h.schema = g(b),
    				e()
    			})))
    		},
    		close: function() {
    			v && (A.style.display = "none", A.removeEventListener("touchmove", f, !1))
    		}
    	}
    } (window, window.lib || (window.lib = {})),
    function(a, b) {
    	function c(a) {
    		return a += "",
    		a.indexOf("px") < 0 && a.indexOf("%") < 0 && "0" !== a && (a += "px"),
    		a
    	}
    	function d(a) {
    		return a += "",
    		a.indexOf("deg") < 0 & "0" !== a && (a += "deg"),
    		a
    	}
    	function e(a, b) {
    		return b || (b = "-"),
    		a.replace(/[a-z][A-Z]/g, "$1" + b + "$2").toLowerCase()
    	}
    	function f(a) {
    		var b = /ms|s|m|h$/.exec(a)[0],
    		c = {
    			ms: 1,
    			s: 1e3,
    			m: 6e4,
    			h: 36e5
    		};
    		return parseFloat(a) * c[b]
    	}
    	var g = /^matrix3d\(\d+, \d+, \d+, \d+, \d+, \d+, \d+, \d+, \d+, \d+, \d+, \d+, ([-\d.]+), ([-\d.]+), [-\d.]+, \d+\)/,
    	h = /^matrix\(\d+, \d+, \d+, \d+, ([-\d.]+), ([-\d.]+)\)$/,
    	i = /^(translate|rotate|scale)(X|Y|Z|3d)?|(matrix)(3d)?|(perspective)|(skew)(X|Y)?$/i,
    	j = (/android/gi.test(navigator.appVersion), /iphone|ipad/gi.test(navigator.appVersion), "WebKitCSSMatrix" in window && "m11" in new WebKitCSSMatrix),
    	k = {
    		translate: function(a, b, c, d, e, f, g) {
    			this.doTransition(a, {
    				translate: [e, f]
    			},
    			{
    				duration: b,
    				timingFunction: c,
    				delay: d,
    				callback: g
    			})
    		},
    		doTransition: function(a, b, g) {
    			function h(b) {
    				t || (a.removeEventListener("webkitTransitionEnd", h, !1), b && b.srcElement !== a || (t = !0, setTimeout(g.callback, 10)))
    			}
    			var k, l = [g.duration, g.timingFunction || "ease", g.delay || "0s"].join(" "),
    			m = "",
    			n = [],
    			o = {};
    			for (var p in b) {
    				var q = b[p];
    				if (k = p.match(i)) {
    					q instanceof Array || (q = [q]);
    					var r = k[1] || k[3] || k[5] || k[6],
    					s = k[2] || k[4] || k[7] || "";
    					"translate" === r && "" === s && j && (s = "3d", q.push(0)),
    					"translate" === r ? q = q.map(c) : ("rotate" === r || "skew" === r) && (q = q.map(d)),
    					m += r + s + "(" + q.join(",") + ")"
    				} else n.push(e(p) + " " + l),
    				o[p] = q;
    				m && n.push("-webkit-transform " + l)
    			}
    			var t = !1;
    			g.callback && a.addEventListener("webkitTransitionEnd", h, !1),
    			setTimeout(h, 1.2 * f(g.duration)),
    			setTimeout(function() {
    				a.style.webkitTransition = n.join(", "),
    				m.length && (a.style.webkitTransform = m);
    				for (var b in o) a.style[b] = o[b]
    			},
    			10)
    		},
    		genCubicBezier: function(a, b) {
    			return [[(a / 3 + (a + b) / 3 - a) / (b - a), (a * a / 3 + a * b * 2 / 3 - a * a) / (b * b - a * a)], [(b / 3 + (a + b) / 3 - a) / (b - a), (b * b / 3 + a * b * 2 / 3 - a * a) / (b * b - a * a)]]
    		},
    		makeTranslateString: function(a, b) {
    			return a = c(a),
    			b = c(b),
    			j ? "translate3d(" + a + ", " + b + ", 0)": "translate(" + a + ", " + b + ")"
    		},
    		getTransformOffset: function(a) {
    			var b, c, d = {
    				x: 0,
    				y: 0
    			},
    			e = getComputedStyle(a).webkitTransform;
    			return "none" !== e && (c = e.indexOf("matrix3d") > -1 ? g: h, (b = e.match(c)) && (d.x = parseInt(b[1]) || 0, d.y = parseInt(b[2]) || 0)),
    			d
    		}
    	};
    	b.module.Animation = k
    } (window, window.app || (window.app = {
    	module: {},
    	plugin: {}
    })),
    function(a, b) {
    	function c(a, b) {
    		b || (b = {}),
    		this._wrapEl = a,
    		this._cacheLength = Math.max(b.cacheLength, 1),
    		this._cacheIndex = 0;
    		for (var c = "",
    		d = 0; d < this._cacheLength; d++) c += '<div class="inactive" index="' + d + '"></div>';
    		this._wrapEl.innerHTML = '<div class="wrap">' + c + '</div><div class="trans"><div></div></div>',
    		this.contentEl = this._wrapEl.childNodes[0],
    		this.transEl = this._wrapEl.childNodes[1],
    		this.transShadeEl = this.transEl.childNodes[0],
    		this.setClassName()
    	}
    	var d = {
    		setClassName: function() {
    			this.getActive().className = "active",
    			this._cacheLength > 2 ? (this.getPrevious().className = "inactive prev", this.getNext().className = "inactive next") : this._cacheLength > 1 && (this.getPrevious().className = "inactive")
    		},
    		getActive: function() {
    			var a = this._cacheIndex;
    			return this.contentEl.childNodes[a]
    		},
    		getNext: function() {
    			var a = (this._cacheIndex + 1) % this._cacheLength;
    			return this.contentEl.childNodes[a]
    		},
    		getPrevious: function() {
    			var a = (this._cacheIndex - 1 + this._cacheLength) % this._cacheLength;
    			return this.contentEl.childNodes[a]
    		},
    		next: function() {
    			this._cacheLength > 2 && (this.getPrevious().className = "inactive"),
    			this._cacheIndex = (this._cacheIndex + 1) % this._cacheLength
    		},
    		previous: function() {
    			this._cacheLength > 2 && (this.getNext().className = "inactive"),
    			this._cacheIndex = (this._cacheIndex - 1 + this._cacheLength) % this._cacheLength
    		},
    		html: function(a) {
    			this.getActive().innerHTML = a
    		}
    	};
    	for (var e in d) c.prototype[e] = d[e];
    	b.module.Content = c
    } (window, window.app || (window.app = {
    	module: {},
    	plugin: {}
    })),
    function(a) {
    	function b(a, b) {
    		for (var c = a; c;) {
    			if (c.contains(b) || c == b) return c;
    			c = c.parentNode
    		}
    		return null
    	}
    	function c(a, b, c) {
    		var d = i.createEvent("HTMLEvents");
    		if (d.initEvent(b, !0, !0), "object" == typeof c) for (var e in c) d[e] = c[e];
    		a.dispatchEvent(d)
    	}
    	function d(a, b, c, d, e, f, g, h) {
    		var i = Math.atan2(h - f, g - e) - Math.atan2(d - b, c - a),
    		j = Math.sqrt((Math.pow(h - f, 2) + Math.pow(g - e, 2)) / (Math.pow(d - b, 2) + Math.pow(c - a, 2))),
    		k = [e - j * a * Math.cos(i) + j * b * Math.sin(i), f - j * b * Math.cos(i) - j * a * Math.sin(i)];
    		return {
    			rotate: i,
    			scale: j,
    			translate: k,
    			matrix: [[j * Math.cos(i), -j * Math.sin(i), k[0]], [j * Math.sin(i), j * Math.cos(i), k[1]], [0, 0, 1]]
    		}
    	}
    	function e(a) {
    		0 === Object.keys(l).length && (j.addEventListener("touchmove", f, !1), j.addEventListener("touchend", g, !1), j.addEventListener("touchcancel", h, !1));
    		for (var d = 0; d < a.changedTouches.length; d++) {
    			var e = a.changedTouches[d],
    			i = {};
    			for (var m in e) i[m] = e[m];
    			var n = {
    				startTouch: i,
    				startTime: Date.now(),
    				status: "tapping",
    				element: a.srcElement,
    				pressingHandler: setTimeout(function(b) {
    					return function() {
    						"tapping" === n.status && (n.status = "pressing", c(b, "press", {
    							touchEvent: a
    						})),
    						clearTimeout(n.pressingHandler),
    						n.pressingHandler = null
    					}
    				} (a.srcElement), 500)
    			};
    			l[e.identifier] = n
    		}
    		if (2 == Object.keys(l).length) {
    			var o = [];
    			for (var m in l) o.push(l[m].element);
    			c(b(o[0], o[1]), "dualtouchstart", {
    				touches: k.call(a.touches),
    				touchEvent: a
    			})
    		}
    	}
    	function f(a) {
    		for (var e = 0; e < a.changedTouches.length; e++) {
    			var f = a.changedTouches[e],
    			g = l[f.identifier];
    			if (!g) return;
    			var h = f.clientX - g.startTouch.clientX,
    			i = f.clientY - g.startTouch.clientY,
    			j = Math.sqrt(Math.pow(h, 2) + Math.pow(i, 2));
    			"tapping" === g.status && j > 10 && (g.status = "panning", c(g.element, "panstart", {
    				touch: f,
    				touchEvent: a
    			}), Math.abs(h) > Math.abs(i) ? (c(g.element, "horizontalpanstart", {
    				touch: f,
    				touchEvent: a
    			}), g.isVertical = !1) : (c(g.element, "verticalpanstart", {
    				touch: f,
    				touchEvent: a
    			}), g.isVertical = !0)),
    			"panning" === g.status && (g.panTime = Date.now(), c(g.element, "pan", {
    				displacementX: h,
    				displacementY: i,
    				touch: f,
    				touchEvent: a
    			}), g.isVertical ? c(g.element, "verticalpan", {
    				displacementY: i,
    				touch: f,
    				touchEvent: a
    			}) : c(g.element, "horizontalpan", {
    				displacementX: h,
    				touch: f,
    				touchEvent: a
    			}))
    		}
    		if (2 == Object.keys(l).length) {
    			for (var k, m = [], n = [], o = [], e = 0; e < a.touches.length; e++) {
    				var f = a.touches[e],
    				g = l[f.identifier];
    				m.push([g.startTouch.clientX, g.startTouch.clientY]),
    				n.push([f.clientX, f.clientY])
    			}
    			for (var p in l) o.push(l[p].element);
    			k = d(m[0][0], m[0][1], m[1][0], m[1][1], n[0][0], n[0][1], n[1][0], n[1][1]),
    			c(b(o[0], o[1]), "dualtouch", {
    				transform: k,
    				touches: a.touches,
    				touchEvent: a
    			})
    		}
    	}
    	function g(a) {
    		if (2 == Object.keys(l).length) {
    			var d = [];
    			for (var e in l) d.push(l[e].element);
    			c(b(d[0], d[1]), "dualtouchend", {
    				touches: k.call(a.touches),
    				touchEvent: a
    			})
    		}
    		for (var i = 0; i < a.changedTouches.length; i++) {
    			var n = a.changedTouches[i],
    			o = n.identifier,
    			p = l[o];
    			if (p) {
    				if (p.pressingHandler && (clearTimeout(p.pressingHandler), p.pressingHandler = null), "tapping" === p.status && (p.timestamp = Date.now(), c(p.element, "tap", {
    					touch: n,
    					touchEvent: a
    				}), m && p.timestamp - m.timestamp < 300 && c(p.element, "doubletap", {
    					touch: n,
    					touchEvent: a
    				}), this.lastTap = p), "panning" === p.status) {
    					var q = Date.now() - p.startTime,
    					r = (n.clientX - p.startTouch.clientX) / q,
    					s = (n.clientY - p.startTouch.clientY) / q,
    					t = n.clientX - p.startTouch.clientX,
    					u = n.clientY - p.startTouch.clientY;
    					c(p.element, "panend", {
    						isflick: 300 > q,
    						touch: n,
    						touchEvent: a
    					}),
    					300 > q && (c(p.element, "flick", {
    						duration: q,
    						velocityX: r,
    						velocityY: s,
    						displacementX: t,
    						displacementY: u,
    						touch: n,
    						touchEvent: a
    					}), p.isVertical ? c(p.element, "verticalflick", {
    						duration: q,
    						velocityY: s,
    						displacementY: u,
    						touch: n,
    						touchEvent: a
    					}) : c(p.element, "horizontalflick", {
    						duration: q,
    						velocityX: r,
    						displacementX: t,
    						touch: n,
    						touchEvent: a
    					}))
    				}
    				"pressing" === p.status && c(p.element, "pressend", {
    					touch: n,
    					touchEvent: a
    				}),
    				delete l[o]
    			}
    		}
    		0 === Object.keys(l).length && (j.removeEventListener("touchmove", f, !1), j.removeEventListener("touchend", g, !1), j.removeEventListener("touchcancel", h, !1))
    	}
    	function h(a) {
    		if (2 == Object.keys(l).length) {
    			var d = [];
    			for (var e in l) d.push(l[e].element);
    			c(b(d[0], d[1]), "dualtouchend", {
    				touches: k.call(a.touches),
    				touchEvent: a
    			})
    		}
    		for (var i = 0; i < a.changedTouches.length; i++) {
    			var m = a.changedTouches[i],
    			n = m.identifier,
    			o = l[n];
    			o && (o.pressingHandler && (clearTimeout(o.pressingHandler), o.pressingHandler = null), "panning" === o.status && c(o.element, "panend", {
    				touch: m,
    				touchEvent: a
    			}), "pressing" === o.status && c(o.element, "pressend", {
    				touch: m,
    				touchEvent: a
    			}), delete l[n])
    		}
    		0 === Object.keys(l).length && (j.removeEventListener("touchmove", f, !1), j.removeEventListener("touchend", g, !1), j.removeEventListener("touchcancel", h, !1))
    	}
    	var i = a.document,
    	j = i.documentElement,
    	k = Array.prototype.slice,
    	l = {},
    	m = null;
    	j.addEventListener("touchstart", e, !1)
    } (window, window.app || (window.app = {
    	module: {},
    	plugin: {}
    })),
    function(a, b) {
    	function c() {
    		this._handlers = {}
    	}
    	function d(a, b, c) {
    		e.isLogging && console.log("[Message]", {
    			scope: a,
    			event: b,
    			args: c
    		})
    	}
    	function e(a) {
    		var b = this;
    		this._scope = a,
    		this._event = new c,
    		this._cache = {},
    		this._handler = function(a) {
    			for (var c = a.type,
    			d = a.args,
    			e = b._cache[c].slice(), f = 0; f < e.length; f += 2) e[f].apply(e[f + 1], d)
    		},
    		h[a] = this
    	}
    	var f = {
    		addEventListener: function(a, b) {
    			var c, d = this._handlers;
    			c = d[a] || (d[a] = []),
    			c.push(b)
    		},
    		removeEventListener: function(a, b) {
    			var c = this._handlers;
    			c[a] && (c[a] = c[a].filter(function(a) {
    				return a != b
    			}), c[a].length || delete c[a])
    		},
    		dispatchEvent: function(a) {
    			var b = this._handlers,
    			c = a.type;
    			b.hasOwnProperty(c) && b[c].forEach(function(b) {
    				b(a)
    			}),
    			this["on" + c] && this["on" + c](a)
    		}
    	};
    	for (var g in f) c.prototype[g] = f[g];
    	var h = {},
    	i = /\s+/,
    	j = {
    		on: function(a, b, c) {
    			var d, e, f = this,
    			g = f._cache,
    			h = f._event;
    			if (!b) return f;
    			for (a = a.split(i); e = a.shift();) d = g[e] || (g[e] = []),
    			d.length || h.addEventListener(e, this._handler),
    			d.push(b, c);
    			return f
    		},
    		off: function(a, b, c) {
    			var d, e, f = this,
    			g = f._cache,
    			h = f._event;
    			for (a = a ? a.split(i) : Object.keys(g); e = a.shift();) { ! (b || c) && (g[e] = []),
    				d = g[e];
    				for (var j = d.length - 2; j >= 0; j -= 2) b && d[j] !== b || c && d[j + 1] !== c || d.splice(j, 2);
    				d.length || (delete g[e], h.removeEventListener(e, this._handler))
    			}
    			return f
    		},
    		once: function(a, b, c) {
    			function d() {
    				b.apply(this, arguments),
    				e.off(a, d, c)
    			}
    			var e = this;
    			return e.on(a, d, c)
    		},
    		after: function(a, b, c) {
    			function d() {
    				for (var a in h) if (!h[a]) return ! 1;
    				return ! 0
    			}
    			function e() {
    				for (var a in h) h[a] = !1
    			}
    			var f, g = this,
    			h = {};
    			return b ? (a = a.split(i), f = a.join("&&"), a.forEach(function(a) {
    				h[a] = !1,
    				g.on(a,
    				function() {
    					h[a] = !0,
    					d() && (g.trigger(f), e())
    				})
    			}), void g.on(f, b, c)) : g
    		},
    		trigger: function(a) {
    			var b, c, e = this,
    			f = e._cache,
    			g = e._event;
    			for (a = a.split(i), b = Array.prototype.slice.call(arguments, 1); c = a.shift();) d(this._scope, c, b),
    			f[c] && g.dispatchEvent({
    				type: c,
    				args: b
    			});
    			return e
    		}
    	};
    	for (var g in j) e.prototype[g] = j[g];
    	e.isLogging = !1,
    	e.mixto = function(a, b) {
    		var c = e.get(b);
    		a.prototype && (a = a.prototype);
    		for (var d in j) void
    		function(b) {
    			a[d] = function() {
    				b.apply(c, arguments)
    			}
    		} (j[d])
    	},
    	e.get = function(a) {
    		if ("string" == typeof a) return h[a] || (h[a] = new e(a));
    		if (a instanceof e) return a;
    		throw new TypeError
    	},
    	b.module.Event = c,
    	b.module.MessageScope = e
    } (window, window.app || (window.app = {
    	module: {},
    	plugin: {}
    })),
    function(a, b) {
    	function c(a, b) {
    		null != b.id && a.setAttribute("data-id", b.id),
    		null != b["class"] && (a.className = b["class"]),
    		null != b.text && (a.innerHTML = b.text),
    		null != b.bg && (a.style.background = b.bg),
    		null != b.icon && (a.innerHTML = '<img src="' + b.icon + '" border="0" width="100%" height="100%" />'),
    		a.style.display = b.hide === !0 ? "none": "",
    		b.onChange && b.onChange.call(a, b),
    		b.handler && (a.handler && a.removeEventListener("click", a.handler, !1), a.addEventListener("click", a.handler = b.handler, !1))
    	}
    	function d(a) {
    		this.wrapEl = a,
    		this.wrapEl.appendChild(this.animWrapEl = e.createElement("ul")),
    		this.animWrapEl.appendChild(this.titleWrapEl = e.createElement("li")),
    		this.animWrapEl.appendChild(this.backWrapEl = e.createElement("li")),
    		this.animWrapEl.appendChild(this.funcWrapEl = e.createElement("li"))
    	}
    	var e = a.document,
    	f = {
    		setTitle: function(a) {
    			"string" == typeof a ? this.titleWrapEl.innerHTML = a: a instanceof HTMLElement && (this.titleWrapEl.innerHTML = "", this.titleWrapEl.appendChild(a))
    		},
    		setButton: function(a) {
    			var b, d;
    			"back" === a.type ? (b = this.backWrapEl, d = b.querySelector("a")) : "func" === a.type ? (b = this.funcWrapEl, d = b.querySelector('a[data-id="' + a.id + '"]')) : a.id && (d = this.wrapEl.querySelector('a[data-id="' + a.id + '"]'), d && (b = d.parentNode)),
    			!d && b && (d = e.createElement("a"), d.className = a.type, b.appendChild(d)),
    			c(d, a)
    		},
    		getButton: function(a) {
    			return this.wrapEl.querySelector('a[data-id="' + a + '"]')
    		},
    		removeButton: function(a) {
    			function b(a) {
    				a && (a.handler && a.removeEventListener("click", a.handler), a.parentNode.removeChild(a))
    			}
    			if (a) {
    				if ("string" == typeof a) var c = this.getButton(a);
    				else if (a instanceof HTMLElement) var c = a;
    				b(c)
    			} else for (var d = this.funcWrapEl.querySelectorAll("a"), e = 0; e < d.length; e++) b(d[e])
    		}
    	};
    	for (var g in f) d.prototype[g] = f[g];
    	b.module.Navbar = d
    } (window, window.app || (window.app = {
    	module: {},
    	plugin: {}
    })),
    function(a, b) {
    	function c(a, b) {
    		for (var c in b) b.hasOwnProperty(c) && (a[c] = b[c])
    	}
    	function d(a, b) {
    		function d() {}
    		d.prototype = b.prototype;
    		var e = new d;
    		c(e, a.prototype),
    		e.constructor = a,
    		a.prototype = e
    	}
    	function e() {}
    	var f = (b.module.MessageScope, {}),
    	g = {
    		ready: function() {},
    		startup: function() {},
    		teardown: function() {},
    		show: function() {},
    		hide: function() {}
    	};
    	for (var h in g) e.prototype[h] = g[h];
    	e.fn = {},
    	e.define = function(a) {
    		function b() {
    			e.apply(this, arguments),
    			this.initialize && this.initialize.apply(this, arguments)
    		}
    		return d(b, e),
    		c(b.prototype, e.fn),
    		c(b.prototype, a),
    		f[a.name] = new b
    	},
    	e.get = function(a) {
    		return f[a]
    	},
    	b.module.Page = e
    } (window, window.app || (window.app = {
    	module: {},
    	plugin: {}
    })),
    function(a, b) {
    	function c() {}
    	var d = (a.document, {
    		load: function(a, b) {
    			var d = c.engine;
    			d.load && "string" == typeof a ? d.load(a, b) : b && b(a)
    		},
    		compile: function(a) {
    			var b = c.engine;
    			return this.originTemplate = a,
    			this.compiledTemplate = b.compile && "string" == typeof a ? b.compile(a) : function() {
    				return a
    			},
    			this.compiledTemplate
    		},
    		render: function(a) {
    			var b = c.engine,
    			d = this.compiledTemplate;
    			return this.content = b.render && d && "object" == typeof a ? b.render(d, a) : d ? d(a) : Object.prototype.toString.call(a),
    			this.content
    		}
    	});
    	for (var e in d) c.prototype[e] = d[e];
    	c.engine = {},
    	b.module.Template = c
    } (window, window.app || (window.app = {
    	module: {},
    	plugin: {}
    })),
    function(a, b) {
    	function c(a, b) {
    		b || (b = {}),
    		this._wrapEl = a,
    		this.set(b)
    	}
    	var d = (a.document, {
    		set: function(a) {
    			a || (a = {}),
    			a.html && (this._wrapEl.innerHTML = a.html),
    			a.el && ((this._wrapEl.innerHTML = "") || this._wrapEl.appendChild(a.el)),
    			a.height && (this._wrapEl.style.height = a.height + "px")
    		},
    		show: function(a) {
    			a && this.set(a),
    			this._wrapEl.style.display = ""
    		},
    		hide: function() {
    			this._wrapEl.style.display = "none"
    		}
    	});
    	for (var e in d) c.prototype[e] = d[e];
    	b.module.Toolbar = c
    } (window, window.app || (window.app = {
    	module: {},
    	plugin: {}
    })),
    function(a, b) {
    	function c(a, b) {
    		for (var c in b) b.hasOwnProperty(c) && (a[c] = b[c])
    	}
    	function d(a, b) {
    		function d() {}
    		d.prototype = b.prototype;
    		var e = new d;
    		c(e, a.prototype),
    		e.constructor = a,
    		a.prototype = e
    	}
    	function e() {
    		var b = a.$;
    		if ("string" == typeof this.el) {
    			var c = this.el.split(/\s*\>\s*/),
    			d = this.el = document.createElement("div");
    			c.forEach(function(a) {
    				var b;
    				if (b = a.match(/^(\w+)?(?:\#([^.]+))?(?:\.(.+))?$/i)) {
    					var c = document.createElement(b[1] || "div");
    					b[2] && c.setAttribute("id", b[2]),
    					b[3] && (c.className = b[3]),
    					d.appendChild(c)
    				} else d.innerHTML = a;
    				d = d.childNodes[0]
    			}),
    			this.el = this.el.removeChild(this.el.childNodes[0])
    		}
    		b && (this.$el = b(this.el))
    	}
    	var f = (a.document, {}),
    	g = {
    		render: function() {},
    		destory: function() {}
    	};
    	for (var h in g) e.prototype[h] = g[h];
    	e.fn = {},
    	e.extend = function(a) {
    		function b() {
    			g.apply(this, arguments),
    			this.initialize && this.initialize.apply(this, arguments)
    		}
    		var g = f[a.parent] || e;
    		return d(b, g),
    		c(b.prototype, g.fn),
    		c(b.prototype, a),
    		f[a.name] = b
    	},
    	e.get = function(a) {
    		return f[a]
    	},
    	b.module.View = e
    } (window, window.app || (window.app = {
    	module: {},
    	plugin: {}
    })),
    function(a, b) {
    	function c(a, b, c, e) {
    		var f = (this.TYPE, d.getTransformOffset(a)),
    		g = {
    			translate: {
    				x: f.x,
    				y: f.y
    			}
    		},
    		h = {
    			translate: {
    				x: f.x,
    				y: f.y
    			}
    		};
    		b = b.split(""),
    		c(g, h, b[0], b[1]);
    		for (var i in g)"translate" === i ? (a.style.webkitTransition = "", a.style.webkitTransform = d.makeTranslateString(g[i].x, g[i].y)) : a.style[i] = g[i];
    		h.translate = [h.translate.x, h.translate.y],
    		a.style.webkitBackfaceVisibility = "hidden",
    		a.style.webkitTransformStyle = "preserve-3d",
    		d.doTransition(a, h, {
    			duration: "0.4s",
    			timingFunction: "ease",
    			callback: function() {
    				a.style.webkitBackfaceVisibility = "",
    				a.style.webkitTransformStyle = "",
    				a.style.webkitTransition = "",
    				e && e()
    			}
    		})
    	}
    	var d = (a.document, b.module.Animation),
    	e = {
    		L: "x",
    		R: "x",
    		T: "y",
    		B: "y"
    	},
    	f = {
    		L: -1,
    		R: 1,
    		T: -1,
    		B: 1
    	},
    	g = {
    		TYPE: {
    			LEFT_IN: "LI",
    			LEFT_OUT: "LO",
    			RIGHT_IN: "RI",
    			RIGHT_OUT: "RO",
    			TOP_IN: "TI",
    			TOP_OUT: "TO",
    			BOTTOM_IN: "BI",
    			BOTTOM_OUT: "BO"
    		},
    		move: function(a, b, c, e) {
    			var f = d.getTransformOffset(a);
    			a.style.webkitBackfaceVisibility = "hidden",
    			a.style.webkitTransformStyle = "preserve-3d",
    			d.translate(a, "0.4s", "ease", "0s", f.x + b, f.y + c,
    			function() {
    				a.style.webkitBackfaceVisibility = "",
    				a.style.webkitTransformStyle = "",
    				a.style.webkitTransition = "",
    				e && e()
    			})
    		},
    		slide: function(a, b, d, g) {
    			c(a, b,
    			function(a, b, c, g) {
    				var h = e[c],
    				i = f[c];
    				"I" === g ? a.translate[h] += i * d: b.translate[h] += i * d
    			},
    			g)
    		},
    		"float": function(a, b, d, g) {
    			c(a, b,
    			function(a, b, c, g) {
    				var h = e[c],
    				i = f[c];
    				"I" === g ? (a.translate[h] += i * d, a.opacity = 0, b.opacity = 1) : (b.translate[h] += i * d, a.opacity = 1, b.opacity = 0)
    			},
    			g)
    		},
    		fadeIn: function(a, b) {
    			c(a, "FI",
    			function(a, b, c, d) {
    				"I" === d ? (a.opacity = 0, b.opacity = 1) : (a.opacity = 1, b.opacity = 0)
    			},
    			b)
    		},
    		fadeOut: function(a) {
    			c(a, "FO",
    			function(a, b, c, d) {
    				"I" === d ? (a.opacity = 0, b.opacity = 1) : (a.opacity = 1, b.opacity = 0)
    			},
    			callback)
    		},
    		zoomIn: function() {},
    		zoomOut: function() {}
    	};
    	b.module.Transition = g
    } (window, window.app || (window.app = {
    	module: {},
    	plugin: {}
    })),
    function(a, b) {
    	function c(a) {
    		return 0 - (a.bounceTop || 0)
    	}
    	function d(a) {
    		var b = a.getBoundingClientRect(),
    		d = a.parentNode.getBoundingClientRect(),
    		e = c(a),
    		f = 0 - b.height + d.height;
    		return Math.min(f + (a.bounceBottom || 0), e)
    	}
    	function e(a, b) {
    		return b > a.minScrollTop ? b - a.minScrollTop: b < a.maxScrollTop ? a.maxScrollTop - b: void 0
    	}
    	function f(a, b) {
    		return b > a.minScrollTop ? b = a.minScrollTop: b < a.maxScrollTop && (b = a.maxScrollTop),
    		b
    	}
    	function g(a, b, c) {
    		var d = u.createEvent("HTMLEvents");
    		d.initEvent(b, !0, !0);
    		for (var e in c) d[e] = c[e];
    		a.dispatchEvent(d)
    	}
    	function h(a) {
    		if (!stopBounce) {
    			for (var b = a.srcElement; ! b.boundScrollEvent;) b = b.parentNode || b.offsetParent;
    			if (r = b.boundScrollElement) {
    				var c = w.getTransformOffset(r);
    				r.style.webkitBackfaceVisibility = "hidden",
    				r.style.webkitTransformStyle = "preserve-3d",
    				r.style.webkitTransition = "",
    				r.style.webkitTransform = w.makeTranslateString(c.x, c.y)
    			}
    		}
    	}
    	function i(a) {
    		return a.preventDefault(),
    		!1
    	}
    	function j() {}
    	function k() { ! stopBounce && r && (r.transformOffset = w.getTransformOffset(r), r.minScrollTop = c(r), r.maxScrollTop = d(r), x = 2.5, stopBounce = !1, y = !1, g(r, "scrollstart"))
    	}
    	function l(a) {
    		if (!stopBounce && r) {
    			var b = r.transformOffset.y + a.displacementY;
    			if (b > r.minScrollTop ? (b = r.minScrollTop + (b - r.minScrollTop) / x, x *= 1.003, x > 4 && (x = 4)) : b < r.maxScrollTop && (b = r.maxScrollTop - (r.maxScrollTop - b) / x, x *= 1.003, x > 4 && (x = 4)), e(r, b)) {
    				if (b > r.minScrollTop) var c = "pulldown",
    				d = Math.abs(b - r.minScrollTop);
    				else if (b < r.maxScrollTop) var c = "pullup",
    				d = Math.abs(r.maxScrollTop - b);
    				r.bounceOffset = d,
    				g(r, c)
    			}
    			r.style.webkitTransition = "",
    			r.style.webkitTransform = w.makeTranslateString(r.transformOffset.x, b)
    		}
    	}
    	function m() {
    		if (!stopBounce && r) {
    			var a = w.getTransformOffset(r).y;
    			e(r, a) ? o() : q()
    		}
    	}
    	function n(a) {
    		if (!stopBounce && r) {
    			var b = w.getTransformOffset(r).y,
    			c = .008 * (a / Math.abs(a));
    			t = a / c,
    			s = b + t * a / 2,
    			g(r, "bouncestart"),
    			w.translate(r, t.toFixed(0) + "ms", "cubic-bezier(" + w.genCubicBezier( - t, 0) + ")", "0s", r.transformOffset.x, s.toFixed(0), o)
    		}
    	}
    	function o() {
    		if (!stopBounce && r) {
    			var a = w.getTransformOffset(r).y;
    			a = f(r, a),
    			w.translate(r, "0.4s", "ease-in-out", "0s", r.transformOffset.x, a,
    			function() {
    				g(r, "bounceend"),
    				q()
    			})
    		}
    	}
    	function p(a) {
    		if (!stopBounce && r) {
    			var b, c, d, e, f, g, h, i = w.getTransformOffset(r).y;
    			y = !0,
    			i > r.minScrollTop || i < r.maxScrollTop ? n(b) : (b = a.velocityY, b > 1.5 && (b = 1.5), -1.5 > b && (b = -1.5), c = .0015 * (b / Math.abs(b)), d = b / c, e = i + d * b / 2, e > r.minScrollTop ? (g = r.minScrollTop - i, h = (b - Math.sqrt( - 2 * c * g + b * b)) / c, f = b - c * h, w.translate(r, h.toFixed(0) + "ms", "cubic-bezier(" + w.genCubicBezier( - d, -d + h) + ")", "0s", r.transformOffset.x, r.minScrollTop,
    			function() {
    				n(f)
    			})) : e < r.maxScrollTop ? (g = r.maxScrollTop - i, h = (b + Math.sqrt( - 2 * c * g + b * b)) / c, f = b - c * h, w.translate(r, h.toFixed(0) + "ms", "cubic-bezier(" + w.genCubicBezier( - d, -d + h) + ")", "0s", r.transformOffset.x, r.maxScrollTop,
    			function() {
    				n(f)
    			})) : w.translate(r, d.toFixed(0) + "ms", "cubic-bezier(" + w.genCubicBezier( - d, 0) + ")", "0s", r.transformOffset.x, e.toFixed(0), q))
    		}
    	}
    	function q() { ! stopBounce && r && (y = !1, setTimeout(function() {
    			y || (r.style.webkitBackfaceVisibility = "initial", r.style.webkitTransformStyle = "flat", r.style.webkitTransition = "", g(r, "scrollend"))
    		},
    		10))
    	}
    	var r, u = a.document,
    	v = u.documentElement,
    	w = b.module.Animation,
    	x = 2,
    	y = !1;
    	stopBounce = !1,
    	prevented = !1;
    	var z = {
    		enable: function(a, b) {
    			var c = a.parentNode || a.offsetParent;
    			prevented || (prevented = !0, v.addEventListener("touchmove", i, !1)),
    			c.boundScrollEvent || (c.boundScrollEvent = !0, c.addEventListener("touchstart", h, !1), c.addEventListener("touchend", j, !1), c.addEventListener("panstart", k, !1), c.addEventListener("pan", l, !1), c.addEventListener("panend", m, !1), c.addEventListener("flick", p, !1)),
    			c.boundScrollElement = a,
    			b ? (a.bounceTop = b.bounceTop, a.bounceBottom = b.bounceBottom) : (a.bounceTop = 0, a.bounceBottom = 0);
    			var d = w.getTransformOffset(a).x,
    			e = -a.bounceTop;
    			a.style.webkitTransition = "",
    			a.style.webkitTransform = w.makeTranslateString(d, e)
    		},
    		disable: function(a) {
    			var b, c = a.parentNode || a.offsetParent;
    			c.boundScrollElement === a && (b = w.getTransformOffset(a), r = c.boundScrollElement = null, setTimeout(function() {
    				a.style.webkitTransition = "",
    				a.style.webkitTransform = w.makeTranslateString(b.x, b.y)
    			},
    			50))
    		},
    		getScrollHeight: function(a) {
    			return a.getBoundingClientRect().height - (a.bounceTop || 0) - (a.bounceBottom || 0)
    		},
    		getScrollTop: function(a) {
    			var b = w.getTransformOffset(a);
    			return - (b.y + (a.bounceTop || 0))
    		},
    		refresh: function(a) {
    			a.style.height = "auto",
    			a.style.height = a.offsetHeight + "px",
    			a.offset = w.getTransformOffset(a),
    			a.minScrollTop = c(a),
    			a.maxScrollTop = d(a),
    			this.scrollTo(a, -a.offset.y - a.bounceTop)
    		},
    		offset: function(a, b) {
    			var c = a.getBoundingClientRect(),
    			d = b.getBoundingClientRect(),
    			e = {
    				top: d.top - ((a.bounceTop || 0) + c.top),
    				left: d.left - c.left,
    				right: c.right - d.right,
    				width: d.width,
    				height: d.height
    			};
    			return e.bottom = e.top + d.height,
    			e
    		},
    		scrollTo: function(a, b) {
    			var c = w.getTransformOffset(a).x,
    			b = -b - (a.bounceTop || 0);
    			b = f(a, b),
    			a.style.webkitTransition = "",
    			a.style.webkitTransform = w.makeTranslateString(c, b)
    		},
    		scollToElement: function(a, b) {
    			var c = this.offset(a, b);
    			this.scrollTo(a, c.top)
    		},
    		getViewHeight: function(a) {
    			return a.parentNode.getBoundingClientRect().height
    		},
    		getBoundaryOffset: function(a) {
    			var b = w.getTransformOffset(a).y;
    			return e(a, b)
    		},
    		stopBounce: function(a) {
    			stopBounce = !0;
    			var b = w.getTransformOffset(a),
    			e = c(a),
    			f = d(a),
    			g = null;
    			b.y > e + (a.bounceTop || 0) ? g = e + (a.bounceTop || 0) : b.y < f - (a.bounceBottom || 0) && (g = f - (a.bounceBottom || 0)),
    			null != g && w.translate(a, "0.4s", "ease-in-out", "0s", b.x, g)
    		},
    		resumeBounce: function(a) {
    			stopBounce = !1;
    			var b, e = w.getTransformOffset(a),
    			f = c(a),
    			g = d(a);
    			e.y > f ? b = f: g > e && (b = g),
    			null != b && w.translate(a, "0.4s", "ease-in-out", "0s", e.x, b)
    		}
    	};
    	b.module.Scroll = z
    } (window, window.app || (window.app = {
    	module: {},
    	plugin: {}
    })),
    function(a, b) {
    	function c(a) {
    		var b = this,
    		d = !0,
    		g = {};
    		e.mixto(b, "model-" + f++),
    		b.addProperty = function(e, f) {
    			Object.defineProperty(b, e, {
    				get: function() {
    					return g[e] || a[e]
    				},
    				set: function(f) {
    					g[e] && (g[e].destory(), delete g[e]),
    					null != f && (a[e] = f, "object" == typeof f && (g[e] = new c(f), g[e].on("propertyChange",
    					function(a) {
    						b.trigger("propertyChange", {
    							target: a.target,
    							value: a.value,
    							name: a.name,
    							path: e + "." + a.path
    						})
    					}))),
    					!d && b.trigger("propertyChange", {
    						target: b,
    						value: g[e] || a[e],
    						name: e,
    						path: e
    					})
    				}
    			}),
    			b[e] = f
    		},
    		b.update = function(a) {
    			if (a instanceof Array) for (var d = 0; d < a.length; d++) a[d] instanceof c || this.addProperty(d, a[d]);
    			else for (var e in a) {
    				if (b.hasOwnProperty(e)) throw new Error('property conflict "' + e + '"'); ! a.hasOwnProperty(e) || a[e] instanceof c || this.addProperty(e, a[e])
    			}
    		},
    		b.destory = function() {
    			for (var a in g) g[a].destory();
    			b.off()
    		},
    		b.on("propertyChange",
    		function(a) {
    			b.trigger("change:" + a.path, a.value)
    		}),
    		b.update(a),
    		d = !1
    	}
    	function d(a) {
    		var b = this; ! a instanceof Array || (b.push = function(c) {
    			a.push(c),
    			b.addProperty(a.length - 1, c)
    		},
    		b.pop = function() {
    			var c = a.pop();
    			return b[a.length] = null,
    			c
    		},
    		Object.defineProperty(b, "length", {
    			get: function() {
    				return a.length
    			}
    		}), c.call(b, a))
    	}
    	var e = b.module.MessageScope,
    	f = 0;
    	b.module.Model = c,
    	b.module.Collection = d
    } (window, window.app || (window.app = {
    	module: {},
    	plugin: {}
    })),
    function(a, b) {
    	function c() {
    		var a = this;
    		a.move = null,
    		a.transition = null,
    		a.datas = null,
    		a._states = [],
    		a._stateIdx = 0,
    		a._stateLimit = 100
    	}
    	function d(a) {
    		return a.replace(m, "(P<$1>[^\\/]*?)").replace(n, "(P<$1>.*?)")
    	}
    	function e(a) {
    		var b = a.match(o),
    		c = {};
    		return b && b.forEach(function(a, b) {
    			c[a.replace(o, "$1")] = b
    		}),
    		c
    	}
    	function f(a) {
    		if (!a) return {};
    		var b = a.split("&"),
    		c = {};
    		return b.forEach(function(a) {
    			if (a) {
    				var b = a.split("=");
    				c[b[0]] = b[1]
    			}
    		}),
    		c
    	}
    	function g(a) {
    		return a = a.replace(o, ""),
    		new RegExp("^(" + a + ")$")
    	}
    	function h() {
    		return r.hash.slice(1) || ""
    	}
    	function i(a) {
    		r.hash = a
    	}
    	function j() {
    		var a = this;
    		a._started = !1,
    		a._routes = {},
    		a._stack = new c,
    		s.mixto(this, "navigation")
    	}
    	var k = {
    		reset: function() {
    			var a = this;
    			a.move = null,
    			a.transition = null,
    			a.datas = null,
    			a.type = null,
    			a._states = [],
    			a._stateIdx = 0,
    			a._stateLimit = 100
    		},
    		pushState: function(a, b, d, e) {
    			var f = this,
    			g = f._states,
    			h = f._stateIdx,
    			i = f._stateLimit,
    			j = g.length,
    			k = f.move,
    			l = f.transition,
    			m = f.datas,
    			n = f.type,
    			o = g[h - 1],
    			p = g[h + 1],
    			q = {
    				name: a,
    				fragment: b,
    				type: n,
    				params: d || {},
    				datas: m || {}
    			};
    			for (var r in e) q.datas[r] = e[r];
    			return null == k && (l = k = !m && c.isEquals(o, q) ? "backward": "forward"),
    			"backward" === k ? 0 === h && j > 0 ? g.unshift(q) : h > 0 && (h--, q = o) : "forward" === k && (h === i - 1 ? (g.shift(), g.push(q), q.referer = location.href.replace(/#[^#]*/, "#" + g[h - 1].fragment)) : 0 === h && 0 === j ? (g.push(q), q.referer = document.referer || "") : !m && c.isEquals(p, q) ? (h++, q = p) : c.isEquals(g[h], q) ? q = g[h] : (h++, g.splice(h), g.push(q), q.referer = location.href.replace(/#[^#]*/, "#" + g[h - 1].fragment))),
    			q.move = k,
    			q.transition = l,
    			q.index = h,
    			f.move = null,
    			f.transition = null,
    			f.datas = null,
    			f._stateIdx = h,
    			q
    		},
    		getState: function() {
    			return this._states[this._stateIdx]
    		},
    		getIndex: function() {
    			return this._stateIdx
    		}
    	};
    	for (var l in k) c.prototype[l] = k[l];
    	c.isEquals = function(a, b) {
    		return a && b ? a.name !== b.name || a.fragment !== b.fragment ? !1 : !0 : !1
    	};
    	var m = /\:([a-z0-9_-][a-z0-9_-]*)/gi,
    	n = /\*([a-z0-9_-][a-z0-9_-]*)/gi,
    	o = /P\<([a-z0-9_-][a-z0-9_-]*?)\>/gi,
    	p = "?",
    	q = a.history,
    	r = a.location,
    	s = b.module.MessageScope,
    	t = {
    		getStack: function() {
    			return this._stack
    		},
    		handleEvent: function() {
    			var a, b, c, d = this,
    			e = d._routes,
    			f = !0;
    			if (d._started) {
    				b = h();
    				for (var g in e) if (a = e[g], a["default"]) c = a;
    				else if (a.routeReg.test(b.split(p)[0]) && (f = !1, a.callback(b), a.last)) break;
    				f && c && c.callback(b)
    			}
    		},
    		addRoute: function(a, b, c) {
    			function h(b, d, e) {
    				var f = k._stack.pushState(a, b, d, e);
    				c.callback && c.callback(f),
    				k.trigger(f.move, f)
    			}
    			var i, j, k = this;
    			1 === arguments.length && (c = arguments[0], a = null, b = null),
    			c || (c = {}),
    			c["default"] ? k._routes[a] = {
    				"default": !0,
    				callback: function(a) {
    					var b = f(a.split(p)[1] || "");
    					h(a, {},
    					b)
    				}
    			}: a && b && (b = d(b), i = e(b), j = g(b), k._routes[a] = {
    				routeText: b,
    				routeReg: j,
    				callback: function(a) {
    					var b = a.split(p),
    					c = b[0].match(j).slice(2),
    					d = f(b[1] || ""),
    					e = {};
    					for (var g in i) e[g] = c[i[g]];
    					h(a, e, d)
    				},
    				last: !!c.last
    			})
    		},
    		removeRoute: function(a) {
    			this._routes[a] && delete this._routes[a]
    		},
    		hasRoute: function(a) {
    			return !! this._routes[a]
    		},
    		start: function() {
    			return this._started ? !1 : (this._started = !0, a.addEventListener("hashchange", this, !1), this.handleEvent(), !0)
    		},
    		stop: function() {
    			return this._started ? (this._routes = {},
    			this._stack.reset(), this._started = !1, a.removeEventListener("hashchange", this, !1), !0) : !1
    		},
    		push: function(a, b) {
    			var c = this,
    			d = c._stack,
    			e = d.getState(),
    			f = d.getIndex();
    			if (args = [], a || (a = ""), b || (b = {}), d.move = "forward", d.transition = "forward", /^https?\:/i.test(a)) location.href = a;
    			else if (a) {
    				if (!e || e.fragment !== a || b.data) {
    					if (b.type || (b.type = "GET"), b.data || (b.data = {}), "GET" === b.type.toUpperCase()) for (var g in b.data) args.push(g + "=" + b.data[g]);
    					"POST" === b.type.toUpperCase() && (d.datas = b.data),
    					"backward" === b.transition && (d.transition = "backward"),
    					d.type = b.type.toUpperCase(),
    					i(a + (args.length ? p + args.join("&") : ""))
    				}
    			} else f < d._states.length - 1 && q.forward()
    		},
    		pop: function(a) {
    			var b = this,
    			c = b._stack,
    			d = c.getIndex();
    			0 !== d && (c.move = "backward", c.transition = "backward", a && "forward" === a.transition && (c.transition = "forward"), q.back())
    		},
    		resolve: function(a, b) {
    			var c, d = this._routes[a],
    			e = "";
    			return d && (c = d.routeText, e = c.replace(/\(P<[a-z0-9_-][a-z0-9_-]*?>.*?\)/g,
    			function(a) {
    				o.lastIndex = 0;
    				var c = o.exec(a)[1];
    				return b[c] || "undefined"
    			}).replace("\\/?", "").replace("\\", "")),
    			e
    		}
    	};
    	for (var l in t) j.prototype[l] = t[l];
    	j.instance = new j,
    	b.module.StateStack = c,
    	b.module.Navigation = j
    } (window, window.app || (window.app = {
    	module: {},
    	plugin: {}
    })),
    function(a, b) {
    	function c(a, b) {
    		return b || (b = l),
    		b.querySelector(a)
    	}
    	function d(a, b) {
    		var c = l.createEvent("HTMLEvents");
    		c.initEvent(b, !0, !0),
    		a.dispatchEvent(c)
    	}
    	function e() {
    		if (o) d(window, "scrollend");
    		else {
    			var a = window.scrollY;
    			setTimeout(function() {
    				window.scrollY === a && d(window, "scrollend")
    			},
    			150)
    		}
    	}
    	function f(a, c) {
    		if (a.plugins) for (var d in a.plugins) {
    			var e = b.plugin[d],
    			f = a.plugins[d];
    			f === !0 && (f = a.plugins[d] = {}),
    			e && f && e[c] && e[c](a, f)
    		}
    	}
    	function g(a, c, d) {
    		if (2 === arguments.length && (d = c, c = a, a = null), c.plugins) for (var e in c.plugins) {
    			var f = b.plugin[e],
    			g = c.plugins[e];
    			if (f && g) {
    				if (g === !0 && (g = c.plugins[e] = {}), a) {
    					a.plugins[e] || (a.plugins[e] = {});
    					for (var h in g) null == a.plugins[e][h] && (a.plugins[e][h] = c.plugins[e][h]);
    					g = a.plugins[e]
    				}
    				f[d] && f[d](c, g)
    			}
    		}
    	}
    	function h(a, b, c) {
    		var d = a[b];
    		if ("string" == typeof d) G.on("template:loaded",
    		function(a) {
    			d === a && (G.off("template:loaded", arguments.callee), c && c())
    		});
    		else if ("object" == typeof d) for (var b in d) h(d, b,
    		function() {
    			var a = !0;
    			for (var b in d) if ("function" != typeof d[b]) {
    				a = !1;
    				break
    			}
    			a && c && c()
    		});
    		else c && c()
    	}
    	function i(a, b) {
    		return a.compile(b),
    		function(b) {
    			return a.render(b)
    		}
    	}
    	function j(a, b) {
    		var c = a[b];
    		if ("string" == typeof c) {
    			var d;
    			D[c] ? a[b] = D[c] : c.match(/\.tpl$/g) ? (d = new t, d.load(c,
    			function(e) {
    				a[b] = D[c] = i(d, e),
    				G.trigger("template:loaded", c)
    			})) : (d = new t, a[b] = D[c] = i(d, c))
    		} else if ("object" == typeof c) for (var b in c) j(c, b)
    	}
    	function k() {
    		return s.getStack().getState()
    	}
    	var l = a.document,
    	m = a.$,
    	n = navigator.appVersion,
    	o = /iphone|ipad/gi.test(n),
    	p = b.module,
    	q = p.MessageScope,
    	r = p.Navigation,
    	s = r.instance,
    	t = p.Template,
    	u = p.View,
    	v = p.Page,
    	w = p.Navbar,
    	x = p.Toolbar,
    	y = p.Content,
    	z = p.Scroll,
    	A = (p.Animation, p.Transition),
    	B = {},
    	C = {},
    	D = {},
    	E = {},
    	F = b.config = {
    		viewport: null,
    		templateEngine: null,
    		resourceCombo: null,
    		resourceBase: "./",
    		enableMessageLog: !1,
    		enableContent: !0,
    		enableNavbar: !1,
    		enableToolbar: !1,
    		enableScroll: !1,
    		enableTransition: !1
    	},
    	G = q.get("hooks");
    	G.on("app:start",
    	function() {
    		var a = b.config;
    		w || (a.enableNavbar = !1),
    		x || (a.enableToolbar = !1),
    		z || (a.enableScroll = !1),
    		A || (a.enableTransition = !1),
    		q.isLogging = a.enableMessageLog,
    		a.enableNavbar === !0 && (a.enableNavbar = {}),
    		a.enableToolbar === !0 && (a.enableToolbar = {}),
    		a.enableScroll === !0 && (a.enableScroll = {}),
    		a.enableTransition === !0 && (a.enableTransition = {}),
    		"number" == typeof a.enableContent ? a.enableContent = {
    			cacheLength: a.enableContent
    		}: a.enableContent instanceof HTMLElement ? a.enableContent = {
    			wrapEl: a.enableContent
    		}: "object" != typeof a.enableContent && (a.enableContent = {})
    	}),
    	"onorientationchange" in a && window.addEventListener("onorientationchange",
    	function() {
    		setTimeout(function() {
    			G.trigger("orientaion:change")
    		},
    		10)
    	},
    	!1),
    	window.addEventListener("resize",
    	function() {
    		setTimeout(function() {
    			G.trigger("screen:resize")
    		},
    		10)
    	}),
    	G.on("view:extend",
    	function(a) {
    		var b = a.prototype.render,
    		c = a.prototype.destory;
    		a.prototype.render = function() {
    			var a = this,
    			c = arguments;
    			h(a, "template",
    			function() {
    				G.trigger("view:render", a, arguments),
    				b.apply(a, c)
    			})
    		},
    		a.prototype.destory = function() {
    			G.trigger("view:destory", this, arguments),
    			c.apply(this, arguments)
    		}
    	}),
    	G.on("page:define",
    	function(a) {
    		var b = a.ready,
    		c = a.startup,
    		d = a.teardown,
    		e = a.show,
    		f = a.hide,
    		g = !1,
    		h = !1;
    		a.ready = function(c) {
    			g || (G.trigger("page:ready", c, a), b.call(a), g = !0)
    		},
    		a.startup = function(b) {
    			G.trigger("page:startup", b, a),
    			c.call(a)
    		},
    		a.show = function(b) {
    			G.trigger("page:show", b, a),
    			e.call(a, h),
    			h = !0
    		},
    		a.hide = function(b) {
    			G.trigger("page:hide", b, a),
    			f.call(a, h)
    		},
    		a.teardown = function(b) {
    			G.trigger("page:teardown", b, a),
    			d.call(a),
    			h = !1
    		},
    		a.html = function(a) {
    			this.el.innerHTML = a
    		}
    	}),
    	G.on("page:define page:defineMeta",
    	function(a) {
    		var b = a.name,
    		c = a.route;
    		s.hasRoute(b) || (c ? "string" == typeof c && (c = {
    			name: b,
    			text: c
    		}) : c = {
    			name: b,
    			"default": !0
    		},
    		s.addRoute(c.name, c.text, {
    			"default": c["default"],
    			callback: c.callback,
    			last: c.last
    		}))
    	}),
    	G.on("app:start",
    	function() {
    		var a, b = F.enableNavbar,
    		d = F.enableToolbar,
    		f = F.enableContent,
    		g = F.enableTransition,
    		h = F.enableScroll;
    		F.viewport || (F.viewport = c(".viewport") || l.body),
    		f.wrapEl || (f.wrapEl = c(".content", F.viewport) || F.viewport),
    		f.cacheLength || (f.cacheLength = f.wrapEl === F.viewport ? 1 : 5),
    		a = f.instance = new y(f.wrapEl, {
    			cacheLength: f.cacheLength
    		}),
    		b && (F.viewport.className += " enableNavbar", b.wrapEl || (b.wrapEl = c(".navbar", F.viewport)), b.instance = new w(b.wrapEl)),
    		d && (F.viewport.className += " enableToolbar", d.wrapEl || (d.wrapEl = c(".toolbar", F.viewport)), d.instance = new x(d.wrapEl, d)),
    		h ? (F.viewport.className += " enableScroll", h.wrapEl = a.getActive()) : window.addEventListener("scroll", e, !1),
    		g && (F.viewport.className += " enableTransition", g.wrapEl = a.contentEl)
    	}),
    	G.on("app:start",
    	function() {
    		for (var a in b.plugin) {
    			var c = b.plugin[a];
    			c.onAppStart && c.onAppStart()
    		}
    	}),
    	G.on("view:render",
    	function(a) {
    		f(a, "onViewRender")
    	}),
    	G.on("view:destory",
    	function(a) {
    		f(a, "onViewTeardown")
    	}),
    	G.on("page:define",
    	function(a) {
    		g(a, "onPageDefine")
    	}),
    	G.on("page:startup",
    	function(a, b) {
    		g(a, b, "onPageStartup")
    	}),
    	G.on("page:show",
    	function(a, b) {
    		g(a, b, "onPageShow")
    	}),
    	G.on("page:hide",
    	function(a, b) {
    		g(a, b, "onPageHide")
    	}),
    	G.on("page:teardown",
    	function(a, b) {
    		g(a, b, "onPageTeardown")
    	}),
    	G.once("view:extend page:define",
    	function() {
    		t.engine = F.templateEngine || {}
    	}),
    	G.on("view:extend",
    	function(a) {
    		a.prototype.template && j(a.prototype, "template")
    	}),
    	G.on("page:define",
    	function(a) {
    		a.template && j(a, "template")
    	}),
    	G.on("app:start",
    	function() {
    		function a() {
    			var a = n.pageMeta.title || o.title,
    			c = n.pageMeta.buttons || o.buttons;
    			if (c) for (var d = 0; d < c.length; d++) {
    				var e = c[d],
    				f = e.handler;
    				e.id || (e.id = "btn-" + Date.now()),
    				"string" == typeof f && (f = o[f]),
    				"back" === e.type && (e.hide = e.autoHide !== !1 && n.index < 1, f || (f = function() {
    					b.navigation.pop()
    				})),
    				e.handler = function(a) {
    					return function(b) {
    						a && a.call(o, b, n.index)
    					}
    				} (f)
    			} else c = [{
    				id: "back",
    				type: "back",
    				text: "back",
    				hide: n.index < 1 ? !0 : !1,
    				handler: function() {
    					b.navigation.pop()
    				}
    			}];
    			if (D || !q) {
    				b.navigation.resetNavbar(),
    				b.navigation.setTitle(a);
    				for (var d = 0; d < c.length; d++) b.navigation.setButton(c[d])
    			} else b.navigation.switchNavbar(a, n.transition, c)
    		}
    		function c() {
    			if (t) {
    				var a = t.instance,
    				c = n.pageMeta.toolbar || o.toolbar;
    				t.wrapEl.innerHTML = "",
    				"number" == typeof c && (c = {
    					height: c
    				}),
    				c ? (b.navigation.setToolbar(c), a.show()) : a.hide()
    			}
    		}
    		function d() {
    			D || ("backward" === n.move ? w.previous() : w.next())
    		}
    		function e() {
    			var a = y ? F.viewport.offsetHeight: window.innerHeight;
    			r && (a -= r.wrapEl.offsetHeight),
    			t && (a -= t.wrapEl.offsetHeight),
    			y ? u.wrapEl.style.height = a + "px": (u.wrapEl.style.minHeight = a - 44 - 98 + "px", u.instance.getActive().style.minHeight = a - 44 - 98 + "px")
    		}
    		function f() { ! D && y && (z.disable(y.wrapEl), y.wrapEl = w.getActive(), z.enable(y.wrapEl, o.scroll))
    		}
    		function g() {
    			if (D) G.trigger("navigation:switchend", n);
    			else {
    				var a = n.transition;
    				if (x && q) {
    					var b = x.wrapEl,
    					c = w.transEl,
    					d = w.transShadeEl,
    					e = b.getBoundingClientRect().width,
    					f = e * ("backward" === a ? 1 : -1),
    					g = b.className += " " + a;
    					d.style["backward" === a ? "right": "left"] = e + "px",
    					c.style.display = "block",
    					A.move(d, f, 0,
    					function() {
    						w.setClassName(),
    						b.className = g.replace(" " + a, ""),
    						d.style.cssText = "",
    						c.style.cssText = "",
    						G.trigger("navigation:switchend", n)
    					})
    				} else w.setClassName(),
    				G.trigger("navigation:switchend", n)
    			}
    		}
    		function i(a) {
    			for (var c in b.plugin) {
    				var d = b.plugin[c];
    				d && (n.plugins[c] || (n.plugins[c] = {}), d[a] && d[a](n.plugins[c]))
    			}
    		}
    		function j() {
    			var a; (a = C[n.name]) && (a.css && b.loadResource(a.css, "css"), a.js && b.loadResource(a.js, "js",
    			function() {
    				o = v.get(n.name),
    				o && (o.ready(), k())
    			}))
    		}
    		function k() {
    			o.el = w.getActive(),
    			m && (o.$el = m(o.el)),
    			a(),
    			c(),
    			f(),
    			g(),
    			h(o, "template", l)
    		}
    		function l() {
    			q && q.hide(p);
    			var a = o.el.getAttribute("data-fragment"),
    			b = B[a];
    			a === n.fragment ? o.show(n) : (b && (b.page.teardown(b.state), delete B[a]), B[n.fragment] = {
    				state: n,
    				page: o
    			},
    			o.el.innerHTML = "", o.el.setAttribute("data-fragment", n.fragment), o.startup(n), o.show(n)),
    			p = n,
    			q = o
    		}
    		var n, o, p, q, r = F.enableNavbar,
    		t = F.enableToolbar,
    		u = F.enableContent,
    		w = u.instance,
    		x = F.enableTransition,
    		y = F.enableScroll,
    		D = !1;
    		s.on("forward backward",
    		function() {
    			n = arguments[0],
    			n.pageMeta || (n.pageMeta = {}),
    			n.plugins || (n.plugins = {}),
    			o = v.get(n.name),
    			D = p && p.name === n.name,
    			G.trigger("navigation:switch", n),
    			o ? k() : j()
    		}),
    		G.on("navigation:switch",
    		function() {
    			d(),
    			i("onNavigationSwitch")
    		}),
    		G.on("navigation:switchend",
    		function() {
    			e(),
    			i("onNavigationSwitchEnd")
    		}),
    		G.after("page:show navigation:switchend",
    		function() {
    			i("onDomReady")
    		}),
    		G.on("orientaion:change screen:resize",
    		function() {
    			e()
    		})
    	}),
    	b.start = function(a) {
    		for (var c in a) b.config[c] = a[c];
    		G.trigger("app:start"),
    		s.start()
    	},
    	b.setTemplate = function(a, b) {
    		"string" == typeof b ? D[a] = i(new t, b) : "function" == typeof b && (D[a] = b)
    	},
    	b.extendView = function(a) {
    		var b = u.extend(a);
    		return G.trigger("view:extend", b),
    		b
    	},
    	b.getView = function(a) {
    		var b = u.get(a);
    		if (b) {
    			var c = Object.create(b.prototype),
    			d = Array.prototype.slice.call(arguments, 1);
    			return b.apply(c, d),
    			c
    		}
    	},
    	b.definePage = function(a) {
    		var b = v.define(a);
    		return G.trigger("page:define", b),
    		b
    	},
    	b.definePageMeta = function(a) {
    		a instanceof Array || (a = [a]),
    		a.forEach(function(a) {
    			C[a.name] = a,
    			G.trigger("page:defineMeta", a)
    		})
    	},
    	b.getPage = function(a) {
    		return v.get(a)
    	};
    	var H = document.createElement("a");
    	b.loadResource = function(a, c, d) {
    		function e() {
    			return "resource-" + Date.now() + "-" + Object.keys(E).length
    		}
    		function f(a) {
    			return 0 === a.indexOf("http") ? a: b.config.resourceBase + a
    		}
    		function g(a, b) {
    			if (!a) return b();
    			if (a = H.href = f(a), "string" == typeof E[a]) return b();
    			var d = E[a] = e();
    			if ("js" === c || a.match(/\.js$/)) {
    				var g = document.createElement("script"),
    				h = !1;
    				g.id = d,
    				g.async = !0,
    				g.onload = g.onreadystatechange = function() {
    					h || (h = !0, b && b(a))
    				},
    				g.src = a,
    				l.body.appendChild(g)
    			} else if ("css" === c || a.match(/\.css$/)) {
    				var i = document.createElement("link");
    				i.id = d,
    				i.type = "text/css",
    				i.rel = "stylesheet",
    				i.href = a,
    				l.body.appendChild(i),
    				b()
    			}
    		}
    		2 === arguments.length && "function" == typeof arguments[1] && (d = arguments[1], c = null),
    		"string" == typeof a && (a = [a]);
    		var h = [],
    		i = F.resourceCombo;
    		a.forEach(function(a) {
    			H.href = f(a),
    			E[H.href] || (E[H.href] = !0, h.push(a))
    		}),
    		i && (h = i(h), "string" == typeof h && (h = [h])),
    		g(h.shift(),
    		function() {
    			h.length ? g(h.shift(), arguments.callee) : d && d()
    		})
    	},
    	b.navigation = {
    		push: function(a, b) {
    			s.push(a, b)
    		},
    		pop: function() {
    			s.pop()
    		},
    		resolveFragment: function(a, b) {
    			return s.resolve(a, b)
    		},
    		getReferer: function() {
    			return k().referer
    		},
    		getParameter: function(a) {
    			var b = k();
    			return b.params[a] || b.datas[a]
    		},
    		getParameters: function() {
    			var a = k(),
    			b = {};
    			for (var c in a.params) b[c] = a.params[c];
    			for (var c in a.datas) b[c] = a.datas[c];
    			return b
    		},
    		setData: function(a, b) {
    			k().datas[a] = b
    		},
    		setTitle: function(a) {
    			var b = k();
    			F.enableNavbar && F.enableNavbar.instance.setTitle(a),
    			b.pageMeta.title = a
    		},
    		setButton: function(a) {
    			if (a instanceof Array) for (var b = 0; b < a.length; b++) this.setButton(a[b]);
    			else {
    				var c = k();
    				if (F.enableNavbar && F.enableNavbar.instance.setButton(a), c.pageMeta.buttons) {
    					for (var b = 0; b < c.pageMeta.buttons.length; b++) {
    						var d = c.pageMeta.buttons[b];
    						if ("back" === d.type && "back" === a.type || d.id === a.id) {
    							for (var e in a) d[e] = a[e];
    							return
    						}
    					}
    					c.pageMeta.buttons.push(a)
    				} else c.pageMeta.buttons = [a]
    			}
    		},
    		switchNavbar: function(a, b, c) {
    			if (F.enableNavbar) {
    				this.resetNavbar(),
    				this.setTitle(a);
    				for (var d = 0; d < c.length; d++) this.setButton(c[d]);
    				A.float(F.enableNavbar.instance.animWrapEl, "backward" === b ? "LI": "RI", 50)
    			}
    		},
    		resetNavbar: function() {
    			var a = k();
    			F.enableNavbar && F.enableNavbar.instance.removeButton(),
    			a.pageMeta.buttons = []
    		},
    		setToolbar: function(a) {
    			var b = k();
    			F.enableToolbar && F.enableToolbar.instance.set(a),
    			b.pageMeta.toolbar = a
    		}
    	},
    	b.scroll = {
    		getScrollHeight: function() {
    			var a = F.enableScroll;
    			return a ? z.getScrollHeight(a.wrapEl) : l.body.scrollHeight
    		},
    		getScrollTop: function() {
    			var a = F.enableScroll;
    			return a ? z.getScrollTop(a.wrapEl) : l.body.scrollTop
    		},
    		refresh: function() {
    			var a = F.enableScroll;
    			a && z.refresh(a.wrapEl)
    		},
    		offset: function(a) {
    			var b = F.enableScroll;
    			return b ? z.offset(b.wrapEl, a) : z.offset(l.body, a)
    		},
    		scrollTo: function(a) {
    			var b = F.enableScroll;
    			b ? z.scrollTo(b.wrapEl, a) : l.body.scrollTop = a
    		},
    		scrollToElement: function(a) {
    			var b = F.enableScroll;
    			b ? z.scrollToElement(b.wrapEl, a) : a.scrollIntoView()
    		},
    		getViewHeight: function() {
    			var a = F.enableScroll;
    			return a ? z.getViewHeight(a.wrapEl) : window.innerHeight
    		},
    		getBoundaryOffset: function() {
    			var a = F.enableScroll;
    			return a ? z.getBoundaryOffset(a.wrapEl) : 0
    		},
    		stopBounce: function() {
    			var a = F.enableScroll;
    			a && z.stopBounce(a.wrapEl)
    		},
    		resumeBounce: function() {
    			var a = F.enableScroll;
    			a && z.resumeBounce(a.wrapEl)
    		},
    		addEventListener: function(a, b, c) {
    			var d = F.enableScroll,
    			e = (F.enableContent.instance, d ? d.wrapEl: window);
    			e.addEventListener(a, b, c)
    		},
    		removeEventListener: function(a, b) {
    			var c = F.enableScroll,
    			d = (F.enableContent.instance, c ? c.wrapEl: window);
    			d.removeEventListener(a, b)
    		},
    		getElement: function() {
    			var a = F.enableScroll;
    			return a ? a.wrapEl: l.body
    		}
    	}
    } (window, window.app || (window.app = {
    	module: {},
    	plugin: {}
    })),
    function(a, b) {
    	var c, d, e, f = a.document,
    	g = (b.config, []);
    	b.plugin.loading = {
    		show: function(a) {
    			if (a && (e.innerHTML = a), "block" !== d.style.display) {
    				d.style.display = "block";
    				var b = document.body.getBoundingClientRect(),
    				c = e.getBoundingClientRect();
    				e.style.left = (b.width - c.width) / 2 + "px",
    				e.style.top = (window.innerHeight - c.height) / 2 - b.top + "px"
    			}
    			var f = Date.now();
    			return g.push(f),
    			f
    		},
    		hide: function(a) {
    			a ? g.splice(g.indexOf(a), 1) : g = [],
    			0 === g.length && (e.innerHTML = "", d.style.display = "none")
    		},
    		onAppStart: function() {
    			d = document.createElement("div"),
    			d.className = "loading",
    			d.style.cssText = ["display: none", "background: transparent", "position: absolute", "width: 100%", "height: 100%", "left: 0", "top: 0", "overflow: hidden", "z-index: 99999"].join(";"),
    			e = document.createElement("div"),
    			e.style.cssText = ["position:absolute", "width: 100px", "height: 90px", "line-height: 100px", "background: url(//assets.alicdn.com/mw/base/styles/component/more/images/loading.gif) no-repeat 20px 35px", "text-align: center", "", "height:" + k + "px", "z-index:999999", "position:absolute", "left:0", "top:0px", "background:#FFF", "display:none"].join(";");
    		var l = document.createElement("div");
    		l.style.cssText = ["width:100%", "height:52px", "background:#EEE", "line-height:52px", "text-align:left", "box-sizing:border-box", "padding-left:20px", "position:absolute", "left:0", "top:0", "", "font-weight:bold", "color:#333"].join(";"),
    		l.innerText = b;
    		var m = document.createElement("a");
    		m.style.cssText = ["display:block", "position:absolute", "right:0", "top:0", "height:52px", "line-height:52px", "padding:0 20px", "color:#999"].join(";"),
    		m.innerText = "关闭";
    		var n = document.createElement("iframe");
    		n.style.cssText = ["width:100%", "height:100%", "border:0", "overflow:hidden"].join(";"),
    		l.appendChild(m),
    		h.appendChild(l),
    		h.appendChild(n),
    		g.body.appendChild(h),
    		n.src = d,
    		m.addEventListener("click",
    		function() {
    			e.hide();
    			var a = g.createEvent("HTMLEvents");
    			a.initEvent("close", !1, !1),
    			h.dispatchEvent(a)
    		},
    		!1),
    		this.addEventListener = function() {
    			h.addEventListener.apply(h, arguments)
    		},
    		this.removeEventListener = function() {
    			h.removeEventListener.apply(h, arguments)
    		},
    		this.show = function() {
    			document.addEventListener("touchmove", c, !1),
    			h.style.display = "block",
    			window.scrollTo(0, 0)
    		},
    		this.hide = function() {
    			document.removeEventListener("touchmove", c),
    			window.scrollTo(0, -i.top),
    			g.body.removeChild(h)
    		}
    	}
    	function e(a, b) {
    		this.request = a,
    		this.response = b;
    		var c = 0,
    		d = {};
    		this.on = function(a, b) {
    			d[a] = b
    		},
    		this.next = function() {
    			var b = m[c++];
    			b ? a[b.__name__] ? b(this) : this.next() : this.end()
    		},
    		this.reset = function() {
    			c = 0,
    			d.reset && d.reset.call(this)
    		},
    		this.end = function() {
    			d.end && d.end.call(this)
    		}
    	}
    	function f(a, b) {
    		b.__name__ = a,
    		m.push(b)
    	}
    	var g = a.document,
    	h = a.navigator.userAgent,
    	i = h.match(/WindVane[\/\s]([\d\.\_]+)/);
    	i && (i = i[1]);
    	var j, k, l = h.match(/AliApp\(([^\/]+)\/([\d\.\_]+)\)/i);
    	l && (j = l[1], k = l[2]),
    	b.mtop = b.mtop || {},
    	b.mtop.middleware = {};
    	var m = [];
    	b.mtop.middleware.pipe = function(a, b) {
    		return new e(a, b)
    	},
    	b.mtop.middleware.add = f,
    	f("LoginRequest",
    	function(a) {
    		function c() {
    			a.reset()
    		}
    		function d() {
    			a.response && a.response.ret.push("MW_ERROR::LOGIN_FAILURE"),
    			a.end()
    		}
    		function e() {
    			a.response && a.response.ret.push("MW_ERROR::WIDGET_CANCEL"),
    			a.end()
    		}
    		var f = (a.response && a.response.ret || []).join(",");
    		f.indexOf("SESSION_EXPIRED") > -1 || f.indexOf("SID_INVALID") > -1 || f.indexOf("AUTH_REJECT") > -1 || f.indexOf("NEED_LOGIN") > -1 ? b.login.goLogin(function(a) {
    			"SUCCESS" === a ? c() : "CANCEL" === a ? e() : d()
    		}) : a.next()
    	}),
    	f("AntiCreep",
    	function(b) {
    		function c() {
    			h.removeEventListener("close", c),
    			a.removeEventListener("message", e),
    			b.response && b.response.ret.push("MW_ERROR::WIDGET_CANCEL"),
    			b.end()
    		}
    		function e() {
    			h.removeEventListener("close", c),
    			a.removeEventListener("message", e);
    			var d = JSON.parse(g.data) || {};
    			if (d && "child" === d.type) {
    				var f;
    				try {
    					f = JSON.parse(decodeURIComponent(d.content)),
    					"string" == typeof f && (f = JSON.parse(f))
    				} catch(g) {
    					f = null
    				}
    				if (f) {
    					for (var i in f) b.request[i] = f[i];
    					b.reset()
    				} else b.response && b.response.ret.push("MW_ERROR::SM_FAILURE"),
    				b.end();
    				h.hide()
    			} else b.end()
    		}
    		var f = (b.response && b.response.ret || []).join(",");
    		if (!l && f.indexOf("RGV587_ERROR::SM") > -1 && b.response.data.url) {
    			var g = b.response.data.url,
    			h = new d("", g);
    			h.addEventListener("close", c, !1),
    			a.addEventListener("message", e, !1),
    			h.show()
    		} else b.next()
    	}),
    	f("AntiFlood",
    	function(a) {
    		var b = (a.response && a.response.ret || []).join(",");
    		if (!l && b.indexOf("FAIL_SYS_USER_VALIDATE") > -1 && a.response.data.url) {
    			var c = a.response.data.url;
    			location.href = c
    		} else a.next()
    	})
    } (window, window.lib || (window.lib = {})),
    function(a, b, c) {
    	function d(a) {
    		var b = new RegExp("(?:^|;\\s*)" + a + "\\=([^;]+)(?:;\\s*|$)").exec(u.cookie);
    		return b ? b[1] : c
    	}
    	function e(a) {
    		return a.preventDefault(),
    		!1
    	}
    	function f(b, c) {
    		var d = this,
    		f = a.dpr || 1,
    		g = document.createElement("div"),
    		h = document.documentElement.getBoundingClientRect(),
    		i = Math.max(h.width, window.innerWidth) / f,
    		j = Math.max(h.height, window.innerHeight) / f;
    		g.style.cssText = ["-webkit-transform:scale(" + f + ") translateZ(0)", "-ms-transform:scale(" + f + ") translateZ(0)", "transform:scale(" + f + ") translateZ(0)", "-webkit-transform-origin:0 0", "-ms-transform-origin:0 0", "transform-origin:0 0", "width:" + i + "px", "height:" + j + "px", "z-index:999999", "position:absolute", "left:0", "top:0px", "background:#FFF", "display:none"].join(";");
    		var k = document.createElement("div");
    		k.style.cssText = ["width:100%", "height:52px", "background:#EEE", "line-height:52px", "text-align:left", "box-sizing:border-box", "padding-left:20px", "position:absolute", "left:0", "top:0", "", "font-weight:bold", "color:#333"].join(";"),
    		k.innerText = b;
    		var l = document.createElement("a");
    		l.style.cssText = ["display:block", "position:absolute", "right:0", "top:0", "height:52px", "line-height:52px", "padding:0 20px", "color:#999"].join(";"),
    		l.innerText = "关闭";
    		var m = document.createElement("iframe");
    		m.style.cssText = ["width:100%", "height:100%", "border:0", "overflow:hidden"].join(";"),
    		k.appendChild(l),
    		g.appendChild(k),
    		g.appendChild(m),
    		u.body.appendChild(g),
    		m.src = c,
    		l.addEventListener("click",
    		function() {
    			d.hide();
    			var a = u.createEvent("HTMLEvents");
    			a.initEvent("close", !1, !1),
    			g.dispatchEvent(a)
    		},
    		!1),
    		this.addEventListener = function() {
    			g.addEventListener.apply(g, arguments)
    		},
    		this.removeEventListener = function() {
    			g.removeEventListener.apply(g, arguments)
    		},
    		this.show = function() {
    			document.addEventListener("touchmove", e, !1),
    			g.style.display = "block",
    			window.scrollTo(0, 0)
    		},
    		this.hide = function() {
    			document.removeEventListener("touchmove", e),
    			window.scrollTo(0, -h.top),
    			u.body.removeChild(g)
    		}
    	}
    	function g(a) {
    		if (!a || "function" != typeof a || !b.mtop) {
    			var d = this.getUserNick();
    			return !! d
    		}
    		b.mtop.request({
    			api: "mtop.user.getUserSimple",
    			v: "1.0",
    			data: {
    				isSec: 0
    			},
    			H5Request: !0
    		},
    		function(d) {
    			d.retType === b.mtop.RESPONSE_TYPE.SUCCESS ? a(!0, d) : d.retType === b.mtop.RESPONSE_TYPE.SESSION_EXPIRED ? a(!1, d) : a(c, d)
    		})
    	}
    	function h(a) {
    		var c;
    		return b.promise && (c = b.promise.defer()),
    		this.isLogin(function(b, d) {
    			a && a(b, d),
    			b === !0 ? c.resolve(d) : c.reject(d)
    		}),
    		c ? c.promise: void 0
    	}
    	function i(a) {
    		if (!a || "function" != typeof a) {
    			var b = "",
    			e = d("_w_tb_nick"),
    			f = d("_nk_") || d("snk");
    			return e && e.length > 0 && "null" != e ? b = decodeURIComponent(e) : f && f.length > 0 && "null" != f && (b = unescape(unescape(f).replace(/\\u/g, "%u"))),
    			b = b.replace(/\</g, "<").replace(/\>/g, ">")
    		}
    		this.isLogin(function(b, d) {
    			a(b === !0 && d && d.data && d.data.nick ? d.data.nick: b === !1 ? "": c)
    		})
    	}
    	function j(a) {
    		var c;
    		return b.promise && (c = b.promise.defer()),
    		this.getUserNick(function(b) {
    			a && a(b),
    			b ? c.resolve(b) : c.reject()
    		}),
    		c ? c.promise: void 0
    	}
    	function k(a, b) {
    		var c = "//" + F + "." + G.subDomain + "." + D + "/" + G[(a || "login") + "Name"];
    		if (b) {
    			var d = [];
    			for (var e in b) d.push(e + "=" + encodeURIComponent(b[e]));
    			c += "?" + d.join("&")
    		}
    		return c
    	}
    	function l(a, b) {
    		if (b) location.replace(a);
    		else {
    			var c = u.createElement("a"),
    			d = u.createEvent("HTMLEvents");
    			c.style.display = "none",
    			c.href = a,
    			u.body.appendChild(c),
    			d.initEvent("click", !1, !0),
    			c.dispatchEvent(d)
    		}
    	}
    	function m(b, c, d) {
    		function e() {
    			j.removeEventListener("close", e),
    			a.removeEventListener("message", g),
    			d("CANCEL")
    		}
    		function g(b) {
    			j.removeEventListener("close", e),
    			a.removeEventListener("message", g),
    			j.hide();
    			var c = b.data || {};
    			d(c && "child" === c.type && c.content.indexOf("SUCCESS") > -1 ? "SUCCESS": "FAILURE")
    		}
    		var h = location.protocol + "//h5." + G.subDomain + ".taobao.com/" + ("waptest" === G.subDomain ? "src": "other") + "/" + b + "end.html?origin=" + encodeURIComponent(location.protocol + "//" + location.hostname),
    		i = k(b, {
    			ttid: "h5@iframe",
    			tpl_redirect_url: h
    		}),
    		j = new f(c.title || "您需要登录才能继续访问", i);
    		j.addEventListener("close", e, !1),
    		a.addEventListener("message", g, !1),
    		j.show()
    	}
    	function n(b, c, d) {
    		var e = k(b, {
    			wvLoginCallback: "wvLoginCallback"
    		});
    		a.wvLoginCallback = function(b) {
    			delete a.wvLoginCallback,
    			d(b.indexOf(":SUCCESS") > -1 ? "SUCCESS": b.indexOf(":CANCEL") > -1 ? "CANCEL": "FAILURE")
    		},
    		l(e)
    	}
    	function o(a, b, c) {
    		if ("function" == typeof b ? (c = b, b = null) : "string" == typeof b && (b = {
    			redirectUrl: b
    		}), b = b || {},
    		c && z) n(a, b, c);
    		else if (c && !y && "login" === a) m(a, b, c);
    		else {
    			var d = k(a, {
    				tpl_redirect_url: b.redirectUrl || location.href
    			});
    			l(d, b.replace)
    		}
    	}
    	function p(a, c, d) {
    		var e;
    		return b.promise && (e = b.promise.defer()),
    		o(a, c,
    		function(a) {
    			d && d(a),
    			"SUCCESS" === a ? e.resolve(a) : e.reject(a)
    		}),
    		e ? e.promise: void 0
    	}
    	function q(a) {
    		o("login", a)
    	}
    	function r(a) {
    		return p("login", a)
    	}
    	function s(a) {
    		o("logout", a)
    	}
    	function t(a) {
    		return p("logout", a)
    	}
    	var u = a.document,
    	v = a.navigator.userAgent,
    	w = location.hostname,
    	x = (a.location.search, v.match(/WindVane[\/\s]([\d\.\_]+)/)),
    	y = v.match(/AliApp\(([^\/]+)\/([\d\.\_]+)\)/i),
    	z = !!(y && "TB" === y[1] && x && parseFloat(x[1]) > 5.2),
    	A = ["taobao.net", "taobao.com"],
    	B = new RegExp("([^.]*?)\\.?((?:" + A.join(")|(?:").replace(/\./g, "\\.") + "))", "i"),
    	C = w.match(B) || [],
    	D = function() {
    		var a = C[2] || "taobao.com";
    		return a.match(/\.?taobao\.net$/) ? "taobao.net": "taobao.com"
    	} (),
    	E = function() {
    		var a = D,
    		b = C[1] || "m";
    		return "taobao.net" === a && (b = "waptest"),
    		b
    	} (),
    	F = "login";
    	b.login = b.login || {};
    	var G = {
    		loginName: "login.htm",
    		logoutName: "logout.htm",
    		subDomain: E
    	};
    	b.login.config = G,
    	b.login.isLogin = g,
    	b.login.isLoginAsync = h,
    	b.login.getUserNick = i,
    	b.login.getUserNickAsync = j,
    	b.login.generateUrl = k,
    	b.login.goLogin = q,
    	b.login.goLoginAsync = r,
    	b.login.goLogout = s,
    	b.login.goLogoutAsync = t
    } (window, window.lib || (window.lib = {})),
    function(a, b) {
    	var c = b.login,
    	d = function(a, b) {
    		b = b || "http://www.taobao.com/index.php?from=wap";
    		var c = "";
    		return c += '<footer class="footer c-footer "><section class="footer-t c-footer-t"><p class="user-info c-user-info">',
    		c += a.isLogin ? '<span><a class="user-login" href="' + a.myTaobaoUrl + '">' + a.nick + '</a></span><span><a id="J_footer_logout" href="' + a.loginOut + '">退出</a></span>': '<span><a href="' + a.loginUrl + '">登录</a></span><span><a href="' + a.registerUrl + '">注册</a></span>',
    		c += '</p><p class="gotop c-gotop"><a id="J_GoTop" href="javascript:(app&&app.scroll)? app.scroll.scrollTo(0):scroll(0,0)">top<b> </b></a></p></section>',
    		c += '<nav class="footer-l c-footer-l">',
    		c += '<a href="' + b + '" target="_blank">电脑版</a>',
    		c += '<a id="J_imgViewType" href="javascript:void(0)" class="J_dps" data-dps="hdedition%23h%23" style="display:none;"></a></nav>',
    		c += '<p class="copyright c-copyright">© 2014 浙B2-20080224<a class="cr-sv c-cr-sv" href="http://service.taobao.com/support/helpWap.htm" id="J_service">服务中心</a></p></footer>'
    	},
    	e = function() {
    		var a = {},
    		b = location.href.replace(/sid=[0-9a-z]+&?/g, "");
    		return c.isLogin() ? (a.isLogin = !0, a.nick = c.getUserNick(), a.myTaobaoUrl = "http://h5." + c.config.subDomain + ".taobao.com/awp/mtb/mtb.htm#!/awp/mtb/mtb.htm", a.loginOut = "http://login." + c.config.subDomain + ".taobao.com/logout.htm?tpl_redirect_url=" + encodeURIComponent(b)) : (a.isLogin = !1, a.loginUrl = "http://login." + c.config.subDomain + ".taobao.com/login.htm?tpl_redirect_url=" + encodeURIComponent(b), a.registerUrl = "http://u." + c.config.subDomain + ".taobao.com/reg/newUser.htm?tpl_redirect_url=" + encodeURIComponent(b)),
    		a
    	};
    	b.bottom || (b.bottom = {}),
    	b.bottom.render = function(a) {
    		var b = e();
    		return d(b, a)
    	},
    	b.bottom.footer = {
    		getFooterTemplate: function(a) {
    			var b = e();
    			return d(b, a)
    		}
    	}
    } (window, window.lib || (window.lib = {})),
    function(a) {
    	var b = {
    		sysType: "m",
    		defaultAppKey: "12574478"
    	};
    	"localhost" === window.location.host || window.location.host.match(".*\\waptest\\.(taobao|tmall|etao|alibaba|alipay|aliyun)\\.com.*") ? (b.sysType = "waptest", b.defaultAppKey = "4272") : window.location.host.match(".*\\wapa\\.(taobao|tmall|etao|alibaba|alipay|aliyun)\\.com.*") ? b.sysType = "wapa": window.location.host.match(".*\\m\\.(taobao|tmall|etao|alibaba|alipay|aliyun)\\.com.*") && (b.sysType = "m"),
    	a.config = b
    } (window.lib || (window.lib = {})),
    function(a) {
    	var b = {},
    	c = a.config,
    	d = {
    		protocol: "http://",
    		sysType: c.sysType,
    		defaultDomain: "taobao.com"
    	},
    	e = function(a) {
    		try {
    			return decodeURIComponent(a)
    		} catch(b) {
    			return a
    		}
    	},
    	f = b.getParam = function(a) {
    		var b, c = this.queryMap ||
    		function(a) {
    			if (a.length < 1) return "";
    			a = a.substr(1);
    			var b, c, d = a.split("&"),
    			f = {};
    			for (c in d) b = d[c].split("="),
    			f[e(b[0])] = e(b[1]);
    			return f
    		} (location.search);
    		return this.queryMap = c,
    		a ? (b = c[a], b && b.indexOf("#") > -1 && (b = encodeURIComponent(b)), b) : c
    	},
    	g = function(a) {
    		var b, c, d, e = "";
    		for (b in a) c = a[b],
    		d = f(c),
    		d && "" !== d && (e += "&" + c + "=" + d);
    		return e
    	} (["ttid", "sprefer"]);
    	b.getUrl = function(a) {
    		function b(a, b) {
    			if (!b) return a;
    			a.indexOf("?") < 0 && (a += "?");
    			var c = a.charAt(a.length - 1),
    			d = b.charAt(0);
    			return "?" === c || "&" === c ? "?" === d || "&" === d ? a + b.substr(1) : a + b: "?" === d || "&" === d ? a + b: a + "&" + b
    		}
    		var c = a.url ||
    		function(b) {
    			var c = a.host || a.subdomain + "." + b.sysType + "." + b.defaultDomain;
    			return b.protocol + c + "/" + a.path
    		} (d);
    		return c.indexOf("?") > 0 || (c += "?"),
    		c = b(c, g),
    		a.data && (c = b(c,
    		function(a) {
    			var b, c, d = "";
    			if (null == a) return d;
    			for (b in a) c = a[b],
    			null != c && "" !== c && (d += b + "=" + encodeURIComponent("object" == typeof c ? JSON.stringify(c) : c) + "&");
    			return "" !== d && d.length - 1 === d.lastIndexOf("&") && (d = d.substr(0, d.length - 1)),
    			d
    		} (a.data))),
    		c
    	},
    	a.uri = b
    } (window.lib || (window.lib = {})),
    function(a, b) {
    	function c(a, c) {
    		if (a) {
    			var d = b(a);
    			if (!d.length) throw new Error("dom not find");
    			this.$container = d,
    			this.init(c || {})
    		}
    	}
    	c.prototype = {
    		init: function(a) {
    			var c = {
    				index: 1,
    				pageCount: null,
    				preFix: "!page/",
    				objId: "Z",
    				disableHash: null
    			};
    			b.extend(this, c, a),
    			this.pageCount || (this.disableHash = !0),
    			this.oldIndex = -1;
    			var d = this.preFix,
    			e = d.length;
    			"/" != d.charAt(e - 1) && (this.preFix += "/"),
    			isNaN(this.index) && (this.index = 1),
    			this.pageCount && this.index > this.pageCount && (this.index = this.pageCount),
    			this.index <= 0 && (this.index = 1),
    			this.createDom(),
    			this.eventAttach(),
    			!this.disableHash && this.parseHash(),
    			this.renderPage()
    		},
    		setIndex: function(a) {
    			var b = this;
    			b.$select && (a = Number(a), isNaN(a) && (a = 1), a > b.pageCount && (a = b.pageCount), 0 >= a && (a = 1), b.index = a, b.renderPage())
    		},
    		setCount: function(a) {
    			a && (this.pageCount = this.index = a, this.renderPage())
    		},
    		parseHash: function() {
    			var a = this,
    			b = location.hash,
    			c = b.substr(b.lastIndexOf("/") + 1),
    			d = [],
    			e = 0,
    			f = [];
    			d = c.split("-");
    			for (var g = 0; g < d.length; g++) {
    				f = d[g].split("");
    				var h = f.shift();
    				h == this.objId && (e = Number(f.join("")), (isNaN(e) || 0 >= e) && (a.index = 1), e > a.pageCount && (a.index = a.pageCount), a.index = e)
    			}
    		},
    		setContainer: function(a) {
    			this.$container = b(a)
    		},
    		getObjId: function() {
    			return this.objId
    		},
    		pContainer: function() {
    			return this.$container
    		},
    		changeHash: function() {
    			var a = this,
    			b = location.hash;
    			if ("" == b) location.hash = a.preFix + "-" + a.objId + a.index;
    			else {
    				var c = b.lastIndexOf(a.objId),
    				d = c;
    				if ( - 1 == c) location.hash += "-" + a.objId + a.index;
    				else {
    					for (;;) if (d++, "-" == b[d] || !b[d]) break;
    					b = b.replace(b.substring(c, d), a.objId + a.index),
    					location.hash = b
    				}
    			}
    		},
    		createDom: function() {
    			var a = this,
    			b = a.$container,
    			c = a.pageCount,
    			d = c && '<i class="aw a-d"></i>' || "",
    			e = c && '<select class="c-p-select"></select>' || "",
    			f = ['<section class="c-p-con">', '<a class="c-btn c-btn-aw c-p-pre"><span>上一页</span></a>', '<div class="c-p-cur c-btn"><span>', '<div class="c-p-arrow">', "<span></span>", d, "</div>", e, "</span></div>", '<a class="c-btn c-btn-awr c-p-next"><span>下一页</span></a>', "</section>"];
    			if (b.html(f.join("")), c) {
    				e = a.$select || (a.$select = b.find("select")),
    				f = new Array(c);
    				for (var g = 1; c >= g; g++) f[g - 1] = "<option>第" + g + "页</option>";
    				e.append(f.join(""))
    			}
    		},
    		renderPage: function(a) {
    			var c = this,
    			d = c.$container,
    			e = c.$select,
    			f = c.pageCount,
    			g = c.index,
    			h = b(".c-p-pre", d),
    			i = b(".c-p-next", d);
    			f ? (1 >= f ? (h.addClass("c-btn-off"), i.addClass("c-btn-off"), c.pageCount = 1) : 1 == g ? (h.addClass("c-btn-off"), f > 1 && i.removeClass("c-btn-off")) : g == f ? (i.addClass("c-btn-off"), f > 1 && h.removeClass("c-btn-off")) : g > 1 && f > g && (h.removeClass("c-btn-off"), i.removeClass("c-btn-off")), e && (e.get(0).selectedIndex = g - 1)) : ("end" == a && (g--, i.addClass("c-btn-off"), c.pageCount = c.index = g), 1 >= g ? h.addClass("c-btn-off") : h.removeClass("c-btn-off"));
    			var j = g + "/" + f;
    			e || (j = "第 " + g + " 页"),
    			b(".c-p-arrow span", d).text(j)
    		},
    		eventDetach: function() {
    			var a = this,
    			b = a.$container,
    			c = a.$select;
    			c && c.off(),
    			b.off("click"),
    			a.$select = null,
    			a.$arrow = null
    		},
    		eventAttach: function() {
    			var a = this,
    			c = a.$container,
    			d = a.$select,
    			e = a.$arrow || (a.$arrow = b(".c-p-arrow i"));
    			commonFunc = function(b) {
    				a.triggerEvent(b)
    			},
    			d && d.on({
    				mousedown: function() {
    					e.addClass("a-u")
    				},
    				blur: function() {
    					e.removeClass("a-u")
    				},
    				change: commonFunc
    			}),
    			c.on("click", ".c-p-pre", commonFunc),
    			c.on("click", ".c-p-next", commonFunc)
    		},
    		triggerEvent: function(a) {
    			a.preventDefault();
    			var c = this,
    			d = a.currentTarget,
    			e = b(d),
    			f = d.tagName.toLowerCase(),
    			g = c.index,
    			h = {};
    			if ("a" == f) {
    				if (e.hasClass("c-btn-off")) return;
    				var i = "";
    				e.hasClass("c-p-pre") ? (g--, i = "pre") : e.hasClass("c-p-next") && (g++, i = "next")
    			} else if ("select" == f) {
    				if (g = d.selectedIndex + 1, c.oldIndex == g) return;
    				c.$arrow.removeClass("a-u"),
    				i = "select"
    			}
    			c.index = g,
    			h = {
    				index: g,
    				type: i
    			},
    			c.$select ? c.renderPage() : h.callback = function(a) {
    				c.renderPage(a)
    			},
    			c.disableHash ? c.$container.trigger("P:switchPage", h) : c.changeHash(),
    			c.oldIndex = g
    		}
    	},
    	a.lib = a.lib || {},
    	lib.PageNav = c
    } (window, $),
    function(a) {
    	if (void 0 == window.define) {
    		var b = {},
    		c = b.exports = {};
    		a(null, c, b),
    		window.floatNotify = window.notification = b.exports
    	} else define(a)
    } (function(a, b, c) {
    	function d(a) {
    		this._options = f.extend({
    			mode: "msg",
    			text: "网页提示",
    			useTap: !1
    		},
    		a || {}),
    		this._init()
    	}
    	var e, f = a ? a("zepto") : window.$,
    	g = f(window),
    	h = ['<div class="c-float-popWrap msgMode hide">', '<div class="c-float-modePop">', '<div class="warnMsg"></div>', '<div class="content"></div>', '<div class="doBtn">', '<button class="ok">确定</button>', '<button class="cancel">取消</button>', "</div>", "</div>", "</div>"].join(""),
    	i = f(h),
    	j = i.find(".warnMsg"),
    	k = i.find(".content"),
    	l = i.find(".doBtn .ok"),
    	m = i.find(".doBtn .cancel"),
    	n = !1,
    	o = "body";
    	f.extend(d.prototype, {
    		_init: function() {
    			var a = this,
    			b = a._options,
    			c = b.mode,
    			d = b.text,
    			e = b.content,
    			h = b.callback,
    			p = b.background,
    			q = b.useTap ? "tap": "click",
    			r = b.usedInWangWang,
    			s = i.attr("class");
    			s = s.replace(/(msg|alert|confirm)Mode/i, c + "Mode"),
    			i.attr("class", s),
    			p && i.css("background", p),
    			d && j.html(d),
    			e && k.html(e),
    			l.off(q).on(q,
    			function(b) {
    				h.call(a, b, !0)
    			}),
    			m.off(q).on(q,
    			function(b) {
    				h.call(a, b, !1)
    			}),
    			n || (n = !0, f(o).append(i), r || g.on("resize",
    			function() {
    				setTimeout(function() {
    					a._pos()
    				},
    				500)
    			}))
    		},
    		_pos: function() {
    			var a, b, c, d, e, f, g = this,
    			h = document,
    			j = h.documentElement,
    			k = h.body;
    			g.isHide() || (a = k.scrollTop, b = k.scrollLeft, c = j.clientWidth, d = j.clientHeight, e = i.width(), f = i.height(), i.css({
    				top: a + (d - f) / 2,
    				left: b + (c - e) / 2
    			}))
    		},
    		isShow: function() {
    			return i.hasClass("show")
    		},
    		isHide: function() {
    			return i.hasClass("hide")
    		},
    		_cbShow: function() {
    			var a = this,
    			b = a._options,
    			c = b.onShow;
    			i.css("opacity", "1").addClass("show"),
    			c && c.call(a)
    		},
    		show: function() {
    			var a = this;
    			e && (clearTimeout(e), e = void 0),
    			a.isShow() ? a._cbShow() : (i.css("opacity", "0").removeClass("hide"), a._pos(), setTimeout(function() {
    				a._cbShow()
    			},
    			300), setTimeout(function() {
    				i.animate({
    					opacity: "1"
    				},
    				300, "linear")
    			},
    			1))
    		},
    		_cbHide: function() {
    			var a = this,
    			b = a._options,
    			c = b.onHide;
    			i.css("opacity", "0").addClass("hide"),
    			c && c.call(a)
    		},
    		hide: function() {
    			var a = this;
    			a.isHide() ? a._cbHide() : (i.css("opacity", "1").removeClass("show"), setTimeout(function() {
    				a._cbHide()
    			},
    			300), setTimeout(function() {
    				i.animate({
    					opacity: "0"
    				},
    				300, "linear")
    			},
    			1))
    		},
    		flash: function(a) {
    			var b = this;
    			opt = b._options,
    			opt.onShow = function() {
    				e = setTimeout(function() {
    					e && b.hide()
    				},
    				a)
    			},
    			b.show()
    		}
    	}),
    	c.exports = new
    	function() {
    		this.simple = function(a, b, c) {
    			2 == arguments.length && "number" == typeof arguments[1] && (c = arguments[1], b = void 0);
    			var e = new d({
    				mode: "msg",
    				text: a,
    				background: b
    			});
    			return e.flash(c || 2e3),
    			e
    		},
    		this.msg = function(a, b) {
    			return new d(f.extend({
    				mode: "msg",
    				text: a
    			},
    			b || {}))
    		},
    		this.alert = function(a, b, c) {
    			return new d(f.extend({
    				mode: "alert",
    				text: a,
    				callback: b
    			},
    			c || {}))
    		},
    		this.confirm = function(a, b, c, e) {
    			return new d(f.extend({
    				mode: "confirm",
    				text: a,
    				content: b,
    				callback: c
    			},
    			e || {}))
    		},
    		this.pop = function(a) {
    			return new d(a)
    		}
    	}
    }),
    function(a) {
    	if (void 0 == window.define) {
    		var b = {},
    		c = b.exports = {};
    		a(null, c, b),
    		window.lazyload = b.exports
    	} else define(a)
    } (function(a, b, c) {
    	function d(a, b) {
    		var c = b.right > a.left && b.left < a.right,
    		d = b.bottom > a.top && b.top < a.bottom;
    		return c && d
    	}
    	function e(a, b) {
    		if (a) {
    			var c, d, e, h, i;
    			if (a != f) i = a.offset ? a: g(a),
    			i = i.offset(),
    			c = i.width,
    			d = i.height,
    			e = i.left,
    			h = i.top;
    			else {
    				var j = b && b.y || 0,
    				k = b && b.x || 0;
    				c = a.innerWidth + k,
    				d = a.innerHeight + j,
    				e = a.pageXOffset,
    				h = a.pageYOffset
    			}
    			return {
    				left: e,
    				top: h,
    				right: e + c,
    				bottom: h + d
    			}
    		}
    	}
    	var f = window,
    	g = a ? a("zepto") : window.$,
    	h = {
    		init: function(a) {
    			this.img.init(a)
    		},
    		img: {
    			init: function(a) {
    				var b = this;
    				if (b.isload) return void b.trigger();
    				var c = {
    					lazyHeight: 400,
    					lazyWidth: 0,
    					definition: !1,
    					size: null
    				},
    				a = a || {};
    				g.extend(b, c, a);
    				var d = b.definition,
    				e = f.devicePixelRatio;
    				b.definition = d && e && e > 1 || !1,
    				b.DPR = e;
    				var h = 5,
    				i = 200,
    				j = b.isPhone = b.fetchVersion();
    				if (j) {
    					var k, l;
    					g(f).on("touchstart",
    					function() {
    						k = {
    							sy: f.pageYOffset,
    							time: Date.now()
    						},
    						l && clearTimeout(l)
    					}).on("touchend",
    					function(a) {
    						if (a && a.changedTouches) {
    							var c = Math.abs(f.pageYOffset - k.sy);
    							if (c > h) {
    								var d = Date.now() - k.time;
    								l = setTimeout(function() {
    									b.changeimg(),
    									k = {},
    									clearTimeout(l),
    									l = null
    								},
    								d > i ? 0 : 200)
    							}
    						} else b.changeimg()
    					}).on("touchcancel",
    					function() {
    						l && clearTimeout(l),
    						k = null
    					})
    				} else g(f).on("scroll",
    				function() {
    					b.changeimg()
    				});
    				b.trigger(),
    				b.isload = !0
    			},
    			trigger: function(a) {
    				var b = this,
    				c = b.isPhone,
    				d = c && "touchend" || "scroll";
    				b.imglist && b.imglist.each(function(a, b) {
    					b && (b.onerror = b.onload = null)
    				}),
    				a && (b.size = a),
    				b.imglist = g("img.lazyimg"),
    				g(window).trigger(d)
    			},
    			fetchVersion: function() {
    				var a = navigator.appVersion.match(/(iPhone\sOS)\s([\d_]+)/),
    				b = a && !0 || !1,
    				c = b && a[2].split("_");
    				return c = c && parseFloat(c.length > 1 ? c.splice(0, 2).join(".") : c[0], 10),
    				b && 6 > c
    			},
    			setImgSrc: function(a, b) {
    				if (a) {
    					b = b || this.size,
    					b = b && ("string" == typeof b ? b: b[this.DPR]) || null,
    					b && (b = ["_", b, ".jpg"].join(""));
    					var c = a.lastIndexOf("_."),
    					d = -1 != c ? a.slice(c + 2) : null,
    					e = d && "webp" == d.toLowerCase() ? !0 : !1,
    					f = e ? a.slice(0, c) : a,
    					g = f.replace(/_\d+x\d+\.jpg?/g, "");
    					return b && (g += b),
    					e && g + "_.webp" || g
    				}
    			},
    			getCoord: e,
    			changeimg: function() {
    				function a(a, c) {
    					var d = a.attr("dataimg"),
    					e = a.attr("datasize");
    					d && (d = b.setImgSrc(d, e), a.attr("src", d), a.css("visibility", "visible"), a[0].onload || (a[0].onload = a[0].onerror = function() {
    						g(this).removeClass("lazyimg").removeAttr("dataimg"),
    						b.imglist[c] = null,
    						this.onerror = this.onload = null
    					}))
    				} {
    					var b = this,
    					c = window,
    					f = {
    						x: b.lazyWidth,
    						y: b.lazyHeight
    					};
    					b.definition
    				}
    				b.imglist.each(function(b, h) {
    					if (h) {
    						var i = g(h);
    						d(e(c, f), e(i)) && a(i, b)
    					}
    				})
    			}
    		}
    	};
    	c.exports = h
    }),
    function(a, b) {
    	var c = function() {
    		var a = "WebkitTransform" in document.documentElement.style ? !0 : !1;
    		return a
    	},
    	d = function() {
    		var a, b = !1,
    		c = document.createElement("div"),
    		a = ["­", '<style id="smodernizr">', "@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}", "</style>"].join(""),
    		d = document.documentElement.style;
    		return c.id = "modernizr",
    		c.innerHTML += a,
    		document.body.appendChild(c),
    		"WebkitPerspective" in d && "webkitPerspective" in d && (b = 9 === c.offsetLeft && 3 === c.offsetHeight),
    		c.parentNode.removeChild(c),
    		b
    	},
    	e = d ? "translate3d(": "translate(",
    	f = d ? ",0)": ")",
    	g = function(a, c) {
    		return a ? (c ? c.container = a: c = "string" == typeof a ? {
    			container: a
    		}: a, b.extend(this, {
    			container: ".slider",
    			wrap: null,
    			panel: null,
    			trigger: null,
    			activeTriggerCls: "sel",
    			hasTrigger: !1,
    			steps: 0,
    			left: 0,
    			visible: 1,
    			margin: 0,
    			curIndex: 0,
    			duration: 300,
    			loop: !1,
    			play: !1,
    			interval: 5e3,
    			useTransform: !0,
    			lazy: ".lazyimg",
    			lazyIndex: 1,
    			callback: null,
    			prev: null,
    			next: null,
    			activePnCls: "none"
    		},
    		c), void(this.findEl() && this.init() && this.increaseEvent())) : null
    	};
    	b.extend(g.prototype, {
    		reset: function(a) {
    			b.extend(this, a || {}),
    			this.init()
    		},
    		findEl: function() {
    			var a = this.container = b(this.container);
    			return a.length ? (this.wrap = this.wrap && a.find(this.wrap) || a.children().first(), this.wrap.length ? (this.panel = this.panel && a.find(this.panel) || this.wrap.children().first(), this.panel.length ? (this.panels = this.panel.children(), this.panels.length ? (this.trigger = this.trigger && a.find(this.trigger), this.prev = this.prev && a.find(this.prev), this.next = this.next && a.find(this.next), this) : (this.container.hide(), null)) : null) : null) : null
    		},
    		init: function() {
    			var a = this.wrap,
    			b = this.panel,
    			d = this.panels,
    			g = this.trigger,
    			h = this.len = d.length,
    			i = this.margin,
    			j = 0,
    			k = this.visible,
    			l = this.useTransform = c ? this.useTransform: !1;
    			this.steps = this.steps || a.width(),
    			d.each(function(a, b) {
    				j += b.offsetWidth
    			}),
    			i && "number" == typeof i && (j += (h - 1) * i, this.steps += i),
    			k > 1 && (this.loop = !1);
    			var m = this.left;
    			m -= this.curIndex * this.steps,
    			this.setCoord(b, m),
    			l && (a.css({
    				"-webkit-transform": "translate3d(0,0,0)"
    			}), b.css({
    				"-webkit-backface-visibility": "hidden"
    			}), d.css({
    				"-webkit-transform": e + "0,0" + f
    			}));
    			var n = this._pages = Math.ceil(h / k);
    			if (this._minpage = 0, this._maxpage = this._pages - 1, this.loadImg(), this.updateArrow(), 1 >= n) return this.getImg(d[0]),
    			g && g.hide(),
    			null;
    			if (this.loop) {
    				b.append(d[0].cloneNode(!0));
    				var o = d[h - 1].cloneNode(!0);
    				b.append(o),
    				this.getImg(o),
    				o.style.cssText += "position:relative;left:" + -this.steps * (h + 2) + "px;",
    				j += d[0].offsetWidth,
    				j += d[h - 1].offsetWidth
    			}
    			if (b.css("width", j), g && g.length) {
    				var p = "",
    				q = g.children();
    				if (!q.length) {
    					for (var r = 0; n > r; r++) p += "<span" + (r == this.curIndex ? " class=" + this.activeTriggerCls: "") + "></span>";
    					g.html(p)
    				}
    				this.triggers = g.children(),
    				this.triggerSel = this.triggers[this.curIndex]
    			} else this.hasTrigger = !1;
    			return this
    		},
    		increaseEvent: function() {
    			var a = this,
    			c = a.wrap[0],
    			d = a.prev,
    			e = a.next,
    			f = a.triggers;
    			c.addEventListener && (c.addEventListener("touchstart", a, !1), c.addEventListener("touchmove", a, !1), c.addEventListener("touchend", a, !1), c.addEventListener("webkitTransitionEnd", a, !1), c.addEventListener("msTransitionEnd", a, !1), c.addEventListener("oTransitionEnd", a, !1), c.addEventListener("transitionend", a, !1)),
    			a.play && a.begin(),
    			d && d.length && d.on("click",
    			function(b) {
    				a.backward.call(a, b)
    			}),
    			e && e.length && e.on("click",
    			function(b) {
    				a.forward.call(a, b)
    			}),
    			a.hasTrigger && f && f.each(function(c, d) {
    				b(d).on("click",
    				function() {
    					a.slideTo(c)
    				})
    			})
    		},
    		handleEvent: function(a) {
    			switch (a.type) {
    			case "touchstart":
    				this.start(a);
    				break;
    			case "touchmove":
    				this.move(a);
    				break;
    			case "touchend":
    			case "touchcancel":
    				this.end(a);
    				break;
    			case "webkitTransitionEnd":
    			case "msTransitionEnd":
    			case "oTransitionEnd":
    			case "transitionend":
    				this.transitionEnd(a)
    			}
    		},
    		loadImg: function(a) {
    			a = a || 0,
    			a < this._minpage ? a = this._maxpage: a > this._maxpage && (a = this._minpage);
    			var b = this.visible,
    			c = this.lazyIndex - 1,
    			d = c + a;
    			if (! (d > this._maxpage)) {
    				d += 1;
    				var e = (a && c + a || a) * b,
    				f = d * b,
    				g = this.panels;
    				f = Math.min(g.length, f);
    				for (var h = e; f > h; h++) this.getImg(g[h])
    			}
    		},
    		getImg: function(a) {
    			if (a && (a = b(a), !a.attr("l"))) {
    				var c = this,
    				d = c.lazy,
    				e = "img" + d;
    				d = d.replace(/^\.|#/g, ""),
    				a.find(e).each(function(a, c) {
    					var e = b(c);
    					src = e.attr("dataimg"),
    					src && e.attr("src", src).removeAttr("dataimg").removeClass(d)
    				}),
    				a.attr("l", "1")
    			}
    		},
    		start: function(a) {
    			var b = a.touches[0];
    			this._movestart = void 0,
    			this._disX = 0,
    			this._coord = {
    				x: b.pageX,
    				y: b.pageY
    			}
    		},
    		move: function(a) {
    			if (! (a.touches.length > 1 || a.scale && 1 !== a.scale)) {
    				var b, c = a.touches[0],
    				d = this._disX = c.pageX - this._coord.x,
    				e = this.left;
    				"undefined" == typeof this._movestart && (this._movestart = !!(this._movestart || Math.abs(d) < Math.abs(c.pageY - this._coord.y))),
    				this._movestart || (a.preventDefault(), this.stop(), this.loop || (d /= !this.curIndex && d > 0 || this.curIndex == this._maxpage && 0 > d ? Math.abs(d) / this.steps + 1 : 1), b = e - this.curIndex * this.steps + d, this.setCoord(this.panel, b), this._disX = d)
    			}
    		},
    		end: function(a) {
    			if (!this._movestart) {
    				var b = this._disX; - 10 > b ? (a.preventDefault(), this.forward()) : b > 10 && (a.preventDefault(), this.backward()),
    				b = null
    			}
    		},
    		backward: function(a) {
    			a && a.preventDefault && a.preventDefault();
    			var b = this.curIndex,
    			c = this._minpage;
    			b -= 1,
    			c > b && (b = this.loop ? c - 1 : c),
    			this.slideTo(b),
    			this.callback && this.callback(Math.max(b, c), -1)
    		},
    		forward: function(a) {
    			a && a.preventDefault && a.preventDefault();
    			var b = this.curIndex,
    			c = this._maxpage;
    			b += 1,
    			b > c && (b = this.loop ? c + 1 : c),
    			this.slideTo(b),
    			this.callback && this.callback(Math.min(b, c), 1)
    		},
    		setCoord: function(a, b) {
    			this.useTransform && a.css("-webkit-transform", e + b + "px,0" + f) || a.css("left", b)
    		},
    		slideTo: function(a, b) {
    			a = a || 0,
    			this.curIndex = a;
    			var c = this.panel,
    			d = c[0].style,
    			e = this.left - a * this.steps;
    			d.webkitTransitionDuration = d.MozTransitionDuration = d.msTransitionDuration = d.OTransitionDuration = d.transitionDuration = (b || this.duration) + "ms",
    			this.setCoord(c, e),
    			this.loadImg(a)
    		},
    		transitionEnd: function() {
    			var a = this.panel,
    			b = a[0].style,
    			c = this.loop,
    			d = this.curIndex;
    			c && (d > this._maxpage ? this.curIndex = 0 : d < this._minpage && (this.curIndex = this._maxpage), this.setCoord(a, this.left - this.curIndex * this.steps)),
    			c || d != this._maxpage ? this.begin() : (this.stop(), this.play = !1),
    			this.update(),
    			this.updateArrow(),
    			b.webkitTransitionDuration = b.MozTransitionDuration = b.msTransitionDuration = b.OTransitionDuration = b.transitionDuration = 0
    		},
    		update: function() {
    			var a = this.triggers,
    			b = this.activeTriggerCls,
    			c = this.curIndex;
    			a && a[c] && (this.triggerSel && (this.triggerSel.className = ""), a[c].className = b, this.triggerSel = a[c])
    		},
    		updateArrow: function() {
    			var a = this.prev,
    			b = this.next;
    			if (a && a.length && b && b.length && !this.loop) {
    				var c = this.curIndex,
    				d = this.activePnCls;
    				0 >= c && a.addClass(d) || a.removeClass(d),
    				c >= this._maxpage && b.addClass(d) || b.removeClass(d)
    			}
    		},
    		begin: function() {
    			var a = this;
    			a.play && !a._playTimer && (a.stop(), a._playTimer = setInterval(function() {
    				a.forward()
    			},
    			a.interval))
    		},
    		stop: function() {
    			var a = this;
    			a.play && a._playTimer && (clearInterval(a._playTimer), a._playTimer = null)
    		},
    		destroy: function() {
    			var a = this,
    			c = a.wrap[0],
    			d = a.prev,
    			e = a.next,
    			f = a.triggers;
    			c.removeEventListener && (c.removeEventListener("touchstart", a, !1), c.removeEventListener("touchmove", a, !1), c.removeEventListener("touchend", a, !1), c.removeEventListener("webkitTransitionEnd", a, !1), c.removeEventListener("msTransitionEnd", a, !1), c.removeEventListener("oTransitionEnd", a, !1), c.removeEventListener("transitionend", a, !1)),
    			d && d.length && d.off("click"),
    			e && e.length && e.off("click"),
    			a.hasTrigger && f && f.each(function(a, c) {
    				b(c).off("click")
    			})
    		},
    		attachTo: function(a, c) {
    			return a = b(a),
    			a.each(function(a, b) {
    				b.getAttribute("l") || (b.setAttribute("l", !0), g.cache.push(new g(b, c)))
    			})
    		}
    	}),
    	g.cache = [],
    	g.destroy = function() {
    		var a = g.cache,
    		b = a.length;
    		if (! (1 > b)) {
    			for (var c = 0; b > c; c++) a[c].destroy();
    			g.cache = []
    		}
    	},
    	a.lib = a.lib || {},
    	lib.Slider = g
    } (window, $),
    function(a) {
    	function b(a) {
    		var b, c, d, e = "",
    		f = 0;
    		for (b = c = d = 0; f < a.length;) b = a.charCodeAt(f),
    		128 > b ? (e += String.fromCharCode(b), f++) : b > 191 && 224 > b ? (d = a.charCodeAt(f + 1), e += String.fromCharCode((31 & b) << 6 | 63 & d), f += 2) : (d = a.charCodeAt(f + 1), c = a.charCodeAt(f + 2), e += String.fromCharCode((15 & b) << 12 | (63 & d) << 6 | 63 & c), f += 3);
    		return e
    	}
    	function c(a) {
    		a = a.replace(/\r\n/g, "\n");
    		for (var b = "",
    		c = 0; c < a.length; c++) {
    			var d = a.charCodeAt(c);
    			128 > d ? b += String.fromCharCode(d) : d > 127 && 2048 > d ? (b += String.fromCharCode(d >> 6 | 192), b += String.fromCharCode(63 & d | 128)) : (b += String.fromCharCode(d >> 12 | 224), b += String.fromCharCode(d >> 6 & 63 | 128), b += String.fromCharCode(63 & d | 128))
    		}
    		return b
    	}
    	var d = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
    	a.encode || (a.encode = {}),
    	a.encode.base64_utf8 = {
    		encode: function(a) {
    			var b, e, f, g, h, i, j, k = "",
    			l = 0;
    			for (a = c(a); l < a.length;) b = a.charCodeAt(l++),
    			e = a.charCodeAt(l++),
    			f = a.charCodeAt(l++),
    			g = b >> 2,
    			h = (3 & b) << 4 | e >> 4,
    			i = (15 & e) << 2 | f >> 6,
    			j = 63 & f,
    			isNaN(e) ? i = j = 64 : isNaN(f) && (j = 64),
    			k = k + d.charAt(g) + d.charAt(h) + d.charAt(i) + d.charAt(j);
    			return k
    		},
    		decode: function(a) {
    			var c, e, f, g, h, i, j, k = "",
    			l = 0;
    			for (a = a.replace(/[^A-Za-z0-9\+\/\=]/g, ""); l < a.length;) g = d.indexOf(a.charAt(l++)),
    			h = d.indexOf(a.charAt(l++)),
    			i = d.indexOf(a.charAt(l++)),
    			j = d.indexOf(a.charAt(l++)),
    			c = g << 2 | h >> 4,
    			e = (15 & h) << 4 | i >> 2,
    			f = (3 & i) << 6 | j,
    			k += String.fromCharCode(c),
    			64 !== i && (k += String.fromCharCode(e)),
    			64 !== j && (k += String.fromCharCode(f));
    			return k = b(k)
    		}
    	}
    } (window.lib || (window.lib = {})),
    function(a, b) {
    	var c = "stop",
    	d = navigator.userAgent,
    	e = /iPhone|iPad|iPod|iTouch/i.test(d),
    	f = function(a, b, c) {
    		var d = document.createElement("script");
    		d.src = "//amos.alicdn.com/getRealCid.aw?toId=cntaobao" + b + "&fromId=" + a + "&charset=utf-8",
    		d.onload = c,
    		document.body.appendChild(d)
    	},
    	g = function() {
    		return - 1 != d.indexOf("UCBrowser") ? "uc": -1 != d.indexOf("baidubrowser") ? "baidu": -1 != d.indexOf("MQQBrowser") ? "qq": -1 != d.indexOf("360browser") ? "360": -1 != d.indexOf("Opera") ? "opera": -1 != d.indexOf("Chrome") ? "chrome": "other"
    	},
    	h = function(a, b, c) {
    		var d, f = e ? "ios": "android",
    		h = "taobao",
    		i = "//log.m.taobao.com/js.do",
    		j = g() || "other"; - 1 != document.location.href.indexOf("tmall.com") && (h = "tmall");
    		var k = document.createElement("script");
    		k.src = i + "?ap_ref=&ap_uri=wx_click_waptowx&ap_data=" + b + ":" + a + ":" + f + ":" + h + ":" + j + "&_aplus=1",
    		d = setTimeout(function() {
    			c()
    		},
    		500),
    		k.onload = function() {
    			clearTimeout(d),
    			c()
    		},
    		k.onerror = function() {
    			clearTimeout(d),
    			c()
    		},
    		document.body.appendChild(k)
    	},
    	i = function() {
    		if ( - 1 != d.indexOf("MQQBrowser")) {
    			if (parseFloat(d.substring(d.indexOf("MQQBrowser") + 1 + new String("MQQBrowser").length)) < 4.2) return ! 1
    		} else if ( - 1 != d.indexOf("baidubrowser")) {
    			var a = parseInt(d.substring(d.indexOf("baidubrowser") + 1 + new String("baidubrowser").length));
    			if (4 != a && 3 != a) return ! 1
    		}
    		return ! 0
    	},
    	j = function() {
    		var a = {},
    		b = window.location.href,
    		c = "",
    		d = window.navigator.userAgent,
    		e = d.match(/\b(?:TBIOS|TBANDROID)\/((?:.*)@taobao_(iphone|android|apad|ipad)_((?:\d+\.){2,3}\d))/i),
    		f = b.match(/(?:\?|&)ttid=(?:.*)@taobao_(iphone|android|apad|ipad)_((?:\d+\.){2,3}\d)/i),
    		g = d.match(/WindVane/i);
    		return c = e || f || g,
    		a.inTaobaoAPP = c ? !0 : !1,
    		a
    	},
    	k = function() {
    		return - 1 != d.indexOf("T-UA=android") ? !0 : !1
    	},
    	l = function(a, b) {
    		{
    			var c = a.itemId || "",
    			d = a.toNick || "",
    			e = a.orderId || "",
    			f = a.wapwwUrl;
    			a.fromNick || ""
    		}
    		"wangtalk" == b ? h(a.pageId || "h5_default", "wx",
    		function() {
    			window.location = "" != d ? "" != e ? "wangtalk://wangxin.taobao.com/talkUser?userid=" + d + "&orderid=" + e + "&selfid=" + a.fromNick: "" != c ? "wangtalk://wangxin.taobao.com/talkUser?userid=" + d + "&itemid=" + c + "&selfid=" + a.fromNick: "wangtalk://wangxin.taobao.com/talkUser?userid=" + d + "&selfid=" + a.fromNick: "wangtalk://wangxin.taobao.com/contacts?selfid=" + a.fromNick
    		}) : "http" == b && (f = escape(f), h(a.pageId || "h5_default", "wapww",
    		function() {
    			window.location = "" != d ? "" != e ? "//www.taobao.com/go/rgn/wx/talkuser.html?userid=" + d + "&orderid=" + e + "&selfid=" + a.fromNick + "&wapww_url=" + f: "" != c ? "//www.taobao.com/go/rgn/wx/talkuser.html?userid=" + d + "&itemid=" + c + "&selfid=" + a.fromNick + "&wapww_url=" + f: "//www.taobao.com/go/rgn/wx/talkuser.html?userid=" + d + "&selfid=" + a.fromNick + "&wapww_url=" + f: "//www.taobao.com/go/rgn/wx/contacts.html?selfid=" + a.fromNick + "&wapww_url=" + f
    		}))
    	},
    	m = function(a) {
    		{
    			var b = (a.itemId || "", a.toNick || ""),
    			d = (a.orderId || "", a.wapwwUrl);
    			a.fromNick || ""
    		}
    		if (0 == b.indexOf("cntaobao") && (b = b.substring(8), a.toNick = b), e) h(a.pageId || "h5_default", "wapww",
    		function() {
    			window.location = d
    		});
    		else if (i()) {
    			var f = !1,
    			g = new Image;
    			g.onload = function() {
    				f = !0
    			},
    			g.src = "content://com.alibaba.mobileim.h5/wx.png?time=" + (new Date).getTime(),
    			setTimeout(function() {
    				f ? l(a, "wangtalk") : l(a, "http")
    			},
    			200)
    		} else l(a, "http");
    		setTimeout(function() {
    			c = "stop"
    		},
    		2e3)
    	};
    	b.wangxin = {
    		waptowx: function(a) {
    			"stop" == c && (c = "running", j().inTaobaoAPP || k() ? h(a.pageId || "h5_default", "wapww",
    			function() {
    				window.location = a.wapwwUrl
    			}) : a.toNick && a.fromNick ? f(a.fromNick, a.toNick,
    			function() {
    				a.toNick = realcid || "",
    				m(a)
    			}) : m(a))
    		},
    		init: function() {
    			for (var a = document.querySelectorAll("a.wangxin-waptowx"), c = 0; c < a.length; c++) a[c].onclick = function(a) {
    				_this = this,
    				a.preventDefault(),
    				b.wangxin.waptowx({
    					fromNick: _this.getAttribute("data-fromnick"),
    					toNick: _this.getAttribute("data-tonick") || "",
    					itemId: _this.getAttribute("data-item") || "",
    					wapwwUrl: _this.href,
    					pageId: "h5_mytaobao_index"
    				})
    			}
    		}
    	}
    } (window, window.lib || (window.lib = {}));
    function G_setImgSrc(a, b) {
    	if (a) {
    		b && (b = ["_", b, ".jpg"].join(""));
    		var c = a.lastIndexOf("_."),
    		d = -1 != c ? a.slice(c + 2) : null,
    		e = d && "webp" == d.toLowerCase() ? !0 : !1,
    		f = e ? a.slice(0, c) : a,
    		g = f.replace(/_\d+x\d+\.jpg?/g, "");
    		return b && (g += b),
    		e && g + "_.webp" || g
    	}
    }
    function G_bottomhtml() {
    	var a = "//shop" + G_msp_shopId + ".taobao.com",
    	b = "//shop" + G_msp_shopId + ".m.taobao.com/?v=1";
    	return lib.bottom.footer.getFooterTemplate(a, b)
    }
    function G_logStatis(a, b) {
    	var a = a || location.origin;
    	$.ajax({
    		aplus: !0,
    		ap_uri: a + "/?#" + b
    	})
    }
    lib.mtop.middleware.enableAntiCreep = !0;
    var templates = {};
    templates.comments_item = new Hogan.Template(function(a, b, c) {
    	var d = this;
    	return d.b(c = c || ""),
    	d.s(d.f("rateList", a, b, 1), a, b, 0, 13, 237, "{{ }}") && (d.rs(a, b,
    	function(a, b, d) {
    		d.b('<li class="item">'),
    		d.b("\n" + c),
    		d.b('    <a class="title omit" href="'),
    		d.b(d.v(d.f("link", a, b, 0))),
    		d.b('">'),
    		d.b(d.v(d.f("auctionTitle", a, b, 0))),
    		d.b("</a>"),
    		d.b("\n" + c),
    		d.b('    <p class="text">'),
    		d.b(d.v(d.f("rateContent", a, b, 0))),
    		d.b("</p>"),
    		d.b("\n" + c),
    		d.b('    <p class="user"><span>'),
    		d.b(d.v(d.f("displayUserNick", a, b, 0))),
    		d.b('</span><span class="date">'),
    		d.b(d.v(d.f("rateDate", a, b, 0))),
    		d.b("</span></p>\r"),
    		d.b("\n" + c),
    		d.b("</li>"),
    		d.b("\n")
    	}), a.pop()),
    	d.s(d.f("rateList", a, b, 1), a, b, 1, 0, 0, "") || (d.b('<li style="height:300px;line-height:300px;text-align:center;">暂无评论~</li>'), d.b("\n")),
    	d.fl()
    }),
    templates.comments_nav = new Hogan.Template(function(a, b, c) {
    	var d = this;
    	return d.b(c = c || ""),
    	d.b('<li class="sel" s="2" n="1">全部</li> \r'),
    	d.b("\n" + c),
    	d.b('                <li s="1" n="'),
    	d.b(d.v(d.f("good", a, b, 0))),
    	d.b('">好评'),
    	d.b(d.v(d.f("good", a, b, 0))),
    	d.b("</li> \r"),
    	d.b("\n" + c),
    	d.b('                <li s="0" n="'),
    	d.b(d.v(d.f("mid", a, b, 0))),
    	d.b('">中评'),
    	d.b(d.v(d.f("mid", a, b, 0))),
    	d.b("</li> \r"),
    	d.b("\n" + c),
    	d.b('                <li s="-1" n="'),
    	d.b(d.v(d.f("bad", a, b, 0))),
    	d.b('">差评'),
    	d.b(d.v(d.f("bad", a, b, 0))),
    	d.b("</li>"),
    	d.fl()
    }),
    templates.goods_list_item = new Hogan.Template(function(a, b, c) {
    	var d = this;
    	return d.b(c = c || ""),
    	d.s(d.f("itemsArray", a, b, 1), a, b, 0, 15, 647, "{{ }}") && (d.rs(a, b,
    	function(a, b, d) {
    		d.b("            <li> "),
    		d.b("\n" + c),
    		d.b('                <a href="'),
    		d.b(d.v(d.f("link", a, b, 0))),
    		d.b('">'),
    		d.b("\n" + c),
    		d.b('                    <div class="left"> <img class="lazyimg" dataimg="'),
    		d.b(d.v(d.f("picUrl", a, b, 0))),
    		d.b('" src="http://a.tbcdn.cn/mw/webapp/fav/img/grey.gif" /> </div>'),
    		d.b("\n" + c),
    		d.b('                    <div class="right">'),
    		d.b("\n" + c),
    		d.b('                        <h3 class="d-title">'),
    		d.b(d.v(d.f("title", a, b, 0))),
    		d.b("</h3>                            "),
    		d.b("\n" + c),
    		d.b('                        <p class="d-price"><em class="h">'),
    		d.b(d.v(d.f("salePrice", a, b, 0))),
    		d.b("</em> <del>"),
    		d.b(d.v(d.f("reservePrice", a, b, 0))),
    		d.b("</del> </p>"),
    		d.b("\n" + c),
    		d.b('                        <p class="info"> <span class="d-num">月售<em>'),
    		d.b(d.v(d.f("sold", a, b, 0))),
    		d.b('</em>笔</span><span class="d-area"></span></p>'),
    		d.b("\n" + c),
    		d.b("                    </div>"),
    		d.b("\n" + c),
    		d.b("                </a>"),
    		d.b("\n" + c),
    		d.b("            </li>"),
    		d.b("\n")
    	}), a.pop()),
    	d.s(d.f("itemsArray", a, b, 1), a, b, 1, 0, 0, "") || (d.b('            <li style="display:block;height:200px;line-height:200px;text-align:center;">未找到符合的宝贝</li>'), d.b("\n")),
    	d.fl()
    }),
    templates.index_recent_view = new Hogan.Template(function(a, b, c) {
    	var d = this;
    	return d.b(c = c || ""),
    	d.b("<!-- 最近浏览 -->"),
    	d.b("\n" + c),
    	d.b('        <div class="js-rv recent-view-wrap clearfix">\r'),
    	d.b("\n" + c),
    	d.b('            <div class="js-rv-des rv-des">\r'),
    	d.b("\n" + c),
    	d.b('                <div class="arrl"></div>\r'),
    	d.b("\n" + c),
    	d.b('                <div class="txt">最近浏览(<span class="js-rv-num">'),
    	d.b(d.v(d.f("len", a, b, 0))),
    	d.b("</span>)</div>\r"),
    	d.b("\n" + c),
    	d.b("            </div>\r"),
    	d.b("\n" + c),
    	d.b('            <div class="rv-slider">\r'),
    	d.b("\n" + c),
    	d.b('                <div class="rv-slider-outer">\r'),
    	d.b("\n" + c),
    	d.b('                    <ul class="rv-slider-wrap">\r'),
    	d.b("\n" + c),
    	d.s(d.f("rvList", a, b, 1), a, b, 0, 428, 568, "{{ }}") && (d.rs(a, b,
    	function(a, b, c) {
    		c.b('                        <li><a href="http://a.m.taobao.com/i'),
    		c.b(c.v(c.f("auctionId", a, b, 0))),
    		c.b('.htm"><img src="'),
    		c.b(c.v(c.f("picUrl", a, b, 0))),
    		c.b('" /></a></li>\r'),
    		c.b("\n")
    	}), a.pop()),
    	d.b('                        <!--<li><a href="javascript:;"><img src="http://q.i03.wimg.taobao.com/bao/uploaded/i2/18557025864159324/T1Gj0WFf4fXXXXXXXX_!!0-item_pic.jpg_90x90.jpg" alt="" /></a></li>\r'),
    	d.b("\n" + c),
    	d.b('                        <li><a href="javascript:;"><img src="http://q.i02.wimg.taobao.com/bao/uploaded/i2/10528024135022620/T1m414XpBcXXXXXXXX_!!0-item_pic.jpg_90x90.jpg" alt="" /></a></li>\r'),
    	d.b("\n" + c),
    	d.b('                        <li><a href="javascript:;"><img src="http://q.i01.wimg.taobao.com/bao/uploaded/i1/17863026293022852/T15hX9FbxfXXXXXXXX_!!0-item_pic.jpg_90x90.jpg" alt="" /></a></li>\r'),
    	d.b("\n" + c),
    	d.b('                        <li><a href="javascript:;"><img src="http://q.i03.wimg.taobao.com/bao/uploaded/i2/18557025864159324/T1Gj0WFf4fXXXXXXXX_!!0-item_pic.jpg_90x90.jpg" alt="" /></a></li>\r'),
    	d.b("\n" + c),
    	d.b('                        <li><a href="javascript:;"><img src="http://q.i02.wimg.taobao.com/bao/uploaded/i2/10528024135022620/T1m414XpBcXXXXXXXX_!!0-item_pic.jpg_90x90.jpg" alt="" /></a></li>\r'),
    	d.b("\n" + c),
    	d.b('                        <li><a href="javascript:;"><img src="http://q.i03.wimg.taobao.com/bao/uploaded/i2/18557025864159324/T1Gj0WFf4fXXXXXXXX_!!0-item_pic.jpg_90x90.jpg" alt="" /></a></li>\r'),
    	d.b("\n" + c),
    	d.b('                        <li><a href="javascript:;"><img src="http://q.i02.wimg.taobao.com/bao/uploaded/i2/10528024135022620/T1m414XpBcXXXXXXXX_!!0-item_pic.jpg_90x90.jpg" alt="" /></a></li>-->\r'),
    	d.b("\n" + c),
    	d.b("                    </ul>                    \r"),
    	d.b("\n" + c),
    	d.b("                </div>\r"),
    	d.b("\n" + c),
    	d.b("            </div>\r"),
    	d.b("\n" + c),
    	d.b("        </div>"),
    	d.fl()
    }),
    templates.shop_cates = new Hogan.Template(function(a, b, c) {
    	var d = this;
    	return d.b(c = c || ""),
    	d.b('<div class="shop-cates-layer">'),
    	d.b("\n" + c),
    	d.b('        <div class="sc-title">分类/搜索</div>'),
    	d.b("\n" + c),
    	d.b('        <div class="js-sc-main sc-main">'),
    	d.b("\n" + c),
    	d.b('            <form class="js-s-form search">'),
    	d.b("\n" + c),
    	d.b('                <div class="s-box">\r'),
    	d.b("\n" + c),
    	d.b('                    <input type="submit" class="js-s-submit s-submit" value="" />'),
    	d.b("\n" + c),
    	d.b('                    <input type="text" class="js-s-txt s-txt" name="name" value="" placeholder="搜索本店商品" />\r'),
    	d.b("\n" + c),
    	d.b("                </div>"),
    	d.b("\n" + c),
    	d.b("            </form>"),
    	d.b("\n" + c),
    	d.b("\n" + c),
    	d.b('            <ul class="menu">'),
    	d.b("\n" + c),
    	d.b("                <li>"),
    	d.b("\n" + c),
    	d.b('                    <h2 class="title">'),
    	d.b("\n" + c),
    	d.b('                        <span class="js-sc-m-title big-title omit" data-id="">所有宝贝</span>\r'),
    	d.b("\n" + c),
    	d.b("                    </h2>"),
    	d.b("\n" + c),
    	d.b("                </li>"),
    	d.b("\n" + c),
    	d.s(d.f("cats", a, b, 1), a, b, 0, 683, 1322, "{{ }}") && (d.rs(a, b,
    	function(a, b, d) {
    		d.b("                <li>"),
    		d.b("\n" + c),
    		d.b('                    <h2 class="title">'),
    		d.b("\n" + c),
    		d.b('                        <span class="js-sc-m-title big-title omit" data-id="'),
    		d.b(d.v(d.f("id", a, b, 0))),
    		d.b('">'),
    		d.b(d.v(d.f("name", a, b, 0))),
    		d.b("</span>\r"),
    		d.b("\n" + c),
    		d.b("                        "),
    		d.s(d.f("hasSubCats", a, b, 1), a, b, 0, 884, 932, "{{ }}") && (d.rs(a, b,
    		function(a, b, c) {
    			c.b('<span class="js-sc-arr sc-arr arr arr-d"></span>')
    		}), a.pop()),
    		d.b("\r"),
    		d.b("\n" + c),
    		d.b("                    </h2>"),
    		d.b("\n" + c),
    		d.s(d.f("hasSubCats", a, b, 1), a, b, 0, 1010, 1268, "{{ }}") && (d.rs(a, b,
    		function(a, b, d) {
    			d.b('                    <ul class="sub-menu">'),
    			d.b("\n" + c),
    			d.s(d.f("subCats", a, b, 1), a, b, 0, 1089, 1209, "{{ }}") && (d.rs(a, b,
    			function(a, b, c) {
    				c.b('                        <li class="js-sc-m-title sub-item omit" data-id="'),
    				c.b(c.v(c.f("id", a, b, 0))),
    				c.b('">'),
    				c.b(c.v(c.f("name", a, b, 0))),
    				c.b("</li>"),
    				c.b("\n")
    			}), a.pop()),
    			d.b("                    </ul>"),
    			d.b("\n")
    		}), a.pop()),
    		d.b("                </li>"),
    		d.b("\n")
    	}), a.pop()),
    	d.b("            </ul>"),
    	d.b("\n" + c),
    	d.b("        </div>"),
    	d.b("\n" + c),
    	d.b("    </div>"),
    	d.fl()
    }),
    templates.shop_info = new Hogan.Template(function(a, b, c) {
    	var d = this;
    	return d.b(c = c || ""),
    	d.b('<div class="shop-info">\r'),
    	d.b("\n" + c),
    	d.b('        <div class="si-title">店铺信息</div>\r'),
    	d.b("\n" + c),
    	d.b('        <div class="js-si-main si-main">\r'),
    	d.b("\n" + c),
    	d.b('            <div class="si-base-info" data-id="'),
    	d.b(d.v(d.f("id", a, b, 0))),
    	d.b('">\r'),
    	d.b("\n" + c),
    	d.b('                <div class="left"> <img id="js-si-img-logo" src="'),
    	d.b(d.v(d.f("picUrl", a, b, 0))),
    	d.b('" alt="" /> </div>'),
    	d.b("\n" + c),
    	d.b('                <div class="right">'),
    	d.b("\n" + c),
    	d.b('                    <h3 class="sp-name">'),
    	d.b(d.v(d.f("title", a, b, 0))),
    	d.b("</h3>"),
    	d.b("\n" + c),
    	d.b('                    <p class="sp-time"> <span class="des">创店时间:</span><span class="sp-t">'),
    	d.b(d.v(d.f("starts", a, b, 0))),
    	d.b("</span></p>"),
    	d.b("\n" + c),
    	d.b("                </div>\r"),
    	d.b("\n" + c),
    	d.b("            </div>\r"),
    	d.b("\n" + c),
    	d.b('            <div class="si-base-info1">\r'),
    	d.b("\n" + c),
    	d.b("                <ul>\r"),
    	d.b("\n" + c),
    	d.b('                    <li><span class="des">宝贝数量</span><span class="r">'),
    	d.b(d.v(d.f("productCount", a, b, 0))),
    	d.b("</span></li>\r"),
    	d.b("\n" + c),
    	d.b('                    <li><span class="des">收藏人气</span><span class="r">'),
    	d.b(d.v(d.f("collectorCount", a, b, 0))),
    	d.b("</span></li>\r"),
    	d.b("\n" + c),
    	d.b("                    "),
    	d.s(d.f("tmallnotshow", a, b, 1), a, b, 0, 806, 900, "{{ }}") && (d.rs(a, b,
    	function(a, b, c) {
    		c.b('<li><span class="des">好评率</span><span class="r">'),
    		c.b(c.v(c.d("shopDSRScore.sellerGoodPercent", a, b, 0))),
    		c.b("</span></li>")
    	}), a.pop()),
    	d.b("\r"),
    	d.b("\n" + c),
    	d.b('                    <li><span class="des">地区</span><span class="r">'),
    	d.b(d.v(d.f("prov", a, b, 0))),
    	d.b(" "),
    	d.b(d.v(d.f("city", a, b, 0))),
    	d.b("</span></li>\r"),
    	d.b("\n" + c),
    	d.b("                </ul>\r"),
    	d.b("\n" + c),
    	d.b("            </div>\r"),
    	d.b("\n" + c),
    	d.b('            <div class="si-base-info2">\r'),
    	d.b("\n" + c),
    	d.b('                <div class="zg"><span class="des">掌柜名</span><a class="js-ww-btn i2-btn" href="http://h5.m.taobao.com/ww/index.htm#!dialog-'),
    	d.b(d.v(d.f("enick", a, b, 0))),
    	d.b('">\r'),
    	d.b("\n" + c),
    	d.b('                    <span class="m name omit">'),
    	d.b(d.v(d.f("nick", a, b, 0))),
    	d.b('</span><span class="r ww-icon"><img src="http://im.wapa.taobao.com/ww/status.do?_input_charset=utf-8&nick='),
    	d.b(d.v(d.f("nick", a, b, 0))),
    	d.b('" alt="" /></span></a></div>\r'),
    	d.b("\n" + c),
    	d.b("                "),
    	d.s(d.f("hasPhone", a, b, 1), a, b, 0, 1479, 1656, "{{ }}") && (d.rs(a, b,
    	function(a, b, c) {
    		c.b('<div class="contact"><span class="des">电话</span><a class="js-phone-btn i2-btn" href="tel:'),
    		c.b(c.v(c.f("phone", a, b, 0))),
    		c.b('"><span class="m num">'),
    		c.b(c.v(c.f("phone", a, b, 0))),
    		c.b('</span><span class="r dh-icon"></span></a></div>')
    	}), a.pop()),
    	d.b(" \r"),
    	d.b("\n" + c),
    	d.b("            </div>\r"),
    	d.b("\n" + c),
    	d.b('            <div class="si-base-info3">\r'),
    	d.b("\n" + c),
    	d.b('                <p class="ms"><span class="des">描述相符</span><span class="num">'),
    	d.b(d.v(d.d("shopDSRScore.merchandisScore", a, b, 0))),
    	d.b('</span><span class="range '),
    	d.s(d.d("mg.green", a, b, 1), a, b, 0, 1881, 1884, "{{ }}") && (d.rs(a, b,
    	function(a, b, c) {
    		c.b("low")
    	}), a.pop()),
    	d.b('">'),
    	d.b(d.v(d.d("mg.data", a, b, 0))),
    	d.b("</span></p>\r"),
    	d.b("\n" + c),
    	d.b('                <p class="fw"><span class="des">服务态度</span><span class="num">'),
    	d.b(d.v(d.d("shopDSRScore.serviceScore", a, b, 0))),
    	d.b('</span><span class="range '),
    	d.s(d.d("sg.green", a, b, 1), a, b, 0, 2068, 2071, "{{ }}") && (d.rs(a, b,
    	function(a, b, c) {
    		c.b("low")
    	}), a.pop()),
    	d.b('">'),
    	d.b(d.v(d.d("sg.data", a, b, 0))),
    	d.b("</span></p>\r"),
    	d.b("\n" + c),
    	d.b('                <p class="fh"><span class="des">发货速度</span><span class="num">'),
    	d.b(d.v(d.d("shopDSRScore.consignmentScore", a, b, 0))),
    	d.b('</span><span class="range '),
    	d.s(d.d("cg.green", a, b, 1), a, b, 0, 2259, 2262, "{{ }}") && (d.rs(a, b,
    	function(a, b, c) {
    		c.b("low")
    	}), a.pop()),
    	d.b('">'),
    	d.b(d.v(d.d("cg.data", a, b, 0))),
    	d.b("</span></p>\r"),
    	d.b("\n" + c),
    	d.b("            </div>\r"),
    	d.b("\n" + c),
    	d.b("        </div>\r"),
    	d.b("\n" + c),
    	d.b("    </div>"),
    	d.fl()
    }),
    Function.prototype.bind || (Function.prototype.bind = function(a) {
    	var b = this,
    	c = Array.prototype.slice;
    	if ("function" != typeof b) throw new TypeError("Function.prototype.bind called on incompatible " + b);
    	var d = c.call(arguments, 1),
    	e = function() {
    		if (this instanceof e) {
    			var f = function() {};
    			f.prototype = b.prototype;
    			var g = new f,
    			h = b.apply(g, d.concat(c.call(arguments)));
    			return Object(h) === h ? h: g
    		}
    		return b.apply(a, d.concat(c.call(arguments)))
    	};
    	return e
    }),
    $.fn.slideDown = function(a) {
    	var b = $(this),
    	c = {
    		callback: function() {},
    		ease: "linear",
    		anitime: .3
    	};
    	$.extend(c, a),
    	b.wrap('<div style="height:1px; overflow:hidden"></div>'),
    	b.show();
    	var d = b.height();
    	return b.parent().anim({
    		height: d
    	},
    	c.anitime, c.ease,
    	function() {
    		$(this).children().first().unwrap("<div></div>"),
    		c.callback()
    	}),
    	this
    },
    $.fn.slideUp = function(a) {
    	var b = {
    		callback: function() {},
    		ease: "linear",
    		anitime: .3
    	};
    	$.extend(b, a);
    	var c = $(this).height();
    	return $(this).wrap('<div style="overflow:hidden"></div>'),
    	$(this).parent().height(c).css("overflow", "hidden"),
    	$(this).parent().anim({
    		height: "1px"
    	},
    	b.anitime, b.ease,
    	function() {
    		$(this).children().hide(),
    		$(this).children().unwrap("<div></div>"),
    		b.callback()
    	}),
    	this
    };
    var G_in_server = !1;
    location.host.match(".*(waptest|wapa|m)\\.(taobao|tmall|etao|alibaba|alipay|aliyun)\\.com.*") && (G_in_server = !0);
    var G_isIos = $.os.ios && parseFloat($.os.version) >= 5,
    G_isPad = $.os.ipad,
    G_loading = '<div style="display:block;height:300px;line-height:300px;text-align:center;"><img src="//assets.alicdn.com/mw/base/styles/component/more/images/loading.gif" /></div>',
    G_msp_not_show_info = "undefined" != typeof G_msp_show_info && !G_msp_show_info,
    G_msp_not_show_search = "undefined" != typeof G_msp_show_search && !G_msp_show_search,
    G_msp_not_show_comments = "undefined" != typeof G_msp_show_comments && !G_msp_show_comments; !
    function() {
    	function a(a, b) {
    		var c = document.getElementsByTagName("head")[0],
    		d = document.createElement("script");
    		d.async = "async",
    		d.type = "text/javascript",
    		d.onload = d.onreadystatechange = function() {
    			this.readyState && "loaded" !== this.readyState && "complete" !== this.readyState || (b && b(), d.onload = d.onreadystatechange = null, c && d.parentNode && c.removeChild(d))
    		},
    		d.src = a,
    		c.insertBefore(d, c.firstChild)
    	}
    	window.G_ttid = "";
    	for (var b, c, d = location.search.slice(1).split("&"), e = 0; e < d.length; e++) b = d[e].split("="),
    	"ttid" == b[0] && (c = b[1], c && (window.G_ttid = "ttid=" + c));
    	var f = location.href.indexOf("mmusdkwakeup=1"); - 1 == f && a("//h5.m.taobao.com/js/smartbanner/setting.js?v=" + Math.random(),
    	function() {
    		if (window.SmartbannerJSON) {
    			var a, b = location.search,
    			c = location.hash;
    			a = /(&|\?)shop_id=\d+(&|\b)/.test(b) ? b: "?shop_id=" + G_msp_shopId + (b ? "&": "") + b.replace(/^\?/, "") + (c.indexOf("?") ? "&": "") + (c.split("?")[1] || ""),
    			SmartbannerJSON.mainShop.href = SmartbannerJSON.mainShop.href + a,
    			lib.smartbanner.sbLogic(SmartbannerJSON.mainShop, 3)
    		}
    	})
    } (),
    $(document.body).append('<div id="bottom">' + G_bottomhtml() + "</div>"),
    $(document).on("click", ".js-ww-btn",
    function(a) {
    	G_logStatis("", "click_shop_aliwangwang"),
    	a.preventDefault();
    	var b = $(a.currentTarget);
    	lib.wangxin.waptowx({
    		fromNick: lib.login.getNickFromCookie() || "",
    		toNick: b.find(".name").text() || "",
    		itemId: "",
    		wapwwUrl: b.attr("href") || "",
    		pageId: "h5_taobao_shop"
    	})
    }).on("click", ".js-phone-btn",
    function() {}),
    app.config.enableMessageLog = !1,
    app.config.enableNavbar = !1,
    app.config.enableToolbar = !1,
    app.config.enableScroll = !1,
    app.config.templateEngine = {
    	load: function(a, b) {
    		$.get(a, b)
    	}
    },
    app.config.enableTransition = G_isPad ? !1 : !0,
    function() {
    	var a = function(a, b, c) {
    		var d = a.api,
    		e = $.extend({
    			shopId: G_msp_shopId
    		},
    		a),
    		f = a.v || "1.0";
    		delete e.api,
    		delete e.v,
    		lib.mtop.request({
    			api: d,
    			v: f,
    			data: e
    		},
    		function(a) {
    			b(a)
    		},
    		function(a) {
    			c(a)
    		})
    	},
    	b = {
    		ajax: function(b, c, d) {
    			function e() {
    				c.apply(this, arguments)
    			}
    			function f(a) {
    				var a = a.data,
    				b = h.dataOpe(a),
    				d = templates.shop_cates && templates.shop_cates.render(b);
    				h.cacheData = {
    					ndata: b,
    					html: d
    				},
    				c && e(b, d)
    			}
    			function g(a) {
    				d && d(a)
    			}
    			var h = this,
    			b = $.extend({
    				api: "com.taobao.search.api.getCatInfoInShop"
    			},
    			b);
    			G_in_server ? h.cacheData ? e(h.cacheData.ndata, h.cacheData.html) : a(b, f, g) : mspCatesData && f(mspCatesData)
    		},
    		dataOpe: function(a) {
    			return a.cats.forEach(function(a) {
    				var b = a.subCats;
    				a.hasSubCats = b.length ? !0 : !1
    			}),
    			a
    		},
    		cacheData: "",
    		action: function(a) {
    			var b = $(a) || $(document);
    			b.on("click", ".js-sc-arr",
    			function(a) {
    				var b = $(a.currentTarget);
    				if (b.hasClass("arr")) {
    					var c = b.parent().siblings(".sub-menu");
    					b.hasClass("arr-d") ? c.slideUp({
    						callback: function() {
    							b.removeClass("arr-d"),
    							b.addClass("arr-r")
    						}
    					}) : (c.removeClass("none"), c.slideDown({
    						callback: function() {
    							b.removeClass("arr-r"),
    							b.addClass("arr-d")
    						}
    					}))
    				}
    			})
    		}
    	},
    	c = {
    		ajax: function(b, c, d) {
    			function e() {
    				$(".content").show(),
    				$("#we-page").hide(),
    				c.apply(this, arguments)
    			}
    			function f(a) {
    				var a = a.data,
    				b = h.dataOpe(a),
    				d = templates.shop_info && templates.shop_info.render(b);
    				h.cacheData = {
    					ndata: b,
    					html: d
    				},
    				c && e(b, d)
    			}
    			function g(a) {
    				d && d(a)
    			}
    			var h = this,
    			b = $.extend({
    				api: "mtop.shop.getWapShopInfo"
    			},
    			b);
    			G_in_server ? h.cacheData ? e(h.cacheData.ndata, h.cacheData.html) : a(b, f, g) : mspInfoData && f(mspInfoData)
    		},
    		dataOpe: function(a) {
    			var b = function(a) {
    				var b = parseFloat(a);
    				a = b > 0 ? "高于同行 " + b + "%": 0 == b ? "持平 ---": "低于同行 " + -b + "%";
    				var c = !1;
    				return 0 > b && (c = !0),
    				{
    					data: a,
    					green: c
    				}
    			};
    			a.starts = a.starts.split(" ")[0],
    			a.phone && (a.hasPhone = !0),
    			a.tmallnotshow = "true" == a.isMall ? !1 : !0,
    			a.enick = lib.encode.base64_utf8.encode(a.nick),
    			a.picUrl = $(".js-msp-logo").find("img").attr("src");
    			var c = a.shopDSRScore;
    			return a.mg = b(c.mg),
    			a.cg = b(c.cg),
    			a.sg = b(c.sg),
    			a
    		},
    		cacheData: ""
    	},
    	d = {
    		ajax: function(b, c, d) {
    			function e() {
    				$(".content").show(),
    				$("#we-page").hide(),
    				c.apply(this, arguments)
    			}
    			function f(a) {
    				var a = a.data,
    				b = h.dataOpe(a);
    				h.cacheData = {
    					data: a,
    					ndata: b
    				},
    				c && e(a, b)
    			}
    			function g(a) {
    				d && d(a)
    			}
    			var h = this,
    			b = $.extend({
    				api: "com.taobao.wireless.shop.feedback.sum"
    			},
    			b);
    			G_in_server ? h.cacheData ? e(h.cacheData.data, h.cacheData.ndata) : a(b, f, g) : f({
    				data: {
    					goodSeller: 0,
    					neutralSeller: 0,
    					badSeller: 0
    				}
    			})
    		},
    		dataOpe: function(a) {
    			var b = {
    				good: parseInt(a.goodSeller),
    				mid: parseInt(a.neutralSeller),
    				bad: parseInt(a.badSeller)
    			};
    			return b.good > 999 && (b.good = "999+"),
    			b.mid > 999 && (b.mid = "999+"),
    			b.bad > 999 && (b.bad = "999+"),
    			b
    		},
    		renderC: function(a) {
    			var b = parseInt(a.goodSeller) + parseInt(a.neutralSeller) + parseInt(a.badSeller) || 0,
    			c = '<ul class="shop-info-comm-num"><li><a id="goComments" href=""><span class="icon"></span><span class="txt">店铺评价</span><span class="num ced5">' + b + '</span><span class="arr"><i class="aw a-r"></i></span></a></li></ul>';
    			return c
    		}
    	},
    	e = {
    		ajax: function(b, c, d) {
    			function e(a) {
    				var a = a.data.html;
    				g.cacheData = a,
    				c && c(a)
    			}
    			function f(a) {
    				d && d(a)
    			}
    			var g = this,
    			b = $.extend({
    				api: "com.taobao.wireless.shop.yyzs.index.html",
    				page: "0",
    				pageSize: "0"
    			},
    			b);
    			G_in_server ? g.cacheData ? c(g.cacheData) : a(b, e, f) : templates.index_pg && e({
    				data: {
    					html: templates.index_pg.render()
    				}
    			})
    		},
    		cacheData: ""
    	},
    	f = {
    		ajax: function(b, c, d) {
    			function e() {
    				$(".content").show(),
    				$("#we-page").hide(),
    				c.apply(this, arguments)
    			}
    			function f(a) {
    				var d = h.dataOpe(a.data),
    				f = h.cacheData,
    				g = b.rateResult;
    				f[g] ? f[g][i] = d: (f[g] = {},
    				f[g][i] = d),
    				c && e(f)
    			}
    			function g(a) {
    				d && d(a)
    			}
    			var h = this,
    			b = $.extend({
    				api: "mtop.shop.getsellerRate",
    				pageSize: "10"
    			},
    			b),
    			i = "" + b.pageNo;
    			G_in_server ? h.cacheData && h.cacheData[b.rateResult] && h.cacheData[b.rateResult][i] ? e(h.cacheData) : a(b, f, g) : commentsList && f(commentsList)
    		},
    		dataOpe: function(a) {
    			var b = this;
    			return a.rateList.forEach(function(a) {
    				a.rateDate = b.dateFormat(a.rateDate)
    			}),
    			a
    		},
    		dateFormat: function(a) {
    			var b = new Date,
    			c = function(a) {
    				return String(a).replace(/^(\d)$/, "0$1")
    			},
    			d = b.getFullYear() + "-" + c(b.getMonth() + 1) + "-" + c(b.getDate() - 1),
    			e = b.getFullYear() + "-" + c(b.getMonth() + 1) + "-" + c(b.getDate()),
    			f = a.split(" ")[0].replace(/\./g, "-");
    			return f == e ? "今天": f == d ? "昨天": f
    		},
    		cacheData: {}
    	},
    	g = {
    		ajax: function(b, c, d) {
    			function e() {
    				$(".content").show(),
    				$("#we-page").hide(),
    				c.apply(this, arguments)
    			}
    			function f(a) {
    				var b = a.data;
    				c && e(b)
    			}
    			function g(a) {
    				d && d(a)
    			} {
    				var h, b = $.extend({
    					api: "com.taobao.search.api.getShopItemList",
    					v: "2.0",
    					currentPage: 1,
    					pageSize: "30"
    				},
    				b);
    				"" + b.currentPage
    			}
    			b.hasOwnProperty("q") && (h = "q"),
    			b.hasOwnProperty("catId") && (h = "catId"),
    			G_in_server ? a(b, f, g) : goodsList && f(goodsList)
    		},
    		cacheData: {
    			q: {
    				oldstarts: {},
    				hotsell: {},
    				bid: {},
    				_bid: {},
    				isPromotion: {}
    			},
    			catId: {
    				oldstarts: {},
    				hotsell: {},
    				bid: {},
    				_bid: {},
    				isPromotion: {}
    			}
    		}
    	};
    	window.msp = {
    		ajax: a,
    		cates: b,
    		info: c,
    		commNum: d,
    		index_html: e,
    		comments_list: f,
    		goods_list: g
    	}
    } (window.app),
    function(a) {
    	"use strict";
    	function b(b) {
    		var d = this.op = {
    			container: c,
    			mask: !0,
    			content: "",
    			wrapId: "popLayerWrap",
    			fixed: !1,
    			minHeight: 480,
    			onHide: function() {},
    			onShow: function() {}
    		};
    		return a.extend(d, b),
    		a("#" + d.warpId).length ? void console.log("[error] This page already have the element [" + d.warpId + "]") : (a(d.container).length || (this.op.container = c), void this.init())
    	}
    	var c = document.body;
    	a.extend(b.prototype, {
    		init: function() {
    			var b = this,
    			d = this.op,
    			e = this.wrapDiv = a('<div id="' + d.wrapId + '" class="pop-layer-wrap" style="display:none;"></div>'),
    			f = this.content = a('<div class="js-pop-layer pop-layer">' + d.content + "</div>"),
    			g = this.mask = a('<div class="' + d.wrapId + '-mask pop-layer-mask"></div>');
    			e.append(f);
    			var h = a(d.container);
    			if (h.append(e), d.mask && (e.append(g), g.on("click",
    			function() {
    				b.hide.apply(b)
    			})), d.fixed) {
    				this.content.addClass("scrollable");
    				var i = a('<div id="ios5_fixed_bug_ele"></div>'),
    				j = a(c);
    				j.append(i),
    				this.ios5_fixed_bug_ele = i;
    				var k = d.minHeight;
    				e.css({
    					"min-height": k,
    					position: "fixed",
    					bottom: 0
    				}),
    				f.css({
    					"min-height": k,
    					position: "fixed",
    					bottom: 0,
    					overflow: "auto"
    				}),
    				g.css("min-height", k)
    			}
    		},
    		refresh: function(b) {
    			var d = this;
    			if (!d.op.fixed) {
    				var e = this.wrapDiv,
    				f = e.css("display"),
    				g = e.find(b),
    				h = g.css("display"),
    				i = g.height();
    				"none" == f.substr(0, 4) && (e.addClass("blockimp"), "none" == h.substr(0, 4) ? (g.addClass("blockimp"), i = g.height(), g.removeClass("blockimp")) : i = g.height(), e.removeClass("blockimp"));
    				var j = a(c).height(),
    				i = parseFloat(i);
    				i > j && (j = i),
    				j += 20,
    				d.content.css("height", j),
    				d.wrapDiv.css("height", j)
    			}
    		},
    		show: function(a) {
    			var b = this;
    			this.wrapDiv.show(),
    			this.content.addClass("stopflick"),
    			a && this.refresh(a),
    			b.op.mask && b.mask.show(),
    			this.translation(this.content[0], {
    				x: 0
    			},
    			function() {
    				b.content.addClass("open3d"),
    				b.op.onShow(),
    				b.wrapDiv.attr("p_show", "show")
    			})
    		},
    		hide: function() {
    			var a = this;
    			a.op.mask && a.mask.hide(),
    			this.translation(this.content[0], {
    				x: 280,
    				duration: "0.4s"
    			},
    			function() {
    				a.content.removeClass("stopflick");
    				var b = a.content[0].style;
    				b.webkitBackfaceVisibility = "",
    				b.webkitTransform = "",
    				b.webkitTransformStyle = "",
    				a.op.fixed && a.content.removeClass("open3d"),
    				a.wrapDiv.hide(),
    				a.op.onHide(),
    				a.wrapDiv.attr("p_show", "hide")
    			})
    		},
    		translation: function(b, c, d) {
    			var e = a.extend({
    				duration: "0.4s",
    				origin: "0 0"
    			},
    			c || {}),
    			f = b.style; ! f.webkitTransitionProperty && (f.webkitTransitionProperty = "-webkit-transform"),
    			f.webkitTransitionDuration !== e.duration && (f.webkitTransitionDuration = e.duration),
    			f.webkitTransformOrigin !== e.origin && (f.webkitTransformOrigin = e.origin),
    			"hidden" !== f.webkitBackfaceVisibility && (f.webkitBackfaceVisibility = "hidden"),
    			"preserve-3d" !== f.webkitTransformStyle && (f.webkitTransformStyle = "preserve-3d"),
    			(null != e.x || null != e.y) && (f.webkitTransform = "translate(" + (e.x ? e.x + "px,": "0,") + (e.y ? e.y + "px": "0") + ")", setTimeout(d, 1500 * parseFloat(e.duration)))
    		},
    		content_destroy: function() {
    			this.content.off()
    		},
    		destroy: function() {
    			this.content.off(),
    			this.op.mask && this.mask.off()
    		}
    	}),
    	window.PopLayer = b
    } ($),
    function(a) {
    	"use strict";
    	var b, c = a(document.body),
    	d = function(b) {
    		var c = a(b.target);
    		c.parents(".js-pop-layer").length || b.preventDefault()
    	};
    	b = new PopLayer(G_isIos ? {
    		mask: !0,
    		fixed: !0,
    		minHeight: 400,
    		content: "",
    		onHide: function() {
    			c.off("touchmove", d)
    		},
    		onShow: function() {
    			b.ios5_fixed_bug_ele.css("height", "200px"),
    			setTimeout(function() {
    				b.ios5_fixed_bug_ele.css("height", "0")
    			},
    			100),
    			c.on("touchmove", d)
    		}
    	}: {
    		mask: !0,
    		content: "",
    		onHide: function() {
    			window.scrollTo(0, 1)
    		}
    	});
    	var e = ['<div class="shop-filter">', '<div class="sf-title">价格区间</div>', '<div class="sf-main">', '<form class="js-filter-form">', '<div class="condi">', '<input class="js-start-price inp" type="text" placeholder="最低价" value="" />元 ~', '<input class="js-end-price inp" type="text" placeholder="最高价" value="" />元', "</div>", '<div class="finish">', '<input class="js-filter-submit fin-btn" type="submit" value="完成" />', "</div>", "</form>", "</div>", "</div>"].join("");
    	b.content.append('<div class="js-shop-cates-flag js-scroll-ele shop-cates-flag none">' + G_loading + "</div>").append('<div class="js-shop-info-flag js-scroll-ele shop-info-flag none"><div class="js-shop-info">' + G_loading + '</div><div class="js-shop-c"></div></div>').append(a('<div class="js-shop-filter-flag js-scroll-ele shop-filter-flag none">' + e + "</div>")),
    	window.G_popLayer = b
    } ($),
    function(a, b) {
    	function c(a) {
    		var b = j.find(a);
    		b.hasClass("none") && (b.removeClass("none"), b.siblings().addClass("none"))
    	}
    	function d(a) {
    		if (G_popLayer.hide(), window.G_pg_name && "goodsList" == window.G_pg_name) {
    			var c = app.getPage("list"),
    			a = c.format_url(a);
    			c.change_state(a),
    			c.urlData = a,
    			b.goods_list.ajax(a,
    			function(a) {
    				c.renderItem(a, "init")
    			})
    		} else app.navigation.push("list", {
    			type: "GET",
    			data: a
    		})
    	}
    	function e() { ! b.info.cacheData && b.info.ajax({},
    		function(a, b) {
    			k.html(b),
    			G_popLayer.refresh(".js-shop-info-flag")
    		},
    		function() {
    			console.log("店铺信息数据出了点小问题~~")
    		}),
    		!G_msp_not_show_comments && !b.commNum.cacheData && b.commNum.ajax({},
    		function(c) {
    			l.html(b.commNum.renderC(c)),
    			a("#goComments").on("click",
    			function(a) {
    				a.preventDefault(),
    				app.navigation.push("comments", {
    					type: "GET",
    					data: c
    				}),
    				G_logStatis("", "click_shop_comments")
    			}),
    			G_popLayer.refresh(".js-shop-info-flag")
    		}),
    		c(".js-shop-info-flag"),
    		G_popLayer.show(".js-shop-info-flag")
    	}
    	if (b) {
    		var f = ['<header class="js-nav-wrap nav-wrap fixed">', '<div class="nav">', '<div class="js-nav-back left">', '<a class="txt" href="javascript:;"><span>back</span></a>', "</div>", '<div class="js-nav-mid-wrap middle center none">', '<div class="js-nav-glist">', '<div class="js-nav-title title omit"></div>', '<div class="js-nav-des des omit"></div>', "</div>", '<div class="js-nav-comm nav-comm none">店铺评论</div>', "</div>", '<div class="js-nav-r-wrap right">', '<span class="js-nav-csch fun csch">分类</span>', '<span class="js-nav-info fun info none" data-info="店铺信息" data-sort="筛选">店铺信息</span>', "</div>", "</div>", "</header>"].join("");
    		a("#js-viewport").append(f).append('<section class="content"></section>');
    		var g = a(".js-nav-back"),
    		h = a(".js-nav-csch"),
    		i = a(".js-nav-info");
    		G_msp_not_show_search && h.addClass("none"),
    		G_msp_not_show_info && i.addClass("none"),
    		g.on("click",
    		function() {
    			return window.IS_RATE ? void history.back() : void(app.module.Navigation.instance.getStack().getIndex() ? (1 == app.module.Navigation.instance.getStack().getIndex() && (a(".content").hide(), a("#we-page").show()), app.navigation.pop()) : document.referrer ? history.back() : location.href = "//m.taobao.com/")
    		});
    		var j = G_popLayer.content;
    		h.on("click",
    		function() { ! b.cates.cacheData && b.cates.ajax({},
    			function(a, b) {
    				j.find(".js-shop-cates-flag").html(b),
    				G_popLayer.refresh(".js-shop-cates-flag")
    			},
    			function() {
    				console.log("店铺类目数据出了点小问题~~")
    			}),
    			c(".js-shop-cates-flag"),
    			G_popLayer.show(".js-shop-cates-flag"),
    			G_isIos || window.scrollTo(0, 0),
    			G_logStatis("", "click_shop_inshopsort")
    		}),
    		b.cates.action(".js-shop-cates-flag"),
    		j.on("submit", ".js-s-form",
    		function(b) {
    			b.preventDefault();
    			var c = a.trim(a(".js-s-txt").val());
    			d({
    				q: encodeURIComponent(c)
    			})
    		}).on("click", ".js-sc-m-title",
    		function(b) {
    			var c = a(b.currentTarget);
    			d({
    				catId: c.attr("data-id"),
    				catTxt: encodeURIComponent(c.text())
    			})
    		});
    		var k = j.find(".js-shop-info"),
    		l = j.find(".js-shop-c");
    		i.on("click",
    		function(a) {
    			i.hasClass("info") ? (e(a), G_logStatis("", "click_shop_shopinfo")) : (c(".js-shop-filter-flag"), G_popLayer.show(".js-shop-filter-flag"), G_logStatis("", "click_shop_listfilter")),
    			G_isIos || window.scrollTo(0, 0)
    		})
    	}
    } ($, window.msp),
    function(a) {
    	var b = {
    		name: "index",
    		isCollect: "unknow",
    		favdo: function(a) {
    			var b = this,
    			c = lib.login,
    			d = $(a.currentTarget).find(".fav-icon"),
    			e = location.href.indexOf("mmusdkwakeup=1"),
    			f = function() {
    				var a = location.search.slice(1),
    				b = ["http://alimamasdk/shopCollect?"];
    				b.push("shopId=" + G_msp_shopId),
    				b.push("&type=0"),
    				b.push("&" + a),
    				b = b.join(""),
    				console.log(b),
    				window.WindVane.call("AlimamaWakeup", "canWakeup", {
    					url: b
    				},
    				function() {
    					$(document).on("Collect:Success",
    					function() {
    						h()
    					}),
    					$(document).on("Collect:Fail",
    					function() {
    						g()
    					})
    				},
    				function() {
    					g()
    				},
    				1e4)
    			},
    			g = function() {
    				lib.mtop.loginedRequest({
    					api: "com.taobao.favorite.api.addCollect",
    					v: "1.0",
    					data: {
    						type: "0",
    						itemId: G_msp_shopId
    					}
    				},
    				{
    					succ: function() {
    						h()
    					},
    					fail: function(a) {
    						var e = a.errcode;
    						"FAIL_SYS_SESSION_EXPIRED" == e ? c.goLogin({
    							rediUrl: location.href,
    							hideType: !0
    						}) : "SHOP_COLLECT" == e ? (b.isCollect = "true", d.addClass("h"), $("#bottom").html(G_bottomhtml())) : notification.simple(a.message)
    					}
    				}),
    				G_logStatis("", "click_shop_addfav")
    			},
    			h = function() {
    				b.isCollect = "true",
    				d.addClass("h"),
    				notification.simple("收藏成功"),
    				$("#bottom").html(G_bottomhtml())
    			};
    			"true" == this.isCollect ? (lib.mtop.loginedRequest({
    				api: "com.taobao.favorite.api.deleteCollect",
    				v: "1.0",
    				data: {
    					infoId: G_msp_shopId + "0"
    				}
    			},
    			{
    				succ: function() {
    					b.isCollect = "false",
    					d.removeClass("h"),
    					notification.simple("取消收藏成功")
    				},
    				fail: function(a) {
    					var b = a.errcode;
    					"FAIL_SYS_SESSION_EXPIRED" == b ? c.goLogin({
    						rediUrl: location.href,
    						hideType: !0
    					}) : notification.simple("取消收藏 出错了")
    				}
    			}), G_logStatis("", "click_shop_cancelfav")) : -1 == e ? g() : f()
    		},
    		rendered: function() {
    			function b(a, b) {
    				if ("[object Array]" == Object.prototype.toString.call(a.data.itemList)) {
    					var c = a.data.itemList,
    					e = c.length;
    					if (e) {
    						var f = {
    							len: e,
    							rvList: c
    						};
    						b.after(templates.index_recent_view.render(f)),
    						b.css("padding-bottom", "0"),
    						d()
    					}
    				}
    			}
    			function c() {
    				var a = document.body.offsetWidth;
    				return G_isPad && (a = k.width()),
    				a
    			}
    			function d() {
    				e.calcRv(m),
    				l = new f(".rv-slider", {
    					visible: 3
    				})
    			}
    			var e = this,
    			f = window.lib.Slider,
    			g = "onorientationchange" in window,
    			h = g ? "orientationchange": "resize";
    			e.$el.find(".js-fav-btn").on("click",
    			function(a) {
    				e.favdo.call(e, a)
    			});
    			var i = e.$el.find(".js-msp-md1");
    			document.title = i.find(".img-title").find(".title").text();
    			var j = 1 == e.$el.find(".msp-md").length,
    			k = this.mainEle = e.$el;
    			G_isPad && (k = e.$el.find(".js-main")),
    			j ? k.append('<div style="height:200px;line-height:200px;text-align:center;">新店铺开张,店铺装修中</div>') : (k.append('<div class="js-all-gls allg-btn"><a href="#">查看所有宝贝</a></div>'), $(".js-all-gls").on("click",
    			function(b) {
    				b.preventDefault(),
    				a.navigation.push("list", {
    					type: "GET",
    					data: {
    						catId: "",
    						catTxt: encodeURIComponent("所有宝贝")
    					}
    				})
    			})),
    			$(".js-msp-logo").on("click",
    			function() {
    				G_msp_not_show_info || $(".js-nav-info").trigger("click")
    			}),
    			G_in_server ? lib.login.isLogin() && (lib.mtop.request({
    				api: "mtop.favorite.checkUserCollect",
    				v: "1.0",
    				data: {
    					type: "0",
    					itemId: G_msp_shopId
    				}
    			},
    			function(a) {
    				e.isCollect = a.data.isCollect,
    				"true" == a.data.isCollect && e.$el.find(".fav-icon").addClass("h")
    			},
    			function() {}), j || lib.mtop.request({
    				api: "com.taobao.wireless.shop.recentview.items",
    				v: "1.0",
    				data: {
    					shopId: G_msp_shopId
    				}
    			},
    			function(a) {
    				b(a, i)
    			},
    			function() {})) : b(recent_view_data, i);
    			var l, m = c();
    			e.calcBan(m);
    			var n = {
    				visible: 1,
    				trigger: ".slider-status",
    				hasTrigger: !0,
    				loop: !0,
    				play: !0,
    				interval: 3e3
    			},
    			o = new f;
    			o.attachTo(".slider", n),
    			$(window).on(h,
    			function() {
    				var a = c();
    				e.calcBan(a),
    				o.attachTo(".slider", n),
    				e.calcRv(a),
    				l && l.reset({
    					visible: 3
    				})
    			})
    		},
    		calcRv: function(a) {
    			var b = this,
    			c = parseFloat(a),
    			d = b.$el.find(".js-rv"),
    			e = d.find(".js-rv-des"),
    			f = d.find(".rv-slider-outer"),
    			g = Math.floor(.21875 * c);
    			f.css({
    				width: Math.floor(.73125 * c),
    				height: g
    			}),
    			f.find("li").css({
    				width: Math.floor(.24375 * c),
    				height: g
    			});
    			var h = {
    				width: g,
    				height: g
    			};
    			f.find("a").css(h),
    			e.css(h)
    		},
    		calcBan: function(a) {
    			var b = this,
    			c = parseInt(.95 * parseFloat(a)),
    			d = b.$el.find(".slider"),
    			e = d.find(".slider-outer"),
    			f = parseInt(c / 2),
    			g = {
    				width: c,
    				height: f
    			};
    			d.css(g),
    			e.css(g),
    			e.find("li").css("width", c)
    		},
    		show: function() {
    			if (window.G_pg_name = "index", !G_isPad) {
    				var a = $(".js-nav-mid-wrap");
    				a.addClass("none"),
    				$(".js-nav-r-wrap").removeClass("none");
    				var b = $(".js-nav-info");
    				b.removeClass("sort").addClass("info").html(b.attr("data-info")),
    				G_popLayer.content.find(".js-sc-m-title").removeClass("highlight"),
    				"show" == G_popLayer.wrapDiv.attr("p_show") && G_popLayer.hide()
    			}
    		},
    		startup: function() {
    			$(".content").hide(),
    			$("#we-page").show()
    		}
    	};
    	G_isPad && $.extend(b, msppad.index_comment),
    	a.definePage(b),
    	document.getElementById("we-page") && (document.getElementById("we-page").style.height = document.documentElement.clientHeight - 44 - 98 + "px")
    } (window.app),
    function(a) {
    	var b = {
    		name: "list",
    		route: "list",
    		show: function() {
    			if (window.G_pg_name = "goodsList", !G_isPad) {
    				$(".js-nav-mid-wrap").removeClass("none").removeClass("center").find(".js-nav-glist").removeClass("none").siblings(".js-nav-comm").addClass("none"),
    				$(".js-nav-r-wrap").removeClass("none");
    				var a = $(".js-nav-info");
    				a.removeClass("info").addClass("sort").html(a.attr("data-sort"))
    			}
    			window.scrollTo(0, 1)
    		},
    		mainHtm: function() {
    			var a, b = ['<div class="js-nav-glist pad-gl-des">', '<div class="js-nav-title title omit"></div>', '<div class="js-nav-des des omit"></div>', "</div>"].join(""),
    			c = ['<form class="js-filter-form pad-gl-filter">', '<div class="condi">', '<input class="js-start-price inp" type="text" placeholder="最低价" value="" />元~', '<input class="js-end-price inp" type="text" placeholder="最高价" value="" />元', "</div>", '<div class="finish clearfix">', '<input class="js-filter-submit fin-btn" type="submit" value="完成" />', "</div>", "</form>"].join(""),
    			d = ['<ul class="g-tab" id="js-gl-sort">', '<li data="oldstarts" class="cur">上新</li>', '<li data="hotsell">销量</li>', '<li data="bid" class="price-flag up">价格</li>', '<li data="isPromotion">促销</li>', "</ul>", "</div>"].join(""),
    			e = '<div class="js-goods-list goods-list"></div>',
    			f = '<div id="gl-pagenav"></div>';
    			if (G_isPad) {
    				d = '<div class="pad-gl-nav">' + d;
    				var g = '<div class="pad-gl-top clearfix">' + b + d + c + "</div>";
    				a = '<div class="goods-list-pg-wrap">' + g + e + f + "</div>"
    			} else d = '<div class="sub-nav pad-gl-nav">' + d,
    			a = '<div class="goods-list-pg-wrap">' + d + e + f + "</div>";
    			return a
    		},
    		format_url: function(a) {
    			var a = $.extend({},
    			a);
    			return a.currentPage || (a.currentPage = 1),
    			a.hasOwnProperty("q") && (a.q = decodeURIComponent(a.q)),
    			!a.hasOwnProperty("sort") && !a.hasOwnProperty("isPromotion") && (a.sort = "oldstarts"),
    			!a.hasOwnProperty("q") && !a.hasOwnProperty("catId") && (a.q = ""),
    			a
    		},
    		change_state: function(a) {
    			var b = this,
    			a = $.extend({},
    			a),
    			c = a.q;
    			a.hasOwnProperty("q") && !a.q && (c = "所有宝贝");
    			var d, e;
    			G_isPad ? (e = b.$el, d = e.find(".js-nav-title")) : (d = $(".js-nav-title"), e = G_popLayer.content),
    			d.text(decodeURIComponent(c || a.catTxt || " ")),
    			"undefined" != typeof a.q ? (e.find(".js-s-txt").val(decodeURIComponent(a.q)), e.find(".js-sc-m-title").each(function() {
    				$(this).removeClass("highlight")
    			})) : "undefined" != typeof a.catId && e.find(".js-sc-m-title").each(function(b, c) {
    				var d = $(c);
    				d.attr("data-id") == a.catId ? d.addClass("highlight") : d.removeClass("highlight")
    			}),
    			b.$el.find("#js-gl-sort").find("li").each(function() {
    				var b = $(this),
    				c = b.attr("data"); (c == a.sort || "isPromotion" == c && a.hasOwnProperty("isPromotion") || "bid" == c && "_bid" == a.sort) && (b.addClass("cur"), b.siblings().removeClass("cur")),
    				"bid" == c && "_bid" == a.sort && (b.addClass("down"), b.removeClass("up"))
    			})
    		},
    		renderItem: function(a, b) {
    			var c = this,
    			d = b,
    			e = c.pg,
    			f = c.goodsListItems;
    			"init" == d || "sort" == d || "filter" == d ? (e.eventDetach(), e.init({
    				index: 1,
    				pageCount: Math.ceil(a.totalResults / a.pageSize),
    				disableHash: !0
    			}), $(".js-nav-des").text(a.totalResults + "个宝贝")) : e.setIndex(a.currentPage),
    			f.render(a),
    			setTimeout(function() {
    				G_isPad ? msppad.replace(c.$el, "210x210") : lazyload.img.trigger(),
    				window.scrollTo(0, 1)
    			},
    			500)
    		},
    		bind_domEvt: function() {
    			function a(a) {
    				var c = a,
    				d = b.urlData;
    				switch ("isPromotion" == c ? ($.extend(d, {
    					isPromotion: "true",
    					currentPage: 1
    				}), delete d.sort) : (delete d.isPromotion, $.extend(d, {
    					sort: c,
    					currentPage: 1
    				})), msp.goods_list.ajax(d,
    				function(a) {
    					b.renderItem(a, "sort")
    				}), c) {
    				case "oldstarts":
    					G_logStatis("", "click_shop_new");
    					break;
    				case "hotsell":
    					G_logStatis("", "click_shop_sale");
    					break;
    				case "bid":
    					G_logStatis("", "click_shop_priceasc");
    					break;
    				case "_bid":
    					G_logStatis("", "click_shop_pricedesc");
    					break;
    				case "isPromotion":
    				}
    			}
    			var b = this,
    			c = b.$mainWrap;
    			c.find("#js-gl-sort").on("click", "li",
    			function(b) {
    				var c = $(b.currentTarget);
    				c.addClass("cur"),
    				c.siblings("li").removeClass("cur"),
    				c.hasClass("price-flag") ? c.hasClass("up") ? (c.removeClass("up"), c.addClass("down"), c.attr("data", "_bid")) : (c.removeClass("down"), c.addClass("up"), c.attr("data", "bid")) : c.siblings(".price-flag").removeClass("up").removeClass("down"),
    				a(c.attr("data"))
    			});
    			var d;
    			d = G_isPad ? c: G_popLayer.content;
    			var e = function(a, b) {
    				return a || b ? a && !/^[0-9.]+$/.test(a) || b && !/^[0-9.]+$/.test(b) ? (notification.simple("请输入数字"), !1) : !0 : (notification.simple("请输入价格"), !1)
    			};
    			d.find(".js-filter-form").on("submit",
    			function(a) {
    				a.preventDefault();
    				var c = $.trim($(".js-start-price").val()),
    				d = $.trim($(".js-end-price").val());
    				if (e(c, d)) {
    					var f = {};
    					c && (f.startPrice = parseFloat(c)),
    					d && (f.endPrice = parseFloat(d)),
    					delete b.urlData.startPrice,
    					delete b.urlData.endPrice;
    					var g = b.urlData;
    					$.extend(g, f),
    					msp.goods_list.ajax(g,
    					function(a) {
    						b.renderItem(a, "filter")
    					}),
    					G_isPad || G_popLayer.hide()
    				}
    			});
    			var f = b.$el.find("#gl-pagenav");
    			b.pg = new lib.PageNav(f, {
    				pageCount: 1,
    				disableHash: !0
    			}),
    			b.pg.$container.on("P:switchPage",
    			function(a, d) {
    				G_isPad ? c[0].scrollTop = 0 : window.scrollTo(0, 1);
    				var e = b.urlData;
    				$.extend(e, {
    					currentPage: d.index
    				}),
    				msp.goods_list.ajax(e,
    				function(a) {
    					b.renderItem(a, "pagenav")
    				})
    			})
    		},
    		startup: function() {
    			var b = this;
    			window.G_pg_name = "goodsList";
    			var c = b.format_url(a.navigation.getParameters()),
    			d = b.mainHtm(),
    			e = b.$el;
    			G_isPad ? (b.html(b.template()), e = b.$el.find(".js-main"), e.html(d), b.showCates()) : b.html(d),
    			b.change_state(c),
    			this.$mainWrap = e,
    			this.goodsListItems = a.getView("goodsListItem"),
    			e.find(".js-goods-list").append(this.goodsListItems.el),
    			this.urlData = c,
    			b.bind_domEvt(),
    			msp.goods_list.ajax(c,
    			function(a) {
    				b.renderItem(a, "init")
    			}),
    			G_isPad ? msppad.replace(b.$el, "210x210") : window.lazyload.init({
    				definition: !0,
    				size: "210x210"
    			})
    		}
    	};
    	G_isPad && $.extend(b, msppad.list),
    	a.definePage(b)
    } (window.app),
    function(a) {
    	a.extendView({
    		name: "goodsListItem",
    		el: "ul#js-goods-list-items.goods-list-items",
    		render: function(a, b) {
    			var c = {};
    			$.extend(!0, c, a),
    			c.itemsArray && c.itemsArray.forEach(function(a) {
    				a.salePrice = "¥" + a.salePrice,
    				a.reservePrice = "¥" + a.reservePrice,
    				a.salePrice == a.reservePrice && (a.reservePrice = ""),
    				"¥" == a.salePrice && (a.salePrice = a.reservePrice, a.reservePrice = ""),
    				a.link = lib.uri.getUrl({
    					subdomain: "h5",
    					path: "awp/core/detail.htm",
    					data: {
    						id: a.auctionId
    					}
    				}),
    				0 === a.link.search("http:") && (a.link = a.link.slice(5))
    			}),
    			this.$el.html(templates.goods_list_item.render(c)),
    			b && b()
    		}
    	})
    } (window.app),
    function(a) {
    	var b = {
    		name: "comments",
    		route: "comments",
    		show: function() {
    			if (window.G_pg_name = "comments", !G_isPad) {
    				var a = $(".js-nav-mid-wrap");
    				a.removeClass("none").addClass("center").find(".js-nav-glist").addClass("none").siblings(".js-nav-comm").removeClass("none"),
    				$(".js-nav-r-wrap").addClass("none"),
    				G_popLayer && "show" == G_popLayer.wrapDiv.attr("p_show") && G_popLayer.hide()
    			}
    			window.scrollTo(0, 1)
    		},
    		startup: function() {
    			function b(a) {
    				i.render(a),
    				"nav" == j ? (m.eventDetach(), m.init({
    					index: 1,
    					pageCount: Math.ceil(a.totalResults / a.pageSize),
    					disableHash: !0
    				})) : (n && (m.eventDetach(), m.init({
    					index: 1,
    					pageCount: Math.ceil(a.totalResults / a.pageSize),
    					disableHash: !0
    				}), n = !1), m.setIndex(a.currentPage))
    			}
    			function c() {
    				o.replaceWith('<div class="comment-tmall-txt">买家评论</div>')
    			}
    			var d = this;
    			window.G_pg_name = "comments";
    			var e = '<div class="comments-pg-wrap"><ul class="js-comm-nav comment-nav"></ul><div class="js-comment-list comment-list"></div><div id="comm-pagenav"></div></div>',
    			f = d.$el;
    			G_isPad ? (d.html(d.template()), f = d.$el.find(".js-main"), f.html(e), d.shopInfo()) : d.html(e);
    			var g = function(a) {
    				var b = templates.comments_nav.render(a);
    				f.find(".js-comm-nav").html(b)
    			},
    			h = a.navigation.getParameters();
    			h && h.hasOwnProperty("goodSeller") && h.hasOwnProperty("neutralSeller") && h.hasOwnProperty("badSeller") ? g(msp.commNum.dataOpe(h)) : msp.commNum.ajax({},
    			function(a, b) {
    				g(b)
    			});
    			var i = a.getView("commentsItem");
    			this.$el.find(".js-comment-list").append(i.el);
    			var j, k = "2",
    			l = d.$el.find("#comm-pagenav"),
    			m = new lib.PageNav(l, {
    				pageCount: 1,
    				disableHash: !0
    			}),
    			n = !0,
    			o = this.$el.find(".js-comm-nav");
    			o.on("click", "li",
    			function(a) {
    				var c = $(a.currentTarget);
    				c.addClass("sel"),
    				c.siblings().removeClass("sel"),
    				"0" != c.attr("n") ? (k = c.attr("s"), j = "nav", m.$container.show(), msp.comments_list.ajax({
    					rateResult: k,
    					pageNo: 1
    				},
    				function(a) {
    					b(a[k][1])
    				})) : (m.$container.hide(), i.render({
    					rateList: []
    				}))
    			});
    			var p;
    			"undefined" != typeof G_isMall && (p = G_isMall);
    			var q = $.type(p),
    			r = {
    				rateResult: k,
    				pageNo: 1
    			};
    			"undefined" == q ? $.extend(r, {
    				requireMall: !0
    			}) : "boolean" == q && p && c(),
    			msp.comments_list.ajax(r,
    			function(a) {
    				var d = a[k][1];
    				b(d),
    				r.hasOwnProperty("requireMall") && (p = d.isMall, "true" == p && c()),
    				0 == parseInt(d.totalResults) && f.find("#comm-pagenav").hide()
    			}),
    			m.$container.on("P:switchPage",
    			function(a, c) {
    				j = "pagenav",
    				G_isPad ? f[0].scrollTop = 0 : window.scrollTo(0, 1),
    				msp.comments_list.ajax({
    					rateResult: k,
    					pageNo: c.index
    				},
    				function(a) {
    					b(a[k][c.index])
    				})
    			})
    		}
    	};
    	G_isPad && $.extend(b, msppad.index_comment),
    	a.definePage(b)
    } (window.app),
    function(a) {
    	a.extendView({
    		name: "commentsItem",
    		el: "ul#js-comments-items.comments-items",
    		render: function(a, b) {
    			var c = {};
    			$.extend(!0, c, a),
    			c.rateList && c.rateList.forEach(function(a) {
    				a.link = lib.uri.getUrl({
    					subdomain: "h5",
    					path: "awp/core/detail.htm",
    					data: {
    						id: a.auctionNumId
    					}
    				}),
    				0 === a.link.search("http:") && (a.link = a.link.slice(5))
    			}),
    			this.$el.html(templates.comments_item.render(c)),
    			b && b()
    		},
    		destroy: function() {}
    	})
    } (window.app),
    function(a) {
    	"use strict";
    	function b(a) {
    		var b = $(a.target);
    		b.parents(".js-side").length || b.hasClass("js-side") || b.parents(".js-main").length || b.hasClass("js-main") || a.preventDefault()
    	}
    	G_isPad && ($("#js-viewport").append('<section class="content"></section>'), console.log("isPad"), $(document).on("click", ".js-nav-back",
    	function() {
    		a.module.Navigation.instance.getStack().getIndex() ? a.navigation.pop() : document.referrer ? history.back() : location.href = "//m.taobao.com/"
    	}).on("click", ".js-nav-info",
    	function() {
    		a.navigation.push("index"),
    		G_logStatis("", "click_shop_shopinfo")
    	}).on("click", ".js-nav-csch",
    	function() {
    		a.navigation.push("list"),
    		G_logStatis("", "click_shop_inshopsort")
    	}).on("touchmove", b)),
    	a.start()
    } (window.app);







    相关文章

    ES6 Promise 实践 Tips Pt.2 (升级现有代码)

    Tue, May 19, 2015

    前言

    在上一篇 (ES6 Promise 实践 Tips Pt.1) 中, 我们总结了一些在使用ES6 Promise模型进行编程时的注意事项,但多面向基于promise实例方法来编写异步流程的场景。现在我们回过头来关注如何改造现有需要传入回调函数来实现异步执行的功能代码,使其返回promise对象实例。

    现状

    由于JavaScript中没有线程模型,为了在执行需要耗时较久的任务(比如网络请求和动画)时不阻塞后续逻辑或失去对用户操作的反馈,我们一般的做法是指定一个回调函数,让需要长时间执行的任务在状态发生变化时调用以便获取任务执行结果(比如XMLHttpRequest对象实例上的onreadystatechange方法 ,或正在执行动画的DOM元素上的transitionend事件触发函数)。

    例如:

    function massiveTask(requirement , successCB, errorCB){
         console.log("begin working on :" + requirement);
         setTimeout(function(){
            try{             
            var result = requirement + "done";
            successCB && successCB(result);
            } catch (err){
            errorCB && errorCB(err);                    
            }
          },3000)
    }
    
    // massiveTask 调用见下文
    
    

    如果我们现在需要把上面的代码改造为支持 ES6 Promise ,我们该怎么做呢?

    在Promise对象创建时处理异步逻辑

    在大多数介绍 ES6 Promise 的文章中或例子中,都会把业务逻辑封装为Promise构造函数所需要的参数, 例如下面这样

    function massiveTask(requirement){
        var p = new Promise(function(resolve,reject){
            console.log("begin working on :" + requirement);
            setTimeout(function(){
              try{        
                var result = requirement + "  done";
                resolve(result);
               }catch (err){
                reject( err);           
               }
            },3000);
        })
        return p;
    }
    
    

    这里特别需要注意的是, Promise 构造函数所需要的参数的类型是一个有两个参数的函数 , 这两个参数又分别是用来传递结果和用来报告错误的的函数.

    这种方式生成Promise对象最为直接,不过如果想更完备一些,我们需要考虑

    • 对异常情况的处理
    • 对传统callback回调函数风格的支持.
    • 在不支持Promise环境的环境运行不能报错.

    考虑以上几点后的代码会进化成这样:

    
    function massiveTask(requirement ,successCB, errorCB){
        var DummyPromise = function( func ){
            func();
        }
        var P = window.Promise || DummyPromise;
        
        var p = new P(function(resolve,reject){
            console.log("begin working on :" + requirement);
            setTimeout(function(){
            try{        
                var result = requirement + "  done";
                successCB && successCB(result);            
                resolve && resolve(result);
            } catch (err){
                errorCB && errorCB(err);            
                reject && reject(err);
              }
            },3000)
            
        })
        
        return  window.Promise ? p ; null ;
    }
    
    

    在进行了如上改造后, 我们就既能以传统 callback 函数方式调用

    massiveTask("earn 100 million",
                function(res){
                    console.log("i need report");
                    console.log(result) ;
                    console.log("good job");                
                },
                function(error){
                    console.log("WTF?  you are been fired ");                
                }
               );
    
    

    也能用 promise 方式调用

    
    var workResult = massiveTask("earn 100 million");
    
    workResult.then(function(result){
        console.log("i need report");
        console.log(result) ;
        console.log("good job");                
    }).catch(function(error){
        console.log("WTF?  you are been fired ");
    })
    
    

    如果是新写的代码或需要改造的逻辑比较简单,可以采用上面这种直观,完备的改造方法。 但如果需要改造的代码较为复杂,上面的方法就会暴露改造范围较大且引入多一层嵌套的问题,使得代码Review和后续维护都不易进行. 这种情况下,我们就要考虑用不同的方法来解决问题.

    在异步业务开始前创建Promise对象

    认真观察上面经过改造过支持Promise的代码,我们能发现要支持Promise实际上最关键的只需要在支持Promise的环境中 (1.)创建并返回Promise对象. (2.)使用resolve和reject来传递结果或报告错误. 我们能不能以某种形式让这部分代码和我们待改造的代码分离呢? 比如如下这样:

    function massiveTask(requirement , successCB, errorCB){
        var promiseData = {promise: null,resolver: null,rejecter: null};
        if (!successCB && window.Promise){
          promiseData.promise = new Promise(function (resolve, reject) {
            promiseData.resolver = resolve;
            promiseData.rejecter = reject;
          });
        }
        
        console.log("begin working on: " + requirement);
        setTimeout(function(){
            try{
                var result = requirement + "  done";
                promiseData.promise && promiseData.resolver(result);        
                successCB && successCB(result);
            }catch (err){
                promiseData.promise && promiseData.rejecter( err);        
                errorCB && errorCB(err);            
            }
        },3000)
        
        if ( promiseData.promise ){
            return promiseData.promise;
        }
    }
    
    

    虽然代码的行数稍微有些增长,但我们做到了最大程度的Promise支持与原有业务代码的分离. 在正常业务代码部分仅需在原本需要回调函数执行的位置增加一行利用提前存储起来的resolver来传递执行结果的代码即可。

    总结

    作为ES6引入新特性中被当前浏览器支持得较好,同时又能被较好的在老旧浏览器中被polyfill补全的重要特性, Promise已经获得了越来越广泛的使用, 如果你想给你手头的老旧代码带来新的活力,不妨现在就开始为她增加ES6 Promise支持。

    下面我们做什么

    Tue, May 5, 2015

    背景

    基础产品型前端项目(承载海量用户,要求高可靠性,需要长期维护持续改进)虽然仍然具备前端项目共通的更新方便,发布灵活特点.但由于维护周期较长,业务影响范围大,需要我们相比运营形项目或快速迭代主动试错型项目更加注重质量和优化.

    在最近两年的前后端分离改造后,前端项目得以从整体Web项目中独立出来,有了更加自主的工作空间以应接业界不断提升的对交互体验的极致追求.同时,随着模块化,依赖管理,构建技术的引入,前端项目的开发流程和可改进优化空间也有了巨大的变更.很多以往多运用于服务端或客户端的软件开发技术和流程(编译优化,自动化测试,持续集成 etc..)现在也能逐步运用于前端项目.

    但同时我们也在不断经历着难于维护或完全没有维护性的项目;虽然有了构建过程,但不完整;在使用了发布平台托管HTML后,托管的版本和代码库中的版本逐渐变得不统一,以至代码库失去完整性.随着项目功能的不断增加及维护时间的延长,项目中的技术债逐渐积累,优化难于下手,偶尔为之的优化由于缺乏可显性和记录,逐渐难于持续.

    在新的财年中,出于以上的背景和问题,我们可以在以下几方面争取有所作为.

    项目质量改进

    过去一年里,我们建立起了项目质量保证Checklist和代码CodeReview机制,今年应该延续,在此之外,为进一步提高项目质量,我们需要对 构建/发布流程;自动化测试;项目工程文档进行改进和完善.

    构建/发布流程

    • 更深入的了解学习 Npm,Grunt/Gulp ,规范化npm package描述和Grunt/Gulp脚本,尝试把HTML中引入的库在npm package 依赖中有所体现.
    • 构建过程覆盖完整, 托管于AWP/MT的HTML应该由构建过程生成.
    • 发布过程应该更加自动化,尽量的避免重复的粘贴与手工修改.

    自动化测试与持续集成

    • 对于现成业务,应该尝试使用BDD对关键业务流程进行覆盖.
    • 对于新业务,时间允许的情况下应该尝试对关键模块编写TDD用例.
    • 尝试把测试用例接入Gitlab持续集成过程,避免测试腐化.

    项目工程文档完善

    • 对项目代码组织方式,关键模块需要有记录并及时更新.
    • 对项目运行环境(测试,预发,正式)以及正常访问所需URL Schema需要有记录并及时更新.
    • 对项目配置项及修改入口需要有记录.

    可度量的优化

    为什么健康手环这么火热,特别在健身人群中,因为这种小工具让健身进展变得可测量并能数据化显示出来.为什么统计,埋点对运营这么重要,因为这能对运营效果进行测量,如果没有这些数据,运营同学就只能凭空猜测运营活动的效果,设计运营方案时也会变得盲目和主观.

    类似的,我们要对代码进行优化的第一步也应该是对改进项进行测量(Profiling),并建立起对Profiling数据的记录.多维度的Profiling数据应该成为我们描述自己项目时的关键一项.这些可能的维度有

    • 首次加载时的请求数.
    • 所需下载的静态资源体积.
    • 在可测量环境中(Chrome/PhantomJS)执行完主要业务流程的内存占用.
    • 在可测量环境中执行关键交互时的帧率.

    平台化与SDK

    平台化是本财年大部门对技术团队的重要目标. 对应到我们团队,我们手头的众多项目天然就是作为支撑无线淘宝及兄弟团队业务的基础平台存在.在这个基础之上,我们没有理由不朝这个目标尽量前进一些.对这个目标的细化,我目前想到如下一些:

    • 优化整个m.taobao.com的访问体验,准备兼容新的移动平台.
    • 尝试从工程上把业务逻辑和UI/UE界面分离, 在改善工程质量的同时让基础业务做好更好服务其他团队和产品的准备.
    • 尝试把分离后的核心业务逻辑模块作为SDK完善和推广.

    综上, 项目质量改进,可度量的优化,平台化与SDK 这三项是我认为本财年我们团队在支持好业务方之外值得共同努力的方向.

    Learn To FE AutoTest

    Mon, Apr 27, 2015

    前言

    前端自动测试在强调快速完成速度的环境常常不能获得足够支持,以至大家在这个领域实践较少.但随着业务环境的变化和技术的发展,这种情况会发生变化. 以下是我又一次实践前端自动测试的总结,希望能对大家进行尝试时有所帮助.

    TDD/BDD

    • TDD: Test Driven Development ,用测试代码来固化需求,针对测试代码编写实现代码,再重构实现代码的一种开发方法论.

    • BDD: Behaviour Driven Development ,相对TDD侧重模块API,BDD更加注重业务描述,追求基于用户故事,由外及内和让测试用例更加贴近自然语言.

    受BDD的影响,出现了越来越接近自然语言的断言库 ,我们可以称他们BDD风格的断言库。虽然是BDD风格,但不妨碍我们用这样的断言库写TDD流程的测试.

    前端测试框架的分类和选型参考

    基于浏览器的框架

    在浏览器里把测试框架和其他JavaScript脚本一并引入。测试结果直接显示在浏览器里。 这种方式比较直观,但不易于接入更为完整的工作流内。jasmine是当前这种类型测试框架里不错的选择.

    基于Node环境的框架

    在Node环境运行,并以Node模块的方式加载测试用例,测试结果在终端显示. 如果是Node项目或者以Node模块组织代码的前端项目( 通过 browserify 提供给浏览器使用),这种类型的测试框架能最好的为你服务. 该类别中 Mocha 目前较为流行.

    基于Server / Client 结构的测试框架

    这种方式通过让浏览器接入一个Server,再由这个Server向接入的浏览器下发测试用例,让其同时兼备上面提到的两种类型的特点 (代码运行于浏览器,同时在终端获取测试结果)。这种方式在需要测试不同浏览器的JavaScript执行环境的情景特别适合,但部署比较麻烦。 Google系较旧的jsTestDriver 和伴随Angularjs发展起来的Karma和支付宝的totorojs 都是以这种思路实现的.

    我自己先后学习过jsTestDriver , jasmine 和 mocha.

    如果一个项目能从底层就开始以TDD思想作为指导编写测试,根据场景特点,以上提到的框架都是不错的选择。但如果是想通过编写测试对一个已成型项目进行质量保障,我们就要借鉴BDD思想做出新的选择。

    基于浏览器行为的测试框架

    除了以TDD的思路从每一个模块,每一个函数这样从内及外的去测试我们的代码。我们也能从外到内的去测试我们的项目, 比如给定时间内你的页面是否如预期的渲染出来 ; 比如点击特定元素时,浏览器是否切换到了预期的URL ; 比如加载一份特定mock数据时,页面上是否渲染出了预期的内容.

    这时我们就可以利用基于浏览器行为的框架来对项目进行测试.

    selenium是一套控制浏览器的强大工具, 我们可以利用它来进行浏览器行为测试。但selenium的设计意图是一套提供给专业测试人员的可视化IDE , 而不仅仅是能方便集成于开发工作流的测试框架,所以用起来会有一些不便。

    幸好有更好的选择 , PhantomJS 和CasperJS 。

    PhantomJS是剥离了显示部分的Webkit(headless webkit ), 和其他基于WebKit的浏览器不同, PhantomJS没有提供哪怕最简单的UI界面,但提供了一套控制WebKit的 API . 我们可以利用它的API加载任意URL,然后像在Chrome控制台中一样对页面进行探知或执行代码获取结果.

    CasperJS是在PhantomJS之上的抽象层,它包裹了PhantomJS的底层方法,以更高级,更方便开发者使用的API暴露出来. 通过CasperJS我们可以更直观的编写浏览器控制代码,触发事件,探测页面DOM结构。

    好上加好的是, 我们还能结合CasperJS 和 Mocha 。利用mocha-casperjs 我们可以用Mocha作为框架,定义我们项目在特定行为发生时应该具备的表现. 然后在用例里以CasperJS来重现特定行为,并判断表现是否符合预期。

    例如以下这个例子

     it('Test Demo From H5 Detail', function() {
          casper.start(TEST_TARGET_URL);    //打开特定URL
          return casper.waitFor(function() {  //直到传入函数返回True
            return this.exists('#J_detail_main');
          }, function() {
            var itemTitle;
            itemTitle = this.fetchText('.dtif-h');
            return expect(itemTitle).to.be.a('string');
          }, function() {
            return this.echo('页面未能加载出商品信息', 'ERROR');
          }, 1000); // 1s 超时阈值
        });
    

    这是一个mocha测试用例,其中测试了在访问TEST_TARGET_URL时,页面在1秒之内是否已经渲染出了”#J_detail_main”元素,同时”.dtif-h”元素是否存在并包含文本内容。

    另一个例子

    it('Another Test Demo From H5 Detail', function() {
          casper.start(TEST_TARGET_URL);
        return casper.waitFor(function() {  
            return this.exists('#J_detail_main');
          }, function() {      
            this.mouseEvent('click', '.dt-sku'); //模拟点击
            return casper.wait(700, function() {
              var targetClass;
              expect(this.visible('.dt-sku')).to.be["false"];
              expect(this.visible('#J_detail_skum')).to.be["true"];
              targetClass = this.getElementAttribute('.dgsc-pc i:nth-child(1)', 'class');
              expect(targetClass).to.eql('sel');
            });
     });
    

    这个例子中,我们测试了点击页面元素”.dt-sku”后,页面在700毫秒内是否已经符合我们一系列的判断。

    得益于Mocha在Node环境中非常好的可集成性, 我们可以把Mocha和现有的 Grunt / Gulp 构建流程整合在一起,在每一次构建,准备发布时为我们的项目增加一重或许能避免重大事故的保障。

    ES6 Promise 实践 Tips Pt.1

    Mon, Apr 13, 2015

    Promises是一种成熟的异步编程模型, 它把程序中的特定后续状态抽象为Promise对象实例,让我们可以方便的对该未来状态进行编程. 在JavaScript世界中,Promises模型有着众多的实现. 虽然是同样或相似的思想,但每一种实现都会有一套自己的API或术语,这种分裂状态让我们对Promises的学习增添了不少困扰.

    已经被各浏览器广泛实现的ECMAScript6中对Promise模型进行了精简 , 同时ES6 Promise模型也能在旧版本浏览器中被较好的模拟. 无论为了改善自己的异步编程技巧,还是使用基于ES6 Promise的新Web API(WebFont ,WebMidi)或是释放ES6 Generator的威力, 学习ES6 Promise都是必须的. ES6 Promise API大家可以通过MDN和es6.ruanyifeng.com学习,我在下面会整理一些自己学习/使用Promise过程中的最佳实践.

    NO.1增强异常处理意识

    Promise模型消解“callback hall”的功用已经被之前众多介绍Promise的文章进行了充分强调,这里不继续累述.在实践中除了该项好处之外,Promise模型在优化复杂控制流程,增强代码健壮性 这方面的作用对我们强调高可用性的电商系统也有着非常大的帮助. 从另一个角度看, ES6 Promise在出现异常时不会像jQuery Deferred 模型一样立即抛出异常,而是把Promise实例置为待Reject Handle状态,并向后传递.jQuery的策略有其优势,但这点上也提醒我们在使用ES6 Promise模型时应该更积极主动的思考异常策略,而不是等待最后调试时控制台抛出的大红叉.

    No.2拆解 then 链

    很多大牛在展示自己的Promise代码时喜欢用类似 .then().then().then().then()…… 这样的长长的then链来突出链式调用. 当其中每一步所需的业务逻辑简单或类似时,这种写法有其优势和美感.但当你的业务流程更为复杂或没有重复性时,这样的写法只会让你才出 “callback hall” 又入 “then hall”. ES6 Promise 模型中,无论是使用new或Promise.resolve ,Promise.reject构造实例,还是then或catch方法,你获得的都是另一个Promise对象实例.在编程时,你可以把每一次获得的Promise对象实例想象成未来的一个状态, 为每一个状态起一个能描述该状态的名字作为该Promise对象实例的变量名. 这样,你的Promise代码就能更清晰整洁,同时方便后续更细粒度的封装.

    No.3使用catch来分离 resolve handler 和 reject handler

    ES6 Promise的API几乎是所用Promise模型中最简单的( 构造函数之外,只有四个静态方法resolve,reject,all,race和两个实例方法then,catch ) ,而其中的catch方法实际上是 then(undefined, rejectHandlerFunc) 调用的语法糖 catch(func)的作用相等于在当前Promise对象实例上追加一次.then(undefined, func)调用 . 如此设计,可见API设计者对.catch 调用形式的重视.

    No.4尽量为拆解后的每一步流程建立独立的异常处理机制

    基于以上我们学到的then链拆解和catch使用技巧,我们可以如此这般来整理自己的ES6 Promise代码:

    var domReadyPromise = new Promise(function(resolve,reject){
        $(document).ready(function() {
            resolve();
        })
    });
    
    var requestPromise  = domReadyPromise.then(function(){
        return lib.mtop.request({ api: "mtop.xxx", v: "1.0",data:"..."});
    }).catch(function(e){
        console.error(e);
        throw new Error("mtop 请求错误");
    });
    
    var parserPromise = requestPromise.then(function(reqRes) {
        return parse(reqResres);
    }).catch(function(e){
        console.error(e);
        throw new Error("parser error");
    });
    
    

    这样,我们既能让异步处理流变得清晰明了,又有了改善代码健壮性的机会.

    No.5尝试从异常状态中恢复

    在ES6 Promise模型中, 异常会让then方法把Promise实例置为待RejectHandle处理,并向后传递.就是说整个then链或拆解后的then链中的每次catch调用都有机会处理之前任意步骤时出现的异常. 同时,如任意 .catch(rejectHandler) 或 .then(undefined, rejectHandler) 中没有把截获的异常继续抛出或抛出新的异常. 后续的promise链路将恢复到正常待ResolveHandler处理的状态. 这样,就为我们提供了从异常中恢复的便捷途径:

    
    var requestPromise  = domReadyPromise.then(function(){
        return lib.mtop.request({ api: "mtop.xxx", v: "1.0",data:"..."});
    }).catch(function(e){
        console.error("mtop 请求错误");
        console.error(e);
        var defaultData = {.....};
        return defaultData;
    });
    
    var parserPromise = requestPromise.then(....);
    
    

    如上面的代码,mtop请求时出现了错误,这时我们返回了默认数据,后续的流程将不会受mtop请求失败的影响继续进行.

    其他

    • 我目前在分析中的一个ES6 Promise polyfill

    http://g.alicdn.com/mtb/lab-zikuan/0.0.7/promise/es6-promise.debug.js

    • 支持ES6 Promise的mtop (仅供测试,下个版本的lib-mtop将正式支持ES6 Promise )

    http://g.alicdn.com/mtb/lab-zikuan/0.0.6/mtop/mtop_es6promise.js

    参考

    • http://www.html5rocks.com/en/tutorials/es6/promises/
    • 对jQuery Promise 模型的吐槽
    • jQuery 开发者的观点
    展开全文
  • JavaScript中的作用域链详解

    万次阅读 2016-08-19 17:16:11
    题外话:最近面试一直被问到作用域链的问题,所以还是要深入透彻的学习一下这两个概念。作用域链在红宝书中对作用域链的描述有这么一段话:当代码在一个环境中执行时,会创建变量对象的一个作用域链。作用域链的用途...

    题外话:最近面试一直被问到作用域链的问题,所以还是要深入透彻的学习一下这两个概念。

    作用域链

    在红宝书中对作用域链的描述有这么一段话:当代码在一个环境中执行时,会创建变量对象的一个作用域链。作用域链的用途是保证对执行环境有权访问的所有变量和函数的有序访问。作用域链的前端始终是当前执行的代码所在环境的变量对象。如果这个环境是函数,则将其活动对象作为变量对象。活动对象在最开始时只包含一个变量,即arguments对象。作用域链的下一个变量对象来自包含环境,而在下一个变量对象则来自下一个包含环境。这样一直延续到全局执行环境;全局执行环境的变量对象始终都是作用域链中的最后一个对象。
    这里面有很多概念,比如什么是执行环境、变量对象等。先说明一下这些概念的理解

    执行环境(Execution Context)

    执行环境是JavaScript中的重要概念之一。执行环境定义了变量或函数有权访问的其他数据,决定了他们各自的行为。每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中。
    全局执行环境是最外围的一个执行环境。在Web浏览器中,全局执行环境被认为是window对象,因此所有全局变量和函数都是作为window对象的属性和方法创建的。某个执行环境中的所有代码执行完毕后,该环境被销毁,保存在其中的所有变量和函数定义也随之销毁(全局执行环境知道应用程序退出–例如关闭网页或浏览器—时才会被销毁)
    每个函数都有自己的执行环境。当执行流进入一个函数时,函数的环境就会被推入一个环境栈中。而在函数执行后,栈将其环境弹出,把控制权返回给之前的执行环境。
    执行环境的建立分为两个阶段:进入执行上下文(创建阶段)和执行阶段(激活/执行阶段)
    (1)进入上下文阶段:发生在函数调用时,但在执行具体代码之前。具体完成创建作用域链;创建变量、函数和参数以及求this的值
    (2)执行代码阶段:主要完成变量赋值、函数引用和解释/执行其他代码
    总的来说可以将执行上下文看作是一个对象

    EC = {
        VO:{/*函数中的arguments对象、参数、内部变量以及函数声明*/}
        this:{},
        Scope:{/*VO以及所有父执行上下文中的VO*/}
    }

    变量对象(Variable Object)

    每一个执行环境都对应一个变量对象,在该执行环境中定义的所有变量和函数都存放在其对应的变量对象中。
    (1)进入执行上下文时,VO的初始化过程如下:
    函数的形参:变量对象的一个属性,其属性名就是形参的名字,其值就是实参的值;对于没有传递的参数,其值为undefined;
    函数声明:变量对象的一个属性,其属性名和属性值都是函数对象创建出来的,如果变量对象已经办好了相同名字的属性,则替换它的值
    变量声明:变量对象的一个属性,其属性名即为变量名,其值为undefined;如果变量名和已经声明的函数名或者函数的参数名,则不会影响已经存在的属性
    (2)执行代码阶段,变量对象中的一些属性undefined值将会确定

    这里需要说明一下:函数表达式不包含在变量对象之中

        var foo = 10;  
    
        function bar() {} // function declaration, FD  
        (function baz() {}); // function expression, FE  
    
        console.log(  
          this.foo == foo, // true  
          window.bar == bar // true  
        );  
    
        console.log(baz); // ReferenceError, "baz" is not defined  

    之后,全局上下文的变量对象为
    这里写图片描述

    活动对象

    当函数被调用的时候,一个特殊的对象–活动对象将会被创建。这个对象中包含形参和arguments对象。活动对象之后会作为函数上下文的变量对象来使用。换句话说,活动对象除了变量和函数声明之外,它还存储了形参和arguments对象。

    作用域详解

    由以上介绍可知,当某个函数被调用时,会创建一个执行环境及相应的作用域链。然后,使用arguments和其他命名参数的值来初始化函数的活动对象。但在作用域链中,外部函数的活动对象始终处于第二位,外部函数的外部函数对象处于第三位……直至作为作用域终点的全局执行环境

    function compare(value1,value2){
        if(value1 < value2){
            return -1;
        } else if( value1 > value2 ) {
            return 1;
        } else {
            return 0;
        }
    }

    以上代码定义了compare()函数,然后又在全局作用域中调用了它。当调用compare()时,会创建一个包含arguments、value1、value2的活动对象。全局执行环境的变量对象(包含result和compare)在compare()执行环境的作用域链中则处于第二位。下图包含了上述关系的compare()函数执行时的作用域链
    这里写图片描述
    后台的每个执行环境都有一个表示变量的对象——变量对象。全局环境的变量对象始终存在,而像compare()函数这样的局部环境的变量对象,则只在函数执行的过程中存在。在创建compare()函数时,会创建一个预先包含全局变量对象的作用域链,这个作用域链会被保存在内部的[[Scope]]属性中。当调用compare()函数时,会为函数创建一个执行环境,然后通过赋值函数的[[Scope]]属性中的对象构建起执行环境的作用域链。此后,又有一个活动对象别创建并被推入执行环境作用域链的前端。对于这个例子中,compare()函数的执行函数而言,其作用域链中包含两个变量对象:本地活动对象和全局便朗对象。作用域链本质上是一个指向变量对象的指针列表,它只引用但不实际包含变量对象

    闭包与作用域链

    无论什么时候在函数中访问一个变量时,就会从作用域链中搜索具有相应名字的变量。一般来讲,当函数执行完毕后,局部活动对象就会被销毁,内存中仅保存全局作用域(全局执行环境的变量对象)。但是闭包的情况又有所不同。

    function createComparisionFunction(propertyName) {
        return function(object1,object2) {
            var value1 = object1[propertyName];
            var value2 = object2[propertyName];
            if(value1 < value2){
                return -1;
            } else if( value1 > value2 ) {
                return 1;
            } else {
                return 0;
            }
        }
    }
    

    在另一个函数内部定义的函数会将包含函数(即外部函数)的活动对象添加到它的作用域链中。因此,在createComparisonFunction()函数内部定义的匿名函数作用域链中,实际上将会包含外部函数createComparisonFunction()的活动对象。

    var compare = createComparisonFunction('name');
    var result = compare({name:'Nicolas'},{name:'Greg'});
    
    //解除对匿名函数的引用,以便释放内存
    compareName = null;

    当上述代码执行时,下图展示了包含函数与内部匿名函数的作用域链
    这里写图片描述
    在匿名函数从createComparisonFunction()中被返回后,它的作用域链被初始化为包含createComparisonFunction()函数的活动对象和全局变量对象。这样,匿名函数就可以访问在createComparisonFunction()中定义的所有变量。更为重要的是, createComparisonFunction()函数在执行完毕后,其活动对象也不会被销毁,因为匿名函数的作用域链仍然在引用这个活动对象。即当createComparisonFunction()函数返回后,其执行环境的作用域链会被销毁,但它的活动对象任然会留在内存中;直到匿名函数被销毁后,createComparisonFunction()的活动对象才会被销毁。

    作用域链知识总结

    当代码在一个环境中执行时,都会创建一个作用域链。 作用域链的用途是保证对执行环境有权访问的所有变量和函数的有序访问。整个作用域链的本质是一个指向变量对象的指针列表。作用域链的最前端,始终是当前正在执行的代码所在环境的变量对象。
      如果这个环境是函数,则将其活动对象(activation object)作为变量对象。活动对象在最开始时只包含一个变量,就是函数内部的arguments对象。作用域链中的下一个变量对象来自该函数的包含环境,而再下一个变量对象来自再下一个包含环境。这样,一直延续到全局执行环境,全局执行环境的变量对象始终是作用域链中的最后一个对象。

    参考文献:跟我学习javascript的执行上下文
    javascript执行环境及作用域详解

    展开全文
  • C++ 作用域与生命周期

    千次阅读 2015-08-28 10:58:11
    Pascal之父Nicklaus Wirth曾经提出一个公式,展示出了程序的本质:程序=算法+数据结构。后人又给出一个公式与之遥相呼应:软件=程序+文档。这两个公式可以简洁明了的为我们展示程序和软件的组成。程序的运行过程可以...

    Pascal 之父 Nicklaus Wirth 曾经提出一个公式展示出了程序的本质:程序=算法+数据结构。后人又给出一个公式与之遥相呼应:软件=程序+文档。这两个公式可以简洁明了地为我们展示程序和软件的组成。

    程序的运行过程可以理解为算法对数据的加工过程,程序的运行的结果,就是算法加工数据产生的结果数据。算法描述的是对数据加工的步骤,对应于程序中的函数。数据结构描述的是数据在计算机中的组织结构,对应于程序中的数据类型。程序中数据对应的就是无处不在变量。对于我们编程人员,面对的无非就是函数,数据类型和变量。因此,C++谈及作用域与生命周期针对的就是这三大程序的组成要素:函数、数据类型和变量。下面将一一讲述。

    1.作用域与生命周期的区别

    作用域与生命周期是两个完全不同的概念。在英文中,作用域用 scope 表示,生命周期则用 duration 表示。作用域是一个静态概念,只在编译源程序的时候用到。一个标识符的作用域指在源文件中该标识符能够独立地合法出现的区域。生命周期则是一个运行时概念,它是指一个变量在整个程序从载入到结束运行的过程中存在的时间周期。由于函数和数据类型是静态的概念,它们没有生命周期的说法,它们从编译、程序的运行到结束整个过程是一直存在的。

    C++ 中作用域的级别由高到低,主要有文件域(全局作用域)、名字空间域、类域、函数作用域和代码块作用域,其中函数作用域和代码块作用域又统称为局部域。

    2.函数的作用域

    函数分为类的成员函数和全局函数。

    类的成员函数:

    • 作用域:类域。
    • 生命周期:无(程序运行期一直存在)。
    • 引用方法:其他文件中要使用点操作符(.)或指针操作符(->)或作用域运算符(::)来引用。
    • 内存分布:代码区。
    • 注意:类成员函数可以定义在类体内,即定义在头文件,当类被不同源文件包含时不会报重定义的错误,因为类体内实现的函数具有inline特性。

    举例如下:

    //main.cpp
    class test
    {
    private:
    	int i;
    public:
    	void show()
    	{
    		cout<<"i:"<<i<<endl;
    	}
    };
    int main(int argc,char* argv[])
    {
    	test t;
    	t.show()
    }
    

    全局函数:

    • 作用域:文件域(全局作用域)。
    • 生命周期:无(程序运行期一直存在)。
    • 引用方法:其他文件中要先进行函数原型声明,再使用。
    • 内存分布:代码段。
    • 注意:如果在两个源文件中定义了同名的全局函数,连接时会出现重定义错误。

    举例如下:

    //function.cpp
    void printHello()
    {
    	cout<<"hello world"<<endl;
    }
    
    //main.cpp
    void printHello();
    int main(int argc,char* argv[])
    {
    	printHello();
    }
    

    3.数据类型的作用域

    C++中的数据类型分为基本数据类型和非基本数据类型,非基本数据类型中又分为复合数据类型和构造数据类型。关于C++中的数据类型,详见本人另一篇blog: C++数据类型

    基本数据类型:
    基本数据类型包括整型(int)、实型(float和double)、字符型(char)、布尔型(bool)和无值型(void)。

    • 作用域:文件域(全局作用域)。
    • 生命周期:无(程序运行期一直存在)。
    • 引用方法:无需申明,直接使用。
    • 内存分布:代码段。

    复合数据类型:
    复合数据类型包括:数组(type[])、指针(type*)、引用(type&)、枚举(enum)。

    如果复合数据类型是构造数据类型参与的复合,其作用域与构造数据类型一致。enum枚举类型的作用域与构造类型相同。

    构造数据类型:

    • 作用域:类型定义所在的域,其他文件不可见。
    • 生命周期:无(程序运行期一直存在)。
    • 引用方法:其他文件中要先进行定义,再通过作用域运算符进行使用。
    • 内存分布:代码区。
    • 注意:只要文件不互相包含,如果在两个源文件中定义了同名的构造,不会出现重定义错误,因为数据类型不具有外部连接性。

    举例如下:

    //main.cpp
    namespace dd
    {
    	class test
    	{
    	private:
    		int i;
        public:
    		void show()
    	   	{
    	   		cout<<"i:"<<i<<endl;
    	   	}
    	};
    }
    using namespace dd;//引用命名空间域中的构造类型test,否则无法使用
    int main(int argc,char* argv[])
    {
    	test t;
    	t.show();
    }
    

    4.变量的作用域与生命周期

    我们面对的变量主要分为全局变量、全局静态变量、局部变量和局部静态变量。下面一一讲述他们的作用域与生命周期。

    全局变量:

    • 作用域:全局作用域(全局变量只需在一个源文件中定义,就可以作用于所有的源文件);
    • 生命周期:程序运行期一直存在;
    • 引用方法:其他文件中要使用必须用extern 关键字声明要引用的全局变量。;
    • 内存分布:全局/静态存储区;
    • 注意:如果在两个文件中都定义了相同名字的全局变量,连接出错:变量重定义。

    举例如下:

    //define.cpp  
    int g_iValue = 1;  
      
    //main.cpp  
    extern int g_iValue;  
      
    int main()  
    {  
        cout << g_iValue;  
        return 0;  
    }  
    

    全局静态变量:

    • 作用域:文件作用域(只在被定义的文件中可见);
    • 生命周期:程序运行期一直存在;
    • 内存分布:全局/静态存储区;
    • 定义方法:static关键字,const 关键字;
    • 注意:只要文件不互相包含,在两个不同的文件中是可以定义完全相同的两个静态变量的,它们是两个完全不同的变量。

    举例如下:

    //define.cpp  
    const int iValue=8;   
    
    //main.cpp
    int iValue;  
    static const int iValue_2;  
    static int iValue_3;  
    int main(int argc,char* argv[])
    {
    	cout<<"iValue:"<<iValue<<endl;
    	return 0;
    }
    

    局部变量:

    • 作用域:局部作用域(只在局部作用域中可见,如函数域,代码块域);
    • 生命周期:程序运行出局部作用域即被销毁;
    • 内存分布:栈区;
    • 注意:auto指示符标示。

    举例如下:

    void print()
    {
    	int a=0;
    	cout<<a<<endl;
    }
    

    局部静态变量:

    • 作用域:局部作用域(只在局部作用域中可见);
    • 生命周期:程序运行期一直存在;
    • 内存分布:全局静态存储区;
    • 定义方法:局部作用域用中用static定义;
    • 注意:只被初始化一次,多线程中需加锁保护。

    举例如下:

    void function()  
    {  
        static int iREFCounter = 0;  
    }  
    

    5.扩展知识点

    5.1变量存储类型说明符

    C语言中提供了四种存储类型说明符auto,register,extern和static,四种存储类型有两种存储期:自动存储期和静态存储期。其中auto和register对应自动存储期,被修饰的变量在进入声明该变量的程序块时被建立,它在该程序块活动时存在,退出该程序块时撤销。静态存储期的变量从程序载入运行到程序结束一直存在。

    5.2static使用建议

    (1)若全局变量仅在单个C文件中访问,则可以将这个变量修改为静态全局变量,以降低模块间的耦合度;
    (2)若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低模块间的耦合度;
    (3)设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑重入问题,因为他们都放在静态数据存储区,可被其他函数共享;
    (4)如果我们需要一个可重入的函数,那么我们一定要避免函数中使用static变量。这样的函数被称为带“内部存储器”功能的函数;
    (5)函数中必须要使用static变量情况:比如当某函数的返回值为指针类型时,则必须是static的局部变量的地址作为返回值,若为auto类型,则返回为野指针。

    参考文献

    [1] C++中变量的作用域与生命周期
    [2] C++高级进阶教程[M].陈刚.武汉大学出版社.2.9作用域和生命周期

    展开全文
  • JavaScript作用域链与闭包

    千次阅读 2017-03-16 20:21:40
    作用域链在js中当一个函数执行时发生了什么? 刚开始所有的代码都在全局环境里,当调用一个函数的时候就进入了函数的执行环境里。(执行环境也叫作用域),在作用域内部可以访问到外部的属性,这多亏了一条作用域链...

    作用域链

    在js中当一个函数执行时发生了什么?
    刚开始所有的代码都在全局环境里,当调用一个函数的时候就进入了函数的执行环境里。(执行环境也叫作用域),在作用域内部可以访问到外部的属性,这多亏了一条作用域链把全局环境和局部环境连在一块。
    作用域链到底是什么呢,本质上来说它是一个指针列表,包含一些对象的引用,作用域内部可以访问这些对象的属性(按顺序来)。
    也就是说,只有在作用域链中存在的对象在函数执行时才能访问到。

    最外层是全局对象window,这个对象有哪些属性呢?基本上我们定义的函数和属性都是在window对象上。
    现在考虑一个普通的函数

    var x = 10;
    
    function y() {
        alert(x);
    }
    
    y();

    变量x,函数y都定义在window对象上。当调用y函数时,进入y的作用域,这个作用域中会有两个对象的引用:window对象和y函数的活动对象,可以把活动对象看作是当前执行环境的代表。当在y内调用x变量时,首先找一下作用域最前端对象(也就是y函数的活动对象)上是否有这个变量,没有,下一个,window上,有,OK,就你了。这就是作用域链的作用,存储作用域(执行环境)内能访问的对象引用。
    这是在函数被调用的时候发生的事情,可是函数在执行时怎么知道自己的作用域链是啥呢?其实在函数定义时就已经将函数外部的作用域链存储起来,在函数执行时只需要简单的在最前端加上函数的活动对象就OK了。
    那当函数执行完之后呢,没错,它的活动对象就会从作用域链中消失(被垃圾回收);当然这是在没有其他对象引用活动对象的时候,有的话肯定不能回收啊。由此就产生了闭包。

    闭包

    闭包其实很简单,就是指能访问其他函数作用域中的变量的函数。也就是一个函数而已,只不过这个函数能访问其他函数作用域中的变量。
    至于它为什么能访问,这就归功于作用域链了。由前面对作用域的叙述完全可以自己推出来。
    看例子:

    function y() {
        var x = 100;
        return function() {
            return x;
        }
    }
    
    var z = y();
    alert(z());

    y函数内部的匿名函数可以访问到y函数的x变量。为什么?考虑调用z函数的时候:进入z函数的作用域,它的作用域链里有什么呢?之前的作用域链+z的活动对象。之前的作用域链是什么呢。这就要考虑z函数创建的时候,调用y创建了z,z创建的时候将y的作用域链复制了一份保存下来,注意,这份作用域链列表里是两个指针,一个指向window对象,一个指向y的活动对象。所以z的作用域链里总共有三个指针,比y的多了一个指向z的活动对象的指针。既然y对象能通过z的作用域链找到,那我们当然可以在z中访问它的x属性了。

    闭包的原理就这么多。完全是依靠作用域链的理论。知道作用域链就算不知道有闭包这个东西也没影响。只不过我们想给这种函数起个名字罢了。

    闭包的影响

    所谓的影响就是我们要注意的地方,不能想当然的地方。
    考查闭包就是考查作用域链,一个经典的题目:

    function y() {
        var result = new Array();
    
        for (var i=0; i < 10; i++) {
            result[i] = function() {
                return i;
            };
        }
    
        return result;
    }

    x函数会返回一个函数数组,函数数组每一项都是一个函数,乍一看你可能以为这十个函数肯定依次会返回0~9;
    那我们来细细分析一下:当我们调用这十个函数中第一个函数result[0]的时候进入它的作用域,它会在作用域链中找有i变量的对象,很明显有一个,那就是y函数的活动对象,ok,问题就是这个y活动对象上的变量i是多少,别忘了,我们result[0]作用域链列表中保存的是指向这个对象的指针,我们不是直接把这个对象复制过来了,这个对象后来已经发生了变化,它的i已经加到10了!当我们在result[0]函数的作用域中去找i的时候,它已经是10了。所以result[0]函数会返回10!其他的九个函数也都是如此。

    另外就是我们知道因为闭包的存在,也就是内部函数要访问外部函数中的参数,所以在外部函数执行完后其活动对象不能被垃圾回收。由此就可能因为大量闭包的存在而浪费内存,正确的做法是不滥用闭包,而且在不需要调用内部函数之后手动断开内部函数对外部函数活动对象的引用。

    闭包的利用

    闭包的好处就在于内部函数可以访问外部函数中的属性。
    而函数再执行时会有两个特殊的属性this和arguments,特殊在哪呢,他们不会像普通属性一样沿着作用域链向上寻找,为什么呢,可以说他们不需要,因为当前函数的活动对象中一定会存在着两个属性。可是这两个属性可能并不是我们想要的,因为一个函数如果没有显式被一个对象调用的话,它的this就会指向全局对象window。
    而我们有时候就是想改变调用内部函数的对象,让内部函数和外部函数是同一个对象调用的(这很常用),这时候闭包就起作用了,通过闭包,内部函数可以访问外部函数的属性,就像传递参数一样。

    function outer() {
        var that = this;
    
        return function() {
            inner.call(that);   
        };
    }
    
    var x = new Object();
    x.outer()();

    如果不用闭包inner就默认被window对象调用。用了之后就被x调用了。
    arguments也是同样的道理。这在我的另一篇重写jQuery中的toggle方法博客中有实例来展示这个应用。

    展开全文
  • 1.概述--美观、强大的可视化监控指标展示工具 1.1基本概念 2.全面瓦解 2.1登录grafana 2.2数据源配置 2.3仪表盘配置 3.特殊配置 3.1变量之interval 3.2变量之query 4.仪表盘导出导入 1.概述--美观、强大的...
  • 微博和微信对企业的作用

    万次阅读 2013-02-20 15:55:33
    微博和微信对企业的作用一、营销的两个终极追求做营销,两个终极追求:1、寻找目标陌生人群,最好精准,这样可以有限的精力投入到聚焦的人群,可以渗透更深刻。把目标陌生人转化成熟人然后引导销售意向2、再通过熟人...
  • 为了更好的理解闭包的作用域,下面我们用一道题来展示闭包函数的执行过程和闭包的作用域 let x = 5; function fn(x){ return function(y){ console.log(y + (++x)); } } let f = fn(6); f(7); fn(8)(9); f(10);...
  • 抽奖活动,应该算是最古老的运营活动之一了,无论线上还是线下,商场还是超市,大转盘都无处不在。然而,在微信红包出现以后,抽奖活动便发生了质的飞跃,因为用户抽到的红包可以直接发放到零钱中,这可是真金白银的...
  • 软件工程开发模型以及在软件工程中的作用: 传统模型: 瀑布模型(water fall model): 规定了各项软件工程活动,包括制定开发计划、需求分析说明、软件设计、程序编码、测试和运行维护,并且规定了它们自上而下...
  • UML--状态图的基本概念和作用

    万次阅读 多人点赞 2019-10-27 19:36:49
    在UML中,状态机由对象的各个状态和连接这些状态的转换组成, 是展示状态与状态转换的图。 在面向对象的软件系统中,一个对象无论多么简单或者多么复杂,都必然会经历一个从开始创建到最终消亡的完整过程,这个过程...
  • 不少App在打开的时候需要弹出一个广告活动弹窗,点击广告活动弹窗中的图片就会跳转到一个H5页面,加载显示具体的活动内容等,为了方便大家的操作,我将其做成了一个标准控件:android-adDialog。需要说明的是,虽然...
  • 安卓Activity的作用

    千次阅读 2017-03-29 21:27:17
    一个程序可以包含若干Activity,每个Acticity负责展示一个用户界面。也就是说在Android中每个界面都是一个Activity,切换界面操作其实是多个不同Activity之间的实例化操作。在Android中Activity的启动模式决定了...
  • 函数调用栈与活动记录

    千次阅读 2012-02-19 20:13:14
    函数调用栈与活动记录 在调试的时候经常遇到栈溢出,由此总结了下函数调用栈的知识。 为了理解C++是如何执行函数调用的,先考虑一个称为栈(stack)的数据结构。栈是一种后入先出的数据结构——压入(插入)栈的最后...
  • 景别的意义和作用

    千次阅读 2010-05-29 13:41:00
    1大远景性质:包含景物较多,人物很... 另外,由于人物从属于画面,从而造成宁静、广漠、空旷、深远、回味等意境、 作用:以景为主、抒情、表意为主——假定你想抒情了,就用大全景2远景的性质:虽然仍景物为主,但是
  • 浅谈UML学习笔记动态图之状态图和活动

    万次阅读 热门讨论 2013-02-15 15:04:38
    1、状态图  我先简单的理解一下,什么是状态... 在UML中,状态机由对象的各个状态和连接这些状态的转换组成,是展示状态与状态转换的图。  状态图本质上就是一个状态机或是状态机的特殊情况。由表示状态的节点和表示
  • UML之活动图、状态图

    千次阅读 2016-07-22 16:25:26
    其中用例图展示了系统中的角色以及用户的功能需求。类图、包图、对象图是UML中的静态图,展示了系统的静态结构。 接下来本文主要讲解UML中的动态行为图:活动图和状态图。 (一)活动图 1、概念:首先回顾以下流程图...
  • 在实际项目中,经常有需要将服务器端返回的图片的url地址显示在listview中的情况,如果我们自己去实现的话,大致思路是:1、创建JavaBean2、创建adapter3、创建http请求类4、在活动中对http返回的消息进行解析5、...
  • 电商限时抢购活动实现思路

    千次阅读 2019-04-02 00:00:46
    最近,应公司要求做了个限时优惠抢购的活动:下面分享一下自己的实现思路(大家有好的想法欢迎指出~~) 首先进行中的限时优惠活动只能有一个,将参加限时优惠活动的商品通过后台管理系统添加到当前进行中的限时优惠...
  • 深度学习,神经网络为人工智能展示了新希望2013年09月05日 ⁄ 计算机视觉 ⁄ 共 7655字 ⁄ 暂无评论 ⁄ 被围观 114 views+摘要:深度学习带来了机器学习的新浪潮,推动“大数据+深度模型”时代的来临,以及...
  • “我们的开源项目”活动发起人——庄表伟专访

    万次阅读 热门讨论 2012-08-13 11:34:12
    目前该活动已经在北京、上海、成都、深圳成功举办了 6 届(活动回顾),在业界引起了较大的反响。  此次我们专访了活动的发起者和组织者之一庄表伟,请他谈谈目前活动的情况以及国内的开源现状。  同时我们...
  • UML中用例图的作用及画法

    万次阅读 2015-01-29 10:10:41
    (2009-09-26 06:46:25) 转载▼ 标签:  ...作用 ...UML中用例图的作用及画法   用例图(Use Case Diagram)是由软件需求分析到最终实现的第一步,它描述人们如何使用一个系统。
  • AndroidManifest.xml文件的作用

    万次阅读 多人点赞 2019-02-25 02:21:30
    这个从字面上就可以看出是什么作用的,当设置为true时,表明该APP在手机上可以被调试。默认为false,在false的情况下调试该APP,就会报以下错误: Device XXX requires that applications explicitely declare ...
  • 看到shell 是不是很亲切,现在知道传递的两个参数的作用了吧,host 和 项目id就是为了确定日志文件的路径,如果命令行参数没有传递行号就返回行号,如果有行号,就返回该行内容。 #!/bin/bash  set -e  HOST=$1  ...
  • 你的打水究竟起多大作用? 大多数游手,在内心深处,都怀疑他们的腿对于提高速度还不够帮忙。但是,由于很明显打水是多少能推动身体向前走的,他们谁都不敢下这个赌注:不进行打水练习了。另外,在各个组或队中最...
  • 滴滴出行活动策划、用户成长体系、用户增长逻辑分析1功能模块分析及产品介绍1.1功能模块1.2产品介绍2活动策划(以愚人节为例)2.1活动主题2.2活动目的2.3活动目标2.4活动资源2.5活动对象2.6活动规则2.7活动时间2.8...
  • UML各种图的作用和特点

    万次阅读 2016-11-01 23:32:52
    类图给出了系统的静态设计视图,活动类的类图给出了系统的静态进程视图。 2)对象图。对象图描述一组对象及它们之间的关系。对象图描述了在类图中所建立的事物实例的静态快照。和类图一样,这些图给出系统的静态设计...
  •  中国社会科学院农村发展研究所于建峰教授主持的救助乞讨儿童公益活动,他于今年1月2日设置相关帐号;该网站在十个月收到超过二十万位支持者并送来超过 5000相关信息。通过将这些信息空间化,可以找到某一时间段内...
  • 人类活动识别的深度学习模型

    千次阅读 2019-04-24 20:22:12
    目录概述人类活动识别 人类活动识别(Human Activity Recognition)是一项具有挑战性的时间序列分类任务。 它涉及到基于传感器数据预测人的移动。为了适应机器学习模型,传统上涉及到从信号处理到根据原始数据正确...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 68,656
精华内容 27,462
关键字:

展示活动的作用