PageSourceSearch

https://www.bensonvisitorcenter.com/libs/Sortable.js?v2

js bensonvisitorcenter.com collected 2026-09-26 14:31:08 UTC 127,301 bytes, 3,783 lines download raw bytes

1/**!
2 * Sortable 1.14.0
3 * @author	RubaXa   <[email protected]>
4 * @author	owenm    <[email protected]>
5 * @license MIT
6 */
7 (function (global, factory) {
8  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
9  typeof define === 'function' && define.amd ? define(factory) :
10  (global = global || self, global.Sortable = factory());
11}(this, (function () { 'use strict';
12
13  function ownKeys(object, enumerableOnly) {
14    var keys = Object.keys(object);
15
16    if (Object.getOwnPropertySymbols) {
17      var symbols = Object.getOwnPropertySymbols(object);
18
19      if (enumerableOnly) {
20        symbols = symbols.filter(function (sym) {
21          return Object.getOwnPropertyDescriptor(object, sym).enumerable;
22        });
23      }
24
25      keys.push.apply(keys, symbols);
26    }
27
28    return keys;
29  }
30
31  function _objectSpread2(target) {
32    for (var i = 1; i < arguments.length; i++) {
33      var source = arguments[i] != null ? arguments[i] : {};
34
35      if (i % 2) {
36        ownKeys(Object(source), true).forEach(function (key) {
37          _defineProperty(target, key, source[key]);
38        });
39      } else if (Object.getOwnPropertyDescriptors) {
40        Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
41      } else {
42        ownKeys(Object(source)).forEach(function (key) {
43          Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
44        });
45      }
46    }
47
48    return target;
49  }
50
51  function _typeof(obj) {
52    "@babel/helpers - typeof";
53
54    if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
55      _typeof = function (obj) {
56        return typeof obj;
57      };
58    } else {
59      _typeof = function (obj) {
60        return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
61      };
62    }
63
64    return _typeof(obj);
65  }
66
67  function _defineProperty(obj, key, value) {
68    if (key in obj) {
69      Object.defineProperty(obj, key, {
70        value: value,
71        enumerable: true,
72        configurable: true,
73        writable: true
74      });
75    } else {
76      obj[key] = value;
77    }
78
79    return obj;
80  }
81
82  function _extends() {
83    _extends = Object.assign || function (target) {
84      for (var i = 1; i < arguments.length; i++) {
85        var source = arguments[i];
86
87        for (var key in source) {
88          if (Object.prototype.hasOwnProperty.call(source, key)) {
89            target[key] = source[key];
90          }
91        }
92      }
93
94      return target;
95    };
96
97    return _extends.apply(this, arguments);
98  }
99
100  function _objectWithoutPropertiesLoose(source, excluded) {
101    if (source == null) return {};
102    var target = {};
103    var sourceKeys = Object.keys(source);
104    var key, i;
105
106    for (i = 0; i < sourceKeys.length; i++) {
107      key = sourceKeys[i];
108      if (excluded.indexOf(key) >= 0) continue;
109      target[key] = source[key];
110    }
111
112    return target;
113  }
114
115  function _objectWithoutProperties(source, excluded) {
116    if (source == null) return {};
117
118    var target = _objectWithoutPropertiesLoose(source, excluded);
119
120    var key, i;
121
122    if (Object.getOwnPropertySymbols) {
123      var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
124
125      for (i = 0; i < sourceSymbolKeys.length; i++) {
126        key = sourceSymbolKeys[i];
127        if (excluded.indexOf(key) >= 0) continue;
128        if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
129        target[key] = source[key];
130      }
131    }
132
133    return target;
134  }
135
136  function _toConsumableArray(arr) {
137    return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
138  }
139
140  function _arrayWithoutHoles(arr) {
141    if (Array.isArray(arr)) return _arrayLikeToArray(arr);
142  }
143
144  function _iterableToArray(iter) {
145    if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
146  }
147
148  function _unsupportedIterableToArray(o, minLen) {
149    if (!o) return;
150    if (typeof o === "string") return _arrayLikeToArray(o, minLen);
151    var n = Object.prototype.toString.call(o).slice(8, -1);
152    if (n === "Object" && o.constructor) n = o.constructor.name;
153    if (n === "Map" || n === "Set") return Array.from(o);
154    if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
155  }
156
157  function _arrayLikeToArray(arr, len) {
158    if (len == null || len > arr.length) len = arr.length;
159
160    for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
161
162    return arr2;
163  }
164
165  function _nonIterableSpread() {
166    throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
167  }
168
169  var version = "1.14.0";
170
171  function userAgent(pattern) {
172    if (typeof window !== 'undefined' && window.navigator) {
173      return !! /*@__PURE__*/navigator.userAgent.match(pattern);
174    }
175  }
176
vendor: 4,211 bytes, lines 177-336
177  var IE11OrLess = userAgent(/(?:Trident.*rv[ :]?11\.|msie|iemobile|Windows Phone)/i);
178  var Edge = userAgent(/Edge/i);
179  var FireFox = userAgent(/firefox/i);
180  var Safari = userAgent(/safari/i) && !userAgent(/chrome/i) && !userAgent(/android/i);
181  var IOS = userAgent(/iP(ad|od|hone)/i);
182  var ChromeForAndroid = userAgent(/chrome/i) && userAgent(/android/i);
183
184  var captureMode = {
185    capture: false,
186    passive: false
187  };
188
189  function on(el, event, fn) {
190    el.addEventListener(event, fn, !IE11OrLess && captureMode);
191  }
192
193  function off(el, event, fn) {
194    el.removeEventListener(event, fn, !IE11OrLess && captureMode);
195  }
196
197  function matches(
198  /**HTMLElement*/
199  el,
200  /**String*/
201  selector) {
202    if (!selector) return;
203    selector[0] === '>' && (selector = selector.substring(1));
204
205    if (el) {
206      try {
207        if (el.matches) {
208          return el.matches(selector);
209        } else if (el.msMatchesSelector) {
210          return el.msMatchesSelector(selector);
211        } else if (el.webkitMatchesSelector) {
212          return el.webkitMatchesSelector(selector);
213        }
214      } catch (_) {
215        return false;
216      }
217    }
218
219    return false;
220  }
221
222  function getParentOrHost(el) {
223    return el.host && el !== document && el.host.nodeType ? el.host : el.parentNode;
224  }
225
226  function closest(
227  /**HTMLElement*/
228  el,
229  /**String*/
230  selector,
231  /**HTMLElement*/
232  ctx, includeCTX) {
233    if (el) {
234      ctx = ctx || document;
235
236      do {
237        if (selector != null && (selector[0] === '>' ? el.parentNode === ctx && matches(el, selector) : matches(el, selector)) || includeCTX && el === ctx) {
238          return el;
239        }
240
241        if (el === ctx) break;
242        /* jshint boss:true */
243      } while (el = getParentOrHost(el));
244    }
245
246    return null;
247  }
248
249  var R_SPACE = /\s+/g;
250
251  function toggleClass(el, name, state) {
252    if (el && name) {
253      if (el.classList) {
254        el.classList[state ? 'add' : 'remove'](name);
255      } else {
256        var className = (' ' + el.className + ' ').replace(R_SPACE, ' ').replace(' ' + name + ' ', ' ');
257        el.className = (className + (state ? ' ' + name : '')).replace(R_SPACE, ' ');
258      }
259    }
260  }
261
262  function css(el, prop, val) {
263    var style = el && el.style;
264
265    if (style) {
266      if (val === void 0) {
267        if (document.defaultView && document.defaultView.getComputedStyle) {
268          val = document.defaultView.getComputedStyle(el, '');
269        } else if (el.currentStyle) {
270          val = el.currentStyle;
271        }
272
273        return prop === void 0 ? val : val[prop];
274      } else {
275        if (!(prop in style) && prop.indexOf('webkit') === -1) {
276          prop = '-webkit-' + prop;
277        }
278
279        style[prop] = val + (typeof val === 'string' ? '' : 'px');
280      }
281    }
282  }
283
284  function matrix(el, selfOnly) {
285    var appliedTransforms = '';
286
287    if (typeof el === 'string') {
288      appliedTransforms = el;
289    } else {
290      do {
291        var transform = css(el, 'transform');
292
293        if (transform && transform !== 'none') {
294          appliedTransforms = transform + ' ' + appliedTransforms;
295        }
296        /* jshint boss:true */
297
298      } while (!selfOnly && (el = el.parentNode));
299    }
300
301    var matrixFn = window.DOMMatrix || window.WebKitCSSMatrix || window.CSSMatrix || window.MSCSSMatrix;
302    /*jshint -W056 */
303
304    return matrixFn && new matrixFn(appliedTransforms);
305  }
306
307  function find(ctx, tagName, iterator) {
308    if (ctx) {
309      var list = ctx.getElementsByTagName(tagName),
310          i = 0,
311          n = list.length;
312
313      if (iterator) {
314        for (; i < n; i++) {
315          iterator(list[i], i);
316        }
317      }
318
319      return list;
320    }
321
322    return [];
323  }
324
325  function getWindowScrollingElement() {
326    var scrollingElement = document.scrollingElement;
327
328    if (scrollingElement) {
329      return scrollingElement;
330    } else {
331      return document.documentElement;
332    }
333  }
334  /**
335   * Returns the "bounding client rect" of given element
336   * @param  {HTMLElement} el                       The element whose boundingClientRect is 
vendor: 10,807 bytes, lines 336-670
336wanted
337   * @param  {[Boolean]} relativeToContainingBlock  Whether the rect should be relative to the containing block of (including) the container
338   * @param  {[Boolean]} relativeToNonStaticParent  Whether the rect should be relative to the relative parent of (including) the contaienr
339   * @param  {[Boolean]} undoScale                  Whether the container's scale() should be undone
340   * @param  {[HTMLElement]} container              The parent the element will be placed in
341   * @return {Object}                               The boundingClientRect of el, with specified adjustments
342   */
343
344
345  function getRect(el, relativeToContainingBlock, relativeToNonStaticParent, undoScale, container) {
346    if (!el.getBoundingClientRect && el !== window) return;
347    var elRect, top, left, bottom, right, height, width;
348
349    if (el !== window && el.parentNode && el !== getWindowScrollingElement()) {
350      elRect = el.getBoundingClientRect();
351      top = elRect.top;
352      left = elRect.left;
353      bottom = elRect.bottom;
354      right = elRect.right;
355      height = elRect.height;
356      width = elRect.width;
357    } else {
358      top = 0;
359      left = 0;
360      bottom = window.innerHeight;
361      right = window.innerWidth;
362      height = window.innerHeight;
363      width = window.innerWidth;
364    }
365
366    if ((relativeToContainingBlock || relativeToNonStaticParent) && el !== window) {
367      // Adjust for translate()
368      container = container || el.parentNode; // solves #1123 (see: https://stackoverflow.com/a/37953806/6088312)
369      // Not needed on <= IE11
370
371      if (!IE11OrLess) {
372        do {
373          if (container && container.getBoundingClientRect && (css(container, 'transform') !== 'none' || relativeToNonStaticParent && css(container, 'position') !== 'static')) {
374            var containerRect = container.getBoundingClientRect(); // Set relative to edges of padding box of container
375
376            top -= containerRect.top + parseInt(css(container, 'border-top-width'));
377            left -= containerRect.left + parseInt(css(container, 'border-left-width'));
378            bottom = top + elRect.height;
379            right = left + elRect.width;
380            break;
381          }
382          /* jshint boss:true */
383
384        } while (container = container.parentNode);
385      }
386    }
387
388    if (undoScale && el !== window) {
389      // Adjust for scale()
390      var elMatrix = matrix(container || el),
391          scaleX = elMatrix && elMatrix.a,
392          scaleY = elMatrix && elMatrix.d;
393
394      if (elMatrix) {
395        top /= scaleY;
396        left /= scaleX;
397        width /= scaleX;
398        height /= scaleY;
399        bottom = top + height;
400        right = left + width;
401      }
402    }
403
404    return {
405      top: top,
406      left: left,
407      bottom: bottom,
408      right: right,
409      width: width,
410      height: height
411    };
412  }
413  /**
414   * Checks if a side of an element is scrolled past a side of its parents
415   * @param  {HTMLElement}  el           The element who's side being scrolled out of view is in question
416   * @param  {String}       elSide       Side of the element in question ('top', 'left', 'right', 'bottom')
417   * @param  {String}       parentSide   Side of the parent in question ('top', 'left', 'right', 'bottom')
418   * @return {HTMLElement}               The parent scroll element that the el's side is scrolled past, or null if there is no such element
419   */
420
421
422  function isScrolledPast(el, elSide, parentSide) {
423    var parent = getParentAutoScrollElement(el, true),
424        elSideVal = getRect(el)[elSide];
425    /* jshint boss:true */
426
427    while (parent) {
428      var parentSideVal = getRect(parent)[parentSide],
429          visible = void 0;
430
431      if (parentSide === 'top' || parentSide === 'left') {
432        visible = elSideVal >= parentSideVal;
433      } else {
434        visible = elSideVal <= parentSideVal;
435      }
436
437      if (!visible) return parent;
438      if (parent === getWindowScrollingElement()) break;
439      parent = getParentAutoScrollElement(parent, false);
440    }
441
442    return false;
443  }
444  /**
445   * Gets nth child of el, ignoring hidden children, sortable's elements (does not ignore clone if it's visible)
446   * and non-draggable elements
447   * @param  {HTMLElement} el       The parent element
448   * @param  {Number} childNum      The index of the child
449   * @param  {Object} options       Parent Sortable's options
450   * @return {HTMLElement}          The child at index childNum, or null if not found
451   */
452
453
454  function getChild(el, childNum, options, includeDragEl) {
455    var currentChild = 0,
456        i = 0,
457        children = el.children;
458
459    while (i < children.length) {
460      if (children[i].style.display !== 'none' && children[i] !== Sortable.ghost && (includeDragEl || children[i] !== Sortable.dragged) && closest(children[i], options.draggable, el, false)) {
461        if (currentChild === childNum) {
462          return children[i];
463        }
464
465        currentChild++;
466      }
467
468      i++;
469    }
470
471    return null;
472  }
473  /**
474   * Gets the last child in the el, ignoring ghostEl or invisible elements (clones)
475   * @param  {HTMLElement} el       Parent element
476   * @param  {selector} selector    Any other elements that should be ignored
477   * @return {HTMLElement}          The last child, ignoring ghostEl
478   */
479
480
481  function lastChild(el, selector) {
482    var last = el.lastElementChild;
483
484    while (last && (last === Sortable.ghost || css(last, 'display') === 'none' || selector && !matches(last, selector))) {
485      last = last.previousElementSibling;
486    }
487
488    return last || null;
489  }
490  /**
491   * Returns the index of an element within its parent for a selected set of
492   * elements
493   * @param  {HTMLElement} el
494   * @param  {selector} selector
495   * @return {number}
496   */
497
498
499  function index(el, selector) {
500    var index = 0;
501
502    if (!el || !el.parentNode) {
503      return -1;
504    }
505    /* jshint boss:true */
506
507
508    while (el = el.previousElementSibling) {
509      if (el.nodeName.toUpperCase() !== 'TEMPLATE' && el !== Sortable.clone && (!selector || matches(el, selector))) {
510        index++;
511      }
512    }
513
514    return index;
515  }
516  /**
517   * Returns the scroll offset of the given element, added with all the scroll offsets of parent elements.
518   * The value is returned in real pixels.
519   * @param  {HTMLElement} el
520   * @return {Array}             Offsets in the format of [left, top]
521   */
522
523
524  function getRelativeScrollOffset(el) {
525    var offsetLeft = 0,
526        offsetTop = 0,
527        winScroller = getWindowScrollingElement();
528
529    if (el) {
530      do {
531        var elMatrix = matrix(el),
532            scaleX = elMatrix.a,
533            scaleY = elMatrix.d;
534        offsetLeft += el.scrollLeft * scaleX;
535        offsetTop += el.scrollTop * scaleY;
536      } while (el !== winScroller && (el = el.parentNode));
537    }
538
539    return [offsetLeft, offsetTop];
540  }
541  /**
542   * Returns the index of the object within the given array
543   * @param  {Array} arr   Array that may or may not hold the object
544   * @param  {Object} obj  An object that has a key-value pair unique to and identical to a key-value pair in the object you want to find
545   * @return {Number}      The index of the object in the array, or -1
546   */
547
548
549  function indexOfObject(arr, obj) {
550    for (var i in arr) {
551      if (!arr.hasOwnProperty(i)) continue;
552
553      for (var key in obj) {
554        if (obj.hasOwnProperty(key) && obj[key] === arr[i][key]) return Number(i);
555      }
556    }
557
558    return -1;
559  }
560
561  function getParentAutoScrollElement(el, includeSelf) {
562    // skip to window
563    if (!el || !el.getBoundingClientRect) return getWindowScrollingElement();
564    var elem = el;
565    var gotSelf = false;
566
567    do {
568      // we don't need to get elem css if it isn't even overflowing in the first place (performance)
569      if (elem.clientWidth < elem.scrollWidth || elem.clientHeight < elem.scrollHeight) {
570        var elemCSS = css(elem);
571
572        if (elem.clientWidth < elem.scrollWidth && (elemCSS.overflowX == 'auto' || elemCSS.overflowX == 'scroll') || elem.clientHeight < elem.scrollHeight && (elemCSS.overflowY == 'auto' || elemCSS.overflowY == 'scroll')) {
573          if (!elem.getBoundingClientRect || elem === document.body) return getWindowScrollingElement();
574          if (gotSelf || includeSelf) return elem;
575          gotSelf = true;
576        }
577      }
578      /* jshint boss:true */
579
580    } while (elem = elem.parentNode);
581
582    return getWindowScrollingElement();
583  }
584
585  function extend(dst, src) {
586    if (dst && src) {
587      for (var key in src) {
588        if (src.hasOwnProperty(key)) {
589          dst[key] = src[key];
590        }
591      }
592    }
593
594    return dst;
595  }
596
597  function isRectEqual(rect1, rect2) {
598    return Math.round(rect1.top) === Math.round(rect2.top) && Math.round(rect1.left) === Math.round(rect2.left) && Math.round(rect1.height) === Math.round(rect2.height) && Math.round(rect1.width) === Math.round(rect2.width);
599  }
600
601  var _throttleTimeout;
602
603  function throttle(callback, ms) {
604    return function () {
605      if (!_throttleTimeout) {
606        var args = arguments,
607            _this = this;
608
609        if (args.length === 1) {
610          callback.call(_this, args[0]);
611        } else {
612          callback.apply(_this, args);
613        }
614
615        _throttleTimeout = setTimeout(function () {
616          _throttleTimeout = void 0;
617        }, ms);
618      }
619    };
620  }
621
622  function cancelThrottle() {
623    clearTimeout(_throttleTimeout);
624    _throttleTimeout = void 0;
625  }
626
627  function scrollBy(el, x, y) {
628    el.scrollLeft += x;
629    el.scrollTop += y;
630  }
631
632  function clone(el) {
633    var Polymer = window.Polymer;
634    var $ = window.jQuery || window.Zepto;
635
636    if (Polymer && Polymer.dom) {
637      return Polymer.dom(el).cloneNode(true);
638    } else if ($) {
639      return $(el).clone(true)[0];
640    } else {
641      return el.cloneNode(true);
642    }
643  }
644
645  function setRect(el, rect) {
646    css(el, 'position', 'absolute');
647    css(el, 'top', rect.top);
648    css(el, 'left', rect.left);
649    css(el, 'width', rect.width);
650    css(el, 'height', rect.height);
651  }
652
653  function unsetRect(el) {
654    css(el, 'position', '');
655    css(el, 'top', '');
656    css(el, 'left', '');
657    css(el, 'width', '');
658    css(el, 'height', '');
659  }
660
661  var expando = 'Sortable' + new Date().getTime();
662
663  function AnimationStateManager() {
664    var animationStates = [],
665        animationCallbackId;
666    return {
667      captureAnimationState: function captureAnimationState() {
668        animationStates = [];
669        if (!this.options.animation) return;
670        var children = [].slice.call(this.el.children);
vendor: 17,082 bytes, lines 671-1119
671        children.forEach(function (child) {
672          if (css(child, 'display') === 'none' || child === Sortable.ghost) return;
673          animationStates.push({
674            target: child,
675            rect: getRect(child)
676          });
677
678          var fromRect = _objectSpread2({}, animationStates[animationStates.length - 1].rect); // If animating: compensate for current animation
679
680
681          if (child.thisAnimationDuration) {
682            var childMatrix = matrix(child, true);
683
684            if (childMatrix) {
685              fromRect.top -= childMatrix.f;
686              fromRect.left -= childMatrix.e;
687            }
688          }
689
690          child.fromRect = fromRect;
691        });
692      },
693      addAnimationState: function addAnimationState(state) {
694        animationStates.push(state);
695      },
696      removeAnimationState: function removeAnimationState(target) {
697        animationStates.splice(indexOfObject(animationStates, {
698          target: target
699        }), 1);
700      },
701      animateAll: function animateAll(callback) {
702        var _this = this;
703
704        if (!this.options.animation) {
705          clearTimeout(animationCallbackId);
706          if (typeof callback === 'function') callback();
707          return;
708        }
709
710        var animating = false,
711            animationTime = 0;
712        animationStates.forEach(function (state) {
713          var time = 0,
714              target = state.target,
715              fromRect = target.fromRect,
716              toRect = getRect(target),
717              prevFromRect = target.prevFromRect,
718              prevToRect = target.prevToRect,
719              animatingRect = state.rect,
720              targetMatrix = matrix(target, true);
721
722          if (targetMatrix) {
723            // Compensate for current animation
724            toRect.top -= targetMatrix.f;
725            toRect.left -= targetMatrix.e;
726          }
727
728          target.toRect = toRect;
729
730          if (target.thisAnimationDuration) {
731            // Could also check if animatingRect is between fromRect and toRect
732            if (isRectEqual(prevFromRect, toRect) && !isRectEqual(fromRect, toRect) && // Make sure animatingRect is on line between toRect & fromRect
733            (animatingRect.top - toRect.top) / (animatingRect.left - toRect.left) === (fromRect.top - toRect.top) / (fromRect.left - toRect.left)) {
734              // If returning to same place as started from animation and on same axis
735              time = calculateRealTime(animatingRect, prevFromRect, prevToRect, _this.options);
736            }
737          } // if fromRect != toRect: animate
738
739
740          if (!isRectEqual(toRect, fromRect)) {
741            target.prevFromRect = fromRect;
742            target.prevToRect = toRect;
743
744            if (!time) {
745              time = _this.options.animation;
746            }
747
748            _this.animate(target, animatingRect, toRect, time);
749          }
750
751          if (time) {
752            animating = true;
753            animationTime = Math.max(animationTime, time);
754            clearTimeout(target.animationResetTimer);
755            target.animationResetTimer = setTimeout(function () {
756              target.animationTime = 0;
757              target.prevFromRect = null;
758              target.fromRect = null;
759              target.prevToRect = null;
760              target.thisAnimationDuration = null;
761            }, time);
762            target.thisAnimationDuration = time;
763          }
764        });
765        clearTimeout(animationCallbackId);
766
767        if (!animating) {
768          if (typeof callback === 'function') callback();
769        } else {
770          animationCallbackId = setTimeout(function () {
771            if (typeof callback === 'function') callback();
772          }, animationTime);
773        }
774
775        animationStates = [];
776      },
777      animate: function animate(target, currentRect, toRect, duration) {
778        if (duration) {
779          css(target, 'transition', '');
780          css(target, 'transform', '');
781          var elMatrix = matrix(this.el),
782              scaleX = elMatrix && elMatrix.a,
783              scaleY = elMatrix && elMatrix.d,
784              translateX = (currentRect.left - toRect.left) / (scaleX || 1),
785              translateY = (currentRect.top - toRect.top) / (scaleY || 1);
786          target.animatingX = !!translateX;
787          target.animatingY = !!translateY;
788          css(target, 'transform', 'translate3d(' + translateX + 'px,' + translateY + 'px,0)');
789          this.forRepaintDummy = repaint(target); // repaint
790
791          css(target, 'transition', 'transform ' + duration + 'ms' + (this.options.easing ? ' ' + this.options.easing : ''));
792          css(target, 'transform', 'translate3d(0,0,0)');
793          typeof target.animated === 'number' && clearTimeout(target.animated);
794          target.animated = setTimeout(function () {
795            css(target, 'transition', '');
796            css(target, 'transform', '');
797            target.animated = false;
798            target.animatingX = false;
799            target.animatingY = false;
800          }, duration);
801        }
802      }
803    };
804  }
805
806  function repaint(target) {
807    return target.offsetWidth;
808  }
809
810  function calculateRealTime(animatingRect, fromRect, toRect, options) {
811    return Math.sqrt(Math.pow(fromRect.top - animatingRect.top, 2) + Math.pow(fromRect.left - animatingRect.left, 2)) / Math.sqrt(Math.pow(fromRect.top - toRect.top, 2) + Math.pow(fromRect.left - toRect.left, 2)) * options.animation;
812  }
813
814  var plugins = [];
815  var defaults = {
816    initializeByDefault: true
817  };
818  var PluginManager = {
819    mount: function mount(plugin) {
820      // Set default static properties
821      for (var option in defaults) {
822        if (defaults.hasOwnProperty(option) && !(option in plugin)) {
823          plugin[option] = defaults[option];
824        }
825      }
826
827      plugins.forEach(function (p) {
828        if (p.pluginName === plugin.pluginName) {
829          throw "Sortable: Cannot mount plugin ".concat(plugin.pluginName, " more than once");
830        }
831      });
832      plugins.push(plugin);
833    },
834    pluginEvent: function pluginEvent(eventName, sortable, evt) {
835      var _this = this;
836
837      this.eventCanceled = false;
838
839      evt.cancel = function () {
840        _this.eventCanceled = true;
841      };
842
843      var eventNameGlobal = eventName + 'Global';
844      plugins.forEach(function (plugin) {
845        if (!sortable[plugin.pluginName]) return; // Fire global events if it exists in this sortable
846
847        if (sortable[plugin.pluginName][eventNameGlobal]) {
848          sortable[plugin.pluginName][eventNameGlobal](_objectSpread2({
849            sortable: sortable
850          }, evt));
851        } // Only fire plugin event if plugin is enabled in this sortable,
852        // and plugin has event defined
853
854
855        if (sortable.options[plugin.pluginName] && sortable[plugin.pluginName][eventName]) {
856          sortable[plugin.pluginName][eventName](_objectSpread2({
857            sortable: sortable
858          }, evt));
859        }
860      });
861    },
862    initializePlugins: function initializePlugins(sortable, el, defaults, options) {
863      plugins.forEach(function (plugin) {
864        var pluginName = plugin.pluginName;
865        if (!sortable.options[pluginName] && !plugin.initializeByDefault) return;
866        var initialized = new plugin(sortable, el, sortable.options);
867        initialized.sortable = sortable;
868        initialized.options = sortable.options;
869        sortable[pluginName] = initialized; // Add default options from plugin
870
871        _extends(defaults, initialized.defaults);
872      });
873
874      for (var option in sortable.options) {
875        if (!sortable.options.hasOwnProperty(option)) continue;
876        var modified = this.modifyOption(sortable, option, sortable.options[option]);
877
878        if (typeof modified !== 'undefined') {
879          sortable.options[option] = modified;
880        }
881      }
882    },
883    getEventProperties: function getEventProperties(name, sortable) {
884      var eventProperties = {};
885      plugins.forEach(function (plugin) {
886        if (typeof plugin.eventProperties !== 'function') return;
887
888        _extends(eventProperties, plugin.eventProperties.call(sortable[plugin.pluginName], name));
889      });
890      return eventProperties;
891    },
892    modifyOption: function modifyOption(sortable, name, value) {
893      var modifiedValue;
894      plugins.forEach(function (plugin) {
895        // Plugin must exist on the Sortable
896        if (!sortable[plugin.pluginName]) return; // If static option listener exists for this option, call in the context of the Sortable's instance of this plugin
897
898        if (plugin.optionListeners && typeof plugin.optionListeners[name] === 'function') {
899          modifiedValue = plugin.optionListeners[name].call(sortable[plugin.pluginName], value);
900        }
901      });
902      return modifiedValue;
903    }
904  };
905
906  function dispatchEvent(_ref) {
907    var sortable = _ref.sortable,
908        rootEl = _ref.rootEl,
909        name = _ref.name,
910        targetEl = _ref.targetEl,
911        cloneEl = _ref.cloneEl,
912        toEl = _ref.toEl,
913        fromEl = _ref.fromEl,
914        oldIndex = _ref.oldIndex,
915        newIndex = _ref.newIndex,
916        oldDraggableIndex = _ref.oldDraggableIndex,
917        newDraggableIndex = _ref.newDraggableIndex,
918        originalEvent = _ref.originalEvent,
919        putSortable = _ref.putSortable,
920        extraEventProperties = _ref.extraEventProperties;
921    sortable = sortable || rootEl && rootEl[expando];
922    if (!sortable) return;
923    var evt,
924        options = sortable.options,
925        onName = 'on' + name.charAt(0).toUpperCase() + name.substr(1); // Support for new CustomEvent feature
926
927    if (window.CustomEvent && !IE11OrLess && !Edge) {
928      evt = new CustomEvent(name, {
929        bubbles: true,
930        cancelable: true
931      });
932    } else {
933      evt = document.createEvent('Event');
934      evt.initEvent(name, true, true);
935    }
936
937    evt.to = toEl || rootEl;
938    evt.from = fromEl || rootEl;
939    evt.item = targetEl || rootEl;
940    evt.clone = cloneEl;
941    evt.oldIndex = oldIndex;
942    evt.newIndex = newIndex;
943    evt.oldDraggableIndex = oldDraggableIndex;
944    evt.newDraggableIndex = newDraggableIndex;
945    evt.originalEvent = originalEvent;
946    evt.pullMode = putSortable ? putSortable.lastPutMode : undefined;
947
948    var allEventProperties = _objectSpread2(_objectSpread2({}, extraEventProperties), PluginManager.getEventProperties(name, sortable));
949
950    for (var option in allEventProperties) {
951      evt[option] = allEventProperties[option];
952    }
953
954    if (rootEl) {
955      rootEl.dispatchEvent(evt);
956    }
957
958    if (options[onName]) {
959      options[onName].call(sortable, evt);
960    }
961  }
962
963  var _excluded = ["evt"];
964
965  var pluginEvent = function pluginEvent(eventName, sortable) {
966    var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
967        originalEvent = _ref.evt,
968        data = _objectWithoutProperties(_ref, _excluded);
969
970    PluginManager.pluginEvent.bind(Sortable)(eventName, sortable, _objectSpread2({
971      dragEl: dragEl,
972      parentEl: parentEl,
973      ghostEl: ghostEl,
974      rootEl: rootEl,
975      nextEl: nextEl,
976      lastDownEl: lastDownEl,
977      cloneEl: cloneEl,
978      cloneHidden: cloneHidden,
979      dragStarted: moved,
980      putSortable: putSortable,
981      activeSortable: Sortable.active,
982      originalEvent: originalEvent,
983      oldIndex: oldIndex,
984      oldDraggableIndex: oldDraggableIndex,
985      newIndex: newIndex,
986      newDraggableIndex: newDraggableIndex,
987      hideGhostForTarget: _hideGhostForTarget,
988      unhideGhostForTarget: _unhideGhostForTarget,
989      cloneNowHidden: function cloneNowHidden() {
990        cloneHidden = true;
991      },
992      cloneNowShown: function cloneNowShown() {
993        cloneHidden = false;
994      },
995      dispatchSortableEvent: function dispatchSortableEvent(name) {
996        _dispatchEvent({
997          sortable: sortable,
998          name: name,
999          originalEvent: originalEvent
1000        });
1001      }
1002    }, data));
1003  };
1004
1005  function _dispatchEvent(info) {
1006    dispatchEvent(_objectSpread2({
1007      putSortable: putSortable,
1008      cloneEl: cloneEl,
1009      targetEl: dragEl,
1010      rootEl: rootEl,
1011      oldIndex: oldIndex,
1012      oldDraggableIndex: oldDraggableIndex,
1013      newIndex: newIndex,
1014      newDraggableIndex: newDraggableIndex
1015    }, info));
1016  }
1017
1018  var dragEl,
1019      parentEl,
1020      ghostEl,
1021      rootEl,
1022      nextEl,
1023      lastDownEl,
1024      cloneEl,
1025      cloneHidden,
1026      oldIndex,
1027      newIndex,
1028      oldDraggableIndex,
1029      newDraggableIndex,
1030      activeGroup,
1031      putSortable,
1032      awaitingDragStarted = false,
1033      ignoreNextClick = false,
1034      sortables = [],
1035      tapEvt,
1036      touchEvt,
1037      lastDx,
1038      lastDy,
1039      tapDistanceLeft,
1040      tapDistanceTop,
1041      moved,
1042      lastTarget,
1043      lastDirection,
1044      pastFirstInvertThresh = false,
1045      isCircumstantialInvert = false,
1046      targetMoveDistance,
1047      // For positioning ghost absolutely
1048  ghostRelativeParent,
1049      ghostRelativeParentInitialScroll = [],
1050      // (left, top)
1051  _silent = false,
1052      savedInputChecked = [];
1053  /** @const */
1054
1055  var documentExists = typeof document !== 'undefined',
1056      PositionGhostAbsolutely = IOS,
1057      CSSFloatProperty = Edge || IE11OrLess ? 'cssFloat' : 'float',
1058      // This will not pass for IE9, because IE9 DnD only works on anchors
1059  supportDraggable = documentExists && !ChromeForAndroid && !IOS && 'draggable' in document.createElement('div'),
1060      supportCssPointerEvents = function () {
1061    if (!documentExists) return; // false when <= IE11
1062
1063    if (IE11OrLess) {
1064      return false;
1065    }
1066
1067    var el = document.createElement('x');
1068    el.style.cssText = 'pointer-events:auto';
1069    return el.style.pointerEvents === 'auto';
1070  }(),
1071      _detectDirection = function _detectDirection(el, options) {
1072    var elCSS = css(el),
1073        elWidth = parseInt(elCSS.width) - parseInt(elCSS.paddingLeft) - parseInt(elCSS.paddingRight) - parseInt(elCSS.borderLeftWidth) - parseInt(elCSS.borderRightWidth),
1074        child1 = getChild(el, 0, options),
1075        child2 = getChild(el, 1, options),
1076        firstChildCSS = child1 && css(child1),
1077        secondChildCSS = child2 && css(child2),
1078        firstChildWidth = firstChildCSS && parseInt(firstChildCSS.marginLeft) + parseInt(firstChildCSS.marginRight) + getRect(child1).width,
1079        secondChildWidth = secondChildCSS && parseInt(secondChildCSS.marginLeft) + parseInt(secondChildCSS.marginRight) + getRect(child2).width;
1080
1081    if (elCSS.display === 'flex') {
1082      return elCSS.flexDirection === 'column' || elCSS.flexDirection === 'column-reverse' ? 'vertical' : 'horizontal';
1083    }
1084
1085    if (elCSS.display === 'grid') {
1086      return elCSS.gridTemplateColumns.split(' ').length <= 1 ? 'vertical' : 'horizontal';
1087    }
1088
1089    if (child1 && firstChildCSS["float"] && firstChildCSS["float"] !== 'none') {
1090      var touchingSideChild2 = firstChildCSS["float"] === 'left' ? 'left' : 'right';
1091      return child2 && (secondChildCSS.clear === 'both' || secondChildCSS.clear === touchingSideChild2) ? 'vertical' : 'horizontal';
1092    }
1093
1094    return child1 && (firstChildCSS.display === 'block' || firstChildCSS.display === 'flex' || firstChildCSS.display === 'table' || firstChildCSS.display === 'grid' || firstChildWidth >= elWidth && elCSS[CSSFloatProperty] === 'none' || child2 && elCSS[CSSFloatProperty] === 'none' && firstChildWidth + secondChildWidth > elWidth) ? 'vertical' : 'horizontal';
1095  },
1096      _dragElInRowColumn = function _dragElInRowColumn(dragRect, targetRect, vertical) {
1097    var dragElS1Opp = vertical ? dragRect.left : dragRect.top,
1098        dragElS2Opp = vertical ? dragRect.right : dragRect.bottom,
1099        dragElOppLength = vertical ? dragRect.width : dragRect.height,
1100        targetS1Opp = vertical ? targetRect.left : targetRect.top,
1101        targetS2Opp = vertical ? targetRect.right : targetRect.bottom,
1102        targetOppLength = vertical ? targetRect.width : targetRect.height;
1103    return dragElS1Opp === targetS1Opp || dragElS2Opp === targetS2Opp || dragElS1Opp + dragElOppLength / 2 === targetS1Opp + targetOppLength / 2;
1104  },
1105
1106  /**
1107   * Detects first nearest empty sortable to X and Y position using emptyInsertThreshold.
1108   * @param  {Number} x      X position
1109   * @param  {Number} y      Y position
1110   * @return {HTMLElement}   Element of the first found nearest Sortable
1111   */
1112  _detectNearestEmptySortable = function _detectNearestEmptySortable(x, y) {
1113    var ret;
1114    sortables.some(function (sortable) {
1115      var threshold = sortable[expando].options.emptyInsertThreshold;
1116      if (!threshold || lastChild(sortable)) return;
1117      var rect = getRect(sortable),
1118          insideHorizontally = x >= rect.left - threshold && x <= rect.right + threshold,
1119          insideVertically = y >
vendor: 26,123 bytes, lines 1119-1899
1119= rect.top - threshold && y <= rect.bottom + threshold;
1120
1121      if (insideHorizontally && insideVertically) {
1122        return ret = sortable;
1123      }
1124    });
1125    return ret;
1126  },
1127      _prepareGroup = function _prepareGroup(options) {
1128    function toFn(value, pull) {
1129      return function (to, from, dragEl, evt) {
1130        var sameGroup = to.options.group.name && from.options.group.name && to.options.group.name === from.options.group.name;
1131
1132        if (value == null && (pull || sameGroup)) {
1133          // Default pull value
1134          // Default pull and put value if same group
1135          return true;
1136        } else if (value == null || value === false) {
1137          return false;
1138        } else if (pull && value === 'clone') {
1139          return value;
1140        } else if (typeof value === 'function') {
1141          return toFn(value(to, from, dragEl, evt), pull)(to, from, dragEl, evt);
1142        } else {
1143          var otherGroup = (pull ? to : from).options.group.name;
1144          return value === true || typeof value === 'string' && value === otherGroup || value.join && value.indexOf(otherGroup) > -1;
1145        }
1146      };
1147    }
1148
1149    var group = {};
1150    var originalGroup = options.group;
1151
1152    if (!originalGroup || _typeof(originalGroup) != 'object') {
1153      originalGroup = {
1154        name: originalGroup
1155      };
1156    }
1157
1158    group.name = originalGroup.name;
1159    group.checkPull = toFn(originalGroup.pull, true);
1160    group.checkPut = toFn(originalGroup.put);
1161    group.revertClone = originalGroup.revertClone;
1162    options.group = group;
1163  },
1164      _hideGhostForTarget = function _hideGhostForTarget() {
1165    if (!supportCssPointerEvents && ghostEl) {
1166      css(ghostEl, 'display', 'none');
1167    }
1168  },
1169      _unhideGhostForTarget = function _unhideGhostForTarget() {
1170    if (!supportCssPointerEvents && ghostEl) {
1171      css(ghostEl, 'display', '');
1172    }
1173  }; // #1184 fix - Prevent click event on fallback if dragged but item not changed position
1174
1175
1176  if (documentExists) {
1177    document.addEventListener('click', function (evt) {
1178      if (ignoreNextClick) {
1179        evt.preventDefault();
1180        evt.stopPropagation && evt.stopPropagation();
1181        evt.stopImmediatePropagation && evt.stopImmediatePropagation();
1182        ignoreNextClick = false;
1183        return false;
1184      }
1185    }, true);
1186  }
1187
1188  var nearestEmptyInsertDetectEvent = function nearestEmptyInsertDetectEvent(evt) {
1189    if (dragEl) {
1190      evt = evt.touches ? evt.touches[0] : evt;
1191
1192      var nearest = _detectNearestEmptySortable(evt.clientX, evt.clientY);
1193
1194      if (nearest) {
1195        // Create imitation event
1196        var event = {};
1197
1198        for (var i in evt) {
1199          if (evt.hasOwnProperty(i)) {
1200            event[i] = evt[i];
1201          }
1202        }
1203
1204        event.target = event.rootEl = nearest;
1205        event.preventDefault = void 0;
1206        event.stopPropagation = void 0;
1207
1208        nearest[expando]._onDragOver(event);
1209      }
1210    }
1211  };
1212
1213  var _checkOutsideTargetEl = function _checkOutsideTargetEl(evt) {
1214    if (dragEl) {
1215      dragEl.parentNode[expando]._isOutsideThisEl(evt.target);
1216    }
1217  };
1218  /**
1219   * @class  Sortable
1220   * @param  {HTMLElement}  el
1221   * @param  {Object}       [options]
1222   */
1223
1224
1225  function Sortable(el, options) {
1226    if (!(el && el.nodeType && el.nodeType === 1)) {
1227      throw "Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(el));
1228    }
1229
1230    this.el = el; // root element
1231
1232    this.options = options = _extends({}, options); // Export instance
1233
1234    el[expando] = this;
1235    var defaults = {
1236      group: null,
1237      sort: true,
1238      disabled: false,
1239      store: null,
1240      handle: null,
1241      draggable: /^[uo]l$/i.test(el.nodeName) ? '>li' : '>*',
1242      swapThreshold: 1,
1243      // percentage; 0 <= x <= 1
1244      invertSwap: false,
1245      // invert always
1246      invertedSwapThreshold: null,
1247      // will be set to same as swapThreshold if default
1248      removeCloneOnHide: true,
1249      direction: function direction() {
1250        return _detectDirection(el, this.options);
1251      },
1252      ghostClass: 'sortable-ghost',
1253      chosenClass: 'sortable-chosen',
1254      dragClass: 'sortable-drag',
1255      ignore: 'a, img',
1256      filter: null,
1257      preventOnFilter: true,
1258      animation: 0,
1259      easing: null,
1260      setData: function setData(dataTransfer, dragEl) {
1261        dataTransfer.setData('Text', dragEl.textContent);
1262      },
1263      dropBubble: false,
1264      dragoverBubble: false,
1265      dataIdAttr: 'data-id',
1266      delay: 0,
1267      delayOnTouchOnly: false,
1268      touchStartThreshold: (Number.parseInt ? Number : window).parseInt(window.devicePixelRatio, 10) || 1,
1269      forceFallback: false,
1270      fallbackClass: 'sortable-fallback',
1271      fallbackOnBody: false,
1272      fallbackTolerance: 0,
1273      fallbackOffset: {
1274        x: 0,
1275        y: 0
1276      },
1277      supportPointer: Sortable.supportPointer !== false && 'PointerEvent' in window && !Safari,
1278      emptyInsertThreshold: 5
1279    };
1280    PluginManager.initializePlugins(this, el, defaults); // Set default options
1281
1282    for (var name in defaults) {
1283      !(name in options) && (options[name] = defaults[name]);
1284    }
1285
1286    _prepareGroup(options); // Bind all private methods
1287
1288
1289    for (var fn in this) {
1290      if (fn.charAt(0) === '_' && typeof this[fn] === 'function') {
1291        this[fn] = this[fn].bind(this);
1292      }
1293    } // Setup drag mode
1294
1295
1296    this.nativeDraggable = options.forceFallback ? false : supportDraggable;
1297
1298    if (this.nativeDraggable) {
1299      // Touch start threshold cannot be greater than the native dragstart threshold
1300      this.options.touchStartThreshold = 1;
1301    } // Bind events
1302
1303
1304    if (options.supportPointer) {
1305      on(el, 'pointerdown', this._onTapStart);
1306    } else {
1307      on(el, 'mousedown', this._onTapStart);
1308      on(el, 'touchstart', this._onTapStart);
1309    }
1310
1311    if (this.nativeDraggable) {
1312      on(el, 'dragover', this);
1313      on(el, 'dragenter', this);
1314    }
1315
1316    sortables.push(this.el); // Restore sorting
1317
1318    options.store && options.store.get && this.sort(options.store.get(this) || []); // Add animation state manager
1319
1320    _extends(this, AnimationStateManager());
1321  }
1322
1323  Sortable.prototype =
1324  /** @lends Sortable.prototype */
1325  {
1326    constructor: Sortable,
1327    _isOutsideThisEl: function _isOutsideThisEl(target) {
1328      if (!this.el.contains(target) && target !== this.el) {
1329        lastTarget = null;
1330      }
1331    },
1332    _getDirection: function _getDirection(evt, target) {
1333      return typeof this.options.direction === 'function' ? this.options.direction.call(this, evt, target, dragEl) : this.options.direction;
1334    },
1335    _onTapStart: function _onTapStart(
1336    /** Event|TouchEvent */
1337    evt) {
1338      if (!evt.cancelable) return;
1339
1340      var _this = this,
1341          el = this.el,
1342          options = this.options,
1343          preventOnFilter = options.preventOnFilter,
1344          type = evt.type,
1345          touch = evt.touches && evt.touches[0] || evt.pointerType && evt.pointerType === 'touch' && evt,
1346          target = (touch || evt).target,
1347          originalTarget = evt.target.shadowRoot && (evt.path && evt.path[0] || evt.composedPath && evt.composedPath()[0]) || target,
1348          filter = options.filter;
1349
1350      _saveInputCheckedState(el); // Don't trigger start event when an element is been dragged, otherwise the evt.oldindex always wrong when set option.group.
1351
1352
1353      if (dragEl) {
1354        return;
1355      }
1356
1357      if (/mousedown|pointerdown/.test(type) && evt.button !== 0 || options.disabled) {
1358        return; // only left button and enabled
1359      } // cancel dnd if original target is content editable
1360
1361
1362      if (originalTarget.isContentEditable) {
1363        return;
1364      } // Safari ignores further event handling after mousedown
1365
1366
1367      if (!this.nativeDraggable && Safari && target && target.tagName.toUpperCase() === 'SELECT') {
1368        return;
1369      }
1370
1371      target = closest(target, options.draggable, el, false);
1372
1373      if (target && target.animated) {
1374        return;
1375      }
1376
1377      if (lastDownEl === target) {
1378        // Ignoring duplicate `down`
1379        return;
1380      } // Get the index of the dragged element within its parent
1381
1382
1383      oldIndex = index(target);
1384      oldDraggableIndex = index(target, options.draggable); // Check filter
1385
1386      if (typeof filter === 'function') {
1387        if (filter.call(this, evt, target, this)) {
1388          _dispatchEvent({
1389            sortable: _this,
1390            rootEl: originalTarget,
1391            name: 'filter',
1392            targetEl: target,
1393            toEl: el,
1394            fromEl: el
1395          });
1396
1397          pluginEvent('filter', _this, {
1398            evt: evt
1399          });
1400          preventOnFilter && evt.cancelable && evt.preventDefault();
1401          return; // cancel dnd
1402        }
1403      } else if (filter) {
1404        filter = filter.split(',').some(function (criteria) {
1405          criteria = closest(originalTarget, criteria.trim(), el, false);
1406
1407          if (criteria) {
1408            _dispatchEvent({
1409              sortable: _this,
1410              rootEl: criteria,
1411              name: 'filter',
1412              targetEl: target,
1413              fromEl: el,
1414              toEl: el
1415            });
1416
1417            pluginEvent('filter', _this, {
1418              evt: evt
1419            });
1420            return true;
1421          }
1422        });
1423
1424        if (filter) {
1425          preventOnFilter && evt.cancelable && evt.preventDefault();
1426          return; // cancel dnd
1427        }
1428      }
1429
1430      if (options.handle && !closest(originalTarget, options.handle, el, false)) {
1431        return;
1432      } // Prepare `dragstart`
1433
1434
1435      this._prepareDragStart(evt, touch, target);
1436    },
1437    _prepareDragStart: function _prepareDragStart(
1438    /** Event */
1439    evt,
1440    /** Touch */
1441    touch,
1442    /** HTMLElement */
1443    target) {
1444      var _this = this,
1445          el = _this.el,
1446          options = _this.options,
1447          ownerDocument = el.ownerDocument,
1448          dragStartFn;
1449
1450      if (target && !dragEl && target.parentNode === el) {
1451        var dragRect = getRect(target);
1452        rootEl = el;
1453        dragEl = target;
1454        parentEl = dragEl.parentNode;
1455        nextEl = dragEl.nextSibling;
1456        lastDownEl = target;
1457        activeGroup = options.group;
1458        Sortable.dragged = dragEl;
1459        tapEvt = {
1460          target: dragEl,
1461          clientX: (touch || evt).clientX,
1462          clientY: (touch || evt).clientY
1463        };
1464        tapDistanceLeft = tapEvt.clientX - dragRect.left;
1465        tapDistanceTop = tapEvt.clientY - dragRect.top;
1466        this._lastX = (touch || evt).clientX;
1467        this._lastY = (touch || evt).clientY;
1468        dragEl.style['will-change'] = 'all';
1469
1470        dragStartFn = function dragStartFn() {
1471          pluginEvent('delayEnded', _this, {
1472            evt: evt
1473          });
1474
1475          if (Sortable.eventCanceled) {
1476            _this._onDrop();
1477
1478            return;
1479          } // Delayed drag has been triggered
1480          // we can re-enable the events: touchmove/mousemove
1481
1482
1483          _this._disableDelayedDragEvents();
1484
1485          if (!FireFox && _this.nativeDraggable) {
1486            dragEl.draggable = true;
1487          } // Bind the events: dragstart/dragend
1488
1489
1490          _this._triggerDragStart(evt, touch); // Drag start event
1491
1492
1493          _dispatchEvent({
1494            sortable: _this,
1495            name: 'choose',
1496            originalEvent: evt
1497          }); // Chosen item
1498
1499
1500          toggleClass(dragEl, options.chosenClass, true);
1501        }; // Disable "draggable"
1502
1503
1504        options.ignore.split(',').forEach(function (criteria) {
1505          find(dragEl, criteria.trim(), _disableDraggable);
1506        });
1507        on(ownerDocument, 'dragover', nearestEmptyInsertDetectEvent);
1508        on(ownerDocument, 'mousemove', nearestEmptyInsertDetectEvent);
1509        on(ownerDocument, 'touchmove', nearestEmptyInsertDetectEvent);
1510        on(ownerDocument, 'mouseup', _this._onDrop);
1511        on(ownerDocument, 'touchend', _this._onDrop);
1512        on(ownerDocument, 'touchcancel', _this._onDrop); // Make dragEl draggable (must be before delay for FireFox)
1513
1514        if (FireFox && this.nativeDraggable) {
1515          this.options.touchStartThreshold = 4;
1516          dragEl.draggable = true;
1517        }
1518
1519        pluginEvent('delayStart', this, {
1520          evt: evt
1521        }); // Delay is impossible for native DnD in Edge or IE
1522
1523        if (options.delay && (!options.delayOnTouchOnly || touch) && (!this.nativeDraggable || !(Edge || IE11OrLess))) {
1524          if (Sortable.eventCanceled) {
1525            this._onDrop();
1526
1527            return;
1528          } // If the user moves the pointer or let go the click or touch
1529          // before the delay has been reached:
1530          // disable the delayed drag
1531
1532
1533          on(ownerDocument, 'mouseup', _this._disableDelayedDrag);
1534          on(ownerDocument, 'touchend', _this._disableDelayedDrag);
1535          on(ownerDocument, 'touchcancel', _this._disableDelayedDrag);
1536          on(ownerDocument, 'mousemove', _this._delayedDragTouchMoveHandler);
1537          on(ownerDocument, 'touchmove', _this._delayedDragTouchMoveHandler);
1538          options.supportPointer && on(ownerDocument, 'pointermove', _this._delayedDragTouchMoveHandler);
1539          _this._dragStartTimer = setTimeout(dragStartFn, options.delay);
1540        } else {
1541          dragStartFn();
1542        }
1543      }
1544    },
1545    _delayedDragTouchMoveHandler: function _delayedDragTouchMoveHandler(
1546    /** TouchEvent|PointerEvent **/
1547    e) {
1548      var touch = e.touches ? e.touches[0] : e;
1549
1550      if (Math.max(Math.abs(touch.clientX - this._lastX), Math.abs(touch.clientY - this._lastY)) >= Math.floor(this.options.touchStartThreshold / (this.nativeDraggable && window.devicePixelRatio || 1))) {
1551        this._disableDelayedDrag();
1552      }
1553    },
1554    _disableDelayedDrag: function _disableDelayedDrag() {
1555      dragEl && _disableDraggable(dragEl);
1556      clearTimeout(this._dragStartTimer);
1557
1558      this._disableDelayedDragEvents();
1559    },
1560    _disableDelayedDragEvents: function _disableDelayedDragEvents() {
1561      var ownerDocument = this.el.ownerDocument;
1562      off(ownerDocument, 'mouseup', this._disableDelayedDrag);
1563      off(ownerDocument, 'touchend', this._disableDelayedDrag);
1564      off(ownerDocument, 'touchcancel', this._disableDelayedDrag);
1565      off(ownerDocument, 'mousemove', this._delayedDragTouchMoveHandler);
1566      off(ownerDocument, 'touchmove', this._delayedDragTouchMoveHandler);
1567      off(ownerDocument, 'pointermove', this._delayedDragTouchMoveHandler);
1568    },
1569    _triggerDragStart: function _triggerDragStart(
1570    /** Event */
1571    evt,
1572    /** Touch */
1573    touch) {
1574      touch = touch || evt.pointerType == 'touch' && evt;
1575
1576      if (!this.nativeDraggable || touch) {
1577        if (this.options.supportPointer) {
1578          on(document, 'pointermove', this._onTouchMove);
1579        } else if (touch) {
1580          on(document, 'touchmove', this._onTouchMove);
1581        } else {
1582          on(document, 'mousemove', this._onTouchMove);
1583        }
1584      } else {
1585        on(dragEl, 'dragend', this);
1586        on(rootEl, 'dragstart', this._onDragStart);
1587      }
1588
1589      try {
1590        if (document.selection) {
1591          // Timeout neccessary for IE9
1592          _nextTick(function () {
1593            document.selection.empty();
1594          });
1595        } else {
1596          window.getSelection().removeAllRanges();
1597        }
1598      } catch (err) {}
1599    },
1600    _dragStarted: function _dragStarted(fallback, evt) {
1601
1602      awaitingDragStarted = false;
1603
1604      if (rootEl && dragEl) {
1605        pluginEvent('dragStarted', this, {
1606          evt: evt
1607        });
1608
1609        if (this.nativeDraggable) {
1610          on(document, 'dragover', _checkOutsideTargetEl);
1611        }
1612
1613        var options = this.options; // Apply effect
1614
1615        !fallback && toggleClass(dragEl, options.dragClass, false);
1616        toggleClass(dragEl, options.ghostClass, true);
1617        Sortable.active = this;
1618        fallback && this._appendGhost(); // Drag start event
1619
1620        _dispatchEvent({
1621          sortable: this,
1622          name: 'start',
1623          originalEvent: evt
1624        });
1625      } else {
1626        this._nulling();
1627      }
1628    },
1629    _emulateDragOver: function _emulateDragOver() {
1630      if (touchEvt) {
1631        this._lastX = touchEvt.clientX;
1632        this._lastY = touchEvt.clientY;
1633
1634        _hideGhostForTarget();
1635
1636        var target = document.elementFromPoint(touchEvt.clientX, touchEvt.clientY);
1637        var parent = target;
1638
1639        while (target && target.shadowRoot) {
1640          target = target.shadowRoot.elementFromPoint(touchEvt.clientX, touchEvt.clientY);
1641          if (target === parent) break;
1642          parent = target;
1643        }
1644
1645        dragEl.parentNode[expando]._isOutsideThisEl(target);
1646
1647        if (parent) {
1648          do {
1649            if (parent[expando]) {
1650              var inserted = void 0;
1651              inserted = parent[expando]._onDragOver({
1652                clientX: touchEvt.clientX,
1653                clientY: touchEvt.clientY,
1654                target: target,
1655                rootEl: parent
1656              });
1657
1658              if (inserted && !this.options.dragoverBubble) {
1659                break;
1660              }
1661            }
1662
1663            target = parent; // store last element
1664          }
1665          /* jshint boss:true */
1666          while (parent = parent.parentNode);
1667        }
1668
1669        _unhideGhostForTarget();
1670      }
1671    },
1672    _onTouchMove: function _onTouchMove(
1673    /**TouchEvent*/
1674    evt) {
1675      if (tapEvt) {
1676        var options = this.options,
1677            fallbackTolerance = options.fallbackTolerance,
1678            fallbackOffset = options.fallbackOffset,
1679            touch = evt.touches ? evt.touches[0] : evt,
1680            ghostMatrix = ghostEl && matrix(ghostEl, true),
1681            scaleX = ghostEl && ghostMatrix && ghostMatrix.a,
1682            scaleY = ghostEl && ghostMatrix && ghostMatrix.d,
1683            relativeScrollOffset = PositionGhostAbsolutely && ghostRelativeParent && getRelativeScrollOffset(ghostRelativeParent),
1684            dx = (touch.clientX - tapEvt.clientX + fallbackOffset.x) / (scaleX || 1) + (relativeScrollOffset ? relativeScrollOffset[0] - ghostRelativeParentInitialScroll[0] : 0) / (scaleX || 1),
1685            dy = (touch.clientY - tapEvt.clientY + fallbackOffset.y) / (scaleY || 1) + (relativeScrollOffset ? relativeScrollOffset[1] - ghostRelativeParentInitialScroll[1] : 0) / (scaleY || 1); // only set the status to dragging, when we are actually dragging
1686
1687        if (!Sortable.active && !awaitingDragStarted) {
1688          if (fallbackTolerance && Math.max(Math.abs(touch.clientX - this._lastX), Math.abs(touch.clientY - this._lastY)) < fallbackTolerance) {
1689            return;
1690          }
1691
1692          this._onDragStart(evt, true);
1693        }
1694
1695        if (ghostEl) {
1696          if (ghostMatrix) {
1697            ghostMatrix.e += dx - (lastDx || 0);
1698            ghostMatrix.f += dy - (lastDy || 0);
1699          } else {
1700            ghostMatrix = {
1701              a: 1,
1702              b: 0,
1703              c: 0,
1704              d: 1,
1705              e: dx,
1706              f: dy
1707            };
1708          }
1709
1710          var cssMatrix = "matrix(".concat(ghostMatrix.a, ",").concat(ghostMatrix.b, ",").concat(ghostMatrix.c, ",").concat(ghostMatrix.d, ",").concat(ghostMatrix.e, ",").concat(ghostMatrix.f, ")");
1711          css(ghostEl, 'webkitTransform', cssMatrix);
1712          css(ghostEl, 'mozTransform', cssMatrix);
1713          css(ghostEl, 'msTransform', cssMatrix);
1714          css(ghostEl, 'transform', cssMatrix);
1715          lastDx = dx;
1716          lastDy = dy;
1717          touchEvt = touch;
1718        }
1719
1720        evt.cancelable && evt.preventDefault();
1721      }
1722    },
1723    _appendGhost: function _appendGhost() {
1724      // Bug if using scale(): https://stackoverflow.com/questions/2637058
1725      // Not being adjusted for
1726      if (!ghostEl) {
1727        var container = this.options.fallbackOnBody ? document.body : rootEl,
1728            rect = getRect(dragEl, true, PositionGhostAbsolutely, true, container),
1729            options = this.options; // Position absolutely
1730
1731        if (PositionGhostAbsolutely) {
1732          // Get relatively positioned parent
1733          ghostRelativeParent = container;
1734
1735          while (css(ghostRelativeParent, 'position') === 'static' && css(ghostRelativeParent, 'transform') === 'none' && ghostRelativeParent !== document) {
1736            ghostRelativeParent = ghostRelativeParent.parentNode;
1737          }
1738
1739          if (ghostRelativeParent !== document.body && ghostRelativeParent !== document.documentElement) {
1740            if (ghostRelativeParent === document) ghostRelativeParent = getWindowScrollingElement();
1741            rect.top += ghostRelativeParent.scrollTop;
1742            rect.left += ghostRelativeParent.scrollLeft;
1743          } else {
1744            ghostRelativeParent = getWindowScrollingElement();
1745          }
1746
1747          ghostRelativeParentInitialScroll = getRelativeScrollOffset(ghostRelativeParent);
1748        }
1749
1750        ghostEl = dragEl.cloneNode(true);
1751        toggleClass(ghostEl, options.ghostClass, false);
1752        toggleClass(ghostEl, options.fallbackClass, true);
1753        toggleClass(ghostEl, options.dragClass, true);
1754        css(ghostEl, 'transition', '');
1755        css(ghostEl, 'transform', '');
1756        css(ghostEl, 'box-sizing', 'border-box');
1757        css(ghostEl, 'margin', 0);
1758        css(ghostEl, 'top', rect.top);
1759        css(ghostEl, 'left', rect.left);
1760        css(ghostEl, 'width', rect.width);
1761        css(ghostEl, 'height', rect.height);
1762        css(ghostEl, 'opacity', '0.8');
1763        css(ghostEl, 'position', PositionGhostAbsolutely ? 'absolute' : 'fixed');
1764        css(ghostEl, 'zIndex', '100000');
1765        css(ghostEl, 'pointerEvents', 'none');
1766        Sortable.ghost = ghostEl;
1767        container.appendChild(ghostEl); // Set transform-origin
1768
1769        css(ghostEl, 'transform-origin', tapDistanceLeft / parseInt(ghostEl.style.width) * 100 + '% ' + tapDistanceTop / parseInt(ghostEl.style.height) * 100 + '%');
1770      }
1771    },
1772    _onDragStart: function _onDragStart(
1773    /**Event*/
1774    evt,
1775    /**boolean*/
1776    fallback) {
1777      var _this = this;
1778
1779      var dataTransfer = evt.dataTransfer;
1780      var options = _this.options;
1781      pluginEvent('dragStart', this, {
1782        evt: evt
1783      });
1784
1785      if (Sortable.eventCanceled) {
1786        this._onDrop();
1787
1788        return;
1789      }
1790
1791      pluginEvent('setupClone', this);
1792
1793      if (!Sortable.eventCanceled) {
1794        cloneEl = clone(dragEl);
1795        cloneEl.draggable = false;
1796        cloneEl.style['will-change'] = '';
1797
1798        this._hideClone();
1799
1800        toggleClass(cloneEl, this.options.chosenClass, false);
1801        Sortable.clone = cloneEl;
1802      } // #1143: IFrame support workaround
1803
1804
1805      _this.cloneId = _nextTick(function () {
1806        pluginEvent('clone', _this);
1807        if (Sortable.eventCanceled) return;
1808
1809        if (!_this.options.removeCloneOnHide) {
1810          rootEl.insertBefore(cloneEl, dragEl);
1811        }
1812
1813        _this._hideClone();
1814
1815        _dispatchEvent({
1816          sortable: _this,
1817          name: 'clone'
1818        });
1819      });
1820      !fallback && toggleClass(dragEl, options.dragClass, true); // Set proper drop events
1821
1822      if (fallback) {
1823        ignoreNextClick = true;
1824        _this._loopId = setInterval(_this._emulateDragOver, 50);
1825      } else {
1826        // Undo what was set in _prepareDragStart before drag started
1827        off(document, 'mouseup', _this._onDrop);
1828        off(document, 'touchend', _this._onDrop);
1829        off(document, 'touchcancel', _this._onDrop);
1830
1831        if (dataTransfer) {
1832          dataTransfer.effectAllowed = 'move';
1833          options.setData && options.setData.call(_this, dataTransfer, dragEl);
1834        }
1835
1836        on(document, 'drop', _this); // #1276 fix:
1837
1838        css(dragEl, 'transform', 'translateZ(0)');
1839      }
1840
1841      awaitingDragStarted = true;
1842      _this._dragStartId = _nextTick(_this._dragStarted.bind(_this, fallback, evt));
1843      on(document, 'selectstart', _this);
1844      moved = true;
1845
1846      if (Safari) {
1847        css(document.body, 'user-select', 'none');
1848      }
1849    },
1850    // Returns true - if no further action is needed (either inserted or another condition)
1851    _onDragOver: function _onDragOver(
1852    /**Event*/
1853    evt) {
1854      var el = this.el,
1855          target = evt.target,
1856          dragRect,
1857          targetRect,
1858          revert,
1859          options = this.options,
1860          group = options.group,
1861          activeSortable = Sortable.active,
1862          isOwner = activeGroup === group,
1863          canSort = options.sort,
1864          fromSortable = putSortable || activeSortable,
1865          vertical,
1866          _this = this,
1867          completedFired = false;
1868
1869      if (_silent) return;
1870
1871      function dragOverEvent(name, extra) {
1872        pluginEvent(name, _this, _objectSpread2({
1873          evt: evt,
1874          isOwner: isOwner,
1875          axis: vertical ? 'vertical' : 'horizontal',
1876          revert: revert,
1877          dragRect: dragRect,
1878          targetRect: targetRect,
1879          canSort: canSort,
1880          fromSortable: fromSortable,
1881          target: target,
1882          completed: completed,
1883          onMove: function onMove(target, after) {
1884            return _onMove(rootEl, el, dragEl, dragRect, target, getRect(target), evt, after);
1885          },
1886          changed: changed
1887        }, extra));
1888      } // Capture animation state
1889
1890
1891      function capture() {
1892        dragOverEvent('dragOverAnimationCapture');
1893
1894        _this.captureAnimationState();
1895
1896        if (_this !== fromSortable) {
1897          fromSortable.captureAnimationState();
1898        }
1899      }
vendor: 7,889 bytes, lines 1899-2116
1899 // Return invocation when dragEl is inserted (or completed)
1900
1901
1902      function completed(insertion) {
1903        dragOverEvent('dragOverCompleted', {
1904          insertion: insertion
1905        });
1906
1907        if (insertion) {
1908          // Clones must be hidden before folding animation to capture dragRectAbsolute properly
1909          if (isOwner) {
1910            activeSortable._hideClone();
1911          } else {
1912            activeSortable._showClone(_this);
1913          }
1914
1915          if (_this !== fromSortable) {
1916            // Set ghost class to new sortable's ghost class
1917            toggleClass(dragEl, putSortable ? putSortable.options.ghostClass : activeSortable.options.ghostClass, false);
1918            toggleClass(dragEl, options.ghostClass, true);
1919          }
1920
1921          if (putSortable !== _this && _this !== Sortable.active) {
1922            putSortable = _this;
1923          } else if (_this === Sortable.active && putSortable) {
1924            putSortable = null;
1925          } // Animation
1926
1927
1928          if (fromSortable === _this) {
1929            _this._ignoreWhileAnimating = target;
1930          }
1931
1932          _this.animateAll(function () {
1933            dragOverEvent('dragOverAnimationComplete');
1934            _this._ignoreWhileAnimating = null;
1935          });
1936
1937          if (_this !== fromSortable) {
1938            fromSortable.animateAll();
1939            fromSortable._ignoreWhileAnimating = null;
1940          }
1941        } // Null lastTarget if it is not inside a previously swapped element
1942
1943
1944        if (target === dragEl && !dragEl.animated || target === el && !target.animated) {
1945          lastTarget = null;
1946        } // no bubbling and not fallback
1947
1948
1949        if (!options.dragoverBubble && !evt.rootEl && target !== document) {
1950          dragEl.parentNode[expando]._isOutsideThisEl(evt.target); // Do not detect for empty insert if already inserted
1951
1952
1953          !insertion && nearestEmptyInsertDetectEvent(evt);
1954        }
1955
1956        !options.dragoverBubble && evt.stopPropagation && evt.stopPropagation();
1957        return completedFired = true;
1958      } // Call when dragEl has been inserted
1959
1960
1961      function changed() {
1962        newIndex = index(dragEl);
1963        newDraggableIndex = index(dragEl, options.draggable);
1964
1965        _dispatchEvent({
1966          sortable: _this,
1967          name: 'change',
1968          toEl: el,
1969          newIndex: newIndex,
1970          newDraggableIndex: newDraggableIndex,
1971          originalEvent: evt
1972        });
1973      }
1974
1975      if (evt.preventDefault !== void 0) {
1976        evt.cancelable && evt.preventDefault();
1977      }
1978
1979      target = closest(target, options.draggable, el, true);
1980      dragOverEvent('dragOver');
1981      if (Sortable.eventCanceled) return completedFired;
1982
1983      if (dragEl.contains(evt.target) || target.animated && target.animatingX && target.animatingY || _this._ignoreWhileAnimating === target) {
1984        return completed(false);
1985      }
1986
1987      ignoreNextClick = false;
1988
1989      if (activeSortable && !options.disabled && (isOwner ? canSort || (revert = parentEl !== rootEl) // Reverting item into the original list
1990      : putSortable === this || (this.lastPutMode = activeGroup.checkPull(this, activeSortable, dragEl, evt)) && group.checkPut(this, activeSortable, dragEl, evt))) {
1991        vertical = this._getDirection(evt, target) === 'vertical';
1992        dragRect = getRect(dragEl);
1993        dragOverEvent('dragOverValid');
1994        if (Sortable.eventCanceled) return completedFired;
1995
1996        if (revert) {
1997          parentEl = rootEl; // actualization
1998
1999          capture();
2000
2001          this._hideClone();
2002
2003          dragOverEvent('revert');
2004
2005          if (!Sortable.eventCanceled) {
2006            if (nextEl) {
2007              rootEl.insertBefore(dragEl, nextEl);
2008            } else {
2009              rootEl.appendChild(dragEl);
2010            }
2011          }
2012
2013          return completed(true);
2014        }
2015
2016        var elLastChild = lastChild(el, options.draggable);
2017
2018        if (!elLastChild || _ghostIsLast(evt, vertical, this) && !elLastChild.animated) {
2019          // Insert to end of list
2020          // If already at end of list: Do not insert
2021          if (elLastChild === dragEl) {
2022            return completed(false);
2023          } // if there is a last element, it is the target
2024
2025
2026          if (elLastChild && el === evt.target) {
2027            target = elLastChild;
2028          }
2029
2030          if (target) {
2031            targetRect = getRect(target);
2032          }
2033
2034          if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, !!target) !== false) {
2035            capture();
2036            el.appendChild(dragEl);
2037            parentEl = el; // actualization
2038
2039            changed();
2040            return completed(true);
2041          }
2042        } else if (elLastChild && _ghostIsFirst(evt, vertical, this)) {
2043          // Insert to start of list
2044          var firstChild = getChild(el, 0, options, true);
2045
2046          if (firstChild === dragEl) {
2047            return completed(false);
2048          }
2049
2050          target = firstChild;
2051          targetRect = getRect(target);
2052
2053          if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, false) !== false) {
2054            capture();
2055            el.insertBefore(dragEl, firstChild);
2056            parentEl = el; // actualization
2057
2058            changed();
2059            return completed(true);
2060          }
2061        } else if (target.parentNode === el) {
2062          targetRect = getRect(target);
2063          var direction = 0,
2064              targetBeforeFirstSwap,
2065              differentLevel = dragEl.parentNode !== el,
2066              differentRowCol = !_dragElInRowColumn(dragEl.animated && dragEl.toRect || dragRect, target.animated && target.toRect || targetRect, vertical),
2067              side1 = vertical ? 'top' : 'left',
2068              scrolledPastTop = isScrolledPast(target, 'top', 'top') || isScrolledPast(dragEl, 'top', 'top'),
2069              scrollBefore = scrolledPastTop ? scrolledPastTop.scrollTop : void 0;
2070
2071          if (lastTarget !== target) {
2072            targetBeforeFirstSwap = targetRect[side1];
2073            pastFirstInvertThresh = false;
2074            isCircumstantialInvert = !differentRowCol && options.invertSwap || differentLevel;
2075          }
2076
2077          direction = _getSwapDirection(evt, target, targetRect, vertical, differentRowCol ? 1 : options.swapThreshold, options.invertedSwapThreshold == null ? options.swapThreshold : options.invertedSwapThreshold, isCircumstantialInvert, lastTarget === target);
2078          var sibling;
2079
2080          if (direction !== 0) {
2081            // Check if target is beside dragEl in respective direction (ignoring hidden elements)
2082            var dragIndex = index(dragEl);
2083
2084            do {
2085              dragIndex -= direction;
2086              sibling = parentEl.children[dragIndex];
2087            } while (sibling && (css(sibling, 'display') === 'none' || sibling === ghostEl));
2088          } // If dragEl is already beside target: Do not insert
2089
2090
2091          if (direction === 0 || sibling === target) {
2092            return completed(false);
2093          }
2094
2095          lastTarget = target;
2096          lastDirection = direction;
2097          var nextSibling = target.nextElementSibling,
2098              after = false;
2099          after = direction === 1;
2100
2101          var moveVector = _onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, after);
2102
2103          if (moveVector !== false) {
2104            if (moveVector === 1 || moveVector === -1) {
2105              after = moveVector === 1;
2106            }
2107
2108            _silent = true;
2109            setTimeout(_unsilent, 30);
2110            capture();
2111
2112            if (after && !nextSibling) {
2113              el.appendChild(dragEl);
2114            } else {
2115              target.parentNode.insertBefore(dragEl, after ? nextSibling : target);
2116            }
vendor: 6,117 bytes, lines 2116-2322
2116 // Undo chrome's scroll adjustment (has no effect on other browsers)
2117
2118
2119            if (scrolledPastTop) {
2120              scrollBy(scrolledPastTop, 0, scrollBefore - scrolledPastTop.scrollTop);
2121            }
2122
2123            parentEl = dragEl.parentNode; // actualization
2124            // must be done before animation
2125
2126            if (targetBeforeFirstSwap !== undefined && !isCircumstantialInvert) {
2127              targetMoveDistance = Math.abs(targetBeforeFirstSwap - getRect(target)[side1]);
2128            }
2129
2130            changed();
2131            return completed(true);
2132          }
2133        }
2134
2135        if (el.contains(dragEl)) {
2136          return completed(false);
2137        }
2138      }
2139
2140      return false;
2141    },
2142    _ignoreWhileAnimating: null,
2143    _offMoveEvents: function _offMoveEvents() {
2144      off(document, 'mousemove', this._onTouchMove);
2145      off(document, 'touchmove', this._onTouchMove);
2146      off(document, 'pointermove', this._onTouchMove);
2147      off(document, 'dragover', nearestEmptyInsertDetectEvent);
2148      off(document, 'mousemove', nearestEmptyInsertDetectEvent);
2149      off(document, 'touchmove', nearestEmptyInsertDetectEvent);
2150    },
2151    _offUpEvents: function _offUpEvents() {
2152      var ownerDocument = this.el.ownerDocument;
2153      off(ownerDocument, 'mouseup', this._onDrop);
2154      off(ownerDocument, 'touchend', this._onDrop);
2155      off(ownerDocument, 'pointerup', this._onDrop);
2156      off(ownerDocument, 'touchcancel', this._onDrop);
2157      off(document, 'selectstart', this);
2158    },
2159    _onDrop: function _onDrop(
2160    /**Event*/
2161    evt) {
2162      var el = this.el,
2163          options = this.options; // Get the index of the dragged element within its parent
2164
2165      newIndex = index(dragEl);
2166      newDraggableIndex = index(dragEl, options.draggable);
2167      pluginEvent('drop', this, {
2168        evt: evt
2169      });
2170      parentEl = dragEl && dragEl.parentNode; // Get again after plugin event
2171
2172      newIndex = index(dragEl);
2173      newDraggableIndex = index(dragEl, options.draggable);
2174
2175      if (Sortable.eventCanceled) {
2176        this._nulling();
2177
2178        return;
2179      }
2180
2181      awaitingDragStarted = false;
2182      isCircumstantialInvert = false;
2183      pastFirstInvertThresh = false;
2184      clearInterval(this._loopId);
2185      clearTimeout(this._dragStartTimer);
2186
2187      _cancelNextTick(this.cloneId);
2188
2189      _cancelNextTick(this._dragStartId); // Unbind events
2190
2191
2192      if (this.nativeDraggable) {
2193        off(document, 'drop', this);
2194        off(el, 'dragstart', this._onDragStart);
2195      }
2196
2197      this._offMoveEvents();
2198
2199      this._offUpEvents();
2200
2201      if (Safari) {
2202        css(document.body, 'user-select', '');
2203      }
2204
2205      css(dragEl, 'transform', '');
2206
2207      if (evt) {
2208        if (moved) {
2209          evt.cancelable && evt.preventDefault();
2210          !options.dropBubble && evt.stopPropagation();
2211        }
2212
2213        ghostEl && ghostEl.parentNode && ghostEl.parentNode.removeChild(ghostEl);
2214
2215        if (rootEl === parentEl || putSortable && putSortable.lastPutMode !== 'clone') {
2216          // Remove clone(s)
2217          cloneEl && cloneEl.parentNode && cloneEl.parentNode.removeChild(cloneEl);
2218        }
2219
2220        if (dragEl) {
2221          if (this.nativeDraggable) {
2222            off(dragEl, 'dragend', this);
2223          }
2224
2225          _disableDraggable(dragEl);
2226
2227          dragEl.style['will-change'] = ''; // Remove classes
2228          // ghostClass is added in dragStarted
2229
2230          if (moved && !awaitingDragStarted) {
2231            toggleClass(dragEl, putSortable ? putSortable.options.ghostClass : this.options.ghostClass, false);
2232          }
2233
2234          toggleClass(dragEl, this.options.chosenClass, false); // Drag stop event
2235
2236          _dispatchEvent({
2237            sortable: this,
2238            name: 'unchoose',
2239            toEl: parentEl,
2240            newIndex: null,
2241            newDraggableIndex: null,
2242            originalEvent: evt
2243          });
2244
2245          if (rootEl !== parentEl) {
2246            if (newIndex >= 0) {
2247              // Add event
2248              _dispatchEvent({
2249                rootEl: parentEl,
2250                name: 'add',
2251                toEl: parentEl,
2252                fromEl: rootEl,
2253                originalEvent: evt
2254              }); // Remove event
2255
2256
2257              _dispatchEvent({
2258                sortable: this,
2259                name: 'remove',
2260                toEl: parentEl,
2261                originalEvent: evt
2262              }); // drag from one list and drop into another
2263
2264
2265              _dispatchEvent({
2266                rootEl: parentEl,
2267                name: 'sort',
2268                toEl: parentEl,
2269                fromEl: rootEl,
2270                originalEvent: evt
2271              });
2272
2273              _dispatchEvent({
2274                sortable: this,
2275                name: 'sort',
2276                toEl: parentEl,
2277                originalEvent: evt
2278              });
2279            }
2280
2281            putSortable && putSortable.save();
2282          } else {
2283            if (newIndex !== oldIndex) {
2284              if (newIndex >= 0) {
2285                // drag & drop within the same list
2286                _dispatchEvent({
2287                  sortable: this,
2288                  name: 'update',
2289                  toEl: parentEl,
2290                  originalEvent: evt
2291                });
2292
2293                _dispatchEvent({
2294                  sortable: this,
2295                  name: 'sort',
2296                  toEl: parentEl,
2297                  originalEvent: evt
2298                });
2299              }
2300            }
2301          }
2302
2303          if (Sortable.active) {
2304            /* jshint eqnull:true */
2305            if (newIndex == null || newIndex === -1) {
2306              newIndex = oldIndex;
2307              newDraggableIndex = oldDraggableIndex;
2308            }
2309
2310            _dispatchEvent({
2311              sortable: this,
2312              name: 'end',
2313              toEl: parentEl,
2314              originalEvent: evt
2315            }); // Save sorting
2316
2317
2318            this.save();
2319          }
2320        }
2321      }
2322
vendor: 5,855 bytes, lines 2323-2532
2323      this._nulling();
2324    },
2325    _nulling: function _nulling() {
2326      pluginEvent('nulling', this);
2327      rootEl = dragEl = parentEl = ghostEl = nextEl = cloneEl = lastDownEl = cloneHidden = tapEvt = touchEvt = moved = newIndex = newDraggableIndex = oldIndex = oldDraggableIndex = lastTarget = lastDirection = putSortable = activeGroup = Sortable.dragged = Sortable.ghost = Sortable.clone = Sortable.active = null;
2328      savedInputChecked.forEach(function (el) {
2329        el.checked = true;
2330      });
2331      savedInputChecked.length = lastDx = lastDy = 0;
2332    },
2333    handleEvent: function handleEvent(
2334    /**Event*/
2335    evt) {
2336      switch (evt.type) {
2337        case 'drop':
2338        case 'dragend':
2339          this._onDrop(evt);
2340
2341          break;
2342
2343        case 'dragenter':
2344        case 'dragover':
2345          if (dragEl) {
2346            this._onDragOver(evt);
2347
2348            _globalDragOver(evt);
2349          }
2350
2351          break;
2352
2353        case 'selectstart':
2354          evt.preventDefault();
2355          break;
2356      }
2357    },
2358
2359    /**
2360     * Serializes the item into an array of string.
2361     * @returns {String[]}
2362     */
2363    toArray: function toArray() {
2364      var order = [],
2365          el,
2366          children = this.el.children,
2367          i = 0,
2368          n = children.length,
2369          options = this.options;
2370
2371      for (; i < n; i++) {
2372        el = children[i];
2373
2374        if (closest(el, options.draggable, this.el, false)) {
2375          order.push(el.getAttribute(options.dataIdAttr) || _generateId(el));
2376        }
2377      }
2378
2379      return order;
2380    },
2381
2382    /**
2383     * Sorts the elements according to the array.
2384     * @param  {String[]}  order  order of the items
2385     */
2386    sort: function sort(order, useAnimation) {
2387      var items = {},
2388          rootEl = this.el;
2389      this.toArray().forEach(function (id, i) {
2390        var el = rootEl.children[i];
2391
2392        if (closest(el, this.options.draggable, rootEl, false)) {
2393          items[id] = el;
2394        }
2395      }, this);
2396      useAnimation && this.captureAnimationState();
2397      order.forEach(function (id) {
2398        if (items[id]) {
2399          rootEl.removeChild(items[id]);
2400          rootEl.appendChild(items[id]);
2401        }
2402      });
2403      useAnimation && this.animateAll();
2404    },
2405
2406    /**
2407     * Save the current sorting
2408     */
2409    save: function save() {
2410      var store = this.options.store;
2411      store && store.set && store.set(this);
2412    },
2413
2414    /**
2415     * For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree.
2416     * @param   {HTMLElement}  el
2417     * @param   {String}       [selector]  default: `options.draggable`
2418     * @returns {HTMLElement|null}
2419     */
2420    closest: function closest$1(el, selector) {
2421      return closest(el, selector || this.options.draggable, this.el, false);
2422    },
2423
2424    /**
2425     * Set/get option
2426     * @param   {string} name
2427     * @param   {*}      [value]
2428     * @returns {*}
2429     */
2430    option: function option(name, value) {
2431      var options = this.options;
2432
2433      if (value === void 0) {
2434        return options[name];
2435      } else {
2436        var modifiedValue = PluginManager.modifyOption(this, name, value);
2437
2438        if (typeof modifiedValue !== 'undefined') {
2439          options[name] = modifiedValue;
2440        } else {
2441          options[name] = value;
2442        }
2443
2444        if (name === 'group') {
2445          _prepareGroup(options);
2446        }
2447      }
2448    },
2449
2450    /**
2451     * Destroy
2452     */
2453    destroy: function destroy() {
2454      pluginEvent('destroy', this);
2455      var el = this.el;
2456      el[expando] = null;
2457      off(el, 'mousedown', this._onTapStart);
2458      off(el, 'touchstart', this._onTapStart);
2459      off(el, 'pointerdown', this._onTapStart);
2460
2461      if (this.nativeDraggable) {
2462        off(el, 'dragover', this);
2463        off(el, 'dragenter', this);
2464      } // Remove draggable attributes
2465
2466
2467      Array.prototype.forEach.call(el.querySelectorAll('[draggable]'), function (el) {
2468        el.removeAttribute('draggable');
2469      });
2470
2471      this._onDrop();
2472
2473      this._disableDelayedDragEvents();
2474
2475      sortables.splice(sortables.indexOf(this.el), 1);
2476      this.el = el = null;
2477    },
2478    _hideClone: function _hideClone() {
2479      if (!cloneHidden) {
2480        pluginEvent('hideClone', this);
2481        if (Sortable.eventCanceled) return;
2482        css(cloneEl, 'display', 'none');
2483
2484        if (this.options.removeCloneOnHide && cloneEl.parentNode) {
2485          cloneEl.parentNode.removeChild(cloneEl);
2486        }
2487
2488        cloneHidden = true;
2489      }
2490    },
2491    _showClone: function _showClone(putSortable) {
2492      if (putSortable.lastPutMode !== 'clone') {
2493        this._hideClone();
2494
2495        return;
2496      }
2497
2498      if (cloneHidden) {
2499        pluginEvent('showClone', this);
2500        if (Sortable.eventCanceled) return; // show clone at dragEl or original position
2501
2502        if (dragEl.parentNode == rootEl && !this.options.group.revertClone) {
2503          rootEl.insertBefore(cloneEl, dragEl);
2504        } else if (nextEl) {
2505          rootEl.insertBefore(cloneEl, nextEl);
2506        } else {
2507          rootEl.appendChild(cloneEl);
2508        }
2509
2510        if (this.options.group.revertClone) {
2511          this.animate(dragEl, cloneEl);
2512        }
2513
2514        css(cloneEl, 'display', '');
2515        cloneHidden = false;
2516      }
2517    }
2518  };
2519
2520  function _globalDragOver(
2521  /**Event*/
2522  evt) {
2523    if (evt.dataTransfer) {
2524      evt.dataTransfer.dropEffect = 'move';
2525    }
2526
2527    evt.cancelable && evt.preventDefault();
2528  }
2529
2530  function _onMove(fromEl, toEl, dragEl, dragRect, targetEl, targetRect, originalEvent, willInsertAfter) {
2531    var evt,
2532        sortable = fromEl[expando],
vendor: 4,862 bytes, lines 2533-2665
2533        onMoveFn = sortable.options.onMove,
2534        retVal; // Support for new CustomEvent feature
2535
2536    if (window.CustomEvent && !IE11OrLess && !Edge) {
2537      evt = new CustomEvent('move', {
2538        bubbles: true,
2539        cancelable: true
2540      });
2541    } else {
2542      evt = document.createEvent('Event');
2543      evt.initEvent('move', true, true);
2544    }
2545
2546    evt.to = toEl;
2547    evt.from = fromEl;
2548    evt.dragged = dragEl;
2549    evt.draggedRect = dragRect;
2550    evt.related = targetEl || toEl;
2551    evt.relatedRect = targetRect || getRect(toEl);
2552    evt.willInsertAfter = willInsertAfter;
2553    evt.originalEvent = originalEvent;
2554    fromEl.dispatchEvent(evt);
2555
2556    if (onMoveFn) {
2557      retVal = onMoveFn.call(sortable, evt, originalEvent);
2558    }
2559
2560    return retVal;
2561  }
2562
2563  function _disableDraggable(el) {
2564    el.draggable = false;
2565  }
2566
2567  function _unsilent() {
2568    _silent = false;
2569  }
2570
2571  function _ghostIsFirst(evt, vertical, sortable) {
2572    var rect = getRect(getChild(sortable.el, 0, sortable.options, true));
2573    var spacer = 10;
2574    return vertical ? evt.clientX < rect.left - spacer || evt.clientY < rect.top && evt.clientX < rect.right : evt.clientY < rect.top - spacer || evt.clientY < rect.bottom && evt.clientX < rect.left;
2575  }
2576
2577  function _ghostIsLast(evt, vertical, sortable) {
2578    var rect = getRect(lastChild(sortable.el, sortable.options.draggable));
2579    var spacer = 10;
2580    return vertical ? evt.clientX > rect.right + spacer || evt.clientX <= rect.right && evt.clientY > rect.bottom && evt.clientX >= rect.left : evt.clientX > rect.right && evt.clientY > rect.top || evt.clientX <= rect.right && evt.clientY > rect.bottom + spacer;
2581  }
2582
2583  function _getSwapDirection(evt, target, targetRect, vertical, swapThreshold, invertedSwapThreshold, invertSwap, isLastTarget) {
2584    var mouseOnAxis = vertical ? evt.clientY : evt.clientX,
2585        targetLength = vertical ? targetRect.height : targetRect.width,
2586        targetS1 = vertical ? targetRect.top : targetRect.left,
2587        targetS2 = vertical ? targetRect.bottom : targetRect.right,
2588        invert = false;
2589
2590    if (!invertSwap) {
2591      // Never invert or create dragEl shadow when target movemenet causes mouse to move past the end of regular swapThreshold
2592      if (isLastTarget && targetMoveDistance < targetLength * swapThreshold) {
2593        // multiplied only by swapThreshold because mouse will already be inside target by (1 - threshold) * targetLength / 2
2594        // check if past first invert threshold on side opposite of lastDirection
2595        if (!pastFirstInvertThresh && (lastDirection === 1 ? mouseOnAxis > targetS1 + targetLength * invertedSwapThreshold / 2 : mouseOnAxis < targetS2 - targetLength * invertedSwapThreshold / 2)) {
2596          // past first invert threshold, do not restrict inverted threshold to dragEl shadow
2597          pastFirstInvertThresh = true;
2598        }
2599
2600        if (!pastFirstInvertThresh) {
2601          // dragEl shadow (target move distance shadow)
2602          if (lastDirection === 1 ? mouseOnAxis < targetS1 + targetMoveDistance // over dragEl shadow
2603          : mouseOnAxis > targetS2 - targetMoveDistance) {
2604            return -lastDirection;
2605          }
2606        } else {
2607          invert = true;
2608        }
2609      } else {
2610        // Regular
2611        if (mouseOnAxis > targetS1 + targetLength * (1 - swapThreshold) / 2 && mouseOnAxis < targetS2 - targetLength * (1 - swapThreshold) / 2) {
2612          return _getInsertDirection(target);
2613        }
2614      }
2615    }
2616
2617    invert = invert || invertSwap;
2618
2619    if (invert) {
2620      // Invert of regular
2621      if (mouseOnAxis < targetS1 + targetLength * invertedSwapThreshold / 2 || mouseOnAxis > targetS2 - targetLength * invertedSwapThreshold / 2) {
2622        return mouseOnAxis > targetS1 + targetLength / 2 ? 1 : -1;
2623      }
2624    }
2625
2626    return 0;
2627  }
2628  /**
2629   * Gets the direction dragEl must be swapped relative to target in order to make it
2630   * seem that dragEl has been "inserted" into that element's position
2631   * @param  {HTMLElement} target       The target whose position dragEl is being inserted at
2632   * @return {Number}                   Direction dragEl must be swapped
2633   */
2634
2635
2636  function _getInsertDirection(target) {
2637    if (index(dragEl) < index(target)) {
2638      return 1;
2639    } else {
2640      return -1;
2641    }
2642  }
2643  /**
2644   * Generate id
2645   * @param   {HTMLElement} el
2646   * @returns {String}
2647   * @private
2648   */
2649
2650
2651  function _generateId(el) {
2652    var str = el.tagName + el.className + el.src + el.href + el.textContent,
2653        i = str.length,
2654        sum = 0;
2655
2656    while (i--) {
2657      sum += str.charCodeAt(i);
2658    }
2659
2660    return sum.toString(36);
2661  }
2662
2663  function _saveInputCheckedState(root) {
2664    savedInputChecked.length = 0;
2665    var inputs = root.getElementsByTagName('input');
vendor: 10,311 bytes, lines 2666-2963
2666    var idx = inputs.length;
2667
2668    while (idx--) {
2669      var el = inputs[idx];
2670      el.checked && savedInputChecked.push(el);
2671    }
2672  }
2673
2674  function _nextTick(fn) {
2675    return setTimeout(fn, 0);
2676  }
2677
2678  function _cancelNextTick(id) {
2679    return clearTimeout(id);
2680  } // Fixed #973:
2681
2682
2683  if (documentExists) {
2684    on(document, 'touchmove', function (evt) {
2685      if ((Sortable.active || awaitingDragStarted) && evt.cancelable) {
2686        evt.preventDefault();
2687      }
2688    });
2689  } // Export utils
2690
2691
2692  Sortable.utils = {
2693    on: on,
2694    off: off,
2695    css: css,
2696    find: find,
2697    is: function is(el, selector) {
2698      return !!closest(el, selector, el, false);
2699    },
2700    extend: extend,
2701    throttle: throttle,
2702    closest: closest,
2703    toggleClass: toggleClass,
2704    clone: clone,
2705    index: index,
2706    nextTick: _nextTick,
2707    cancelNextTick: _cancelNextTick,
2708    detectDirection: _detectDirection,
2709    getChild: getChild
2710  };
2711  /**
2712   * Get the Sortable instance of an element
2713   * @param  {HTMLElement} element The element
2714   * @return {Sortable|undefined}         The instance of Sortable
2715   */
2716
2717  Sortable.get = function (element) {
2718    return element[expando];
2719  };
2720  /**
2721   * Mount a plugin to Sortable
2722   * @param  {...SortablePlugin|SortablePlugin[]} plugins       Plugins being mounted
2723   */
2724
2725
2726  Sortable.mount = function () {
2727    for (var _len = arguments.length, plugins = new Array(_len), _key = 0; _key < _len; _key++) {
2728      plugins[_key] = arguments[_key];
2729    }
2730
2731    if (plugins[0].constructor === Array) plugins = plugins[0];
2732    plugins.forEach(function (plugin) {
2733      if (!plugin.prototype || !plugin.prototype.constructor) {
2734        throw "Sortable: Mounted plugin must be a constructor function, not ".concat({}.toString.call(plugin));
2735      }
2736
2737      if (plugin.utils) Sortable.utils = _objectSpread2(_objectSpread2({}, Sortable.utils), plugin.utils);
2738      PluginManager.mount(plugin);
2739    });
2740  };
2741  /**
2742   * Create sortable instance
2743   * @param {HTMLElement}  el
2744   * @param {Object}      [options]
2745   */
2746
2747
2748  Sortable.create = function (el, options) {
2749    return new Sortable(el, options);
2750  }; // Export
2751
2752
2753  Sortable.version = version;
2754
2755  var autoScrolls = [],
2756      scrollEl,
2757      scrollRootEl,
2758      scrolling = false,
2759      lastAutoScrollX,
2760      lastAutoScrollY,
2761      touchEvt$1,
2762      pointerElemChangedInterval;
2763
2764  function AutoScrollPlugin() {
2765    function AutoScroll() {
2766      this.defaults = {
2767        scroll: true,
2768        forceAutoScrollFallback: false,
2769        scrollSensitivity: 30,
2770        scrollSpeed: 10,
2771        bubbleScroll: true
2772      }; // Bind all private methods
2773
2774      for (var fn in this) {
2775        if (fn.charAt(0) === '_' && typeof this[fn] === 'function') {
2776          this[fn] = this[fn].bind(this);
2777        }
2778      }
2779    }
2780
2781    AutoScroll.prototype = {
2782      dragStarted: function dragStarted(_ref) {
2783        var originalEvent = _ref.originalEvent;
2784
2785        if (this.sortable.nativeDraggable) {
2786          on(document, 'dragover', this._handleAutoScroll);
2787        } else {
2788          if (this.options.supportPointer) {
2789            on(document, 'pointermove', this._handleFallbackAutoScroll);
2790          } else if (originalEvent.touches) {
2791            on(document, 'touchmove', this._handleFallbackAutoScroll);
2792          } else {
2793            on(document, 'mousemove', this._handleFallbackAutoScroll);
2794          }
2795        }
2796      },
2797      dragOverCompleted: function dragOverCompleted(_ref2) {
2798        var originalEvent = _ref2.originalEvent;
2799
2800        // For when bubbling is canceled and using fallback (fallback 'touchmove' always reached)
2801        if (!this.options.dragOverBubble && !originalEvent.rootEl) {
2802          this._handleAutoScroll(originalEvent);
2803        }
2804      },
2805      drop: function drop() {
2806        if (this.sortable.nativeDraggable) {
2807          off(document, 'dragover', this._handleAutoScroll);
2808        } else {
2809          off(document, 'pointermove', this._handleFallbackAutoScroll);
2810          off(document, 'touchmove', this._handleFallbackAutoScroll);
2811          off(document, 'mousemove', this._handleFallbackAutoScroll);
2812        }
2813
2814        clearPointerElemChangedInterval();
2815        clearAutoScrolls();
2816        cancelThrottle();
2817      },
2818      nulling: function nulling() {
2819        touchEvt$1 = scrollRootEl = scrollEl = scrolling = pointerElemChangedInterval = lastAutoScrollX = lastAutoScrollY = null;
2820        autoScrolls.length = 0;
2821      },
2822      _handleFallbackAutoScroll: function _handleFallbackAutoScroll(evt) {
2823        this._handleAutoScroll(evt, true);
2824      },
2825      _handleAutoScroll: function _handleAutoScroll(evt, fallback) {
2826        var _this = this;
2827
2828        var x = (evt.touches ? evt.touches[0] : evt).clientX,
2829            y = (evt.touches ? evt.touches[0] : evt).clientY,
2830            elem = document.elementFromPoint(x, y);
2831        touchEvt$1 = evt; // IE does not seem to have native autoscroll,
2832        // Edge's autoscroll seems too conditional,
2833        // MACOS Safari does not have autoscroll,
2834        // Firefox and Chrome are good
2835
2836        if (fallback || this.options.forceAutoScrollFallback || Edge || IE11OrLess || Safari) {
2837          autoScroll(evt, this.options, elem, fallback); // Listener for pointer element change
2838
2839          var ogElemScroller = getParentAutoScrollElement(elem, true);
2840
2841          if (scrolling && (!pointerElemChangedInterval || x !== lastAutoScrollX || y !== lastAutoScrollY)) {
2842            pointerElemChangedInterval && clearPointerElemChangedInterval(); // Detect for pointer elem change, emulating native DnD behaviour
2843
2844            pointerElemChangedInterval = setInterval(function () {
2845              var newElem = getParentAutoScrollElement(document.elementFromPoint(x, y), true);
2846
2847              if (newElem !== ogElemScroller) {
2848                ogElemScroller = newElem;
2849                clearAutoScrolls();
2850              }
2851
2852              autoScroll(evt, _this.options, newElem, fallback);
2853            }, 10);
2854            lastAutoScrollX = x;
2855            lastAutoScrollY = y;
2856          }
2857        } else {
2858          // if DnD is enabled (and browser has good autoscrolling), first autoscroll will already scroll, so get parent autoscroll of first autoscroll
2859          if (!this.options.bubbleScroll || getParentAutoScrollElement(elem, true) === getWindowScrollingElement()) {
2860            clearAutoScrolls();
2861            return;
2862          }
2863
2864          autoScroll(evt, this.options, getParentAutoScrollElement(elem, false), false);
2865        }
2866      }
2867    };
2868    return _extends(AutoScroll, {
2869      pluginName: 'scroll',
2870      initializeByDefault: true
2871    });
2872  }
2873
2874  function clearAutoScrolls() {
2875    autoScrolls.forEach(function (autoScroll) {
2876      clearInterval(autoScroll.pid);
2877    });
2878    autoScrolls = [];
2879  }
2880
2881  function clearPointerElemChangedInterval() {
2882    clearInterval(pointerElemChangedInterval);
2883  }
2884
2885  var autoScroll = throttle(function (evt, options, rootEl, isFallback) {
2886    // Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=505521
2887    if (!options.scroll) return;
2888    var x = (evt.touches ? evt.touches[0] : evt).clientX,
2889        y = (evt.touches ? evt.touches[0] : evt).clientY,
2890        sens = options.scrollSensitivity,
2891        speed = options.scrollSpeed,
2892        winScroller = getWindowScrollingElement();
2893    var scrollThisInstance = false,
2894        scrollCustomFn; // New scroll root, set scrollEl
2895
2896    if (scrollRootEl !== rootEl) {
2897      scrollRootEl = rootEl;
2898      clearAutoScrolls();
2899      scrollEl = options.scroll;
2900      scrollCustomFn = options.scrollFn;
2901
2902      if (scrollEl === true) {
2903        scrollEl = getParentAutoScrollElement(rootEl, true);
2904      }
2905    }
2906
2907    var layersOut = 0;
2908    var currentParent = scrollEl;
2909
2910    do {
2911      var el = currentParent,
2912          rect = getRect(el),
2913          top = rect.top,
2914          bottom = rect.bottom,
2915          left = rect.left,
2916          right = rect.right,
2917          width = rect.width,
2918          height = rect.height,
2919          canScrollX = void 0,
2920          canScrollY = void 0,
2921          scrollWidth = el.scrollWidth,
2922          scrollHeight = el.scrollHeight,
2923          elCSS = css(el),
2924          scrollPosX = el.scrollLeft,
2925          scrollPosY = el.scrollTop;
2926
2927      if (el === winScroller) {
2928        canScrollX = width < scrollWidth && (elCSS.overflowX === 'auto' || elCSS.overflowX === 'scroll' || elCSS.overflowX === 'visible');
2929        canScrollY = height < scrollHeight && (elCSS.overflowY === 'auto' || elCSS.overflowY === 'scroll' || elCSS.overflowY === 'visible');
2930      } else {
2931        canScrollX = width < scrollWidth && (elCSS.overflowX === 'auto' || elCSS.overflowX === 'scroll');
2932        canScrollY = height < scrollHeight && (elCSS.overflowY === 'auto' || elCSS.overflowY === 'scroll');
2933      }
2934
2935      var vx = canScrollX && (Math.abs(right - x) <= sens && scrollPosX + width < scrollWidth) - (Math.abs(left - x) <= sens && !!scrollPosX);
2936      var vy = canScrollY && (Math.abs(bottom - y) <= sens && scrollPosY + height < scrollHeight) - (Math.abs(top - y) <= sens && !!scrollPosY);
2937
2938      if (!autoScrolls[layersOut]) {
2939        for (var i = 0; i <= layersOut; i++) {
2940          if (!autoScrolls[i]) {
2941            autoScrolls[i] = {};
2942          }
2943        }
2944      }
2945
2946      if (autoScrolls[layersOut].vx != vx || autoScrolls[layersOut].vy != vy || autoScrolls[layersOut].el !== el) {
2947        autoScrolls[layersOut].el = el;
2948        autoScrolls[layersOut].vx = vx;
2949        autoScrolls[layersOut].vy = vy;
2950        clearInterval(autoScrolls[layersOut].pid);
2951
2952        if (vx != 0 || vy != 0) {
2953          scrollThisInstance = true;
2954          /* jshint loopfunc:true */
2955
2956          autoScrolls[layersOut].pid = setInterval(function () {
2957            // emulate drag over during autoscroll (fallback), emulating native DnD behaviour
2958            if (isFallback && this.layer === 0) {
2959              Sortable.active._onTouchMove(touchEvt$1); // To move ghost if it is positioned absolutely
2960
2961            }
2962
2963            var scrollOffsetY = autoScrolls[this.layer].vy ? autoScrolls[this.layer].vy * 
vendor: 28,854 bytes, lines 2963-3783
2963speed : 0;
2964            var scrollOffsetX = autoScrolls[this.layer].vx ? autoScrolls[this.layer].vx * speed : 0;
2965
2966            if (typeof scrollCustomFn === 'function') {
2967              if (scrollCustomFn.call(Sortable.dragged.parentNode[expando], scrollOffsetX, scrollOffsetY, evt, touchEvt$1, autoScrolls[this.layer].el) !== 'continue') {
2968                return;
2969              }
2970            }
2971
2972            scrollBy(autoScrolls[this.layer].el, scrollOffsetX, scrollOffsetY);
2973          }.bind({
2974            layer: layersOut
2975          }), 24);
2976        }
2977      }
2978
2979      layersOut++;
2980    } while (options.bubbleScroll && currentParent !== winScroller && (currentParent = getParentAutoScrollElement(currentParent, false)));
2981
2982    scrolling = scrollThisInstance; // in case another function catches scrolling as false in between when it is not
2983  }, 30);
2984
2985  var drop = function drop(_ref) {
2986    var originalEvent = _ref.originalEvent,
2987        putSortable = _ref.putSortable,
2988        dragEl = _ref.dragEl,
2989        activeSortable = _ref.activeSortable,
2990        dispatchSortableEvent = _ref.dispatchSortableEvent,
2991        hideGhostForTarget = _ref.hideGhostForTarget,
2992        unhideGhostForTarget = _ref.unhideGhostForTarget;
2993    if (!originalEvent) return;
2994    var toSortable = putSortable || activeSortable;
2995    hideGhostForTarget();
2996    var touch = originalEvent.changedTouches && originalEvent.changedTouches.length ? originalEvent.changedTouches[0] : originalEvent;
2997    var target = document.elementFromPoint(touch.clientX, touch.clientY);
2998    unhideGhostForTarget();
2999
3000    if (toSortable && !toSortable.el.contains(target)) {
3001      dispatchSortableEvent('spill');
3002      this.onSpill({
3003        dragEl: dragEl,
3004        putSortable: putSortable
3005      });
3006    }
3007  };
3008
3009  function Revert() {}
3010
3011  Revert.prototype = {
3012    startIndex: null,
3013    dragStart: function dragStart(_ref2) {
3014      var oldDraggableIndex = _ref2.oldDraggableIndex;
3015      this.startIndex = oldDraggableIndex;
3016    },
3017    onSpill: function onSpill(_ref3) {
3018      var dragEl = _ref3.dragEl,
3019          putSortable = _ref3.putSortable;
3020      this.sortable.captureAnimationState();
3021
3022      if (putSortable) {
3023        putSortable.captureAnimationState();
3024      }
3025
3026      var nextSibling = getChild(this.sortable.el, this.startIndex, this.options);
3027
3028      if (nextSibling) {
3029        this.sortable.el.insertBefore(dragEl, nextSibling);
3030      } else {
3031        this.sortable.el.appendChild(dragEl);
3032      }
3033
3034      this.sortable.animateAll();
3035
3036      if (putSortable) {
3037        putSortable.animateAll();
3038      }
3039    },
3040    drop: drop
3041  };
3042
3043  _extends(Revert, {
3044    pluginName: 'revertOnSpill'
3045  });
3046
3047  function Remove() {}
3048
3049  Remove.prototype = {
3050    onSpill: function onSpill(_ref4) {
3051      var dragEl = _ref4.dragEl,
3052          putSortable = _ref4.putSortable;
3053      var parentSortable = putSortable || this.sortable;
3054      parentSortable.captureAnimationState();
3055      dragEl.parentNode && dragEl.parentNode.removeChild(dragEl);
3056      parentSortable.animateAll();
3057    },
3058    drop: drop
3059  };
3060
3061  _extends(Remove, {
3062    pluginName: 'removeOnSpill'
3063  });
3064
3065  var lastSwapEl;
3066
3067  function SwapPlugin() {
3068    function Swap() {
3069      this.defaults = {
3070        swapClass: 'sortable-swap-highlight'
3071      };
3072    }
3073
3074    Swap.prototype = {
3075      dragStart: function dragStart(_ref) {
3076        var dragEl = _ref.dragEl;
3077        lastSwapEl = dragEl;
3078      },
3079      dragOverValid: function dragOverValid(_ref2) {
3080        var completed = _ref2.completed,
3081            target = _ref2.target,
3082            onMove = _ref2.onMove,
3083            activeSortable = _ref2.activeSortable,
3084            changed = _ref2.changed,
3085            cancel = _ref2.cancel;
3086        if (!activeSortable.options.swap) return;
3087        var el = this.sortable.el,
3088            options = this.options;
3089
3090        if (target && target !== el) {
3091          var prevSwapEl = lastSwapEl;
3092
3093          if (onMove(target) !== false) {
3094            toggleClass(target, options.swapClass, true);
3095            lastSwapEl = target;
3096          } else {
3097            lastSwapEl = null;
3098          }
3099
3100          if (prevSwapEl && prevSwapEl !== lastSwapEl) {
3101            toggleClass(prevSwapEl, options.swapClass, false);
3102          }
3103        }
3104
3105        changed();
3106        completed(true);
3107        cancel();
3108      },
3109      drop: function drop(_ref3) {
3110        var activeSortable = _ref3.activeSortable,
3111            putSortable = _ref3.putSortable,
3112            dragEl = _ref3.dragEl;
3113        var toSortable = putSortable || this.sortable;
3114        var options = this.options;
3115        lastSwapEl && toggleClass(lastSwapEl, options.swapClass, false);
3116
3117        if (lastSwapEl && (options.swap || putSortable && putSortable.options.swap)) {
3118          if (dragEl !== lastSwapEl) {
3119            toSortable.captureAnimationState();
3120            if (toSortable !== activeSortable) activeSortable.captureAnimationState();
3121            swapNodes(dragEl, lastSwapEl);
3122            toSortable.animateAll();
3123            if (toSortable !== activeSortable) activeSortable.animateAll();
3124          }
3125        }
3126      },
3127      nulling: function nulling() {
3128        lastSwapEl = null;
3129      }
3130    };
3131    return _extends(Swap, {
3132      pluginName: 'swap',
3133      eventProperties: function eventProperties() {
3134        return {
3135          swapItem: lastSwapEl
3136        };
3137      }
3138    });
3139  }
3140
3141  function swapNodes(n1, n2) {
3142    var p1 = n1.parentNode,
3143        p2 = n2.parentNode,
3144        i1,
3145        i2;
3146    if (!p1 || !p2 || p1.isEqualNode(n2) || p2.isEqualNode(n1)) return;
3147    i1 = index(n1);
3148    i2 = index(n2);
3149
3150    if (p1.isEqualNode(p2) && i1 < i2) {
3151      i2++;
3152    }
3153
3154    p1.insertBefore(n2, p1.children[i1]);
3155    p2.insertBefore(n1, p2.children[i2]);
3156  }
3157
3158  var multiDragElements = [],
3159      multiDragClones = [],
3160      lastMultiDragSelect,
3161      // for selection with modifier key down (SHIFT)
3162  multiDragSortable,
3163      initialFolding = false,
3164      // Initial multi-drag fold when drag started
3165  folding = false,
3166      // Folding any other time
3167  dragStarted = false,
3168      dragEl$1,
3169      clonesFromRect,
3170      clonesHidden;
3171
3172  function MultiDragPlugin() {
3173    function MultiDrag(sortable) {
3174      // Bind all private methods
3175      for (var fn in this) {
3176        if (fn.charAt(0) === '_' && typeof this[fn] === 'function') {
3177          this[fn] = this[fn].bind(this);
3178        }
3179      }
3180
3181      if (sortable.options.supportPointer) {
3182        on(document, 'pointerup', this._deselectMultiDrag);
3183      } else {
3184        on(document, 'mouseup', this._deselectMultiDrag);
3185        on(document, 'touchend', this._deselectMultiDrag);
3186      }
3187
3188      on(document, 'keydown', this._checkKeyDown);
3189      on(document, 'keyup', this._checkKeyUp);
3190      this.defaults = {
3191        selectedClass: 'sortable-selected',
3192        multiDragKey: null,
3193        setData: function setData(dataTransfer, dragEl) {
3194          var data = '';
3195
3196          if (multiDragElements.length && multiDragSortable === sortable) {
3197            multiDragElements.forEach(function (multiDragElement, i) {
3198              data += (!i ? '' : ', ') + multiDragElement.textContent;
3199            });
3200          } else {
3201            data = dragEl.textContent;
3202          }
3203
3204          dataTransfer.setData('Text', data);
3205        }
3206      };
3207    }
3208
3209    MultiDrag.prototype = {
3210      multiDragKeyDown: false,
3211      isMultiDrag: false,
3212      delayStartGlobal: function delayStartGlobal(_ref) {
3213        var dragged = _ref.dragEl;
3214        dragEl$1 = dragged;
3215      },
3216      delayEnded: function delayEnded() {
3217        this.isMultiDrag = ~multiDragElements.indexOf(dragEl$1);
3218      },
3219      setupClone: function setupClone(_ref2) {
3220        var sortable = _ref2.sortable,
3221            cancel = _ref2.cancel;
3222        if (!this.isMultiDrag) return;
3223
3224        for (var i = 0; i < multiDragElements.length; i++) {
3225          multiDragClones.push(clone(multiDragElements[i]));
3226          multiDragClones[i].sortableIndex = multiDragElements[i].sortableIndex;
3227          multiDragClones[i].draggable = false;
3228          multiDragClones[i].style['will-change'] = '';
3229          toggleClass(multiDragClones[i], this.options.selectedClass, false);
3230          multiDragElements[i] === dragEl$1 && toggleClass(multiDragClones[i], this.options.chosenClass, false);
3231        }
3232
3233        sortable._hideClone();
3234
3235        cancel();
3236      },
3237      clone: function clone(_ref3) {
3238        var sortable = _ref3.sortable,
3239            rootEl = _ref3.rootEl,
3240            dispatchSortableEvent = _ref3.dispatchSortableEvent,
3241            cancel = _ref3.cancel;
3242        if (!this.isMultiDrag) return;
3243
3244        if (!this.options.removeCloneOnHide) {
3245          if (multiDragElements.length && multiDragSortable === sortable) {
3246            insertMultiDragClones(true, rootEl);
3247            dispatchSortableEvent('clone');
3248            cancel();
3249          }
3250        }
3251      },
3252      showClone: function showClone(_ref4) {
3253        var cloneNowShown = _ref4.cloneNowShown,
3254            rootEl = _ref4.rootEl,
3255            cancel = _ref4.cancel;
3256        if (!this.isMultiDrag) return;
3257        insertMultiDragClones(false, rootEl);
3258        multiDragClones.forEach(function (clone) {
3259          css(clone, 'display', '');
3260        });
3261        cloneNowShown();
3262        clonesHidden = false;
3263        cancel();
3264      },
3265      hideClone: function hideClone(_ref5) {
3266        var _this = this;
3267
3268        var sortable = _ref5.sortable,
3269            cloneNowHidden = _ref5.cloneNowHidden,
3270            cancel = _ref5.cancel;
3271        if (!this.isMultiDrag) return;
3272        multiDragClones.forEach(function (clone) {
3273          css(clone, 'display', 'none');
3274
3275          if (_this.options.removeCloneOnHide && clone.parentNode) {
3276            clone.parentNode.removeChild(clone);
3277          }
3278        });
3279        cloneNowHidden();
3280        clonesHidden = true;
3281        cancel();
3282      },
3283      dragStartGlobal: function dragStartGlobal(_ref6) {
3284        var sortable = _ref6.sortable;
3285
3286        if (!this.isMultiDrag && multiDragSortable) {
3287          multiDragSortable.multiDrag._deselectMultiDrag();
3288        }
3289
3290        multiDragElements.forEach(function (multiDragElement) {
3291          multiDragElement.sortableIndex = index(multiDragElement);
3292        }); // Sort multi-drag elements
3293
3294        multiDragElements = multiDragElements.sort(function (a, b) {
3295          return a.sortableIndex - b.sortableIndex;
3296        });
3297        dragStarted = true;
3298      },
3299      dragStarted: function dragStarted(_ref7) {
3300        var _this2 = this;
3301
3302        var sortable = _ref7.sortable;
3303        if (!this.isMultiDrag) return;
3304
3305        if (this.options.sort) {
3306          // Capture rects,
3307          // hide multi drag elements (by positioning them absolute),
3308          // set multi drag elements rects to dragRect,
3309          // show multi drag elements,
3310          // animate to rects,
3311          // unset rects & remove from DOM
3312          sortable.captureAnimationState();
3313
3314          if (this.options.animation) {
3315            multiDragElements.forEach(function (multiDragElement) {
3316              if (multiDragElement === dragEl$1) return;
3317              css(multiDragElement, 'position', 'absolute');
3318            });
3319            var dragRect = getRect(dragEl$1, false, true, true);
3320            multiDragElements.forEach(function (multiDragElement) {
3321              if (multiDragElement === dragEl$1) return;
3322              setRect(multiDragElement, dragRect);
3323            });
3324            folding = true;
3325            initialFolding = true;
3326          }
3327        }
3328
3329        sortable.animateAll(function () {
3330          folding = false;
3331          initialFolding = false;
3332
3333          if (_this2.options.animation) {
3334            multiDragElements.forEach(function (multiDragElement) {
3335              unsetRect(multiDragElement);
3336            });
3337          } // Remove all auxiliary multidrag items from el, if sorting enabled
3338
3339
3340          if (_this2.options.sort) {
3341            removeMultiDragElements();
3342          }
3343        });
3344      },
3345      dragOver: function dragOver(_ref8) {
3346        var target = _ref8.target,
3347            completed = _ref8.completed,
3348            cancel = _ref8.cancel;
3349
3350        if (folding && ~multiDragElements.indexOf(target)) {
3351          completed(false);
3352          cancel();
3353        }
3354      },
3355      revert: function revert(_ref9) {
3356        var fromSortable = _ref9.fromSortable,
3357            rootEl = _ref9.rootEl,
3358            sortable = _ref9.sortable,
3359            dragRect = _ref9.dragRect;
3360
3361        if (multiDragElements.length > 1) {
3362          // Setup unfold animation
3363          multiDragElements.forEach(function (multiDragElement) {
3364            sortable.addAnimationState({
3365              target: multiDragElement,
3366              rect: folding ? getRect(multiDragElement) : dragRect
3367            });
3368            unsetRect(multiDragElement);
3369            multiDragElement.fromRect = dragRect;
3370            fromSortable.removeAnimationState(multiDragElement);
3371          });
3372          folding = false;
3373          insertMultiDragElements(!this.options.removeCloneOnHide, rootEl);
3374        }
3375      },
3376      dragOverCompleted: function dragOverCompleted(_ref10) {
3377        var sortable = _ref10.sortable,
3378            isOwner = _ref10.isOwner,
3379            insertion = _ref10.insertion,
3380            activeSortable = _ref10.activeSortable,
3381            parentEl = _ref10.parentEl,
3382            putSortable = _ref10.putSortable;
3383        var options = this.options;
3384
3385        if (insertion) {
3386          // Clones must be hidden before folding animation to capture dragRectAbsolute properly
3387          if (isOwner) {
3388            activeSortable._hideClone();
3389          }
3390
3391          initialFolding = false; // If leaving sort:false root, or already folding - Fold to new location
3392
3393          if (options.animation && multiDragElements.length > 1 && (folding || !isOwner && !activeSortable.options.sort && !putSortable)) {
3394            // Fold: Set all multi drag elements's rects to dragEl's rect when multi-drag elements are invisible
3395            var dragRectAbsolute = getRect(dragEl$1, false, true, true);
3396            multiDragElements.forEach(function (multiDragElement) {
3397              if (multiDragElement === dragEl$1) return;
3398              setRect(multiDragElement, dragRectAbsolute); // Move element(s) to end of parentEl so that it does not interfere with multi-drag clones insertion if they are inserted
3399              // while folding, and so that we can capture them again because old sortable will no longer be fromSortable
3400
3401              parentEl.appendChild(multiDragElement);
3402            });
3403            folding = true;
3404          } // Clones must be shown (and check to remove multi drags) after folding when interfering multiDragElements are moved out
3405
3406
3407          if (!isOwner) {
3408            // Only remove if not folding (folding will remove them anyways)
3409            if (!folding) {
3410              removeMultiDragElements();
3411            }
3412
3413            if (multiDragElements.length > 1) {
3414              var clonesHiddenBefore = clonesHidden;
3415
3416              activeSortable._showClone(sortable); // Unfold animation for clones if showing from hidden
3417
3418
3419              if (activeSortable.options.animation && !clonesHidden && clonesHiddenBefore) {
3420                multiDragClones.forEach(function (clone) {
3421                  activeSortable.addAnimationState({
3422                    target: clone,
3423                    rect: clonesFromRect
3424                  });
3425                  clone.fromRect = clonesFromRect;
3426                  clone.thisAnimationDuration = null;
3427                });
3428              }
3429            } else {
3430              activeSortable._showClone(sortable);
3431            }
3432          }
3433        }
3434      },
3435      dragOverAnimationCapture: function dragOverAnimationCapture(_ref11) {
3436        var dragRect = _ref11.dragRect,
3437            isOwner = _ref11.isOwner,
3438            activeSortable = _ref11.activeSortable;
3439        multiDragElements.forEach(function (multiDragElement) {
3440          multiDragElement.thisAnimationDuration = null;
3441        });
3442
3443        if (activeSortable.options.animation && !isOwner && activeSortable.multiDrag.isMultiDrag) {
3444          clonesFromRect = _extends({}, dragRect);
3445          var dragMatrix = matrix(dragEl$1, true);
3446          clonesFromRect.top -= dragMatrix.f;
3447          clonesFromRect.left -= dragMatrix.e;
3448        }
3449      },
3450      dragOverAnimationComplete: function dragOverAnimationComplete() {
3451        if (folding) {
3452          folding = false;
3453          removeMultiDragElements();
3454        }
3455      },
3456      drop: function drop(_ref12) {
3457        var evt = _ref12.originalEvent,
3458            rootEl = _ref12.rootEl,
3459            parentEl = _ref12.parentEl,
3460            sortable = _ref12.sortable,
3461            dispatchSortableEvent = _ref12.dispatchSortableEvent,
3462            oldIndex = _ref12.oldIndex,
3463            putSortable = _ref12.putSortable;
3464        var toSortable = putSortable || this.sortable;
3465        if (!evt) return;
3466        var options = this.options,
3467            children = parentEl.children; // Multi-drag selection
3468
3469        if (!dragStarted) {
3470          if (options.multiDragKey && !this.multiDragKeyDown) {
3471            this._deselectMultiDrag();
3472          }
3473
3474          toggleClass(dragEl$1, options.selectedClass, !~multiDragElements.indexOf(dragEl$1));
3475
3476          if (!~multiDragElements.indexOf(dragEl$1)) {
3477            multiDragElements.push(dragEl$1);
3478            dispatchEvent({
3479              sortable: sortable,
3480              rootEl: rootEl,
3481              name: 'select',
3482              targetEl: dragEl$1,
3483              originalEvt: evt
3484            }); // Modifier activated, select from last to dragEl
3485
3486            if (evt.shiftKey && lastMultiDragSelect && sortable.el.contains(lastMultiDragSelect)) {
3487              var lastIndex = index(lastMultiDragSelect),
3488                  currentIndex = index(dragEl$1);
3489
3490              if (~lastIndex && ~currentIndex && lastIndex !== currentIndex) {
3491                // Must include lastMultiDragSelect (select it), in case modified selection from no selection
3492                // (but previous selection existed)
3493                var n, i;
3494
3495                if (currentIndex > lastIndex) {
3496                  i = lastIndex;
3497                  n = currentIndex;
3498                } else {
3499                  i = currentIndex;
3500                  n = lastIndex + 1;
3501                }
3502
3503                for (; i < n; i++) {
3504                  if (~multiDragElements.indexOf(children[i])) continue;
3505                  toggleClass(children[i], options.selectedClass, true);
3506                  multiDragElements.push(children[i]);
3507                  dispatchEvent({
3508                    sortable: sortable,
3509                    rootEl: rootEl,
3510                    name: 'select',
3511                    targetEl: children[i],
3512                    originalEvt: evt
3513                  });
3514                }
3515              }
3516            } else {
3517              lastMultiDragSelect = dragEl$1;
3518            }
3519
3520            multiDragSortable = toSortable;
3521          } else {
3522            multiDragElements.splice(multiDragElements.indexOf(dragEl$1), 1);
3523            lastMultiDragSelect = null;
3524            dispatchEvent({
3525              sortable: sortable,
3526              rootEl: rootEl,
3527              name: 'deselect',
3528              targetEl: dragEl$1,
3529              originalEvt: evt
3530            });
3531          }
3532        } // Multi-drag drop
3533
3534
3535        if (dragStarted && this.isMultiDrag) {
3536          folding = false; // Do not "unfold" after around dragEl if reverted
3537
3538          if ((parentEl[expando].options.sort || parentEl !== rootEl) && multiDragElements.length > 1) {
3539            var dragRect = getRect(dragEl$1),
3540                multiDragIndex = index(dragEl$1, ':not(.' + this.options.selectedClass + ')');
3541            if (!initialFolding && options.animation) dragEl$1.thisAnimationDuration = null;
3542            toSortable.captureAnimationState();
3543
3544            if (!initialFolding) {
3545              if (options.animation) {
3546                dragEl$1.fromRect = dragRect;
3547                multiDragElements.forEach(function (multiDragElement) {
3548                  multiDragElement.thisAnimationDuration = null;
3549
3550                  if (multiDragElement !== dragEl$1) {
3551                    var rect = folding ? getRect(multiDragElement) : dragRect;
3552                    multiDragElement.fromRect = rect; // Prepare unfold animation
3553
3554                    toSortable.addAnimationState({
3555                      target: multiDragElement,
3556                      rect: rect
3557                    });
3558                  }
3559                });
3560              } // Multi drag elements are not necessarily removed from the DOM on drop, so to reinsert
3561              // properly they must all be removed
3562
3563
3564              removeMultiDragElements();
3565              multiDragElements.forEach(function (multiDragElement) {
3566                if (children[multiDragIndex]) {
3567                  parentEl.insertBefore(multiDragElement, children[multiDragIndex]);
3568                } else {
3569                  parentEl.appendChild(multiDragElement);
3570                }
3571
3572                multiDragIndex++;
3573              }); // If initial folding is done, the elements may have changed position because they are now
3574              // unfolding around dragEl, even though dragEl may not have his index changed, so update event
3575              // must be fired here as Sortable will not.
3576
3577              if (oldIndex === index(dragEl$1)) {
3578                var update = false;
3579                multiDragElements.forEach(function (multiDragElement) {
3580                  if (multiDragElement.sortableIndex !== index(multiDragElement)) {
3581                    update = true;
3582                    return;
3583                  }
3584                });
3585
3586                if (update) {
3587                  dispatchSortableEvent('update');
3588                }
3589              }
3590            } // Must be done after capturing individual rects (scroll bar)
3591
3592
3593            multiDragElements.forEach(function (multiDragElement) {
3594              unsetRect(multiDragElement);
3595            });
3596            toSortable.animateAll();
3597          }
3598
3599          multiDragSortable = toSortable;
3600        } // Remove clones if necessary
3601
3602
3603        if (rootEl === parentEl || putSortable && putSortable.lastPutMode !== 'clone') {
3604          multiDragClones.forEach(function (clone) {
3605            clone.parentNode && clone.parentNode.removeChild(clone);
3606          });
3607        }
3608      },
3609      nullingGlobal: function nullingGlobal() {
3610        this.isMultiDrag = dragStarted = false;
3611        multiDragClones.length = 0;
3612      },
3613      destroyGlobal: function destroyGlobal() {
3614        this._deselectMultiDrag();
3615
3616        off(document, 'pointerup', this._deselectMultiDrag);
3617        off(document, 'mouseup', this._deselectMultiDrag);
3618        off(document, 'touchend', this._deselectMultiDrag);
3619        off(document, 'keydown', this._checkKeyDown);
3620        off(document, 'keyup', this._checkKeyUp);
3621      },
3622      _deselectMultiDrag: function _deselectMultiDrag(evt) {
3623        if (typeof dragStarted !== "undefined" && dragStarted) return; // Only deselect if selection is in this sortable
3624
3625        if (multiDragSortable !== this.sortable) return; // Only deselect if target is not item in this sortable
3626
3627        if (evt && closest(evt.target, this.options.draggable, this.sortable.el, false)) return; // Only deselect if left click
3628
3629        if (evt && evt.button !== 0) return;
3630
3631        while (multiDragElements.length) {
3632          var el = multiDragElements[0];
3633          toggleClass(el, this.options.selectedClass, false);
3634          multiDragElements.shift();
3635          dispatchEvent({
3636            sortable: this.sortable,
3637            rootEl: this.sortable.el,
3638            name: 'deselect',
3639            targetEl: el,
3640            originalEvt: evt
3641          });
3642        }
3643      },
3644      _checkKeyDown: function _checkKeyDown(evt) {
3645        if (evt.key === this.options.multiDragKey) {
3646          this.multiDragKeyDown = true;
3647        }
3648      },
3649      _checkKeyUp: function _checkKeyUp(evt) {
3650        if (evt.key === this.options.multiDragKey) {
3651          this.multiDragKeyDown = false;
3652        }
3653      }
3654    };
3655    return _extends(MultiDrag, {
3656      // Static methods & properties
3657      pluginName: 'multiDrag',
3658      utils: {
3659        /**
3660         * Selects the provided multi-drag item
3661         * @param  {HTMLElement} el    The element to be selected
3662         */
3663        select: function select(el) {
3664          var sortable = el.parentNode[expando];
3665          if (!sortable || !sortable.options.multiDrag || ~multiDragElements.indexOf(el)) return;
3666
3667          if (multiDragSortable && multiDragSortable !== sortable) {
3668            multiDragSortable.multiDrag._deselectMultiDrag();
3669
3670            multiDragSortable = sortable;
3671          }
3672
3673          toggleClass(el, sortable.options.selectedClass, true);
3674          multiDragElements.push(el);
3675        },
3676
3677        /**
3678         * Deselects the provided multi-drag item
3679         * @param  {HTMLElement} el    The element to be deselected
3680         */
3681        deselect: function deselect(el) {
3682          var sortable = el.parentNode[expando],
3683              index = multiDragElements.indexOf(el);
3684          if (!sortable || !sortable.options.multiDrag || !~index) return;
3685          toggleClass(el, sortable.options.selectedClass, false);
3686          multiDragElements.splice(index, 1);
3687        }
3688      },
3689      eventProperties: function eventProperties() {
3690        var _this3 = this;
3691
3692        var oldIndicies = [],
3693            newIndicies = [];
3694        multiDragElements.forEach(function (multiDragElement) {
3695          oldIndicies.push({
3696            multiDragElement: multiDragElement,
3697            index: multiDragElement.sortableIndex
3698          }); // multiDragElements will already be sorted if folding
3699
3700          var newIndex;
3701
3702          if (folding && multiDragElement !== dragEl$1) {
3703            newIndex = -1;
3704          } else if (folding) {
3705            newIndex = index(multiDragElement, ':not(.' + _this3.options.selectedClass + ')');
3706          } else {
3707            newIndex = index(multiDragElement);
3708          }
3709
3710          newIndicies.push({
3711            multiDragElement: multiDragElement,
3712            index: newIndex
3713          });
3714        });
3715        return {
3716          items: _toConsumableArray(multiDragElements),
3717          clones: [].concat(multiDragClones),
3718          oldIndicies: oldIndicies,
3719          newIndicies: newIndicies
3720        };
3721      },
3722      optionListeners: {
3723        multiDragKey: function multiDragKey(key) {
3724          key = key.toLowerCase();
3725
3726          if (key === 'ctrl') {
3727            key = 'Control';
3728          } else if (key.length > 1) {
3729            key = key.charAt(0).toUpperCase() + key.substr(1);
3730          }
3731
3732          return key;
3733        }
3734      }
3735    });
3736  }
3737
3738  function insertMultiDragElements(clonesInserted, rootEl) {
3739    multiDragElements.forEach(function (multiDragElement, i) {
3740      var target = rootEl.children[multiDragElement.sortableIndex + (clonesInserted ? Number(i) : 0)];
3741
3742      if (target) {
3743        rootEl.insertBefore(multiDragElement, target);
3744      } else {
3745        rootEl.appendChild(multiDragElement);
3746      }
3747    });
3748  }
3749  /**
3750   * Insert multi-drag clones
3751   * @param  {[Boolean]} elementsInserted  Whether the multi-drag elements are inserted
3752   * @param  {HTMLElement} rootEl
3753   */
3754
3755
3756  function insertMultiDragClones(elementsInserted, rootEl) {
3757    multiDragClones.forEach(function (clone, i) {
3758      var target = rootEl.children[clone.sortableIndex + (elementsInserted ? Number(i) : 0)];
3759
3760      if (target) {
3761        rootEl.insertBefore(clone, target);
3762      } else {
3763        rootEl.appendChild(clone);
3764      }
3765    });
3766  }
3767
3768  function removeMultiDragElements() {
3769    multiDragElements.forEach(function (multiDragElement) {
3770      if (multiDragElement === dragEl$1) return;
3771      multiDragElement.parentNode && multiDragElement.parentNode.removeChild(multiDragElement);
3772    });
3773  }
3774
3775  Sortable.mount(new AutoScrollPlugin());
3776  Sortable.mount(Remove, Revert);
3777
3778  Sortable.mount(new SwapPlugin());
3779  Sortable.mount(new MultiDragPlugin());
3780
3781  return Sortable;
3782
3783})));

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