PageSourceSearch

https://www.huetten.com/(cms)/module/static/default/content/libs/js/jquery.touchswipe-1.6/jquery.touchSwipe.js

js huetten.com collected 2026-09-26 06:12:29 UTC 72,119 bytes, 2,080 lines download raw bytes

1/*
2* @fileOverview TouchSwipe - jQuery Plugin
3* @version 1.6.9
4*
5* @author Matt Bryson http://www.github.com/mattbryson
6* @see https://github.com/mattbryson/TouchSwipe-Jquery-Plugin
7* @see http://labs.rampinteractive.co.uk/touchSwipe/
8* @see http://plugins.jquery.com/project/touchSwipe
9*
10* Copyright (c) 2010-2015 Matt Bryson
11* Dual licensed under the MIT or GPL Version 2 licenses.
12*
13*/
14
15/*
16*
17* Changelog
18* $Date: 2015-07-17 06:24:09 $
19* $version: 1.0.0
20* $version: 1.0.1 - removed multibyte comments
21*
22* $Date: 2015-07-17 06:24:09 $
23* $version: 1.1.0 	- added allowPageScroll property to allow swiping and scrolling of page
24*					- changed handler signatures so one handler can be used for multiple events
25* $Date: 2015-07-17 06:24:09 $
26* $version: 1.2.0 	- added click handler. This is fired if the user simply clicks and does not swipe. The event object and click target are passed to handler.
27*					- If you use the http://code.google.com/p/jquery-ui-for-ipad-and-iphone/ plugin, you can also assign jQuery mouse events to children of a touchSwipe object.
28* $version: 1.2.1 	- removed console log!
29*
30* $version: 1.2.2 	- Fixed bug where scope was not preserved in callback methods.
31*
32* $Date: 2015-07-17 06:24:09 $
33* $version: 1.2.4 	- Changed licence terms to be MIT or GPL inline with jQuery. Added check for support of touch events to stop non compatible browsers erroring.
34*
35* $Date: 2015-07-17 06:24:09 $
36* $version: 1.2.5 	- Added support for testing swipes with mouse on desktop browser (thanks to https://github.com/joelhy)
37*
38* $Date: 2015-07-17 06:24:09 $
39* $version: 1.2.6 	- Added timeThreshold between start and end touch, so user can ignore slow swipes (thanks to Mark Chase). Default is null, all swipes are detected
40*
41* $Date: 2015-07-17 06:24:09 $
42* $version: 1.2.7 	- Changed time threshold to have null default for backwards compatibility. Added duration param passed back in events, and refactored how time is handled.
43*
44* $Date: 2015-07-17 06:24:09 $
45* $version: 1.2.8 	- Added the possibility to return a value like null or false in the trigger callback. In that way we can control when the touch start/move should take effect or not (simply by returning in some cases return null; or return false;) This effects the ontouchstart/ontouchmove event.
46*
47* $Date: 2015-07-17 06:24:09 $
48* $version: 1.3.0 	- Refactored whole plugin to allow for methods to be executed, as well as exposed defaults for user override. Added 'enable', 'disable', and 'destroy' methods
49*
50* $Date: 2015-07-17 06:24:09 $
51* $version: 1.3.1 	- Bug fixes  - bind() with false as last argument is no longer supported in jQuery 1.6, also, if you just click, the duration is now returned correctly.
52*
53* $Date: 2015-07-17 06:24:09 $
54* $version: 1.3.2	- Added fallbackToMouseEvents option to NOT capture mouse events on non touch devices.
55* 			- Added "all" fingers value to the fingers property, so any combination of fingers triggers the swipe, allowing event handlers to check the finger count
56*
57* $Date: 2015-07-17 06:24:09 $
58* $version: 1.3.3	- Code tidy prep for minefied version
59*
60* $Date: 2015-07-17 06:24:09 $
61* $version: 1.4.0	- Added pinch support, pinchIn and pinchOut
62*
63* $Date: 2015-07-17 06:24:09 $
64* $version: 1.5.0	- Added excludedElements, a jquery selector that specifies child elements that do NOT trigger swipes. By default, this is one select that removes all form, input select, button and anchor elements.
65*
66* $Date: 2015-07-17 06:24:09 $
67* $version: 1.5.1	- Fixed bug with jQuery 1.8 and trailing comma in excludedElements
68*					- Fixed bug with IE and eventPreventDefault()
69* $Date: 2015-07-17 06:24:09 $
70* $version: 1.6.0	- Fixed bugs with pinching, mainly when both pinch and swipe enabled, as well as adding time threshold for multifinger gestures, so releasing one finger beofre the other doesnt trigger as single finger gesture.
71*					- made the demo site all static local HTML pages so they can be run locally by a developer
72*					- added jsDoc comments and added documentation for the plugin	
73*					- code tidy
74*					- added triggerOnTouchLeave property that will end the event when the user swipes off the element.
75* $Date: 2015-07-17 06:24:09 $
76* $version: 1.6.1	- Added support for ie8 touch events
77* $version: 1.6.2	- Added support for events binding with on / off / bind in jQ for all callback names.
78*                   - Deprecated the 'click' handler in favour of tap.
79*                   - added cancelThreshold property
80*                   - added option method to update init options at runtime
81* $version 1.6.3    - added doubletap, longtap events and longTapThreshold, doubleTapThreshold property
82*
83* $Date: 2015-07-17 06:24:09 $
84* $version 1.6.4    - Fixed bug with cancelThreshold introduced in 1.6.3, where swipe status no longer fired start event, and stopped once swiping back.
85*
86* $Date: 2015-07-17 06:24:09 $
87* $version 1.6.5    - Merged a few pull requests fixing various bugs, added AMD support.
88*
89* $Date: 2015-07-17 06:24:09 $
90* $version 1.6.6 	- Merge of pull requests.
91*    				- IE10 touch support 
92*    				- Only prevent default event handling on valid swipe
93*    				- Separate license/changelog comment
94*    				- Detect if the swipe is valid at the end of the touch event.
95*    				- Pass fingerdata to event handlers. 
96*    				- Add 'hold' gesture 
97*    				- Be more tolerant about the tap distance
98*    				- Typos and minor fixes
99*
100* $Date: 2015-07-17 06:24:09 $
101* $version 1.6.7    - Added patch from https://github.com/mattbryson/TouchSwipe-Jquery-Plugin/issues/206 to fix memory leak
102*
103* $Date: 2015-07-17 06:24:09 $
104* $version 1.6.8    - Added preventDefaultEvents option to proxy events regardless.
105*					- Fixed issue with swipe and pinch not triggering at the same time
106*
107* $Date: 2015-07-17 06:24:09 $
108* $version 1.6.9    - Added PR from jdalton/hybrid to fix pointer events
109*					- Added scrolling demo
110*					- Added version property to plugin
111*
112*
113*/
114
115/**
116 * See (http://jquery.com/).
117 * @name $
118 * @class 
119 * See the jQuery Library  (http://jquery.com/) for full details.  This just
120 * documents the function and classes that are added to jQuery by this plug-in.
121 */
122 
123/**
124 * See (http://jquery.com/)
125 * @name fn
126 * @class 
127 * See the jQuery Library  (http://jquery.com/) for full details.  This just
128 * documents the function and classes that are added to jQuery by this plug-in.
129 * @memberOf $
130 */
131
132
133
134(function (factory) {
135    if (typeof define === 'function' && define.amd && define.amd.jQuery) {
136        // AMD. Register as anonymous module.
137        define(['jquery'], factory);
138    } else {
139        // Browser globals.
140        factory(jQuery);
141    }
142}(function ($) {
143	"use strict";
144
145	//Constants
146	var VERSION = "1.6.9",
147		LEFT = "left",
148		RIGHT = "right",
149		UP = "up",
150		DOWN = "down",
151		IN = "in",
152		OUT = "out",
153
154		NONE = "none",
155		AUTO = "auto",
156		
157		SWIPE = "swipe",
158		PINCH = "pinch",
159		TAP = "tap",
160		DOUBLE_TAP = "doubletap",
161		LONG_TAP = "longtap",
162		HOLD = "hold",
163		
164		HORIZONTAL = "horizontal",
165		VERTICAL = "vertical",
166
167		ALL_FINGERS = "all",
168		
169		DOUBLE_TAP_THRESHOLD = 10,
170
171		PHASE_START = "start",
172		PHASE_MOVE = "move",
173		PHASE_END = "end",
174		PHASE_CANCEL = "cancel",
175
176		SUPPORTS_TOUCH = 'ontouchstart' in window,
177		
178		SUPPORTS_POINTER_IE10 = window.navigator.msPointerEnabled && !window.navigator.pointerEnabled,
179		
180		SUPPORTS_POINTER = window.navigator.pointerEnabled || window.navigator.msPointerEnabled,
181
182		PLUGIN_NS = 'TouchSwipe';
183
184
185
186	/**
187	* The default configuration, and available options to configure touch swipe with.
188	* You can set the default values by updating any of the properties prior to instantiation.
189	* @name $.fn.swipe.defaults
190	* @namespace
191	* @property {int} [fingers=1] The number of fingers to detect in a swipe. Any swipes that do not meet this requirement will NOT trigger swipe handlers.
192	* @property {int} [threshold=75] The number of pixels that the user must move their finger by before it is considered a swipe. 
193	* @property {int} [cancelThreshold=null] The number of pixels that the user must move their finger back from the original swipe direction to cancel the gesture.
194	* @property {int} [pinchThreshold=20] The number of pixels that the user must pinch their finger by before it is considered a pinch. 
195	* @property {int} [maxTimeThreshold=null] Time, in milliseconds, between touchStart and touchEnd must NOT exceed in order to be considered a swipe. 
196	* @property {int} [fingerReleaseThreshold=250] Time in milliseconds between releasing multiple fingers.  If 2 fingers are down, and are released one after the other, if they are within this threshold, it counts as a simultaneous release. 
197	* @property {int} [longTapThreshold=500] Time in milliseconds between tap and release for a long tap
198	* @property {int} [doubleTapThreshold=200] Time in milliseconds between 2 taps to count as a double tap
199	* @property {function} [swipe=null] A handler to catch all swipes. See {@link $.fn.swipe#event:swipe}
200	* @property {function} [swipeLeft=null] A handler that is triggered for "left" swipes. See {@link $.fn.swipe#event:swipeLeft}
201	* @property {function} [swipeRight=null] A handler that is triggered for "right" swipes. See {@link $.fn.swipe#event:swipeRight}
202	* @property {function} [swipeUp=null] A handler that is triggered for "up" swipes. See {@link $.fn.swipe#event:swipeUp}
203	* @property {function} [swipeDown=null] A handler that is triggered for "down" swipes. See {@link $.fn.swipe#event:swipeDown}
204	* @property {function} [swipeStatus=null] A handler triggered for every phase of the swipe. See {@link $.fn.swipe#event:swipeStatus}
205	* @property {function} [pinchIn=null] A handler triggered for pinch in events. See {@link $.fn.swipe#event:pinchIn}
206	* @property {function} [pinchOut=null] A handler triggered for pinch out events. See {@link $.fn.swipe#event:pinchOut}
207	* @property {function} [pinchStatus=null] A handler triggered for every phase of a pinch. See {@link $.fn.swipe#event:pinchStatus}
208	* @property {function} [tap=null] A handler triggered when a user just taps on the item, rather than swipes it. If they do not move, tap is triggered, if they do move, it is not. 
209	* @property {function} [doubleTap=null] A handler triggered when a user double taps on the item. The delay between taps can be set with the doubleTapThreshold property. See {@link $.fn.swipe.defaults#doubleTapThreshold}
210	* @property {function} [longTap=null] A handler triggered when a user long taps on the item. The delay between start and end can be set with the longTapThreshold property. See {@link $.fn.swipe.defaults#longTapThreshold}
211	* @property (function) [hold=null] A handler triggered when a user reaches longTapThreshold on the item. See {@link $.fn.swipe.defaults#longTapThreshold}
212	* @property {boolean} [triggerOnTouchEnd=true] If true, the swipe events are triggered when the touch end event is received (user releases finger).  If false, it will be triggered on reaching the threshold, and then cancel the touch event automatically. 
213	* @property {boolean} [triggerOnTouchLeave=false] If true, then when the user leaves the swipe object, the swipe will end and trigger appropriate handlers. 
214	* @property {string|undefined} [allowPageScroll='auto'] How the browser handles page scrolls when the user is swiping on a touchSwipe object. See {@link $.fn.swipe.pageScroll}.  <br/><br/>
215										<code>"auto"</code> : all undefined swipes will cause the page to scroll in that direction. <br/>
216										<code>"none"</code> : the page will not scroll when user swipes. <br/>
217										<code>"horizontal"</code> : will force page to scroll on horizontal swipes. <br/>
218										<code>"vertical"</code> : will force page to scroll on vertical swipes. <br/>
219	* @property {boolean} [fallbackToMouseEvents=true] If true mouse events are used when run on a non touch device, false will stop swipes being triggered by mouse events on non tocuh devices. 
220	* @property {string} [excludedElements="button, input, select, textarea, a, .noSwipe"] A jquery selector that specifies child elements that do NOT trigger swipes. By default this excludes all form, input, select, button, anchor and .noSwipe elements. 
221	* @property {boolean} [preventDefaultEvents=true] by default default events are cancelled, so the page doesn't move.  You can dissable this so both native events fire as well as your handlers. 
222	
223	*/
224	var defaults = {
225		fingers: 1, 		
226		threshold: 75, 	
227		cancelThreshold:null,	
228		pinchThreshold:20,
229		maxTimeThreshold: null, 
230		fingerReleaseThreshold:250, 
231		longTapThreshold:500,
232		doubleTapThreshold:200,
233		swipe: null, 		
234		swipeLeft: null, 	
235		swipeRight: null, 	
236		swipeUp: null, 		
237		swipeDown: null, 	
238		swipeStatus: null, 	
239		pinchIn:null,		
240		pinchOut:null,		
241		pinchStatus:null,	
242		click:null, //Deprecated since 1.6.2
243		tap:null,
244		doubleTap:null,
245		longTap:null, 		
246		hold:null, 
247		triggerOnTouchEnd: true, 
248		triggerOnTouchLeave:false, 
249		allowPageScroll: "auto", 
250		fallbackToMouseEvents: true,	
251		excludedElements:"label, button, input, select, textarea, a, .noSwipe",
252		preventDefaultEvents:true
253	};
254
255
256
257	/**
258	* Applies TouchSwipe behaviour to one or more jQuery objects.
259	* The TouchSwipe plugin can be instantiated via this method, or methods within 
260	* TouchSwipe can be executed via this method as per jQuery plugin architecture.
261	* @see TouchSwipe
262	* @class
263	* @param {Mixed} method If the current DOMNode is a TouchSwipe object, and <code>method</code> is a TouchSwipe method, then
264	* the <code>method</code> is executed, and any following arguments are passed to the TouchSwipe method.
265	* If <code>method</code> is an object, then the TouchSwipe class is instantiated on the current DOMNode, passing the 
266	* configuration properties defined in the object. See TouchSwipe
267	*
268	*/
269	$.fn.swipe = function (method) {
270		var $this = $(this),
271			plugin = $this.data(PLUGIN_NS);
272
273		//Check if we are already instantiated and trying to execute a method	
274		if (plugin && typeof method === 'string') {
275			if (plugin[method]) {
276				return plugin[method].apply(this, Array.prototype.slice.call(arguments, 1));
277			} else {
278				$.error('Method ' + method + ' does not exist on jQuery.swipe');
279			}
280		}
281		//Else not instantiated and trying to pass init object (or nothing)
282		else if (!plugin && (typeof method === 'object' || !method)) {
283			return init.apply(this, arguments);
284		}
285
286		return $this;
287	};
288	
289	/**
290	 * The version of the plugin
291	 * @readonly
292	 */
293	$.fn.swipe.version = VERSION;
294
295
296
297	//Expose our defaults so a user could override the plugin defaults
298	$.fn.swipe.defaults = defaults;
299
300	/**
301	* The phases that a touch event goes through.  The <code>phase</code> is passed to the event handlers. 
302	* These properties are read only, attempting to change them will not alter the values passed to the event handlers.
303	* @namespace
304	* @readonly
305	* @property {string} PHASE_START Constant indicating the start phase of the touch event. Value is <code>"start"</code>.
306	* @property {string} PHASE_MOVE Constant indicating the move phase of the touch event. Value is <code>"move"</code>.
307	* @property {string} PHASE_END Constant indicating the end phase of the touch event. Value is <code>"end"</code>.
308	* @property {string} PHASE_CANCEL Constant indicating the cancel phase of the touch event. Value is <code>"cancel"</code>.
309	*/
310	$.fn.swipe.phases = {
311		PHASE_START: PHASE_START,
312		PHASE_MOVE: PHASE_MOVE,
313		PHASE_END: PHASE_END,
314		PHASE_CANCEL: PHASE_CANCEL
315	};
316
317	/**
318	* The direction constants that are passed to the event handlers. 
319	* These properties are read only, attempting to change them will not alter the values passed to the event handlers.
320	* @namespace
321	* @readonly
322	* @property {string} LEFT Constant indicating the left direction. Value is <code>"left"</code>.
323	* @property {string} RIGHT Constant indicating the right direction. Value is <code>"right"</code>.
324	* @property {string} UP Constant indicating the up direction. Value is <code>"up"</code>.
325	* @property {string} DOWN Constant indicating the down direction. Value is <code>"cancel"</code>.
326	* @property {string} IN Constant indicating the in direction. Value is <code>"in"</code>.
327	* @property {string} OUT Constant indicating the out direction. Value is <code>"out"</code>.
328	*/
329	$.fn.swipe.directions = {
330		LEFT: LEFT,
331		RIGHT: RIGHT,
332		UP: UP,
333		DOWN: DOWN,
334		IN : IN,
335		OUT: OUT
336	};
337	
338	/**
339	* The page scroll constants that can be used to set the value of <code>allowPageScroll</code> option
340	* These properties are read only
341	* @namespace
342	* @readonly
343	* @see $.fn.swipe.defaults#allowPageScroll
344	* @property {string} NONE Constant indicating no page scrolling is allowed. Value is <code>"none"</code>.
345	* @property {string} HORIZONTAL Constant indicating horizontal page scrolling is allowed. Value is <code>"horizontal"</code>.
346	* @property {string} VERTICAL Constant indicating vertical page scrolling is allowed. Value is <code>"vertical"</code>.
347	* @property {string} AUTO Constant indicating either horizontal or vertical will be allowed, depending on the swipe handlers registered. Value is <code>"auto"</code>.
348	*/
349	$.fn.swipe.pageScroll = {
350		NONE: NONE,
351		HORIZONTAL: HORIZONTAL,
352		VERTICAL: VERTICAL,
353		AUTO: AUTO
354	};
355
356	/**
357	* Constants representing the number of fingers used in a swipe.  These are used to set both the value of <code>fingers</code> in the 
358	* options object, as well as the value of the <code>fingers</code> event property.
359	* These properties are read only, attempting to change them will not alter the values passed to the event handlers.
360	* @namespace
361	* @readonly
362	* @see $.fn.swipe.defaults#fingers
363	* @property {string} ONE Constant indicating 1 finger is to be detected / was detected. Value is <code>1</code>.
364	* @property {string} TWO Constant indicating 2 fingers are to be detected / were detected. Value is <code>1</code>.
365	* @property {string} THREE Constant indicating 3 finger are to be detected / were detected. Value is <code>1</code>.
366	* @property {string} ALL Constant indicating any combination of finger are to be detected.  Value is <code>"all"</code>.
367	*/
368	$.fn.swipe.fingers = {
369		ONE: 1,
370		TWO: 2,
371		THREE: 3,
372		ALL: ALL_FINGERS
373	};
374
375	/**
376	* Initialise the plugin for each DOM element matched
vendor: 38,301 bytes, lines 377-1615
377	* This creates a new instance of the main TouchSwipe class for each DOM element, and then
378	* saves a reference to that instance in the elements data property.
379	* @internal
380	*/
381	function init(options) {
382		//Prep and extend the options
383		if (options && (options.allowPageScroll === undefined && (options.swipe !== undefined || options.swipeStatus !== undefined))) {
384			options.allowPageScroll = NONE;
385		}
386		
387        //Check for deprecated options
388		//Ensure that any old click handlers are assigned to the new tap, unless we have a tap
389		if(options.click!==undefined && options.tap===undefined) {
390		    options.tap = options.click;
391		}
392
393		if (!options) {
394			options = {};
395		}
396		
397        //pass empty object so we dont modify the defaults
398		options = $.extend({}, $.fn.swipe.defaults, options);
399
400		//For each element instantiate the plugin
401		return this.each(function () {
402			var $this = $(this);
403
404			//Check we havent already initialised the plugin
405			var plugin = $this.data(PLUGIN_NS);
406
407			if (!plugin) {
408				plugin = new TouchSwipe(this, options);
409				$this.data(PLUGIN_NS, plugin);
410			}
411		});
412	}
413
414	/**
415	* Main TouchSwipe Plugin Class.
416	* Do not use this to construct your TouchSwipe object, use the jQuery plugin method $.fn.swipe(); {@link $.fn.swipe}
417	* @private
418	* @name TouchSwipe
419	* @param {DOMNode} element The HTML DOM object to apply to plugin to
420	* @param {Object} options The options to configure the plugin with.  @link {$.fn.swipe.defaults}
421	* @see $.fh.swipe.defaults
422	* @see $.fh.swipe
423    * @class
424	*/
425	function TouchSwipe(element, options) {
426        var useTouchEvents = (SUPPORTS_TOUCH || SUPPORTS_POINTER || !options.fallbackToMouseEvents),
427            START_EV = useTouchEvents ? (SUPPORTS_POINTER ? (SUPPORTS_POINTER_IE10 ? 'MSPointerDown' : 'pointerdown') : 'touchstart') : 'mousedown',
428            MOVE_EV = useTouchEvents ? (SUPPORTS_POINTER ? (SUPPORTS_POINTER_IE10 ? 'MSPointerMove' : 'pointermove') : 'touchmove') : 'mousemove',
429            END_EV = useTouchEvents ? (SUPPORTS_POINTER ? (SUPPORTS_POINTER_IE10 ? 'MSPointerUp' : 'pointerup') : 'touchend') : 'mouseup',
430            LEAVE_EV = useTouchEvents ? null : 'mouseleave', //we manually detect leave on touch devices, so null event here
431            CANCEL_EV = (SUPPORTS_POINTER ? (SUPPORTS_POINTER_IE10 ? 'MSPointerCancel' : 'pointercancel') : 'touchcancel');
432
433
434
435		//touch properties
436		var distance = 0,
437			direction = null,
438			duration = 0,
439			startTouchesDistance = 0,
440			endTouchesDistance = 0,
441			pinchZoom = 1,
442			pinchDistance = 0,
443			pinchDirection = 0,
444			maximumsMap=null;
445
446		
447		
448		//jQuery wrapped element for this instance
449		var $element = $(element);
450		
451		//Current phase of th touch cycle
452		var phase = "start";
453
454		// the current number of fingers being used.
455		var fingerCount = 0; 			
456
457		//track mouse points / delta
458		var fingerData=null;
459
460		//track times
461		var startTime = 0,
462			endTime = 0,
463			previousTouchEndTime=0,
464			previousTouchFingerCount=0,
465			doubleTapStartTime=0;
466
467		//Timeouts
468		var singleTapTimeout=null,
469			holdTimeout=null;
470        
471		// Add gestures to all swipable areas if supported
472		try {
473			$element.bind(START_EV, touchStart);
474			$element.bind(CANCEL_EV, touchCancel);
475		}
476		catch (e) {
477			$.error('events not supported ' + START_EV + ',' + CANCEL_EV + ' on jQuery.swipe');
478		}
479
480		//
481		//Public methods
482		//
483		
484		/**
485		* re-enables the swipe plugin with the previous configuration
486		* @function
487		* @name $.fn.swipe#enable
488		* @return {DOMNode} The Dom element that was registered with TouchSwipe 
489		* @example $("#element").swipe("enable");
490		*/
491		this.enable = function () {
492			$element.bind(START_EV, touchStart);
493			$element.bind(CANCEL_EV, touchCancel);
494			return $element;
495		};
496
497		/**
498		* disables the swipe plugin
499		* @function
500		* @name $.fn.swipe#disable
501		* @return {DOMNode} The Dom element that is now registered with TouchSwipe
502	    * @example $("#element").swipe("disable");
503		*/
504		this.disable = function () {
505			removeListeners();
506			return $element;
507		};
508
509		/**
510		* Destroy the swipe plugin completely. To use any swipe methods, you must re initialise the plugin.
511		* @function
512		* @name $.fn.swipe#destroy
513		* @example $("#element").swipe("destroy");
514		*/
515		this.destroy = function () {
516			removeListeners();
517			$element.data(PLUGIN_NS, null);
518			$element = null;
519		};
520
521		
522        /**
523         * Allows run time updating of the swipe configuration options.
524         * @function
525    	 * @name $.fn.swipe#option
526    	 * @param {String} property The option property to get or set
527         * @param {Object} [value] The value to set the property to
528		 * @return {Object} If only a property name is passed, then that property value is returned.
529		 * @example $("#element").swipe("option", "threshold"); // return the threshold
530         * @example $("#element").swipe("option", "threshold", 100); // set the threshold after init
531         * @see $.fn.swipe.defaults
532         *
533         */
534        this.option = function (property, value) {
535            if(options[property]!==undefined) {
536                if(value===undefined) {
537                    return options[property];
538                } else {
539                    options[property] = value;
540                }
541            } else {
542                $.error('Option ' + property + ' does not exist on jQuery.swipe.options');
543            }
544
545            return null;
546        }
547
548		//
549		// Private methods
550		//
551		
552		//
553		// EVENTS
554		//
555		/**
556		* Event handler for a touch start event.
557		* Stops the default click event from triggering and stores where we touched
558		* @inner
559		* @param {object} jqEvent The normalised jQuery event object.
560		*/
561		function touchStart(jqEvent) {
562			//If we already in a touch event (a finger already in use) then ignore subsequent ones..
563			if( getTouchInProgress() )
564				return;
565			
566			//Check if this element matches any in the excluded elements selectors,  or its parent is excluded, if so, DON'T swipe
567			if( $(jqEvent.target).closest( options.excludedElements, $element ).length>0 ) 
568				return;
569				
570			//As we use Jquery bind for events, we need to target the original event object
571			//If these events are being programmatically triggered, we don't have an original event object, so use the Jq one.
572			var event = jqEvent.originalEvent ? jqEvent.originalEvent : jqEvent;
573			
574			var ret,
575				touches = event.touches,
576				evt = touches ? touches[0] : event;
577
578			phase = PHASE_START;
579
580			//If we support touches, get the finger count
581			if (touches) {
582				// get the total number of fingers touching the screen
583				fingerCount = touches.length;
584			}
585			//Else this is the desktop, so stop the browser from dragging content
586			else {
587				jqEvent.preventDefault(); //call this on jq event so we are cross browser
588			}
589
590			//clear vars..
591			distance = 0;
592			direction = null;
593			pinchDirection=null;
594			duration = 0;
595			startTouchesDistance=0;
596			endTouchesDistance=0;
597			pinchZoom = 1;
598			pinchDistance = 0;
599			fingerData=createAllFingerData();
600			maximumsMap=createMaximumsData();
601			cancelMultiFingerRelease();
602
603			
604			// check the number of fingers is what we are looking for, or we are capturing pinches
605			if (!touches || (fingerCount === options.fingers || options.fingers === ALL_FINGERS) || hasPinches()) {
606				// get the coordinates of the touch
607				createFingerData( 0, evt );
608				startTime = getTimeStamp();
609				
610				if(fingerCount==2) {
611					//Keep track of the initial pinch distance, so we can calculate the diff later
612					//Store second finger data as start
613					createFingerData( 1, touches[1] );
614					startTouchesDistance = endTouchesDistance = calculateTouchesDistance(fingerData[0].start, fingerData[1].start);
615				}
616				
617				if (options.swipeStatus || options.pinchStatus) {
618					ret = triggerHandler(event, phase);
619				}
620			}
621			else {
622				//A touch with more or less than the fingers we are looking for, so cancel
623				ret = false; 
624			}
625
626			//If we have a return value from the users handler, then return and cancel
627			if (ret === false) {
628				phase = PHASE_CANCEL;
629				triggerHandler(event, phase);
630				return ret;
631			}
632			else {
633				if (options.hold) {
634					holdTimeout = setTimeout($.proxy(function() {
635						//Trigger the event
636						$element.trigger('hold', [event.target]);
637						//Fire the callback
638						if(options.hold) {
639							ret = options.hold.call($element, event, event.target);
640						}
641					}, this), options.longTapThreshold );
642				}
643
644				setTouchInProgress(true);
645			}
646
647            return null;
648		};
649		
650		
651		
652		/**
653		* Event handler for a touch move event. 
654		* If we change fingers during move, then cancel the event
655		* @inner
656		* @param {object} jqEvent The normalised jQuery event object.
657		*/
658		function touchMove(jqEvent) {
659			
660			//As we use Jquery bind for events, we need to target the original event object
661			//If these events are being programmatically triggered, we don't have an original event object, so use the Jq one.
662			var event = jqEvent.originalEvent ? jqEvent.originalEvent : jqEvent;
663			
664			//If we are ending, cancelling, or within the threshold of 2 fingers being released, don't track anything..
665			if (phase === PHASE_END || phase === PHASE_CANCEL || inMultiFingerRelease())
666				return;
667
668			var ret,
669				touches = event.touches,
670				evt = touches ? touches[0] : event;
671			
672
673			//Update the  finger data 
674			var currentFinger = updateFingerData(evt);
675			endTime = getTimeStamp();
676			
677			if (touches) {
678				fingerCount = touches.length;
679			}
680
681			if (options.hold)
682				clearTimeout(holdTimeout);
683
684			phase = PHASE_MOVE;
685
686			//If we have 2 fingers get Touches distance as well
687			if(fingerCount==2) {
688				
689				//Keep track of the initial pinch distance, so we can calculate the diff later
690				//We do this here as well as the start event, in case they start with 1 finger, and the press 2 fingers
691				if(startTouchesDistance==0) {
692					//Create second finger if this is the first time...
693					createFingerData( 1, touches[1] );
694					
695					startTouchesDistance = endTouchesDistance = calculateTouchesDistance(fingerData[0].start, fingerData[1].start);
696				} else {
697					//Else just update the second finger
698					updateFingerData(touches[1]);
699				
700					endTouchesDistance = calculateTouchesDistance(fingerData[0].end, fingerData[1].end);
701					pinchDirection = calculatePinchDirection(fingerData[0].end, fingerData[1].end);
702				}
703				
704				
705				pinchZoom = calculatePinchZoom(startTouchesDistance, endTouchesDistance);
706				pinchDistance = Math.abs(startTouchesDistance - endTouchesDistance);
707			}
708			
709			
710			
711
712			if ( (fingerCount === options.fingers || options.fingers === ALL_FINGERS) || !touches || hasPinches() ) {
713				
714				direction = calculateDirection(currentFinger.start, currentFinger.end);
715				
716				//Check if we need to prevent default event (page scroll / pinch zoom) or not
717				validateDefaultEvent(jqEvent, direction);
718
719				//Distance and duration are all off the main finger
720				distance = calculateDistance(currentFinger.start, currentFinger.end);
721				duration = calculateDuration();
722
723                //Cache the maximum distance we made in this direction
724                setMaxDistance(direction, distance);
725
726
727				if (options.swipeStatus || options.pinchStatus) {
728					ret = triggerHandler(event, phase);
729				}
730				
731				
732				//If we trigger end events when threshold are met, or trigger events when touch leaves element
733				if(!options.triggerOnTouchEnd || options.triggerOnTouchLeave) {
734					
735					var inBounds = true;
736					
737					//If checking if we leave the element, run the bounds check (we can use touchleave as its not supported on webkit)
738					if(options.triggerOnTouchLeave) {
739						var bounds = getbounds( this );
740						inBounds = isInBounds( currentFinger.end, bounds );
741					}
742					
743					//Trigger end handles as we swipe if thresholds met or if we have left the element if the user has asked to check these..
744					if(!options.triggerOnTouchEnd && inBounds) {
745						phase = getNextPhase( PHASE_MOVE );
746					} 
747					//We end if out of bounds here, so set current phase to END, and check if its modified 
748					else if(options.triggerOnTouchLeave && !inBounds ) {
749						phase = getNextPhase( PHASE_END );
750					}
751						
752					if(phase==PHASE_CANCEL || phase==PHASE_END)	{
753						triggerHandler(event, phase);
754					}				
755				}
756			}
757			else {
758				phase = PHASE_CANCEL;
759				triggerHandler(event, phase);
760			}
761
762			if (ret === false) {
763				phase = PHASE_CANCEL;
764				triggerHandler(event, phase);
765			}
766		}
767
768
769
770		/**
771		* Event handler for a touch end event. 
772		* Calculate the direction and trigger events
773		* @inner
774		* @param {object} jqEvent The normalised jQuery event object.
775		*/
776		function touchEnd(jqEvent) {
777			//As we use Jquery bind for events, we need to target the original event object
778			//If these events are being programmatically triggered, we don't have an original event object, so use the Jq one.
779			var event = jqEvent.originalEvent ? jqEvent.originalEvent : jqEvent,
780			    touches = event.touches;
781
782			//If we are still in a touch with another finger return
783			//This allows us to wait a fraction and see if the other finger comes up, if it does within the threshold, then we treat it as a multi release, not a single release.
784			if (touches) {
785				if(touches.length) {
786					startMultiFingerRelease();
787					return true;
788				}
789			}
790			
791			//If a previous finger has been released, check how long ago, if within the threshold, then assume it was a multifinger release.
792			//This is used to allow 2 fingers to release fractionally after each other, whilst maintainig the event as containg 2 fingers, not 1
793			if(inMultiFingerRelease()) {	
794				fingerCount=previousTouchFingerCount;
795			}	
796		
797			//Set end of swipe
798			endTime = getTimeStamp();
799			
800			//Get duration incase move was never fired
801			duration = calculateDuration();
802			
803			//If we trigger handlers at end of swipe OR, we trigger during, but they didnt trigger and we are still in the move phase
804			if(didSwipeBackToCancel() || !validateSwipeDistance()) {
805			    phase = PHASE_CANCEL;
806                triggerHandler(event, phase);
807			} else if (options.triggerOnTouchEnd || (options.triggerOnTouchEnd == false && phase === PHASE_MOVE)) {
808				//call this on jq event so we are cross browser 
809				jqEvent.preventDefault(); 
810				phase = PHASE_END;
811                triggerHandler(event, phase);
812			}
813			//Special cases - A tap should always fire on touch end regardless,
814			//So here we manually trigger the tap end handler by itself
815			//We dont run trigger handler as it will re-trigger events that may have fired already
816			else if (!options.triggerOnTouchEnd && hasTap()) {
817                //Trigger the pinch events...
818			    phase = PHASE_END;
819			    triggerHandlerForGesture(event, phase, TAP);
820			}
821			else if (phase === PHASE_MOVE) {
822				phase = PHASE_CANCEL;
823				triggerHandler(event, phase);
824			}
825
826			setTouchInProgress(false);
827
828            return null;
829		}
830
831
832
833		/**
834		* Event handler for a touch cancel event. 
835		* Clears current vars
836		* @inner
837		*/
838		function touchCancel() {
839			// reset the variables back to default values
840			fingerCount = 0;
841			endTime = 0;
842			startTime = 0;
843			startTouchesDistance=0;
844			endTouchesDistance=0;
845			pinchZoom=1;
846			
847			//If we were in progress of tracking a possible multi touch end, then re set it.
848			cancelMultiFingerRelease();
849			
850			setTouchInProgress(false);
851		}
852		
853		
854		/**
855		* Event handler for a touch leave event. 
856		* This is only triggered on desktops, in touch we work this out manually
857		* as the touchleave event is not supported in webkit
858		* @inner
859		*/
860		function touchLeave(jqEvent) {
861			var event = jqEvent.originalEvent ? jqEvent.originalEvent : jqEvent;
862			
863			//If we have the trigger on leave property set....
864			if(options.triggerOnTouchLeave) {
865				phase = getNextPhase( PHASE_END );
866				triggerHandler(event, phase);
867			}
868		}
869		
870		/**
871		* Removes all listeners that were associated with the plugin
872		* @inner
873		*/
874		function removeListeners() {
875			$element.unbind(START_EV, touchStart);
876			$element.unbind(CANCEL_EV, touchCancel);
877			$element.unbind(MOVE_EV, touchMove);
878			$element.unbind(END_EV, touchEnd);
879			
880			//we only have leave events on desktop, we manually calculate leave on touch as its not supported in webkit
881			if(LEAVE_EV) { 
882				$element.unbind(LEAVE_EV, touchLeave);
883			}
884			
885			setTouchInProgress(false);
886		}
887
888		
889		/**
890		 * Checks if the time and distance thresholds have been met, and if so then the appropriate handlers are fired.
891		 */
892		function getNextPhase(currentPhase) {
893			
894			var nextPhase = currentPhase;
895			
896			// Ensure we have valid swipe (under time and over distance  and check if we are out of bound...)
897			var validTime = validateSwipeTime();
898			var validDistance = validateSwipeDistance();
899			var didCancel = didSwipeBackToCancel();
900						
901			//If we have exceeded our time, then cancel	
902			if(!validTime || didCancel) {
903				nextPhase = PHASE_CANCEL;
904			}
905			//Else if we are moving, and have reached distance then end
906			else if (validDistance && currentPhase == PHASE_MOVE && (!options.triggerOnTouchEnd || options.triggerOnTouchLeave) ) {
907				nextPhase = PHASE_END;
908			} 
909			//Else if we have ended by leaving and didn't reach distance, then cancel
910			else if (!validDistance && currentPhase==PHASE_END && options.triggerOnTouchLeave) {
911				nextPhase = PHASE_CANCEL;
912			}
913			
914			return nextPhase;
915		}
916		
917		
918		/**
919		* Trigger the relevant event handler
920		* The handlers are passed the original event, the element that was swiped, and in the case of the catch all handler, the direction that was swiped, "left", "right", "up", or "down"
921		* @param {object} event the original event object
922		* @param {string} phase the phase of the swipe (start, end cancel etc) {@link $.fn.swipe.phases}
923		* @inner
924		*/
925		function triggerHandler(event, phase) {
926
927			var ret,
928				touches = event.touches;
929			
930			//Swipes and pinches are not mutually exclusive - can happend at same time, so need to trigger 2 events potentially
931			if( (didSwipe() || hasSwipes()) || (didPinch() || hasPinches()) ) {
932				// SWIPE GESTURES
933				if(didSwipe() || hasSwipes()) { //hasSwipes as status needs to fire even if swipe is invalid
934					//Trigger the swipe events...
935					ret = triggerHandlerForGesture(event, phase, SWIPE);
936				}	
937
938				// PINCH GESTURES (if the above didn't cancel)
939				if((didPinch() || hasPinches()) && ret!==false) {
940					//Trigger the pinch events...
941					ret = triggerHandlerForGesture(event, phase, PINCH);
942				}
943			} else {
944			 
945				// CLICK / TAP (if the above didn't cancel)
946				if(didDoubleTap() && ret!==false) {
947					//Trigger the tap events...
948					ret = triggerHandlerForGesture(event, phase, DOUBLE_TAP);
949				}
950				
951				// CLICK / TAP (if the above didn't cancel)
952				else if(didLongTap() && ret!==false) {
953					//Trigger the tap events...
954					ret = triggerHandlerForGesture(event, phase, LONG_TAP);
955				}
956
957				// CLICK / TAP (if the above didn't cancel)
958				else if(didTap() && ret!==false) {
959					//Trigger the tap event..
960					ret = triggerHandlerForGesture(event, phase, TAP);
961				}
962			}
963			
964			
965			
966			// If we are cancelling the gesture, then manually trigger the reset handler
967			if (phase === PHASE_CANCEL) {
968				touchCancel(event);
969			}
970			
971			// If we are ending the gesture, then manually trigger the reset handler IF all fingers are off
972			if(phase === PHASE_END) {
973				//If we support touch, then check that all fingers are off before we cancel
974				if (touches) {
975					if(!touches.length) {
976						touchCancel(event);	
977					}
978				} 
979				else {
980					touchCancel(event);
981				}
982			}
983					
984			return ret;
985		}
986		
987		
988		
989		/**
990		* Trigger the relevant event handler
991		* The handlers are passed the original event, the element that was swiped, and in the case of the catch all handler, the direction that was swiped, "left", "right", "up", or "down"
992		* @param {object} event the original event object
993		* @param {string} phase the phase of the swipe (start, end cancel etc) {@link $.fn.swipe.phases}
994		* @param {string} gesture the gesture to trigger a handler for : PINCH or SWIPE {@link $.fn.swipe.gestures}
995		* @return Boolean False, to indicate that the event should stop propagation, or void.
996		* @inner
997		*/
998		function triggerHandlerForGesture(event, phase, gesture) {	
999			
1000			var ret;
1001			
1002			//SWIPES....
1003			if(gesture==SWIPE) {
1004				//Trigger status every time..
1005				
1006				//Trigger the event...
1007				$element.trigger('swipeStatus', [phase, direction || null, distance || 0, duration || 0, fingerCount, fingerData]);
1008				
1009				//Fire the callback
1010				if (options.swipeStatus) {
1011					ret = options.swipeStatus.call($element, event, phase, direction || null, distance || 0, duration || 0, fingerCount, fingerData);
1012					//If the status cancels, then dont run the subsequent event handlers..
1013					if(ret===false) return false;
1014				}
1015				
1016				
1017				
1018				
1019				if (phase == PHASE_END && validateSwipe()) {
1020					//Fire the catch all event
1021					$element.trigger('swipe', [direction, distance, duration, fingerCount, fingerData]);
1022					
1023					//Fire catch all callback
1024					if (options.swipe) {
1025						ret = options.swipe.call($element, event, direction, distance, duration, fingerCount, fingerData);
1026						//If the status cancels, then dont run the subsequent event handlers..
1027						if(ret===false) return false;
1028					}
1029					
1030					//trigger direction specific event handlers	
1031					switch (direction) {
1032						case LEFT:
1033							//Trigger the event
1034							$element.trigger('swipeLeft', [direction, distance, duration, fingerCount, fingerData]);
1035					
1036					        //Fire the callback
1037							if (options.swipeLeft) {
1038								ret = options.swipeLeft.call($element, event, direction, distance, duration, fingerCount, fingerData);
1039							}
1040							break;
1041	
1042						case RIGHT:
1043							//Trigger the event
1044					        $element.trigger('swipeRight', [direction, distance, duration, fingerCount, fingerData]);
1045					
1046					        //Fire the callback
1047							if (options.swipeRight) {
1048								ret = options.swipeRight.call($element, event, direction, distance, duration, fingerCount, fingerData);
1049							}
1050							break;
1051	
1052						case UP:
1053							//Trigger the event
1054					        $element.trigger('swipeUp', [direction, distance, duration, fingerCount, fingerData]);
1055					
1056					        //Fire the callback
1057							if (options.swipeUp) {
1058								ret = options.swipeUp.call($element, event, direction, distance, duration, fingerCount, fingerData);
1059							}
1060							break;
1061	
1062						case DOWN:
1063							//Trigger the event
1064					        $element.trigger('swipeDown', [direction, distance, duration, fingerCount, fingerData]);
1065					
1066					        //Fire the callback
1067							if (options.swipeDown) {
1068								ret = options.swipeDown.call($element, event, direction, distance, duration, fingerCount, fingerData);
1069							}
1070							break;
1071					}
1072				}
1073			}
1074			
1075			
1076			//PINCHES....
1077			if(gesture==PINCH) {
1078				//Trigger the event
1079			     $element.trigger('pinchStatus', [phase, pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData]);
1080					
1081                //Fire the callback
1082				if (options.pinchStatus) {
1083					ret = options.pinchStatus.call($element, event, phase, pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData);
1084					//If the status cancels, then dont run the subsequent event handlers..
1085					if(ret===false) return false;
1086				}
1087				
1088				if(phase==PHASE_END && validatePinch()) {
1089					
1090					switch (pinchDirection) {
1091						case IN:
1092							//Trigger the event
1093                            $element.trigger('pinchIn', [pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData]);
1094                    
1095                            //Fire the callback
1096                            if (options.pinchIn) {
1097								ret = options.pinchIn.call($element, event, pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData);
1098							}
1099							break;
1100						
1101						case OUT:
1102							//Trigger the event
1103                            $element.trigger('pinchOut', [pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData]);
1104                    
1105                            //Fire the callback
1106                            if (options.pinchOut) {
1107								ret = options.pinchOut.call($element, event, pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData);
1108							}
1109							break;	
1110					}
1111				}
1112			}
1113			
1114
1115
1116                
1117	    		
1118			if(gesture==TAP) {
1119				if(phase === PHASE_CANCEL || phase === PHASE_END) {
1120					
1121    			    
1122    			    //Cancel any existing double tap
1123				    clearTimeout(singleTapTimeout);
1124    			    //Cancel hold timeout
1125				    clearTimeout(holdTimeout);
1126				           
1127					//If we are also looking for doubelTaps, wait incase this is one...
1128				    if(hasDoubleTap() && !inDoubleTap()) {
1129				        //Cache the time of this tap
1130                        doubleTapStartTime = getTimeStamp();
1131                       
1132				        //Now wait for the double tap timeout, and trigger this single tap
1133				        //if its not cancelled by a double tap
1134				        singleTapTimeout = setTimeout($.proxy(function() {
1135        			        doubleTapStartTime=null;
1136        			        //Trigger the event
1137                			$element.trigger('tap', [event.target]);
1138
1139                        
1140                            //Fire the callback
1141                            if(options.tap) {
1142                                ret = options.tap.call($element, event, event.target);
1143                            }
1144    			        }, this), options.doubleTapThreshold );
1145    			    	
1146    			    } else {
1147                        doubleTapStartTime=null;
1148                        
1149                        //Trigger the event
1150                        $element.trigger('tap', [event.target]);
1151
1152                        
1153                        //Fire the callback
1154                        if(options.tap) {
1155                            ret = options.tap.call($element, event, event.target);
1156                        }
1157	    		    }
1158	    		}
1159			}
1160			
1161			else if (gesture==DOUBLE_TAP) {
1162				if(phase === PHASE_CANCEL || phase === PHASE_END) {
1163					//Cancel any pending singletap 
1164				    clearTimeout(singleTapTimeout);
1165				    doubleTapStartTime=null;
1166				        
1167                    //Trigger the event
1168                    $element.trigger('doubletap', [event.target]);
1169                
1170                    //Fire the callback
1171                    if(options.doubleTap) {
1172                        ret = options.doubleTap.call($element, event, event.target);
1173                    }
1174	    		}
1175			}
1176			
1177			else if (gesture==LONG_TAP) {
1178				if(phase === PHASE_CANCEL || phase === PHASE_END) {
1179					//Cancel any pending singletap (shouldnt be one)
1180				    clearTimeout(singleTapTimeout);
1181				    doubleTapStartTime=null;
1182				        
1183                    //Trigger the event
1184                    $element.trigger('longtap', [event.target]);
1185                
1186                    //Fire the callback
1187                    if(options.longTap) {
1188                        ret = options.longTap.call($element, event, event.target);
1189                    }
1190	    		}
1191			}				
1192				
1193			return ret;
1194		}
1195
1196
1197
1198		
1199		//
1200		// GESTURE VALIDATION
1201		//
1202		
1203		/**
1204		* Checks the user has swipe far enough
1205		* @return Boolean if <code>threshold</code> has been set, return true if the threshold was met, else false.
1206		* If no threshold was set, then we return true.
1207		* @inner
1208		*/
1209		function validateSwipeDistance() {
1210			var valid = true;
1211			//If we made it past the min swipe distance..
1212			if (options.threshold !== null) {
1213				valid = distance >= options.threshold;
1214			}
1215			
1216            return valid;
1217		}
1218		
1219		/**
1220		* Checks the user has swiped back to cancel.
1221		* @return Boolean if <code>cancelThreshold</code> has been set, return true if the cancelThreshold was met, else false.
1222		* If no cancelThreshold was set, then we return true.
1223		* @inner
1224		*/
1225		function didSwipeBackToCancel() {
1226            var cancelled = false;
1227    		if(options.cancelThreshold !== null && direction !==null)  {
1228    		    cancelled =  (getMaxDistance( direction ) - distance) >= options.cancelThreshold;
1229			}
1230			
1231			return cancelled;
1232		}
1233
1234		/**
1235		* Checks the user has pinched far enough
1236		* @return Boolean if <code>pinchThreshold</code> has been set, return true if the threshold was met, else false.
1237		* If no threshold was set, then we return true.
1238		* @inner
1239		*/
1240		function validatePinchDistance() {
1241			if (options.pinchThreshold !== null) {
1242				return pinchDistance >= options.pinchThreshold;
1243			}
1244			return true;
1245		}
1246
1247		/**
1248		* Checks that the time taken to swipe meets the minimum / maximum requirements
1249		* @return Boolean
1250		* @inner
1251		*/
1252		function validateSwipeTime() {
1253			var result;
1254			//If no time set, then return true
1255
1256			if (options.maxTimeThreshold) {
1257				if (duration >= options.maxTimeThreshold) {
1258					result = false;
1259				} else {
1260					result = true;
1261				}
1262			}
1263			else {
1264				result = true;
1265			}
1266
1267			return result;
1268		}
1269
1270	
1271
1272		/**
1273		* Checks direction of the swipe and the value allowPageScroll to see if we should allow or prevent the default behaviour from occurring.
1274		* This will essentially allow page scrolling or not when the user is swiping on a touchSwipe object.
1275		* @param {object} jqEvent The normalised jQuery representation of the event object.
1276		* @param {string} direction The direction of the event. See {@link $.fn.swipe.directions}
1277		* @see $.fn.swipe.directions
1278		* @inner
1279		*/
1280		function validateDefaultEvent(jqEvent, direction) {
1281
1282			//If we have no pinches, then do this
1283			//If we have a pinch, and we we have 2 fingers or more down, then dont allow page scroll.
1284
1285			//If the option is set, allways allow the event to bubble up (let user handle wiredness)
1286			if( options.preventDefaultEvents === false) {
1287				return;
1288			}
1289
1290			if (options.allowPageScroll === NONE) {
1291				jqEvent.preventDefault();
1292			} else {
1293				var auto = options.allowPageScroll === AUTO;
1294
1295				switch (direction) {
1296					case LEFT:
1297						if ((options.swipeLeft && auto) || (!auto && options.allowPageScroll != HORIZONTAL)) {
1298							jqEvent.preventDefault();
1299						}
1300						break;
1301
1302					case RIGHT:
1303						if ((options.swipeRight && auto) || (!auto && options.allowPageScroll != HORIZONTAL)) {
1304							jqEvent.preventDefault();
1305						}
1306						break;
1307
1308					case UP:
1309						if ((options.swipeUp && auto) || (!auto && options.allowPageScroll != VERTICAL)) {
1310							jqEvent.preventDefault();
1311						}
1312						break;
1313
1314					case DOWN:
1315						if ((options.swipeDown && auto) || (!auto && options.allowPageScroll != VERTICAL)) {
1316							jqEvent.preventDefault();
1317						}
1318						break;
1319				}
1320			}
1321
1322		}
1323
1324
1325		// PINCHES
1326		/**
1327		 * Returns true of the current pinch meets the thresholds
1328		 * @return Boolean
1329		 * @inner
1330		*/
1331		function validatePinch() {
1332		    var hasCorrectFingerCount = validateFingers();
1333		    var hasEndPoint = validateEndPoint();
1334			var hasCorrectDistance = validatePinchDistance();
1335			return hasCorrectFingerCount && hasEndPoint && hasCorrectDistance;
1336			
1337		}
1338		
1339		/**
1340		 * Returns true if any Pinch events have been registered
1341		 * @return Boolean
1342		 * @inner
1343		*/
1344		function hasPinches() {
1345			//Enure we dont return 0 or null for false values
1346			return !!(options.pinchStatus || options.pinchIn || options.pinchOut);
1347		}
1348		
1349		/**
1350		 * Returns true if we are detecting pinches, and have one
1351		 * @return Boolean
1352		 * @inner
1353		 */
1354		function didPinch() {
1355			//Enure we dont return 0 or null for false values
1356			return !!(validatePinch() && hasPinches());
1357		}
1358
1359
1360
1361
1362		// SWIPES
1363		/**
1364		 * Returns true if the current swipe meets the thresholds
1365		 * @return Boolean
1366		 * @inner
1367		*/
1368		function validateSwipe() {
1369			//Check validity of swipe
1370			var hasValidTime = validateSwipeTime();
1371			var hasValidDistance = validateSwipeDistance();	
1372			var hasCorrectFingerCount = validateFingers();
1373		    var hasEndPoint = validateEndPoint();
1374		    var didCancel = didSwipeBackToCancel();	
1375		    
1376			// if the user swiped more than the minimum length, perform the appropriate action
1377			// hasValidDistance is null when no distance is set 
1378			var valid =  !didCancel && hasEndPoint && hasCorrectFingerCount && hasValidDistance && hasValidTime;
1379			
1380			return valid;
1381		}
1382		
1383		/**
1384		 * Returns true if any Swipe events have been registered
1385		 * @return Boolean
1386		 * @inner
1387		*/
1388		function hasSwipes() {
1389			//Enure we dont return 0 or null for false values
1390			return !!(options.swipe || options.swipeStatus || options.swipeLeft || options.swipeRight || options.swipeUp || options.swipeDown);
1391		}
1392		
1393		
1394		/**
1395		 * Returns true if we are detecting swipes and have one
1396		 * @return Boolean
1397		 * @inner
1398		*/
1399		function didSwipe() {
1400			//Enure we dont return 0 or null for false values
1401			return !!(validateSwipe() && hasSwipes());
1402		}
1403
1404        /**
1405		 * Returns true if we have matched the number of fingers we are looking for
1406		 * @return Boolean
1407		 * @inner
1408		*/
1409        function validateFingers() {
1410            //The number of fingers we want were matched, or on desktop we ignore
1411    		return ((fingerCount === options.fingers || options.fingers === ALL_FINGERS) || !SUPPORTS_TOUCH);
1412    	}
1413        
1414        /**
1415		 * Returns true if we have an end point for the swipe
1416		 * @return Boolean
1417		 * @inner
1418		*/
1419        function validateEndPoint() {
1420            //We have an end value for the finger
1421		    return fingerData[0].end.x !== 0;
1422        }
1423
1424		// TAP / CLICK
1425		/**
1426		 * Returns true if a click / tap events have been registered
1427		 * @return Boolean
1428		 * @inner
1429		*/
1430		function hasTap() {
1431			//Enure we dont return 0 or null for false values
1432			return !!(options.tap) ;
1433		}
1434		
1435		/**
1436		 * Returns true if a double tap events have been registered
1437		 * @return Boolean
1438		 * @inner
1439		*/
1440		function hasDoubleTap() {
1441			//Enure we dont return 0 or null for false values
1442			return !!(options.doubleTap) ;
1443		}
1444		
1445		/**
1446		 * Returns true if any long tap events have been registered
1447		 * @return Boolean
1448		 * @inner
1449		*/
1450		function hasLongTap() {
1451			//Enure we dont return 0 or null for false values
1452			return !!(options.longTap) ;
1453		}
1454		
1455		/**
1456		 * Returns true if we could be in the process of a double tap (one tap has occurred, we are listening for double taps, and the threshold hasn't past.
1457		 * @return Boolean
1458		 * @inner
1459		*/
1460		function validateDoubleTap() {
1461		    if(doubleTapStartTime==null){
1462		        return false;
1463		    }
1464		    var now = getTimeStamp();
1465		    return (hasDoubleTap() && ((now-doubleTapStartTime) <= options.doubleTapThreshold));
1466		}
1467		
1468		/**
1469		 * Returns true if we could be in the process of a double tap (one tap has occurred, we are listening for double taps, and the threshold hasn't past.
1470		 * @return Boolean
1471		 * @inner
1472		*/
1473		function inDoubleTap() {
1474		    return validateDoubleTap();
1475		}
1476		
1477		
1478		/**
1479		 * Returns true if we have a valid tap
1480		 * @return Boolean
1481		 * @inner
1482		*/
1483		function validateTap() {
1484		    return ((fingerCount === 1 || !SUPPORTS_TOUCH) && (isNaN(distance) || distance < options.threshold));
1485		}
1486		
1487		/**
1488		 * Returns true if we have a valid long tap
1489		 * @return Boolean
1490		 * @inner
1491		*/
1492		function validateLongTap() {
1493		    //slight threshold on moving finger
1494            return ((duration > options.longTapThreshold) && (distance < DOUBLE_TAP_THRESHOLD)); 
1495		}
1496		
1497		/**
1498		 * Returns true if we are detecting taps and have one
1499		 * @return Boolean
1500		 * @inner
1501		*/
1502		function didTap() {
1503		    //Enure we dont return 0 or null for false values
1504			return !!(validateTap() && hasTap());
1505		}
1506		
1507		
1508		/**
1509		 * Returns true if we are detecting double taps and have one
1510		 * @return Boolean
1511		 * @inner
1512		*/
1513		function didDoubleTap() {
1514		    //Enure we dont return 0 or null for false values
1515			return !!(validateDoubleTap() && hasDoubleTap());
1516		}
1517		
1518		/**
1519		 * Returns true if we are detecting long taps and have one
1520		 * @return Boolean
1521		 * @inner
1522		*/
1523		function didLongTap() {
1524		    //Enure we dont return 0 or null for false values
1525			return !!(validateLongTap() && hasLongTap());
1526		}
1527		
1528		
1529		
1530		
1531		// MULTI FINGER TOUCH
1532		/**
1533		 * Starts tracking the time between 2 finger releases, and keeps track of how many fingers we initially had up
1534		 * @inner
1535		*/
1536		function startMultiFingerRelease() {
1537			previousTouchEndTime = getTimeStamp();
1538			previousTouchFingerCount = event.touches.length+1;
1539		}
1540		
1541		/**
1542		 * Cancels the tracking of time between 2 finger releases, and resets counters
1543		 * @inner
1544		*/
1545		function cancelMultiFingerRelease() {
1546			previousTouchEndTime = 0;
1547			previousTouchFingerCount = 0;
1548		}
1549		
1550		/**
1551		 * Checks if we are in the threshold between 2 fingers being released 
1552		 * @return Boolean
1553		 * @inner
1554		*/
1555		function inMultiFingerRelease() {
1556			
1557			var withinThreshold = false;
1558			
1559			if(previousTouchEndTime) {	
1560				var diff = getTimeStamp() - previousTouchEndTime	
1561				if( diff<=options.fingerReleaseThreshold ) {
1562					withinThreshold = true;
1563				}
1564			}
1565			
1566			return withinThreshold;	
1567		}
1568		
1569
1570		/**
1571		* gets a data flag to indicate that a touch is in progress
1572		* @return Boolean
1573		* @inner
1574		*/
1575		function getTouchInProgress() {
1576			//strict equality to ensure only true and false are returned
1577			return !!($element.data(PLUGIN_NS+'_intouch') === true);
1578		}
1579		
1580		/**
1581		* Sets a data flag to indicate that a touch is in progress
1582		* @param {boolean} val The value to set the property to
1583		* @inner
1584		*/
1585		function setTouchInProgress(val) {
1586			
1587			//Add or remove event listeners depending on touch status
1588			if(val===true) {
1589				$element.bind(MOVE_EV, touchMove);
1590				$element.bind(END_EV, touchEnd);
1591				
1592				//we only have leave events on desktop, we manually calcuate leave on touch as its not supported in webkit
1593				if(LEAVE_EV) { 
1594					$element.bind(LEAVE_EV, touchLeave);
1595				}
1596			} else {
1597				$element.unbind(MOVE_EV, touchMove, false);
1598				$element.unbind(END_EV, touchEnd, false);
1599			
1600				//we only have leave events on desktop, we manually calcuate leave on touch as its not supported in webkit
1601				if(LEAVE_EV) { 
1602					$element.unbind(LEAVE_EV, touchLeave, false);
1603				}
1604			}
1605			
1606		
1607			//strict equality to ensure only true and false can update the value
1608			$element.data(PLUGIN_NS+'_intouch', val === true);
1609		}
1610		
1611		
1612		/**
1613		 * Creates the finger data for the touch/finger in the event object.
1614		 * @param {int} index The index in the array to store the finger data (usually the order the fingers were pressed)
1615		 * @param {object}
1615 evt The event object containing finger data
1616		 * @return finger data object
1617		 * @inner
1618		*/
1619		function createFingerData( index, evt ) {
1620			var id = evt.identifier!==undefined ? evt.identifier : 0; 
1621			
1622			fingerData[index].identifier = id;
1623			fingerData[index].start.x = fingerData[index].end.x = evt.pageX||evt.clientX;
1624			fingerData[index].start.y = fingerData[index].end.y = evt.pageY||evt.clientY;
1625			
1626			return fingerData[index];
1627		}
1628		
1629		/**
1630		 * Updates the finger data for a particular event object
1631		 * @param {object} evt The event object containing the touch/finger data to upadte
1632		 * @return a finger data object.
1633		 * @inner
1634		*/
1635		function updateFingerData(evt) {
1636			
1637			var id = evt.identifier!==undefined ? evt.identifier : 0; 
1638			var f = getFingerData( id );
1639			
1640			f.end.x = evt.pageX||evt.clientX;
1641			f.end.y = evt.pageY||evt.clientY;
1642			
1643			return f;
1644		}
1645		
1646		/**
1647		 * Returns a finger data object by its event ID.
1648		 * Each touch event has an identifier property, which is used 
1649		 * to track repeat touches
1650		 * @param {int} id The unique id of the finger in the sequence of touch events.
1651		 * @return a finger data object.
1652		 * @inner
1653		*/
1654		function getFingerData( id ) {
1655			for(var i=0; i<fingerData.length; i++) {
1656				if(fingerData[i].identifier == id) {
1657					return fingerData[i];	
1658				}
1659			}
1660		}
1661		
1662		/**
1663		 * Creats all the finger onjects and returns an array of finger data
1664		 * @return Array of finger objects
1665		 * @inner
1666		*/
1667		function createAllFingerData() {
1668			var fingerData=[];
1669			for (var i=0; i<=5; i++) {
1670				fingerData.push({
1671					start:{ x: 0, y: 0 },
1672					end:{ x: 0, y: 0 },
1673					identifier:0
1674				});
1675			}
1676			
1677			return fingerData;
1678		}
1679		
1680		/**
1681		 * Sets the maximum distance swiped in the given direction. 
1682		 * If the new value is lower than the current value, the max value is not changed.
1683		 * @param {string}  direction The direction of the swipe
1684		 * @param {int}  distance The distance of the swipe
1685		 * @inner
1686		*/
1687		function setMaxDistance(direction, distance) {
1688    		distance = Math.max(distance, getMaxDistance(direction) );
1689    		maximumsMap[direction].distance = distance;
1690		}
1691        
1692        /**
1693		 * gets the maximum distance swiped in the given direction. 
1694		 * @param {string}  direction The direction of the swipe
1695		 * @return int  The distance of the swipe
1696		 * @inner
1697		*/        
1698		function getMaxDistance(direction) {
1699			if (maximumsMap[direction]) return maximumsMap[direction].distance;
1700			return undefined;
1701		}
1702		
1703		/**
1704		 * Creats a map of directions to maximum swiped values.
1705		 * @return Object A dictionary of maximum values, indexed by direction.
1706		 * @inner
1707		*/
1708		function createMaximumsData() {
1709			var maxData={};
1710			maxData[LEFT]=createMaximumVO(LEFT);
1711			maxData[RIGHT]=createMaximumVO(RIGHT);
1712			maxData[UP]=createMaximumVO(UP);
1713			maxData[DOWN]=createMaximumVO(DOWN);
1714			
1715			return maxData;
1716		}
1717		
1718		/**
1719		 * Creates a map maximum swiped values for a given swipe direction
1720		 * @param {string} The direction that these values will be associated with
1721		 * @return Object Maximum values
1722		 * @inner
1723		*/
1724		function createMaximumVO(dir) {
1725		    return { 
1726		        direction:dir, 
1727		        distance:0
1728		    }
1729		}
1730		
1731		
1732		//
1733		// MATHS / UTILS
1734		//
1735
1736		/**
1737		* Calculate the duration of the swipe
1738		* @return int
1739		* @inner
1740		*/
1741		function calculateDuration() {
1742			return endTime - startTime;
1743		}
1744		
1745		/**
1746		* Calculate the distance between 2 touches (pinch)
1747		* @param {point} startPoint A point object containing x and y co-ordinates
1748	    * @param {point} endPoint A point object containing x and y co-ordinates
1749	    * @return int;
1750		* @inner
1751		*/
1752		function calculateTouchesDistance(startPoint, endPoint) {
1753			var diffX = Math.abs(startPoint.x - endPoint.x);
1754			var diffY = Math.abs(startPoint.y - endPoint.y);
1755				
1756			return Math.round(Math.sqrt(diffX*diffX+diffY*diffY));
1757		}
1758		
1759		/**
1760		* Calculate the zoom factor between the start and end distances
1761		* @param {int} startDistance Distance (between 2 fingers) the user started pinching at
1762	    * @param {int} endDistance Distance (between 2 fingers) the user ended pinching at
1763	    * @return float The zoom value from 0 to 1.
1764		* @inner
1765		*/
1766		function calculatePinchZoom(startDistance, endDistance) {
1767			var percent = (endDistance/startDistance) * 1;
1768			return percent.toFixed(2);
1769		}
1770		
1771		
1772		/**
1773		* Returns the pinch direction, either IN or OUT for the given points
1774		* @return string Either {@link $.fn.swipe.directions.IN} or {@link $.fn.swipe.directions.OUT}
1775		* @see $.fn.swipe.directions
1776		* @inner
1777		*/
1778		function calculatePinchDirection() {
1779			if(pinchZoom<1) {
1780				return OUT;
1781			}
1782			else {
1783				return IN;
1784			}
1785		}
1786		
1787		
1788		/**
1789		* Calculate the length / distance of the swipe
1790		* @param {point}
vendor: 5,862 bytes, lines 1790-1967
1790 startPoint A point object containing x and y co-ordinates
1791	    * @param {point} endPoint A point object containing x and y co-ordinates
1792	    * @return int
1793		* @inner
1794		*/
1795		function calculateDistance(startPoint, endPoint) {
1796			return Math.round(Math.sqrt(Math.pow(endPoint.x - startPoint.x, 2) + Math.pow(endPoint.y - startPoint.y, 2)));
1797		}
1798
1799		/**
1800		* Calculate the angle of the swipe
1801		* @param {point} startPoint A point object containing x and y co-ordinates
1802	    * @param {point} endPoint A point object containing x and y co-ordinates
1803	    * @return int
1804		* @inner
1805		*/
1806		function calculateAngle(startPoint, endPoint) {
1807			var x = startPoint.x - endPoint.x;
1808			var y = endPoint.y - startPoint.y;
1809			var r = Math.atan2(y, x); //radians
1810			var angle = Math.round(r * 180 / Math.PI); //degrees
1811
1812			//ensure value is positive
1813			if (angle < 0) {
1814				angle = 360 - Math.abs(angle);
1815			}
1816
1817			return angle;
1818		}
1819
1820		/**
1821		* Calculate the direction of the swipe
1822		* This will also call calculateAngle to get the latest angle of swipe
1823		* @param {point} startPoint A point object containing x and y co-ordinates
1824	    * @param {point} endPoint A point object containing x and y co-ordinates
1825	    * @return string Either {@link $.fn.swipe.directions.LEFT} / {@link $.fn.swipe.directions.RIGHT} / {@link $.fn.swipe.directions.DOWN} / {@link $.fn.swipe.directions.UP}
1826		* @see $.fn.swipe.directions
1827		* @inner
1828		*/
1829		function calculateDirection(startPoint, endPoint ) {
1830			var angle = calculateAngle(startPoint, endPoint);
1831
1832			if ((angle <= 45) && (angle >= 0)) {
1833				return LEFT;
1834			} else if ((angle <= 360) && (angle >= 315)) {
1835				return LEFT;
1836			} else if ((angle >= 135) && (angle <= 225)) {
1837				return RIGHT;
1838			} else if ((angle > 45) && (angle < 135)) {
1839				return DOWN;
1840			} else {
1841				return UP;
1842			}
1843		}
1844		
1845
1846		/**
1847		* Returns a MS time stamp of the current time
1848		* @return int
1849		* @inner
1850		*/
1851		function getTimeStamp() {
1852			var now = new Date();
1853			return now.getTime();
1854		}
1855		
1856		
1857		
1858		/**
1859		 * Returns a bounds object with left, right, top and bottom properties for the element specified.
1860		 * @param {DomNode} The DOM node to get the bounds for.
1861		 */
1862		function getbounds( el ) {
1863			el = $(el);
1864			var offset = el.offset();
1865			
1866			var bounds = {	
1867					left:offset.left,
1868					right:offset.left+el.outerWidth(),
1869					top:offset.top,
1870					bottom:offset.top+el.outerHeight()
1871					}
1872			
1873			return bounds;	
1874		}
1875		
1876		
1877		/**
1878		 * Checks if the point object is in the bounds object.
1879		 * @param {object} point A point object.
1880		 * @param {int} point.x The x value of the point.
1881		 * @param {int} point.y The x value of the point.
1882		 * @param {object} bounds The bounds object to test
1883		 * @param {int} bounds.left The leftmost value
1884		 * @param {int} bounds.right The righttmost value
1885		 * @param {int} bounds.top The topmost value
1886		* @param {int} bounds.bottom The bottommost value
1887		 */
1888		function isInBounds(point, bounds) {
1889			return (point.x > bounds.left && point.x < bounds.right && point.y > bounds.top && point.y < bounds.bottom);
1890		};
1891	
1892	
1893	}
1894	
1895	
1896
1897
1898/**
1899 * A catch all handler that is triggered for all swipe directions. 
1900 * @name $.fn.swipe#swipe
1901 * @event
1902 * @default null
1903 * @param {EventObject} event The original event object
1904 * @param {int} direction The direction the user swiped in. See {@link $.fn.swipe.directions}
1905 * @param {int} distance The distance the user swiped
1906 * @param {int} duration The duration of the swipe in milliseconds
1907 * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers}
1908 * @param {object} fingerData The coordinates of fingers in event
1909 */
1910 
1911
1912
1913
1914/**
1915 * A handler that is triggered for "left" swipes.
1916 * @name $.fn.swipe#swipeLeft
1917 * @event
1918 * @default null
1919 * @param {EventObject} event The original event object
1920 * @param {int} direction The direction the user swiped in. See {@link $.fn.swipe.directions}
1921 * @param {int} distance The distance the user swiped
1922 * @param {int} duration The duration of the swipe in milliseconds
1923 * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers}
1924 * @param {object} fingerData The coordinates of fingers in event
1925 */
1926 
1927/**
1928 * A handler that is triggered for "right" swipes.
1929 * @name $.fn.swipe#swipeRight
1930 * @event
1931 * @default null
1932 * @param {EventObject} event The original event object
1933 * @param {int} direction The direction the user swiped in. See {@link $.fn.swipe.directions}
1934 * @param {int} distance The distance the user swiped
1935 * @param {int} duration The duration of the swipe in milliseconds
1936 * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers}
1937 * @param {object} fingerData The coordinates of fingers in event
1938 */
1939
1940/**
1941 * A handler that is triggered for "up" swipes.
1942 * @name $.fn.swipe#swipeUp
1943 * @event
1944 * @default null
1945 * @param {EventObject} event The original event object
1946 * @param {int} direction The direction the user swiped in. See {@link $.fn.swipe.directions}
1947 * @param {int} distance The distance the user swiped
1948 * @param {int} duration The duration of the swipe in milliseconds
1949 * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers}
1950 * @param {object} fingerData The coordinates of fingers in event
1951 */
1952 
1953/**
1954 * A handler that is triggered for "down" swipes.
1955 * @name $.fn.swipe#swipeDown
1956 * @event
1957 * @default null
1958 * @param {EventObject} event The original event object
1959 * @param {int} direction The direction the user swiped in. See {@link $.fn.swipe.directions}
1960 * @param {int} distance The distance the user swiped
1961 * @param {int} duration The duration of the swipe in milliseconds
1962 * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers}
1963 * @param {object} fingerData The coordinates of fingers in event
1964 */
1965 
1966/**
1967 * A handler triggered for every phase of the swipe. This handler is constantly f
1967ired for the duration of the pinch.
1968 * This is triggered regardless of swipe thresholds.
1969 * @name $.fn.swipe#swipeStatus
1970 * @event
1971 * @default null
1972 * @param {EventObject} event The original event object
1973 * @param {string} phase The phase of the swipe event. See {@link $.fn.swipe.phases}
1974 * @param {string} direction The direction the user swiped in. This is null if the user has yet to move. See {@link $.fn.swipe.directions}
1975 * @param {int} distance The distance the user swiped. This is 0 if the user has yet to move.
1976 * @param {int} duration The duration of the swipe in milliseconds
1977 * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers}
1978 * @param {object} fingerData The coordinates of fingers in event
1979 */
1980 
1981/**
1982 * A handler triggered for pinch in events.
1983 * @name $.fn.swipe#pinchIn
1984 * @event
1985 * @default null
1986 * @param {EventObject} event The original event object
1987 * @param {int} direction The direction the user pinched in. See {@link $.fn.swipe.directions}
1988 * @param {int} distance The distance the user pinched
1989 * @param {int} duration The duration of the swipe in milliseconds
1990 * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers}
1991 * @param {int} zoom The zoom/scale level the user pinched too, 0-1.
1992 * @param {object} fingerData The coordinates of fingers in event
1993 */
1994
1995/**
1996 * A handler triggered for pinch out events.
1997 * @name $.fn.swipe#pinchOut
1998 * @event
1999 * @default null
2000 * @param {EventObject} event The original event object
2001 * @param {int} direction The direction the user pinched in. See {@link $.fn.swipe.directions}
2002 * @param {int} distance The distance the user pinched
2003 * @param {int} duration The duration of the swipe in milliseconds
2004 * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers}
2005 * @param {int} zoom The zoom/scale level the user pinched too, 0-1.
2006 * @param {object} fingerData The coordinates of fingers in event
2007 */ 
2008
2009/**
2010 * A handler triggered for all pinch events. This handler is constantly fired for the duration of the pinch. This is triggered regardless of thresholds.
2011 * @name $.fn.swipe#pinchStatus
2012 * @event
2013 * @default null
2014 * @param {EventObject} event The original event object
2015 * @param {int} direction The direction the user pinched in. See {@link $.fn.swipe.directions}
2016 * @param {int} distance The distance the user pinched
2017 * @param {int} duration The duration of the swipe in milliseconds
2018 * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers}
2019 * @param {int} zoom The zoom/scale level the user pinched too, 0-1.
2020 * @param {object} fingerData The coordinates of fingers in event
2021 */
2022
2023/**
2024 * A click handler triggered when a user simply clicks, rather than swipes on an element.
2025 * This is deprecated since version 1.6.2, any assignment to click will be assigned to the tap handler.
2026 * You cannot use <code>on</code> to bind to this event as the default jQ <code>click</code> event will be triggered.
2027 * Use the <code>tap</code> event instead.
2028 * @name $.fn.swipe#click
2029 * @event
2030 * @deprecated since version 1.6.2, please use {@link $.fn.swipe#tap} instead 
2031 * @default null
2032 * @param {EventObject} event The original event object
2033 * @param {DomObject} target The element clicked on.
2034 */
2035 
2036 /**
2037 * A click / tap handler triggered when a user simply clicks or taps, rather than swipes on an element.
2038 * @name $.fn.swipe#tap
2039 * @event
2040 * @default null
2041 * @param {EventObject} event The original event object
2042 * @param {DomObject} target The element clicked on.
2043 */
2044 
2045/**
2046 * A double tap handler triggered when a user double clicks or taps on an element.
2047 * You can set the time delay for a double tap with the {@link $.fn.swipe.defaults#doubleTapThreshold} property. 
2048 * Note: If you set both <code>doubleTap</code> and <code>tap</code> handlers, the <code>tap</code> event will be delayed by the <code>doubleTapThreshold</code>
2049 * as the script needs to check if its a double tap.
2050 * @name $.fn.swipe#doubleTap
2051 * @see  $.fn.swipe.defaults#doubleTapThreshold
2052 * @event
2053 * @default null
2054 * @param {EventObject} event The original event object
2055 * @param {DomObject} target The element clicked on.
2056 */
2057 
2058 /**
2059 * A long tap handler triggered once a tap has been release if the tap was longer than the longTapThreshold.
2060 * You can set the time delay for a long tap with the {@link $.fn.swipe.defaults#longTapThreshold} property. 
2061 * @name $.fn.swipe#longTap
2062 * @see  $.fn.swipe.defaults#longTapThreshold
2063 * @event
2064 * @default null
2065 * @param {EventObject} event The original event object
2066 * @param {DomObject} target The element clicked on.
2067 */
2068
2069  /**
2070 * A hold tap handler triggered as soon as the longTapThreshold is reached
2071 * You can set the time delay for a long tap with the {@link $.fn.swipe.defaults#longTapThreshold} property. 
2072 * @name $.fn.swipe#hold
2073 * @see  $.fn.swipe.defaults#longTapThreshold
2074 * @event
2075 * @default null
2076 * @param {EventObject} event The original event object
2077 * @param {DomObject} target The element clicked on.
2078 */
2079
2080}));

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.