returns mouse or all finger touch coords
349586
function(event) {
    if (typeof event.touches != 'undefined' && event.touches.length > 0) {
      var c = {
        x: event.touches[0].pageX, 
        y: event.touches[0].pageY
      };
    } else {
      var  c = {
        x: (event.pageX || (event.clientX + document.body.scrollLeft)),
        y: (event.pageY || (event.clientY + document.body.scrollTop))
      };
    }
    
    return c;
  }
650771
function w3cTouchConvert(touchList) {
      var canvasOffset = display._getCanvasOffset();
      var tList = [];
      for (var i = 0; i < touchList.length; i++) {
         var touchEvent = touchList.item(i);
         tList.push({
            identifier: touchEvent.identifier,
            pos: [touchEvent.clientX - canvasOffset[0], touchEvent.clientY - canvasOffset[1]]
         });
      }
      return tList;
   }
686331
function onTouch(element, eventType, handler) {
    var self = this;

    this.bindDom(element, Hammer.EVENT_TYPES[eventType], function bindDomOnTouch(ev) {
      var sourceEventType = ev.type.toLowerCase();

      // onmouseup, but when touchend has been fired we do nothing.
      // this is for touchdevices which also fire a mouseup on touchend
      if(sourceEventType.match(/mouse/) && touch_triggered) {
        return;
      }

      // mousebutton must be down or a touch event
      else if(sourceEventType.match(/touch/) ||   // touch events are always on screen
        sourceEventType.match(/pointerdown/) || // pointerevents touch
        (sourceEventType.match(/mouse/) && ev.which === 1)   // mouse is pressed
        ) {
        enable_detect = true;
      }

      // mouse isn't pressed
      else if(sourceEventType.match(/mouse/) && !ev.which) {
        enable_detect = false;
      }


      // we are in a touch event, set the touch triggered bool to true,
      // this for the conflicts that may occur on ios and android
      if(sourceEventType.match(/touch|pointer/)) {
        touch_triggered = true;
      }

      // count the total touches on the screen
      var count_touches = 0;

      // when touch has been triggered in this detection session
      // and we are now handling a mouse event, we stop that to prevent conflicts
      if(enable_detect) {
        // update pointerevent
        if(Hammer.HAS_POINTEREVENTS && eventType != Hammer.EVENT_END) {
          count_touches = Hammer.PointerEvent.updatePointer(eventType, ev);
        }
        // touch
        else if(sourceEventType.match(/touch/)) {
          count_touches = ev.touches.length;
        }
        // mouse
        else if(!touch_triggered) {
          count_touches = sourceEventType.match(/up/) ? 0 : 1;
        }

        // if we are in a end event, but when we remove one touch and
        // we still have enough, set eventType to move
        if(count_touches > 0 && eventType == Hammer.EVENT_END) {
          eventType = Hammer.EVENT_MOVE;
        }
        // no touches, force the end event
        else if(!count_touches) {
          eventType = Hammer.EVENT_END;
        }

        // store the last move event
        if(count_touches || last_move_event === null) {
          last_move_event = ev;
        }

        // trigger the handler
        handler.call(Hammer.detection, self.collectEventData(element, eventType, self.getTouchList(last_move_event, eventType), ev));

        // remove pointerevent from list
        if(Hammer.HAS_POINTEREVENTS && eventType == Hammer.EVENT_END) {
          count_touches = Hammer.PointerEvent.updatePointer(eventType, ev);
        }
      }

      // on the end we reset everything
      if(!count_touches) {
        last_move_event = null;
        enable_detect = false;
        touch_triggered = false;
        Hammer.PointerEvent.reset();
      }
    });
  }
901969
function getGesture( element_ ) {
    const element = ensureDom( element_ );
    if ( !element[ SYMBOL ] ) element[ SYMBOL ] = new Gesture( element );
    return element[ SYMBOL ];
}
250625
function multitouch(position, element, done) {
                var points = config.randomizer.integer({ min: 2, max: config.maxTouches});
                var gesture = {
                    scale:     config.randomizer.floating({ min: 0, max: 2 }),
                    rotation:  config.randomizer.natural({ min: -100, max: 100 }),
                    radius:    config.randomizer.integer({ min: 50, max: 200 }),
                    distanceX: config.randomizer.integer({ min: -20, max: 20 }),
                    distanceY: config.randomizer.integer({ min: -20, max: 20 }),
                    duration:  config.randomizer.integer({ min: 100, max: 1500 })
                };
                var touches = getTouches(position, points, gesture.radius);

                triggerGesture(element, position, touches, gesture, function(touches) {
                    done(touches, gesture);
                });
            }
