手机淘宝列表页面 的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




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


列表页面

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>")),
		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>/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("
").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, 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 = ['"]; return b.join("") }, resetHtml: function(a) { this.setParam(a); var b = ['', "" + this.title + "", '' + this.text + ""].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 = ['
', '
', '', "
", '
', "淘宝客户端不仅可以更流畅地收藏宝贝,还能分享,立刻下载体验!", "
", '", '
', '立即打开', "
", "
"].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 = ['
', '
', '', "
", '
', "淘宝客户端不仅可以更流畅地收藏宝贝,还能分享,立刻下载体验!", "
", '", '
', '点此下载', "
", "
", ''].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 += '
'; this._wrapEl.innerHTML = '
' + c + '
', 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 = ''), 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, ">") } 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 += '' }, 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 && '' || "", e = c && '' || "", f = ['
', '上一页', '
', '
', "", d, "
", e, "
", '下一页', "
"]; 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] = ""; 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 = ['
', '
', '
', '
', '
', '', '', "
", "
", "
"].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 = ["­", '"].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 += ""; 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('
  • '), d.b("\n" + c), d.b(' '), d.b(d.v(d.f("auctionTitle", a, b, 0))), d.b(""), d.b("\n" + c), d.b('

    '), d.b(d.v(d.f("rateContent", a, b, 0))), d.b("

    "), d.b("\n" + c), d.b('

    '), d.b(d.v(d.f("displayUserNick", a, b, 0))), d.b(''), d.b(d.v(d.f("rateDate", a, b, 0))), d.b("

    \r"), d.b("\n" + c), d.b("
  • "), d.b("\n") }), a.pop()), d.s(d.f("rateList", a, b, 1), a, b, 1, 0, 0, "") || (d.b('
  • 暂无评论~
  • '), 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('
  • 全部
  • \r'), d.b("\n" + c), d.b('
  • 好评'), d.b(d.v(d.f("good", a, b, 0))), d.b("
  • \r"), d.b("\n" + c), d.b('
  • 中评'), d.b(d.v(d.f("mid", a, b, 0))), d.b("
  • \r"), d.b("\n" + c), d.b('
  • 差评'), d.b(d.v(d.f("bad", a, b, 0))), d.b("
  • "), 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("
  • "), d.b("\n" + c), d.b(' '), d.b("\n" + c), d.b('
    '), d.b("\n" + c), d.b('
    '), d.b("\n" + c), d.b('

    '), d.b(d.v(d.f("title", a, b, 0))), d.b("

    "), d.b("\n" + c), d.b('

    '), d.b(d.v(d.f("salePrice", a, b, 0))), d.b(" "), d.b(d.v(d.f("reservePrice", a, b, 0))), d.b("

    "), d.b("\n" + c), d.b('

    月售'), d.b(d.v(d.f("sold", a, b, 0))), d.b('

    '), d.b("\n" + c), d.b("
    "), d.b("\n" + c), d.b("
    "), d.b("\n" + c), d.b("
  • "), d.b("\n") }), a.pop()), d.s(d.f("itemsArray", a, b, 1), a, b, 1, 0, 0, "") || (d.b('
  • 未找到符合的宝贝
  • '), 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('
    \r'), d.b("\n" + c), d.b('
    \r'), d.b("\n" + c), d.b('
    \r'), d.b("\n" + c), d.b('
    最近浏览('), d.b(d.v(d.f("len", a, b, 0))), d.b(")
    \r"), d.b("\n" + c), d.b("
    \r"), d.b("\n" + c), d.b('
    \r'), d.b("\n" + c), d.b('
    \r'), d.b("\n" + c), d.b('
      \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('
    • \r'), c.b("\n") }), a.pop()), d.b(' \r'), d.b("\n" + c), d.b("
    \r"), d.b("\n" + c), d.b("
    \r"), d.b("\n" + c), d.b("
    \r"), d.b("\n" + c), d.b("
    "), d.fl() }), templates.shop_cates = new Hogan.Template(function(a, b, c) { var d = this; return d.b(c = c || ""), d.b('
    '), d.b("\n" + c), d.b('
    分类/搜索
    '), d.b("\n" + c), d.b('
    '), d.b("\n" + c), d.b(' "), d.b("\n" + c), d.b("\n" + c), d.b(' "), d.b("\n" + c), d.b("
    "), d.b("\n" + c), d.b("
    "), d.fl() }), templates.shop_info = new Hogan.Template(function(a, b, c) { var d = this; return d.b(c = c || ""), d.b('
    \r'), d.b("\n" + c), d.b('
    店铺信息
    \r'), d.b("\n" + c), d.b('
    \r'), d.b("\n" + c), d.b('
    \r'), d.b("\n" + c), d.b('
    '), d.b("\n" + c), d.b('
    '), d.b("\n" + c), d.b('

    '), d.b(d.v(d.f("title", a, b, 0))), d.b("

    "), d.b("\n" + c), d.b('

    创店时间:'), d.b(d.v(d.f("starts", a, b, 0))), d.b("

    "), d.b("\n" + c), d.b("
    \r"), d.b("\n" + c), d.b("
    \r"), d.b("\n" + c), d.b('
    \r'), d.b("\n" + c), d.b("
      \r"), d.b("\n" + c), d.b('
    • 宝贝数量'), d.b(d.v(d.f("productCount", a, b, 0))), d.b("
    • \r"), d.b("\n" + c), d.b('
    • 收藏人气'), d.b(d.v(d.f("collectorCount", a, b, 0))), d.b("
    • \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('
    • 好评率'), c.b(c.v(c.d("shopDSRScore.sellerGoodPercent", a, b, 0))), c.b("
    • ") }), a.pop()), d.b("\r"), d.b("\n" + c), d.b('
    • 地区'), d.b(d.v(d.f("prov", a, b, 0))), d.b(" "), d.b(d.v(d.f("city", a, b, 0))), d.b("
    • \r"), d.b("\n" + c), d.b("
    \r"), d.b("\n" + c), d.b("
    \r"), d.b("\n" + c), d.b('
    \r'), d.b("\n" + c), d.b(' \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('') }), a.pop()), d.b(" \r"), d.b("\n" + c), d.b("
    \r"), d.b("\n" + c), d.b('
    \r'), d.b("\n" + c), d.b('

    描述相符'), d.b(d.v(d.d("shopDSRScore.merchandisScore", a, b, 0))), d.b(''), d.b(d.v(d.d("mg.data", a, b, 0))), d.b("

    \r"), d.b("\n" + c), d.b('

    服务态度'), d.b(d.v(d.d("shopDSRScore.serviceScore", a, b, 0))), d.b(''), d.b(d.v(d.d("sg.data", a, b, 0))), d.b("

    \r"), d.b("\n" + c), d.b('

    发货速度'), d.b(d.v(d.d("shopDSRScore.consignmentScore", a, b, 0))), d.b(''), d.b(d.v(d.d("cg.data", a, b, 0))), d.b("

    \r"), d.b("\n" + c), d.b("
    \r"), d.b("\n" + c), d.b("
    \r"), d.b("\n" + c), d.b("
    "), 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('
    '), b.show(); var d = b.height(); return b.parent().anim({ height: d }, c.anitime, c.ease, function() { $(this).children().first().unwrap("
    "), 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('
    '), $(this).parent().height(c).css("overflow", "hidden"), $(this).parent().anim({ height: "1px" }, b.anitime, b.ease, function() { $(this).children().hide(), $(this).children().unwrap("
    "), 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 = '
    ', 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('
    ' + G_bottomhtml() + "
    "), $(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 = ''; 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(''), f = this.content = a('
    ' + d.content + "
    "), g = this.mask = a('
    '); 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('
    '), 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 = ['
    ', '
    价格区间
    ', '
    ', '
    ', '
    ', '元 ~', '元', "
    ", '
    ', '', "
    ", "
    ", "
    ", "
    "].join(""); b.content.append('
    ' + G_loading + "
    ").append('
    ' + G_loading + '
    ').append(a('
    ' + e + "
    ")), 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 = ['"].join(""); a("#js-viewport").append(f).append('
    '); 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('
    新店铺开张,店铺装修中
    ') : (k.append(''), $(".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 = ['
    ', '
    ', '
    ', "
    "].join(""), c = ['
    ', '
    ', '元~', '元', "
    ", '
    ', '', "
    ", "
    "].join(""), d = ['
      ', '
    • 上新
    • ', '
    • 销量
    • ', '
    • 价格
    • ', '
    • 促销
    • ', "
    ", "
    "].join(""), e = '
    ', f = '
    '; if (G_isPad) { d = '
    ' + d; var g = '
    ' + b + d + c + "
    "; a = '
    ' + g + e + f + "
    " } else d = '







    相关文章

    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 开发者的观点

    你可能感兴趣的:(php,javascript)