interact

JavaScript drag and drop, resizing and multi-touch gestures with inertia and snapping for modern browsers (and also IE9+).

当前为 2025-08-26 提交的版本,查看 最新版本

此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.gf.qytechs.cn/scripts/547397/1649829/interact.js

/**
 * interact.js 1.10.27
 *
 * Copyright (c) 2012-present Taye Adeyemi <[email protected]>
 * Released under the MIT License.
 * https://raw.github.com/taye/interact.js/main/LICENSE
 */

(function (global, factory) {
  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
  typeof define === 'function' && define.amd ? define(factory) :
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.interact = factory());
})(this, (function () { 'use strict';

  function ownKeys(e, r) {
    var t = Object.keys(e);
    if (Object.getOwnPropertySymbols) {
      var o = Object.getOwnPropertySymbols(e);
      r && (o = o.filter(function (r) {
        return Object.getOwnPropertyDescriptor(e, r).enumerable;
      })), t.push.apply(t, o);
    }
    return t;
  }
  function _objectSpread2(e) {
    for (var r = 1; r < arguments.length; r++) {
      var t = null != arguments[r] ? arguments[r] : {};
      r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {
        _defineProperty(e, r, t[r]);
      }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
        Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
      });
    }
    return e;
  }
  function _typeof(o) {
    "@babel/helpers - typeof";

    return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
      return typeof o;
    } : function (o) {
      return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
    }, _typeof(o);
  }
  function _classCallCheck(instance, Constructor) {
    if (!(instance instanceof Constructor)) {
      throw new TypeError("Cannot call a class as a function");
    }
  }
  function _defineProperties(target, props) {
    for (var i = 0; i < props.length; i++) {
      var descriptor = props[i];
      descriptor.enumerable = descriptor.enumerable || false;
      descriptor.configurable = true;
      if ("value" in descriptor) descriptor.writable = true;
      Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor);
    }
  }
  function _createClass(Constructor, protoProps, staticProps) {
    if (protoProps) _defineProperties(Constructor.prototype, protoProps);
    if (staticProps) _defineProperties(Constructor, staticProps);
    Object.defineProperty(Constructor, "prototype", {
      writable: false
    });
    return Constructor;
  }
  function _defineProperty(obj, key, value) {
    key = _toPropertyKey(key);
    if (key in obj) {
      Object.defineProperty(obj, key, {
        value: value,
        enumerable: true,
        configurable: true,
        writable: true
      });
    } else {
      obj[key] = value;
    }
    return obj;
  }
  function _inherits(subClass, superClass) {
    if (typeof superClass !== "function" && superClass !== null) {
      throw new TypeError("Super expression must either be null or a function");
    }
    subClass.prototype = Object.create(superClass && superClass.prototype, {
      constructor: {
        value: subClass,
        writable: true,
        configurable: true
      }
    });
    Object.defineProperty(subClass, "prototype", {
      writable: false
    });
    if (superClass) _setPrototypeOf(subClass, superClass);
  }
  function _getPrototypeOf(o) {
    _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) {
      return o.__proto__ || Object.getPrototypeOf(o);
    };
    return _getPrototypeOf(o);
  }
  function _setPrototypeOf(o, p) {
    _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {
      o.__proto__ = p;
      return o;
    };
    return _setPrototypeOf(o, p);
  }
  function _isNativeReflectConstruct() {
    if (typeof Reflect === "undefined" || !Reflect.construct) return false;
    if (Reflect.construct.sham) return false;
    if (typeof Proxy === "function") return true;
    try {
      Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
      return true;
    } catch (e) {
      return false;
    }
  }
  function _assertThisInitialized(self) {
    if (self === void 0) {
      throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
    }
    return self;
  }
  function _possibleConstructorReturn(self, call) {
    if (call && (typeof call === "object" || typeof call === "function")) {
      return call;
    } else if (call !== void 0) {
      throw new TypeError("Derived constructors may only return object or undefined");
    }
    return _assertThisInitialized(self);
  }
  function _createSuper(Derived) {
    var hasNativeReflectConstruct = _isNativeReflectConstruct();
    return function _createSuperInternal() {
      var Super = _getPrototypeOf(Derived),
        result;
      if (hasNativeReflectConstruct) {
        var NewTarget = _getPrototypeOf(this).constructor;
        result = Reflect.construct(Super, arguments, NewTarget);
      } else {
        result = Super.apply(this, arguments);
      }
      return _possibleConstructorReturn(this, result);
    };
  }
  function _superPropBase(object, property) {
    while (!Object.prototype.hasOwnProperty.call(object, property)) {
      object = _getPrototypeOf(object);
      if (object === null) break;
    }
    return object;
  }
  function _get() {
    if (typeof Reflect !== "undefined" && Reflect.get) {
      _get = Reflect.get.bind();
    } else {
      _get = function _get(target, property, receiver) {
        var base = _superPropBase(target, property);
        if (!base) return;
        var desc = Object.getOwnPropertyDescriptor(base, property);
        if (desc.get) {
          return desc.get.call(arguments.length < 3 ? target : receiver);
        }
        return desc.value;
      };
    }
    return _get.apply(this, arguments);
  }
  function _toPrimitive(input, hint) {
    if (typeof input !== "object" || input === null) return input;
    var prim = input[Symbol.toPrimitive];
    if (prim !== undefined) {
      var res = prim.call(input, hint || "default");
      if (typeof res !== "object") return res;
      throw new TypeError("@@toPrimitive must return a primitive value.");
    }
    return (hint === "string" ? String : Number)(input);
  }
  function _toPropertyKey(arg) {
    var key = _toPrimitive(arg, "string");
    return typeof key === "symbol" ? key : String(key);
  }

  var isWindow = (function (thing) {
    return !!(thing && thing.Window) && thing instanceof thing.Window;
  });

  var realWindow = undefined;
  var win = undefined;
  function init$3(window) {
    // get wrapped window if using Shadow DOM polyfill

    realWindow = window;

    // create a TextNode
    var el = window.document.createTextNode('');

    // check if it's wrapped by a polyfill
    if (el.ownerDocument !== window.document && typeof window.wrap === 'function' && window.wrap(el) === el) {
      // use wrapped window
      window = window.wrap(window);
    }
    win = window;
  }
  if (typeof window !== 'undefined' && !!window) {
    init$3(window);
  }
  function getWindow(node) {
    if (isWindow(node)) {
      return node;
    }
    var rootNode = node.ownerDocument || node;
    return rootNode.defaultView || win.window;
  }

  var window$1 = function window(thing) {
    return thing === win || isWindow(thing);
  };
  var docFrag = function docFrag(thing) {
    return object(thing) && thing.nodeType === 11;
  };
  var object = function object(thing) {
    return !!thing && _typeof(thing) === 'object';
  };
  var func = function func(thing) {
    return typeof thing === 'function';
  };
  var number = function number(thing) {
    return typeof thing === 'number';
  };
  var bool = function bool(thing) {
    return typeof thing === 'boolean';
  };
  var string = function string(thing) {
    return typeof thing === 'string';
  };
  var element = function element(thing) {
    if (!thing || _typeof(thing) !== 'object') {
      return false;
    }
    var _window = getWindow(thing) || win;
    return /object|function/.test(typeof Element === "undefined" ? "undefined" : _typeof(Element)) ? thing instanceof Element || thing instanceof _window.Element : thing.nodeType === 1 && typeof thing.nodeName === 'string';
  };
  var plainObject = function plainObject(thing) {
    return object(thing) && !!thing.constructor && /function Object\b/.test(thing.constructor.toString());
  };
  var array = function array(thing) {
    return object(thing) && typeof thing.length !== 'undefined' && func(thing.splice);
  };
  var is = {
    window: window$1,
    docFrag: docFrag,
    object: object,
    func: func,
    number: number,
    bool: bool,
    string: string,
    element: element,
    plainObject: plainObject,
    array: array
  };

  function install$g(scope) {
    var actions = scope.actions,
      Interactable = scope.Interactable,
      defaults = scope.defaults;
    Interactable.prototype.draggable = drag.draggable;
    actions.map.drag = drag;
    actions.methodDict.drag = 'draggable';
    defaults.actions.drag = drag.defaults;
  }
  function beforeMove(_ref) {
    var interaction = _ref.interaction;
    if (interaction.prepared.name !== 'drag') return;
    var axis = interaction.prepared.axis;
    if (axis === 'x') {
      interaction.coords.cur.page.y = interaction.coords.start.page.y;
      interaction.coords.cur.client.y = interaction.coords.start.client.y;
      interaction.coords.velocity.client.y = 0;
      interaction.coords.velocity.page.y = 0;
    } else if (axis === 'y') {
      interaction.coords.cur.page.x = interaction.coords.start.page.x;
      interaction.coords.cur.client.x = interaction.coords.start.client.x;
      interaction.coords.velocity.client.x = 0;
      interaction.coords.velocity.page.x = 0;
    }
  }
  function move$1(_ref2) {
    var iEvent = _ref2.iEvent,
      interaction = _ref2.interaction;
    if (interaction.prepared.name !== 'drag') return;
    var axis = interaction.prepared.axis;
    if (axis === 'x' || axis === 'y') {
      var opposite = axis === 'x' ? 'y' : 'x';
      iEvent.page[opposite] = interaction.coords.start.page[opposite];
      iEvent.client[opposite] = interaction.coords.start.client[opposite];
      iEvent.delta[opposite] = 0;
    }
  }
  var draggable = function draggable(options) {
    if (is.object(options)) {
      this.options.drag.enabled = options.enabled !== false;
      this.setPerAction('drag', options);
      this.setOnEvents('drag', options);
      if (/^(xy|x|y|start)$/.test(options.lockAxis)) {
        this.options.drag.lockAxis = options.lockAxis;
      }
      if (/^(xy|x|y)$/.test(options.startAxis)) {
        this.options.drag.startAxis = options.startAxis;
      }
      return this;
    }
    if (is.bool(options)) {
      this.options.drag.enabled = options;
      return this;
    }
    return this.options.drag;
  };
  var drag = {
    id: 'actions/drag',
    install: install$g,
    listeners: {
      'interactions:before-action-move': beforeMove,
      'interactions:action-resume': beforeMove,
      // dragmove
      'interactions:action-move': move$1,
      'auto-start:check': function autoStartCheck(arg) {
        var interaction = arg.interaction,
          interactable = arg.interactable,
          buttons = arg.buttons;
        var dragOptions = interactable.options.drag;
        if (!(dragOptions && dragOptions.enabled) ||
        // check mouseButton setting if the pointer is down
        interaction.pointerIsDown && /mouse|pointer/.test(interaction.pointerType) && (buttons & interactable.options.drag.mouseButtons) === 0) {
          return undefined;
        }
        arg.action = {
          name: 'drag',
          axis: dragOptions.lockAxis === 'start' ? dragOptions.startAxis : dragOptions.lockAxis
        };
        return false;
      }
    },
    draggable: draggable,
    beforeMove: beforeMove,
    move: move$1,
    defaults: {
      startAxis: 'xy',
      lockAxis: 'xy'
    },
    getCursor: function getCursor() {
      return 'move';
    },
    filterEventType: function filterEventType(type) {
      return type.search('drag') === 0;
    }
  };
  var drag$1 = drag;

  var domObjects = {
    init: init$2,
    document: null,
    DocumentFragment: null,
    SVGElement: null,
    SVGSVGElement: null,
    SVGElementInstance: null,
    Element: null,
    HTMLElement: null,
    Event: null,
    Touch: null,
    PointerEvent: null
  };
  function blank() {}
  var domObjects$1 = domObjects;
  function init$2(window) {
    var win = window;
    domObjects.document = win.document;
    domObjects.DocumentFragment = win.DocumentFragment || blank;
    domObjects.SVGElement = win.SVGElement || blank;
    domObjects.SVGSVGElement = win.SVGSVGElement || blank;
    domObjects.SVGElementInstance = win.SVGElementInstance || blank;
    domObjects.Element = win.Element || blank;
    domObjects.HTMLElement = win.HTMLElement || domObjects.Element;
    domObjects.Event = win.Event;
    domObjects.Touch = win.Touch || blank;
    domObjects.PointerEvent = win.PointerEvent || win.MSPointerEvent;
  }

  var browser = {
    init: init$1,
    supportsTouch: null,
    supportsPointerEvent: null,
    isIOS7: null,
    isIOS: null,
    isIe9: null,
    isOperaMobile: null,
    prefixedMatchesSelector: null,
    pEventTypes: null,
    wheelEvent: null
  };
  function init$1(window) {
    var Element = domObjects$1.Element;
    var navigator = window.navigator || {};

    // Does the browser support touch input?
    browser.supportsTouch = 'ontouchstart' in window || is.func(window.DocumentTouch) && domObjects$1.document instanceof window.DocumentTouch;

    // Does the browser support PointerEvents
    // https://github.com/taye/interact.js/issues/703#issuecomment-471570492
    browser.supportsPointerEvent = navigator.pointerEnabled !== false && !!domObjects$1.PointerEvent;
    browser.isIOS = /iP(hone|od|ad)/.test(navigator.platform);

    // scrolling doesn't change the result of getClientRects on iOS 7
    browser.isIOS7 = /iP(hone|od|ad)/.test(navigator.platform) && /OS 7[^\d]/.test(navigator.appVersion);
    browser.isIe9 = /MSIE 9/.test(navigator.userAgent);

    // Opera Mobile must be handled differently
    browser.isOperaMobile = navigator.appName === 'Opera' && browser.supportsTouch && /Presto/.test(navigator.userAgent);

    // prefix matchesSelector
    browser.prefixedMatchesSelector = 'matches' in Element.prototype ? 'matches' : 'webkitMatchesSelector' in Element.prototype ? 'webkitMatchesSelector' : 'mozMatchesSelector' in Element.prototype ? 'mozMatchesSelector' : 'oMatchesSelector' in Element.prototype ? 'oMatchesSelector' : 'msMatchesSelector';
    browser.pEventTypes = browser.supportsPointerEvent ? domObjects$1.PointerEvent === window.MSPointerEvent ? {
      up: 'MSPointerUp',
      down: 'MSPointerDown',
      over: 'mouseover',
      out: 'mouseout',
      move: 'MSPointerMove',
      cancel: 'MSPointerCancel'
    } : {
      up: 'pointerup',
      down: 'pointerdown',
      over: 'pointerover',
      out: 'pointerout',
      move: 'pointermove',
      cancel: 'pointercancel'
    } : null;

    // because Webkit and Opera still use 'mousewheel' event type
    browser.wheelEvent = domObjects$1.document && 'onmousewheel' in domObjects$1.document ? 'mousewheel' : 'wheel';
  }
  var browser$1 = browser;

  function nodeContains(parent, child) {
    if (parent.contains) {
      return parent.contains(child);
    }
    while (child) {
      if (child === parent) {
        return true;
      }
      child = child.parentNode;
    }
    return false;
  }
  function closest(element, selector) {
    while (is.element(element)) {
      if (matchesSelector(element, selector)) {
        return element;
      }
      element = parentNode(element);
    }
    return null;
  }
  function parentNode(node) {
    var parent = node.parentNode;
    if (is.docFrag(parent)) {
      // skip past #shado-root fragments
      // tslint:disable-next-line
      while ((parent = parent.host) && is.docFrag(parent)) {
        continue;
      }
      return parent;
    }
    return parent;
  }
  function matchesSelector(element, selector) {
    // remove /deep/ from selectors if shadowDOM polyfill is used
    if (win !== realWindow) {
      selector = selector.replace(/\/deep\//g, ' ');
    }
    return element[browser$1.prefixedMatchesSelector](selector);
  }
  var getParent = function getParent(el) {
    return el.parentNode || el.host;
  };

  // Test for the element that's "above" all other qualifiers
  function indexOfDeepestElement(elements) {
    var deepestNodeParents = [];
    var deepestNodeIndex;
    for (var i = 0; i < elements.length; i++) {
      var currentNode = elements[i];
      var deepestNode = elements[deepestNodeIndex];

      // node may appear in elements array multiple times
      if (!currentNode || i === deepestNodeIndex) {
        continue;
      }
      if (!deepestNode) {
        deepestNodeIndex = i;
        continue;
      }
      var currentNodeParent = getParent(currentNode);
      var deepestNodeParent = getParent(deepestNode);

      // check if the deepest or current are document.documentElement/rootElement
      // - if the current node is, do nothing and continue
      if (currentNodeParent === currentNode.ownerDocument) {
        continue;
      }
      // - if deepest is, update with the current node and continue to next
      else if (deepestNodeParent === currentNode.ownerDocument) {
        deepestNodeIndex = i;
        continue;
      }

      // compare zIndex of siblings
      if (currentNodeParent === deepestNodeParent) {
        if (zIndexIsHigherThan(currentNode, deepestNode)) {
          deepestNodeIndex = i;
        }
        continue;
      }

      // populate the ancestry array for the latest deepest node
      deepestNodeParents = deepestNodeParents.length ? deepestNodeParents : getNodeParents(deepestNode);
      var ancestryStart = void 0;

      // if the deepest node is an HTMLElement and the current node is a non root svg element
      if (deepestNode instanceof domObjects$1.HTMLElement && currentNode instanceof domObjects$1.SVGElement && !(currentNode instanceof domObjects$1.SVGSVGElement)) {
        // TODO: is this check necessary? Was this for HTML elements embedded in SVG?
        if (currentNode === deepestNodeParent) {
          continue;
        }
        ancestryStart = currentNode.ownerSVGElement;
      } else {
        ancestryStart = currentNode;
      }
      var currentNodeParents = getNodeParents(ancestryStart, deepestNode.ownerDocument);
      var commonIndex = 0;

      // get (position of closest common ancestor) + 1
      while (currentNodeParents[commonIndex] && currentNodeParents[commonIndex] === deepestNodeParents[commonIndex]) {
        commonIndex++;
      }
      var parents = [currentNodeParents[commonIndex - 1], currentNodeParents[commonIndex], deepestNodeParents[commonIndex]];
      if (parents[0]) {
        var child = parents[0].lastChild;
        while (child) {
          if (child === parents[1]) {
            deepestNodeIndex = i;
            deepestNodeParents = currentNodeParents;
            break;
          } else if (child === parents[2]) {
            break;
          }
          child = child.previousSibling;
        }
      }
    }
    return deepestNodeIndex;
  }
  function getNodeParents(node, limit) {
    var parents = [];
    var parent = node;
    var parentParent;
    while ((parentParent = getParent(parent)) && parent !== limit && parentParent !== parent.ownerDocument) {
      parents.unshift(parent);
      parent = parentParent;
    }
    return parents;
  }
  function zIndexIsHigherThan(higherNode, lowerNode) {
    var higherIndex = parseInt(getWindow(higherNode).getComputedStyle(higherNode).zIndex, 10) || 0;
    var lowerIndex = parseInt(getWindow(lowerNode).getComputedStyle(lowerNode).zIndex, 10) || 0;
    return higherIndex >= lowerIndex;
  }
  function matchesUpTo(element, selector, limit) {
    while (is.element(element)) {
      if (matchesSelector(element, selector)) {
        return true;
      }
      element = parentNode(element);
      if (element === limit) {
        return matchesSelector(element, selector);
      }
    }
    return false;
  }
  function getActualElement(element) {
    return element.correspondingUseElement || element;
  }
  function getScrollXY(relevantWindow) {
    relevantWindow = relevantWindow || win;
    return {
      x: relevantWindow.scrollX || relevantWindow.document.documentElement.scrollLeft,
      y: relevantWindow.scrollY || relevantWindow.document.documentElement.scrollTop
    };
  }
  function getElementClientRect(element) {
    var clientRect = element instanceof domObjects$1.SVGElement ? element.getBoundingClientRect() : element.getClientRects()[0];
    return clientRect && {
      left: clientRect.left,
      right: clientRect.right,
      top: clientRect.top,
      bottom: clientRect.bottom,
      width: clientRect.width || clientRect.right - clientRect.left,
      height: clientRect.height || clientRect.bottom - clientRect.top
    };
  }
  function getElementRect(element) {
    var clientRect = getElementClientRect(element);
    if (!browser$1.isIOS7 && clientRect) {
      var scroll = getScrollXY(getWindow(element));
      clientRect.left += scroll.x;
      clientRect.right += scroll.x;
      clientRect.top += scroll.y;
      clientRect.bottom += scroll.y;
    }
    return clientRect;
  }
  function getPath(node) {
    var path = [];
    while (node) {
      path.push(node);
      node = parentNode(node);
    }
    return path;
  }
  function trySelector(value) {
    if (!is.string(value)) {
      return false;
    }

    // an exception will be raised if it is invalid
    domObjects$1.document.querySelector(value);
    return true;
  }

  function extend(dest, source) {
    for (var prop in source) {
      dest[prop] = source[prop];
    }
    var ret = dest;
    return ret;
  }

  function getStringOptionResult(value, target, element) {
    if (value === 'parent') {
      return parentNode(element);
    }
    if (value === 'self') {
      return target.getRect(element);
    }
    return closest(element, value);
  }
  function resolveRectLike(value, target, element, functionArgs) {
    var returnValue = value;
    if (is.string(returnValue)) {
      returnValue = getStringOptionResult(returnValue, target, element);
    } else if (is.func(returnValue)) {
      returnValue = returnValue.apply(void 0, functionArgs);
    }
    if (is.element(returnValue)) {
      returnValue = getElementRect(returnValue);
    }
    return returnValue;
  }
  function rectToXY(rect) {
    return rect && {
      x: 'x' in rect ? rect.x : rect.left,
      y: 'y' in rect ? rect.y : rect.top
    };
  }
  function xywhToTlbr(rect) {
    if (rect && !('left' in rect && 'top' in rect)) {
      rect = extend({}, rect);
      rect.left = rect.x || 0;
      rect.top = rect.y || 0;
      rect.right = rect.right || rect.left + rect.width;
      rect.bottom = rect.bottom || rect.top + rect.height;
    }
    return rect;
  }
  function tlbrToXywh(rect) {
    if (rect && !('x' in rect && 'y' in rect)) {
      rect = extend({}, rect);
      rect.x = rect.left || 0;
      rect.y = rect.top || 0;
      rect.width = rect.width || (rect.right || 0) - rect.x;
      rect.height = rect.height || (rect.bottom || 0) - rect.y;
    }
    return rect;
  }
  function addEdges(edges, rect, delta) {
    if (edges.left) {
      rect.left += delta.x;
    }
    if (edges.right) {
      rect.right += delta.x;
    }
    if (edges.top) {
      rect.top += delta.y;
    }
    if (edges.bottom) {
      rect.bottom += delta.y;
    }
    rect.width = rect.right - rect.left;
    rect.height = rect.bottom - rect.top;
  }

  function getOriginXY(target, element, actionName) {
    var actionOptions = actionName && target.options[actionName];
    var actionOrigin = actionOptions && actionOptions.origin;
    var origin = actionOrigin || target.options.origin;
    var originRect = resolveRectLike(origin, target, element, [target && element]);
    return rectToXY(originRect) || {
      x: 0,
      y: 0
    };
  }

  function normalize(type, listeners) {
    var filter = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : function (_typeOrPrefix) {
      return true;
    };
    var result = arguments.length > 3 ? arguments[3] : undefined;
    result = result || {};
    if (is.string(type) && type.search(' ') !== -1) {
      type = split(type);
    }
    if (is.array(type)) {
      type.forEach(function (t) {
        return normalize(t, listeners, filter, result);
      });
      return result;
    }

    // before:  type = [{ drag: () => {} }], listeners = undefined
    // after:   type = ''                  , listeners = [{ drag: () => {} }]
    if (is.object(type)) {
      listeners = type;
      type = '';
    }
    if (is.func(listeners) && filter(type)) {
      result[type] = result[type] || [];
      result[type].push(listeners);
    } else if (is.array(listeners)) {
      for (var _i2 = 0, _listeners2 = listeners; _i2 < _listeners2.length; _i2++) {
        var l = _listeners2[_i2];
        normalize(type, l, filter, result);
      }
    } else if (is.object(listeners)) {
      for (var prefix in listeners) {
        var combinedTypes = split(prefix).map(function (p) {
          return "".concat(type).concat(p);
        });
        normalize(combinedTypes, listeners[prefix], filter, result);
      }
    }
    return result;
  }
  function split(type) {
    return type.trim().split(/ +/);
  }

  var hypot = (function (x, y) {
    return Math.sqrt(x * x + y * y);
  });

  var VENDOR_PREFIXES = ['webkit', 'moz'];
  function pointerExtend(dest, source) {
    dest.__set || (dest.__set = {});
    var _loop = function _loop(prop) {
      // skip deprecated prefixed properties
      if (VENDOR_PREFIXES.some(function (prefix) {
        return prop.indexOf(prefix) === 0;
      })) return 1; // continue
      if (typeof dest[prop] !== 'function' && prop !== '__set') {
        Object.defineProperty(dest, prop, {
          get: function get() {
            if (prop in dest.__set) return dest.__set[prop];
            return dest.__set[prop] = source[prop];
          },
          set: function set(value) {
            dest.__set[prop] = value;
          },
          configurable: true
        });
      }
    };
    for (var prop in source) {
      if (_loop(prop)) continue;
    }
    return dest;
  }

  function copyCoords(dest, src) {
    dest.page = dest.page || {};
    dest.page.x = src.page.x;
    dest.page.y = src.page.y;
    dest.client = dest.client || {};
    dest.client.x = src.client.x;
    dest.client.y = src.client.y;
    dest.timeStamp = src.timeStamp;
  }
  function setCoordDeltas(targetObj, prev, cur) {
    targetObj.page.x = cur.page.x - prev.page.x;
    targetObj.page.y = cur.page.y - prev.page.y;
    targetObj.client.x = cur.client.x - prev.client.x;
    targetObj.client.y = cur.client.y - prev.client.y;
    targetObj.timeStamp = cur.timeStamp - prev.timeStamp;
  }
  function setCoordVelocity(targetObj, delta) {
    var dt = Math.max(delta.timeStamp / 1000, 0.001);
    targetObj.page.x = delta.page.x / dt;
    targetObj.page.y = delta.page.y / dt;
    targetObj.client.x = delta.client.x / dt;
    targetObj.client.y = delta.client.y / dt;
    targetObj.timeStamp = dt;
  }
  function setZeroCoords(targetObj) {
    targetObj.page.x = 0;
    targetObj.page.y = 0;
    targetObj.client.x = 0;
    targetObj.client.y = 0;
  }
  function isNativePointer(pointer) {
    return pointer instanceof domObjects$1.Event || pointer instanceof domObjects$1.Touch;
  }

  // Get specified X/Y coords for mouse or event.touches[0]
  function getXY(type, pointer, xy) {
    xy = xy || {};
    type = type || 'page';
    xy.x = pointer[type + 'X'];
    xy.y = pointer[type + 'Y'];
    return xy;
  }
  function getPageXY(pointer, page) {
    page = page || {
      x: 0,
      y: 0
    };

    // Opera Mobile handles the viewport and scrolling oddly
    if (browser$1.isOperaMobile && isNativePointer(pointer)) {
      getXY('screen', pointer, page);
      page.x += window.scrollX;
      page.y += window.scrollY;
    } else {
      getXY('page', pointer, page);
    }
    return page;
  }
  function getClientXY(pointer, client) {
    client = client || {};
    if (browser$1.isOperaMobile && isNativePointer(pointer)) {
      // Opera Mobile handles the viewport and scrolling oddly
      getXY('screen', pointer, client);
    } else {
      getXY('client', pointer, client);
    }
    return client;
  }
  function getPointerId(pointer) {
    return is.number(pointer.pointerId) ? pointer.pointerId : pointer.identifier;
  }
  function setCoords(dest, pointers, timeStamp) {
    var pointer = pointers.length > 1 ? pointerAverage(pointers) : pointers[0];
    getPageXY(pointer, dest.page);
    getClientXY(pointer, dest.client);
    dest.timeStamp = timeStamp;
  }
  function getTouchPair(event) {
    var touches = [];

    // array of touches is supplied
    if (is.array(event)) {
      touches[0] = event[0];
      touches[1] = event[1];
    }
    // an event
    else {
      if (event.type === 'touchend') {
        if (event.touches.length === 1) {
          touches[0] = event.touches[0];
          touches[1] = event.changedTouches[0];
        } else if (event.touches.length === 0) {
          touches[0] = event.changedTouches[0];
          touches[1] = event.changedTouches[1];
        }
      } else {
        touches[0] = event.touches[0];
        touches[1] = event.touches[1];
      }
    }
    return touches;
  }
  function pointerAverage(pointers) {
    var average = {
      pageX: 0,
      pageY: 0,
      clientX: 0,
      clientY: 0,
      screenX: 0,
      screenY: 0
    };
    for (var _i2 = 0; _i2 < pointers.length; _i2++) {
      var pointer = pointers[_i2];
      for (var prop in average) {
        average[prop] += pointer[prop];
      }
    }
    for (var _prop in average) {
      average[_prop] /= pointers.length;
    }
    return average;
  }
  function touchBBox(event) {
    if (!event.length) {
      return null;
    }
    var touches = getTouchPair(event);
    var minX = Math.min(touches[0].pageX, touches[1].pageX);
    var minY = Math.min(touches[0].pageY, touches[1].pageY);
    var maxX = Math.max(touches[0].pageX, touches[1].pageX);
    var maxY = Math.max(touches[0].pageY, touches[1].pageY);
    return {
      x: minX,
      y: minY,
      left: minX,
      top: minY,
      right: maxX,
      bottom: maxY,
      width: maxX - minX,
      height: maxY - minY
    };
  }
  function touchDistance(event, deltaSource) {
    var sourceX = deltaSource + 'X';
    var sourceY = deltaSource + 'Y';
    var touches = getTouchPair(event);
    var dx = touches[0][sourceX] - touches[1][sourceX];
    var dy = touches[0][sourceY] - touches[1][sourceY];
    return hypot(dx, dy);
  }
  function touchAngle(event, deltaSource) {
    var sourceX = deltaSource + 'X';
    var sourceY = deltaSource + 'Y';
    var touches = getTouchPair(event);
    var dx = touches[1][sourceX] - touches[0][sourceX];
    var dy = touches[1][sourceY] - touches[0][sourceY];
    var angle = 180 * Math.atan2(dy, dx) / Math.PI;
    return angle;
  }
  function getPointerType(pointer) {
    return is.string(pointer.pointerType) ? pointer.pointerType : is.number(pointer.pointerType) ? [undefined, undefined, 'touch', 'pen', 'mouse'][pointer.pointerType] :
    // if the PointerEvent API isn't available, then the "pointer" must
    // be either a MouseEvent, TouchEvent, or Touch object
    /touch/.test(pointer.type || '') || pointer instanceof domObjects$1.Touch ? 'touch' : 'mouse';
  }

  // [ event.target, event.currentTarget ]
  function getEventTargets(event) {
    var path = is.func(event.composedPath) ? event.composedPath() : event.path;
    return [getActualElement(path ? path[0] : event.target), getActualElement(event.currentTarget)];
  }
  function newCoords() {
    return {
      page: {
        x: 0,
        y: 0
      },
      client: {
        x: 0,
        y: 0
      },
      timeStamp: 0
    };
  }
  function coordsToEvent(coords) {
    var event = {
      coords: coords,
      get page() {
        return this.coords.page;
      },
      get client() {
        return this.coords.client;
      },
      get timeStamp() {
        return this.coords.timeStamp;
      },
      get pageX() {
        return this.coords.page.x;
      },
      get pageY() {
        return this.coords.page.y;
      },
      get clientX() {
        return this.coords.client.x;
      },
      get clientY() {
        return this.coords.client.y;
      },
      get pointerId() {
        return this.coords.pointerId;
      },
      get target() {
        return this.coords.target;
      },
      get type() {
        return this.coords.type;
      },
      get pointerType() {
        return this.coords.pointerType;
      },
      get buttons() {
        return this.coords.buttons;
      },
      preventDefault: function preventDefault() {}
    };
    return event;
  }

  var BaseEvent = /*#__PURE__*/function () {
    function BaseEvent(interaction) {
      _classCallCheck(this, BaseEvent);
      /** @internal */
      this.immediatePropagationStopped = false;
      this.propagationStopped = false;
      this._interaction = interaction;
    }
    _createClass(BaseEvent, [{
      key: "preventDefault",
      value: function preventDefault() {}

      /**
       * Don't call any other listeners (even on the current target)
       */
    }, {
      key: "stopPropagation",
      value: function stopPropagation() {
        this.propagationStopped = true;
      }

      /**
       * Don't call listeners on the remaining targets
       */
    }, {
      key: "stopImmediatePropagation",
      value: function stopImmediatePropagation() {
        this.immediatePropagationStopped = this.propagationStopped = true;
      }
    }]);
    return BaseEvent;
  }();

  // defined outside of class definition to avoid assignment of undefined during
  // construction

  // getters and setters defined here to support typescript 3.6 and below which
  // don't support getter and setters in .d.ts files
  Object.defineProperty(BaseEvent.prototype, 'interaction', {
    get: function get() {
      return this._interaction._proxy;
    },
    set: function set() {}
  });

  var remove = function remove(array, target) {
    return array.splice(array.indexOf(target), 1);
  };
  var merge = function merge(target, source) {
    for (var _i2 = 0; _i2 < source.length; _i2++) {
      var item = source[_i2];
      target.push(item);
    }
    return target;
  };
  var from = function from(source) {
    return merge([], source);
  };
  var findIndex = function findIndex(array, func) {
    for (var i = 0; i < array.length; i++) {
      if (func(array[i], i, array)) {
        return i;
      }
    }
    return -1;
  };
  var find = function find(array, func) {
    return array[findIndex(array, func)];
  };

  var DropEvent = /*#__PURE__*/function (_BaseEvent) {
    _inherits(DropEvent, _BaseEvent);
    var _super = _createSuper(DropEvent);
    /**
     * Class of events fired on dropzones during drags with acceptable targets.
     */
    function DropEvent(dropState, dragEvent, type) {
      var _this;
      _classCallCheck(this, DropEvent);
      _this = _super.call(this, dragEvent._interaction);
      _this.dropzone = void 0;
      _this.dragEvent = void 0;
      _this.relatedTarget = void 0;
      _this.draggable = void 0;
      _this.propagationStopped = false;
      _this.immediatePropagationStopped = false;
      var _ref = type === 'dragleave' ? dropState.prev : dropState.cur,
        element = _ref.element,
        dropzone = _ref.dropzone;
      _this.type = type;
      _this.target = element;
      _this.currentTarget = element;
      _this.dropzone = dropzone;
      _this.dragEvent = dragEvent;
      _this.relatedTarget = dragEvent.target;
      _this.draggable = dragEvent.interactable;
      _this.timeStamp = dragEvent.timeStamp;
      return _this;
    }

    /**
     * If this is a `dropactivate` event, the dropzone element will be
     * deactivated.
     *
     * If this is a `dragmove` or `dragenter`, a `dragleave` will be fired on the
     * dropzone element and more.
     */
    _createClass(DropEvent, [{
      key: "reject",
      value: function reject() {
        var _this2 = this;
        var dropState = this._interaction.dropState;
        if (this.type !== 'dropactivate' && (!this.dropzone || dropState.cur.dropzone !== this.dropzone || dropState.cur.element !== this.target)) {
          return;
        }
        dropState.prev.dropzone = this.dropzone;
        dropState.prev.element = this.target;
        dropState.rejected = true;
        dropState.events.enter = null;
        this.stopImmediatePropagation();
        if (this.type === 'dropactivate') {
          var activeDrops = dropState.activeDrops;
          var index = findIndex(activeDrops, function (_ref2) {
            var dropzone = _ref2.dropzone,
              element = _ref2.element;
            return dropzone === _this2.dropzone && element === _this2.target;
          });
          dropState.activeDrops.splice(index, 1);
          var deactivateEvent = new DropEvent(dropState, this.dragEvent, 'dropdeactivate');
          deactivateEvent.dropzone = this.dropzone;
          deactivateEvent.target = this.target;
          this.dropzone.fire(deactivateEvent);
        } else {
          this.dropzone.fire(new DropEvent(dropState, this.dragEvent, 'dragleave'));
        }
      }
    }, {
      key: "preventDefault",
      value: function preventDefault() {}
    }, {
      key: "stopPropagation",
      value: function stopPropagation() {
        this.propagationStopped = true;
      }
    }, {
      key: "stopImmediatePropagation",
      value: function stopImmediatePropagation() {
        this.immediatePropagationStopped = this.propagationStopped = true;
      }
    }]);
    return DropEvent;
  }(BaseEvent);

  function install$f(scope) {
    var actions = scope.actions,
      interact = scope.interactStatic,
      Interactable = scope.Interactable,
      defaults = scope.defaults;
    scope.usePlugin(drag$1);
    Interactable.prototype.dropzone = function (options) {
      return dropzoneMethod(this, options);
    };
    Interactable.prototype.dropCheck = function (dragEvent, event, draggable, draggableElement, dropElement, rect) {
      return dropCheckMethod(this, dragEvent, event, draggable, draggableElement, dropElement, rect);
    };
    interact.dynamicDrop = function (newValue) {
      if (is.bool(newValue)) {
        // if (dragging && scope.dynamicDrop !== newValue && !newValue) {
        //  calcRects(dropzones)
        // }

        scope.dynamicDrop = newValue;
        return interact;
      }
      return scope.dynamicDrop;
    };
    extend(actions.phaselessTypes, {
      dragenter: true,
      dragleave: true,
      dropactivate: true,
      dropdeactivate: true,
      dropmove: true,
      drop: true
    });
    actions.methodDict.drop = 'dropzone';
    scope.dynamicDrop = false;
    defaults.actions.drop = drop.defaults;
  }
  function collectDropzones(_ref, draggableElement) {
    var interactables = _ref.interactables;
    var drops = [];

    // collect all dropzones and their elements which qualify for a drop
    for (var _i2 = 0, _interactables$list2 = interactables.list; _i2 < _interactables$list2.length; _i2++) {
      var _dropzone = _interactables$list2[_i2];
      if (!_dropzone.options.drop.enabled) {
        continue;
      }
      var accept = _dropzone.options.drop.accept;

      // test the draggable draggableElement against the dropzone's accept setting
      if (is.element(accept) && accept !== draggableElement || is.string(accept) && !matchesSelector(draggableElement, accept) || is.func(accept) && !accept({
        dropzone: _dropzone,
        draggableElement: draggableElement
      })) {
        continue;
      }
      for (var _i4 = 0, _dropzone$getAllEleme2 = _dropzone.getAllElements(); _i4 < _dropzone$getAllEleme2.length; _i4++) {
        var dropzoneElement = _dropzone$getAllEleme2[_i4];
        if (dropzoneElement !== draggableElement) {
          drops.push({
            dropzone: _dropzone,
            element: dropzoneElement,
            rect: _dropzone.getRect(dropzoneElement)
          });
        }
      }
    }
    return drops;
  }
  function fireActivationEvents(activeDrops, event) {
    // loop through all active dropzones and trigger event
    for (var _i6 = 0, _activeDrops$slice2 = activeDrops.slice(); _i6 < _activeDrops$slice2.length; _i6++) {
      var _activeDrops$slice2$_ = _activeDrops$slice2[_i6],
        _dropzone2 = _activeDrops$slice2$_.dropzone,
        element = _activeDrops$slice2$_.element;
      event.dropzone = _dropzone2;

      // set current element as event target
      event.target = element;
      _dropzone2.fire(event);
      event.propagationStopped = event.immediatePropagationStopped = false;
    }
  }

  // return a new array of possible drops. getActiveDrops should always be
  // called when a drag has just started or a drag event happens while
  // dynamicDrop is true
  function getActiveDrops(scope, dragElement) {
    // get dropzones and their elements that could receive the draggable
    var activeDrops = collectDropzones(scope, dragElement);
    for (var _i8 = 0; _i8 < activeDrops.length; _i8++) {
      var activeDrop = activeDrops[_i8];
      activeDrop.rect = activeDrop.dropzone.getRect(activeDrop.element);
    }
    return activeDrops;
  }
  function getDrop(_ref2, dragEvent, pointerEvent) {
    var dropState = _ref2.dropState,
      draggable = _ref2.interactable,
      dragElement = _ref2.element;
    var validDrops = [];

    // collect all dropzones and their elements which qualify for a drop
    for (var _i10 = 0, _dropState$activeDrop2 = dropState.activeDrops; _i10 < _dropState$activeDrop2.length; _i10++) {
      var _dropState$activeDrop3 = _dropState$activeDrop2[_i10],
        _dropzone3 = _dropState$activeDrop3.dropzone,
        dropzoneElement = _dropState$activeDrop3.element,
        _rect = _dropState$activeDrop3.rect;
      var isValid = _dropzone3.dropCheck(dragEvent, pointerEvent, draggable, dragElement, dropzoneElement, _rect);
      validDrops.push(isValid ? dropzoneElement : null);
    } // get the most appropriate dropzone based on DOM depth and order
    var dropIndex = indexOfDeepestElement(validDrops);
    return dropState.activeDrops[dropIndex] || null;
  }
  function getDropEvents(interaction, _pointerEvent, dragEvent) {
    var dropState = interaction.dropState;
    var dropEvents = {
      enter: null,
      leave: null,
      activate: null,
      deactivate: null,
      move: null,
      drop: null
    };
    if (dragEvent.type === 'dragstart') {
      dropEvents.activate = new DropEvent(dropState, dragEvent, 'dropactivate');
      dropEvents.activate.target = null;
      dropEvents.activate.dropzone = null;
    }
    if (dragEvent.type === 'dragend') {
      dropEvents.deactivate = new DropEvent(dropState, dragEvent, 'dropdeactivate');
      dropEvents.deactivate.target = null;
      dropEvents.deactivate.dropzone = null;
    }
    if (dropState.rejected) {
      return dropEvents;
    }
    if (dropState.cur.element !== dropState.prev.element) {
      // if there was a previous dropzone, create a dragleave event
      if (dropState.prev.dropzone) {
        dropEvents.leave = new DropEvent(dropState, dragEvent, 'dragleave');
        dragEvent.dragLeave = dropEvents.leave.target = dropState.prev.element;
        dragEvent.prevDropzone = dropEvents.leave.dropzone = dropState.prev.dropzone;
      }
      // if dropzone is not null, create a dragenter event
      if (dropState.cur.dropzone) {
        dropEvents.enter = new DropEvent(dropState, dragEvent, 'dragenter');
        dragEvent.dragEnter = dropState.cur.element;
        dragEvent.dropzone = dropState.cur.dropzone;
      }
    }
    if (dragEvent.type === 'dragend' && dropState.cur.dropzone) {
      dropEvents.drop = new DropEvent(dropState, dragEvent, 'drop');
      dragEvent.dropzone = dropState.cur.dropzone;
      dragEvent.relatedTarget = dropState.cur.element;
    }
    if (dragEvent.type === 'dragmove' && dropState.cur.dropzone) {
      dropEvents.move = new DropEvent(dropState, dragEvent, 'dropmove');
      dragEvent.dropzone = dropState.cur.dropzone;
    }
    return dropEvents;
  }
  function fireDropEvents(interaction, events) {
    var dropState = interaction.dropState;
    var activeDrops = dropState.activeDrops,
      cur = dropState.cur,
      prev = dropState.prev;
    if (events.leave) {
      prev.dropzone.fire(events.leave);
    }
    if (events.enter) {
      cur.dropzone.fire(events.enter);
    }
    if (events.move) {
      cur.dropzone.fire(events.move);
    }
    if (events.drop) {
      cur.dropzone.fire(events.drop);
    }
    if (events.deactivate) {
      fireActivationEvents(activeDrops, events.deactivate);
    }
    dropState.prev.dropzone = cur.dropzone;
    dropState.prev.element = cur.element;
  }
  function onEventCreated(_ref3, scope) {
    var interaction = _ref3.interaction,
      iEvent = _ref3.iEvent,
      event = _ref3.event;
    if (iEvent.type !== 'dragmove' && iEvent.type !== 'dragend') {
      return;
    }
    var dropState = interaction.dropState;
    if (scope.dynamicDrop) {
      dropState.activeDrops = getActiveDrops(scope, interaction.element);
    }
    var dragEvent = iEvent;
    var dropResult = getDrop(interaction, dragEvent, event);

    // update rejected status
    dropState.rejected = dropState.rejected && !!dropResult && dropResult.dropzone === dropState.cur.dropzone && dropResult.element === dropState.cur.element;
    dropState.cur.dropzone = dropResult && dropResult.dropzone;
    dropState.cur.element = dropResult && dropResult.element;
    dropState.events = getDropEvents(interaction, event, dragEvent);
  }
  function dropzoneMethod(interactable, options) {
    if (is.object(options)) {
      interactable.options.drop.enabled = options.enabled !== false;
      if (options.listeners) {
        var normalized = normalize(options.listeners);
        // rename 'drop' to '' as it will be prefixed with 'drop'
        var corrected = Object.keys(normalized).reduce(function (acc, type) {
          var correctedType = /^(enter|leave)/.test(type) ? "drag".concat(type) : /^(activate|deactivate|move)/.test(type) ? "drop".concat(type) : type;
          acc[correctedType] = normalized[type];
          return acc;
        }, {});
        var prevListeners = interactable.options.drop.listeners;
        prevListeners && interactable.off(prevListeners);
        interactable.on(corrected);
        interactable.options.drop.listeners = corrected;
      }
      if (is.func(options.ondrop)) {
        interactable.on('drop', options.ondrop);
      }
      if (is.func(options.ondropactivate)) {
        interactable.on('dropactivate', options.ondropactivate);
      }
      if (is.func(options.ondropdeactivate)) {
        interactable.on('dropdeactivate', options.ondropdeactivate);
      }
      if (is.func(options.ondragenter)) {
        interactable.on('dragenter', options.ondragenter);
      }
      if (is.func(options.ondragleave)) {
        interactable.on('dragleave', options.ondragleave);
      }
      if (is.func(options.ondropmove)) {
        interactable.on('dropmove', options.ondropmove);
      }
      if (/^(pointer|center)$/.test(options.overlap)) {
        interactable.options.drop.overlap = options.overlap;
      } else if (is.number(options.overlap)) {
        interactable.options.drop.overlap = Math.max(Math.min(1, options.overlap), 0);
      }
      if ('accept' in options) {
        interactable.options.drop.accept = options.accept;
      }
      if ('checker' in options) {
        interactable.options.drop.checker = options.checker;
      }
      return interactable;
    }
    if (is.bool(options)) {
      interactable.options.drop.enabled = options;
      return interactable;
    }
    return interactable.options.drop;
  }
  function dropCheckMethod(interactable, dragEvent, event, draggable, draggableElement, dropElement, rect) {
    var dropped = false;

    // if the dropzone has no rect (eg. display: none)
    // call the custom dropChecker or just return false
    if (!(rect = rect || interactable.getRect(dropElement))) {
      return interactable.options.drop.checker ? interactable.options.drop.checker(dragEvent, event, dropped, interactable, dropElement, draggable, draggableElement) : false;
    }
    var dropOverlap = interactable.options.drop.overlap;
    if (dropOverlap === 'pointer') {
      var origin = getOriginXY(draggable, draggableElement, 'drag');
      var page = getPageXY(dragEvent);
      page.x += origin.x;
      page.y += origin.y;
      var horizontal = page.x > rect.left && page.x < rect.right;
      var vertical = page.y > rect.top && page.y < rect.bottom;
      dropped = horizontal && vertical;
    }
    var dragRect = draggable.getRect(draggableElement);
    if (dragRect && dropOverlap === 'center') {
      var cx = dragRect.left + dragRect.width / 2;
      var cy = dragRect.top + dragRect.height / 2;
      dropped = cx >= rect.left && cx <= rect.right && cy >= rect.top && cy <= rect.bottom;
    }
    if (dragRect && is.number(dropOverlap)) {
      var overlapArea = Math.max(0, Math.min(rect.right, dragRect.right) - Math.max(rect.left, dragRect.left)) * Math.max(0, Math.min(rect.bottom, dragRect.bottom) - Math.max(rect.top, dragRect.top));
      var overlapRatio = overlapArea / (dragRect.width * dragRect.height);
      dropped = overlapRatio >= dropOverlap;
    }
    if (interactable.options.drop.checker) {
      dropped = interactable.options.drop.checker(dragEvent, event, dropped, interactable, dropElement, draggable, draggableElement);
    }
    return dropped;
  }
  var drop = {
    id: 'actions/drop',
    install: install$f,
    listeners: {
      'interactions:before-action-start': function interactionsBeforeActionStart(_ref4) {
        var interaction = _ref4.interaction;
        if (interaction.prepared.name !== 'drag') {
          return;
        }
        interaction.dropState = {
          cur: {
            dropzone: null,
            element: null
          },
          prev: {
            dropzone: null,
            element: null
          },
          rejected: null,
          events: null,
          activeDrops: []
        };
      },
      'interactions:after-action-start': function interactionsAfterActionStart(_ref5, scope) {
        var interaction = _ref5.interaction,
          event = _ref5.event,
          dragEvent = _ref5.iEvent;
        if (interaction.prepared.name !== 'drag') {
          return;
        }
        var dropState = interaction.dropState;

        // reset active dropzones
        dropState.activeDrops = [];
        dropState.events = {};
        dropState.activeDrops = getActiveDrops(scope, interaction.element);
        dropState.events = getDropEvents(interaction, event, dragEvent);
        if (dropState.events.activate) {
          fireActivationEvents(dropState.activeDrops, dropState.events.activate);
          scope.fire('actions/drop:start', {
            interaction: interaction,
            dragEvent: dragEvent
          });
        }
      },
      'interactions:action-move': onEventCreated,
      'interactions:after-action-move': function interactionsAfterActionMove(_ref6, scope) {
        var interaction = _ref6.interaction,
          dragEvent = _ref6.iEvent;
        if (interaction.prepared.name !== 'drag') {
          return;
        }
        var dropState = interaction.dropState;
        fireDropEvents(interaction, dropState.events);
        scope.fire('actions/drop:move', {
          interaction: interaction,
          dragEvent: dragEvent
        });
        dropState.events = {};
      },
      'interactions:action-end': function interactionsActionEnd(arg, scope) {
        if (arg.interaction.prepared.name !== 'drag') {
          return;
        }
        var interaction = arg.interaction,
          dragEvent = arg.iEvent;
        onEventCreated(arg, scope);
        fireDropEvents(interaction, interaction.dropState.events);
        scope.fire('actions/drop:end', {
          interaction: interaction,
          dragEvent: dragEvent
        });
      },
      'interactions:stop': function interactionsStop(_ref7) {
        var interaction = _ref7.interaction;
        if (interaction.prepared.name !== 'drag') {
          return;
        }
        var dropState = interaction.dropState;
        if (dropState) {
          dropState.activeDrops = null;
          dropState.events = null;
          dropState.cur.dropzone = null;
          dropState.cur.element = null;
          dropState.prev.dropzone = null;
          dropState.prev.element = null;
          dropState.rejected = false;
        }
      }
    },
    getActiveDrops: getActiveDrops,
    getDrop: getDrop,
    getDropEvents: getDropEvents,
    fireDropEvents: fireDropEvents,
    filterEventType: function filterEventType(type) {
      return type.search('drag') === 0 || type.search('drop') === 0;
    },
    defaults: {
      enabled: false,
      accept: null,
      overlap: 'pointer'
    }
  };
  var drop$1 = drop;

  function install$e(scope) {
    var actions = scope.actions,
      Interactable = scope.Interactable,
      defaults = scope.defaults;
    Interactable.prototype.gesturable = function (options) {
      if (is.object(options)) {
        this.options.gesture.enabled = options.enabled !== false;
        this.setPerAction('gesture', options);
        this.setOnEvents('gesture', options);
        return this;
      }
      if (is.bool(options)) {
        this.options.gesture.enabled = options;
        return this;
      }
      return this.options.gesture;
    };
    actions.map.gesture = gesture;
    actions.methodDict.gesture = 'gesturable';
    defaults.actions.gesture = gesture.defaults;
  }
  function updateGestureProps(_ref) {
    var interaction = _ref.interaction,
      iEvent = _ref.iEvent,
      phase = _ref.phase;
    if (interaction.prepared.name !== 'gesture') return;
    var pointers = interaction.pointers.map(function (p) {
      return p.pointer;
    });
    var starting = phase === 'start';
    var ending = phase === 'end';
    var deltaSource = interaction.interactable.options.deltaSource;
    iEvent.touches = [pointers[0], pointers[1]];
    if (starting) {
      iEvent.distance = touchDistance(pointers, deltaSource);
      iEvent.box = touchBBox(pointers);
      iEvent.scale = 1;
      iEvent.ds = 0;
      iEvent.angle = touchAngle(pointers, deltaSource);
      iEvent.da = 0;
      interaction.gesture.startDistance = iEvent.distance;
      interaction.gesture.startAngle = iEvent.angle;
    } else if (ending || interaction.pointers.length < 2) {
      var prevEvent = interaction.prevEvent;
      iEvent.distance = prevEvent.distance;
      iEvent.box = prevEvent.box;
      iEvent.scale = prevEvent.scale;
      iEvent.ds = 0;
      iEvent.angle = prevEvent.angle;
      iEvent.da = 0;
    } else {
      iEvent.distance = touchDistance(pointers, deltaSource);
      iEvent.box = touchBBox(pointers);
      iEvent.scale = iEvent.distance / interaction.gesture.startDistance;
      iEvent.angle = touchAngle(pointers, deltaSource);
      iEvent.ds = iEvent.scale - interaction.gesture.scale;
      iEvent.da = iEvent.angle - interaction.gesture.angle;
    }
    interaction.gesture.distance = iEvent.distance;
    interaction.gesture.angle = iEvent.angle;
    if (is.number(iEvent.scale) && iEvent.scale !== Infinity && !isNaN(iEvent.scale)) {
      interaction.gesture.scale = iEvent.scale;
    }
  }
  var gesture = {
    id: 'actions/gesture',
    before: ['actions/drag', 'actions/resize'],
    install: install$e,
    listeners: {
      'interactions:action-start': updateGestureProps,
      'interactions:action-move': updateGestureProps,
      'interactions:action-end': updateGestureProps,
      'interactions:new': function interactionsNew(_ref2) {
        var interaction = _ref2.interaction;
        interaction.gesture = {
          angle: 0,
          distance: 0,
          scale: 1,
          startAngle: 0,
          startDistance: 0
        };
      },
      'auto-start:check': function autoStartCheck(arg) {
        if (arg.interaction.pointers.length < 2) {
          return undefined;
        }
        var gestureOptions = arg.interactable.options.gesture;
        if (!(gestureOptions && gestureOptions.enabled)) {
          return undefined;
        }
        arg.action = {
          name: 'gesture'
        };
        return false;
      }
    },
    defaults: {},
    getCursor: function getCursor() {
      return '';
    },
    filterEventType: function filterEventType(type) {
      return type.search('gesture') === 0;
    }
  };
  var gesture$1 = gesture;

  function install$d(scope) {
    var actions = scope.actions,
      browser = scope.browser,
      Interactable = scope.Interactable,
      defaults = scope.defaults;

    // Less Precision with touch input

    resize.cursors = initCursors(browser);
    resize.defaultMargin = browser.supportsTouch || browser.supportsPointerEvent ? 20 : 10;
    Interactable.prototype.resizable = function (options) {
      return resizable(this, options, scope);
    };
    actions.map.resize = resize;
    actions.methodDict.resize = 'resizable';
    defaults.actions.resize = resize.defaults;
  }
  function resizeChecker(arg) {
    var interaction = arg.interaction,
      interactable = arg.interactable,
      element = arg.element,
      rect = arg.rect,
      buttons = arg.buttons;
    if (!rect) {
      return undefined;
    }
    var page = extend({}, interaction.coords.cur.page);
    var resizeOptions = interactable.options.resize;
    if (!(resizeOptions && resizeOptions.enabled) ||
    // check mouseButton setting if the pointer is down
    interaction.pointerIsDown && /mouse|pointer/.test(interaction.pointerType) && (buttons & resizeOptions.mouseButtons) === 0) {
      return undefined;
    }

    // if using resize.edges
    if (is.object(resizeOptions.edges)) {
      var resizeEdges = {
        left: false,
        right: false,
        top: false,
        bottom: false
      };
      for (var edge in resizeEdges) {
        resizeEdges[edge] = checkResizeEdge(edge, resizeOptions.edges[edge], page, interaction._latestPointer.eventTarget, element, rect, resizeOptions.margin || resize.defaultMargin);
      }
      resizeEdges.left = resizeEdges.left && !resizeEdges.right;
      resizeEdges.top = resizeEdges.top && !resizeEdges.bottom;
      if (resizeEdges.left || resizeEdges.right || resizeEdges.top || resizeEdges.bottom) {
        arg.action = {
          name: 'resize',
          edges: resizeEdges
        };
      }
    } else {
      var right = resizeOptions.axis !== 'y' && page.x > rect.right - resize.defaultMargin;
      var bottom = resizeOptions.axis !== 'x' && page.y > rect.bottom - resize.defaultMargin;
      if (right || bottom) {
        arg.action = {
          name: 'resize',
          axes: (right ? 'x' : '') + (bottom ? 'y' : '')
        };
      }
    }
    return arg.action ? false : undefined;
  }
  function resizable(interactable, options, scope) {
    if (is.object(options)) {
      interactable.options.resize.enabled = options.enabled !== false;
      interactable.setPerAction('resize', options);
      interactable.setOnEvents('resize', options);
      if (is.string(options.axis) && /^x$|^y$|^xy$/.test(options.axis)) {
        interactable.options.resize.axis = options.axis;
      } else if (options.axis === null) {
        interactable.options.resize.axis = scope.defaults.actions.resize.axis;
      }
      if (is.bool(options.preserveAspectRatio)) {
        interactable.options.resize.preserveAspectRatio = options.preserveAspectRatio;
      } else if (is.bool(options.square)) {
        interactable.options.resize.square = options.square;
      }
      return interactable;
    }
    if (is.bool(options)) {
      interactable.options.resize.enabled = options;
      return interactable;
    }
    return interactable.options.resize;
  }
  function checkResizeEdge(name, value, page, element, interactableElement, rect, margin) {
    // false, '', undefined, null
    if (!value) {
      return false;
    }

    // true value, use pointer coords and element rect
    if (value === true) {
      // if dimensions are negative, "switch" edges
      var width = is.number(rect.width) ? rect.width : rect.right - rect.left;
      var height = is.number(rect.height) ? rect.height : rect.bottom - rect.top;

      // don't use margin greater than half the relevent dimension
      margin = Math.min(margin, Math.abs((name === 'left' || name === 'right' ? width : height) / 2));
      if (width < 0) {
        if (name === 'left') {
          name = 'right';
        } else if (name === 'right') {
          name = 'left';
        }
      }
      if (height < 0) {
        if (name === 'top') {
          name = 'bottom';
        } else if (name === 'bottom') {
          name = 'top';
        }
      }
      if (name === 'left') {
        var edge = width >= 0 ? rect.left : rect.right;
        return page.x < edge + margin;
      }
      if (name === 'top') {
        var _edge = height >= 0 ? rect.top : rect.bottom;
        return page.y < _edge + margin;
      }
      if (name === 'right') {
        return page.x > (width >= 0 ? rect.right : rect.left) - margin;
      }
      if (name === 'bottom') {
        return page.y > (height >= 0 ? rect.bottom : rect.top) - margin;
      }
    }

    // the remaining checks require an element
    if (!is.element(element)) {
      return false;
    }
    return is.element(value) ?
    // the value is an element to use as a resize handle
    value === element :
    // otherwise check if element matches value as selector
    matchesUpTo(element, value, interactableElement);
  }

  /* eslint-disable multiline-ternary */
  // eslint-disable-next-line @typescript-eslint/consistent-type-imports
  function initCursors(browser) {
    return browser.isIe9 ? {
      x: 'e-resize',
      y: 's-resize',
      xy: 'se-resize',
      top: 'n-resize',
      left: 'w-resize',
      bottom: 's-resize',
      right: 'e-resize',
      topleft: 'se-resize',
      bottomright: 'se-resize',
      topright: 'ne-resize',
      bottomleft: 'ne-resize'
    } : {
      x: 'ew-resize',
      y: 'ns-resize',
      xy: 'nwse-resize',
      top: 'ns-resize',
      left: 'ew-resize',
      bottom: 'ns-resize',
      right: 'ew-resize',
      topleft: 'nwse-resize',
      bottomright: 'nwse-resize',
      topright: 'nesw-resize',
      bottomleft: 'nesw-resize'
    };
  }
  /* eslint-enable multiline-ternary */

  function start$7(_ref) {
    var iEvent = _ref.iEvent,
      interaction = _ref.interaction;
    if (interaction.prepared.name !== 'resize' || !interaction.prepared.edges) {
      return;
    }
    var resizeEvent = iEvent;
    var rect = interaction.rect;
    interaction._rects = {
      start: extend({}, rect),
      corrected: extend({}, rect),
      previous: extend({}, rect),
      delta: {
        left: 0,
        right: 0,
        width: 0,
        top: 0,
        bottom: 0,
        height: 0
      }
    };
    resizeEvent.edges = interaction.prepared.edges;
    resizeEvent.rect = interaction._rects.corrected;
    resizeEvent.deltaRect = interaction._rects.delta;
  }
  function move(_ref2) {
    var iEvent = _ref2.iEvent,
      interaction = _ref2.interaction;
    if (interaction.prepared.name !== 'resize' || !interaction.prepared.edges) return;
    var resizeEvent = iEvent;
    var resizeOptions = interaction.interactable.options.resize;
    var invert = resizeOptions.invert;
    var invertible = invert === 'reposition' || invert === 'negate';
    var current = interaction.rect;
    var _interaction$_rects = interaction._rects,
      startRect = _interaction$_rects.start,
      corrected = _interaction$_rects.corrected,
      deltaRect = _interaction$_rects.delta,
      previous = _interaction$_rects.previous;
    extend(previous, corrected);
    if (invertible) {
      // if invertible, copy the current rect
      extend(corrected, current);
      if (invert === 'reposition') {
        // swap edge values if necessary to keep width/height positive
        if (corrected.top > corrected.bottom) {
          var swap = corrected.top;
          corrected.top = corrected.bottom;
          corrected.bottom = swap;
        }
        if (corrected.left > corrected.right) {
          var _swap = corrected.left;
          corrected.left = corrected.right;
          corrected.right = _swap;
        }
      }
    } else {
      // if not invertible, restrict to minimum of 0x0 rect
      corrected.top = Math.min(current.top, startRect.bottom);
      corrected.bottom = Math.max(current.bottom, startRect.top);
      corrected.left = Math.min(current.left, startRect.right);
      corrected.right = Math.max(current.right, startRect.left);
    }
    corrected.width = corrected.right - corrected.left;
    corrected.height = corrected.bottom - corrected.top;
    for (var edge in corrected) {
      deltaRect[edge] = corrected[edge] - previous[edge];
    }
    resizeEvent.edges = interaction.prepared.edges;
    resizeEvent.rect = corrected;
    resizeEvent.deltaRect = deltaRect;
  }
  function end$1(_ref3) {
    var iEvent = _ref3.iEvent,
      interaction = _ref3.interaction;
    if (interaction.prepared.name !== 'resize' || !interaction.prepared.edges) return;
    var resizeEvent = iEvent;
    resizeEvent.edges = interaction.prepared.edges;
    resizeEvent.rect = interaction._rects.corrected;
    resizeEvent.deltaRect = interaction._rects.delta;
  }
  function updateEventAxes(_ref4) {
    var iEvent = _ref4.iEvent,
      interaction = _ref4.interaction;
    if (interaction.prepared.name !== 'resize' || !interaction.resizeAxes) return;
    var options = interaction.interactable.options;
    var resizeEvent = iEvent;
    if (options.resize.square) {
      if (interaction.resizeAxes === 'y') {
        resizeEvent.delta.x = resizeEvent.delta.y;
      } else {
        resizeEvent.delta.y = resizeEvent.delta.x;
      }
      resizeEvent.axes = 'xy';
    } else {
      resizeEvent.axes = interaction.resizeAxes;
      if (interaction.resizeAxes === 'x') {
        resizeEvent.delta.y = 0;
      } else if (interaction.resizeAxes === 'y') {
        resizeEvent.delta.x = 0;
      }
    }
  }
  var resize = {
    id: 'actions/resize',
    before: ['actions/drag'],
    install: install$d,
    listeners: {
      'interactions:new': function interactionsNew(_ref5) {
        var interaction = _ref5.interaction;
        interaction.resizeAxes = 'xy';
      },
      'interactions:action-start': function interactionsActionStart(arg) {
        start$7(arg);
        updateEventAxes(arg);
      },
      'interactions:action-move': function interactionsActionMove(arg) {
        move(arg);
        updateEventAxes(arg);
      },
      'interactions:action-end': end$1,
      'auto-start:check': resizeChecker
    },
    defaults: {
      square: false,
      preserveAspectRatio: false,
      axis: 'xy',
      // use default margin
      margin: NaN,
      // object with props left, right, top, bottom which are
      // true/false values to resize when the pointer is over that edge,
      // CSS selectors to match the handles for each direction
      // or the Elements for each handle
      edges: null,
      // a value of 'none' will limit the resize rect to a minimum of 0x0
      // 'negate' will alow the rect to have negative width/height
      // 'reposition' will keep the width/height positive by swapping
      // the top and bottom edges and/or swapping the left and right edges
      invert: 'none'
    },
    cursors: null,
    getCursor: function getCursor(_ref6) {
      var edges = _ref6.edges,
        axis = _ref6.axis,
        name = _ref6.name;
      var cursors = resize.cursors;
      var result = null;
      if (axis) {
        result = cursors[name + axis];
      } else if (edges) {
        var cursorKey = '';
        for (var _i2 = 0, _ref8 = ['top', 'bottom', 'left', 'right']; _i2 < _ref8.length; _i2++) {
          var edge = _ref8[_i2];
          if (edges[edge]) {
            cursorKey += edge;
          }
        }
        result = cursors[cursorKey];
      }
      return result;
    },
    filterEventType: function filterEventType(type) {
      return type.search('resize') === 0;
    },
    defaultMargin: null
  };
  var resize$1 = resize;

  /* eslint-disable import/no-duplicates -- for typescript module augmentations */
  /* eslint-enable import/no-duplicates */

  var actions = {
    id: 'actions',
    install: function install(scope) {
      scope.usePlugin(gesture$1);
      scope.usePlugin(resize$1);
      scope.usePlugin(drag$1);
      scope.usePlugin(drop$1);
    }
  };

  var lastTime = 0;
  var _request;
  var _cancel;
  function init(global) {
    _request = global.requestAnimationFrame;
    _cancel = global.cancelAnimationFrame;
    if (!_request) {
      var vendors = ['ms', 'moz', 'webkit', 'o'];
      for (var _i2 = 0; _i2 < vendors.length; _i2++) {
        var vendor = vendors[_i2];
        _request = global["".concat(vendor, "RequestAnimationFrame")];
        _cancel = global["".concat(vendor, "CancelAnimationFrame")] || global["".concat(vendor, "CancelRequestAnimationFrame")];
      }
    }
    _request = _request && _request.bind(global);
    _cancel = _cancel && _cancel.bind(global);
    if (!_request) {
      _request = function request(callback) {
        var currTime = Date.now();
        var timeToCall = Math.max(0, 16 - (currTime - lastTime));
        var token = global.setTimeout(function () {
          // eslint-disable-next-line n/no-callback-literal
          callback(currTime + timeToCall);
        }, timeToCall);
        lastTime = currTime + timeToCall;
        return token;
      };
      _cancel = function cancel(token) {
        return clearTimeout(token);
      };
    }
  }
  var raf = {
    request: function request(callback) {
      return _request(callback);
    },
    cancel: function cancel(token) {
      return _cancel(token);
    },
    init: init
  };

  function install$c(scope) {
    var defaults = scope.defaults,
      actions = scope.actions;
    scope.autoScroll = autoScroll;
    autoScroll.now = function () {
      return scope.now();
    };
    actions.phaselessTypes.autoscroll = true;
    defaults.perAction.autoScroll = autoScroll.defaults;
  }
  var autoScroll = {
    defaults: {
      enabled: false,
      margin: 60,
      // the item that is scrolled (Window or HTMLElement)
      container: null,
      // the scroll speed in pixels per second
      speed: 300
    },
    now: Date.now,
    interaction: null,
    i: 0,
    // the handle returned by window.setInterval

    // Direction each pulse is to scroll in
    x: 0,
    y: 0,
    isScrolling: false,
    prevTime: 0,
    margin: 0,
    speed: 0,
    start: function start(interaction) {
      autoScroll.isScrolling = true;
      raf.cancel(autoScroll.i);
      interaction.autoScroll = autoScroll;
      autoScroll.interaction = interaction;
      autoScroll.prevTime = autoScroll.now();
      autoScroll.i = raf.request(autoScroll.scroll);
    },
    stop: function stop() {
      autoScroll.isScrolling = false;
      if (autoScroll.interaction) {
        autoScroll.interaction.autoScroll = null;
      }
      raf.cancel(autoScroll.i);
    },
    // scroll the window by the values in scroll.x/y
    scroll: function scroll() {
      var interaction = autoScroll.interaction;
      var interactable = interaction.interactable,
        element = interaction.element;
      var actionName = interaction.prepared.name;
      var options = interactable.options[actionName].autoScroll;
      var container = getContainer(options.container, interactable, element);
      var now = autoScroll.now();
      // change in time in seconds
      var dt = (now - autoScroll.prevTime) / 1000;
      // displacement
      var s = options.speed * dt;
      if (s >= 1) {
        var scrollBy = {
          x: autoScroll.x * s,
          y: autoScroll.y * s
        };
        if (scrollBy.x || scrollBy.y) {
          var prevScroll = getScroll(container);
          if (is.window(container)) {
            container.scrollBy(scrollBy.x, scrollBy.y);
          } else if (container) {
            container.scrollLeft += scrollBy.x;
            container.scrollTop += scrollBy.y;
          }
          var curScroll = getScroll(container);
          var delta = {
            x: curScroll.x - prevScroll.x,
            y: curScroll.y - prevScroll.y
          };
          if (delta.x || delta.y) {
            interactable.fire({
              type: 'autoscroll',
              target: element,
              interactable: interactable,
              delta: delta,
              interaction: interaction,
              container: container
            });
          }
        }
        autoScroll.prevTime = now;
      }
      if (autoScroll.isScrolling) {
        raf.cancel(autoScroll.i);
        autoScroll.i = raf.request(autoScroll.scroll);
      }
    },
    check: function check(interactable, actionName) {
      var _options$actionName$a;
      var options = interactable.options;
      return (_options$actionName$a = options[actionName].autoScroll) == null ? void 0 : _options$actionName$a.enabled;
    },
    onInteractionMove: function onInteractionMove(_ref) {
      var interaction = _ref.interaction,
        pointer = _ref.pointer;
      if (!(interaction.interacting() && autoScroll.check(interaction.interactable, interaction.prepared.name))) {
        return;
      }
      if (interaction.simulation) {
        autoScroll.x = autoScroll.y = 0;
        return;
      }
      var top;
      var right;
      var bottom;
      var left;
      var interactable = interaction.interactable,
        element = interaction.element;
      var actionName = interaction.prepared.name;
      var options = interactable.options[actionName].autoScroll;
      var container = getContainer(options.container, interactable, element);
      if (is.window(container)) {
        left = pointer.clientX < autoScroll.margin;
        top = pointer.clientY < autoScroll.margin;
        right = pointer.clientX > container.innerWidth - autoScroll.margin;
        bottom = pointer.clientY > container.innerHeight - autoScroll.margin;
      } else {
        var rect = getElementClientRect(container);
        left = pointer.clientX < rect.left + autoScroll.margin;
        top = pointer.clientY < rect.top + autoScroll.margin;
        right = pointer.clientX > rect.right - autoScroll.margin;
        bottom = pointer.clientY > rect.bottom - autoScroll.margin;
      }
      autoScroll.x = right ? 1 : left ? -1 : 0;
      autoScroll.y = bottom ? 1 : top ? -1 : 0;
      if (!autoScroll.isScrolling) {
        // set the autoScroll properties to those of the target
        autoScroll.margin = options.margin;
        autoScroll.speed = options.speed;
        autoScroll.start(interaction);
      }
    }
  };
  function getContainer(value, interactable, element) {
    return (is.string(value) ? getStringOptionResult(value, interactable, element) : value) || getWindow(element);
  }
  function getScroll(container) {
    if (is.window(container)) {
      container = window.document.body;
    }
    return {
      x: container.scrollLeft,
      y: container.scrollTop
    };
  }
  var autoScrollPlugin = {
    id: 'auto-scroll',
    install: install$c,
    listeners: {
      'interactions:new': function interactionsNew(_ref3) {
        var interaction = _ref3.interaction;
        interaction.autoScroll = null;
      },
      'interactions:destroy': function interactionsDestroy(_ref4) {
        var interaction = _ref4.interaction;
        interaction.autoScroll = null;
        autoScroll.stop();
        if (autoScroll.interaction) {
          autoScroll.interaction = null;
        }
      },
      'interactions:stop': autoScroll.stop,
      'interactions:action-move': function interactionsActionMove(arg) {
        return autoScroll.onInteractionMove(arg);
      }
    }
  };
  var autoScroll$1 = autoScrollPlugin;

  function warnOnce(method, message) {
    var warned = false;
    return function () {
      if (!warned) {
        win.console.warn(message);
        warned = true;
      }
      return method.apply(this, arguments);
    };
  }
  function copyAction(dest, src) {
    dest.name = src.name;
    dest.axis = src.axis;
    dest.edges = src.edges;
    return dest;
  }

  function install$b(scope) {
    var Interactable = scope.Interactable;
    Interactable.prototype.getAction = function getAction(pointer, event, interaction, element) {
      var action = defaultActionChecker(this, event, interaction, element, scope);
      if (this.options.actionChecker) {
        return this.options.actionChecker(pointer, event, action, this, element, interaction);
      }
      return action;
    };
    Interactable.prototype.ignoreFrom = warnOnce(function (newValue) {
      return this._backCompatOption('ignoreFrom', newValue);
    }, 'Interactable.ignoreFrom() has been deprecated. Use Interactble.draggable({ignoreFrom: newValue}).');
    Interactable.prototype.allowFrom = warnOnce(function (newValue) {
      return this._backCompatOption('allowFrom', newValue);
    }, 'Interactable.allowFrom() has been deprecated. Use Interactble.draggable({allowFrom: newValue}).');
    Interactable.prototype.actionChecker = actionChecker;
    Interactable.prototype.styleCursor = styleCursor;
  }
  function defaultActionChecker(interactable, event, interaction, element, scope) {
    var rect = interactable.getRect(element);
    var buttons = event.buttons || {
      0: 1,
      1: 4,
      3: 8,
      4: 16
    }[event.button];
    var arg = {
      action: null,
      interactable: interactable,
      interaction: interaction,
      element: element,
      rect: rect,
      buttons: buttons
    };
    scope.fire('auto-start:check', arg);
    return arg.action;
  }
  function styleCursor(newValue) {
    if (is.bool(newValue)) {
      this.options.styleCursor = newValue;
      return this;
    }
    if (newValue === null) {
      delete this.options.styleCursor;
      return this;
    }
    return this.options.styleCursor;
  }
  function actionChecker(checker) {
    if (is.func(checker)) {
      this.options.actionChecker = checker;
      return this;
    }
    if (checker === null) {
      delete this.options.actionChecker;
      return this;
    }
    return this.options.actionChecker;
  }
  var InteractableMethods = {
    id: 'auto-start/interactableMethods',
    install: install$b
  };

  /* eslint-enable import/no-duplicates */

  function install$a(scope) {
    var interact = scope.interactStatic,
      defaults = scope.defaults;
    scope.usePlugin(InteractableMethods);
    defaults.base.actionChecker = null;
    defaults.base.styleCursor = true;
    extend(defaults.perAction, {
      manualStart: false,
      max: Infinity,
      maxPerElement: 1,
      allowFrom: null,
      ignoreFrom: null,
      // only allow left button by default
      // see https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/buttons#Return_value
      mouseButtons: 1
    });
    interact.maxInteractions = function (newValue) {
      return maxInteractions(newValue, scope);
    };
    scope.autoStart = {
      // Allow this many interactions to happen simultaneously
      maxInteractions: Infinity,
      withinInteractionLimit: withinInteractionLimit,
      cursorElement: null
    };
  }
  function prepareOnDown(_ref, scope) {
    var interaction = _ref.interaction,
      pointer = _ref.pointer,
      event = _ref.event,
      eventTarget = _ref.eventTarget;
    if (interaction.interacting()) return;
    var actionInfo = getActionInfo(interaction, pointer, event, eventTarget, scope);
    prepare(interaction, actionInfo, scope);
  }
  function prepareOnMove(_ref2, scope) {
    var interaction = _ref2.interaction,
      pointer = _ref2.pointer,
      event = _ref2.event,
      eventTarget = _ref2.eventTarget;
    if (interaction.pointerType !== 'mouse' || interaction.pointerIsDown || interaction.interacting()) return;
    var actionInfo = getActionInfo(interaction, pointer, event, eventTarget, scope);
    prepare(interaction, actionInfo, scope);
  }
  function startOnMove(arg, scope) {
    var interaction = arg.interaction;
    if (!interaction.pointerIsDown || interaction.interacting() || !interaction.pointerWasMoved || !interaction.prepared.name) {
      return;
    }
    scope.fire('autoStart:before-start', arg);
    var interactable = interaction.interactable;
    var actionName = interaction.prepared.name;
    if (actionName && interactable) {
      // check manualStart and interaction limit
      if (interactable.options[actionName].manualStart || !withinInteractionLimit(interactable, interaction.element, interaction.prepared, scope)) {
        interaction.stop();
      } else {
        interaction.start(interaction.prepared, interactable, interaction.element);
        setInteractionCursor(interaction, scope);
      }
    }
  }
  function clearCursorOnStop(_ref3, scope) {
    var interaction = _ref3.interaction;
    var interactable = interaction.interactable;
    if (interactable && interactable.options.styleCursor) {
      setCursor(interaction.element, '', scope);
    }
  }

  // Check if the current interactable supports the action.
  // If so, return the validated action. Otherwise, return null
  function validateAction(action, interactable, element, eventTarget, scope) {
    if (interactable.testIgnoreAllow(interactable.options[action.name], element, eventTarget) && interactable.options[action.name].enabled && withinInteractionLimit(interactable, element, action, scope)) {
      return action;
    }
    return null;
  }
  function validateMatches(interaction, pointer, event, matches, matchElements, eventTarget, scope) {
    for (var i = 0, len = matches.length; i < len; i++) {
      var match = matches[i];
      var matchElement = matchElements[i];
      var matchAction = match.getAction(pointer, event, interaction, matchElement);
      if (!matchAction) {
        continue;
      }
      var action = validateAction(matchAction, match, matchElement, eventTarget, scope);
      if (action) {
        return {
          action: action,
          interactable: match,
          element: matchElement
        };
      }
    }
    return {
      action: null,
      interactable: null,
      element: null
    };
  }
  function getActionInfo(interaction, pointer, event, eventTarget, scope) {
    var matches = [];
    var matchElements = [];
    var element = eventTarget;
    function pushMatches(interactable) {
      matches.push(interactable);
      matchElements.push(element);
    }
    while (is.element(element)) {
      matches = [];
      matchElements = [];
      scope.interactables.forEachMatch(element, pushMatches);
      var actionInfo = validateMatches(interaction, pointer, event, matches, matchElements, eventTarget, scope);
      if (actionInfo.action && !actionInfo.interactable.options[actionInfo.action.name].manualStart) {
        return actionInfo;
      }
      element = parentNode(element);
    }
    return {
      action: null,
      interactable: null,
      element: null
    };
  }
  function prepare(interaction, _ref4, scope) {
    var action = _ref4.action,
      interactable = _ref4.interactable,
      element = _ref4.element;
    action = action || {
      name: null
    };
    interaction.interactable = interactable;
    interaction.element = element;
    copyAction(interaction.prepared, action);
    interaction.rect = interactable && action.name ? interactable.getRect(element) : null;
    setInteractionCursor(interaction, scope);
    scope.fire('autoStart:prepared', {
      interaction: interaction
    });
  }
  function withinInteractionLimit(interactable, element, action, scope) {
    var options = interactable.options;
    var maxActions = options[action.name].max;
    var maxPerElement = options[action.name].maxPerElement;
    var autoStartMax = scope.autoStart.maxInteractions;
    var activeInteractions = 0;
    var interactableCount = 0;
    var elementCount = 0;

    // no actions if any of these values == 0
    if (!(maxActions && maxPerElement && autoStartMax)) {
      return false;
    }
    for (var _i2 = 0, _scope$interactions$l2 = scope.interactions.list; _i2 < _scope$interactions$l2.length; _i2++) {
      var interaction = _scope$interactions$l2[_i2];
      var otherAction = interaction.prepared.name;
      if (!interaction.interacting()) {
        continue;
      }
      activeInteractions++;
      if (activeInteractions >= autoStartMax) {
        return false;
      }
      if (interaction.interactable !== interactable) {
        continue;
      }
      interactableCount += otherAction === action.name ? 1 : 0;
      if (interactableCount >= maxActions) {
        return false;
      }
      if (interaction.element === element) {
        elementCount++;
        if (otherAction === action.name && elementCount >= maxPerElement) {
          return false;
        }
      }
    }
    return autoStartMax > 0;
  }
  function maxInteractions(newValue, scope) {
    if (is.number(newValue)) {
      scope.autoStart.maxInteractions = newValue;
      return this;
    }
    return scope.autoStart.maxInteractions;
  }
  function setCursor(element, cursor, scope) {
    var prevCursorElement = scope.autoStart.cursorElement;
    if (prevCursorElement && prevCursorElement !== element) {
      prevCursorElement.style.cursor = '';
    }
    element.ownerDocument.documentElement.style.cursor = cursor;
    element.style.cursor = cursor;
    scope.autoStart.cursorElement = cursor ? element : null;
  }
  function setInteractionCursor(interaction, scope) {
    var interactable = interaction.interactable,
      element = interaction.element,
      prepared = interaction.prepared;
    if (!(interaction.pointerType === 'mouse' && interactable && interactable.options.styleCursor)) {
      // clear previous target element cursor
      if (scope.autoStart.cursorElement) {
        setCursor(scope.autoStart.cursorElement, '', scope);
      }
      return;
    }
    var cursor = '';
    if (prepared.name) {
      var cursorChecker = interactable.options[prepared.name].cursorChecker;
      if (is.func(cursorChecker)) {
        cursor = cursorChecker(prepared, interactable, element, interaction._interacting);
      } else {
        cursor = scope.actions.map[prepared.name].getCursor(prepared);
      }
    }
    setCursor(interaction.element, cursor || '', scope);
  }
  var autoStart$1 = {
    id: 'auto-start/base',
    before: ['actions'],
    install: install$a,
    listeners: {
      'interactions:down': prepareOnDown,
      'interactions:move': function interactionsMove(arg, scope) {
        prepareOnMove(arg, scope);
        startOnMove(arg, scope);
      },
      'interactions:stop': clearCursorOnStop
    },
    maxInteractions: maxInteractions,
    withinInteractionLimit: withinInteractionLimit,
    validateAction: validateAction
  };
  var autoStart$2 = autoStart$1;

  function beforeStart(_ref, scope) {
    var interaction = _ref.interaction,
      eventTarget = _ref.eventTarget,
      dx = _ref.dx,
      dy = _ref.dy;
    if (interaction.prepared.name !== 'drag') return;

    // check if a drag is in the correct axis
    var absX = Math.abs(dx);
    var absY = Math.abs(dy);
    var targetOptions = interaction.interactable.options.drag;
    var startAxis = targetOptions.startAxis;
    var currentAxis = absX > absY ? 'x' : absX < absY ? 'y' : 'xy';
    interaction.prepared.axis = targetOptions.lockAxis === 'start' ? currentAxis[0] // always lock to one axis even if currentAxis === 'xy'
    : targetOptions.lockAxis;

    // if the movement isn't in the startAxis of the interactable
    if (currentAxis !== 'xy' && startAxis !== 'xy' && startAxis !== currentAxis) {
      interaction.prepared.name = null;

      // then try to get a drag from another ineractable
      var element = eventTarget;
      var getDraggable = function getDraggable(interactable) {
        if (interactable === interaction.interactable) return;
        var options = interaction.interactable.options.drag;
        if (!options.manualStart && interactable.testIgnoreAllow(options, element, eventTarget)) {
          var action = interactable.getAction(interaction.downPointer, interaction.downEvent, interaction, element);
          if (action && action.name === 'drag' && checkStartAxis(currentAxis, interactable) && autoStart$2.validateAction(action, interactable, element, eventTarget, scope)) {
            return interactable;
          }
        }
      };

      // check all interactables
      while (is.element(element)) {
        var interactable = scope.interactables.forEachMatch(element, getDraggable);
        if (interactable) {
          interaction.prepared.name = 'drag';
          interaction.interactable = interactable;
          interaction.element = element;
          break;
        }
        element = parentNode(element);
      }
    }
  }
  function checkStartAxis(startAxis, interactable) {
    if (!interactable) {
      return false;
    }
    var thisAxis = interactable.options.drag.startAxis;
    return startAxis === 'xy' || thisAxis === 'xy' || thisAxis === startAxis;
  }
  var dragAxis = {
    id: 'auto-start/dragAxis',
    listeners: {
      'autoStart:before-start': beforeStart
    }
  };

  /* eslint-disable import/no-duplicates -- for typescript module augmentations */
  /* eslint-enable */

  function install$9(scope) {
    var defaults = scope.defaults;
    scope.usePlugin(autoStart$2);
    defaults.perAction.hold = 0;
    defaults.perAction.delay = 0;
  }
  function getHoldDuration(interaction) {
    var actionName = interaction.prepared && interaction.prepared.name;
    if (!actionName) {
      return null;
    }
    var options = interaction.interactable.options;
    return options[actionName].hold || options[actionName].delay;
  }
  var hold = {
    id: 'auto-start/hold',
    install: install$9,
    listeners: {
      'interactions:new': function interactionsNew(_ref) {
        var interaction = _ref.interaction;
        interaction.autoStartHoldTimer = null;
      },
      'autoStart:prepared': function autoStartPrepared(_ref2) {
        var interaction = _ref2.interaction;
        var hold = getHoldDuration(interaction);
        if (hold > 0) {
          interaction.autoStartHoldTimer = setTimeout(function () {
            interaction.start(interaction.prepared, interaction.interactable, interaction.element);
          }, hold);
        }
      },
      'interactions:move': function interactionsMove(_ref3) {
        var interaction = _ref3.interaction,
          duplicate = _ref3.duplicate;
        if (interaction.autoStartHoldTimer && interaction.pointerWasMoved && !duplicate) {
          clearTimeout(interaction.autoStartHoldTimer);
          interaction.autoStartHoldTimer = null;
        }
      },
      // prevent regular down->move autoStart
      'autoStart:before-start': function autoStartBeforeStart(_ref4) {
        var interaction = _ref4.interaction;
        var holdDuration = getHoldDuration(interaction);
        if (holdDuration > 0) {
          interaction.prepared.name = null;
        }
      }
    },
    getHoldDuration: getHoldDuration
  };
  var hold$1 = hold;

  /* eslint-disable import/no-duplicates -- for typescript module augmentations */
  /* eslint-enable import/no-duplicates */

  var autoStart = {
    id: 'auto-start',
    install: function install(scope) {
      scope.usePlugin(autoStart$2);
      scope.usePlugin(hold$1);
      scope.usePlugin(dragAxis);
    }
  };

  var preventDefault = function preventDefault(newValue) {
    if (/^(always|never|auto)$/.test(newValue)) {
      this.options.preventDefault = newValue;
      return this;
    }
    if (is.bool(newValue)) {
      this.options.preventDefault = newValue ? 'always' : 'never';
      return this;
    }
    return this.options.preventDefault;
  };
  function checkAndPreventDefault(interactable, scope, event) {
    var setting = interactable.options.preventDefault;
    if (setting === 'never') return;
    if (setting === 'always') {
      event.preventDefault();
      return;
    }

    // setting === 'auto'

    // if the browser supports passive event listeners and isn't running on iOS,
    // don't preventDefault of touch{start,move} events. CSS touch-action and
    // user-select should be used instead of calling event.preventDefault().
    if (scope.events.supportsPassive && /^touch(start|move)$/.test(event.type)) {
      var doc = getWindow(event.target).document;
      var docOptions = scope.getDocOptions(doc);
      if (!(docOptions && docOptions.events) || docOptions.events.passive !== false) {
        return;
      }
    }

    // don't preventDefault of pointerdown events
    if (/^(mouse|pointer|touch)*(down|start)/i.test(event.type)) {
      return;
    }

    // don't preventDefault on editable elements
    if (is.element(event.target) && matchesSelector(event.target, 'input,select,textarea,[contenteditable=true],[contenteditable=true] *')) {
      return;
    }
    event.preventDefault();
  }
  function onInteractionEvent(_ref) {
    var interaction = _ref.interaction,
      event = _ref.event;
    if (interaction.interactable) {
      interaction.interactable.checkAndPreventDefault(event);
    }
  }
  function install$8(scope) {
    var Interactable = scope.Interactable;
    Interactable.prototype.preventDefault = preventDefault;
    Interactable.prototype.checkAndPreventDefault = function (event) {
      return checkAndPreventDefault(this, scope, event);
    };

    // prevent native HTML5 drag on interact.js target elements
    scope.interactions.docEvents.push({
      type: 'dragstart',
      listener: function listener(event) {
        for (var _i2 = 0, _scope$interactions$l2 = scope.interactions.list; _i2 < _scope$interactions$l2.length; _i2++) {
          var interaction = _scope$interactions$l2[_i2];
          if (interaction.element && (interaction.element === event.target || nodeContains(interaction.element, event.target))) {
            interaction.interactable.checkAndPreventDefault(event);
            return;
          }
        }
      }
    });
  }
  var interactablePreventDefault = {
    id: 'core/interactablePreventDefault',
    install: install$8,
    listeners: ['down', 'move', 'up', 'cancel'].reduce(function (acc, eventType) {
      acc["interactions:".concat(eventType)] = onInteractionEvent;
      return acc;
    }, {})
  };

  function isNonNativeEvent(type, actions) {
    if (actions.phaselessTypes[type]) {
      return true;
    }
    for (var name in actions.map) {
      if (type.indexOf(name) === 0 && type.substr(name.length) in actions.phases) {
        return true;
      }
    }
    return false;
  }

  var CheckName = /*#__PURE__*/function (CheckName) {
    CheckName["touchAction"] = "touchAction";
    CheckName["boxSizing"] = "boxSizing";
    CheckName["noListeners"] = "noListeners";
    return CheckName;
  }(CheckName || {});
  var prefix = '[interact.js] ';
  var links = {
    touchAction: 'https://developer.mozilla.org/en-US/docs/Web/CSS/touch-action',
    boxSizing: 'https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing'
  };

  // eslint-disable-next-line no-undef
  var isProduction = "development" === 'production';
  function install$7(scope) {
    var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
      logger = _ref.logger;
    var Interactable = scope.Interactable,
      defaults = scope.defaults;
    scope.logger = logger || console;
    defaults.base.devTools = {
      ignore: {}
    };
    Interactable.prototype.devTools = function (options) {
      if (options) {
        extend(this.options.devTools, options);
        return this;
      }
      return this.options.devTools;
    };

    // can't set native events on non string targets without `addEventListener` prop
    var _onOff = Interactable.prototype._onOff;
    Interactable.prototype._onOff = function (method, typeArg, listenerArg, options, filter) {
      if (is.string(this.target) || this.target.addEventListener) {
        return _onOff.call(this, method, typeArg, listenerArg, options, filter);
      }
      if (is.object(typeArg) && !is.array(typeArg)) {
        options = listenerArg;
        listenerArg = null;
      }
      var normalizedListeners = normalize(typeArg, listenerArg, filter);
      for (var type in normalizedListeners) {
        if (isNonNativeEvent(type, scope.actions)) continue;
        scope.logger.warn(prefix + "Can't add native \"".concat(type, "\" event listener to target without `addEventListener(type, listener, options)` prop."));
      }
      return _onOff.call(this, method, normalizedListeners, options);
    };
  }
  var checks = [{
    name: CheckName.touchAction,
    perform: function perform(_ref2) {
      var element = _ref2.element;
      return !!element && !parentHasStyle(element, 'touchAction', /pan-|pinch|none/);
    },
    getInfo: function getInfo(_ref3) {
      var element = _ref3.element;
      return [element, links.touchAction];
    },
    text: 'Consider adding CSS "touch-action: none" to this element\n'
  }, {
    name: CheckName.boxSizing,
    perform: function perform(interaction) {
      var element = interaction.element;
      return interaction.prepared.name === 'resize' && element instanceof domObjects$1.HTMLElement && !hasStyle(element, 'boxSizing', /border-box/);
    },
    text: 'Consider adding CSS "box-sizing: border-box" to this resizable element',
    getInfo: function getInfo(_ref4) {
      var element = _ref4.element;
      return [element, links.boxSizing];
    }
  }, {
    name: CheckName.noListeners,
    perform: function perform(interaction) {
      var _interaction$interact;
      var actionName = interaction.prepared.name;
      var moveListeners = ((_interaction$interact = interaction.interactable) == null ? void 0 : _interaction$interact.events.types["".concat(actionName, "move")]) || [];
      return !moveListeners.length;
    },
    getInfo: function getInfo(interaction) {
      return [interaction.prepared.name, interaction.interactable];
    },
    text: 'There are no listeners set for this action'
  }];
  function hasStyle(element, prop, styleRe) {
    var value = element.style[prop] || win.getComputedStyle(element)[prop];
    return styleRe.test((value || '').toString());
  }
  function parentHasStyle(element, prop, styleRe) {
    var parent = element;
    while (is.element(parent)) {
      if (hasStyle(parent, prop, styleRe)) {
        return true;
      }
      parent = parentNode(parent);
    }
    return false;
  }
  var id = 'dev-tools';
  var defaultExport = isProduction ? {
    id: id,
    install: function install() {}
  } : {
    id: id,
    install: install$7,
    listeners: {
      'interactions:action-start': function interactionsActionStart(_ref5, scope) {
        var interaction = _ref5.interaction;
        for (var _i2 = 0; _i2 < checks.length; _i2++) {
          var check = checks[_i2];
          var options = interaction.interactable && interaction.interactable.options;
          if (!(options && options.devTools && options.devTools.ignore[check.name]) && check.perform(interaction)) {
            var _scope$logger;
            (_scope$logger = scope.logger).warn.apply(_scope$logger, [prefix + check.text].concat(check.getInfo(interaction)));
          }
        }
      }
    },
    checks: checks,
    CheckName: CheckName,
    links: links,
    prefix: prefix
  };
  var devTools = defaultExport;

  // tslint:disable-next-line ban-types
  function clone(source) {
    var dest = {};
    for (var prop in source) {
      var value = source[prop];
      if (is.plainObject(value)) {
        dest[prop] = clone(value);
      } else if (is.array(value)) {
        dest[prop] = from(value);
      } else {
        dest[prop] = value;
      }
    }
    return dest;
  }

  var Modification = /*#__PURE__*/function () {
    function Modification(interaction) {
      _classCallCheck(this, Modification);
      this.states = [];
      this.startOffset = {
        left: 0,
        right: 0,
        top: 0,
        bottom: 0
      };
      this.startDelta = void 0;
      this.result = void 0;
      this.endResult = void 0;
      this.startEdges = void 0;
      this.edges = void 0;
      this.interaction = void 0;
      this.interaction = interaction;
      this.result = createResult();
      this.edges = {
        left: false,
        right: false,
        top: false,
        bottom: false
      };
    }
    _createClass(Modification, [{
      key: "start",
      value: function start(_ref, pageCoords) {
        var phase = _ref.phase;
        var interaction = this.interaction;
        var modifierList = getModifierList(interaction);
        this.prepareStates(modifierList);
        this.startEdges = extend({}, interaction.edges);
        this.edges = extend({}, this.startEdges);
        this.startOffset = getRectOffset(interaction.rect, pageCoords);
        this.startDelta = {
          x: 0,
          y: 0
        };
        var arg = this.fillArg({
          phase: phase,
          pageCoords: pageCoords,
          preEnd: false
        });
        this.result = createResult();
        this.startAll(arg);
        var result = this.result = this.setAll(arg);
        return result;
      }
    }, {
      key: "fillArg",
      value: function fillArg(arg) {
        var interaction = this.interaction;
        arg.interaction = interaction;
        arg.interactable = interaction.interactable;
        arg.element = interaction.element;
        arg.rect || (arg.rect = interaction.rect);
        arg.edges || (arg.edges = this.startEdges);
        arg.startOffset = this.startOffset;
        return arg;
      }
    }, {
      key: "startAll",
      value: function startAll(arg) {
        for (var _i2 = 0, _this$states2 = this.states; _i2 < _this$states2.length; _i2++) {
          var state = _this$states2[_i2];
          if (state.methods.start) {
            arg.state = state;
            state.methods.start(arg);
          }
        }
      }
    }, {
      key: "setAll",
      value: function setAll(arg) {
        var phase = arg.phase,
          preEnd = arg.preEnd,
          skipModifiers = arg.skipModifiers,
          unmodifiedRect = arg.rect,
          unmodifiedEdges = arg.edges;
        arg.coords = extend({}, arg.pageCoords);
        arg.rect = extend({}, unmodifiedRect);
        arg.edges = extend({}, unmodifiedEdges);
        var states = skipModifiers ? this.states.slice(skipModifiers) : this.states;
        var newResult = createResult(arg.coords, arg.rect);
        for (var _i4 = 0; _i4 < states.length; _i4++) {
          var _state$methods;
          var state = states[_i4];
          var options = state.options;
          var lastModifierCoords = extend({}, arg.coords);
          var returnValue = null;
          if ((_state$methods = state.methods) != null && _state$methods.set && this.shouldDo(options, preEnd, phase)) {
            arg.state = state;
            returnValue = state.methods.set(arg);
            addEdges(arg.edges, arg.rect, {
              x: arg.coords.x - lastModifierCoords.x,
              y: arg.coords.y - lastModifierCoords.y
            });
          }
          newResult.eventProps.push(returnValue);
        }
        extend(this.edges, arg.edges);
        newResult.delta.x = arg.coords.x - arg.pageCoords.x;
        newResult.delta.y = arg.coords.y - arg.pageCoords.y;
        newResult.rectDelta.left = arg.rect.left - unmodifiedRect.left;
        newResult.rectDelta.right = arg.rect.right - unmodifiedRect.right;
        newResult.rectDelta.top = arg.rect.top - unmodifiedRect.top;
        newResult.rectDelta.bottom = arg.rect.bottom - unmodifiedRect.bottom;
        var prevCoords = this.result.coords;
        var prevRect = this.result.rect;
        if (prevCoords && prevRect) {
          var rectChanged = newResult.rect.left !== prevRect.left || newResult.rect.right !== prevRect.right || newResult.rect.top !== prevRect.top || newResult.rect.bottom !== prevRect.bottom;
          newResult.changed = rectChanged || prevCoords.x !== newResult.coords.x || prevCoords.y !== newResult.coords.y;
        }
        return newResult;
      }
    }, {
      key: "applyToInteraction",
      value: function applyToInteraction(arg) {
        var interaction = this.interaction;
        var phase = arg.phase;
        var curCoords = interaction.coords.cur;
        var startCoords = interaction.coords.start;
        var result = this.result,
          startDelta = this.startDelta;
        var curDelta = result.delta;
        if (phase === 'start') {
          extend(this.startDelta, result.delta);
        }
        for (var _i6 = 0, _ref3 = [[startCoords, startDelta], [curCoords, curDelta]]; _i6 < _ref3.length; _i6++) {
          var _ref3$_i = _ref3[_i6],
            coordsSet = _ref3$_i[0],
            delta = _ref3$_i[1];
          coordsSet.page.x += delta.x;
          coordsSet.page.y += delta.y;
          coordsSet.client.x += delta.x;
          coordsSet.client.y += delta.y;
        }
        var rectDelta = this.result.rectDelta;
        var rect = arg.rect || interaction.rect;
        rect.left += rectDelta.left;
        rect.right += rectDelta.right;
        rect.top += rectDelta.top;
        rect.bottom += rectDelta.bottom;
        rect.width = rect.right - rect.left;
        rect.height = rect.bottom - rect.top;
      }
    }, {
      key: "setAndApply",
      value: function setAndApply(arg) {
        var interaction = this.interaction;
        var phase = arg.phase,
          preEnd = arg.preEnd,
          skipModifiers = arg.skipModifiers;
        var result = this.setAll(this.fillArg({
          preEnd: preEnd,
          phase: phase,
          pageCoords: arg.modifiedCoords || interaction.coords.cur.page
        }));
        this.result = result;

        // don't fire an action move if a modifier would keep the event in the same
        // cordinates as before
        if (!result.changed && (!skipModifiers || skipModifiers < this.states.length) && interaction.interacting()) {
          return false;
        }
        if (arg.modifiedCoords) {
          var page = interaction.coords.cur.page;
          var adjustment = {
            x: arg.modifiedCoords.x - page.x,
            y: arg.modifiedCoords.y - page.y
          };
          result.coords.x += adjustment.x;
          result.coords.y += adjustment.y;
          result.delta.x += adjustment.x;
          result.delta.y += adjustment.y;
        }
        this.applyToInteraction(arg);
      }
    }, {
      key: "beforeEnd",
      value: function beforeEnd(arg) {
        var interaction = arg.interaction,
          event = arg.event;
        var states = this.states;
        if (!states || !states.length) {
          return;
        }
        var doPreend = false;
        for (var _i8 = 0; _i8 < states.length; _i8++) {
          var state = states[_i8];
          arg.state = state;
          var options = state.options,
            methods = state.methods;
          var endPosition = methods.beforeEnd && methods.beforeEnd(arg);
          if (endPosition) {
            this.endResult = endPosition;
            return false;
          }
          doPreend = doPreend || !doPreend && this.shouldDo(options, true, arg.phase, true);
        }
        if (doPreend) {
          // trigger a final modified move before ending
          interaction.move({
            event: event,
            preEnd: true
          });
        }
      }
    }, {
      key: "stop",
      value: function stop(arg) {
        var interaction = arg.interaction;
        if (!this.states || !this.states.length) {
          return;
        }
        var modifierArg = extend({
          states: this.states,
          interactable: interaction.interactable,
          element: interaction.element,
          rect: null
        }, arg);
        this.fillArg(modifierArg);
        for (var _i10 = 0, _this$states4 = this.states; _i10 < _this$states4.length; _i10++) {
          var state = _this$states4[_i10];
          modifierArg.state = state;
          if (state.methods.stop) {
            state.methods.stop(modifierArg);
          }
        }
        this.states = null;
        this.endResult = null;
      }
    }, {
      key: "prepareStates",
      value: function prepareStates(modifierList) {
        this.states = [];
        for (var index = 0; index < modifierList.length; index++) {
          var _modifierList$index = modifierList[index],
            options = _modifierList$index.options,
            methods = _modifierList$index.methods,
            name = _modifierList$index.name;
          this.states.push({
            options: options,
            methods: methods,
            index: index,
            name: name
          });
        }
        return this.states;
      }
    }, {
      key: "restoreInteractionCoords",
      value: function restoreInteractionCoords(_ref4) {
        var _ref4$interaction = _ref4.interaction,
          coords = _ref4$interaction.coords,
          rect = _ref4$interaction.rect,
          modification = _ref4$interaction.modification;
        if (!modification.result) return;
        var startDelta = modification.startDelta;
        var _modification$result = modification.result,
          curDelta = _modification$result.delta,
          rectDelta = _modification$result.rectDelta;
        var coordsAndDeltas = [[coords.start, startDelta], [coords.cur, curDelta]];
        for (var _i12 = 0, _ref6 = coordsAndDeltas; _i12 < _ref6.length; _i12++) {
          var _ref6$_i = _ref6[_i12],
            coordsSet = _ref6$_i[0],
            delta = _ref6$_i[1];
          coordsSet.page.x -= delta.x;
          coordsSet.page.y -= delta.y;
          coordsSet.client.x -= delta.x;
          coordsSet.client.y -= delta.y;
        }
        rect.left -= rectDelta.left;
        rect.right -= rectDelta.right;
        rect.top -= rectDelta.top;
        rect.bottom -= rectDelta.bottom;
      }
    }, {
      key: "shouldDo",
      value: function shouldDo(options, preEnd, phase, requireEndOnly) {
        if (
        // ignore disabled modifiers
        !options || options.enabled === false ||
        // check if we require endOnly option to fire move before end
        requireEndOnly && !options.endOnly ||
        // don't apply endOnly modifiers when not ending
        options.endOnly && !preEnd ||
        // check if modifier should run be applied on start
        phase === 'start' && !options.setStart) {
          return false;
        }
        return true;
      }
    }, {
      key: "copyFrom",
      value: function copyFrom(other) {
        this.startOffset = other.startOffset;
        this.startDelta = other.startDelta;
        this.startEdges = other.startEdges;
        this.edges = other.edges;
        this.states = other.states.map(function (s) {
          return clone(s);
        });
        this.result = createResult(extend({}, other.result.coords), extend({}, other.result.rect));
      }
    }, {
      key: "destroy",
      value: function destroy() {
        for (var prop in this) {
          this[prop] = null;
        }
      }
    }]);
    return Modification;
  }();
  function createResult(coords, rect) {
    return {
      rect: rect,
      coords: coords,
      delta: {
        x: 0,
        y: 0
      },
      rectDelta: {
        left: 0,
        right: 0,
        top: 0,
        bottom: 0
      },
      eventProps: [],
      changed: true
    };
  }
  function getModifierList(interaction) {
    var actionOptions = interaction.interactable.options[interaction.prepared.name];
    var actionModifiers = actionOptions.modifiers;
    if (actionModifiers && actionModifiers.length) {
      return actionModifiers;
    }
    return ['snap', 'snapSize', 'snapEdges', 'restrict', 'restrictEdges', 'restrictSize'].map(function (type) {
      var options = actionOptions[type];
      return options && options.enabled && {
        options: options,
        methods: options._methods
      };
    }).filter(function (m) {
      return !!m;
    });
  }
  function getRectOffset(rect, coords) {
    return rect ? {
      left: coords.x - rect.left,
      top: coords.y - rect.top,
      right: rect.right - coords.x,
      bottom: rect.bottom - coords.y
    } : {
      left: 0,
      top: 0,
      right: 0,
      bottom: 0
    };
  }

  function makeModifier(module, name) {
    var defaults = module.defaults;
    var methods = {
      start: module.start,
      set: module.set,
      beforeEnd: module.beforeEnd,
      stop: module.stop
    };
    var modifier = function modifier(_options) {
      var options = _options || {};
      options.enabled = options.enabled !== false;

      // add missing defaults to options
      for (var prop in defaults) {
        if (!(prop in options)) {
          options[prop] = defaults[prop];
        }
      }
      var m = {
        options: options,
        methods: methods,
        name: name,
        enable: function enable() {
          options.enabled = true;
          return m;
        },
        disable: function disable() {
          options.enabled = false;
          return m;
        }
      };
      return m;
    };
    if (name && typeof name === 'string') {
      // for backwrads compatibility
      modifier._defaults = defaults;
      modifier._methods = methods;
    }
    return modifier;
  }
  function addEventModifiers(_ref) {
    var iEvent = _ref.iEvent,
      interaction = _ref.interaction;
    var result = interaction.modification.result;
    if (result) {
      iEvent.modifiers = result.eventProps;
    }
  }
  var modifiersBase = {
    id: 'modifiers/base',
    before: ['actions'],
    install: function install(scope) {
      scope.defaults.perAction.modifiers = [];
    },
    listeners: {
      'interactions:new': function interactionsNew(_ref2) {
        var interaction = _ref2.interaction;
        interaction.modification = new Modification(interaction);
      },
      'interactions:before-action-start': function interactionsBeforeActionStart(arg) {
        var interaction = arg.interaction;
        var modification = arg.interaction.modification;
        modification.start(arg, interaction.coords.start.page);
        interaction.edges = modification.edges;
        modification.applyToInteraction(arg);
      },
      'interactions:before-action-move': function interactionsBeforeActionMove(arg) {
        var interaction = arg.interaction;
        var modification = interaction.modification;
        var ret = modification.setAndApply(arg);
        interaction.edges = modification.edges;
        return ret;
      },
      'interactions:before-action-end': function interactionsBeforeActionEnd(arg) {
        var interaction = arg.interaction;
        var modification = interaction.modification;
        var ret = modification.beforeEnd(arg);
        interaction.edges = modification.startEdges;
        return ret;
      },
      'interactions:action-start': addEventModifiers,
      'interactions:action-move': addEventModifiers,
      'interactions:action-end': addEventModifiers,
      'interactions:after-action-start': function interactionsAfterActionStart(arg) {
        return arg.interaction.modification.restoreInteractionCoords(arg);
      },
      'interactions:after-action-move': function interactionsAfterActionMove(arg) {
        return arg.interaction.modification.restoreInteractionCoords(arg);
      },
      'interactions:stop': function interactionsStop(arg) {
        return arg.interaction.modification.stop(arg);
      }
    }
  };
  var base = modifiersBase;

  // eslint-disable-next-line @typescript-eslint/no-empty-interface

  var defaults$7 = {
    base: {
      preventDefault: 'auto',
      deltaSource: 'page'
    },
    perAction: {
      enabled: false,
      origin: {
        x: 0,
        y: 0
      }
    },
    actions: {}
  };

  // defined outside of class definition to avoid assignment of undefined during
  // construction

  var InteractEvent = /*#__PURE__*/function (_BaseEvent) {
    _inherits(InteractEvent, _BaseEvent);
    var _super = _createSuper(InteractEvent);
    function InteractEvent(interaction, event, actionName, phase, element, preEnd, type) {
      var _this;
      _classCallCheck(this, InteractEvent);
      _this = _super.call(this, interaction);
      _this.relatedTarget = null;
      _this.screenX = void 0;
      _this.screenY = void 0;
      _this.button = void 0;
      _this.buttons = void 0;
      _this.ctrlKey = void 0;
      _this.shiftKey = void 0;
      _this.altKey = void 0;
      _this.metaKey = void 0;
      _this.page = void 0;
      _this.client = void 0;
      _this.delta = void 0;
      _this.rect = void 0;
      _this.x0 = void 0;
      _this.y0 = void 0;
      _this.t0 = void 0;
      _this.dt = void 0;
      _this.duration = void 0;
      _this.clientX0 = void 0;
      _this.clientY0 = void 0;
      _this.velocity = void 0;
      _this.speed = void 0;
      _this.swipe = void 0;
      // resize
      _this.axes = void 0;
      /** @internal */
      _this.preEnd = void 0;
      element = element || interaction.element;
      var target = interaction.interactable;
      var deltaSource = (target && target.options || defaults$7).deltaSource;
      var origin = getOriginXY(target, element, actionName);
      var starting = phase === 'start';
      var ending = phase === 'end';
      var prevEvent = starting ? _assertThisInitialized(_this) : interaction.prevEvent;
      var coords = starting ? interaction.coords.start : ending ? {
        page: prevEvent.page,
        client: prevEvent.client,
        timeStamp: interaction.coords.cur.timeStamp
      } : interaction.coords.cur;
      _this.page = extend({}, coords.page);
      _this.client = extend({}, coords.client);
      _this.rect = extend({}, interaction.rect);
      _this.timeStamp = coords.timeStamp;
      if (!ending) {
        _this.page.x -= origin.x;
        _this.page.y -= origin.y;
        _this.client.x -= origin.x;
        _this.client.y -= origin.y;
      }
      _this.ctrlKey = event.ctrlKey;
      _this.altKey = event.altKey;
      _this.shiftKey = event.shiftKey;
      _this.metaKey = event.metaKey;
      _this.button = event.button;
      _this.buttons = event.buttons;
      _this.target = element;
      _this.currentTarget = element;
      _this.preEnd = preEnd;
      _this.type = type || actionName + (phase || '');
      _this.interactable = target;
      _this.t0 = starting ? interaction.pointers[interaction.pointers.length - 1].downTime : prevEvent.t0;
      _this.x0 = interaction.coords.start.page.x - origin.x;
      _this.y0 = interaction.coords.start.page.y - origin.y;
      _this.clientX0 = interaction.coords.start.client.x - origin.x;
      _this.clientY0 = interaction.coords.start.client.y - origin.y;
      if (starting || ending) {
        _this.delta = {
          x: 0,
          y: 0
        };
      } else {
        _this.delta = {
          x: _this[deltaSource].x - prevEvent[deltaSource].x,
          y: _this[deltaSource].y - prevEvent[deltaSource].y
        };
      }
      _this.dt = interaction.coords.delta.timeStamp;
      _this.duration = _this.timeStamp - _this.t0;

      // velocity and speed in pixels per second
      _this.velocity = extend({}, interaction.coords.velocity[deltaSource]);
      _this.speed = hypot(_this.velocity.x, _this.velocity.y);
      _this.swipe = ending || phase === 'inertiastart' ? _this.getSwipe() : null;
      return _this;
    }
    _createClass(InteractEvent, [{
      key: "getSwipe",
      value: function getSwipe() {
        var interaction = this._interaction;
        if (interaction.prevEvent.speed < 600 || this.timeStamp - interaction.prevEvent.timeStamp > 150) {
          return null;
        }
        var angle = 180 * Math.atan2(interaction.prevEvent.velocityY, interaction.prevEvent.velocityX) / Math.PI;
        var overlap = 22.5;
        if (angle < 0) {
          angle += 360;
        }
        var left = 135 - overlap <= angle && angle < 225 + overlap;
        var up = 225 - overlap <= angle && angle < 315 + overlap;
        var right = !left && (315 - overlap <= angle || angle < 45 + overlap);
        var down = !up && 45 - overlap <= angle && angle < 135 + overlap;
        return {
          up: up,
          down: down,
          left: left,
          right: right,
          angle: angle,
          speed: interaction.prevEvent.speed,
          velocity: {
            x: interaction.prevEvent.velocityX,
            y: interaction.prevEvent.velocityY
          }
        };
      }
    }, {
      key: "preventDefault",
      value: function preventDefault() {}

      /**
       * Don't call listeners on the remaining targets
       */
    }, {
      key: "stopImmediatePropagation",
      value: function stopImmediatePropagation() {
        this.immediatePropagationStopped = this.propagationStopped = true;
      }

      /**
       * Don't call any other listeners (even on the current target)
       */
    }, {
      key: "stopPropagation",
      value: function stopPropagation() {
        this.propagationStopped = true;
      }
    }]);
    return InteractEvent;
  }(BaseEvent);

  // getters and setters defined here to support typescript 3.6 and below which
  // don't support getter and setters in .d.ts files
  Object.defineProperties(InteractEvent.prototype, {
    pageX: {
      get: function get() {
        return this.page.x;
      },
      set: function set(value) {
        this.page.x = value;
      }
    },
    pageY: {
      get: function get() {
        return this.page.y;
      },
      set: function set(value) {
        this.page.y = value;
      }
    },
    clientX: {
      get: function get() {
        return this.client.x;
      },
      set: function set(value) {
        this.client.x = value;
      }
    },
    clientY: {
      get: function get() {
        return this.client.y;
      },
      set: function set(value) {
        this.client.y = value;
      }
    },
    dx: {
      get: function get() {
        return this.delta.x;
      },
      set: function set(value) {
        this.delta.x = value;
      }
    },
    dy: {
      get: function get() {
        return this.delta.y;
      },
      set: function set(value) {
        this.delta.y = value;
      }
    },
    velocityX: {
      get: function get() {
        return this.velocity.x;
      },
      set: function set(value) {
        this.velocity.x = value;
      }
    },
    velocityY: {
      get: function get() {
        return this.velocity.y;
      },
      set: function set(value) {
        this.velocity.y = value;
      }
    }
  });

  var PointerInfo = /*#__PURE__*/_createClass(function PointerInfo(id, pointer, event, downTime, downTarget) {
    _classCallCheck(this, PointerInfo);
    this.id = void 0;
    this.pointer = void 0;
    this.event = void 0;
    this.downTime = void 0;
    this.downTarget = void 0;
    this.id = id;
    this.pointer = pointer;
    this.event = event;
    this.downTime = downTime;
    this.downTarget = downTarget;
  });

  var _ProxyValues = /*#__PURE__*/function (_ProxyValues) {
    _ProxyValues["interactable"] = "";
    _ProxyValues["element"] = "";
    _ProxyValues["prepared"] = "";
    _ProxyValues["pointerIsDown"] = "";
    _ProxyValues["pointerWasMoved"] = "";
    _ProxyValues["_proxy"] = "";
    return _ProxyValues;
  }({});
  var _ProxyMethods = /*#__PURE__*/function (_ProxyMethods) {
    _ProxyMethods["start"] = "";
    _ProxyMethods["move"] = "";
    _ProxyMethods["end"] = "";
    _ProxyMethods["stop"] = "";
    _ProxyMethods["interacting"] = "";
    return _ProxyMethods;
  }({});
  var idCounter = 0;
  var Interaction = /*#__PURE__*/function () {
    function Interaction(_ref) {
      var _this = this;
      var pointerType = _ref.pointerType,
        scopeFire = _ref.scopeFire;
      _classCallCheck(this, Interaction);
      /** current interactable being interacted with */
      this.interactable = null;
      /** the target element of the interactable */
      this.element = null;
      this.rect = null;
      /** @internal */
      this._rects = void 0;
      /** @internal */
      this.edges = null;
      /** @internal */
      this._scopeFire = void 0;
      // action that's ready to be fired on next move event
      this.prepared = {
        name: null,
        axis: null,
        edges: null
      };
      this.pointerType = void 0;
      /** @internal keep track of added pointers */
      this.pointers = [];
      /** @internal pointerdown/mousedown/touchstart event */
      this.downEvent = null;
      /** @internal */
      this.downPointer = {};
      /** @internal */
      this._latestPointer = {
        pointer: null,
        event: null,
        eventTarget: null
      };
      /** @internal */
      this.prevEvent = null;
      this.pointerIsDown = false;
      this.pointerWasMoved = false;
      /** @internal */
      this._interacting = false;
      /** @internal */
      this._ending = false;
      /** @internal */
      this._stopped = true;
      /** @internal */
      this._proxy = void 0;
      /** @internal */
      this.simulation = null;
      this.doMove = warnOnce(function (signalArg) {
        this.move(signalArg);
      }, 'The interaction.doMove() method has been renamed to interaction.move()');
      this.coords = {
        // Starting InteractEvent pointer coordinates
        start: newCoords(),
        // Previous native pointer move event coordinates
        prev: newCoords(),
        // current native pointer move event coordinates
        cur: newCoords(),
        // Change in coordinates and time of the pointer
        delta: newCoords(),
        // pointer velocity
        velocity: newCoords()
      };
      /** @internal */
      this._id = idCounter++;
      this._scopeFire = scopeFire;
      this.pointerType = pointerType;
      var that = this;
      this._proxy = {};
      var _loop = function _loop(key) {
        Object.defineProperty(_this._proxy, key, {
          get: function get() {
            return that[key];
          }
        });
      };
      for (var key in _ProxyValues) {
        _loop(key);
      }
      var _loop2 = function _loop2(_key) {
        Object.defineProperty(_this._proxy, _key, {
          value: function value() {
            return that[_key].apply(that, arguments);
          }
        });
      };
      for (var _key in _ProxyMethods) {
        _loop2(_key);
      }
      this._scopeFire('interactions:new', {
        interaction: this
      });
    }
    _createClass(Interaction, [{
      key: "pointerMoveTolerance",
      get: /** @internal */function get() {
        return 1;
      }
    }, {
      key: "pointerDown",
      value: function pointerDown(pointer, event, eventTarget) {
        var pointerIndex = this.updatePointer(pointer, event, eventTarget, true);
        var pointerInfo = this.pointers[pointerIndex];
        this._scopeFire('interactions:down', {
          pointer: pointer,
          event: event,
          eventTarget: eventTarget,
          pointerIndex: pointerIndex,
          pointerInfo: pointerInfo,
          type: 'down',
          interaction: this
        });
      }

      /**
       * ```js
       * interact(target)
       *   .draggable({
       *     // disable the default drag start by down->move
       *     manualStart: true
       *   })
       *   // start dragging after the user holds the pointer down
       *   .on('hold', function (event) {
       *     var interaction = event.interaction
       *
       *     if (!interaction.interacting()) {
       *       interaction.start({ name: 'drag' },
       *                         event.interactable,
       *                         event.currentTarget)
       *     }
       * })
       * ```
       *
       * Start an action with the given Interactable and Element as tartgets. The
       * action must be enabled for the target Interactable and an appropriate
       * number of pointers must be held down - 1 for drag/resize, 2 for gesture.
       *
       * Use it with `interactable.<action>able({ manualStart: false })` to always
       * [start actions manually](https://github.com/taye/interact.js/issues/114)
       *
       * @param action - The action to be performed - drag, resize, etc.
       * @param target - The Interactable to target
       * @param element - The DOM Element to target
       * @returns Whether the interaction was successfully started
       */
    }, {
      key: "start",
      value: function start(action, interactable, element) {
        if (this.interacting() || !this.pointerIsDown || this.pointers.length < (action.name === 'gesture' ? 2 : 1) || !interactable.options[action.name].enabled) {
          return false;
        }
        copyAction(this.prepared, action);
        this.interactable = interactable;
        this.element = element;
        this.rect = interactable.getRect(element);
        this.edges = this.prepared.edges ? extend({}, this.prepared.edges) : {
          left: true,
          right: true,
          top: true,
          bottom: true
        };
        this._stopped = false;
        this._interacting = this._doPhase({
          interaction: this,
          event: this.downEvent,
          phase: 'start'
        }) && !this._stopped;
        return this._interacting;
      }
    }, {
      key: "pointerMove",
      value: function pointerMove(pointer, event, eventTarget) {
        if (!this.simulation && !(this.modification && this.modification.endResult)) {
          this.updatePointer(pointer, event, eventTarget, false);
        }
        var duplicateMove = this.coords.cur.page.x === this.coords.prev.page.x && this.coords.cur.page.y === this.coords.prev.page.y && this.coords.cur.client.x === this.coords.prev.client.x && this.coords.cur.client.y === this.coords.prev.client.y;
        var dx;
        var dy;

        // register movement greater than pointerMoveTolerance
        if (this.pointerIsDown && !this.pointerWasMoved) {
          dx = this.coords.cur.client.x - this.coords.start.client.x;
          dy = this.coords.cur.client.y - this.coords.start.client.y;
          this.pointerWasMoved = hypot(dx, dy) > this.pointerMoveTolerance;
        }
        var pointerIndex = this.getPointerIndex(pointer);
        var signalArg = {
          pointer: pointer,
          pointerIndex: pointerIndex,
          pointerInfo: this.pointers[pointerIndex],
          event: event,
          type: 'move',
          eventTarget: eventTarget,
          dx: dx,
          dy: dy,
          duplicate: duplicateMove,
          interaction: this
        };
        if (!duplicateMove) {
          // set pointer coordinate, time changes and velocity
          setCoordVelocity(this.coords.velocity, this.coords.delta);
        }
        this._scopeFire('interactions:move', signalArg);
        if (!duplicateMove && !this.simulation) {
          // if interacting, fire an 'action-move' signal etc
          if (this.interacting()) {
            signalArg.type = null;
            this.move(signalArg);
          }
          if (this.pointerWasMoved) {
            copyCoords(this.coords.prev, this.coords.cur);
          }
        }
      }

      /**
       * ```js
       * interact(target)
       *   .draggable(true)
       *   .on('dragmove', function (event) {
       *     if (someCondition) {
       *       // change the snap settings
       *       event.interactable.draggable({ snap: { targets: [] }})
       *       // fire another move event with re-calculated snap
       *       event.interaction.move()
       *     }
       *   })
       * ```
       *
       * Force a move of the current action at the same coordinates. Useful if
       * snap/restrict has been changed and you want a movement with the new
       * settings.
       */
    }, {
      key: "move",
      value: function move(signalArg) {
        if (!signalArg || !signalArg.event) {
          setZeroCoords(this.coords.delta);
        }
        signalArg = extend({
          pointer: this._latestPointer.pointer,
          event: this._latestPointer.event,
          eventTarget: this._latestPointer.eventTarget,
          interaction: this
        }, signalArg || {});
        signalArg.phase = 'move';
        this._doPhase(signalArg);
      }

      /**
       * @internal
       * End interact move events and stop auto-scroll unless simulation is running
       */
    }, {
      key: "pointerUp",
      value: function pointerUp(pointer, event, eventTarget, curEventTarget) {
        var pointerIndex = this.getPointerIndex(pointer);
        if (pointerIndex === -1) {
          pointerIndex = this.updatePointer(pointer, event, eventTarget, false);
        }
        var type = /cancel$/i.test(event.type) ? 'cancel' : 'up';
        this._scopeFire("interactions:".concat(type), {
          pointer: pointer,
          pointerIndex: pointerIndex,
          pointerInfo: this.pointers[pointerIndex],
          event: event,
          eventTarget: eventTarget,
          type: type,
          curEventTarget: curEventTarget,
          interaction: this
        });
        if (!this.simulation) {
          this.end(event);
        }
        this.removePointer(pointer, event);
      }

      /** @internal */
    }, {
      key: "documentBlur",
      value: function documentBlur(event) {
        this.end(event);
        this._scopeFire('interactions:blur', {
          event: event,
          type: 'blur',
          interaction: this
        });
      }

      /**
       * ```js
       * interact(target)
       *   .draggable(true)
       *   .on('move', function (event) {
       *     if (event.pageX > 1000) {
       *       // end the current action
       *       event.interaction.end()
       *       // stop all further listeners from being called
       *       event.stopImmediatePropagation()
       *     }
       *   })
       * ```
       */
    }, {
      key: "end",
      value: function end(event) {
        this._ending = true;
        event = event || this._latestPointer.event;
        var endPhaseResult;
        if (this.interacting()) {
          endPhaseResult = this._doPhase({
            event: event,
            interaction: this,
            phase: 'end'
          });
        }
        this._ending = false;
        if (endPhaseResult === true) {
          this.stop();
        }
      }
    }, {
      key: "currentAction",
      value: function currentAction() {
        return this._interacting ? this.prepared.name : null;
      }
    }, {
      key: "interacting",
      value: function interacting() {
        return this._interacting;
      }
    }, {
      key: "stop",
      value: function stop() {
        this._scopeFire('interactions:stop', {
          interaction: this
        });
        this.interactable = this.element = null;
        this._interacting = false;
        this._stopped = true;
        this.prepared.name = this.prevEvent = null;
      }

      /** @internal */
    }, {
      key: "getPointerIndex",
      value: function getPointerIndex(pointer) {
        var pointerId = getPointerId(pointer);

        // mouse and pen interactions may have only one pointer
        return this.pointerType === 'mouse' || this.pointerType === 'pen' ? this.pointers.length - 1 : findIndex(this.pointers, function (curPointer) {
          return curPointer.id === pointerId;
        });
      }

      /** @internal */
    }, {
      key: "getPointerInfo",
      value: function getPointerInfo(pointer) {
        return this.pointers[this.getPointerIndex(pointer)];
      }

      /** @internal */
    }, {
      key: "updatePointer",
      value: function updatePointer(pointer, event, eventTarget, down) {
        var id = getPointerId(pointer);
        var pointerIndex = this.getPointerIndex(pointer);
        var pointerInfo = this.pointers[pointerIndex];
        down = down === false ? false : down || /(down|start)$/i.test(event.type);
        if (!pointerInfo) {
          pointerInfo = new PointerInfo(id, pointer, event, null, null);
          pointerIndex = this.pointers.length;
          this.pointers.push(pointerInfo);
        } else {
          pointerInfo.pointer = pointer;
        }
        setCoords(this.coords.cur, this.pointers.map(function (p) {
          return p.pointer;
        }), this._now());
        setCoordDeltas(this.coords.delta, this.coords.prev, this.coords.cur);
        if (down) {
          this.pointerIsDown = true;
          pointerInfo.downTime = this.coords.cur.timeStamp;
          pointerInfo.downTarget = eventTarget;
          pointerExtend(this.downPointer, pointer);
          if (!this.interacting()) {
            copyCoords(this.coords.start, this.coords.cur);
            copyCoords(this.coords.prev, this.coords.cur);
            this.downEvent = event;
            this.pointerWasMoved = false;
          }
        }
        this._updateLatestPointer(pointer, event, eventTarget);
        this._scopeFire('interactions:update-pointer', {
          pointer: pointer,
          event: event,
          eventTarget: eventTarget,
          down: down,
          pointerInfo: pointerInfo,
          pointerIndex: pointerIndex,
          interaction: this
        });
        return pointerIndex;
      }

      /** @internal */
    }, {
      key: "removePointer",
      value: function removePointer(pointer, event) {
        var pointerIndex = this.getPointerIndex(pointer);
        if (pointerIndex === -1) return;
        var pointerInfo = this.pointers[pointerIndex];
        this._scopeFire('interactions:remove-pointer', {
          pointer: pointer,
          event: event,
          eventTarget: null,
          pointerIndex: pointerIndex,
          pointerInfo: pointerInfo,
          interaction: this
        });
        this.pointers.splice(pointerIndex, 1);
        this.pointerIsDown = false;
      }

      /** @internal */
    }, {
      key: "_updateLatestPointer",
      value: function _updateLatestPointer(pointer, event, eventTarget) {
        this._latestPointer.pointer = pointer;
        this._latestPointer.event = event;
        this._latestPointer.eventTarget = eventTarget;
      }
    }, {
      key: "destroy",
      value: function destroy() {
        this._latestPointer.pointer = null;
        this._latestPointer.event = null;
        this._latestPointer.eventTarget = null;
      }

      /** @internal */
    }, {
      key: "_createPreparedEvent",
      value: function _createPreparedEvent(event, phase, preEnd, type) {
        return new InteractEvent(this, event, this.prepared.name, phase, this.element, preEnd, type);
      }

      /** @internal */
    }, {
      key: "_fireEvent",
      value: function _fireEvent(iEvent) {
        var _this$interactable;
        (_this$interactable = this.interactable) == null ? void 0 : _this$interactable.fire(iEvent);
        if (!this.prevEvent || iEvent.timeStamp >= this.prevEvent.timeStamp) {
          this.prevEvent = iEvent;
        }
      }

      /** @internal */
    }, {
      key: "_doPhase",
      value: function _doPhase(signalArg) {
        var event = signalArg.event,
          phase = signalArg.phase,
          preEnd = signalArg.preEnd,
          type = signalArg.type;
        var rect = this.rect;
        if (rect && phase === 'move') {
          // update the rect changes due to pointer move
          addEdges(this.edges, rect, this.coords.delta[this.interactable.options.deltaSource]);
          rect.width = rect.right - rect.left;
          rect.height = rect.bottom - rect.top;
        }
        var beforeResult = this._scopeFire("interactions:before-action-".concat(phase), signalArg);
        if (beforeResult === false) {
          return false;
        }
        var iEvent = signalArg.iEvent = this._createPreparedEvent(event, phase, preEnd, type);
        this._scopeFire("interactions:action-".concat(phase), signalArg);
        if (phase === 'start') {
          this.prevEvent = iEvent;
        }
        this._fireEvent(iEvent);
        this._scopeFire("interactions:after-action-".concat(phase), signalArg);
        return true;
      }

      /** @internal */
    }, {
      key: "_now",
      value: function _now() {
        return Date.now();
      }
    }]);
    return Interaction;
  }();

  _ProxyMethods.offsetBy = '';
  function addTotal(interaction) {
    if (!interaction.pointerIsDown) {
      return;
    }
    addToCoords(interaction.coords.cur, interaction.offset.total);
    interaction.offset.pending.x = 0;
    interaction.offset.pending.y = 0;
  }
  function beforeAction(_ref) {
    var interaction = _ref.interaction;
    applyPending(interaction);
  }
  function beforeEnd(_ref2) {
    var interaction = _ref2.interaction;
    var hadPending = applyPending(interaction);
    if (!hadPending) return;
    interaction.move({
      offset: true
    });
    interaction.end();
    return false;
  }
  function end(_ref3) {
    var interaction = _ref3.interaction;
    interaction.offset.total.x = 0;
    interaction.offset.total.y = 0;
    interaction.offset.pending.x = 0;
    interaction.offset.pending.y = 0;
  }
  function applyPending(interaction) {
    if (!hasPending(interaction)) {
      return false;
    }
    var pending = interaction.offset.pending;
    addToCoords(interaction.coords.cur, pending);
    addToCoords(interaction.coords.delta, pending);
    addEdges(interaction.edges, interaction.rect, pending);
    pending.x = 0;
    pending.y = 0;
    return true;
  }
  function offsetBy(_ref4) {
    var x = _ref4.x,
      y = _ref4.y;
    this.offset.pending.x += x;
    this.offset.pending.y += y;
    this.offset.total.x += x;
    this.offset.total.y += y;
  }
  function addToCoords(_ref5, _ref6) {
    var page = _ref5.page,
      client = _ref5.client;
    var x = _ref6.x,
      y = _ref6.y;
    page.x += x;
    page.y += y;
    client.x += x;
    client.y += y;
  }
  function hasPending(interaction) {
    return !!(interaction.offset.pending.x || interaction.offset.pending.y);
  }
  var offset = {
    id: 'offset',
    before: ['modifiers', 'pointer-events', 'actions', 'inertia'],
    install: function install(scope) {
      scope.Interaction.prototype.offsetBy = offsetBy;
    },
    listeners: {
      'interactions:new': function interactionsNew(_ref7) {
        var interaction = _ref7.interaction;
        interaction.offset = {
          total: {
            x: 0,
            y: 0
          },
          pending: {
            x: 0,
            y: 0
          }
        };
      },
      'interactions:update-pointer': function interactionsUpdatePointer(_ref8) {
        var interaction = _ref8.interaction;
        return addTotal(interaction);
      },
      'interactions:before-action-start': beforeAction,
      'interactions:before-action-move': beforeAction,
      'interactions:before-action-end': beforeEnd,
      'interactions:stop': end
    }
  };
  var offset$1 = offset;

  function install$6(scope) {
    var defaults = scope.defaults;
    scope.usePlugin(offset$1);
    scope.usePlugin(base);
    scope.actions.phases.inertiastart = true;
    scope.actions.phases.resume = true;
    defaults.perAction.inertia = {
      enabled: false,
      resistance: 10,
      // the lambda in exponential decay
      minSpeed: 100,
      // target speed must be above this for inertia to start
      endSpeed: 10,
      // the speed at which inertia is slow enough to stop
      allowResume: true,
      // allow resuming an action in inertia phase
      smoothEndDuration: 300 // animate to snap/restrict endOnly if there's no inertia
    };
  }
  var InertiaState = /*#__PURE__*/function () {
    function InertiaState(interaction) {
      _classCallCheck(this, InertiaState);
      this.active = false;
      this.isModified = false;
      this.smoothEnd = false;
      this.allowResume = false;
      this.modification = void 0;
      this.modifierCount = 0;
      this.modifierArg = void 0;
      this.startCoords = void 0;
      this.t0 = 0;
      this.v0 = 0;
      this.te = 0;
      this.targetOffset = void 0;
      this.modifiedOffset = void 0;
      this.currentOffset = void 0;
      this.lambda_v0 = 0;
      // eslint-disable-line camelcase
      this.one_ve_v0 = 0;
      // eslint-disable-line camelcase
      this.timeout = void 0;
      this.interaction = void 0;
      this.interaction = interaction;
    }
    _createClass(InertiaState, [{
      key: "start",
      value: function start(event) {
        var interaction = this.interaction;
        var options = getOptions$1(interaction);
        if (!options || !options.enabled) {
          return false;
        }
        var velocityClient = interaction.coords.velocity.client;
        var pointerSpeed = hypot(velocityClient.x, velocityClient.y);
        var modification = this.modification || (this.modification = new Modification(interaction));
        modification.copyFrom(interaction.modification);
        this.t0 = interaction._now();
        this.allowResume = options.allowResume;
        this.v0 = pointerSpeed;
        this.currentOffset = {
          x: 0,
          y: 0
        };
        this.startCoords = interaction.coords.cur.page;
        this.modifierArg = modification.fillArg({
          pageCoords: this.startCoords,
          preEnd: true,
          phase: 'inertiastart'
        });
        var thrown = this.t0 - interaction.coords.cur.timeStamp < 50 && pointerSpeed > options.minSpeed && pointerSpeed > options.endSpeed;
        if (thrown) {
          this.startInertia();
        } else {
          modification.result = modification.setAll(this.modifierArg);
          if (!modification.result.changed) {
            return false;
          }
          this.startSmoothEnd();
        }

        // force modification change
        interaction.modification.result.rect = null;

        // bring inertiastart event to the target coords
        interaction.offsetBy(this.targetOffset);
        interaction._doPhase({
          interaction: interaction,
          event: event,
          phase: 'inertiastart'
        });
        interaction.offsetBy({
          x: -this.targetOffset.x,
          y: -this.targetOffset.y
        });
        // force modification change
        interaction.modification.result.rect = null;
        this.active = true;
        interaction.simulation = this;
        return true;
      }
    }, {
      key: "startInertia",
      value: function startInertia() {
        var _this = this;
        var startVelocity = this.interaction.coords.velocity.client;
        var options = getOptions$1(this.interaction);
        var lambda = options.resistance;
        var inertiaDur = -Math.log(options.endSpeed / this.v0) / lambda;
        this.targetOffset = {
          x: (startVelocity.x - inertiaDur) / lambda,
          y: (startVelocity.y - inertiaDur) / lambda
        };
        this.te = inertiaDur;
        this.lambda_v0 = lambda / this.v0;
        this.one_ve_v0 = 1 - options.endSpeed / this.v0;
        var modification = this.modification,
          modifierArg = this.modifierArg;
        modifierArg.pageCoords = {
          x: this.startCoords.x + this.targetOffset.x,
          y: this.startCoords.y + this.targetOffset.y
        };
        modification.result = modification.setAll(modifierArg);
        if (modification.result.changed) {
          this.isModified = true;
          this.modifiedOffset = {
            x: this.targetOffset.x + modification.result.delta.x,
            y: this.targetOffset.y + modification.result.delta.y
          };
        }
        this.onNextFrame(function () {
          return _this.inertiaTick();
        });
      }
    }, {
      key: "startSmoothEnd",
      value: function startSmoothEnd() {
        var _this2 = this;
        this.smoothEnd = true;
        this.isModified = true;
        this.targetOffset = {
          x: this.modification.result.delta.x,
          y: this.modification.result.delta.y
        };
        this.onNextFrame(function () {
          return _this2.smoothEndTick();
        });
      }
    }, {
      key: "onNextFrame",
      value: function onNextFrame(tickFn) {
        var _this3 = this;
        this.timeout = raf.request(function () {
          if (_this3.active) {
            tickFn();
          }
        });
      }
    }, {
      key: "inertiaTick",
      value: function inertiaTick() {
        var _this4 = this;
        var interaction = this.interaction;
        var options = getOptions$1(interaction);
        var lambda = options.resistance;
        var t = (interaction._now() - this.t0) / 1000;
        if (t < this.te) {
          var progress = 1 - (Math.exp(-lambda * t) - this.lambda_v0) / this.one_ve_v0;
          var newOffset;
          if (this.isModified) {
            newOffset = getQuadraticCurvePoint(0, 0, this.targetOffset.x, this.targetOffset.y, this.modifiedOffset.x, this.modifiedOffset.y, progress);
          } else {
            newOffset = {
              x: this.targetOffset.x * progress,
              y: this.targetOffset.y * progress
            };
          }
          var delta = {
            x: newOffset.x - this.currentOffset.x,
            y: newOffset.y - this.currentOffset.y
          };
          this.currentOffset.x += delta.x;
          this.currentOffset.y += delta.y;
          interaction.offsetBy(delta);
          interaction.move();
          this.onNextFrame(function () {
            return _this4.inertiaTick();
          });
        } else {
          interaction.offsetBy({
            x: this.modifiedOffset.x - this.currentOffset.x,
            y: this.modifiedOffset.y - this.currentOffset.y
          });
          this.end();
        }
      }
    }, {
      key: "smoothEndTick",
      value: function smoothEndTick() {
        var _this5 = this;
        var interaction = this.interaction;
        var t = interaction._now() - this.t0;
        var _getOptions = getOptions$1(interaction),
          duration = _getOptions.smoothEndDuration;
        if (t < duration) {
          var newOffset = {
            x: easeOutQuad(t, 0, this.targetOffset.x, duration),
            y: easeOutQuad(t, 0, this.targetOffset.y, duration)
          };
          var delta = {
            x: newOffset.x - this.currentOffset.x,
            y: newOffset.y - this.currentOffset.y
          };
          this.currentOffset.x += delta.x;
          this.currentOffset.y += delta.y;
          interaction.offsetBy(delta);
          interaction.move({
            skipModifiers: this.modifierCount
          });
          this.onNextFrame(function () {
            return _this5.smoothEndTick();
          });
        } else {
          interaction.offsetBy({
            x: this.targetOffset.x - this.currentOffset.x,
            y: this.targetOffset.y - this.currentOffset.y
          });
          this.end();
        }
      }
    }, {
      key: "resume",
      value: function resume(_ref) {
        var pointer = _ref.pointer,
          event = _ref.event,
          eventTarget = _ref.eventTarget;
        var interaction = this.interaction;

        // undo inertia changes to interaction coords
        interaction.offsetBy({
          x: -this.currentOffset.x,
          y: -this.currentOffset.y
        });

        // update pointer at pointer down position
        interaction.updatePointer(pointer, event, eventTarget, true);

        // fire resume signals and event
        interaction._doPhase({
          interaction: interaction,
          event: event,
          phase: 'resume'
        });
        copyCoords(interaction.coords.prev, interaction.coords.cur);
        this.stop();
      }
    }, {
      key: "end",
      value: function end() {
        this.interaction.move();
        this.interaction.end();
        this.stop();
      }
    }, {
      key: "stop",
      value: function stop() {
        this.active = this.smoothEnd = false;
        this.interaction.simulation = null;
        raf.cancel(this.timeout);
      }
    }]);
    return InertiaState;
  }();
  function start$6(_ref2) {
    var interaction = _ref2.interaction,
      event = _ref2.event;
    if (!interaction._interacting || interaction.simulation) {
      return null;
    }
    var started = interaction.inertia.start(event);

    // prevent action end if inertia or smoothEnd
    return started ? false : null;
  }

  // Check if the down event hits the current inertia target
  // control should be return to the user
  function resume(arg) {
    var interaction = arg.interaction,
      eventTarget = arg.eventTarget;
    var state = interaction.inertia;
    if (!state.active) return;
    var element = eventTarget;

    // climb up the DOM tree from the event target
    while (is.element(element)) {
      // if interaction element is the current inertia target element
      if (element === interaction.element) {
        state.resume(arg);
        break;
      }
      element = parentNode(element);
    }
  }
  function stop(_ref3) {
    var interaction = _ref3.interaction;
    var state = interaction.inertia;
    if (state.active) {
      state.stop();
    }
  }
  function getOptions$1(_ref4) {
    var interactable = _ref4.interactable,
      prepared = _ref4.prepared;
    return interactable && interactable.options && prepared.name && interactable.options[prepared.name].inertia;
  }
  var inertia = {
    id: 'inertia',
    before: ['modifiers', 'actions'],
    install: install$6,
    listeners: {
      'interactions:new': function interactionsNew(_ref5) {
        var interaction = _ref5.interaction;
        interaction.inertia = new InertiaState(interaction);
      },
      'interactions:before-action-end': start$6,
      'interactions:down': resume,
      'interactions:stop': stop,
      'interactions:before-action-resume': function interactionsBeforeActionResume(arg) {
        var modification = arg.interaction.modification;
        modification.stop(arg);
        modification.start(arg, arg.interaction.coords.cur.page);
        modification.applyToInteraction(arg);
      },
      'interactions:before-action-inertiastart': function interactionsBeforeActionInertiastart(arg) {
        return arg.interaction.modification.setAndApply(arg);
      },
      'interactions:action-resume': addEventModifiers,
      'interactions:action-inertiastart': addEventModifiers,
      'interactions:after-action-inertiastart': function interactionsAfterActionInertiastart(arg) {
        return arg.interaction.modification.restoreInteractionCoords(arg);
      },
      'interactions:after-action-resume': function interactionsAfterActionResume(arg) {
        return arg.interaction.modification.restoreInteractionCoords(arg);
      }
    }
  };

  // http://stackoverflow.com/a/5634528/2280888
  function _getQBezierValue(t, p1, p2, p3) {
    var iT = 1 - t;
    return iT * iT * p1 + 2 * iT * t * p2 + t * t * p3;
  }
  function getQuadraticCurvePoint(startX, startY, cpX, cpY, endX, endY, position) {
    return {
      x: _getQBezierValue(position, startX, cpX, endX),
      y: _getQBezierValue(position, startY, cpY, endY)
    };
  }

  // http://gizma.com/easing/
  function easeOutQuad(t, b, c, d) {
    t /= d;
    return -c * t * (t - 2) + b;
  }
  var inertia$1 = inertia;

  function fireUntilImmediateStopped(event, listeners) {
    for (var _i2 = 0; _i2 < listeners.length; _i2++) {
      var listener = listeners[_i2];
      if (event.immediatePropagationStopped) {
        break;
      }
      listener(event);
    }
  }
  var Eventable = /*#__PURE__*/function () {
    function Eventable(options) {
      _classCallCheck(this, Eventable);
      this.options = void 0;
      this.types = {};
      this.propagationStopped = false;
      this.immediatePropagationStopped = false;
      this.global = void 0;
      this.options = extend({}, options || {});
    }
    _createClass(Eventable, [{
      key: "fire",
      value: function fire(event) {
        var listeners;
        var global = this.global;

        // Interactable#on() listeners
        // tslint:disable no-conditional-assignment
        if (listeners = this.types[event.type]) {
          fireUntilImmediateStopped(event, listeners);
        }

        // interact.on() listeners
        if (!event.propagationStopped && global && (listeners = global[event.type])) {
          fireUntilImmediateStopped(event, listeners);
        }
      }
    }, {
      key: "on",
      value: function on(type, listener) {
        var listeners = normalize(type, listener);
        for (type in listeners) {
          this.types[type] = merge(this.types[type] || [], listeners[type]);
        }
      }
    }, {
      key: "off",
      value: function off(type, listener) {
        var listeners = normalize(type, listener);
        for (type in listeners) {
          var eventList = this.types[type];
          if (!eventList || !eventList.length) {
            continue;
          }
          for (var _i4 = 0, _listeners$type2 = listeners[type]; _i4 < _listeners$type2.length; _i4++) {
            var subListener = _listeners$type2[_i4];
            var _index = eventList.indexOf(subListener);
            if (_index !== -1) {
              eventList.splice(_index, 1);
            }
          }
        }
      }
    }, {
      key: "getRect",
      value: function getRect(_element) {
        return null;
      }
    }]);
    return Eventable;
  }();

  function install$5(scope) {
    var _scope$document;
    var targets = [];
    var delegatedEvents = {};
    var documents = [];
    var eventsMethods = {
      add: add,
      remove: remove,
      addDelegate: addDelegate,
      removeDelegate: removeDelegate,
      delegateListener: delegateListener,
      delegateUseCapture: delegateUseCapture,
      delegatedEvents: delegatedEvents,
      documents: documents,
      targets: targets,
      supportsOptions: false,
      supportsPassive: false
    };

    // check if browser supports passive events and options arg
    (_scope$document = scope.document) == null ? void 0 : _scope$document.createElement('div').addEventListener('test', null, {
      get capture() {
        return eventsMethods.supportsOptions = true;
      },
      get passive() {
        return eventsMethods.supportsPassive = true;
      }
    });
    scope.events = eventsMethods;
    function add(eventTarget, type, listener, optionalArg) {
      if (!eventTarget.addEventListener) return;
      var options = getOptions(optionalArg);
      var target = find(targets, function (t) {
        return t.eventTarget === eventTarget;
      });
      if (!target) {
        target = {
          eventTarget: eventTarget,
          events: {}
        };
        targets.push(target);
      }
      if (!target.events[type]) {
        target.events[type] = [];
      }
      if (!find(target.events[type], function (l) {
        return l.func === listener && optionsMatch(l.options, options);
      })) {
        eventTarget.addEventListener(type, listener, eventsMethods.supportsOptions ? options : options.capture);
        target.events[type].push({
          func: listener,
          options: options
        });
      }
    }
    function remove(eventTarget, type, listener, optionalArg) {
      if (!eventTarget.addEventListener || !eventTarget.removeEventListener) return;
      var targetIndex = findIndex(targets, function (t) {
        return t.eventTarget === eventTarget;
      });
      var target = targets[targetIndex];
      if (!target || !target.events) {
        return;
      }
      if (type === 'all') {
        for (type in target.events) {
          if (target.events.hasOwnProperty(type)) {
            remove(eventTarget, type, 'all');
          }
        }
        return;
      }
      var typeIsEmpty = false;
      var typeListeners = target.events[type];
      if (typeListeners) {
        if (listener === 'all') {
          for (var i = typeListeners.length - 1; i >= 0; i--) {
            var entry = typeListeners[i];
            remove(eventTarget, type, entry.func, entry.options);
          }
          return;
        } else {
          var options = getOptions(optionalArg);
          for (var _i = 0; _i < typeListeners.length; _i++) {
            var _entry = typeListeners[_i];
            if (_entry.func === listener && optionsMatch(_entry.options, options)) {
              eventTarget.removeEventListener(type, listener, eventsMethods.supportsOptions ? options : options.capture);
              typeListeners.splice(_i, 1);
              if (typeListeners.length === 0) {
                delete target.events[type];
                typeIsEmpty = true;
              }
              break;
            }
          }
        }
      }
      if (typeIsEmpty && !Object.keys(target.events).length) {
        targets.splice(targetIndex, 1);
      }
    }
    function addDelegate(selector, context, type, listener, optionalArg) {
      var options = getOptions(optionalArg);
      if (!delegatedEvents[type]) {
        delegatedEvents[type] = [];

        // add delegate listener functions
        for (var _i3 = 0; _i3 < documents.length; _i3++) {
          var doc = documents[_i3];
          add(doc, type, delegateListener);
          add(doc, type, delegateUseCapture, true);
        }
      }
      var delegates = delegatedEvents[type];
      var delegate = find(delegates, function (d) {
        return d.selector === selector && d.context === context;
      });
      if (!delegate) {
        delegate = {
          selector: selector,
          context: context,
          listeners: []
        };
        delegates.push(delegate);
      }
      delegate.listeners.push({
        func: listener,
        options: options
      });
    }
    function removeDelegate(selector, context, type, listener, optionalArg) {
      var options = getOptions(optionalArg);
      var delegates = delegatedEvents[type];
      var matchFound = false;
      var index;
      if (!delegates) return;

      // count from last index of delegated to 0
      for (index = delegates.length - 1; index >= 0; index--) {
        var cur = delegates[index];
        // look for matching selector and context Node
        if (cur.selector === selector && cur.context === context) {
          var listeners = cur.listeners;

          // each item of the listeners array is an array: [function, capture, passive]
          for (var i = listeners.length - 1; i >= 0; i--) {
            var entry = listeners[i];

            // check if the listener functions and capture and passive flags match
            if (entry.func === listener && optionsMatch(entry.options, options)) {
              // remove the listener from the array of listeners
              listeners.splice(i, 1);

              // if all listeners for this target have been removed
              // remove the target from the delegates array
              if (!listeners.length) {
                delegates.splice(index, 1);

                // remove delegate function from context
                remove(context, type, delegateListener);
                remove(context, type, delegateUseCapture, true);
              }

              // only remove one listener
              matchFound = true;
              break;
            }
          }
          if (matchFound) {
            break;
          }
        }
      }
    }

    // bound to the interactable context when a DOM event
    // listener is added to a selector interactable
    function delegateListener(event, optionalArg) {
      var options = getOptions(optionalArg);
      var fakeEvent = new FakeEvent(event);
      var delegates = delegatedEvents[event.type];
      var _pointerUtils$getEven = getEventTargets(event),
        eventTarget = _pointerUtils$getEven[0];
      var element = eventTarget;

      // climb up document tree looking for selector matches
      while (is.element(element)) {
        for (var i = 0; i < delegates.length; i++) {
          var cur = delegates[i];
          var selector = cur.selector,
            context = cur.context;
          if (matchesSelector(element, selector) && nodeContains(context, eventTarget) && nodeContains(context, element)) {
            var listeners = cur.listeners;
            fakeEvent.currentTarget = element;
            for (var _i5 = 0; _i5 < listeners.length; _i5++) {
              var entry = listeners[_i5];
              if (optionsMatch(entry.options, options)) {
                entry.func(fakeEvent);
              }
            }
          }
        }
        element = parentNode(element);
      }
    }
    function delegateUseCapture(event) {
      return delegateListener.call(this, event, true);
    }

    // for type inferrence
    return eventsMethods;
  }
  var FakeEvent = /*#__PURE__*/function () {
    function FakeEvent(originalEvent) {
      _classCallCheck(this, FakeEvent);
      this.currentTarget = void 0;
      this.originalEvent = void 0;
      this.type = void 0;
      this.originalEvent = originalEvent;
      // duplicate the event so that currentTarget can be changed
      pointerExtend(this, originalEvent);
    }
    _createClass(FakeEvent, [{
      key: "preventOriginalDefault",
      value: function preventOriginalDefault() {
        this.originalEvent.preventDefault();
      }
    }, {
      key: "stopPropagation",
      value: function stopPropagation() {
        this.originalEvent.stopPropagation();
      }
    }, {
      key: "stopImmediatePropagation",
      value: function stopImmediatePropagation() {
        this.originalEvent.stopImmediatePropagation();
      }
    }]);
    return FakeEvent;
  }();
  function getOptions(param) {
    if (!is.object(param)) {
      return {
        capture: !!param,
        passive: false
      };
    }
    return {
      capture: !!param.capture,
      passive: !!param.passive
    };
  }
  function optionsMatch(a, b) {
    if (a === b) return true;
    if (typeof a === 'boolean') return !!b.capture === a && !!b.passive === false;
    return !!a.capture === !!b.capture && !!a.passive === !!b.passive;
  }
  var events = {
    id: 'events',
    install: install$5
  };

  var finder = {
    methodOrder: ['simulationResume', 'mouseOrPen', 'hasPointer', 'idle'],
    search: function search(details) {
      for (var _i2 = 0, _finder$methodOrder2 = finder.methodOrder; _i2 < _finder$methodOrder2.length; _i2++) {
        var method = _finder$methodOrder2[_i2];
        var interaction = finder[method](details);
        if (interaction) {
          return interaction;
        }
      }
      return null;
    },
    // try to resume simulation with a new pointer
    simulationResume: function simulationResume(_ref) {
      var pointerType = _ref.pointerType,
        eventType = _ref.eventType,
        eventTarget = _ref.eventTarget,
        scope = _ref.scope;
      if (!/down|start/i.test(eventType)) {
        return null;
      }
      for (var _i4 = 0, _scope$interactions$l2 = scope.interactions.list; _i4 < _scope$interactions$l2.length; _i4++) {
        var interaction = _scope$interactions$l2[_i4];
        var element = eventTarget;
        if (interaction.simulation && interaction.simulation.allowResume && interaction.pointerType === pointerType) {
          while (element) {
            // if the element is the interaction element
            if (element === interaction.element) {
              return interaction;
            }
            element = parentNode(element);
          }
        }
      }
      return null;
    },
    // if it's a mouse or pen interaction
    mouseOrPen: function mouseOrPen(_ref2) {
      var pointerId = _ref2.pointerId,
        pointerType = _ref2.pointerType,
        eventType = _ref2.eventType,
        scope = _ref2.scope;
      if (pointerType !== 'mouse' && pointerType !== 'pen') {
        return null;
      }
      var firstNonActive;
      for (var _i6 = 0, _scope$interactions$l4 = scope.interactions.list; _i6 < _scope$interactions$l4.length; _i6++) {
        var interaction = _scope$interactions$l4[_i6];
        if (interaction.pointerType === pointerType) {
          // if it's a down event, skip interactions with running simulations
          if (interaction.simulation && !hasPointerId(interaction, pointerId)) {
            continue;
          }

          // if the interaction is active, return it immediately
          if (interaction.interacting()) {
            return interaction;
          }
          // otherwise save it and look for another active interaction
          else if (!firstNonActive) {
            firstNonActive = interaction;
          }
        }
      } // if no active mouse interaction was found use the first inactive mouse
      // interaction
      if (firstNonActive) {
        return firstNonActive;
      }

      // find any mouse or pen interaction.
      // ignore the interaction if the eventType is a *down, and a simulation
      // is active
      for (var _i8 = 0, _scope$interactions$l6 = scope.interactions.list; _i8 < _scope$interactions$l6.length; _i8++) {
        var _interaction = _scope$interactions$l6[_i8];
        if (_interaction.pointerType === pointerType && !(/down/i.test(eventType) && _interaction.simulation)) {
          return _interaction;
        }
      }
      return null;
    },
    // get interaction that has this pointer
    hasPointer: function hasPointer(_ref3) {
      var pointerId = _ref3.pointerId,
        scope = _ref3.scope;
      for (var _i10 = 0, _scope$interactions$l8 = scope.interactions.list; _i10 < _scope$interactions$l8.length; _i10++) {
        var interaction = _scope$interactions$l8[_i10];
        if (hasPointerId(interaction, pointerId)) {
          return interaction;
        }
      }
      return null;
    },
    // get first idle interaction with a matching pointerType
    idle: function idle(_ref4) {
      var pointerType = _ref4.pointerType,
        scope = _ref4.scope;
      for (var _i12 = 0, _scope$interactions$l10 = scope.interactions.list; _i12 < _scope$interactions$l10.length; _i12++) {
        var interaction = _scope$interactions$l10[_i12];
        // if there's already a pointer held down
        if (interaction.pointers.length === 1) {
          var target = interaction.interactable;
          // don't add this pointer if there is a target interactable and it
          // isn't gesturable
          if (target && !(target.options.gesture && target.options.gesture.enabled)) {
            continue;
          }
        }
        // maximum of 2 pointers per interaction
        else if (interaction.pointers.length >= 2) {
          continue;
        }
        if (!interaction.interacting() && pointerType === interaction.pointerType) {
          return interaction;
        }
      }
      return null;
    }
  };
  function hasPointerId(interaction, pointerId) {
    return interaction.pointers.some(function (_ref5) {
      var id = _ref5.id;
      return id === pointerId;
    });
  }
  var finder$1 = finder;

  var methodNames = ['pointerDown', 'pointerMove', 'pointerUp', 'updatePointer', 'removePointer', 'windowBlur'];
  function install$4(scope) {
    var listeners = {};
    for (var _i2 = 0; _i2 < methodNames.length; _i2++) {
      var method = methodNames[_i2];
      listeners[method] = doOnInteractions(method, scope);
    }
    var pEventTypes = browser$1.pEventTypes;
    var docEvents;
    if (domObjects$1.PointerEvent) {
      docEvents = [{
        type: pEventTypes.down,
        listener: releasePointersOnRemovedEls
      }, {
        type: pEventTypes.down,
        listener: listeners.pointerDown
      }, {
        type: pEventTypes.move,
        listener: listeners.pointerMove
      }, {
        type: pEventTypes.up,
        listener: listeners.pointerUp
      }, {
        type: pEventTypes.cancel,
        listener: listeners.pointerUp
      }];
    } else {
      docEvents = [{
        type: 'mousedown',
        listener: listeners.pointerDown
      }, {
        type: 'mousemove',
        listener: listeners.pointerMove
      }, {
        type: 'mouseup',
        listener: listeners.pointerUp
      }, {
        type: 'touchstart',
        listener: releasePointersOnRemovedEls
      }, {
        type: 'touchstart',
        listener: listeners.pointerDown
      }, {
        type: 'touchmove',
        listener: listeners.pointerMove
      }, {
        type: 'touchend',
        listener: listeners.pointerUp
      }, {
        type: 'touchcancel',
        listener: listeners.pointerUp
      }];
    }
    docEvents.push({
      type: 'blur',
      listener: function listener(event) {
        for (var _i4 = 0, _scope$interactions$l2 = scope.interactions.list; _i4 < _scope$interactions$l2.length; _i4++) {
          var interaction = _scope$interactions$l2[_i4];
          interaction.documentBlur(event);
        }
      }
    });

    // for ignoring browser's simulated mouse events
    scope.prevTouchTime = 0;
    scope.Interaction = /*#__PURE__*/function (_InteractionBase) {
      _inherits(_class, _InteractionBase);
      var _super = _createSuper(_class);
      function _class() {
        _classCallCheck(this, _class);
        return _super.apply(this, arguments);
      }
      _createClass(_class, [{
        key: "pointerMoveTolerance",
        get: function get() {
          return scope.interactions.pointerMoveTolerance;
        },
        set: function set(value) {
          scope.interactions.pointerMoveTolerance = value;
        }
      }, {
        key: "_now",
        value: function _now() {
          return scope.now();
        }
      }]);
      return _class;
    }(Interaction);
    scope.interactions = {
      // all active and idle interactions
      list: [],
      new: function _new(options) {
        options.scopeFire = function (name, arg) {
          return scope.fire(name, arg);
        };
        var interaction = new scope.Interaction(options);
        scope.interactions.list.push(interaction);
        return interaction;
      },
      listeners: listeners,
      docEvents: docEvents,
      pointerMoveTolerance: 1
    };
    function releasePointersOnRemovedEls() {
      // for all inactive touch interactions with pointers down
      for (var _i6 = 0, _scope$interactions$l4 = scope.interactions.list; _i6 < _scope$interactions$l4.length; _i6++) {
        var interaction = _scope$interactions$l4[_i6];
        if (!interaction.pointerIsDown || interaction.pointerType !== 'touch' || interaction._interacting) {
          continue;
        }

        // if a pointer is down on an element that is no longer in the DOM tree
        var _loop = function _loop() {
          var pointer = _interaction$pointers2[_i8];
          if (!scope.documents.some(function (_ref) {
            var doc = _ref.doc;
            return nodeContains(doc, pointer.downTarget);
          })) {
            // remove the pointer from the interaction
            interaction.removePointer(pointer.pointer, pointer.event);
          }
        };
        for (var _i8 = 0, _interaction$pointers2 = interaction.pointers; _i8 < _interaction$pointers2.length; _i8++) {
          _loop();
        }
      }
    }
    scope.usePlugin(interactablePreventDefault);
  }
  function doOnInteractions(method, scope) {
    return function (event) {
      var interactions = scope.interactions.list;
      var pointerType = getPointerType(event);
      var _pointerUtils$getEven = getEventTargets(event),
        eventTarget = _pointerUtils$getEven[0],
        curEventTarget = _pointerUtils$getEven[1];
      var matches = []; // [ [pointer, interaction], ...]

      if (/^touch/.test(event.type)) {
        scope.prevTouchTime = scope.now();

        // @ts-expect-error
        for (var _i10 = 0, _event$changedTouches2 = event.changedTouches; _i10 < _event$changedTouches2.length; _i10++) {
          var changedTouch = _event$changedTouches2[_i10];
          var pointer = changedTouch;
          var pointerId = getPointerId(pointer);
          var searchDetails = {
            pointer: pointer,
            pointerId: pointerId,
            pointerType: pointerType,
            eventType: event.type,
            eventTarget: eventTarget,
            curEventTarget: curEventTarget,
            scope: scope
          };
          var interaction = getInteraction(searchDetails);
          matches.push([searchDetails.pointer, searchDetails.eventTarget, searchDetails.curEventTarget, interaction]);
        }
      } else {
        var invalidPointer = false;
        if (!browser$1.supportsPointerEvent && /mouse/.test(event.type)) {
          // ignore mouse events while touch interactions are active
          for (var i = 0; i < interactions.length && !invalidPointer; i++) {
            invalidPointer = interactions[i].pointerType !== 'mouse' && interactions[i].pointerIsDown;
          }

          // try to ignore mouse events that are simulated by the browser
          // after a touch event
          invalidPointer = invalidPointer || scope.now() - scope.prevTouchTime < 500 ||
          // on iOS and Firefox Mobile, MouseEvent.timeStamp is zero if simulated
          event.timeStamp === 0;
        }
        if (!invalidPointer) {
          var _searchDetails = {
            pointer: event,
            pointerId: getPointerId(event),
            pointerType: pointerType,
            eventType: event.type,
            curEventTarget: curEventTarget,
            eventTarget: eventTarget,
            scope: scope
          };
          var _interaction = getInteraction(_searchDetails);
          matches.push([_searchDetails.pointer, _searchDetails.eventTarget, _searchDetails.curEventTarget, _interaction]);
        }
      }

      // eslint-disable-next-line no-shadow
      for (var _i12 = 0; _i12 < matches.length; _i12++) {
        var _matches$_i = matches[_i12],
          _pointer = _matches$_i[0],
          _eventTarget = _matches$_i[1],
          _curEventTarget = _matches$_i[2],
          _interaction2 = _matches$_i[3];
        _interaction2[method](_pointer, event, _eventTarget, _curEventTarget);
      }
    };
  }
  function getInteraction(searchDetails) {
    var pointerType = searchDetails.pointerType,
      scope = searchDetails.scope;
    var foundInteraction = finder$1.search(searchDetails);
    var signalArg = {
      interaction: foundInteraction,
      searchDetails: searchDetails
    };
    scope.fire('interactions:find', signalArg);
    return signalArg.interaction || scope.interactions.new({
      pointerType: pointerType
    });
  }
  function onDocSignal(_ref2, eventMethodName) {
    var doc = _ref2.doc,
      scope = _ref2.scope,
      options = _ref2.options;
    var docEvents = scope.interactions.docEvents,
      events = scope.events;
    var eventMethod = events[eventMethodName];
    if (scope.browser.isIOS && !options.events) {
      options.events = {
        passive: false
      };
    }

    // delegate event listener
    for (var eventType in events.delegatedEvents) {
      eventMethod(doc, eventType, events.delegateListener);
      eventMethod(doc, eventType, events.delegateUseCapture, true);
    }
    var eventOptions = options && options.events;
    for (var _i14 = 0; _i14 < docEvents.length; _i14++) {
      var _docEvents$_i = docEvents[_i14],
        _type = _docEvents$_i.type,
        listener = _docEvents$_i.listener;
      eventMethod(doc, _type, listener, eventOptions);
    }
  }
  var interactions = {
    id: 'core/interactions',
    install: install$4,
    listeners: {
      'scope:add-document': function scopeAddDocument(arg) {
        return onDocSignal(arg, 'add');
      },
      'scope:remove-document': function scopeRemoveDocument(arg) {
        return onDocSignal(arg, 'remove');
      },
      'interactable:unset': function interactableUnset(_ref3, scope) {
        var interactable = _ref3.interactable;
        // Stop and destroy related interactions when an Interactable is unset
        for (var i = scope.interactions.list.length - 1; i >= 0; i--) {
          var interaction = scope.interactions.list[i];
          if (interaction.interactable !== interactable) {
            continue;
          }
          interaction.stop();
          scope.fire('interactions:destroy', {
            interaction: interaction
          });
          interaction.destroy();
          if (scope.interactions.list.length > 2) {
            scope.interactions.list.splice(i, 1);
          }
        }
      }
    },
    onDocSignal: onDocSignal,
    doOnInteractions: doOnInteractions,
    methodNames: methodNames
  };
  var interactions$1 = interactions;

  var OnOffMethod = /*#__PURE__*/function (OnOffMethod) {
    OnOffMethod[OnOffMethod["On"] = 0] = "On";
    OnOffMethod[OnOffMethod["Off"] = 1] = "Off";
    return OnOffMethod;
  }(OnOffMethod || {});
  /**
   * ```ts
   * const interactable = interact('.cards')
   *   .draggable({
   *     listeners: { move: event => console.log(event.type, event.pageX, event.pageY) }
   *   })
   *   .resizable({
   *     listeners: { move: event => console.log(event.rect) },
   *     modifiers: [interact.modifiers.restrictEdges({ outer: 'parent' })]
   *   })
   * ```
   */
  var Interactable = /*#__PURE__*/function () {
    function Interactable(target, options, defaultContext, scopeEvents) {
      _classCallCheck(this, Interactable);
      this.target = void 0;
      /** @internal */
      this.options = void 0;
      /** @internal */
      this._actions = void 0;
      /** @internal */
      this.events = new Eventable();
      /** @internal */
      this._context = void 0;
      /** @internal */
      this._win = void 0;
      /** @internal */
      this._doc = void 0;
      /** @internal */
      this._scopeEvents = void 0;
      this._actions = options.actions;
      this.target = target;
      this._context = options.context || defaultContext;
      this._win = getWindow(trySelector(target) ? this._context : target);
      this._doc = this._win.document;
      this._scopeEvents = scopeEvents;
      this.set(options);
    }
    _createClass(Interactable, [{
      key: "_defaults",
      get: /** @internal */function get() {
        return {
          base: {},
          perAction: {},
          actions: {}
        };
      }
    }, {
      key: "setOnEvents",
      value: function setOnEvents(actionName, phases) {
        if (is.func(phases.onstart)) {
          this.on("".concat(actionName, "start"), phases.onstart);
        }
        if (is.func(phases.onmove)) {
          this.on("".concat(actionName, "move"), phases.onmove);
        }
        if (is.func(phases.onend)) {
          this.on("".concat(actionName, "end"), phases.onend);
        }
        if (is.func(phases.oninertiastart)) {
          this.on("".concat(actionName, "inertiastart"), phases.oninertiastart);
        }
        return this;
      }
    }, {
      key: "updatePerActionListeners",
      value: function updatePerActionListeners(actionName, prev, cur) {
        var _this$_actions$map$ac,
          _this = this;
        var actionFilter = (_this$_actions$map$ac = this._actions.map[actionName]) == null ? void 0 : _this$_actions$map$ac.filterEventType;
        var filter = function filter(type) {
          return (actionFilter == null || actionFilter(type)) && isNonNativeEvent(type, _this._actions);
        };
        if (is.array(prev) || is.object(prev)) {
          this._onOff(OnOffMethod.Off, actionName, prev, undefined, filter);
        }
        if (is.array(cur) || is.object(cur)) {
          this._onOff(OnOffMethod.On, actionName, cur, undefined, filter);
        }
      }
    }, {
      key: "setPerAction",
      value: function setPerAction(actionName, options) {
        var defaults = this._defaults;

        // for all the default per-action options
        for (var optionName_ in options) {
          var optionName = optionName_;
          var actionOptions = this.options[actionName];
          var optionValue = options[optionName];

          // remove old event listeners and add new ones
          if (optionName === 'listeners') {
            this.updatePerActionListeners(actionName, actionOptions.listeners, optionValue);
          }

          // if the option value is an array
          if (is.array(optionValue)) {
            actionOptions[optionName] = from(optionValue);
          }
          // if the option value is an object
          else if (is.plainObject(optionValue)) {
            actionOptions[optionName] = extend(actionOptions[optionName] || {}, clone(optionValue));

            // set anabled field to true if it exists in the defaults
            if (is.object(defaults.perAction[optionName]) && 'enabled' in defaults.perAction[optionName]) {
              actionOptions[optionName].enabled = optionValue.enabled !== false;
            }
          }
          // if the option value is a boolean and the default is an object
          else if (is.bool(optionValue) && is.object(defaults.perAction[optionName])) {
            actionOptions[optionName].enabled = optionValue;
          }
          // if it's anything else, do a plain assignment
          else {
            actionOptions[optionName] = optionValue;
          }
        }
      }

      /**
       * The default function to get an Interactables bounding rect. Can be
       * overridden using {@link Interactable.rectChecker}.
       *
       * @param {Element} [element] The element to measure.
       * @return {Rect} The object's bounding rectangle.
       */
    }, {
      key: "getRect",
      value: function getRect(element) {
        element = element || (is.element(this.target) ? this.target : null);
        if (is.string(this.target)) {
          element = element || this._context.querySelector(this.target);
        }
        return getElementRect(element);
      }

      /**
       * Returns or sets the function used to calculate the interactable's
       * element's rectangle
       *
       * @param {function} [checker] A function which returns this Interactable's
       * bounding rectangle. See {@link Interactable.getRect}
       * @return {function | object} The checker function or this Interactable
       */
    }, {
      key: "rectChecker",
      value: function rectChecker(checker) {
        var _this2 = this;
        if (is.func(checker)) {
          this.getRect = function (element) {
            var rect = extend({}, checker.apply(_this2, element));
            if (!('width' in rect)) {
              rect.width = rect.right - rect.left;
              rect.height = rect.bottom - rect.top;
            }
            return rect;
          };
          return this;
        }
        if (checker === null) {
          delete this.getRect;
          return this;
        }
        return this.getRect;
      }

      /** @internal */
    }, {
      key: "_backCompatOption",
      value: function _backCompatOption(optionName, newValue) {
        if (trySelector(newValue) || is.object(newValue)) {
          this.options[optionName] = newValue;
          for (var action in this._actions.map) {
            this.options[action][optionName] = newValue;
          }
          return this;
        }
        return this.options[optionName];
      }

      /**
       * Gets or sets the origin of the Interactable's element.  The x and y
       * of the origin will be subtracted from action event coordinates.
       *
       * @param {Element | object | string} [origin] An HTML or SVG Element whose
       * rect will be used, an object eg. { x: 0, y: 0 } or string 'parent', 'self'
       * or any CSS selector
       *
       * @return {object} The current origin or this Interactable
       */
    }, {
      key: "origin",
      value: function origin(newValue) {
        return this._backCompatOption('origin', newValue);
      }

      /**
       * Returns or sets the mouse coordinate types used to calculate the
       * movement of the pointer.
       *
       * @param {string} [newValue] Use 'client' if you will be scrolling while
       * interacting; Use 'page' if you want autoScroll to work
       * @return {string | object} The current deltaSource or this Interactable
       */
    }, {
      key: "deltaSource",
      value: function deltaSource(newValue) {
        if (newValue === 'page' || newValue === 'client') {
          this.options.deltaSource = newValue;
          return this;
        }
        return this.options.deltaSource;
      }

      /** @internal */
    }, {
      key: "getAllElements",
      value: function getAllElements() {
        var target = this.target;
        if (is.string(target)) {
          return Array.from(this._context.querySelectorAll(target));
        }
        if (is.func(target) && target.getAllElements) {
          return target.getAllElements();
        }
        return is.element(target) ? [target] : [];
      }

      /**
       * Gets the selector context Node of the Interactable. The default is
       * `window.document`.
       *
       * @return {Node} The context Node of this Interactable
       */
    }, {
      key: "context",
      value: function context() {
        return this._context;
      }
    }, {
      key: "inContext",
      value: function inContext(element) {
        return this._context === element.ownerDocument || nodeContains(this._context, element);
      }

      /** @internal */
    }, {
      key: "testIgnoreAllow",
      value: function testIgnoreAllow(options, targetNode, eventTarget) {
        return !this.testIgnore(options.ignoreFrom, targetNode, eventTarget) && this.testAllow(options.allowFrom, targetNode, eventTarget);
      }

      /** @internal */
    }, {
      key: "testAllow",
      value: function testAllow(allowFrom, targetNode, element) {
        if (!allowFrom) {
          return true;
        }
        if (!is.element(element)) {
          return false;
        }
        if (is.string(allowFrom)) {
          return matchesUpTo(element, allowFrom, targetNode);
        } else if (is.element(allowFrom)) {
          return nodeContains(allowFrom, element);
        }
        return false;
      }

      /** @internal */
    }, {
      key: "testIgnore",
      value: function testIgnore(ignoreFrom, targetNode, element) {
        if (!ignoreFrom || !is.element(element)) {
          return false;
        }
        if (is.string(ignoreFrom)) {
          return matchesUpTo(element, ignoreFrom, targetNode);
        } else if (is.element(ignoreFrom)) {
          return nodeContains(ignoreFrom, element);
        }
        return false;
      }

      /**
       * Calls listeners for the given InteractEvent type bound globally
       * and directly to this Interactable
       *
       * @param {InteractEvent} iEvent The InteractEvent object to be fired on this
       * Interactable
       * @return {Interactable} this Interactable
       */
    }, {
      key: "fire",
      value: function fire(iEvent) {
        this.events.fire(iEvent);
        return this;
      }

      /** @internal */
    }, {
      key: "_onOff",
      value: function _onOff(method, typeArg, listenerArg, options, filter) {
        if (is.object(typeArg) && !is.array(typeArg)) {
          options = listenerArg;
          listenerArg = null;
        }
        var listeners = normalize(typeArg, listenerArg, filter);
        for (var _type in listeners) {
          if (_type === 'wheel') {
            _type = browser$1.wheelEvent;
          }
          for (var _i2 = 0, _listeners$_type2 = listeners[_type]; _i2 < _listeners$_type2.length; _i2++) {
            var listener = _listeners$_type2[_i2];
            // if it is an action event type
            if (isNonNativeEvent(_type, this._actions)) {
              this.events[method === OnOffMethod.On ? 'on' : 'off'](_type, listener);
            }
            // delegated event
            else if (is.string(this.target)) {
              this._scopeEvents[method === OnOffMethod.On ? 'addDelegate' : 'removeDelegate'](this.target, this._context, _type, listener, options);
            }
            // remove listener from this Interactable's element
            else {
              this._scopeEvents[method === OnOffMethod.On ? 'add' : 'remove'](this.target, _type, listener, options);
            }
          }
        }
        return this;
      }

      /**
       * Binds a listener for an InteractEvent, pointerEvent or DOM event.
       *
       * @param {string | array | object} types The types of events to listen
       * for
       * @param {function | array | object} [listener] The event listener function(s)
       * @param {object | boolean} [options] options object or useCapture flag for
       * addEventListener
       * @return {Interactable} This Interactable
       */
    }, {
      key: "on",
      value: function on(types, listener, options) {
        return this._onOff(OnOffMethod.On, types, listener, options);
      }

      /**
       * Removes an InteractEvent, pointerEvent or DOM event listener.
       *
       * @param {string | array | object} types The types of events that were
       * listened for
       * @param {function | array | object} [listener] The event listener function(s)
       * @param {object | boolean} [options] options object or useCapture flag for
       * removeEventListener
       * @return {Interactable} This Interactable
       */
    }, {
      key: "off",
      value: function off(types, listener, options) {
        return this._onOff(OnOffMethod.Off, types, listener, options);
      }

      /**
       * Reset the options of this Interactable
       *
       * @param {object} options The new settings to apply
       * @return {object} This Interactable
       */
    }, {
      key: "set",
      value: function set(options) {
        var defaults = this._defaults;
        if (!is.object(options)) {
          options = {};
        }
        this.options = clone(defaults.base);
        for (var actionName_ in this._actions.methodDict) {
          var actionName = actionName_;
          var methodName = this._actions.methodDict[actionName];
          this.options[actionName] = {};
          this.setPerAction(actionName, extend(extend({}, defaults.perAction), defaults.actions[actionName]));
          this[methodName](options[actionName]);
        }
        for (var setting in options) {
          if (setting === 'getRect') {
            this.rectChecker(options.getRect);
            continue;
          }
          if (is.func(this[setting])) {
            this[setting](options[setting]);
          }
        }
        return this;
      }

      /**
       * Remove this interactable from the list of interactables and remove it's
       * action capabilities and event listeners
       */
    }, {
      key: "unset",
      value: function unset() {
        if (is.string(this.target)) {
          // remove delegated events
          for (var _type2 in this._scopeEvents.delegatedEvents) {
            var delegated = this._scopeEvents.delegatedEvents[_type2];
            for (var i = delegated.length - 1; i >= 0; i--) {
              var _delegated$i = delegated[i],
                selector = _delegated$i.selector,
                context = _delegated$i.context,
                listeners = _delegated$i.listeners;
              if (selector === this.target && context === this._context) {
                delegated.splice(i, 1);
              }
              for (var l = listeners.length - 1; l >= 0; l--) {
                this._scopeEvents.removeDelegate(this.target, this._context, _type2, listeners[l][0], listeners[l][1]);
              }
            }
          }
        } else {
          this._scopeEvents.remove(this.target, 'all');
        }
      }
    }]);
    return Interactable;
  }();

  var InteractableSet = /*#__PURE__*/function () {
    function InteractableSet(scope) {
      var _this = this;
      _classCallCheck(this, InteractableSet);
      // all set interactables
      this.list = [];
      this.selectorMap = {};
      this.scope = void 0;
      this.scope = scope;
      scope.addListeners({
        'interactable:unset': function interactableUnset(_ref) {
          var interactable = _ref.interactable;
          var target = interactable.target;
          var interactablesOnTarget = is.string(target) ? _this.selectorMap[target] : target[_this.scope.id];
          var targetIndex = findIndex(interactablesOnTarget, function (i) {
            return i === interactable;
          });
          interactablesOnTarget.splice(targetIndex, 1);
        }
      });
    }
    _createClass(InteractableSet, [{
      key: "new",
      value: function _new(target, options) {
        options = extend(options || {}, {
          actions: this.scope.actions
        });
        var interactable = new this.scope.Interactable(target, options, this.scope.document, this.scope.events);
        this.scope.addDocument(interactable._doc);
        this.list.push(interactable);
        if (is.string(target)) {
          if (!this.selectorMap[target]) {
            this.selectorMap[target] = [];
          }
          this.selectorMap[target].push(interactable);
        } else {
          if (!interactable.target[this.scope.id]) {
            Object.defineProperty(target, this.scope.id, {
              value: [],
              configurable: true
            });
          }
          target[this.scope.id].push(interactable);
        }
        this.scope.fire('interactable:new', {
          target: target,
          options: options,
          interactable: interactable,
          win: this.scope._win
        });
        return interactable;
      }
    }, {
      key: "getExisting",
      value: function getExisting(target, options) {
        var context = options && options.context || this.scope.document;
        var isSelector = is.string(target);
        var interactablesOnTarget = isSelector ? this.selectorMap[target] : target[this.scope.id];
        if (!interactablesOnTarget) return undefined;
        return find(interactablesOnTarget, function (interactable) {
          return interactable._context === context && (isSelector || interactable.inContext(target));
        });
      }
    }, {
      key: "forEachMatch",
      value: function forEachMatch(node, callback) {
        for (var _i2 = 0, _this$list2 = this.list; _i2 < _this$list2.length; _i2++) {
          var _interactable = _this$list2[_i2];
          var ret = void 0;
          if ((is.string(_interactable.target) ?
          // target is a selector and the element matches
          is.element(node) && matchesSelector(node, _interactable.target) :
          // target is the element
          node === _interactable.target) &&
          // the element is in context
          _interactable.inContext(node)) {
            ret = callback(_interactable);
          }
          if (ret !== undefined) {
            return ret;
          }
        }
      }
    }]);
    return InteractableSet;
  }();

  /**
   * ```js
   * interact('#draggable').draggable(true)
   *
   * var rectables = interact('rect')
   * rectables
   *   .gesturable(true)
   *   .on('gesturemove', function (event) {
   *       // ...
   *   })
   * ```
   *
   * The methods of this variable can be used to set elements as interactables
   * and also to change various default settings.
   *
   * Calling it as a function and passing an element or a valid CSS selector
   * string returns an Interactable object which has various methods to configure
   * it.
   *
   * @param {Element | string} target The HTML or SVG Element to interact with
   * or CSS selector
   * @return {Interactable}
   */

  function createInteractStatic(scope) {
    var interact = function interact(target, options) {
      var interactable = scope.interactables.getExisting(target, options);
      if (!interactable) {
        interactable = scope.interactables.new(target, options);
        interactable.events.global = interact.globalEvents;
      }
      return interactable;
    };

    // expose the functions used to calculate multi-touch properties
    interact.getPointerAverage = pointerAverage;
    interact.getTouchBBox = touchBBox;
    interact.getTouchDistance = touchDistance;
    interact.getTouchAngle = touchAngle;
    interact.getElementRect = getElementRect;
    interact.getElementClientRect = getElementClientRect;
    interact.matchesSelector = matchesSelector;
    interact.closest = closest;
    interact.globalEvents = {};

    // eslint-disable-next-line no-undef
    interact.version = "1.10.27";
    interact.scope = scope;
    interact.use = function (plugin, options) {
      this.scope.usePlugin(plugin, options);
      return this;
    };
    interact.isSet = function (target, options) {
      return !!this.scope.interactables.get(target, options && options.context);
    };
    interact.on = warnOnce(function on(type, listener, options) {
      if (is.string(type) && type.search(' ') !== -1) {
        type = type.trim().split(/ +/);
      }
      if (is.array(type)) {
        for (var _i2 = 0, _ref2 = type; _i2 < _ref2.length; _i2++) {
          var eventType = _ref2[_i2];
          this.on(eventType, listener, options);
        }
        return this;
      }
      if (is.object(type)) {
        for (var prop in type) {
          this.on(prop, type[prop], listener);
        }
        return this;
      }

      // if it is an InteractEvent type, add listener to globalEvents
      if (isNonNativeEvent(type, this.scope.actions)) {
        // if this type of event was never bound
        if (!this.globalEvents[type]) {
          this.globalEvents[type] = [listener];
        } else {
          this.globalEvents[type].push(listener);
        }
      }
      // If non InteractEvent type, addEventListener to document
      else {
        this.scope.events.add(this.scope.document, type, listener, {
          options: options
        });
      }
      return this;
    }, 'The interact.on() method is being deprecated');
    interact.off = warnOnce(function off(type, listener, options) {
      if (is.string(type) && type.search(' ') !== -1) {
        type = type.trim().split(/ +/);
      }
      if (is.array(type)) {
        for (var _i4 = 0, _type2 = type; _i4 < _type2.length; _i4++) {
          var eventType = _type2[_i4];
          this.off(eventType, listener, options);
        }
        return this;
      }
      if (is.object(type)) {
        for (var prop in type) {
          this.off(prop, type[prop], listener);
        }
        return this;
      }
      if (isNonNativeEvent(type, this.scope.actions)) {
        var index;
        if (type in this.globalEvents && (index = this.globalEvents[type].indexOf(listener)) !== -1) {
          this.globalEvents[type].splice(index, 1);
        }
      } else {
        this.scope.events.remove(this.scope.document, type, listener, options);
      }
      return this;
    }, 'The interact.off() method is being deprecated');
    interact.debug = function () {
      return this.scope;
    };
    interact.supportsTouch = function () {
      return browser$1.supportsTouch;
    };
    interact.supportsPointerEvent = function () {
      return browser$1.supportsPointerEvent;
    };
    interact.stop = function () {
      for (var _i6 = 0, _this$scope$interacti2 = this.scope.interactions.list; _i6 < _this$scope$interacti2.length; _i6++) {
        var interaction = _this$scope$interacti2[_i6];
        interaction.stop();
      }
      return this;
    };
    interact.pointerMoveTolerance = function (newValue) {
      if (is.number(newValue)) {
        this.scope.interactions.pointerMoveTolerance = newValue;
        return this;
      }
      return this.scope.interactions.pointerMoveTolerance;
    };
    interact.addDocument = function (doc, options) {
      this.scope.addDocument(doc, options);
    };
    interact.removeDocument = function (doc) {
      this.scope.removeDocument(doc);
    };
    return interact;
  }

  /** @internal */
  var Scope = /*#__PURE__*/function () {
    function Scope() {
      var _this = this;
      _classCallCheck(this, Scope);
      this.id = "__interact_scope_".concat(Math.floor(Math.random() * 100));
      this.isInitialized = false;
      this.listenerMaps = [];
      this.browser = browser$1;
      this.defaults = clone(defaults$7);
      this.Eventable = Eventable;
      this.actions = {
        map: {},
        phases: {
          start: true,
          move: true,
          end: true
        },
        methodDict: {},
        phaselessTypes: {}
      };
      this.interactStatic = createInteractStatic(this);
      this.InteractEvent = InteractEvent;
      this.Interactable = void 0;
      this.interactables = new InteractableSet(this);
      // main window
      this._win = void 0;
      // main document
      this.document = void 0;
      // main window
      this.window = void 0;
      // all documents being listened to
      this.documents = [];
      this._plugins = {
        list: [],
        map: {}
      };
      this.onWindowUnload = function (event) {
        return _this.removeDocument(event.target);
      };
      var scope = this;
      this.Interactable = /*#__PURE__*/function (_InteractableBase) {
        _inherits(_class2, _InteractableBase);
        var _super = _createSuper(_class2);
        function _class2() {
          _classCallCheck(this, _class2);
          return _super.apply(this, arguments);
        }
        _createClass(_class2, [{
          key: "_defaults",
          get: function get() {
            return scope.defaults;
          }
        }, {
          key: "set",
          value: function set(options) {
            _get(_getPrototypeOf(_class2.prototype), "set", this).call(this, options);
            scope.fire('interactable:set', {
              options: options,
              interactable: this
            });
            return this;
          }
        }, {
          key: "unset",
          value: function unset() {
            _get(_getPrototypeOf(_class2.prototype), "unset", this).call(this);
            var index = scope.interactables.list.indexOf(this);
            if (index < 0) return;
            scope.interactables.list.splice(index, 1);
            scope.fire('interactable:unset', {
              interactable: this
            });
          }
        }]);
        return _class2;
      }(Interactable);
    }
    _createClass(Scope, [{
      key: "addListeners",
      value: function addListeners(map, id) {
        this.listenerMaps.push({
          id: id,
          map: map
        });
      }
    }, {
      key: "fire",
      value: function fire(name, arg) {
        for (var _i2 = 0, _this$listenerMaps2 = this.listenerMaps; _i2 < _this$listenerMaps2.length; _i2++) {
          var listener = _this$listenerMaps2[_i2].map[name];
          if (!!listener && listener(arg, this, name) === false) {
            return false;
          }
        }
      }
    }, {
      key: "init",
      value: function init(window) {
        return this.isInitialized ? this : initScope(this, window);
      }
    }, {
      key: "pluginIsInstalled",
      value: function pluginIsInstalled(plugin) {
        var id = plugin.id;
        return id ? !!this._plugins.map[id] : this._plugins.list.indexOf(plugin) !== -1;
      }
    }, {
      key: "usePlugin",
      value: function usePlugin(plugin, options) {
        if (!this.isInitialized) {
          return this;
        }
        if (this.pluginIsInstalled(plugin)) {
          return this;
        }
        if (plugin.id) {
          this._plugins.map[plugin.id] = plugin;
        }
        this._plugins.list.push(plugin);
        if (plugin.install) {
          plugin.install(this, options);
        }
        if (plugin.listeners && plugin.before) {
          var index = 0;
          var len = this.listenerMaps.length;
          var before = plugin.before.reduce(function (acc, id) {
            acc[id] = true;
            acc[pluginIdRoot(id)] = true;
            return acc;
          }, {});
          for (; index < len; index++) {
            var otherId = this.listenerMaps[index].id;
            if (otherId && (before[otherId] || before[pluginIdRoot(otherId)])) {
              break;
            }
          }
          this.listenerMaps.splice(index, 0, {
            id: plugin.id,
            map: plugin.listeners
          });
        } else if (plugin.listeners) {
          this.listenerMaps.push({
            id: plugin.id,
            map: plugin.listeners
          });
        }
        return this;
      }
    }, {
      key: "addDocument",
      value: function addDocument(doc, options) {
        // do nothing if document is already known
        if (this.getDocIndex(doc) !== -1) {
          return false;
        }
        var window = getWindow(doc);
        options = options ? extend({}, options) : {};
        this.documents.push({
          doc: doc,
          options: options
        });
        this.events.documents.push(doc);

        // don't add an unload event for the main document
        // so that the page may be cached in browser history
        if (doc !== this.document) {
          this.events.add(window, 'unload', this.onWindowUnload);
        }
        this.fire('scope:add-document', {
          doc: doc,
          window: window,
          scope: this,
          options: options
        });
      }
    }, {
      key: "removeDocument",
      value: function removeDocument(doc) {
        var index = this.getDocIndex(doc);
        var window = getWindow(doc);
        var options = this.documents[index].options;
        this.events.remove(window, 'unload', this.onWindowUnload);
        this.documents.splice(index, 1);
        this.events.documents.splice(index, 1);
        this.fire('scope:remove-document', {
          doc: doc,
          window: window,
          scope: this,
          options: options
        });
      }
    }, {
      key: "getDocIndex",
      value: function getDocIndex(doc) {
        for (var i = 0; i < this.documents.length; i++) {
          if (this.documents[i].doc === doc) {
            return i;
          }
        }
        return -1;
      }
    }, {
      key: "getDocOptions",
      value: function getDocOptions(doc) {
        var docIndex = this.getDocIndex(doc);
        return docIndex === -1 ? null : this.documents[docIndex].options;
      }
    }, {
      key: "now",
      value: function now() {
        return (this.window.Date || Date).now();
      }
    }]);
    return Scope;
  }();

  // Keep Scope class internal, but expose minimal interface to avoid broken types when Scope is stripped out

  /** @internal */
  function initScope(scope, window) {
    scope.isInitialized = true;
    if (is.window(window)) {
      init$3(window);
    }
    domObjects$1.init(window);
    browser$1.init(window);
    raf.init(window);

    // @ts-expect-error
    scope.window = window;
    scope.document = window.document;
    scope.usePlugin(interactions$1);
    scope.usePlugin(events);
    return scope;
  }
  function pluginIdRoot(id) {
    return id && id.replace(/\/.*$/, '');
  }

  var scope = new Scope();
  var interact = scope.interactStatic;
  var interact$1 = interact;
  var _global = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : window;
  scope.init(_global);

  var edgeTarget = (function () {});

  var elements = (function () {});

  var grid = (function (grid) {
    var coordFields = [['x', 'y'], ['left', 'top'], ['right', 'bottom'], ['width', 'height']].filter(function (_ref) {
      var xField = _ref[0],
        yField = _ref[1];
      return xField in grid || yField in grid;
    });
    var gridFunc = function gridFunc(x, y) {
      var range = grid.range,
        _grid$limits = grid.limits,
        limits = _grid$limits === void 0 ? {
          left: -Infinity,
          right: Infinity,
          top: -Infinity,
          bottom: Infinity
        } : _grid$limits,
        _grid$offset = grid.offset,
        offset = _grid$offset === void 0 ? {
          x: 0,
          y: 0
        } : _grid$offset;
      var result = {
        range: range,
        grid: grid,
        x: null,
        y: null
      };
      for (var _i2 = 0; _i2 < coordFields.length; _i2++) {
        var _coordFields$_i = coordFields[_i2],
          xField = _coordFields$_i[0],
          yField = _coordFields$_i[1];
        var gridx = Math.round((x - offset.x) / grid[xField]);
        var gridy = Math.round((y - offset.y) / grid[yField]);
        result[xField] = Math.max(limits.left, Math.min(limits.right, gridx * grid[xField] + offset.x));
        result[yField] = Math.max(limits.top, Math.min(limits.bottom, gridy * grid[yField] + offset.y));
      }
      return result;
    };
    gridFunc.grid = grid;
    gridFunc.coordFields = coordFields;
    return gridFunc;
  });

  /* eslint-disable import/no-named-as-default, import/no-unresolved */

  var allSnappers = /*#__PURE__*/Object.freeze({
    __proto__: null,
    edgeTarget: edgeTarget,
    elements: elements,
    grid: grid
  });

  var snappersPlugin = {
    id: 'snappers',
    install: function install(scope) {
      var interact = scope.interactStatic;
      interact.snappers = extend(interact.snappers || {}, allSnappers);
      interact.createSnapGrid = interact.snappers.grid;
    }
  };
  var snappers = snappersPlugin;

  var aspectRatio = {
    start: function start(arg) {
      var state = arg.state,
        rect = arg.rect,
        edges = arg.edges,
        coords = arg.pageCoords;
      var _state$options = state.options,
        ratio = _state$options.ratio,
        enabled = _state$options.enabled;
      var _state$options2 = state.options,
        equalDelta = _state$options2.equalDelta,
        modifiers = _state$options2.modifiers;
      if (ratio === 'preserve') {
        ratio = rect.width / rect.height;
      }
      state.startCoords = extend({}, coords);
      state.startRect = extend({}, rect);
      state.ratio = ratio;
      state.equalDelta = equalDelta;
      var linkedEdges = state.linkedEdges = {
        top: edges.top || edges.left && !edges.bottom,
        left: edges.left || edges.top && !edges.right,
        bottom: edges.bottom || edges.right && !edges.top,
        right: edges.right || edges.bottom && !edges.left
      };
      state.xIsPrimaryAxis = !!(edges.left || edges.right);
      if (state.equalDelta) {
        var sign = (linkedEdges.left ? 1 : -1) * (linkedEdges.top ? 1 : -1);
        state.edgeSign = {
          x: sign,
          y: sign
        };
      } else {
        state.edgeSign = {
          x: linkedEdges.left ? -1 : 1,
          y: linkedEdges.top ? -1 : 1
        };
      }
      if (enabled !== false) {
        extend(edges, linkedEdges);
      }
      if (!(modifiers != null && modifiers.length)) return;
      var subModification = new Modification(arg.interaction);
      subModification.copyFrom(arg.interaction.modification);
      subModification.prepareStates(modifiers);
      state.subModification = subModification;
      subModification.startAll(_objectSpread2({}, arg));
    },
    set: function set(arg) {
      var state = arg.state,
        rect = arg.rect,
        coords = arg.coords;
      var linkedEdges = state.linkedEdges;
      var initialCoords = extend({}, coords);
      var aspectMethod = state.equalDelta ? setEqualDelta : setRatio;
      extend(arg.edges, linkedEdges);
      aspectMethod(state, state.xIsPrimaryAxis, coords, rect);
      if (!state.subModification) {
        return null;
      }
      var correctedRect = extend({}, rect);
      addEdges(linkedEdges, correctedRect, {
        x: coords.x - initialCoords.x,
        y: coords.y - initialCoords.y
      });
      var result = state.subModification.setAll(_objectSpread2(_objectSpread2({}, arg), {}, {
        rect: correctedRect,
        edges: linkedEdges,
        pageCoords: coords,
        prevCoords: coords,
        prevRect: correctedRect
      }));
      var delta = result.delta;
      if (result.changed) {
        var xIsCriticalAxis = Math.abs(delta.x) > Math.abs(delta.y);

        // do aspect modification again with critical edge axis as primary
        aspectMethod(state, xIsCriticalAxis, result.coords, result.rect);
        extend(coords, result.coords);
      }
      return result.eventProps;
    },
    defaults: {
      ratio: 'preserve',
      equalDelta: false,
      modifiers: [],
      enabled: false
    }
  };
  function setEqualDelta(_ref, xIsPrimaryAxis, coords) {
    var startCoords = _ref.startCoords,
      edgeSign = _ref.edgeSign;
    if (xIsPrimaryAxis) {
      coords.y = startCoords.y + (coords.x - startCoords.x) * edgeSign.y;
    } else {
      coords.x = startCoords.x + (coords.y - startCoords.y) * edgeSign.x;
    }
  }
  function setRatio(_ref2, xIsPrimaryAxis, coords, rect) {
    var startRect = _ref2.startRect,
      startCoords = _ref2.startCoords,
      ratio = _ref2.ratio,
      edgeSign = _ref2.edgeSign;
    if (xIsPrimaryAxis) {
      var newHeight = rect.width / ratio;
      coords.y = startCoords.y + (newHeight - startRect.height) * edgeSign.y;
    } else {
      var newWidth = rect.height * ratio;
      coords.x = startCoords.x + (newWidth - startRect.width) * edgeSign.x;
    }
  }
  var aspectRatio$1 = makeModifier(aspectRatio, 'aspectRatio');

  var noop = function noop() {};
  noop._defaults = {};
  var rubberband = noop;

  function start$5(_ref) {
    var rect = _ref.rect,
      startOffset = _ref.startOffset,
      state = _ref.state,
      interaction = _ref.interaction,
      pageCoords = _ref.pageCoords;
    var options = state.options;
    var elementRect = options.elementRect;
    var offset = extend({
      left: 0,
      top: 0,
      right: 0,
      bottom: 0
    }, options.offset || {});
    if (rect && elementRect) {
      var restriction = getRestrictionRect(options.restriction, interaction, pageCoords);
      if (restriction) {
        var widthDiff = restriction.right - restriction.left - rect.width;
        var heightDiff = restriction.bottom - restriction.top - rect.height;
        if (widthDiff < 0) {
          offset.left += widthDiff;
          offset.right += widthDiff;
        }
        if (heightDiff < 0) {
          offset.top += heightDiff;
          offset.bottom += heightDiff;
        }
      }
      offset.left += startOffset.left - rect.width * elementRect.left;
      offset.top += startOffset.top - rect.height * elementRect.top;
      offset.right += startOffset.right - rect.width * (1 - elementRect.right);
      offset.bottom += startOffset.bottom - rect.height * (1 - elementRect.bottom);
    }
    state.offset = offset;
  }
  function set$4(_ref2) {
    var coords = _ref2.coords,
      interaction = _ref2.interaction,
      state = _ref2.state;
    var options = state.options,
      offset = state.offset;
    var restriction = getRestrictionRect(options.restriction, interaction, coords);
    if (!restriction) return;
    var rect = xywhToTlbr(restriction);
    coords.x = Math.max(Math.min(rect.right - offset.right, coords.x), rect.left + offset.left);
    coords.y = Math.max(Math.min(rect.bottom - offset.bottom, coords.y), rect.top + offset.top);
  }
  function getRestrictionRect(value, interaction, coords) {
    if (is.func(value)) {
      return resolveRectLike(value, interaction.interactable, interaction.element, [coords.x, coords.y, interaction]);
    } else {
      return resolveRectLike(value, interaction.interactable, interaction.element);
    }
  }
  var defaults$6 = {
    restriction: null,
    elementRect: null,
    offset: null,
    endOnly: false,
    enabled: false
  };
  var restrict = {
    start: start$5,
    set: set$4,
    defaults: defaults$6
  };
  var restrict$1 = makeModifier(restrict, 'restrict');

  // This modifier adds the options.resize.restrictEdges setting which sets min and
  // max for the top, left, bottom and right edges of the target being resized.
  //
  // interact(target).resize({
  //   edges: { top: true, left: true },
  //   restrictEdges: {
  //     inner: { top: 200, left: 200, right: 400, bottom: 400 },
  //     outer: { top:   0, left:   0, right: 600, bottom: 600 },
  //   },
  // })

  var noInner = {
    top: +Infinity,
    left: +Infinity,
    bottom: -Infinity,
    right: -Infinity
  };
  var noOuter = {
    top: -Infinity,
    left: -Infinity,
    bottom: +Infinity,
    right: +Infinity
  };
  function start$4(_ref) {
    var interaction = _ref.interaction,
      startOffset = _ref.startOffset,
      state = _ref.state;
    var options = state.options;
    var offset;
    if (options) {
      var offsetRect = getRestrictionRect(options.offset, interaction, interaction.coords.start.page);
      offset = rectToXY(offsetRect);
    }
    offset = offset || {
      x: 0,
      y: 0
    };
    state.offset = {
      top: offset.y + startOffset.top,
      left: offset.x + startOffset.left,
      bottom: offset.y - startOffset.bottom,
      right: offset.x - startOffset.right
    };
  }
  function set$3(_ref2) {
    var coords = _ref2.coords,
      edges = _ref2.edges,
      interaction = _ref2.interaction,
      state = _ref2.state;
    var offset = state.offset,
      options = state.options;
    if (!edges) {
      return;
    }
    var page = extend({}, coords);
    var inner = getRestrictionRect(options.inner, interaction, page) || {};
    var outer = getRestrictionRect(options.outer, interaction, page) || {};
    fixRect(inner, noInner);
    fixRect(outer, noOuter);
    if (edges.top) {
      coords.y = Math.min(Math.max(outer.top + offset.top, page.y), inner.top + offset.top);
    } else if (edges.bottom) {
      coords.y = Math.max(Math.min(outer.bottom + offset.bottom, page.y), inner.bottom + offset.bottom);
    }
    if (edges.left) {
      coords.x = Math.min(Math.max(outer.left + offset.left, page.x), inner.left + offset.left);
    } else if (edges.right) {
      coords.x = Math.max(Math.min(outer.right + offset.right, page.x), inner.right + offset.right);
    }
  }
  function fixRect(rect, defaults) {
    for (var _i2 = 0, _ref4 = ['top', 'left', 'bottom', 'right']; _i2 < _ref4.length; _i2++) {
      var edge = _ref4[_i2];
      if (!(edge in rect)) {
        rect[edge] = defaults[edge];
      }
    }
    return rect;
  }
  var defaults$5 = {
    inner: null,
    outer: null,
    offset: null,
    endOnly: false,
    enabled: false
  };
  var restrictEdges = {
    noInner: noInner,
    noOuter: noOuter,
    start: start$4,
    set: set$3,
    defaults: defaults$5
  };
  var restrictEdges$1 = makeModifier(restrictEdges, 'restrictEdges');

  var defaults$4 = extend({
    get elementRect() {
      return {
        top: 0,
        left: 0,
        bottom: 1,
        right: 1
      };
    },
    set elementRect(_) {}
  }, restrict.defaults);
  var restrictRect = {
    start: restrict.start,
    set: restrict.set,
    defaults: defaults$4
  };
  var restrictRect$1 = makeModifier(restrictRect, 'restrictRect');

  var noMin = {
    width: -Infinity,
    height: -Infinity
  };
  var noMax = {
    width: +Infinity,
    height: +Infinity
  };
  function start$3(arg) {
    return restrictEdges.start(arg);
  }
  function set$2(arg) {
    var interaction = arg.interaction,
      state = arg.state,
      rect = arg.rect,
      edges = arg.edges;
    var options = state.options;
    if (!edges) {
      return;
    }
    var minSize = tlbrToXywh(getRestrictionRect(options.min, interaction, arg.coords)) || noMin;
    var maxSize = tlbrToXywh(getRestrictionRect(options.max, interaction, arg.coords)) || noMax;
    state.options = {
      endOnly: options.endOnly,
      inner: extend({}, restrictEdges.noInner),
      outer: extend({}, restrictEdges.noOuter)
    };
    if (edges.top) {
      state.options.inner.top = rect.bottom - minSize.height;
      state.options.outer.top = rect.bottom - maxSize.height;
    } else if (edges.bottom) {
      state.options.inner.bottom = rect.top + minSize.height;
      state.options.outer.bottom = rect.top + maxSize.height;
    }
    if (edges.left) {
      state.options.inner.left = rect.right - minSize.width;
      state.options.outer.left = rect.right - maxSize.width;
    } else if (edges.right) {
      state.options.inner.right = rect.left + minSize.width;
      state.options.outer.right = rect.left + maxSize.width;
    }
    restrictEdges.set(arg);
    state.options = options;
  }
  var defaults$3 = {
    min: null,
    max: null,
    endOnly: false,
    enabled: false
  };
  var restrictSize = {
    start: start$3,
    set: set$2,
    defaults: defaults$3
  };
  var restrictSize$1 = makeModifier(restrictSize, 'restrictSize');

  function start$2(arg) {
    var interaction = arg.interaction,
      interactable = arg.interactable,
      element = arg.element,
      rect = arg.rect,
      state = arg.state,
      startOffset = arg.startOffset;
    var options = state.options;
    var origin = options.offsetWithOrigin ? getOrigin(arg) : {
      x: 0,
      y: 0
    };
    var snapOffset;
    if (options.offset === 'startCoords') {
      snapOffset = {
        x: interaction.coords.start.page.x,
        y: interaction.coords.start.page.y
      };
    } else {
      var offsetRect = resolveRectLike(options.offset, interactable, element, [interaction]);
      snapOffset = rectToXY(offsetRect) || {
        x: 0,
        y: 0
      };
      snapOffset.x += origin.x;
      snapOffset.y += origin.y;
    }
    var relativePoints = options.relativePoints;
    state.offsets = rect && relativePoints && relativePoints.length ? relativePoints.map(function (relativePoint, index) {
      return {
        index: index,
        relativePoint: relativePoint,
        x: startOffset.left - rect.width * relativePoint.x + snapOffset.x,
        y: startOffset.top - rect.height * relativePoint.y + snapOffset.y
      };
    }) : [{
      index: 0,
      relativePoint: null,
      x: snapOffset.x,
      y: snapOffset.y
    }];
  }
  function set$1(arg) {
    var interaction = arg.interaction,
      coords = arg.coords,
      state = arg.state;
    var options = state.options,
      offsets = state.offsets;
    var origin = getOriginXY(interaction.interactable, interaction.element, interaction.prepared.name);
    var page = extend({}, coords);
    var targets = [];
    if (!options.offsetWithOrigin) {
      page.x -= origin.x;
      page.y -= origin.y;
    }
    for (var _i2 = 0, _ref2 = offsets; _i2 < _ref2.length; _i2++) {
      var _offset = _ref2[_i2];
      var relativeX = page.x - _offset.x;
      var relativeY = page.y - _offset.y;
      for (var _index = 0, len = options.targets.length; _index < len; _index++) {
        var snapTarget = options.targets[_index];
        var target = void 0;
        if (is.func(snapTarget)) {
          target = snapTarget(relativeX, relativeY, interaction._proxy, _offset, _index);
        } else {
          target = snapTarget;
        }
        if (!target) {
          continue;
        }
        targets.push({
          x: (is.number(target.x) ? target.x : relativeX) + _offset.x,
          y: (is.number(target.y) ? target.y : relativeY) + _offset.y,
          range: is.number(target.range) ? target.range : options.range,
          source: snapTarget,
          index: _index,
          offset: _offset
        });
      }
    }
    var closest = {
      target: null,
      inRange: false,
      distance: 0,
      range: 0,
      delta: {
        x: 0,
        y: 0
      }
    };
    for (var _i4 = 0; _i4 < targets.length; _i4++) {
      var _target = targets[_i4];
      var range = _target.range;
      var dx = _target.x - page.x;
      var dy = _target.y - page.y;
      var distance = hypot(dx, dy);
      var inRange = distance <= range;

      // Infinite targets count as being out of range
      // compared to non infinite ones that are in range
      if (range === Infinity && closest.inRange && closest.range !== Infinity) {
        inRange = false;
      }
      if (!closest.target || (inRange ?
      // is the closest target in range?
      closest.inRange && range !== Infinity ?
      // the pointer is relatively deeper in this target
      distance / range < closest.distance / closest.range :
      // this target has Infinite range and the closest doesn't
      range === Infinity && closest.range !== Infinity ||
      // OR this target is closer that the previous closest
      distance < closest.distance :
      // The other is not in range and the pointer is closer to this target
      !closest.inRange && distance < closest.distance)) {
        closest.target = _target;
        closest.distance = distance;
        closest.range = range;
        closest.inRange = inRange;
        closest.delta.x = dx;
        closest.delta.y = dy;
      }
    }
    if (closest.inRange) {
      coords.x = closest.target.x;
      coords.y = closest.target.y;
    }
    state.closest = closest;
    return closest;
  }
  function getOrigin(arg) {
    var element = arg.interaction.element;
    var optionsOrigin = rectToXY(resolveRectLike(arg.state.options.origin, null, null, [element]));
    var origin = optionsOrigin || getOriginXY(arg.interactable, element, arg.interaction.prepared.name);
    return origin;
  }
  var defaults$2 = {
    range: Infinity,
    targets: null,
    offset: null,
    offsetWithOrigin: true,
    origin: null,
    relativePoints: null,
    endOnly: false,
    enabled: false
  };
  var snap = {
    start: start$2,
    set: set$1,
    defaults: defaults$2
  };
  var snap$1 = makeModifier(snap, 'snap');

  // This modifier allows snapping of the size of targets during resize
  // interactions.

  function start$1(arg) {
    var state = arg.state,
      edges = arg.edges;
    var options = state.options;
    if (!edges) {
      return null;
    }
    arg.state = {
      options: {
        targets: null,
        relativePoints: [{
          x: edges.left ? 0 : 1,
          y: edges.top ? 0 : 1
        }],
        offset: options.offset || 'self',
        origin: {
          x: 0,
          y: 0
        },
        range: options.range
      }
    };
    state.targetFields = state.targetFields || [['width', 'height'], ['x', 'y']];
    snap.start(arg);
    state.offsets = arg.state.offsets;
    arg.state = state;
  }
  function set(arg) {
    var interaction = arg.interaction,
      state = arg.state,
      coords = arg.coords;
    var options = state.options,
      offsets = state.offsets;
    var relative = {
      x: coords.x - offsets[0].x,
      y: coords.y - offsets[0].y
    };
    state.options = extend({}, options);
    state.options.targets = [];
    for (var _i2 = 0, _ref2 = options.targets || []; _i2 < _ref2.length; _i2++) {
      var snapTarget = _ref2[_i2];
      var target = void 0;
      if (is.func(snapTarget)) {
        target = snapTarget(relative.x, relative.y, interaction);
      } else {
        target = snapTarget;
      }
      if (!target) {
        continue;
      }
      for (var _i4 = 0, _state$targetFields2 = state.targetFields; _i4 < _state$targetFields2.length; _i4++) {
        var _state$targetFields2$ = _state$targetFields2[_i4],
          xField = _state$targetFields2$[0],
          yField = _state$targetFields2$[1];
        if (xField in target || yField in target) {
          target.x = target[xField];
          target.y = target[yField];
          break;
        }
      }
      state.options.targets.push(target);
    }
    var returnValue = snap.set(arg);
    state.options = options;
    return returnValue;
  }
  var defaults$1 = {
    range: Infinity,
    targets: null,
    offset: null,
    endOnly: false,
    enabled: false
  };
  var snapSize = {
    start: start$1,
    set: set,
    defaults: defaults$1
  };
  var snapSize$1 = makeModifier(snapSize, 'snapSize');

  /**
   * @module modifiers/snapEdges
   *
   * @description
   * This modifier allows snapping of the edges of targets during resize
   * interactions.
   *
   * ```js
   * interact(target).resizable({
   *   snapEdges: {
   *     targets: [interact.snappers.grid({ x: 100, y: 50 })],
   *   },
   * })
   *
   * interact(target).resizable({
   *   snapEdges: {
   *     targets: [
   *       interact.snappers.grid({
   *        top: 50,
   *        left: 50,
   *        bottom: 100,
   *        right: 100,
   *       }),
   *     ],
   *   },
   * })
   * ```
   */

  function start(arg) {
    var edges = arg.edges;
    if (!edges) {
      return null;
    }
    arg.state.targetFields = arg.state.targetFields || [[edges.left ? 'left' : 'right', edges.top ? 'top' : 'bottom']];
    return snapSize.start(arg);
  }
  var snapEdges = {
    start: start,
    set: snapSize.set,
    defaults: extend(clone(snapSize.defaults), {
      targets: undefined,
      range: undefined,
      offset: {
        x: 0,
        y: 0
      }
    })
  };
  var snapEdges$1 = makeModifier(snapEdges, 'snapEdges');

  /* eslint-disable n/no-extraneous-import, import/no-unresolved */
  var all = {
    aspectRatio: aspectRatio$1,
    restrictEdges: restrictEdges$1,
    restrict: restrict$1,
    restrictRect: restrictRect$1,
    restrictSize: restrictSize$1,
    snapEdges: snapEdges$1,
    snap: snap$1,
    snapSize: snapSize$1,
    spring: rubberband,
    avoid: rubberband,
    transform: rubberband,
    rubberband: rubberband
  };

  /* eslint-enable import/no-duplicates */

  var modifiers = {
    id: 'modifiers',
    install: function install(scope) {
      var interact = scope.interactStatic;
      scope.usePlugin(base);
      scope.usePlugin(snappers);
      interact.modifiers = all;

      // for backwrads compatibility
      for (var type in all) {
        var _all = all[type],
          _defaults = _all._defaults,
          _methods = _all._methods;
        _defaults._methods = _methods;
        scope.defaults.perAction[type] = _defaults;
      }
    }
  };
  var modifiers$1 = modifiers;

  var PointerEvent = /*#__PURE__*/function (_BaseEvent) {
    _inherits(PointerEvent, _BaseEvent);
    var _super = _createSuper(PointerEvent);
    function PointerEvent(type, pointer, event, eventTarget, interaction, timeStamp) {
      var _this;
      _classCallCheck(this, PointerEvent);
      _this = _super.call(this, interaction);
      pointerExtend(_assertThisInitialized(_this), event);
      if (event !== pointer) {
        pointerExtend(_assertThisInitialized(_this), pointer);
      }
      _this.timeStamp = timeStamp;
      _this.originalEvent = event;
      _this.type = type;
      _this.pointerId = getPointerId(pointer);
      _this.pointerType = getPointerType(pointer);
      _this.target = eventTarget;
      _this.currentTarget = null;
      if (type === 'tap') {
        var pointerIndex = interaction.getPointerIndex(pointer);
        _this.dt = _this.timeStamp - interaction.pointers[pointerIndex].downTime;
        var interval = _this.timeStamp - interaction.tapTime;
        _this.double = !!interaction.prevTap && interaction.prevTap.type !== 'doubletap' && interaction.prevTap.target === _this.target && interval < 500;
      } else if (type === 'doubletap') {
        _this.dt = pointer.timeStamp - interaction.tapTime;
        _this.double = true;
      }
      return _this;
    }
    _createClass(PointerEvent, [{
      key: "_subtractOrigin",
      value: function _subtractOrigin(_ref) {
        var originX = _ref.x,
          originY = _ref.y;
        this.pageX -= originX;
        this.pageY -= originY;
        this.clientX -= originX;
        this.clientY -= originY;
        return this;
      }
    }, {
      key: "_addOrigin",
      value: function _addOrigin(_ref2) {
        var originX = _ref2.x,
          originY = _ref2.y;
        this.pageX += originX;
        this.pageY += originY;
        this.clientX += originX;
        this.clientY += originY;
        return this;
      }

      /**
       * Prevent the default behaviour of the original Event
       */
    }, {
      key: "preventDefault",
      value: function preventDefault() {
        this.originalEvent.preventDefault();
      }
    }]);
    return PointerEvent;
  }(BaseEvent);

  var defaults = {
    holdDuration: 600,
    ignoreFrom: null,
    allowFrom: null,
    origin: {
      x: 0,
      y: 0
    }
  };
  var pointerEvents$1 = {
    id: 'pointer-events/base',
    before: ['inertia', 'modifiers', 'auto-start', 'actions'],
    install: install$3,
    listeners: {
      'interactions:new': addInteractionProps,
      'interactions:update-pointer': addHoldInfo,
      'interactions:move': moveAndClearHold,
      'interactions:down': function interactionsDown(arg, scope) {
        downAndStartHold(arg, scope);
        fire(arg, scope);
      },
      'interactions:up': function interactionsUp(arg, scope) {
        clearHold(arg);
        fire(arg, scope);
        tapAfterUp(arg, scope);
      },
      'interactions:cancel': function interactionsCancel(arg, scope) {
        clearHold(arg);
        fire(arg, scope);
      }
    },
    PointerEvent: PointerEvent,
    fire: fire,
    collectEventTargets: collectEventTargets,
    defaults: defaults,
    types: {
      down: true,
      move: true,
      up: true,
      cancel: true,
      tap: true,
      doubletap: true,
      hold: true
    }
  };
  function fire(arg, scope) {
    var interaction = arg.interaction,
      pointer = arg.pointer,
      event = arg.event,
      eventTarget = arg.eventTarget,
      type = arg.type,
      _arg$targets = arg.targets,
      targets = _arg$targets === void 0 ? collectEventTargets(arg, scope) : _arg$targets;
    var pointerEvent = new PointerEvent(type, pointer, event, eventTarget, interaction, scope.now());
    scope.fire('pointerEvents:new', {
      pointerEvent: pointerEvent
    });
    var signalArg = {
      interaction: interaction,
      pointer: pointer,
      event: event,
      eventTarget: eventTarget,
      targets: targets,
      type: type,
      pointerEvent: pointerEvent
    };
    for (var i = 0; i < targets.length; i++) {
      var target = targets[i];
      for (var prop in target.props || {}) {
        pointerEvent[prop] = target.props[prop];
      }
      var origin = getOriginXY(target.eventable, target.node);
      pointerEvent._subtractOrigin(origin);
      pointerEvent.eventable = target.eventable;
      pointerEvent.currentTarget = target.node;
      target.eventable.fire(pointerEvent);
      pointerEvent._addOrigin(origin);
      if (pointerEvent.immediatePropagationStopped || pointerEvent.propagationStopped && i + 1 < targets.length && targets[i + 1].node !== pointerEvent.currentTarget) {
        break;
      }
    }
    scope.fire('pointerEvents:fired', signalArg);
    if (type === 'tap') {
      // if pointerEvent should make a double tap, create and fire a doubletap
      // PointerEvent and use that as the prevTap
      var prevTap = pointerEvent.double ? fire({
        interaction: interaction,
        pointer: pointer,
        event: event,
        eventTarget: eventTarget,
        type: 'doubletap'
      }, scope) : pointerEvent;
      interaction.prevTap = prevTap;
      interaction.tapTime = prevTap.timeStamp;
    }
    return pointerEvent;
  }
  function collectEventTargets(_ref, scope) {
    var interaction = _ref.interaction,
      pointer = _ref.pointer,
      event = _ref.event,
      eventTarget = _ref.eventTarget,
      type = _ref.type;
    var pointerIndex = interaction.getPointerIndex(pointer);
    var pointerInfo = interaction.pointers[pointerIndex];

    // do not fire a tap event if the pointer was moved before being lifted
    if (type === 'tap' && (interaction.pointerWasMoved ||
    // or if the pointerup target is different to the pointerdown target
    !(pointerInfo && pointerInfo.downTarget === eventTarget))) {
      return [];
    }
    var path = getPath(eventTarget);
    var signalArg = {
      interaction: interaction,
      pointer: pointer,
      event: event,
      eventTarget: eventTarget,
      type: type,
      path: path,
      targets: [],
      node: null
    };
    for (var _i2 = 0; _i2 < path.length; _i2++) {
      var node = path[_i2];
      signalArg.node = node;
      scope.fire('pointerEvents:collect-targets', signalArg);
    }
    if (type === 'hold') {
      signalArg.targets = signalArg.targets.filter(function (target) {
        var _interaction$pointers, _interaction$pointers2;
        return target.eventable.options.holdDuration === ((_interaction$pointers = interaction.pointers[pointerIndex]) == null ? void 0 : (_interaction$pointers2 = _interaction$pointers.hold) == null ? void 0 : _interaction$pointers2.duration);
      });
    }
    return signalArg.targets;
  }
  function addInteractionProps(_ref2) {
    var interaction = _ref2.interaction;
    interaction.prevTap = null; // the most recent tap event on this interaction
    interaction.tapTime = 0; // time of the most recent tap event
  }
  function addHoldInfo(_ref3) {
    var down = _ref3.down,
      pointerInfo = _ref3.pointerInfo;
    if (!down && pointerInfo.hold) {
      return;
    }
    pointerInfo.hold = {
      duration: Infinity,
      timeout: null
    };
  }
  function clearHold(_ref4) {
    var interaction = _ref4.interaction,
      pointerIndex = _ref4.pointerIndex;
    var hold = interaction.pointers[pointerIndex].hold;
    if (hold && hold.timeout) {
      clearTimeout(hold.timeout);
      hold.timeout = null;
    }
  }
  function moveAndClearHold(arg, scope) {
    var interaction = arg.interaction,
      pointer = arg.pointer,
      event = arg.event,
      eventTarget = arg.eventTarget,
      duplicate = arg.duplicate;
    if (!duplicate && (!interaction.pointerIsDown || interaction.pointerWasMoved)) {
      if (interaction.pointerIsDown) {
        clearHold(arg);
      }
      fire({
        interaction: interaction,
        pointer: pointer,
        event: event,
        eventTarget: eventTarget,
        type: 'move'
      }, scope);
    }
  }
  function downAndStartHold(_ref5, scope) {
    var interaction = _ref5.interaction,
      pointer = _ref5.pointer,
      event = _ref5.event,
      eventTarget = _ref5.eventTarget,
      pointerIndex = _ref5.pointerIndex;
    var timer = interaction.pointers[pointerIndex].hold;
    var path = getPath(eventTarget);
    var signalArg = {
      interaction: interaction,
      pointer: pointer,
      event: event,
      eventTarget: eventTarget,
      type: 'hold',
      targets: [],
      path: path,
      node: null
    };
    for (var _i4 = 0; _i4 < path.length; _i4++) {
      var node = path[_i4];
      signalArg.node = node;
      scope.fire('pointerEvents:collect-targets', signalArg);
    }
    if (!signalArg.targets.length) return;
    var minDuration = Infinity;
    for (var _i6 = 0, _signalArg$targets2 = signalArg.targets; _i6 < _signalArg$targets2.length; _i6++) {
      var target = _signalArg$targets2[_i6];
      var holdDuration = target.eventable.options.holdDuration;
      if (holdDuration < minDuration) {
        minDuration = holdDuration;
      }
    }
    timer.duration = minDuration;
    timer.timeout = setTimeout(function () {
      fire({
        interaction: interaction,
        eventTarget: eventTarget,
        pointer: pointer,
        event: event,
        type: 'hold'
      }, scope);
    }, minDuration);
  }
  function tapAfterUp(_ref6, scope) {
    var interaction = _ref6.interaction,
      pointer = _ref6.pointer,
      event = _ref6.event,
      eventTarget = _ref6.eventTarget;
    if (!interaction.pointerWasMoved) {
      fire({
        interaction: interaction,
        eventTarget: eventTarget,
        pointer: pointer,
        event: event,
        type: 'tap'
      }, scope);
    }
  }
  function install$3(scope) {
    scope.pointerEvents = pointerEvents$1;
    scope.defaults.actions.pointerEvents = pointerEvents$1.defaults;
    extend(scope.actions.phaselessTypes, pointerEvents$1.types);
  }

  var pointerEvents$2 = /*#__PURE__*/Object.freeze({
    __proto__: null,
    default: pointerEvents$1
  });

  /* eslint-disable import/no-duplicates -- for typescript module augmentations */
  function install$2(scope) {
    scope.usePlugin(pointerEvents$1);
    var pointerEvents = scope.pointerEvents;

    // don't repeat by default
    pointerEvents.defaults.holdRepeatInterval = 0;
    pointerEvents.types.holdrepeat = scope.actions.phaselessTypes.holdrepeat = true;
  }
  function onNew(_ref) {
    var pointerEvent = _ref.pointerEvent;
    if (pointerEvent.type !== 'hold') return;
    pointerEvent.count = (pointerEvent.count || 0) + 1;
  }
  function onFired(_ref2, scope) {
    var interaction = _ref2.interaction,
      pointerEvent = _ref2.pointerEvent,
      eventTarget = _ref2.eventTarget,
      targets = _ref2.targets;
    if (pointerEvent.type !== 'hold' || !targets.length) return;

    // get the repeat interval from the first eventable
    var interval = targets[0].eventable.options.holdRepeatInterval;

    // don't repeat if the interval is 0 or less
    if (interval <= 0) return;

    // set a timeout to fire the holdrepeat event
    interaction.holdIntervalHandle = setTimeout(function () {
      scope.pointerEvents.fire({
        interaction: interaction,
        eventTarget: eventTarget,
        type: 'hold',
        pointer: pointerEvent,
        event: pointerEvent
      }, scope);
    }, interval);
  }
  function endHoldRepeat(_ref3) {
    var interaction = _ref3.interaction;
    // set the interaction's holdStopTime property
    // to stop further holdRepeat events
    if (interaction.holdIntervalHandle) {
      clearInterval(interaction.holdIntervalHandle);
      interaction.holdIntervalHandle = null;
    }
  }
  var holdRepeat = {
    id: 'pointer-events/holdRepeat',
    install: install$2,
    listeners: ['move', 'up', 'cancel', 'endall'].reduce(function (acc, enderTypes) {
      acc["pointerEvents:".concat(enderTypes)] = endHoldRepeat;
      return acc;
    }, {
      'pointerEvents:new': onNew,
      'pointerEvents:fired': onFired
    })
  };
  var holdRepeat$1 = holdRepeat;

  function install$1(scope) {
    var Interactable = scope.Interactable;
    Interactable.prototype.pointerEvents = function (options) {
      extend(this.events.options, options);
      return this;
    };
    var __backCompatOption = Interactable.prototype._backCompatOption;
    Interactable.prototype._backCompatOption = function (optionName, newValue) {
      var ret = __backCompatOption.call(this, optionName, newValue);
      if (ret === this) {
        this.events.options[optionName] = newValue;
      }
      return ret;
    };
  }
  var plugin$1 = {
    id: 'pointer-events/interactableTargets',
    install: install$1,
    listeners: {
      'pointerEvents:collect-targets': function pointerEventsCollectTargets(_ref, scope) {
        var targets = _ref.targets,
          node = _ref.node,
          type = _ref.type,
          eventTarget = _ref.eventTarget;
        scope.interactables.forEachMatch(node, function (interactable) {
          var eventable = interactable.events;
          var options = eventable.options;
          if (eventable.types[type] && eventable.types[type].length && interactable.testIgnoreAllow(options, node, eventTarget)) {
            targets.push({
              node: node,
              eventable: eventable,
              props: {
                interactable: interactable
              }
            });
          }
        });
      },
      'interactable:new': function interactableNew(_ref2) {
        var interactable = _ref2.interactable;
        interactable.events.getRect = function (element) {
          return interactable.getRect(element);
        };
      },
      'interactable:set': function interactableSet(_ref3, scope) {
        var interactable = _ref3.interactable,
          options = _ref3.options;
        extend(interactable.events.options, scope.pointerEvents.defaults);
        extend(interactable.events.options, options.pointerEvents || {});
      }
    }
  };
  var interactableTargets = plugin$1;

  /* eslint-disable import/no-duplicates -- for typescript module augmentations */
  /* eslint-enable import/no-duplicates */

  var plugin = {
    id: 'pointer-events',
    install: function install(scope) {
      scope.usePlugin(pointerEvents$2);
      scope.usePlugin(holdRepeat$1);
      scope.usePlugin(interactableTargets);
    }
  };
  var pointerEvents = plugin;

  function install(scope) {
    var Interactable = scope.Interactable;
    scope.actions.phases.reflow = true;
    Interactable.prototype.reflow = function (action) {
      return doReflow(this, action, scope);
    };
  }
  function doReflow(interactable, action, scope) {
    var elements = interactable.getAllElements();

    // tslint:disable-next-line variable-name
    var Promise = scope.window.Promise;
    var promises = Promise ? [] : null;
    var _loop = function _loop() {
      var element = elements[_i2];
      var rect = interactable.getRect(element);
      if (!rect) {
        return 1; // break
      }
      var runningInteraction = find(scope.interactions.list, function (interaction) {
        return interaction.interacting() && interaction.interactable === interactable && interaction.element === element && interaction.prepared.name === action.name;
      });
      var reflowPromise;
      if (runningInteraction) {
        runningInteraction.move();
        if (promises) {
          reflowPromise = runningInteraction._reflowPromise || new Promise(function (resolve) {
            runningInteraction._reflowResolve = resolve;
          });
        }
      } else {
        var xywh = tlbrToXywh(rect);
        var coords = {
          page: {
            x: xywh.x,
            y: xywh.y
          },
          client: {
            x: xywh.x,
            y: xywh.y
          },
          timeStamp: scope.now()
        };
        var event = coordsToEvent(coords);
        reflowPromise = startReflow(scope, interactable, element, action, event);
      }
      if (promises) {
        promises.push(reflowPromise);
      }
    };
    for (var _i2 = 0; _i2 < elements.length; _i2++) {
      if (_loop()) break;
    }
    return promises && Promise.all(promises).then(function () {
      return interactable;
    });
  }
  function startReflow(scope, interactable, element, action, event) {
    var interaction = scope.interactions.new({
      pointerType: 'reflow'
    });
    var signalArg = {
      interaction: interaction,
      event: event,
      pointer: event,
      eventTarget: element,
      phase: 'reflow'
    };
    interaction.interactable = interactable;
    interaction.element = element;
    interaction.prevEvent = event;
    interaction.updatePointer(event, event, element, true);
    setZeroCoords(interaction.coords.delta);
    copyAction(interaction.prepared, action);
    interaction._doPhase(signalArg);
    var _ref = scope.window,
      Promise = _ref.Promise;
    var reflowPromise = Promise ? new Promise(function (resolve) {
      interaction._reflowResolve = resolve;
    }) : undefined;
    interaction._reflowPromise = reflowPromise;
    interaction.start(action, interactable, element);
    if (interaction._interacting) {
      interaction.move(signalArg);
      interaction.end(event);
    } else {
      interaction.stop();
      interaction._reflowResolve();
    }
    interaction.removePointer(event, event);
    return reflowPromise;
  }
  var reflow = {
    id: 'reflow',
    install: install,
    listeners: {
      // remove completed reflow interactions
      'interactions:stop': function interactionsStop(_ref2, scope) {
        var interaction = _ref2.interaction;
        if (interaction.pointerType === 'reflow') {
          if (interaction._reflowResolve) {
            interaction._reflowResolve();
          }
          remove(scope.interactions.list, interaction);
        }
      }
    }
  };
  var reflow$1 = reflow;

  /* eslint-disable import/no-duplicates -- for typescript module augmentations */
  /* eslint-enable import/no-duplicates */

  interact$1.use(interactablePreventDefault);
  interact$1.use(offset$1);

  // pointerEvents
  interact$1.use(pointerEvents);

  // inertia
  interact$1.use(inertia$1);

  // snap, resize, etc.
  interact$1.use(modifiers$1);

  // autoStart, hold
  interact$1.use(autoStart);

  // drag and drop, resize, gesture
  interact$1.use(actions);

  // autoScroll
  interact$1.use(autoScroll$1);

  // reflow
  interact$1.use(reflow$1);

  // eslint-disable-next-line no-undef
  {
    interact$1.use(devTools);
  }
  interact$1.default = interact$1;

  if ((typeof module === "undefined" ? "undefined" : _typeof(module)) === 'object' && !!module) {
    try {
      module.exports = interact$1;
    } catch (_unused) {}
  }
  interact$1.default = interact$1;

  return interact$1;

}));
//# sourceMappingURL=interact.js.map

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址