1049791
function () {
    var gesture;
    var isGripActive = this.pressedButtons['grip'];
    var isSurfaceActive = this.pressedButtons['surface'] || this.touchedButtons['surface'];
    var isTrackpadActive = this.pressedButtons['trackpad'] || this.touchedButtons['trackpad'];
    var isTriggerActive = this.pressedButtons['trigger'] || this.touchedButtons['trigger'];
    var isABXYActive = this.touchedButtons['AorX'] || this.touchedButtons['BorY'];
    var isVive = isViveController(this.el.components['tracked-controls']);

    // Works well with Oculus Touch and Windows Motion Controls, but Vive needs tweaks.
    if (isVive) {
      if (isGripActive || isTriggerActive) {
        gesture = ANIMATIONS.fist;
      } else if (isTrackpadActive) {
        gesture = ANIMATIONS.point;
      }
    } else {
      if (isGripActive) {
        if (isSurfaceActive || isABXYActive || isTrackpadActive) {
          gesture = isTriggerActive ? ANIMATIONS.fist : ANIMATIONS.point;
        } else {
          gesture = isTriggerActive ? ANIMATIONS.thumbUp : ANIMATIONS.pointThumb;
        }
      } else if (isTriggerActive) {
        gesture = ANIMATIONS.hold;
      }
    }

    return gesture;
  }
530457
function (i) {
      return function (e) {
        if (this.props.disabled || e.touches.length > 1) return;
        var position = this._getTouchPosition(e);
        this.startPosition = position;
        this.isScrolling = undefined; // don't know yet if the user is trying to scroll
        this._start(i, position[0]);
        this._addHandlers(this._getTouchEventMap());
        stopPropagation(e);
      }.bind(this);
    }
42523
function TouchList() {
  var touchList = [];

  touchList['item'] = function(index) {
    return this[index] || null;
  };

  // specified by Mozilla
  touchList['identifiedTouch'] = function(id) {
    return this[id + 1] || null;
  };

  return touchList;
}
633254
function (event) {
            // Standard touch
            if (event.touches && event.changedTouches
                    && (event.changedTouches.length || 0) + (event.touches.length || 0) >= 2) {
                var positions = aria.touch.Event.getPositions(event);
                this.primaryPoint = positions[0];
                this.secondaryPoint = positions[1];
            }
            // IE10 touch
            if (typeof event.isPrimary != 'undefined') {
                if (event.isPrimary) {
                    this.primaryPoint = aria.touch.Event.getPositions(event);
                } else {
                    this.secondaryPoint = aria.touch.Event.getPositions(event);
                }
            }
            if (event.touches && event.changedTouches
                    && (event.changedTouches.length || 0) + (event.touches.length || 0) >= 2
                    || typeof event.isPrimary != 'undefined') {
                var finalDist = this._calculateDistance(this.primaryPoint.x, this.primaryPoint.y, this.secondaryPoint.x, this.secondaryPoint.y);
                var finalAngle = this.__calculateAngle(this.primaryPoint.x, this.primaryPoint.y, this.secondaryPoint.x, this.secondaryPoint.y);
                if (Math.abs(finalAngle - this.lastKnownAngle) > 150) {
                    finalAngle = this.__calculateAngle(this.secondaryPoint.x, this.secondaryPoint.y, this.primaryPoint.x, this.primaryPoint.y);
                }
                var finalData = {
                    distance : finalDist,
                    dVariation : (finalDist - this.initialPinchData.distance),
                    angle : finalAngle
                };
                this.$raiseEvent({
                    name : "pinchend",
                    distance : finalDist,
                    dVariation : (finalDist - this.initialPinchData.distance),
                    angle : finalAngle,
                    originalEvent : event
                });
                return this._gestureEnd(event, finalData);
            } else {
                this.$raiseEvent({
                    name : "pinchcancel"
                });
                return this._gestureCancel(event);
            }
        }
812705
function(inEvent) {
      var lts = this.lastTouches;
      var x = inEvent.clientX, y = inEvent.clientY;
      for (var i = 0, l = lts.length, t; i < l && (t = lts[i]); i++) {
        // simulated mouse events will be swallowed near a primary touchend
        var dx = Math.abs(x - t.x), dy = Math.abs(y - t.y);
        if (dx <= DEDUP_DIST && dy <= DEDUP_DIST) {
          return true;
        }
      }
    }
820479
function getTouchList(ev/*, eventType*/) {
      // get the fake pointerEvent touchlist
      if(ionic.Gestures.HAS_POINTEREVENTS) {
        return ionic.Gestures.PointerEvent.getTouchList();
      }
      // get the touchlist
      else if(ev.touches) {
        return ev.touches;
      }
      // make fake touchlist from mouse position
      else {
        ev.identifier = 1;
        return [ev];
      }
    }
