Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

| Ultima modificación | Ver Log |

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