You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by pp...@apache.org on 2013/09/10 20:04:08 UTC

[03/51] [partial] [cordova-tizen] Tizen SDK 2.2 support mores samples

http://git-wip-us.apache.org/repos/asf/cordova-tizen/blob/4ebce38e/samples/TizenWebUI-sample-v1/tizen-web-ui-fw/latest/js/tizen-web-ui-fw.js
----------------------------------------------------------------------
diff --git a/samples/TizenWebUI-sample-v1/tizen-web-ui-fw/latest/js/tizen-web-ui-fw.js b/samples/TizenWebUI-sample-v1/tizen-web-ui-fw/latest/js/tizen-web-ui-fw.js
new file mode 100644
index 0000000..c726d09
--- /dev/null
+++ b/samples/TizenWebUI-sample-v1/tizen-web-ui-fw/latest/js/tizen-web-ui-fw.js
@@ -0,0 +1,18826 @@
+
+/*
+* jQuery Mobile Framework : scrollview plugin
+* Copyright (c) 2010 Adobe Systems Incorporated - Kin Blas (jblas@adobe.com)
+* Licensed under the MIT (MIT-LICENSE.txt) license.
+* Note: Code is in draft form and is subject to change
+* Modified by Koeun Choi <ko...@samsung.com>
+* Modified by Minkyu Kang <mk...@samsung.com>
+*/
+
+(function ( $, window, document, undefined ) {
+
+	/**
+	 * Resizes page content height according to footer
+	 * header elements, and page padding
+	 * @param {HTMLElement|jQuery} page
+	 */
+	function resizePageContentHeight( page ) {
+		var $page = $( page ),
+			$content = $page.children(".ui-content"),
+			hh = $page.children(".ui-header").outerHeight() || 0,
+			fh = $page.children(".ui-footer").outerHeight() || 0,
+			pt = parseFloat( $content.css("padding-top") ),
+			pb = parseFloat( $content.css("padding-bottom") ),
+			wh = $( window ).height();
+
+		$content.height( wh - (hh + fh) - (pt + pb) );
+	}
+
+	/**
+	 * MomentumTracker - helper class to ease momentum
+	 * movement calculations
+	 * @class
+	 * @param {Object} options
+	 */
+	function MomentumTracker( options ) {
+		this.options = $.extend( {}, options );
+		this.easing = "easeOutQuad";
+		this.reset();
+	}
+
+	/**
+	 * Scroll states dictionary
+	 * @type {Object}
+	 */
+	var tstates = {
+		scrolling: 0,
+		overshot:  1,
+		snapback:  2,
+		done:      3
+	};
+
+	/**
+	 * Returns current time in miliseconds
+	 * @return {number}
+	 */
+	function getCurrentTime() {
+		return Date.now();
+	};
+
+	function bitwiseAbs( e ) {
+		return ( e ^ (e>>31)) - (e>>31);
+	}
+
+	jQuery.widget( "tizen.scrollview", jQuery.mobile.widget, {
+		/**
+		 * Default options
+		 * @type {Object}
+		 */
+		options: {
+			/**
+			 * Direction of scroll, can be:
+			 * "x" for horizontal scroll
+			 * "y" for vertical scroll
+			 * null for horizontal and vertical scroll
+			 * @type {string|null}
+			 */
+			direction:         null,  // "x", "y", or null for both.
+
+			/**
+			 * Internal timer inteval
+			 * @type {number}
+			 */
+			timerInterval:     10,
+
+			/**
+			 * Duration of the scrolling animation in miliseconds
+			 * @type {number}
+			 */
+			scrollDuration:    1000,
+
+			/**
+			 * Duration of the overshoot animation in miliseconds
+			 * @type {number}
+			 */
+			overshootDuration: 250,
+
+			/**
+			 * Duration of snapback animation in miliseconds
+			 * @type {number}
+			 */
+			snapbackDuration:  500,
+
+			/**
+			 * Scroll detection threshold
+			 * @type {number}
+			 */
+			moveThreshold:     10,
+
+			/**
+			 * Maximal time between mouse movements while scrolling
+			 * @type {number}
+			 */
+			moveIntervalThreshold:     150,
+
+			/**
+			 * Scroll method type, can be "translate" or "position"
+			 * @type {string}
+			 */
+			scrollMethod:      "translate",
+
+			/**
+			 * The event fired when started scrolling
+			 * @type {string}
+			 */
+			startEventName:    "scrollstart",
+
+			/**
+			 * The event fired on each scroll update (movement)
+			 * @type {string}
+			 */
+			updateEventName:   "scrollupdate",
+
+			/**
+			 * The event fired after scroll stopped
+			 * @type {string}
+			 */
+			stopEventName:     "scrollstop",
+
+			/**
+			 * Determines the event group for detecting scroll
+			 * if $.support.touch has truthy value the group
+			 * that starts scroll will be touch events, otherwise
+			 * mouse events will be used
+			 * @type {string}
+			 */
+			eventType:         $.support.touch ? "touch" : "mouse",
+
+			/**
+			 * Determines if we should show the scrollbars
+			 * @type {boolean}
+			 */
+			showScrollBars:    true,
+
+			/**
+			 * Determines if overshoot animation is enabled
+			 * @type {boolean}
+			 */
+			overshootEnable:   false,
+
+			/**
+			 * Determines if we enable the window scroll
+			 * @type {boolean}
+			 */
+			outerScrollEnable: false,
+
+			/**
+			 * Determines if the overflow animation is enabled
+			 * @type {boolean}
+			 */
+			overflowEnable:    true,
+
+			/**
+			 * Determines if we allow scroll jumps
+			 * @type {boolean}
+			 */
+			scrollJump:        false
+		},
+
+		/**
+		 * Returns view height
+		 * @private
+		 * @return {number}
+		 */
+		_getViewHeight: function () {
+			return this._$view.height();
+		},
+
+		/**
+		 * Returns view width
+		 * @private
+		 * @return {number}
+		 */
+		_getViewWidth: function () {
+			return this._$view.width();
+		},
+
+		/**
+		 * Changes specified elements position to relative if
+		 * previous position state was static
+		 * @private
+		 * @param {jQuery} $ele
+		 */
+		_makePositioned: function ( $ele ) {
+			if ( $ele.css("position") === "static" ) {
+				$ele.css( "position", "relative" );
+			}
+		},
+
+		/**
+		 * Creates scrollview widget,
+		 * binds events and initiaties timers
+		 * @private
+		 */
+		_create: function () {
+			var direction,
+				self = this;
+
+			this._$clip = $( this.element ).addClass("ui-scrollview-clip");
+
+			if ( this._$clip.children(".ui-scrollview-view").length ) {
+				this._$view = this._$clip.children(".ui-scrollview-view");
+			} else {
+				this._$view = this._$clip.wrapInner("<div></div>").children()
+							.addClass("ui-scrollview-view");
+			}
+
+			if ( this.options.scrollMethod === "translate" ) {
+				if ( this._$view.css("transform") === undefined ) {
+					this.options.scrollMethod = "position";
+				}
+			}
+
+			this._$clip.css( "overflow", "hidden" );
+			this._makePositioned( this._$clip );
+
+			this._makePositioned( this._$view );
+			this._$view.css( { left: 0, top: 0 } );
+
+			this._view_height = this._getViewHeight();
+
+			this._sx = 0;
+			this._sy = 0;
+
+			direction = this.options.direction;
+
+			this._hTracker = ( direction !== "y" ) ?
+					new MomentumTracker( this.options ) : null;
+			this._vTracker = ( direction !== "x" ) ?
+					new MomentumTracker( this.options ) : null;
+
+			this._timerInterval = this.options.timerInterval;
+			this._timerID = 0;
+
+			this._timerCB = function () {
+				self._handleMomentumScroll();
+			};
+
+			this._add_event();
+			this._add_scrollbar();
+			this._add_scroll_jump();
+			this._add_overflow_indicator();
+			this._moveInterval = 10; /* Add Interval */
+			this._clipHeight = 0;
+		},
+
+		/**
+		 * Starts momentum scroll after user stopped
+		 * scrolling
+		 * @private
+		 * @param {number} speedX Horizontal speed
+		 * @param {number} speedY Vertical speed
+		 */
+		_startMScroll: function ( speedX, speedY ) {
+			var keepGoing = false,
+				duration = this.options.scrollDuration,
+				ht = this._hTracker,
+				vt = this._vTracker,
+				c,
+				v;
+
+			this._$clip.trigger( this.options.startEventName );
+
+			if ( ht ) {
+				c = this._$clip.width();
+				v = this._getViewWidth();
+
+				if ( (( this._sx === 0 && speedX > 0 ) ||
+					( this._sx === -(v - c) && speedX < 0 )) &&
+						v > c ) {
+					return;
+				}
+
+				ht.start( this._sx, speedX,
+					duration, (v > c) ? -(v - c) : 0, 0 );
+				keepGoing = !ht.done();
+			}
+
+			if ( vt ) {
+				c = this._$clip.height();
+				v = this._getViewHeight();
+
+				if ( (( this._sy === 0 && speedY > 0 ) ||
+					( this._sy === -(v - c) && speedY < 0 )) &&
+						v > c ) {
+					return;
+				}
+
+				vt.start( this._sy, speedY,
+					duration, (v > c) ? -(v - c) : 0, 0 );
+				keepGoing = keepGoing || !vt.done();
+			}
+
+			if ( keepGoing ) {
+				this._timerID = setTimeout( this._timerCB, this._timerInterval );
+			} else {
+				this._stopMScroll();
+			}
+		},
+
+		/**
+		 * Ends momentum scroll
+		 * @private
+		 */
+		_stopMScroll: function () {
+			if ( this._timerID ) {
+				this._$clip.trigger( this.options.stopEventName );
+				clearTimeout( this._timerID );
+			}
+			this._timerID = 0;
+
+			if ( this._vTracker ) {
+				this._vTracker.reset();
+			}
+
+			if ( this._hTracker ) {
+				this._hTracker.reset();
+			}
+
+			this._hideScrollBars();
+			this._hideOverflowIndicator();
+		},
+
+		/**
+		 * Updates scroll while in momentum scroll mode
+		 * @private
+		 */
+		_handleMomentumScroll: function () {
+			var keepGoing = false,
+				x = 0,
+				y = 0,
+				scroll_height = 0,
+				self = this,
+				vt = this._vTracker,
+				ht = this._hTracker;
+
+			if ( this._outerScrolling ) {
+				return;
+			}
+
+			if ( vt ) {
+				vt.update( this.options.overshootEnable );
+				y = vt.getPosition();
+				keepGoing = !vt.done();
+
+				if ( vt.getRemained() > this.options.overshootDuration ) {
+					scroll_height = this._getViewHeight() - this._$clip.height();
+
+					if ( !vt.isAvail() ) {
+						if ( this._speedY > 0 ) {
+							this._outerScroll( vt.getRemained() / 3, scroll_height );
+						} else {
+							this._outerScroll( y - vt.getRemained() / 3, scroll_height );
+						}
+					} else if ( vt.isMin() ) {
+						this._outerScroll( y - vt.getRemained() / 3, scroll_height );
+
+					} else if ( vt.isMax() ) {
+						this._outerScroll( vt.getRemained() / 3, scroll_height );
+					}
+				}
+			}
+
+			if ( ht ) {
+				ht.update( this.options.overshootEnable );
+				x = ht.getPosition();
+				keepGoing = keepGoing || !ht.done();
+			}
+
+			this._setScrollPosition( x, y );
+			this._$clip.trigger( this.options.updateEventName,
+					[ { x: x, y: y } ] );
+
+			if ( keepGoing ) {
+				this._timerID = setTimeout( this._timerCB, this._timerInterval );
+			} else {
+				this._stopMScroll();
+			}
+		},
+
+		/**
+		 * Sets css translate transformation for element
+		 * @param {jQuery} $ele
+		 * @param {number} x
+		 * @param {number} y
+		 * @param {number} duration
+		 */
+		_setElementTransform: function ( $ele, x, y, duration ) {
+			var translate,
+				transition;
+
+			if ( !duration || duration === undefined ) {
+				transition = "none";
+			} else {
+				transition =  "-webkit-transform " + duration / 1000 + "s ease-out";
+			}
+
+			if ( $.support.cssTransform3d ) {
+				translate = "translate3d(" + x + "," + y + ", 0px)";
+			} else {
+				translate = "translate(" + x + "," + y + ")";
+			}
+
+			$ele.css({
+				"-moz-transform": translate,
+				"-webkit-transform": translate,
+				"-ms-transform": translate,
+				"-o-transform": translate,
+				"transform": translate,
+				"-webkit-transition": transition
+			});
+		},
+
+		/**
+		 * Applies scroll end effect according to direction
+		 * @param {string} dir Direction, can be "in" or "out"
+		 */
+		_setEndEffect: function ( dir ) {
+			var scroll_height = this._getViewHeight() - this._$clip.height();
+
+			if ( this._softkeyboard ) {
+				if ( this._effect_dir ) {
+					this._outerScroll( -scroll_height - this._softkeyboardHeight,
+							scroll_height );
+				} else {
+					this._outerScroll( this._softkeyboardHeight, scroll_height );
+				}
+				return;
+			}
+
+			if ( dir === "in" ) {
+				if ( this._endEffect ) {
+					return;
+				}
+
+				this._endEffect = true;
+				this._setOverflowIndicator( this._effect_dir );
+				this._showOverflowIndicator();
+			} else if ( dir === "out" ) {
+				if ( !this._endEffect ) {
+					return;
+				}
+
+				this._endEffect = false;
+			} else {
+				this._endEffect = false;
+				this._setOverflowIndicator();
+				this._showOverflowIndicator();
+			}
+		},
+
+		/**
+		 * Calibrates scroll position and scroll end effect
+		 * @private
+		 * @param {number} x
+		 * @param {number} y
+		 */
+		_setCalibration: function ( x, y ) {
+			if ( this.options.overshootEnable ) {
+				this._sx = x;
+				this._sy = y;
+				return;
+			}
+
+			var $v = this._$view,
+				$c = this._$clip,
+				dirLock = this._directionLock,
+				scroll_height = 0,
+				scroll_width = 0,
+				vh,
+				ch;
+
+			if ( dirLock !== "y" && this._hTracker ) {
+				scroll_width = $v.width() - $c.width();
+
+				if ( x >= 0 ) {
+					this._sx = 0;
+				} else if ( x < -scroll_width ) {
+					this._sx = -scroll_width;
+				} else {
+					this._sx = x;
+				}
+
+				if ( scroll_width < 0 ) {
+					this._sx = 0;
+				}
+			}
+
+			if ( dirLock !== "x" && this._vTracker ) {
+				vh = this._getViewHeight();
+				ch = $c.height();
+				/*
+				When used changePage() function, this._getViewHeight() value set 0.
+				So scroll_height has incorrect value and showed indicator incorrectly.
+				Below condition is exception handling that avoid this situation.
+				*/
+				if ( vh != 0 && ch > 0 ) {
+					scroll_height = vh - ch;
+				}
+
+				if ( y > 0 ) {
+					this._sy = 0;
+
+					this._effect_dir = 0;
+					this._setEndEffect( "in" );
+				} else if ( y < -scroll_height ) {
+					this._sy = -scroll_height;
+
+					this._effect_dir = 1;
+					this._setEndEffect( "in" );
+				} else {
+					if ( this._endEffect && this._sy !== y ) {
+						this._setEndEffect();
+					}
+
+					this._sy = y;
+				}
+
+				if ( scroll_height < 0 ) {
+					this._sy = 0;
+				}
+			}
+		},
+
+		/**
+		 * Moves scroll to specified position
+		 * @private
+		 * @param {number} x
+		 * @param {number} y
+		 * @param {number} duration
+		 */
+		_setScrollPosition: function ( x, y, duration ) {
+			var $v = this._$view,
+				sm = this.options.scrollMethod,
+				$vsb = this._$vScrollBar,
+				$hsb = this._$hScrollBar,
+				$sbt;
+
+			this._setCalibration( x, y );
+
+			x = this._sx;
+			y = this._sy;
+
+			if ( sm === "translate" ) {
+				this._setElementTransform( $v, x + "px", y + "px", duration );
+			} else {
+				$v.css( {left: x + "px", top: y + "px"} );
+			}
+
+			if ( $vsb ) {
+				$sbt = $vsb.find(".ui-scrollbar-thumb");
+
+				if ( sm === "translate" ) {
+					if ( bitwiseAbs( this._moveInterval - bitwiseAbs(y)) > 20 ) {
+						/* update scrollbar every 20(clientY) move*/
+						/* Add Interval */
+						this._setElementTransform( $sbt, "0px",
+							-y / this._getViewHeight() * this._clipHeight + "px",
+							duration );
+					}
+				} else {
+					$sbt.css( "top", -y / this._getViewHeight() * 100 + "%" );
+				}
+			}
+
+			if ( $hsb ) {
+				$sbt = $hsb.find(".ui-scrollbar-thumb");
+
+				if ( sm === "translate" ) {
+					this._setElementTransform( $sbt,
+						-x / $v.outerWidth() * $sbt.parent().width() + "px", "0px",
+						duration);
+				} else {
+					$sbt.css("left", -x / $v.width() * 100 + "%");
+				}
+			}
+		},
+
+		/**
+		 * Handles window scrolling
+		 * @private
+		 * @param {number} y
+		 * @param {number} scroll_height
+		 */
+		_outerScroll: function ( y, scroll_height ) {
+			var self = this,
+				top = $( window ).scrollTop() - window.screenTop,
+				sy = 0,
+				duration = this.options.snapbackDuration,
+				start = getCurrentTime(),
+				tfunc;
+
+			if ( !this.options.outerScrollEnable ) {
+				return;
+			}
+
+			if ( this._$clip.jqmData("scroll") !== "y" ) {
+				return;
+			}
+
+			if ( this._outerScrolling ) {
+				return;
+			}
+
+			if ( y > 0 ) {
+				sy = ( window.screenTop ? window.screenTop : -y );
+			} else if ( y < -scroll_height ) {
+				sy = -y - scroll_height;
+			} else {
+				return;
+			}
+
+			tfunc = function () {
+				var elapsed = getCurrentTime() - start;
+
+				if ( elapsed >= duration ) {
+					window.scrollTo( 0, top + sy );
+					self._outerScrolling = undefined;
+
+					self._stopMScroll();
+				} else {
+					ec = $.easing.easeOutQuad( elapsed / duration,
+							elapsed, 0, 1, duration );
+
+					window.scrollTo( 0, top + ( sy * ec ) );
+					self._outerScrolling = setTimeout( tfunc, self._timerInterval );
+				}
+			};
+			this._outerScrolling = setTimeout( tfunc, self._timerInterval );
+		},
+
+		/**
+		 * Scrolls to specified position with easeOutQuad calculations
+		 * @private
+		 * @param {number} x
+		 * @param {number} y
+		 * @param {number} duration
+		 */
+		_scrollTo: function ( x, y, duration ) {
+			var self = this,
+				start = getCurrentTime(),
+				efunc = $.easing.easeOutQuad,
+				sx = this._sx,
+				sy = this._sy,
+				dx = x - sx,
+				dy = y - sy,
+				tfunc;
+
+			x = -x;
+			y = -y;
+
+			tfunc = function () {
+				var elapsed = getCurrentTime() - start,
+				    ec;
+
+				if ( elapsed >= duration ) {
+					self._timerID = 0;
+					self._setScrollPosition( x, y );
+				} else {
+					ec = efunc( elapsed / duration, elapsed, 0, 1, duration );
+
+					self._setScrollPosition( sx + ( dx * ec ), sy + ( dy * ec ) );
+					self._timerID = setTimeout( tfunc, self._timerInterval );
+				}
+			};
+
+			this._timerID = setTimeout( tfunc, this._timerInterval );
+		},
+
+		/**
+		 * Scrolls to specified position
+		 * If scroll method is css translation or duration is a
+		 * falsy value, the position is changed via translation,
+		 * otherwise it's animated to that position
+		 * @param {number} x
+		 * @param {number} y
+		 * @param {number} duration
+		 */
+		scrollTo: function ( x, y, duration ) {
+			this._stopMScroll();
+			this._didDrag = false;
+
+			if ( !duration || this.options.scrollMethod === "translate" ) {
+				this._setScrollPosition( x, y, duration );
+			} else {
+				this._scrollTo( x, y, duration );
+			}
+		},
+
+		/**
+		 * Centers scroll to view the specified child element
+		 * @param {Element|jQuery} target
+		 */
+		centerToElement: function ( element ) {
+			var $clip = this._$clip,
+				$view = this._$view,
+				$element = element.get ? element : $( element ),
+				delta = ( $clip.height() / 2 ) - ( element.height() / 2 ),
+				elementPosition = element.position().top;
+
+			element.parentsUntil( $view ).each( function () {
+				var $parent = $( this );
+				elementPosition += ( $parent.position().top + parseFloat( $parent.css( "marginTop" ) ) + parseFloat( $parent.css( "paddingTop" ) ) );
+			});
+
+			this.scrollTo( this._sx, -( elementPosition - delta ) );
+		},
+
+		/**
+		 * Checks if the specified child element is visible
+		 * and centers the scroll on it if it's not visible
+		 * @param {Element|jQuery}
+		 */
+		ensureElementIsVisible: function ( element ) {
+			var $element = element.get ? element : $( element ),
+				$clip = this._$clip,
+				clipHeight = $clip.height(),
+				clipTop = $clip.offset().top,
+				clipBottom = clipTop + clipHeight,
+				elementHeight = $element.height(),
+				elementTop = $element.offset().top,
+				elementBottom = elementTop + elementHeight,
+				elementFits = clipHeight > elementHeight,
+				$anchor,
+				anchorPosition = 0,
+				findPositionAnchor = function ( input ) {
+					var $label,
+						id = input.attr( "id" );
+					if ( input.is( ":input" ) && id ) {
+						$label = input.siblings( "label[for=" + id + "]" );
+						if ( $label.length > 0 ) {
+							return $label.eq( 0 );
+						}
+					}
+					return input;
+				};
+
+			switch( true ) {
+				case elementFits && clipTop < elementTop && clipBottom > elementBottom: // element fits in view is inside clip area
+					// pass, element position is ok
+					break;
+				case elementFits && clipTop < elementTop && clipBottom < elementBottom: // element fits in view but its visible only at top
+				case elementFits && clipTop > elementTop && clipBottom > elementBottom: // element fits in view but its visible only at bottom
+				case elementFits: // element fits in view but is not visible
+					this.centerToElement(element);
+					break;
+				case clipTop < elementTop && clipBottom < elementBottom: // element visible only at top
+				case clipTop > elementTop && clipBottom > elementBottom: // element visible only at bottom
+					// pass, we cant do anything, if we move the scroll
+					// the user could lost view of something he scrolled to
+					break;
+				default: // element is not visible
+					$anchor = findPositionAnchor( $element );
+					anchorPosition = $anchor.position().top + parseFloat( $anchor.css("marginTop" ) );
+					$anchor.parentsUntil($view).each(function () {
+						var $p = $( this );
+						anchorPosition += ( $p.position().top + parseFloat( $p.css("marginTop" ) ) );
+					});
+					this.scrollTo( self._sx, -anchorPosition );
+					break;
+			}
+		},
+
+		/**
+		 * Returns current scroll position {x,y}
+		 * @return {Object}
+		 */
+		getScrollPosition: function () {
+			return { x: -this._sx, y: -this._sy };
+		},
+
+		/**
+		 * Skipps dragging
+		 * @param {Boolean}
+		 */
+		skipDragging: function ( value ) {
+			this._skip_dragging = value;
+		},
+
+		/**
+		 * Returns scroll hierarchy in an array of elements
+		 * @private
+		 * @return {Array}
+		 */
+		_getScrollHierarchy: function () {
+			var svh = [],
+				d;
+
+			this._$clip.parents( ".ui-scrollview-clip").each( function () {
+				d = $( this ).jqmData("scrollview");
+				if ( d ) {
+					svh.unshift( d );
+				}
+			} );
+			return svh;
+		},
+
+		/**
+		 * Returns ancestor for specified direction
+		 * @private
+		 * @param {string} dir
+		 */
+		_getAncestorByDirection: function ( dir ) {
+			var svh = this._getScrollHierarchy(),
+				n = svh.length,
+				sv,
+				svdir;
+
+			while ( 0 < n-- ) {
+				sv = svh[n];
+				svdir = sv.options.direction;
+
+				if (!svdir || svdir === dir) {
+					return sv;
+				}
+			}
+			return null;
+		},
+
+		/**
+		 * Handles dragstart event
+		 * @private
+		 * @param {Event} e
+		 * @param {number} ex Event x position
+		 * @param {number} ey Event y position
+		 */
+		_handleDragStart: function ( e, ex, ey ) {
+			this._stopMScroll();
+
+			this._didDrag = false;
+			this._skip_dragging = false;
+			this._clipHeight = this._$clip.height();
+			var target = $( e.target ),
+				self = this,
+				$c = this._$clip,
+				svdir = this.options.direction;
+
+			/* should prevent the default behavior when click the button */
+			this._is_button = target.is( '.ui-btn' ) ||
+					target.is( '.ui-btn-text' ) ||
+					target.is( '.ui-btn-inner' ) ||
+					target.is( '.ui-btn-inner .ui-icon' );
+
+			/* should prevent the default behavior when click the slider */
+			if ( target.parents('.ui-slider').length || target.is('.ui-slider') ) {
+				this._skip_dragging = true;
+				return;
+			}
+
+			if ( target.is('textarea') ) {
+				target.bind( "scroll", function () {
+					self._skip_dragging = true;
+					target.unbind("scroll");
+				});
+			}
+
+			/*
+			 * We need to prevent the default behavior to
+			 * suppress accidental selection of text, etc.
+			 */
+			this._is_inputbox = target.is(':input') ||
+					target.parents(':input').length > 0;
+
+			if ( this._is_inputbox ) {
+				target.one( "resize.scrollview", function () {
+					if ( ey > $c.height() ) {
+						self.scrollTo( -ex, self._sy - ey + $c.height(),
+							self.options.snapbackDuration );
+					}
+				});
+			}
+
+			if ( this.options.eventType === "mouse" && !this._is_inputbox && !this._is_button ) {
+				e.preventDefault();
+			}
+
+			this._lastX = ex;
+			this._lastY = ey;
+			this._startY = ey;
+			this._doSnapBackX = false;
+			this._doSnapBackY = false;
+			this._speedX = 0;
+			this._speedY = 0;
+			this._directionLock = "";
+
+			this._lastMove = 0;
+			this._enableTracking();
+
+			this._set_scrollbar_size();
+		},
+
+		/**
+		 * Propagates dragging
+		 * @private
+		 * @param {jQuery} sv
+		 * @param {Event} e
+		 * @param {number} ex
+		 * @param {number} ey
+		 * @param {string} dir
+		 */
+		_propagateDragMove: function ( sv, e, ex, ey, dir ) {
+			this._hideScrollBars();
+			this._hideOverflowIndicator();
+			this._disableTracking();
+			sv._handleDragStart( e, ex, ey );
+			sv._directionLock = dir;
+			sv._didDrag = this._didDrag;
+		},
+
+		/**
+		 * Handles drag event
+		 * @private
+		 * @param {Event}
+		 * @param {number} ex
+		 * @param {number} ey
+		 * @return {boolean|undefined}
+		 */
+		_handleDragMove: function ( e, ex, ey ) {
+			this._moveInterval = ey;
+			if ( this._skip_dragging ) {
+				return;
+			}
+
+			if ( !this._dragging ) {
+				return;
+			}
+
+			if ( !this._is_inputbox && !this._is_button ) {
+				e.preventDefault();
+			}
+
+			var mt = this.options.moveThreshold,
+				dx = ex - this._lastX,
+				dy = ey - this._lastY,
+				svdir = this.options.direction,
+				dir = null,
+				x,
+				y,
+				sv,
+				scope,
+				newX,
+				newY,
+				dirLock;
+
+			this._lastMove = getCurrentTime();
+
+			if ( !this._directionLock ) {
+				x = Math.abs( dx );
+				y = Math.abs( dy );
+
+				if ( x < mt && y < mt ) {
+					return false;
+				}
+
+				if ( x < y && (x / y) < 0.5 ) {
+					dir = "y";
+				} else if ( x > y && (y / x) < 0.5 ) {
+					dir = "x";
+				}
+
+				if ( svdir && dir && svdir !== dir ) {
+					/*
+					 * This scrollview can't handle the direction the user
+					 * is attempting to scroll. Find an ancestor scrollview
+					 * that can handle the request.
+					 */
+
+					sv = this._getAncestorByDirection( dir );
+					if ( sv ) {
+						this._propagateDragMove( sv, e, ex, ey, dir );
+						return false;
+					}
+				}
+
+				this._directionLock = svdir || (dir || "none");
+			}
+
+			newX = this._sx;
+			newY = this._sy;
+			dirLock = this._directionLock;
+
+			if ( dirLock !== "y" && this._hTracker ) {
+				x = this._sx;
+				this._speedX = dx;
+				newX = x + dx;
+
+				this._doSnapBackX = false;
+
+				scope = ( newX > 0 || newX < this._maxX );
+
+				if ( scope && dirLock === "x" ) {
+					sv = this._getAncestorByDirection("x");
+					if ( sv ) {
+						this._setScrollPosition( newX > 0 ?
+								0 : this._maxX, newY );
+						this._propagateDragMove( sv, e, ex, ey, dir );
+						return false;
+					}
+
+					newX = x + ( dx / 2 );
+					this._doSnapBackX = true;
+				}
+			}
+
+			if ( dirLock !== "x" && this._vTracker ) {
+				if ( Math.abs( this._startY - ey ) < mt && dirLock !== "xy" && this._didDrag === false ) {
+					return;
+				}
+
+				y = this._sy;
+				this._speedY = dy;
+				newY = y + dy;
+
+				this._doSnapBackY = false;
+
+				scope = ( newY > 0 || newY < this._maxY );
+
+				if ( scope && dirLock === "y" ) {
+					sv = this._getAncestorByDirection("y");
+					if ( sv ) {
+						this._setScrollPosition( newX,
+								newY > 0 ? 0 : this._maxY );
+						this._propagateDragMove( sv, e, ex, ey, dir );
+						return false;
+					}
+
+					newY = y + ( dy / 2 );
+					this._doSnapBackY = true;
+				}
+			}
+
+			if ( this.options.overshootEnable === false ) {
+				this._doSnapBackX = false;
+				this._doSnapBackY = false;
+			}
+
+			this._lastX = ex;
+			this._lastY = ey;
+
+			this._setScrollPosition( newX, newY );
+
+			if ( this._didDrag === false ) {
+				this._didDrag = true;
+				this._showScrollBars();
+				this._showOverflowIndicator();
+
+				this._$clip.parents(".ui-scrollview-clip").each( function () {
+					$( this ).scrollview( "skipDragging", true );
+				} );
+			}
+		},
+
+		/**
+		 * Handles drag stop event, and returns drag status
+		 * @param {Event} e
+		 * @return {Boolean|undefined}
+		 */
+		_handleDragStop: function ( e ) {
+			var self = this;
+
+			if ( this._skip_dragging ) {
+				return;
+			}
+
+			var l = this._lastMove,
+				t = getCurrentTime(),
+				doScroll = (l && (t - l) <= this.options.moveIntervalThreshold),
+				sx = ( this._hTracker && this._speedX && doScroll ) ?
+						this._speedX : ( this._doSnapBackX ? 1 : 0 ),
+				sy = ( this._vTracker && this._speedY && doScroll ) ?
+						this._speedY : ( this._doSnapBackY ? 1 : 0 ),
+				svdir = this.options.direction,
+				x,
+				y;
+
+			if ( sx || sy ) {
+				if ( !this._setGestureScroll( sx, sy ) ) {
+					this._startMScroll( sx, sy );
+				}
+			} else {
+				this._hideScrollBars();
+				this._hideOverflowIndicator();
+			}
+
+			this._disableTracking();
+
+			if ( this._endEffect ) {
+				setTimeout( function () {
+					self._setEndEffect( "out" );
+					self._hideScrollBars();
+					self._hideOverflowIndicator();
+				}, 300 );
+			}
+
+			return !this._didDrag;
+		},
+
+		/**
+		 * Detects gestures and sets proper gesture direction
+		 * @private
+		 * @param {number} sx
+		 * @param {number} sy
+		 * @return {boolean}
+		 */
+		_setGestureScroll: function ( sx, sy ) {
+			var self = this,
+				reset = function () {
+					clearTimeout( self._gesture_timer );
+					self._gesture_dir = 0;
+					self._gesture_timer = undefined;
+				},
+				direction = {
+					top: 0,
+					bottom: 1,
+					left: 2,
+					right: 3
+				};
+
+			if ( !sy && !sx ) {
+				return false;
+			}
+
+			if ( Math.abs( sx ) > Math.abs( sy ) ) {
+				dir = sx > 0 ? direction.left : direction.right;
+			} else {
+				dir = sy > 0 ? direction.top : direction.bottom;
+			}
+
+			if ( !this._gesture_timer ) {
+				this._gesture_dir = dir;
+
+				this._gesture_timer = setTimeout( function () {
+					reset();
+				}, 1000 );
+
+				return false;
+			}
+
+			if ( this._gesture_dir !== dir ) {
+				reset();
+				return false;
+			}
+
+			return false;
+		},
+
+		/**
+		 * Enables dragging
+		 * @private
+		 */
+		_enableTracking: function () {
+			this._dragging = true;
+		},
+
+		/**
+		 * Disables dragging
+		 * @private
+		 */
+		_disableTracking: function () {
+			this._dragging = false;
+		},
+
+		/**
+		 * Shows scrollbars
+		 * When interval is specified, the scrollbars will be
+		 * hidden after the specified time in miliseconds
+		 * @private
+		 * @param {number} [interval]
+		 */
+		_showScrollBars: function ( interval ) {
+			var vclass = "ui-scrollbar-visible",
+				self = this;
+
+			if ( !this.options.showScrollBars ) {
+				return;
+			}
+			if ( this._scrollbar_showed ) {
+				return;
+			}
+
+			if ( this._$vScrollBar ) {
+				this._$vScrollBar.addClass( vclass );
+			}
+			if ( this._$hScrollBar ) {
+				this._$hScrollBar.addClass( vclass );
+			}
+
+			this._scrollbar_showed = true;
+
+			if ( interval ) {
+				setTimeout( function () {
+					self._hideScrollBars();
+				}, interval );
+			}
+		},
+
+		/**
+		 * Hides scrollbars
+		 * @private
+		 */
+		_hideScrollBars: function () {
+			var vclass = "ui-scrollbar-visible";
+
+			if ( !this.options.showScrollBars ) {
+				return;
+			}
+			if ( !this._scrollbar_showed ) {
+				return;
+			}
+
+			if ( this._$vScrollBar ) {
+				this._$vScrollBar.removeClass( vclass );
+			}
+			if ( this._$hScrollBar ) {
+				this._$hScrollBar.removeClass( vclass );
+			}
+
+			this._scrollbar_showed = false;
+		},
+
+		/**
+		 * Sets opacities for the oveflow indicator
+		 * according to specified direction. The direction
+		 * is optional. Specify 1 for top, 0 for bottom, and
+		 * a falsy value for both
+		 * @private
+		 * @param {number} [dir] 0
+		 */
+		_setOverflowIndicator: function ( dir ) {
+			if ( dir === 1 ) {
+				this._display_indicator_top = "none";
+				this._display_indicator_bottom = "block";
+			} else if ( dir === 0 ) {
+				this._display_indicator_top = "block";
+				this._display_indicator_bottom = "none";
+			} else {
+				this._display_indicator_top = "block";
+				this._display_indicator_bottom = "block";
+			}
+		},
+
+		/**
+		 * Display overflow indicator
+		 * @private
+		 */
+		_showOverflowIndicator: function () {
+			if ( !$( this.element ).is( ".ui-content" ) ) {
+				return true;
+			}
+
+			if ( !this.options.overflowEnable || !this._overflowAvail || this._softkeyboard ) {
+				return;
+			}
+
+			this._overflow_top.css( "display", this._display_indicator_top );
+			this._overflow_bottom.css( "display", this._display_indicator_bottom );
+
+			this._overflow_showed = true;
+		},
+
+		/**
+		 * Hide overflow indicator
+		 * @private
+		 */
+		_hideOverflowIndicator: function () {
+			if ( !this.options.overflowEnable || !this._overflowAvail || this._softkeyboard ) {
+				return;
+			}
+
+			if ( this._overflow_showed === false ) {
+				return;
+			}
+
+			this._overflow_top.css( "display", "none" );
+			this._overflow_bottom.css( "display", "none" );
+
+			this._overflow_showed = false;
+			this._setOverflowIndicator();
+		},
+
+		/**
+		 * Bind events
+		 * @private
+		 * @return {boolean|undefined}
+		 */
+		_add_event: function () {
+			var self = this,
+				$c = this._$clip,
+				$v = this._$view;
+
+			if ( this.options.eventType === "mouse" ) {
+				this._dragEvt = "mousedown mousemove mouseup click mousewheel";
+
+				this._dragCB = function ( e ) {
+					switch ( e.type ) {
+					case "mousedown":
+						return self._handleDragStart( e,
+								e.clientX, e.clientY );
+
+					case "mousemove":
+						return self._handleDragMove( e,
+								e.clientX, e.clientY );
+
+					case "mouseup":
+						return self._handleDragStop( e );
+
+					case "click":
+						return !self._didDrag;
+
+					case "mousewheel":
+						var old = self.getScrollPosition();
+						self.scrollTo( -old.x,
+							-(old.y - e.originalEvent.wheelDelta) );
+						break;
+					}
+				};
+			} else {
+				this._dragEvt = "touchstart touchmove touchend";
+				var _in_progress = false;
+				this._dragCB = function ( e ) {
+					var touches = e.originalEvent.touches;
+
+					switch ( e.type ) {
+					case "touchstart":
+						if ( touches.length != 1 || _in_progress ) {
+							return;
+						}
+
+						_in_progress = true;
+
+						return self._handleDragStart( e,
+								touches[0].pageX, touches[0].pageY );
+
+					case "touchmove":
+						if ( !_in_progress || touches.length != 1) {
+							return;
+						}
+
+						return self._handleDragMove( e,
+								touches[0].pageX, touches[0].pageY );
+
+					case "touchend":
+						if ( !_in_progress ) {
+							return;
+						}
+
+						_in_progress = false;
+
+						if ( touches.length != 0 ) {
+							return;
+						}
+
+						return self._handleDragStop( e );
+					}
+				};
+			};
+
+			$v.bind( this._dragEvt, this._dragCB );
+
+			// N_SE-35696 / N_SE-35800
+			var clipScrollDelta = 0,
+				clipScrollLast = 0;
+			$c.on( "scroll", function () {
+				var clipScrollTop = $c.scrollTop(),
+					currentPositon = self.getScrollPosition(),
+					inputs;
+
+				clipScrollDelta = clipScrollTop - clipScrollLast;
+				clipScrollLast = clipScrollTop;
+
+				if ( clipScrollDelta > 0 ) {
+					inputs = $v.find( ":input.ui-focus" );
+					$c.scrollTop( 0 );
+					if ( inputs.length ) {
+						// CHECK WHERE WE ARE IN THE INPUTS
+						clipScrollDelta = 0;
+					}
+					self.scrollTo( -currentPositon.x, -( currentPositon.y + clipScrollDelta ) );
+				}
+			} );
+
+			$v.bind( "keydown", function ( e ) {
+				var $focusedElement;
+
+				if ( e.keyCode == 9 ) {
+					return false;
+				}
+
+				$focusedElement = $c.find( ".ui-focus" );
+				if ( !$focusedElement.length ) {
+					return;
+				}
+				self.ensureElementIsVisible( $focusedElement );
+
+				return;
+			});
+
+			$v.bind( "keyup", function ( e ) {
+				var $input;
+
+				if ( e.keyCode !== 9 ) {
+					return;
+				}
+
+				/* Tab Key */
+				$input = $( this ).find( ":input.ui-focus" ).eq( 0 );
+				if ( !$input ) {
+					return;
+				}
+				self.ensureElementIsVisible( $input );
+				$input.focus();
+
+				return false;
+			});
+
+			$c.bind( "updatelayout", function ( e ) {
+				var sy,
+					vh,
+					view_h = self._getViewHeight();
+
+				if ( !$c.height() || !view_h ) {
+					self.scrollTo( 0, 0, 0 );
+					return;
+				}
+
+				sy = $c.height() - view_h;
+				vh = view_h - self._view_height;
+
+				self._view_height = view_h;
+
+				if ( vh == 0 || vh > $c.height() / 2 ) {
+					return;
+				}
+
+				if ( sy > 0 ) {
+					self.scrollTo( 0, 0, 0 );
+				} else if ( self._sy - sy <= -vh ) {
+					self.scrollTo( 0, self._sy,
+						self.options.snapbackDuration );
+				} else if ( self._sy - sy <= vh + self.options.moveThreshold ) {
+					self.scrollTo( 0, sy,
+						self.options.snapbackDuration );
+				}
+			});
+
+			$( window ).bind( "resize", function ( e ) {
+				var focused,
+					view_h = self._getViewHeight();
+
+				if ( $(".ui-page-active").get(0) !== $c.closest(".ui-page").get(0) ) {
+					return;
+				}
+
+				if ( !$c.height() || !view_h ) {
+					return;
+				}
+
+				focused = $c.find(".ui-focus");
+
+				if ( focused ) {
+					focused.trigger("resize.scrollview");
+				}
+
+				/* calibration - after triggered throttledresize */
+				setTimeout( function () {
+					var view_w = $v.outerWidth(),
+						cw = $c.outerWidth(),
+						scroll_x,
+						scroll_y;
+					if ( self._sy < $c.height() - self._getViewHeight() ) {
+						scroll_y = $c.height() - self._getViewHeight();
+						scroll_x = 0;
+					}
+					if ( self._sx < cw - view_w ) {
+						scroll_x = cw - view_w;
+						scroll_y = scroll_y || 0;
+					}
+					if (scroll_x || scroll_y) {
+						self.scrollTo( scroll_x, scroll_y, self.options.overshootDuration );
+					}
+				}, 260 );
+
+				self._view_height = view_h;
+				self._clipHeight = self._$clip.height();
+			});
+
+			$( window ).bind( "vmouseout", function ( e ) {
+				var drag_stop = false;
+
+				if ( $(".ui-page-active").get(0) !== $c.closest(".ui-page").get(0) ) {
+					return;
+				}
+
+				if ( !self._dragging ) {
+					return;
+				}
+
+				if ( e.pageX < 0 || e.pageX > $( window ).width() ) {
+					drag_stop = true;
+				}
+
+				if ( e.pageY < 0 || e.pageY > $( window ).height() ) {
+					drag_stop = true;
+				}
+
+				if ( drag_stop ) {
+					self._hideScrollBars();
+					self._hideOverflowIndicator();
+					self._disableTracking();
+				}
+			});
+
+			this._softkeyboard = false;
+			this._softkeyboardHeight = 0;
+
+			window.addEventListener( "softkeyboardchange", function ( e ) {
+				if ( $(".ui-page-active").get(0) !== $c.closest(".ui-page").get(0) ) {
+					return;
+				}
+
+				self._softkeyboard = ( e.state === "on" ? true : false );
+				self._softkeyboardHeight = parseInt( e.height ) *
+						( $( window ).width() / window.screen.availWidth );
+			});
+
+			$c.closest(".ui-page")
+				.bind( "pageshow", function ( e ) {
+					self._view_height = self._$view.height();
+
+					/* should be called after pagelayout */
+					setTimeout( function () {
+						self._view_height = self._getViewHeight();
+						self._set_scrollbar_size();
+						self._setScrollPosition( self._sx, self._sy );
+						self._showScrollBars( 2000 );
+					}, 0 );
+				});
+
+			$c.closest(".ui-page").find( ".ui-popup" )
+				.bind( "popupafteropen", function ( e ) {
+					if ( !$( self.element ).parents().is( ".ui-ctxpopup" ) ) {
+						return true;
+					}
+
+                                        setTimeout( function () {
+                                                self._setScrollPosition( self._sx, self._sy );
+						self._showScrollBars( 2000 );
+                                        }, 0 );
+				});
+		},
+
+		/**
+		 * Adds scrollbar elements to DOM
+		 * @private
+		 */
+		_add_scrollbar: function () {
+			var $c = this._$clip,
+				prefix = "<div class=\"ui-scrollbar ui-scrollbar-",
+				suffix = "\"><div class=\"ui-scrollbar-track\"><div class=\"ui-scrollbar-thumb\"></div></div></div>";
+
+			if ( !this.options.showScrollBars ) {
+				return;
+			}
+
+			if ( this._vTracker ) {
+				$c.append( prefix + "y" + suffix );
+				this._$vScrollBar = $c.children(".ui-scrollbar-y");
+			}
+			if ( this._hTracker ) {
+				$c.append( prefix + "x" + suffix );
+				this._$hScrollBar = $c.children(".ui-scrollbar-x");
+			}
+
+			this._scrollbar_showed = false;
+		},
+
+		/**
+		 * Adds scroll jump button to DOM
+		 * @private
+		 */
+		_add_scroll_jump: function () {
+			var $c = this._$clip,
+				self = this,
+				top_btn,
+				left_btn;
+
+			if ( !this.options.scrollJump ) {
+				return;
+			}
+
+			if ( this._vTracker ) {
+				top_btn = $( '<div class="ui-scroll-jump-top-bg">' +
+						'<div data-role="button" data-inline="true" data-icon="scrolltop" data-style="box"></div></div>' );
+				$c.append( top_btn ).trigger("create");
+
+				top_btn.bind( "vclick", function () {
+					self.scrollTo( 0, 0, self.options.overshootDuration );
+				} );
+			}
+
+			if ( this._hTracker ) {
+				left_btn = $( '<div class="ui-scroll-jump-left-bg">' +
+						'<div data-role="button" data-inline="true" data-icon="scrollleft" data-style="box"></div></div>' );
+				$c.append( left_btn ).trigger("create");
+
+				left_btn.bind( "vclick", function () {
+					self.scrollTo( 0, 0, self.options.overshootDuration );
+				} );
+			}
+		},
+
+		/**
+		 * Adds overflow indicator to DOM
+		 * @private
+		 */
+		_add_overflow_indicator: function () {
+			if ( !this.options.overflowEnable ) {
+				return;
+			}
+
+			this._overflow_top = $( '<div class="ui-overflow-indicator-top"></div>' );
+			this._overflow_bottom = $( '<div class="ui-overflow-indicator-bottom"></div>' );
+
+			this._$clip.append( this._overflow_top );
+			this._$clip.append( this._overflow_bottom );
+
+			this._display_indicator_top = "block";
+			this._display_indicator_bottom = "block";
+			this._overflow_showed = false;
+		},
+
+		/**
+		 * Sets the size of the scrollbars
+		 * @private
+		 */
+		_set_scrollbar_size: function () {
+			var $c = this._$clip,
+				$v = this._$view,
+				cw = 0,
+				vw = 0,
+				ch = 0,
+				vh = 0,
+				thumb;
+
+			if ( !this.options.showScrollBars ) {
+				return;
+			}
+
+			if ( this._hTracker ) {
+				cw = $c.width();
+				vw = $v.width();
+				this._maxX = cw - vw;
+
+				if ( this._maxX > 0 ) {
+					this._maxX = 0;
+				}
+				if ( this._$hScrollBar && vw ) {
+					thumb = this._$hScrollBar.find(".ui-scrollbar-thumb");
+					thumb.css( "width", (cw >= vw ? "0" :
+							(Math.floor(cw / vw * 100) || 1) + "%") );
+				}
+			}
+
+			if ( this._vTracker ) {
+				ch = $c.height();
+				vh = this._getViewHeight();
+				this._maxY = ch - vh;
+
+				if ( this._maxY > 0 || vh === 0 ) {
+					this._maxY = 0;
+				}
+				if ( ( this._$vScrollBar && vh ) || vh === 0 ) {
+					thumb = this._$vScrollBar.find(".ui-scrollbar-thumb");
+					thumb.css( "height", (ch >= vh ? "0" :
+							(Math.floor(ch / vh * 100) || 1) + "%") );
+
+					this._overflowAvail = !!thumb.height();
+				}
+			}
+		}
+	});
+
+	/**
+	 * Momentum tracker
+	 */
+	$.extend( MomentumTracker.prototype, {
+		/**
+		 * Starts momentum callculations
+		 * @param {number} pos
+		 * @param {number} speed
+		 * @param {number} duration
+		 * @param {number} minPos
+		 * @param {number} maxPos
+		 */
+		start: function ( pos, speed, duration, minPos, maxPos ) {
+			var tstate = ( pos < minPos || pos > maxPos ) ?
+					tstates.snapback : tstates.scrolling,
+				pos_temp;
+
+			this.state = ( speed !== 0 ) ? tstate : tstates.done;
+			this.pos = pos;
+			this.speed = speed;
+			this.duration = ( this.state === tstates.snapback ) ?
+					this.options.snapbackDuration : duration;
+			this.minPos = minPos;
+			this.maxPos = maxPos;
+
+			this.fromPos = ( this.state === tstates.snapback ) ? this.pos : 0;
+			pos_temp = ( this.pos < this.minPos ) ? this.minPos : this.maxPos;
+			this.toPos = ( this.state === tstates.snapback ) ? pos_temp : 0;
+
+			this.startTime = getCurrentTime();
+		},
+
+		/**
+		 * Resets momentum tracker calculations and sets
+		 * state to done
+		 */
+		reset: function () {
+			this.state = tstates.done;
+			this.pos = 0;
+			this.speed = 0;
+			this.minPos = 0;
+			this.maxPos = 0;
+			this.duration = 0;
+			this.remained = 0;
+		},
+
+		/**
+		 * Recalculate momentum tracker estimates
+		 * @param {boolean} overshootEnable
+		 * @return {number} position
+		 */
+		update: function ( overshootEnable ) {
+			var state = this.state,
+				cur_time = getCurrentTime(),
+				duration = this.duration,
+				elapsed =  cur_time - this.startTime,
+				dx,
+				x,
+				didOverShoot;
+
+			if ( state === tstates.done ) {
+				return this.pos;
+			}
+
+			elapsed = elapsed > duration ? duration : elapsed;
+
+			this.remained = duration - elapsed;
+
+			if ( state === tstates.scrolling || state === tstates.overshot ) {
+				dx = this.speed *
+					( 1 - $.easing[this.easing]( elapsed / duration,
+								elapsed, 0, 1, duration ) );
+
+				x = this.pos + dx;
+
+				didOverShoot = ( state === tstates.scrolling ) &&
+					( x < this.minPos || x > this.maxPos );
+
+				if ( didOverShoot ) {
+					x = ( x < this.minPos ) ? this.minPos : this.maxPos;
+				}
+
+				this.pos = x;
+
+				if ( state === tstates.overshot ) {
+					if ( !overshootEnable ) {
+						this.state = tstates.done;
+					}
+					if ( elapsed >= duration ) {
+						this.state = tstates.snapback;
+						this.fromPos = this.pos;
+						this.toPos = ( x < this.minPos ) ?
+								this.minPos : this.maxPos;
+						this.duration = this.options.snapbackDuration;
+						this.startTime = cur_time;
+						elapsed = 0;
+					}
+				} else if ( state === tstates.scrolling ) {
+					if ( didOverShoot && overshootEnable ) {
+						this.state = tstates.overshot;
+						this.speed = dx / 2;
+						this.duration = this.options.overshootDuration;
+						this.startTime = cur_time;
+					} else if ( elapsed >= duration ) {
+						this.state = tstates.done;
+					}
+				}
+			} else if ( state === tstates.snapback ) {
+				if ( elapsed >= duration ) {
+					this.pos = this.toPos;
+					this.state = tstates.done;
+				} else {
+					this.pos = this.fromPos + (( this.toPos - this.fromPos ) *
+						$.easing[this.easing]( elapsed / duration,
+							elapsed, 0, 1, duration ));
+				}
+			}
+
+			return this.pos;
+		},
+
+		/**
+		 * Checks if momentum state is done
+		 * @return {boolean}
+		 */
+		done: function () {
+			return this.state === tstates.done;
+		},
+
+		/**
+		 * Checks if the position is minimal
+		 * @return {boolean}
+		 */
+		isMin: function () {
+			return this.pos === this.minPos;
+		},
+
+		/**
+		 * Checks if the position is maximal
+		 * @return {boolean}
+		 */
+		isMax: function () {
+			return this.pos === this.maxPos;
+		},
+
+		/**
+		 * Check if momentum tracking is available
+		 * @return {boolean}
+		 */
+		isAvail: function () {
+			return !( this.minPos === this.maxPos );
+		},
+
+		/**
+		 * Returns remaining time
+		 * @return {number}
+		 */
+		getRemained: function () {
+			return this.remained;
+		},
+
+		/**
+		 * Returns current position
+		 * @return {number}
+		 */
+		getPosition: function () {
+			return this.pos;
+		}
+	});
+
+	$( document ).bind( 'pagecreate create', function ( e ) {
+		var $page = $( e.target ),
+			content_scroll = $page.find(".ui-content").jqmData("scroll");
+
+		/* content scroll */
+		if ( $.support.scrollview === undefined ) {
+			$.support.scrollview = true;
+		}
+
+		if ( $.support.scrollview === true && content_scroll === undefined ) {
+			content_scroll = "y";
+		}
+
+		if ( content_scroll !== "y" ) {
+			content_scroll = "none";
+		}
+
+		$page.find(".ui-content").attr( "data-scroll", content_scroll );
+
+		$page.find(":jqmData(scroll)").not(".ui-scrollview-clip").each( function () {
+			if ( $( this ).hasClass("ui-scrolllistview") ) {
+				$( this ).scrolllistview();
+			} else {
+				var st = $( this ).jqmData("scroll"),
+					dir = st && ( st.search(/^[xy]/) !== -1 ) ? st : null,
+					content = $(this).hasClass("ui-content"),
+					opts;
+
+				if ( st === "none" ) {
+					return;
+				}
+
+				opts = {
+					direction: dir || undefined,
+					overflowEnable: content,
+					scrollMethod: $( this ).jqmData("scroll-method") || undefined,
+					scrollJump: $( this ).jqmData("scroll-jump") || undefined
+				};
+
+				$( this ).scrollview( opts );
+			}
+		});
+	});
+
+	$( document ).bind( 'pageshow', function ( e ) {
+		var $page = $( e.target ),
+			scroll = $page.find(".ui-content").jqmData("scroll");
+
+		if ( scroll === "y" ) {
+			resizePageContentHeight( e.target );
+		}
+	});
+
+}( jQuery, window, document ) );
+
+
+
+/* ***************************************************************************
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ * ***************************************************************************
+ *
+ *	Author: Minkyu Kang <mk...@samsung.com>
+ */
+
+/*
+ * Gallery widget
+ *
+ * HTML Attributes
+ *
+ *  data-role: set to 'gallery'
+ *  data-index: start index
+ *  data-vertical-align: set to top or middle or bottom.
+ *
+ * APIs
+ *
+ *  add(file): add the image (parameter: url of iamge)
+ *  remove(index): remove the image (parameter: index of image)
+ *  refresh(index): refresh the widget, should be called after add or remove. (parameter: start index)
+ *  empty: remove all of images from the gallery
+ *  length: get length of images
+ *  value(index): get or set current index of gallery (parameter: index of image)
+ *
+ * Events
+ *
+ *  N/A
+ *
+ * Example
+ *
+ * <div data-role="gallery" id="gallery" data-index="3" data-vertical-align="middle">
+ *	<img src="01.jpg">
+ *	<img src="02.jpg">
+ *	<img src="03.jpg">
+ *	<img src="04.jpg">
+ *	<img src="05.jpg">
+ * </div>
+ *
+ *
+ * $('#gallery-add').bind('vmouseup', function ( e ) {
+ *	$('#gallery').gallery('add', '9.jpg');
+ *	$('#gallery').gallery('add', '10.jpg');
+ *	$('#gallery').gallery('refresh');
+ * });
+ *
+ * $('#gallery-del').bind('vmouseup', function ( e ) {
+ *	$('#gallery').gallery('remove');
+ * });
+ *
+ */
+
+ /**
+	@class Gallery
+	The gallery widget shows images in a gallery on the screen. <br/><br/> To add an gallery widget to the application, use the following code:
+
+		<div data-role="gallery" id="gallery" data-vertical-align="middle" data-index="3">
+			<img src="01.jpg">
+			<img src="02.jpg">
+			<img src="03.jpg">
+			<img src="04.jpg">
+			<img src="05.jpg">
+		</div>
+*/
+/**
+	@property {Integer} data-index
+	Defines the index number of the first image in the gallery.
+	<br/>The default value is 0.
+*/
+/**
+	@property {String} data-vertical-align
+	Defines the image alignment. The alignment options are top, middle, and bottom.
+	<br/>The default value is top.
+*/
+/**
+	@method add
+	The add method is used to add an image to the gallery. The image_file attribute defines the image file URL.
+
+		<div id="gallery" data-role="gallery" data-vertical-align="middle"></div>
+		$("#gallery").gallery('add', [image_file]);
+*/
+/**
+	@method remove
+	The remove method is used to delete an image from the gallery. The image_index attribute defines the index of the image to be deleted. If not set removes current image.
+
+		<div id="gallery" data-role="gallery" data-vertical-align="middle"></div>
+		$("#gallery").gallery('remove', [image_index]);
+*/
+/**
+	@method refresh
+	The refresh method is used to refresh the gallery. This method must be called after adding images to the gallery.
+
+		<div id="gallery" data-role="gallery" data-vertical-align="middle"></div>
+		$("#gallery").gallery('refresh');
+*/
+/**
+	@method empty
+	The empty method is used to remove all of images from the gallery.
+
+		<div id="gallery" data-role="gallery" data-vertical-align="middle"></div>
+		$("#gallery").gallery('empty');
+*/
+/**
+	@method length
+	The length method is used to get length of images.
+
+		<div id="gallery" data-role="gallery" data-vertical-align="middle"></div>
+		length = $("#gallery").gallery('length');
+*/
+/**
+	@method value
+	The value method is used to get or set current index of gallery. The image_index attribute defines the index of the image to be set. If not get current index.
+
+		<div id="gallery" data-role="gallery" data-vertical-align="middle"></div>
+		value = $("#gallery").gallery('value');
+		$("#gallery").gallery('value', [image_index]);
+*/
+(function ( $, window, undefined ) {
+	$.widget( "tizen.gallery", $.mobile.widget, {
+		options: {
+			flicking: false,
+			duration: 500
+		},
+
+		dragging: false,
+		moving: false,
+		max_width: 0,
+		max_height: 0,
+		org_x: 0,
+		org_time: null,
+		cur_img: null,
+		prev_img: null,
+		next_img: null,
+		images: [],
+		images_hold: [],
+		index: 0,
+		align_type: null,
+		direction: 1,
+		container: null,
+		orientationEventFire: false,
+
+		_resize: function ( index ) {
+			var img = this.images[index],
+				width = this.images[index].width(),
+				height = this.images[index].height(),
+				margin = 0,
+				ratio,
+				img_max_width = this.max_width - margin,
+				img_max_height = this.max_height - margin;
+
+			ratio = height / width;
+
+			if( img_max_width == 0 && isNaN( img_max_height ) ) {
+				/*
+				Exception : When image max width and height has incorrect value.
+				This exception is occured when this.max_width value is 0 and this.max_height value is NaN when page transition like rotation.
+				This exception affect that image width and height values are 0.
+				*/
+				img.width( width );
+				img.height( width * ratio );
+			} else {
+				if ( width > img_max_width ) {
+					img.width( img_max_width );
+					img.height( img_max_width * ratio );
+				}
+
+				height = img.height();
+
+				if ( height > img_max_height ) {
+					img.height( img_max_height );
+					img.width( img_max_height / ratio );
+				}
+			}
+		},
+
+		_align: function ( index, obj ) {
+			var img = this.images[index],
+				img_top = 0;
+
+			if ( !obj ) {
+				return;
+			}
+			if ( !obj.length ) {
+				return;
+			}
+
+			if ( this.align_type == "middle" ) {
+				img_top = ( this.max_height - img.height() ) / 2;
+			} else if ( this.align_type == "bottom" ) {
+				img_top = this.max_height - img.height();
+			} else {
+				img_top = 0;
+			}
+
+			obj.css( 'top', img_top + 'px' );
+		},
+
+		_attach: function ( index, obj ) {
+			var self = this,
+				processing = function () {
+					self._resize( index );
+					self._align( index, obj );
+
+				},
+				loading = function () {
+					if ( self.images[index] === undefined ) {
+						return;
+					}
+
+					if ( !self.images[index].height() ) {
+						setTimeout( loading, 10 );
+						return;
+					}
+
+					processing();
+				};
+
+			if ( !obj ) {
+				return;
+			}
+			if ( !obj.length ) {
+				return;
+			}
+			if ( index < 0 ) {
+				return;
+			}
+			if ( !this.images.length ) {
+				return;
+			}
+			if ( index >= this.images.length ) {
+				return;
+			}
+
+			obj.css( "display", "block" );
+			obj.css( "visibility", "hidden" );
+			obj.append( this.images[index] );
+			loading();
+		},
+
+		_detach: function ( index, obj ) {
+			if ( !obj ) {
+				return;
+			}
+			if ( !obj.length ) {
+				return;
+			}
+			if ( index < 0 ) {
+				return;
+			}
+			if ( index >= this.images.length ) {
+				return;
+			}
+
+			obj.css( "display", "none" );
+			this.images[index].removeAttr("style");
+			this.images[index].detach();
+		},
+
+		_detach_all: function () {
+			var i;
+
+			for ( i = 0; i < this.images.length; i++ ) {
+				this.images[i].detach();
+			}
+		},
+
+		_drag: function ( _x ) {
+			var delta,
+				coord_x;
+
+			if ( !this.dragging ) {
+				return;
+			}
+
+			if ( this.options.flicking === false ) {
+				delta = this.org_x - _x;
+
+				// first image
+				if ( delta < 0 && !this.prev_img.length ) {
+					return;
+				}
+				// last image
+				if ( delta > 0 && !this.next_img.length ) {
+					return;
+				}
+			}
+
+			coord_x = _x - this.org_x;
+
+			this._moveLeft( this.cur_img , coord_x + 'px' );
+			if ( this.next_img.length ) {
+				this._moveLeft( this.next_img ,  coord_x + this.window_width + 'px' );
+			}
+			if ( this.prev_img.length ) {
+				this._moveLeft( this.prev_img ,  coord_x - this.window_width + 'px' );
+			}
+		},
+
+		_move: function ( _x ) {
+			var delta = this.org_x - _x,
+				flip = 0,
+				drag_time,
+				sec,
+				self;
+
+			if ( delta == 0 ) {
+				return;
+			}
+
+			if ( delta > 0 ) {
+				flip = delta < ( this.max_width * 0.45 ) ? 0 : 1;
+			} else {
+				flip = -delta < ( this.max_width * 0.45 ) ? 0 : 1;
+			}
+
+			if ( !flip ) {
+				drag_time = Date.now() - this.org_time;
+
+				if ( Math.abs( delta ) / drag_time > 1 ) {
+					flip = 1;
+				}
+			}
+
+			if ( flip ) {
+				if ( delta > 0 && this.next_img.length ) {
+					/* next */
+					this._detach( this.index - 1, this.prev_img );
+
+					this.prev_img = this.cur_img;
+					this.cur_img = this.next_img;
+					this.next_img = this.next_img.next();
+
+					this.index++;
+
+					if ( this.next_img.length ) {
+						this._moveLeft( this.next_img ,  this.window_width + 'px' );
+						this._attach( this.index + 1, this.next_img );
+					}
+
+					this.direction = 1;
+
+				} else if ( delta < 0 && this.prev_img.length ) {
+					/* prev */
+					this._detach( this.index + 1, this.next_img );
+
+					this.next_img = this.cur_img;
+					this.cur_img = this.prev_img;
+					this.prev_img = this.prev_img.prev();
+
+					this.index--;
+
+					if ( this.prev_img.length ) {
+						this._moveLeft( this.prev_img , -this.window_width + 'px' );
+						this._attach( this.index - 1, this.prev_img );
+					}
+
+					this.direction = -1;
+				}
+			}
+
+			sec = this.options.duration;
+			self = this;
+
+			this.moving = true;
+
+			setTimeout( function () {
+				self.moving = false;
+			}, sec - 25 );
+
+			this._moveLeft( this.cur_img, 0 + 'px', sec );
+			if ( this.next_img.length ) {
+				this._moveLeft( this.next_img, this.window_width + 'px', sec );
+			}
+			if ( this.prev_img.length ) {
+				this._moveLeft( this.prev_img, -this.window_width + 'px', sec );
+			}
+		},
+
+		_add_event: function () {
+			var self = this,
+				date;
+
+			this.container.bind( 'vmousemove', function ( e ) {
+				e.preventDefault();
+
+				if ( self.moving ) {
+					return;
+				}
+				if ( !self.dragging ) {
+					return;
+				}
+
+				self._drag( e.pageX );
+			} );
+
+			this.container.bind( 'vmousedown', function ( e ) {
+				e.preventDefault();
+
+				if ( self.moving ) {
+					return;
+				}
+
+				self.dragging = true;
+
+				self.org_x = e.pageX;
+
+				self.org_time = Date.now();
+			} );
+
+			this.container.bind( 'vmouseup', function ( e ) {
+				if ( self.moving ) {
+					return;
+				}
+
+				self.dragging = false;
+
+				self._move( e.pageX );
+			} );
+
+			this.container.bind( 'vmouseout', function ( e ) {
+				if ( self.moving ) {
+					return;
+				}
+				if ( !self.dragging ) {
+					return;
+				}
+
+				if ( ( e.pageX < 20 ) ||
+						( e.pageX > ( self.max_width - 20 ) ) ) {
+					self._move( e.pageX );
+					self.dragging = false;
+				}
+			} );
+		},
+
+		_del_event: function () {
+			this.container.unbind( 'vmousemove' );
+			this.container.unbind( 'vmousedown' );
+			this.container.unbind( 'vmouseup' );
+			this.container.unbind( 'vmouseout' );
+		},
+		_setTranslateposition : function ( $ele, value ) {
+			var translate,
+				cssArray = null,
+				self = this;
+
+			if ( $.support.cssTransform3d ) {
+				translate = "translate3d(" + value + ", 0px, 0px)";
+			} else {
+				translate = "translate(" + value + ", 0px)";
+			}
+			cssArray = {"-moz-transform": translate,
+					"-webkit-transform": translate,
+					"-ms-transform": translate,
+					"-o-transform": translate,
+					"transform": translate};
+
+			$ele.css(cssArray);
+			return $ele;
+		},
+		_hidePrevNext : function() {
+			var self = this;
+
+			if( self.next_img ) {
+				self.next_img.css( "visibility", "hidden" );
+			}
+			if( self.prev_img ) {
+				self.prev_img.css( "visibility", "hidden" );
+			}
+
+		},
+		_hideCur : function() {
+			var self = this;
+			if( self.cur_img ) {
+				self.cur_img.css( "visibility", "hidden" );
+			}
+		},
+		_moveLeft : function ( $ele , value , duration ) {
+			var translate,
+				transition = "",
+				cssArray = null,
+				self = this;
+
+			if ( $.support.cssTransform3d ) {
+				translate = "translate3d(" + value + ", 0px, 0px)";
+			} else {
+				translate = "translate(" + value + ", 0px)";
+			}
+			if( duration !== undefined ) {
+				transition =  "-webkit-transform " + (duration / 1000)+ "s ease";
+			}
+			cssArray = {"-moz-transform": translate,
+					"-webkit-transform": translate,
+					"-ms-transform": translate,
+					"-o-transform": translate,
+					"transform": translate};
+			if( transition !== "" ) {
+				cssArray["-webkit-transition"] = transition ;
+				if( value == "0px" ) {
+					$ele.one( 'webkitTransitionEnd', self._hidePrevNext );
+				} else {
+					$ele.one( 'webkitTransitionEnd', self._hideCur );
+				}
+			}
+			if( value == "0px" ) {
+				$ele.css( "visibility", "visible" );
+			}
+
+			$ele.css(cssArray);
+			return $ele;
+		},
+		_show: function () {
+			/* resizing */
+			this.window_width = $( window ).width();
+			this.max_width = this._get_width();
+			this.max_height = this._get_height();
+			this.container.css( 'height', this.max_height );
+
+			this.cur_img = $( 'div' ).find( '.ui-gallery-bg:eq(' + this.index + ')' );
+			this.prev_img = this.cur_img.prev();
+			this.next_img = this.cur_img.next();
+
+			this._attach( this.index - 1, this.prev_img );
+			this._attach( this.index, this.cur_img );
+			this._attach( this.index + 1, this.next_img );
+
+			this.cur_img.css( 'visibility', 'visible' );
+			if ( this.prev_img.length ) {
+				this._setTranslateposition( this.prev_img, -this.window_width + 'px');
+			}
+
+			this._moveLeft( this.cur_img, '0px');
+			if ( this.next_img.length ) {
+				this._setTranslateposition( this.next_img, this.window_width + 'px' );
+			}
+		},
+
+		show: function () {
+			if ( !this.images.length ) {
+				return;
+			}
+
+			this._show();
+			this._add_event();
+		},
+
+		_hide: function () {
+			this._detach( this.index - 1, this.prev_img );
+			this._detach( this.index, this.cur_img );
+			this._detach( this.index + 1, this.next_img );
+		},
+
+		hide: function () {
+			this._hide();
+			this._del_event();
+		},
+
+		_get_width: function () {
+			return $( this.element ).width();
+		},
+
+		_get_height: function () {
+			var $page = $( this.element ).parentsUntil( 'ui-page' ),
+				$content = $page.children( '.ui-content' ),
+				header_h = $page.children( '.ui-header' ).outerHeight() || 0,
+				footer_h = $page.children( '.ui-footer' ).outerHeight() || 0,
+				padding = parseFloat( $content.css( 'padding-top' ) )
+					+ parseFloat( $content.css( 'padding-bottom' ) ),
+				content_h = $( window ).height() - header_h - footer_h - padding;
+
+			return content_h;
+		},
+
+		_create: function () {
+			var temp_img,
+				self = this,
+				index,
+				i = 0;
+
+			$( this.element ).wrapInner( '<div class="ui-gallery"></div>' );
+			$( this.element ).find( 'img' ).wrap( '<div class="ui-gallery-bg"></div>' );
+
+			this.container = $( this.element ).find('.ui-gallery');
+
+			temp_img = $( 'div' ).find( '.ui-gallery-bg:first' );
+
+			while ( temp_img.length ) {
+				this.images[i] = temp_img.find( 'img' );
+				temp_img = temp_img.next();
+				i++;
+			}
+
+			this._detach_all();
+
+			index = parseInt( $( this.element ).jqmData( 'index' ), 10 );
+			if ( !index ) {
+				index = 0;
+			}
+			if ( index < 0 ) {
+				index = 0;
+			}
+			if ( index >= this.images.length ) {
+				index = this.images.length - 1;
+			}
+
+			this.index = index;
+
+			this.align_type = $( this.element ).jqmData( 'vertical-align' );
+
+			$.extend( this, {
+				_globalHandlers: [
+					{
+						src: $( window ),
+						handler: {
+							orientationchange: $.proxy( this, "_orientationHandler" ),
+							resize: $.proxy( this, "_resizeHandler" )
+						}
+					}
+				]
+			});
+
+			$.each( this._globalHandlers, function( idx, value ) {
+				value.src.bind( value.handler );
+			});
+		},
+
+		_update: function () {
+			var image_file,
+				bg_html,
+				temp_img;
+
+			while ( this.images_hold.length ) {
+				image_file = this.images_hold.shift();
+
+				bg_html = $( '<div class="ui-gallery-bg"></div>' );
+				temp_img = $( '<img src="' + image_file + '"></div>' );
+
+				bg_html.append( temp_img );
+				this.container.append( bg_html );
+				this.images.push( temp_img );
+			}
+
+			this._detach_all();
+		},
+		_resizeHandler: function() {
+			var self = this;
+			if( self.orientationEventFire ) {
+				self.refresh();
+				$( event.target ).trigger( "galleryorientationchanged", this );
+				self.orientationEventFire = false;
+			}
+		},
+		_orientationHandler: function() {
+			var self = this;
+			self.refresh();
+			self.orientationEventFire = true;
+		},
+		refresh: function ( start_index ) {
+			this._update();
+
+			this._hide();
+
+			if ( start_index === undefined ) {
+				start_index = this.index;
+			}
+			if ( start_index < 0 ) {
+				start_index = 0;
+			}
+			if ( start_index >= this.images.length ) {
+				start_index = this.images.length - 1;
+			}
+
+			this.index = start_index;
+
+			this._show();
+
+			return this.index;
+		},
+
+		add: function ( file ) {
+			this.images_hold.push( file );
+		},
+
+		remove: function ( index ) {
+			var temp_img;
+
+			if ( index === undefined ) {
+				index = this.index;
+			}
+
+			if ( index < 0 || index >= this.images.length ) {
+				return;
+			}
+
+			if ( index == this.index ) {
+				temp_img = this.cur_img;
+
+				if ( this.index == 0 ) {
+					this.direction = 1;
+				} else if ( this.index == this.images.length - 1 ) {
+					this.direction = -1;
+				}
+
+				if ( this.direction < 0 ) {
+					this.cur_img = this.prev_img;
+					this.prev_img = this.prev_img.prev();
+					if ( this.prev_img.length ) {
+						this._moveLeft( this.prev_img, -this.window_width + 'px' );
+						this._attach( index - 2, this.prev_img );
+					}
+					this.index--;
+				} else {
+					this.cur_img = this.next_img;
+					this.next_img = this.next_img.next();
+					if ( this.next_img.length ) {
+						this._moveLeft( this.next_img, this.window_width + 'px' );
+						this._attach( index + 2, this.next_img );
+					}
+				}
+				this._moveLeft( this.cur_img, '0px', this.options.duration );
+
+			} else if ( index == this.index - 1 ) {
+				temp_img = this.prev_img;
+				this.prev_img = this.prev_img.prev();
+				if ( this.prev_img.length ) {
+					this._moveLeft( this.prev_img, -this.window_width + 'px' );
+					this._attach( index - 1, this.prev_img );
+				}
+				this.index--;
+
+			} else if ( index == this.index + 1 ) {
+				temp_img = this.next_img;
+				this.next_img = this.next_img.next();
+				if ( this.next_img.length ) {
+					this._moveLeft( this.next_img, this.window_width + 'px' );
+					this._attach( index + 1, this.next_img );
+				}
+
+			} else {
+				temp_img = $( 'div' ).find( '.ui-gallery-bg:eq(' + index + ')' );
+			}
+
+			this.images.splice( index, 1 );
+			temp_img.detach();
+		},
+
+		empty: function () {
+			this.images.splice( 0, this.images.length );
+			this.container.find('.ui-gallery-bg').detach();
+		},
+
+		length: function () {
+			return this.images.length;
+		},
+
+		value: function ( index ) {
+			if ( index === undefined ) {
+				return this.index;
+			}
+
+			this.refresh( index );
+		},
+
+		unbind: function() {
+			$.each( this._globalHandlers, function( idx, value ) {
+				value.src.unbind( value.handler );
+			});
+		},
+
+		destory: function() {
+			this.unbind();
+		}
+
+	}); /* End of widget */
+
+	// auto self-init widgets
+	$( document ).bind( "pagecreate create", function ( e ) {
+		$( e.target ).find( ":jqmData(role='gallery')" ).gallery();
+	});
+
+	$( document ).bind( "pageshow", function ( e ) {
+		$( e.target ).find( ":jqmData(role='gallery')" ).gallery( 'show' );
+	});
+
+	$( document ).bind( "pagebeforehide", function ( e ) {
+		$( e.target ).find( ":jqmData(role='gallery')" ).gallery( 'hide' );
+	} );
+
+	$( document ).bind( "pageremove", function ( e ) {
+		//unbind resize and orientationchange events
+		$( e.target ).find( ":jqmData(role='gallery')" ).gallery( 'unbind' );
+	});
+
+}( jQuery, this ) );
+
+
+
+/* ***************************************************************************
+* style : normal, check
+* option :
+*    - folded : decide to show divider press effect or not
+*    - line : decide to draw divider line or not
+*/
+/**
+	@class ListDivider
+	The list divider widget is used as a list separator for grouping lists. List dividers can be used in Tizen as described in the jQueryMobile documentation for list dividers.<br/>
+	To add a list divider widget to the application, use the following code:
+
+		<li data-role="list-divider" data-style="check">
+		<form><input type="checkbox" name="c2line-check1" /></form></li>
+
+	The list divider can define callbacks for events as described in the jQueryMobile documentation for list events. <br/> You can use methods with the list divider as described in the jQueryMobile documentation for list methods.
+
+	@since tizen2.0	
+*/
+/**
+	@property {String} data-style
+	Sets the style of the list divider. The style options are dialogue, check, expandable, and checkexpandable.
+*/
+
+(function ( $, undefined ) {
+	$.widget( "tizen.listdivider", $.mobile.widget, {
+		options: {
+			initSelector: ":jqmData(role='list-divider')",
+			folded : false,
+			listDividerLine : true
+		},
+
+		_create: function () {
+
+			var $listdivider = this.element,
+				openStatus = true,
+				expandSrc,
+				listDividerLine = true,
+				style = $listdivider.attr( "data-style" );
+
+			if ( $listdivider.data("line") === false ) {
+				this.options.listDividerLine = false;
+			}
+
+			if ( $listdivider.data("folded") === true ) {
+				this.options.folded = true;
+			}
+
+			if ( style == undefined || style === "normal" || style === "check" ) {
+				if ( this.options.folded ) {
+					$listdivider.buttonMarkup();
+				} else {
+					$listdivider.wrapInner("<span class='ui-btn-text'></span>");
+				}
+
+				if ( this.options.listDividerLine ) {
+					expandSrc = "<span class='ui-divider-normal-line'></span>";
+					if ( this.options.folded ) {
+						$( expandSrc ).appendTo( $listdivider.children( ".ui-btn-inner" ) );
+					} else {
+						$( expandSrc ).appendTo( $listdivider);
+					}
+				}
+			}
+
+			$listdivider.bind( "vclick", function ( event, ui ) {
+			/* need to implement expand/collapse divider */
+			});
+		}
+	});
+
+	//auto self-init widgets
+	$( document ).bind( "pagecreate create", function ( e ) {
+		$( $.tizen.listdivider.prototype.options.initSelector, e.target ).listdivider();
+	});
+}( jQuery ) );
+
+
+
+/* ***************************************************************************
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ * ***************************************************************************
+ *
+ * Authors: Yonghwi Park <yo...@samsung.com>
+ *		 Wonseop Kim <wo...@samsung.com>
+*/
+
+/**
+ *
+ * MultiMediaView is a widget that lets the user view and handle multimedia contents.
+ * Video and audio elements are coded as standard HTML elements and enhanced by the 
+ * MultiMediaview to make them attractive and usable on a mobile device.
+ *
+ * HTML Attributes:
+ *			data-theme : Set a theme of widget.
+ *				If this value is not defined, widget will use parent`s theme. (optional)
+ *			data-controls : If this value is 'true', widget will use belonging controller.
+ *				If this value is 'false', widget will use browser`s controller.
+ *				Default value is 'true'.
+ *			data-full-screen : Set a status that full-screen when inital start.
+ *				Default value is 'false'.
+ *
+ * APIs:
+ *			width( [number] )
+ *					: Get or set the width of widget.
+ *					The first argument is the width of widget.
+ *					If no first argument is specified, will act as a getter.
+ *			height( [number] )
+ *					: Get or set the height of widget.
+ *					The first argument is the height of widget.
+ *					If no first argument is specified, will act as a getter.
+ *			fullScreen( [boolean] )
+ *					: Get or Set the status of full-screen.
+ *					If no first argument is specified, will act as a getter.
+ *
+ * Events:
+ *
+ *			N/A
+ *
+ * Examples:
+ *
+ *			VIDEO :
+ *				<video data-controls="true" style="width:100%;">
+ *					<source src="media/oceans-clip.mp4" type="video/mp4" />
+ *					Your browser does not support the video tag.
+ *				</video>
+ *
+ *			AUDIO :
+ *				<audio data-controls="true" style="width:100%;">
+ *					<source src="media/Over the horizon.mp3" type="audio/mp3" />
+ *					Your browser does not support the audio tag.
+ *				</audio>
+ *
+ */
+/**
+	@class MutimediaView
+	The multimedia view widget shows a player control that you can use to view and handle multimedia content. This widget uses the standard HTML video and audio elements, which have been enhanced for use on a mobile device.
+
+	To add a multimedia view widget to the application, use the following code:
+	
+		// Video player control
+		<video data-controls="true" style="width:100%;">
+		<source src="<VIDEO_FILE_URL>" type="video/mp4" /> Your browser does not support the video tag. </video>
+		// Audio player control
+		<audio data-controls="true" style="width:100%;"> <source src="<AUDIO_FILE_URL>" type="audio/mp3" /> Your browser does not support the audio tag.
+		</audio>
+*/
+/**
+	@property {Boolean} data-control
+	Sets the controls for the widget.
+	The default value is true. If the value is set to true, the widget uses its own player controls. If the value is set to false, the widget uses the browser's player controls.
+*/
+/**
+	@property {Boolean} data-full-screen
+	Defines whether the widget opens in the fullscreen view mode.
+	The default value is false.
+*/
+/**
+	@property {String} data-theme
+	Sets the widget theme.
+	If the value is not set, the parent control's theme is used
+*/
+/**
+	@method width
+	The width method is used to get (if no value is defined) or set the multimedia view widget width:
+		<video>
+			 <source src="test.mp4" type="video/mp4" />
+		</video>
+		$(".selector").multimediaview("width", [value]);
+*/
+/**
+	@method height
+	The height method is used to get (if no value is defined) or set the multimedia view widget height:
+		<video>
+			<source src="test.mp4" type="video/mp4" />
+		</video>
+		$(".selector").multimediaview("height", [value]);
+*/
+/**
+	@method fullScreen
+	The fullScreen method is used to get (if no value is defined) or set the full-screen mode of the multimedia view widget. If the value is true, the full-screen mode is used; otherwise the multimedia view widget runs in the normal mode.
+
+		<video>
+			<source src="test.mp4" type="video/mp4" />
+		</video>
+		$(".selector").multimediaview("fullScreen", [value]);
+*/
+( function ( $, document, window, undefined ) {
+	$.widget( "tizen.multimediaview", $.mobile.widget, {
+		options: {
+			theme: null,
+			controls: true,
+			fullScreen: false,
+			initSelector: "video, audio"
+		},
+
+		_create: function () {
+			var self = this,
+				view = self.element,
+				viewElement = view[0],
+				isVideo = ( viewElement.nodeName === "VIDEO" ),
+				option = self.options,
+				parentTheme = $.mobile.getInheritedTheme( view, "s" ),
+				theme = option.theme || parentTheme,
+				width = viewElement.style.getPropertyValue( "width" ) || "",
+				wrap = $( "<div class='ui-multimediaview-wrap ui-multimediaview-" + theme + "'>" ),
+				control = null;
+
+			$.extend( this, {
+				role: null,
+				controlTimer: null,
+				isVolumeHide: true,
+				backupView: null,
+				_reserveVolume: -1,
+				_isVideo: isVideo
+			});
+
+			view.addClass( "ui-multimediaview" );
+			control = self._createControl();
+			control.hide();
+
+			$( ".ui-button", control ).addClass( "ui-shadow ui-btn-corner-all" );
+			$( ".ui-volumecontrol .ui-handle", control ).addClass( "ui-shadow ui-btn-corner-circle" );
+
+			view.wrap( wrap ).after( control );
+
+			if ( isVideo ) {
+				control.addClass( "ui-multimediaview-video" );
+			} else {
+				self.width( width );
+				self.options.fullScreen = false;
+			}
+
+			if ( option.controls && view.attr( "controls" ) ) {
+				view.removeAttr( "controls" );
+			}
+
+			self._addEvent();
+		},
+
+		_resize: function () {
+			this._resizeFullscreen( this.options.fullScreen );
+			this._resizeControl();
+			this._updateSeekBar();
+			this._updateVolumeState();
+		},
+
+		_resizeControl: function () {
+			var self = this,
+				view = self.element,
+				viewElement = view[0],
+				isVideo = self._isVideo,
+				wrap = view.parent( ".ui-multimediaview-wrap" ),
+				control = wrap.find( ".ui-multimediaview-control" ),
+				buttons = control.find( ".ui-button" ),
+				playpauseButton = control.find( ".ui-playpausebutton" ),
+				seekBar = control.find( ".ui-seekbar" ),
+				durationLabel = control.find( ".ui-durationlabel" ),
+				timestampLabel = control.find( ".ui-timestamplabel" ),
+				volumeControl = control.find( ".ui-volumecontrol" ),
+				volumeBar = volumeControl.find( ".ui-volumebar" ),
+				width = ( isVideo ? view.width() : wrap.width() ),
+				height = ( isVideo ? view.height() : control.height() ),
+				offset = view.offset(),
+				controlHeight = control.height(),
+				availableWidth = 0,
+				controlOffset = null;
+
+			if ( control ) {
+				if ( isVideo ) {
+					controlOffset = control.offset();
+					controlOffset.left = offset.left;
+					controlOffset.top = offset.top + height - controlHeight;
+					control.offset( controlOffset );
+				}
+				control.width( width );
+			}
+
+			if ( seekBar ) {
+				availableWidth = control.width() - ( buttons.outerWidth( true ) * buttons.length );
+				availableWidth -= ( parseInt( buttons.eq( 0 ).css( "margin-left" ), 10 ) + parseInt( buttons.eq( 0 ).css( "margin-right" ), 10 ) ) * buttons.length;
+				if ( !self.isVolumeHide ) {
+					availableWidth -= volumeControl.outerWidth( true );
+				}
+				seekBar.width( availableWidth );
+			}
+
+			if ( durationLabel && !isNaN( viewElement.duration ) ) {
+				durationLabel.find( "p" ).text( self._convertTimeFormat( viewElement.duration ) );
+			}
+
+			if ( viewElement.autoplay && viewElement.paused === false ) {
+				playpauseButton.removeClass( "ui-play-icon" ).addClass( "ui-pause-icon" );
+			}
+
+			if ( seekBar.width() < ( volumeBar.width() + timestampLabel.width() + durationLabel.width() ) ) {
+				durationLabel.hide();
+			} else {
+				durationLabel.show();
+			}
+		},
+
+		_resizeFullscreen: function ( isFullscreen ) {
+			if ( !this._isVideo ) {
+				return;
+			}
+
+			var self = this,
+				view = self.element,
+				viewElement = view[0],
+				wrap = view.parent( ".ui-multimediaview-wrap" ),
+				control = wrap.find( ".ui-multimediaview-control" ),
+				fullscreenButton = control.find( ".ui-fullscreenbutton" ),
+				currentPage = $( ".ui-page-active" ),
+				playpauseButton = control.find( ".ui-playpausebutton" ),
+				timestampLabel = control.find( ".ui-timestamplabel" ),
+				seekBar = control.find( ".ui-seekbar" ),
+				durationBar = seekBar.find( ".ui-duration" ),
+				currenttimeBar = seekBar.find( ".ui-currenttime" ),
+				body = $( "body" )[0],
+				header = currentPage.children( ".ui-header" ),
+				footer = currentPage.children( ".ui-footer" ),
+				docWidth = 0,
+				docHeight = 0;
+
+			if ( isFullscreen ) {
+				if ( !self.backupView ) {
+					self.backupView = {
+						width: viewElement.style.getPropertyValue( "width" ) || "",
+						height: viewElement.style.getPropertyValue( "height" ) || "",
+						position: view.css( "position" ),
+						zindex: view.css( "z-index" ),
+						wrapHeight: wrap[0].style.getPropertyValue( "height" ) || ""
+					};
+				}
+				docWidth = body.clientWidth;
+				docHeight = body.clientHeight - 1;
+
+				header.hide();
+				footer.hide();
+				view.parents().each( function ( e ) {
+					var element = $( this );
+					element.addClass( "ui-fullscreen-parents" )
+						.siblings()
+						.addClass( "ui-multimediaview-siblings-off" );
+				});
+				fullscreenButton.removeClass( "ui-fullscreen-on" ).addClass( "ui-fullscreen-off" );
+
+				wrap.height( docHeight );
+				view.width( docWidth ).height( docHeight );
+			} else {
+				if ( !self.backupView ) {
+					return;
+				}
+
+				header.show();
+				footer.show();
+				view.parents().each( function ( e ) {
+					var element = $( this );
+					element.removeClass( "ui-fullscreen-parents" )
+						.siblings()
+						.removeClass( "ui-multimediaview-siblings-off" );
+				});
+
+				fullscreenButton.removeClass( "ui-fullscreen-off" ).addClass( "ui-fullscreen-on" );
+
+				wrap.css( "height", self.backupView.wrapHeight );
+				view.css( {
+					"width": self.backupView.width,
+					"height": self.backupView.height,
+					"position": self.backupView.position,
+					"z-index": self.backupView.zindex
+				});
+				self.backupView = null;
+
+				$( window ).trigger( "throttledresize" );
+			}
+		},
+
+		_addEvent: function () {
+			var self = this,
+				view = self.element,
+				option = self.options,
+				viewElement = view[0],
+				isVideo = self._isVideo,
+				control = view.parent( ".ui-multimediaview-wrap" ).find( ".ui-multimediaview-control" ),
+				playpauseButton = control.find( ".ui-playpausebutton" ),
+				timestampLabel = control.find( ".ui-timestamplabel" ),
+				durationLabel = control.find( ".ui-durationlabel" ),
+				volumeButton = control.find( ".ui-volumebutton" ),
+				volumeControl = control.find( ".ui-volumecontrol" ),
+				volumeBar = volumeControl.find( ".ui-volumebar" ),
+				volumeGuide = volumeControl.find( ".ui-guide" ),
+				volumeHandle = volumeControl.find( ".ui-handle" ),
+				fullscreenButton = control.find( ".ui-fullscreenbutton" ),
+				seekBar = control.find( ".ui-seekbar" ),
+				durationBar = seekBar.find( ".ui-duration" ),
+				currenttimeBar = seekBar.find( ".ui-currenttime" ),
+				touchStartEvt = ( $.support.touch ? "touchstart" : "mousedown" ),
+				touchMoveEvt = ( $.support.touch ? "touchmove" : "mousemove" ) + ".multimediaview",
+				touchEndEvt = ( $.support.touch ? "touchend" : "mouseup" ) + ".multimediaview",
+				$document = $( document );
+
+			view.bind( "loadedmetadata.multimediaview", function ( e ) {
+				if ( !isNaN( viewElement.duration ) ) {
+					durationLabel.find( "p" ).text( self._convertTimeFormat( viewElement.duration ) );
+				}
+				self._resize();
+			}).bind( "timeupdate.multimediaview", function ( e ) {
+				self._updateSeekBar();
+			}).bind( "play.multimediaview", function ( e ) {
+				playpauseButton.removeClass( "ui-play-icon" ).addClass( "ui-pause-icon" );
+			}).bind( "pause.multimediaview", function ( e ) {
+				playpauseButton.removeClass( "ui-pause-icon" ).addClass( "ui-play-icon" );
+			}).bind( "ended.multimediaview", function ( e ) {
+				if ( typeof viewElement.loop == "undefined" || viewElement.loop === "" ) {
+					self.stop();
+				}
+			}).bind( "volumechange.multimediaview", function ( e ) {
+				if ( viewElement.muted && viewElement.volume > 0.1 ) {
+					volumeButton.removeClass( "ui-volume-icon" ).addClass( "ui-mute-icon" );
+					self._reserveVolume = viewElement.volume;
+					viewElement.volume = 0;
+				} else if ( self._reserveVolume !== -1 && !viewElement.muted ) {
+					volumeButton.removeClass( "ui-mute-icon" ).addClass( "ui-volume-icon" );
+					viewElement.volume = self._reserveVolume;
+					self._reserveVolume = -1;
+				} else if ( viewElement.volume < 0.1 ) {
+					volumeButton.removeClass( "ui-volume-icon" ).addClass( "ui-mute-icon" );
+				} else {
+					volumeButton.removeClass( "ui-mute-icon" ).addClass( "ui-volume-icon" );
+				}
+
+				if ( !self.isVolumeHide ) {
+					self._updateVolumeState();
+				}
+			}).bind( "durationchange.multimediaview", function ( e ) {
+				if ( !isNaN( viewElement.duration ) ) {
+					durationLabel.find( "p" ).text( self._convertTimeFormat( viewElement.duration ) );
+				}
+				self._resize();
+			}).bind( "click.multimediaview", function ( e ) {
+				if ( !self.options.controls ) {
+					return;
+				}
+
+				control.fadeToggle( "fast" );
+				self._resize();
+			}).bind( "multimediaviewinit", function ( e ) {
+				if ( option.controls ) {
+					control.show();
+				}
+				self._resize();
+			});
+
+			$( ".ui-button", control ).bind( touchStartEvt, function () {
+				var button = $( this ).addClass( "ui-button-down" );
+
+				$document.bind( touchMoveEvt, function () {
+					button.trigger( touchEndEvt );
+				});
+			}).bind( touchEndEvt, function () {
+				$( this ).removeClass( "ui-button-down" );
+				$document.unbind( touchMoveEvt );
+			});
+
+			playpauseButton.bind( "click.multimediaview", function () {
+				self._endTimer();
+
+				if ( viewElement.paused ) {
+					viewElement.play();
+				} else {
+					viewElement.pause();
+				}
+
+				if ( isVideo ) {
+					self._startTimer();
+				}
+			});
+
+			fullscreenButton.bind( "click.multimediaview", function ( e ) {
+				e.preventDefault();
+				self.fullScreen( !self.options.fullScreen );
+				self._resize();
+				self._endTimer();
+				e.stopPropagation();
+			});
+
+			seekBar.bind( touchStartEvt, function ( e ) {
+				var x = $.support.touch ? e.originalEvent.changedTouches[0].pageX : e.pageX,
+					duration = viewElement.duration,
+					durationOffset = durationBar.offset(),
+					durationWidth = durationBar.width(),
+					timerate = ( x - durationOffset.left ) / durationWidth,
+					time = duration * timerate;
+
+				if ( !viewElement.played.length ) {
+					return;
+				}
+
+				viewElement.currentTime = time;
+
+				self._endTimer();
+
+				e.preventDefault();
+
+				control.bind( touchMoveEvt, function ( e ) {
+					var x = $.support.touch ? e.originalEvent.changedTouches[0].pageX : e.pageX,
+						timerate = ( x - durationOffset.left ) / durationWidth;
+
+					viewElement.currentTime = duration * timerate;
+
+					e.stopPropagation();
+				}).bind( touchEndEvt, function () {
+					control.unbind( ".multimediaview" );
+					$document.unbind( touchMoveEvt );
+					if ( viewElement.paused ) {
+						viewElement.pause();
+					} else {
+						viewElement.play();
+					}
+					e.stopPropagation();
+				});
+
+				$document.bind( touchMoveEvt, function () {
+					control.trigger( touchEndEvt );
+				});
+			});
+
+			volumeButton.bind( "click.multimediaview", function () {
+				if ( self.isVolumeHide ) {
+					var view = self.element,
+						volume = viewElement.volume;
+
+					self.isVolumeHide = false;
+					volumeControl.fadeIn( "fast", function () {
+						self._updateVolumeState();
+						self._updateSeekBar();
+					});
+					self._resize();
+				} else {
+					self.isVolumeHide = true;
+					volumeControl.fadeOut( "fast", function () {
+						self._resize();
+					});
+				}
+			});
+
+			volumeBar.bind( touchStartEvt, function ( e ) {
+				var baseX = $.support.touch ? e.originalEvent.changedTouches[0].pageX : e.pageX,
+					volumeGuideLeft = volumeGuide.offset().left,
+					volumeGuideWidth = volumeGuide.width(),
+					volumeBase = volumeGuideLeft + volumeGuideWidth,
+					handlerOffset = volumeHandle.offset(),
+					volumerate = ( baseX - volumeGuideLeft ) / volumeGuideWidth,
+					currentVolume = ( baseX - volumeGuideLeft ) / volumeGuideWidth;
+
+				self._endTimer();
+				volumeHandle.addClass( "ui-button-down" );
+				self._setVolume( currentVolume.toFixed( 2 ) );
+
+				e.preventDefault();
+
+				control.bind( touchMoveEvt, function ( e ) {
+					var x = $.support.touch ? e.originalEvent.changedTouches[0].pageX : e.pageX,
+						currentVolume = ( x - volumeGuideLeft );
+					currentVolume = ( currentVolume < 0 ) ? 0 : currentVolume / volumeGuideWidth;
+					self._setVolume( ( currentVolume > 1 ) ? 1 : currentVolume.toFixed( 2 ) );
+
+					e.stopPropagation();
+				}).bind( touchEndEvt, function () {
+					control.unbind( ".multimediaview" );
+					$document.unbind( touchMoveEvt );
+					volumeHandle.removeClass( "ui-button-down" );
+					e.stopPropagation();
+				});
+
+				$document.bind( touchMoveEvt, function () {
+					control.trigger( touchEndEvt );
+				});
+			});
+		},
+
+		_removeEvent: function () {
+			var view = this.element,
+				control = view.parent( ".ui-multimediaview-wrap" ).find( ".ui-multimediaview-control" ),
+				playpauseButton = contr

<TRUNCATED>