/*! touchjs.min v0.2.14 2014-08-05 */ "use strict"; ! function(a, b) { "function" == typeof define && (define.amd || define.cmd) ? define(b) : a.touch = b() }(this, function() { function a() { var a = "mouseup mousedown mousemove mouseout", c = "touchstart touchmove touchend touchcancel", d = b.hasTouch ? c : a; d.split(" ").forEach(function(a) { document.addEventListener(a, A, !1) }) } var b = {}; b.PCevts = { touchstart: "mousedown", touchmove: "mousemove", touchend: "mouseup", touchcancel: "mouseout" }, b.hasTouch = "ontouchstart" in window, b.getType = function(a) { return Object.prototype.toString.call(a).match(/\s([a-z|A-Z]+)/)[1].toLowerCase() }, b.getSelector = function(a) { if (a.id) return "#" + a.id; if (a.className) { var b = a.className.split(/\s+/); return "." + b.join(".") } return a === document ? "body" : a.tagName.toLowerCase() }, b.matchSelector = function(a, b) { return a.webkitMatchesSelector(b) }, b.getEventListeners = function(a) { return a.listeners }, b.getPCevts = function(a) { return this.PCevts[a] || a }, b.forceReflow = function() { var a = "reflowDivBlock", b = document.getElementById(a); b || (b = document.createElement("div"), b.id = a, document.body.appendChild(b)); var c = b.parentNode, d = b.nextSibling; c.removeChild(b), c.insertBefore(b, d) }, b.simpleClone = function(a) { return Object.create(a) }, b.getPosOfEvent = function(a) { if (this.hasTouch) { for (var b = [], c = null, d = 0, e = a.touches.length; e > d; d++) c = a.touches[d], b.push({ x: c.pageX, y: c.pageY }); return b } return [{ x: a.pageX, y: a.pageY }] }, b.getDistance = function(a, b) { var c = b.x - a.x, d = b.y - a.y; return Math.sqrt(c * c + d * d) }, b.getFingers = function(a) { return a.touches ? a.touches.length : 1 }, b.calScale = function(a, b) { if (a.length >= 2 && b.length >= 2) { var c = this.getDistance(a[1], a[0]), d = this.getDistance(b[1], b[0]); return d / c } return 1 }, b.getAngle = function(a, b) { return 180 * Math.atan2(b.y - a.y, b.x - a.x) / Math.PI }, b.getAngle180 = function(a, b) { var c = Math.atan(-1 * (b.y - a.y) / (b.x - a.x)) * (180 / Math.PI); return 0 > c ? c + 180 : c }, b.getDirectionFromAngle = function(a) { var b = { up: -45 > a && a > -135, down: a >= 45 && 135 > a, left: a >= 135 || -135 >= a, right: a >= -45 && 45 >= a }; for (var c in b) if (b[c]) return c; return null }, b.getXYByElement = function(a) { for (var b = 0, c = 0; a.offsetParent;) b += a.offsetLeft, c += a.offsetTop, a = a.offsetParent; return { left: b, top: c } }, b.reset = function() { h = i = j = null, q = o = k = l = !1, m = !1, f = {}, t = !1 }, b.isTouchMove = function(a) { return "touchmove" === a.type || "mousemove" === a.type }, b.isTouchEnd = function(a) { return "touchend" === a.type || "mouseup" === a.type || "touchcancel" === a.type }, b.env = function() { var a = {}, b = navigator.userAgent, c = b.match(/(Android)[\s\/]+([\d\.]+)/), d = b.match(/(iPad|iPhone|iPod)\s+OS\s([\d_\.]+)/), e = b.match(/(Windows\s+Phone)\s([\d\.]+)/), f = /WebKit\/[\d.]+/i.test(b), g = d ? navigator.standalone ? f : /Safari/i.test(b) && !/CriOS/i.test(b) && !/MQQBrowser/i.test(b) : !1; return c && (a.android = !0, a.version = c[2]), d && (a.ios = !0, a.version = d[2].replace(/_/g, "."), a.ios7 = /^7/.test(a.version), "iPad" === d[1] ? a.ipad = !0 : "iPhone" === d[1] ? (a.iphone = !0, a.iphone5 = 568 == screen.height) : "iPod" === d[1] && (a.ipod = !0)), e && (a.wp = !0, a.version = e[2], a.wp8 = /^8/.test(a.version)), f && (a.webkit = !0), g && (a.safari = !0), a }(); var c = { proxyid: 0, proxies: [], trigger: function(a, b, c) { c = c || {}; var d, e = { bubbles: !0, cancelable: !0, detail: c }; try { "undefined" != typeof CustomEvent ? (d = new CustomEvent(b, e), a && a.dispatchEvent(d)) : (d = document.createEvent("CustomEvent"), d.initCustomEvent(b, !0, !0, c), a && a.dispatchEvent(d)) } catch (f) { console.warn("Touch.js is not supported by environment.") } }, bind: function(a, c, d) { a.listeners = a.listeners || {}, a.listeners[c] ? a.listeners[c].push(d) : a.listeners[c] = [d]; var e = function(a) { b.env.ios7 && b.forceReflow(), a.originEvent = a; for (var c in a.detail) "type" !== c && (a[c] = a.detail[c]); a.startRotate = function() { t = !0 }; var e = d.call(a.target, a); "undefined" == typeof e || e || (a.stopPropagation(), a.preventDefault()) }; d.proxy = d.proxy || {}, d.proxy[c] ? d.proxy[c].push(this.proxyid++) : d.proxy[c] = [this.proxyid++], this.proxies.push(e), a.addEventListener && a.addEventListener(c, e, !1) }, unbind: function(a, b, c) { if (c) { var d = c.proxy[b]; d && d.length && d.forEach(function() { a.removeEventListener && a.removeEventListener(b, this.proxies[this.proxyid], !1) }) } else { var e = a.listeners[b]; e && e.length && e.forEach(function(c) { a.removeEventListener(b, c, !1) }) } }, delegate: function(a, c, d, e) { var f = function(c) { var f, g; c.originEvent = c; for (var h in c.detail) "type" !== h && (c[h] = c.detail[h]); c.startRotate = function() { t = !0 }; var i = b.getSelector(a) + " " + d, j = b.matchSelector(c.target, i), k = b.matchSelector(c.target, i + " " + c.target.nodeName); if (!j && k) { for (b.env.ios7 && b.forceReflow(), f = c.target; !b.matchSelector(f, i);) f = f.parentNode; g = e.call(c.target, c), "undefined" == typeof g || g || (c.stopPropagation(), c.preventDefault()) } else b.env.ios7 && b.forceReflow(), (j || k) && (g = e.call(c.target, c), "undefined" == typeof g || g || (c.stopPropagation(), c.preventDefault())) }; e.proxy = e.proxy || {}, e.proxy[c] ? e.proxy[c].push(this.proxyid++) : e.proxy[c] = [this.proxyid++], this.proxies.push(f), a.listeners = a.listeners || {}, a.listeners[c] ? a.listeners[c].push(f) : a.listeners[c] = [f], a.addEventListener && a.addEventListener(c, f, !1) }, undelegate: function(a, b, c, d) { if (d) { var e = d.proxy[b]; e.length && e.forEach(function() { a.removeEventListener && a.removeEventListener(b, this.proxies[this.proxyid], !1) }) } else { var f = a.listeners[b]; f.forEach(function(c) { a.removeEventListener(b, c, !1) }) } } }, d = { tap: !0, doubleTap: !0, tapMaxDistance: 10, hold: !0, tapTime: 200, holdTime: 650, maxDoubleTapInterval: 300, swipe: !0, swipeTime: 300, swipeMinDistance: 18, swipeFactor: 5, drag: !0, pinch: !0, minScaleRate: 0, minRotationAngle: 0 }, e = { TOUCH_START: "touchstart", TOUCH_MOVE: "touchmove", TOUCH_END: "touchend", TOUCH_CANCEL: "touchcancel", MOUSE_DOWN: "mousedown", MOUSE_MOVE: "mousemove", MOUSE_UP: "mouseup", CLICK: "click", PINCH_START: "pinchstart", PINCH_END: "pinchend", PINCH: "pinch", PINCH_IN: "pinchin", PINCH_OUT: "pinchout", ROTATION_LEFT: "rotateleft", ROTATION_RIGHT: "rotateright", ROTATION: "rotate", SWIPE_START: "swipestart", SWIPING: "swiping", SWIPE_END: "swipeend", SWIPE_LEFT: "swipeleft", SWIPE_RIGHT: "swiperight", SWIPE_UP: "swipeup", SWIPE_DOWN: "swipedown", SWIPE: "swipe", DRAG: "drag", DRAGSTART: "dragstart", DRAGEND: "dragend", HOLD: "hold", TAP: "tap", DOUBLE_TAP: "doubletap" }, f = { start: null, move: null, end: null }, g = 0, h = null, i = null, j = null, k = !1, l = !1, m = !1, n = {}, o = !1, p = null, q = !1, r = null, s = 1, t = !1, u = [], v = 0, w = 0, x = 0, y = null, z = { getAngleDiff: function(a) { for (var c = parseInt(v - b.getAngle180(a[0], a[1]), 10), d = 0; Math.abs(c - w) > 90 && d++ < 50;) 0 > w ? c -= 180 : c += 180; return w = parseInt(c, 10) }, pinch: function(a) { var g = a.target; if (d.pinch) { if (!o) return; if (b.getFingers(a) < 2 && !b.isTouchEnd(a)) return; var h = b.calScale(f.start, f.move), i = this.getAngleDiff(f.move), j = { type: "", originEvent: a, scale: h, rotation: i, direction: i > 0 ? "right" : "left", fingersCount: b.getFingers(a) }; if (l ? b.isTouchMove(a) ? (j.fingerStatus = "move", c.trigger(g, e.PINCH, j)) : b.isTouchEnd(a) && (j.fingerStatus = "end", c.trigger(g, e.PINCH_END, j), b.reset()) : (l = !0, j.fingerStatus = "start", c.trigger(g, e.PINCH_START, j)), Math.abs(1 - h) > d.minScaleRate) { var k = b.simpleClone(j), m = 1e-11; h > s ? (s = h - m, c.trigger(g, e.PINCH_OUT, k, !1)) : s > h && (s = h + m, c.trigger(g, e.PINCH_IN, k, !1)), b.isTouchEnd(a) && (s = 1) } if (Math.abs(i) > d.minRotationAngle) { var n, p = b.simpleClone(j); n = i > 0 ? e.ROTATION_RIGHT : e.ROTATION_LEFT, c.trigger(g, n, p, !1), c.trigger(g, e.ROTATION, j) } } }, rotateSingleFinger: function(a) { var d = a.target; if (t && b.getFingers(a) < 2) { if (!f.move) return; if (u.length < 2) { var g = b.getXYByElement(d); u = [{ x: g.left + d.offsetWidth / 2, y: g.top + d.offsetHeight / 2 }, f.move[0]], v = parseInt(b.getAngle180(u[0], u[1]), 10) } var h = [u[0], f.move[0]], i = this.getAngleDiff(h), j = { type: "", originEvent: a, rotation: i, direction: i > 0 ? "right" : "left", fingersCount: b.getFingers(a) }; b.isTouchMove(a) ? j.fingerStatus = "move" : (b.isTouchEnd(a) || "mouseout" === a.type) && (j.fingerStatus = "end", c.trigger(d, e.PINCH_END, j), b.reset()); var k = i > 0 ? e.ROTATION_RIGHT : e.ROTATION_LEFT; c.trigger(d, k, j), c.trigger(d, e.ROTATION, j) } }, swipe: function(a) { var h = a.target; if (o && f.move && !(b.getFingers(a) > 1)) { var i = Date.now(), j = i - g, l = b.getDistance(f.start[0], f.move[0]), p = { x: f.move[0].x - n.left, y: f.move[0].y - n.top }, q = b.getAngle(f.start[0], f.move[0]), r = b.getDirectionFromAngle(q), s = j / 1e3, t = 10 * (10 - d.swipeFactor) * s * s, u = { type: e.SWIPE, originEvent: a, position: p, direction: r, distance: l, distanceX: f.move[0].x - f.start[0].x, distanceY: f.move[0].y - f.start[0].y, x: f.move[0].x - f.start[0].x, y: f.move[0].y - f.start[0].y, angle: q, duration: j, fingersCount: b.getFingers(a), factor: t }; if (d.swipe) { var v = function() { var a = e; switch (r) { case "up": c.trigger(h, a.SWIPE_UP, u); break; case "down": c.trigger(h, a.SWIPE_DOWN, u); break; case "left": c.trigger(h, a.SWIPE_LEFT, u); break; case "right": c.trigger(h, a.SWIPE_RIGHT, u) } }; k ? b.isTouchMove(a) ? (u.fingerStatus = u.swipe = "move", c.trigger(h, e.SWIPING, u), j > d.swipeTime && j < d.swipeTime + 50 && l > d.swipeMinDistance && (v(), c.trigger(h, e.SWIPE, u, !1))) : (b.isTouchEnd(a) || "mouseout" === a.type) && (u.fingerStatus = u.swipe = "end", c.trigger(h, e.SWIPE_END, u), d.swipeTime > j && l > d.swipeMinDistance && (v(), c.trigger(h, e.SWIPE, u, !1))) : (u.fingerStatus = u.swipe = "start", k = !0, c.trigger(h, e.SWIPE_START, u)) } d.drag && (m ? b.isTouchMove(a) ? (u.fingerStatus = u.swipe = "move", c.trigger(h, e.DRAG, u)) : b.isTouchEnd(a) && (u.fingerStatus = u.swipe = "end", c.trigger(h, e.DRAGEND, u)) : (u.fingerStatus = u.swipe = "start", m = !0, c.trigger(h, e.DRAGSTART, u))) } }, tap: function(a) { var h = a.target; if (d.tap) { var i = Date.now(), j = i - g, k = b.getDistance(f.start[0], f.move ? f.move[0] : f.start[0]); clearTimeout(p); var l = function() { if (y && d.doubleTap && g - x < d.maxDoubleTapInterval) { var a = b.getDistance(y, f.start[0]); if (16 > a) return !0 } return !1 }(); if (l) return clearTimeout(r), void c.trigger(h, e.DOUBLE_TAP, { type: e.DOUBLE_TAP, originEvent: a, position: f.start[0] }); if (d.tapMaxDistance < k) return; d.holdTime > j && b.getFingers(a) <= 1 && (q = !0, x = i, y = f.start[0], r = setTimeout(function() { c.trigger(h, e.TAP, { type: e.TAP, originEvent: a, fingersCount: b.getFingers(a), position: y }) }, d.tapTime)) } }, hold: function(a) { var e = a.target; d.hold && (clearTimeout(p), p = setTimeout(function() { if (f.start) { var g = b.getDistance(f.start[0], f.move ? f.move[0] : f.start[0]); d.tapMaxDistance < g || q || c.trigger(e, "hold", { type: "hold", originEvent: a, fingersCount: b.getFingers(a), position: f.start[0] }) } }, d.holdTime)) } }, A = function(a) { var c = a.target; switch (a.type) { case "touchstart": case "mousedown": u = [], o = !0, (!f.start || f.start.length < 2) && (f.start = b.getPosOfEvent(a)), b.getFingers(a) >= 2 && (v = parseInt(b.getAngle180(f.start[0], f.start[1]), 10)), g = Date.now(), h = a, n = {}; var d = c.getBoundingClientRect(), e = document.documentElement; n = { top: d.top + (window.pageYOffset || e.scrollTop) - (e.clientTop || 0), left: d.left + (window.pageXOffset || e.scrollLeft) - (e.clientLeft || 0) }, z.hold(a); break; case "touchmove": case "mousemove": if (!o || !f.start) return; f.move = b.getPosOfEvent(a), b.getFingers(a) >= 2 ? z.pinch(a) : t ? z.rotateSingleFinger(a) : z.swipe(a); break; case "touchend": case "touchcancel": case "mouseup": case "mouseout": if (!o) return; j = a, l ? z.pinch(a) : t ? z.rotateSingleFinger(a) : k ? z.swipe(a) : z.tap(a), b.reset(), v = 0, w = 0, a.touches && 1 === a.touches.length && (o = !0, t = !0) } }, B = function() { function a(a) { b.hasTouch || (a = b.getPCevts(a)), j.forEach(function(b) { c.delegate(b, a, h, g[a]) }) } function d(a) { b.hasTouch || (a = b.getPCevts(a)), j.forEach(function(b) { c.bind(b, a, g[a]) }) } var e, f, g, h, i = arguments; if (i.length < 2 || i > 4) return console.error("unexpected arguments!"); var j = "string" === b.getType(i[0]) ? document.querySelectorAll(i[0]) : i[0]; if (j = j.length ? Array.prototype.slice.call(j) : [j], 3 === i.length && "string" === b.getType(i[1])) return e = i[1].split(" "), f = i[2], void e.forEach(function(a) { b.hasTouch || (a = b.getPCevts(a)), j.forEach(function(b) { c.bind(b, a, f) }) }); if (3 !== i.length || "object" !== b.getType(i[1])) if (2 !== i.length || "object" !== b.getType(i[1])) { if (4 === i.length && "object" === b.getType(i[2])) return e = i[1].split(" "), f = i[3], void e.forEach(function(a) { b.hasTouch || (a = b.getPCevts(a)), j.forEach(function(b) { c.bind(b, a, f) }) }); if (4 === i.length) { var k = j[0]; return e = i[1].split(" "), h = i[2], f = i[3], void e.forEach(function(a) { b.hasTouch || (a = b.getPCevts(a)), c.delegate(k, a, h, f) }) } } else { g = i[1]; for (var l in g) d(l) } else { g = i[1], h = i[2]; for (var m in g) a(m) } }, C = function() { var a, d, e = arguments; if (e.length < 1 || e.length > 4) return console.error("unexpected arguments!"); var f = "string" === b.getType(e[0]) ? document.querySelectorAll(e[0]) : e[0]; if (f = f.length ? Array.prototype.slice.call(f) : [f], 1 === e.length || 2 === e.length) return void f.forEach(function(d) { a = e[1] ? e[1].split(" ") : Object.keys(d.listeners), a.length && a.forEach(function(a) { b.hasTouch || (a = b.getPCevts(a)), c.unbind(d, a), c.undelegate(d, a) }) }); if (3 === e.length && "function" === b.getType(e[2])) return d = e[2], void f.forEach(function(f) { a = e[1].split(" "), a.forEach(function(a) { b.hasTouch || (a = b.getPCevts(a)), c.unbind(f, a, d) }) }); if (3 === e.length && "string" === b.getType(e[2])) { var g = e[2]; return void f.forEach(function(d) { a = e[1].split(" "), a.forEach(function(a) { b.hasTouch || (a = b.getPCevts(a)), c.undelegate(d, a, g) }) }) } return 4 === e.length ? (d = e[3], void f.forEach(function(f) { a = e[1].split(" "), a.forEach(function(a) { b.hasTouch || (a = b.getPCevts(a)), c.undelegate(f, a, g, d) }) })) : void 0 }, D = function(a, d, e) { var f = arguments; b.hasTouch || (d = b.getPCevts(d)); var g = "string" === b.getType(f[0]) ? document.querySelectorAll(f[0]) : f[0]; g = g.length ? Array.prototype.call(g) : [g], g.forEach(function(a) { c.trigger(a, d, e) }) }; a(); var E = {}; return E.on = E.bind = E.live = B, E.off = E.unbind = E.die = C, E.config = d, E.trigger = D, E });