352388
function triggerTouch(eventName, mouseEv) {
  var touchEvent = document.createEvent('Event');
  touchEvent.initEvent(eventName, true, true);

  touchEvent.altKey = mouseEv.altKey;
  touchEvent.ctrlKey = mouseEv.ctrlKey;
  touchEvent.metaKey = mouseEv.metaKey;
  touchEvent.shiftKey = mouseEv.shiftKey;

  touchEvent.touches = getActiveTouches(mouseEv);
  touchEvent.targetTouches = getActiveTouches(mouseEv);
  touchEvent.changedTouches = createTouchList(mouseEv);

  eventTarget.dispatchEvent(touchEvent);
}
640758
function () {
        this._touchHandler = $B.bind(function (e) {
            if ( !this._enable ) return this._removeTouchEvent();

            var evt, pageX1, pageY1, pageX2, pageY2, clientX1, clientY1, clientX2, clientY2,
                touches = e.touches, touch1, touch2, currentTouchLength = e.touches.length;

            if ( currentTouchLength > 1 ) {
                touch1 = touches[0];
                touch2 = touches[1];

                pageX1 = touch1.pageX;
                pageY1 = touch1.pageY;
                pageX2 = touch2.pageX;
                pageY2 = touch2.pageY;
                clientX1 = touch1.clientX;
                clientY1 = touch1.clientY;
                clientX2 = touch2.clientX;
                clientY2 = touch2.clientY;

                var distanceH = this._getDistance( pageX1, pageX2 ),
                    distanceV = this._getDistance( pageY1, pageY2 ),
                    radius = this._getRadius( distanceH, distanceV ),
                    radian = this._getRadian( distanceH, distanceV ),
                    degree = this._radianToDeg( radian ),
                    cPageX = this._getCenterPos( pageX1, pageX2, distanceH ),
                    cPageY = this._getCenterPos( pageY1, pageY2, distanceV ),
                    cClientX = this._getCenterPos( clientX1, clientX2, distanceH ),
                    cClientY = this._getCenterPos( clientY1, clientY2, distanceV );

                evt = {
                    type: '', pointers: this._getPointers( touches ),
                    growAngle: 0, growScale: 0, angle: 0, scale: 1,
                    degree: degree, radian: radian, radius: radius,
                    distance: radius * 2, distanceH: distanceH, distanceV: distanceV,
                    pageX: cPageX, pageY: cPageY, clientX: cClientX, clientY: cClientY, pan: false
                };

                if ( e.type == 'touchmove' ) {
                    e.preventDefault();

                    var gAngle = this._getBetweenAngle( this._oldPageX1, this._oldPageY1, pageX1, pageY1, this._oldCenterX, this._oldCenterY, cPageX, cPageY ),
                        tScale = radius / this._startRadius,
                        gScale = ( radius - this._oldRadius ) / this._startRadius;

                    this._totalAngle += gAngle;

                    evt.growAngle = gAngle;
                    evt.angle = this._totalAngle;
                    evt.scale = tScale;
                    evt.growScale = gScale;
                    evt.pan = this._isPanEvent( this._startDistanceH, this._startDistanceV, distanceH, distanceV );
                    this.dispatch( 'multitouchmove', evt );
                    //Start
                } else if ( e.type == 'touchstart' ) {
                    var touchStarted = this._hasMultiTouchStart;

                    this._hasMultiTouchStart = true;
                    this._startRadius = radius;
                    this._totalAngle = 0;
                    this._isPan = null;
                    this._startDistanceH = distanceH;
                    this._startDistanceV = distanceV;

                    if ( !touchStarted ) {
                        //start시에는 grow관련값이 모두 0이다.
                        this.dispatch( 'multitouchstart', evt );
                    }
                }

                this._oldPageX1 = pageX1;
                this._oldPageY1 = pageY1;
                this._oldCenterX = cPageX;
                this._oldCenterY = cPageY;
                this._oldRadius = radius;
                this._oldEvt = evt;
            }

            if ( e.type == 'touchend' || e.type == 'touchcancel' ) {
                //MultiTouchStart가 발생하고 난후에만 End이벤트가 발생한다.
                if ( this._hasMultiTouchStart && currentTouchLength < 2 ) {
                    this._removeTouchEvent();
                    this.dispatch( 'multitouchend', this._oldEvt );
                    this._hasMultiTouchStart = false;
                }
            }
        }, this);

        this._startHandler = $B.bind(function (e) {
            this._addTouchEvent();
        }, this);

        this._touchEvent = new $B.event.TouchEvent( this._target ).addListener( 'touchstart', this._startHandler );
        this._winTouchEvent = new $B.event.TouchEvent( window );
    }
