var PREFIXED_TOUCH_ACTION = prefixed(TEST_ELEMENT.style, 'touchAction');
var NATIVE_TOUCH_ACTION = PREFIXED_TOUCH_ACTION !== undefined;

// magical touchAction value
var TOUCH_ACTION_COMPUTE = 'compute';
var TOUCH_ACTION_AUTO = 'auto';
var TOUCH_ACTION_MANIPULATION = 'manipulation'; // not implemented
var TOUCH_ACTION_NONE = 'none';
var TOUCH_ACTION_PAN_X = 'pan-x';
var TOUCH_ACTION_PAN_Y = 'pan-y';

/**
 * Touch Action
 * sets the touchAction property or uses the js alternative
 * @param {Manager} manager
 * @param {String} value
 * @constructor
 */
function TouchAction(manager, value) {
    this.manager = manager;
    this.set(value);
}

TouchAction.prototype = {
    /**
     * set the touchAction value on the element or enable the polyfill
     * @param {String} value
     */
    set: function(value) {
        // find out the touch-action by the event handlers
        if (value == TOUCH_ACTION_COMPUTE) {
            value = this.compute();
        }

        if (NATIVE_TOUCH_ACTION && this.manager.element.style) {
            this.manager.element.style[PREFIXED_TOUCH_ACTION] = value;
        }
        this.actions = value.toLowerCase().trim();
    },

    /**
     * just re-set the touchAction value
     */
    update: function() {
        this.set(this.manager.options.touchAction);
    },

    /**
     * compute the value for the touchAction property based on the recognizer's settings
     * @returns {String} value
     */
    compute: function() {
        var actions = [];
        each(this.manager.recognizers, function(recognizer) {
            if (boolOrFn(recognizer.options.enable, [recognizer])) {
                actions = actions.concat(recognizer.getTouchAction());
            }
        });
        return cleanTouchActions(actions.join(' '));
    },

    /**
     * this method is called on each input cycle and provides the preventing of the browser behavior
     * @param {Object} input
     */
    preventDefaults: function(input) {
        // not needed with native support for the touchAction property
        if (NATIVE_TOUCH_ACTION) {
            return;
        }

        var srcEvent = input.srcEvent;
        var direction = input.offsetDirection;

        // if the touch action did prevented once this session
        if (this.manager.session.prevented) {
            srcEvent.preventDefault();
            return;
        }

        var actions = this.actions;
        var hasNone = inStr(actions, TOUCH_ACTION_NONE);
        var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y);
        var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X);

        if (hasNone) {
            //do not prevent defaults if this is a tap gesture

            var isTapPointer = input.pointers.length === 1;
            var isTapMovement = input.distance < 2;
            var isTapTouchTime = input.deltaTime < 250;

            if (isTapPointer && isTapMovement && isTapTouchTime) {
                return;
            }
        }

        if (hasPanX && hasPanY) {
            // `pan-x pan-y` means browser handles all scrolling/panning, do not prevent
            return;
        }

        if (hasNone ||
            (hasPanY && direction & DIRECTION_HORIZONTAL) ||
            (hasPanX && direction & DIRECTION_VERTICAL)) {
            return this.preventSrc(srcEvent);
        }
    },

    /**
     * call preventDefault to prevent the browser's default behavior (scrolling in most cases)
     * @param {Object} srcEvent
     */
    preventSrc: function(srcEvent) {
        this.manager.session.prevented = true;
        srcEvent.preventDefault();
    }
};

/**
 * when the touchActions are collected they are not a valid value, so we need to clean things up. *
 * @param {String} actions
 * @returns {*}
 */
function cleanTouchActions(actions) {
    // none
    if (inStr(actions, TOUCH_ACTION_NONE)) {
        return TOUCH_ACTION_NONE;
    }

    var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X);
    var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y);

    // if both pan-x and pan-y are set (different recognizers
    // for different directions, e.g. horizontal pan but vertical swipe?)
    // we need none (as otherwise with pan-x pan-y combined none of these
    // recognizers will work, since the browser would handle all panning
    if (hasPanX && hasPanY) {
        return TOUCH_ACTION_NONE;
    }

    // pan-x OR pan-y
    if (hasPanX || hasPanY) {
        return hasPanX ? TOUCH_ACTION_PAN_X : TOUCH_ACTION_PAN_Y;
    }

    // manipulation
    if (inStr(actions, TOUCH_ACTION_MANIPULATION)) {
        return TOUCH_ACTION_MANIPULATION;
    }

    return TOUCH_ACTION_AUTO;
}

@@ -395,16 +395,62 @@
 'pan-y';
+%0Avar TOUCH_ACTION_MAP = getTouchActionProps();
 %0A%0A/**%0A *
@@ -1068,16 +1068,43 @@
 nt.style
+ && TOUCH_ACTION_MAP%5Bvalue%5D
 ) %7B%0A    
@@ -2047,145 +2047,8 @@
 ) %7B%0A
-        // not needed with native support for the touchAction property%0A        if (NATIVE_TOUCH_ACTION) %7B%0A            return;%0A        %7D%0A%0A
     
@@ -2400,16 +2400,56 @@
 ON_NONE)
+ && !TOUCH_ACTION_MAP%5BTOUCH_ACTION_NONE%5D
 ;%0A      
@@ -2498,16 +2498,57 @@
 N_PAN_Y)
+ && !TOUCH_ACTION_MAP%5BTOUCH_ACTION_PAN_Y%5D
 ;%0A      
@@ -2597,16 +2597,57 @@
 N_PAN_X)
+ && !TOUCH_ACTION_MAP%5BTOUCH_ACTION_PAN_X%5D
 ;%0A%0A     
@@ -4639,24 +4639,24 @@
 ION;%0A    %7D%0A%0A
-
     return T
@@ -4671,12 +4671,553 @@
 ION_AUTO;%0A%7D%0A
+%0Afunction getTouchActionProps() %7B%0A    if (!NATIVE_TOUCH_ACTION) %7B%0A        return false;%0A    %7D%0A    var touchMap = %7B%7D;%0A    var cssSupports = window.CSS && window.CSS.supports;%0A    %5B'auto', 'manipulation', 'pan-y', 'pan-x', 'pan-x pan-y', 'none'%5D.forEach(function(val) %7B%0A%0A        // If css.supports is not supported but there is native touch-action assume it supports%0A        // all values. This is the case for IE 10 and 11.%0A        touchMap%5Bval%5D = cssSupports ? window.CSS.supports('touch-action', val) : true;%0A    %7D);%0A    return touchMap;%0A%7D%0A

Add support map for specific values of touch-action