1227393
function () {
        return $(this).bind ('touchstart', function preventZoom (e) {
            var t2 = e.timeStamp
            var t1 = $(this).data ('lastTouch') || t2
            var dt = t2 - t1
            var fingers = e.originalEvent.touches.length
            $(this).data ('lastTouch', t2)
            if (!dt || dt > 500 || fingers > 1) {
                return } // not double-tap
            e.preventDefault ()                     // double tap - prevent the zoom
            $(e.target).trigger ('click') }) }
59945
function (e) {

				// let the system handle multitouch operations like two finger scroll
				// and pinching
				if (e && e.touches && e.touches.length > 1) {
					return;
				}

				// normalize
				e = normalizeMouseEvent(e);
				if (!hasTouch) { // not for touch devices
					e.returnValue = false;
				}

				var chartX = e.chartX,
					chartY = e.chartY,
					isOutsidePlot = !isInsidePlot(chartX - plotLeft, chartY - plotTop);

				// cache chart position for issue #149 fix
				if (!chartPosition) {
					chartPosition = getPosition(container);
				}

				// on touch devices, only trigger click if a handler is defined
				if (hasTouch && e.type === 'touchstart') {
					if (attr(e.target, 'isTracker')) {
						if (!chart.runTrackerClick) {
							e.preventDefault();
						}
					} else if (!runChartClick && !isOutsidePlot) {
						e.preventDefault();
					}
				}

				// cancel on mouse outside
				if (isOutsidePlot) {

					/*if (!lastWasOutsidePlot) {
						// reset the tracker
						resetTracker();
					}*/

					// drop the selection if any and reset mouseIsDown and hasDragged
					//drop();
					if (chartX < plotLeft) {
						chartX = plotLeft;
					} else if (chartX > plotLeft + plotWidth) {
						chartX = plotLeft + plotWidth;
					}

					if (chartY < plotTop) {
						chartY = plotTop;
					} else if (chartY > plotTop + plotHeight) {
						chartY = plotTop + plotHeight;
					}

				}

				if (mouseIsDown && e.type !== 'touchstart') { // make selection

					// determine if the mouse has moved more than 10px
					hasDragged = Math.sqrt(
						Math.pow(mouseDownX - chartX, 2) +
						Math.pow(mouseDownY - chartY, 2)
					);
					if (hasDragged > 10) {

						// make a selection
						if (hasCartesianSeries && (zoomX || zoomY) &&
								isInsidePlot(mouseDownX - plotLeft, mouseDownY - plotTop)) {
							if (!selectionMarker) {
								selectionMarker = renderer.rect(
									plotLeft,
									plotTop,
									zoomHor ? 1 : plotWidth,
									zoomVert ? 1 : plotHeight,
									0
								)
								.attr({
									fill: optionsChart.selectionMarkerFill || 'rgba(69,114,167,0.25)',
									zIndex: 7
								})
								.add();
							}
						}

						// adjust the width of the selection marker
						if (selectionMarker && zoomHor) {
							var xSize = chartX - mouseDownX;
							selectionMarker.attr({
								width: mathAbs(xSize),
								x: (xSize > 0 ? 0 : xSize) + mouseDownX
							});
						}
						// adjust the height of the selection marker
						if (selectionMarker && zoomVert) {
							var ySize = chartY - mouseDownY;
							selectionMarker.attr({
								height: mathAbs(ySize),
								y: (ySize > 0 ? 0 : ySize) + mouseDownY
							});
						}
					}

				} else if (!isOutsidePlot) {
					// show the tooltip
					onmousemove(e);
				}

				lastWasOutsidePlot = isOutsidePlot;

				// when outside plot, allow touch-drag by returning true
				return isOutsidePlot || !hasCartesianSeries;
			}
278274
function triggerTouch(touches, element, type) {
            var touchlist = [],
                event = document.createEvent('Event');

            event.initEvent('touch' + type, true, true);

            touchlist.identifiedTouch = touchlist.item = function(index) {
                return this[index] || {};
            };

            touches.forEach(function(touch, i) {
                var x = Math.round(touch.x),
                    y = Math.round(touch.y);
                touchlist.push({
                    pageX: x,
                    pageY: y,
                    clientX: x,
                    clientY: y,
                    screenX: x,
                    screenY: y,
                    target: element,
                    identifier: i
                });
            });

            event.touches = (type == 'end') ? [] : touchlist;
            event.targetTouches = (type == 'end') ? [] : touchlist;
            event.changedTouches = touchlist;

            element.dispatchEvent(event);
            config.showAction(touches);
        }
341605
function getTargetTouch (touches, target) {
  return Array.prototype.slice.call(touches).filter(function (t) {
    return t.target === target
  })[0] || touches[0]
}