Built motion from commit 943eae279.|1.0.24
[motion.git] / public / bower_components / Sortable / Sortable.js
index 60c9575..f4ac38d 100644 (file)
@@ -4,7 +4,8 @@
  * @license MIT
  */
 
-(function sortableModule(factory) {
+
+(function (factory) {
        "use strict";
 
        if (typeof define === "function" && define.amd) {
        else if (typeof module != "undefined" && typeof module.exports != "undefined") {
                module.exports = factory();
        }
+       else if (typeof Package !== "undefined") {
+               Sortable = factory();  // export for Meteor.js
+       }
        else {
                /* jshint sub:true */
                window["Sortable"] = factory();
        }
-})(function sortableFactory() {
+})(function () {
        "use strict";
 
-       if (typeof window == "undefined" || !window.document) {
-               return function sortableError() {
-                       throw new Error("Sortable.js requires a window with a document");
-               };
-       }
-
        var dragEl,
                parentEl,
                ghostEl,
                cloneEl,
                rootEl,
                nextEl,
-               lastDownEl,
 
                scrollEl,
                scrollParentEl,
-               scrollCustomFn,
 
                lastEl,
                lastCSS,
@@ -46,8 +42,6 @@
                newIndex,
 
                activeGroup,
-               putSortable,
-
                autoScroll = {},
 
                tapEvt,
@@ -56,8 +50,7 @@
                moved,
 
                /** @const */
-               R_SPACE = /\s+/g,
-               R_FLOAT = /left|right|inline/,
+               RSPACE = /\s+/g,
 
                expando = 'Sortable' + (new Date).getTime(),
 
                document = win.document,
                parseInt = win.parseInt,
 
-               $ = win.jQuery || win.Zepto,
-               Polymer = win.Polymer,
-
-               captureMode = false,
-
                supportDraggable = !!('draggable' in document.createElement('div')),
                supportCssPointerEvents = (function (el) {
-                       // false when IE11
-                       if (!!navigator.userAgent.match(/Trident.*rv[ :]?11\./)) {
-                               return false;
-                       }
                        el = document.createElement('x');
                        el.style.cssText = 'pointer-events:auto';
                        return el.style.pointerEvents === 'auto';
                _silent = false,
 
                abs = Math.abs,
-               min = Math.min,
+               slice = [].slice,
 
-               savedInputChecked = [],
                touchDragOverListeners = [],
 
                _autoScroll = _throttle(function (/**Event*/evt, /**Object*/options, /**HTMLElement*/rootEl) {
                        // Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=505521
                        if (rootEl && options.scroll) {
-                               var _this = rootEl[expando],
-                                       el,
+                               var el,
                                        rect,
                                        sens = options.scrollSensitivity,
                                        speed = options.scrollSpeed,
                                        winHeight = window.innerHeight,
 
                                        vx,
-                                       vy,
-
-                                       scrollOffsetX,
-                                       scrollOffsetY
+                                       vy
                                ;
 
                                // Delect scrollEl
                                if (scrollParentEl !== rootEl) {
                                        scrollEl = options.scroll;
                                        scrollParentEl = rootEl;
-                                       scrollCustomFn = options.scrollFn;
 
                                        if (scrollEl === true) {
                                                scrollEl = rootEl;
 
                                        if (el) {
                                                autoScroll.pid = setInterval(function () {
-                                                       scrollOffsetY = vy ? vy * speed : 0;
-                                                       scrollOffsetX = vx ? vx * speed : 0;
-
-                                                       if ('function' === typeof(scrollCustomFn)) {
-                                                               return scrollCustomFn.call(_this, scrollOffsetX, scrollOffsetY, evt);
-                                                       }
-
                                                        if (el === win) {
-                                                               win.scrollTo(win.pageXOffset + scrollOffsetX, win.pageYOffset + scrollOffsetY);
+                                                               win.scrollTo(win.pageXOffset + vx * speed, win.pageYOffset + vy * speed);
                                                        } else {
-                                                               el.scrollTop += scrollOffsetY;
-                                                               el.scrollLeft += scrollOffsetX;
+                                                               vy && (el.scrollTop += vy * speed);
+                                                               vx && (el.scrollLeft += vx * speed);
                                                        }
                                                }, 24);
                                        }
                }, 30),
 
                _prepareGroup = function (options) {
-                       function toFn(value, pull) {
-                               if (value === void 0 || value === true) {
-                                       value = group.name;
-                               }
-
-                               if (typeof value === 'function') {
-                                       return value;
-                               } else {
-                                       return function (to, from) {
-                                               var fromGroup = from.options.group.name;
-
-                                               return pull
-                                                       ? value
-                                                       : value && (value.join
-                                                               ? value.indexOf(fromGroup) > -1
-                                                               : (fromGroup == value)
-                                                       );
-                                       };
-                               }
-                       }
+                       var group = options.group;
 
-                       var group = {};
-                       var originalGroup = options.group;
-
-                       if (!originalGroup || typeof originalGroup != 'object') {
-                               originalGroup = {name: originalGroup};
+                       if (!group || typeof group != 'object') {
+                               group = options.group = {name: group};
                        }
 
-                       group.name = originalGroup.name;
-                       group.checkPull = toFn(originalGroup.pull, true);
-                       group.checkPut = toFn(originalGroup.put);
-                       group.revertClone = originalGroup.revertClone;
+                       ['pull', 'put'].forEach(function (key) {
+                               if (!(key in group)) {
+                                       group[key] = true;
+                               }
+                       });
 
-                       options.group = group;
+                       options.groups = ' ' + group.name + (group.put.join ? ' ' + group.put.join(' ') : '') + ' ';
                }
        ;
 
 
+
        /**
         * @class  Sortable
         * @param  {HTMLElement}  el
                // Export instance
                el[expando] = this;
 
+
                // Default options
                var defaults = {
                        group: Math.random(),
                        draggable: /[uo]l/i.test(el.nodeName) ? 'li' : '>*',
                        ghostClass: 'sortable-ghost',
                        chosenClass: 'sortable-chosen',
-                       dragClass: 'sortable-drag',
                        ignore: 'a, img',
                        filter: null,
-                       preventOnFilter: true,
                        animation: 0,
                        setData: function (dataTransfer, dragEl) {
                                dataTransfer.setData('Text', dragEl.textContent);
                        delay: 0,
                        forceFallback: false,
                        fallbackClass: 'sortable-fallback',
-                       fallbackOnBody: false,
-                       fallbackTolerance: 0,
-                       fallbackOffset: {x: 0, y: 0}
+                       fallbackOnBody: false
                };
 
 
 
                // Bind all private methods
                for (var fn in this) {
-                       if (fn.charAt(0) === '_' && typeof this[fn] === 'function') {
+                       if (fn.charAt(0) === '_') {
                                this[fn] = this[fn].bind(this);
                        }
                }
                // Bind events
                _on(el, 'mousedown', this._onTapStart);
                _on(el, 'touchstart', this._onTapStart);
-               _on(el, 'pointerdown', this._onTapStart);
 
                if (this.nativeDraggable) {
                        _on(el, 'dragover', this);
                        var _this = this,
                                el = this.el,
                                options = this.options,
-                               preventOnFilter = options.preventOnFilter,
                                type = evt.type,
                                touch = evt.touches && evt.touches[0],
                                target = (touch || evt).target,
-                               originalTarget = evt.target.shadowRoot && evt.path[0] || target,
-                               filter = options.filter,
-                               startIndex;
+                               originalTarget = target,
+                               filter = options.filter;
 
-                       _saveInputCheckedState(el);
-
-
-                       // Don't trigger start event when an element is been dragged, otherwise the evt.oldindex always wrong when set option.group.
-                       if (dragEl) {
-                               return;
-                       }
 
                        if (type === 'mousedown' && evt.button !== 0 || options.disabled) {
                                return; // only left button or enabled
                        }
 
-
                        target = _closest(target, options.draggable, el);
 
                        if (!target) {
                                return;
                        }
 
-                       if (lastDownEl === target) {
-                               // Ignoring duplicate `down`
-                               return;
-                       }
-
-                       // Get the index of the dragged element within its parent
-                       startIndex = _index(target, options.draggable);
+                       // get the index of the dragged element within its parent
+                       oldIndex = _index(target);
 
                        // Check filter
                        if (typeof filter === 'function') {
                                if (filter.call(this, evt, target, this)) {
-                                       _dispatchEvent(_this, originalTarget, 'filter', target, el, startIndex);
-                                       preventOnFilter && evt.preventDefault();
+                                       _dispatchEvent(_this, originalTarget, 'filter', target, el, oldIndex);
+                                       evt.preventDefault();
                                        return; // cancel dnd
                                }
                        }
                                        criteria = _closest(originalTarget, criteria.trim(), el);
 
                                        if (criteria) {
-                                               _dispatchEvent(_this, criteria, 'filter', target, el, startIndex);
+                                               _dispatchEvent(_this, criteria, 'filter', target, el, oldIndex);
                                                return true;
                                        }
                                });
 
                                if (filter) {
-                                       preventOnFilter && evt.preventDefault();
+                                       evt.preventDefault();
                                        return; // cancel dnd
                                }
                        }
 
+
                        if (options.handle && !_closest(originalTarget, options.handle, el)) {
                                return;
                        }
 
+
                        // Prepare `dragstart`
-                       this._prepareDragStart(evt, touch, target, startIndex);
+                       this._prepareDragStart(evt, touch, target);
                },
 
-               _prepareDragStart: function (/** Event */evt, /** Touch */touch, /** HTMLElement */target, /** Number */startIndex) {
+               _prepareDragStart: function (/** Event */evt, /** Touch */touch, /** HTMLElement */target) {
                        var _this = this,
                                el = _this.el,
                                options = _this.options,
                                dragEl = target;
                                parentEl = dragEl.parentNode;
                                nextEl = dragEl.nextSibling;
-                               lastDownEl = target;
                                activeGroup = options.group;
-                               oldIndex = startIndex;
-
-                               this._lastX = (touch || evt).clientX;
-                               this._lastY = (touch || evt).clientY;
-
-                               dragEl.style['will-change'] = 'transform';
 
                                dragStartFn = function () {
                                        // Delayed drag has been triggered
                                        _this._disableDelayedDrag();
 
                                        // Make the element draggable
-                                       dragEl.draggable = _this.nativeDraggable;
+                                       dragEl.draggable = true;
 
                                        // Chosen item
-                                       _toggleClass(dragEl, options.chosenClass, true);
+                                       _toggleClass(dragEl, _this.options.chosenClass, true);
 
                                        // Bind the events: dragstart/dragend
-                                       _this._triggerDragStart(evt, touch);
-
-                                       // Drag start event
-                                       _dispatchEvent(_this, rootEl, 'choose', dragEl, rootEl, oldIndex);
+                                       _this._triggerDragStart(touch);
                                };
 
                                // Disable "draggable"
                                _on(ownerDocument, 'mouseup', _this._onDrop);
                                _on(ownerDocument, 'touchend', _this._onDrop);
                                _on(ownerDocument, 'touchcancel', _this._onDrop);
-                               _on(ownerDocument, 'pointercancel', _this._onDrop);
-                               _on(ownerDocument, 'selectstart', _this);
 
                                if (options.delay) {
                                        // If the user moves the pointer or let go the click or touch
                                        _on(ownerDocument, 'touchcancel', _this._disableDelayedDrag);
                                        _on(ownerDocument, 'mousemove', _this._disableDelayedDrag);
                                        _on(ownerDocument, 'touchmove', _this._disableDelayedDrag);
-                                       _on(ownerDocument, 'pointermove', _this._disableDelayedDrag);
 
                                        _this._dragStartTimer = setTimeout(dragStartFn, options.delay);
                                } else {
                                        dragStartFn();
                                }
-
-
                        }
                },
 
                        _off(ownerDocument, 'touchcancel', this._disableDelayedDrag);
                        _off(ownerDocument, 'mousemove', this._disableDelayedDrag);
                        _off(ownerDocument, 'touchmove', this._disableDelayedDrag);
-                       _off(ownerDocument, 'pointermove', this._disableDelayedDrag);
                },
 
-               _triggerDragStart: function (/** Event */evt, /** Touch */touch) {
-                       touch = touch || (evt.pointerType == 'touch' ? evt : null);
-
+               _triggerDragStart: function (/** Touch */touch) {
                        if (touch) {
                                // Touch device support
                                tapEvt = {
 
                        try {
                                if (document.selection) {
-                                       // Timeout neccessary for IE9
-                                       setTimeout(function () {
-                                               document.selection.empty();
-                                       });
+                                       document.selection.empty();
                                } else {
                                        window.getSelection().removeAllRanges();
                                }
 
                _dragStarted: function () {
                        if (rootEl && dragEl) {
-                               var options = this.options;
-
                                // Apply effect
-                               _toggleClass(dragEl, options.ghostClass, true);
-                               _toggleClass(dragEl, options.dragClass, false);
+                               _toggleClass(dragEl, this.options.ghostClass, true);
 
                                Sortable.active = this;
 
                                // Drag start event
                                _dispatchEvent(this, rootEl, 'start', dragEl, rootEl, oldIndex);
-                       } else {
-                               this._nulling();
                        }
                },
 
 
                                var target = document.elementFromPoint(touchEvt.clientX, touchEvt.clientY),
                                        parent = target,
+                                       groupName = ' ' + this.options.group.name + '',
                                        i = touchDragOverListeners.length;
 
                                if (parent) {
                                        do {
-                                               if (parent[expando]) {
+                                               if (parent[expando] && parent[expando].options.groups.indexOf(groupName) > -1) {
                                                        while (i--) {
                                                                touchDragOverListeners[i]({
                                                                        clientX: touchEvt.clientX,
 
                _onTouchMove: function (/**TouchEvent*/evt) {
                        if (tapEvt) {
-                               var     options = this.options,
-                                       fallbackTolerance = options.fallbackTolerance,
-                                       fallbackOffset = options.fallbackOffset,
-                                       touch = evt.touches ? evt.touches[0] : evt,
-                                       dx = (touch.clientX - tapEvt.clientX) + fallbackOffset.x,
-                                       dy = (touch.clientY - tapEvt.clientY) + fallbackOffset.y,
-                                       translate3d = evt.touches ? 'translate3d(' + dx + 'px,' + dy + 'px,0)' : 'translate(' + dx + 'px,' + dy + 'px)';
-
                                // only set the status to dragging, when we are actually dragging
                                if (!Sortable.active) {
-                                       if (fallbackTolerance &&
-                                               min(abs(touch.clientX - this._lastX), abs(touch.clientY - this._lastY)) < fallbackTolerance
-                                       ) {
-                                               return;
-                                       }
-
                                        this._dragStarted();
                                }
 
                                // as well as creating the ghost element on the document body
                                this._appendGhost();
 
+                               var touch = evt.touches ? evt.touches[0] : evt,
+                                       dx = touch.clientX - tapEvt.clientX,
+                                       dy = touch.clientY - tapEvt.clientY,
+                                       translate3d = evt.touches ? 'translate3d(' + dx + 'px,' + dy + 'px,0)' : 'translate(' + dx + 'px,' + dy + 'px)';
+
                                moved = true;
                                touchEvt = touch;
 
 
                                _toggleClass(ghostEl, options.ghostClass, false);
                                _toggleClass(ghostEl, options.fallbackClass, true);
-                               _toggleClass(ghostEl, options.dragClass, true);
 
                                _css(ghostEl, 'top', rect.top - parseInt(css.marginTop, 10));
                                _css(ghostEl, 'left', rect.left - parseInt(css.marginLeft, 10));
 
                        this._offUpEvents();
 
-                       if (activeGroup.checkPull(this, this, dragEl, evt)) {
-                               cloneEl = _clone(dragEl);
-
-                               cloneEl.draggable = false;
-                               cloneEl.style['will-change'] = '';
-
+                       if (activeGroup.pull == 'clone') {
+                               cloneEl = dragEl.cloneNode(true);
                                _css(cloneEl, 'display', 'none');
-                               _toggleClass(cloneEl, this.options.chosenClass, false);
-
                                rootEl.insertBefore(cloneEl, dragEl);
-                               _dispatchEvent(this, rootEl, 'clone', dragEl);
                        }
 
-                       _toggleClass(dragEl, options.dragClass, true);
-
                        if (useFallback) {
+
                                if (useFallback === 'touch') {
                                        // Bind touch events
                                        _on(document, 'touchmove', this._onTouchMove);
                                        _on(document, 'touchend', this._onDrop);
                                        _on(document, 'touchcancel', this._onDrop);
-                                       _on(document, 'pointermove', this._onTouchMove);
-                                       _on(document, 'pointerup', this._onDrop);
                                } else {
                                        // Old brwoser
                                        _on(document, 'mousemove', this._onTouchMove);
                        var el = this.el,
                                target,
                                dragRect,
-                               targetRect,
                                revert,
                                options = this.options,
                                group = options.group,
-                               activeSortable = Sortable.active,
+                               groupPut = group.put,
                                isOwner = (activeGroup === group),
-                               isMovingBetweenSortable = false,
                                canSort = options.sort;
 
                        if (evt.preventDefault !== void 0) {
                                !options.dragoverBubble && evt.stopPropagation();
                        }
 
-                       if (dragEl.animated) {
-                               return;
-                       }
-
                        moved = true;
 
-                       if (activeSortable && !options.disabled &&
+                       if (activeGroup && !options.disabled &&
                                (isOwner
                                        ? canSort || (revert = !rootEl.contains(dragEl)) // Reverting item into the original list
-                                       : (
-                                               putSortable === this ||
-                                               (
-                                                       (activeSortable.lastPullMode = activeGroup.checkPull(this, activeSortable, dragEl, evt)) &&
-                                                       group.checkPut(this, activeSortable, dragEl, evt)
-                                               )
+                                       : activeGroup.pull && groupPut && (
+                                               (activeGroup.name === group.name) || // by Name
+                                               (groupPut.indexOf && ~groupPut.indexOf(activeGroup.name)) // by Array
                                        )
                                ) &&
                                (evt.rootEl === void 0 || evt.rootEl === this.el) // touch fallback
                                target = _closest(evt.target, options.draggable, el);
                                dragRect = dragEl.getBoundingClientRect();
 
-                               if (putSortable !== this) {
-                                       putSortable = this;
-                                       isMovingBetweenSortable = true;
-                               }
-
                                if (revert) {
-                                       _cloneHide(activeSortable, true);
-                                       parentEl = rootEl; // actualization
+                                       _cloneHide(true);
 
                                        if (cloneEl || nextEl) {
                                                rootEl.insertBefore(dragEl, cloneEl || nextEl);
 
 
                                if ((el.children.length === 0) || (el.children[0] === ghostEl) ||
-                                       (el === evt.target) && (_ghostIsLast(el, evt))
+                                       (el === evt.target) && (target = _ghostIsLast(el, evt))
                                ) {
-                                       //assign target only if condition is true
-                                       if (el.children.length !== 0 && el.children[0] !== ghostEl && el === evt.target) {
-                                               target = el.lastElementChild;
-                                       }
 
                                        if (target) {
                                                if (target.animated) {
                                                targetRect = target.getBoundingClientRect();
                                        }
 
-                                       _cloneHide(activeSortable, isOwner);
+                                       _cloneHide(isOwner);
 
-                                       if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt) !== false) {
+                                       if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect) !== false) {
                                                if (!dragEl.contains(el)) {
                                                        el.appendChild(dragEl);
                                                        parentEl = el; // actualization
                                                lastParentCSS = _css(target.parentNode);
                                        }
 
-                                       targetRect = target.getBoundingClientRect();
 
-                                       var width = targetRect.right - targetRect.left,
+                                       var targetRect = target.getBoundingClientRect(),
+                                               width = targetRect.right - targetRect.left,
                                                height = targetRect.bottom - targetRect.top,
-                                               floating = R_FLOAT.test(lastCSS.cssFloat + lastCSS.display)
+                                               floating = /left|right|inline/.test(lastCSS.cssFloat + lastCSS.display)
                                                        || (lastParentCSS.display == 'flex' && lastParentCSS['flex-direction'].indexOf('row') === 0),
                                                isWide = (target.offsetWidth > dragEl.offsetWidth),
                                                isLong = (target.offsetHeight > dragEl.offsetHeight),
                                                halfway = (floating ? (evt.clientX - targetRect.left) / width : (evt.clientY - targetRect.top) / height) > 0.5,
                                                nextSibling = target.nextElementSibling,
-                                               after = false
+                                               moveVector = _onMove(rootEl, el, dragEl, dragRect, target, targetRect),
+                                               after
                                        ;
 
-                                       if (floating) {
-                                               var elTop = dragEl.offsetTop,
-                                                       tgTop = target.offsetTop;
-
-                                               if (elTop === tgTop) {
-                                                       after = (target.previousElementSibling === dragEl) && !isWide || halfway && isWide;
-                                               }
-                                               else if (target.previousElementSibling === dragEl || dragEl.previousElementSibling === target) {
-                                                       after = (evt.clientY - targetRect.top) / height > 0.5;
-                                               } else {
-                                                       after = tgTop > elTop;
-                                               }
-                                               } else if (!isMovingBetweenSortable) {
-                                               after = (nextSibling !== dragEl) && !isLong || halfway && isLong;
-                                       }
+                                       if (moveVector !== false) {
+                                               _silent = true;
+                                               setTimeout(_unsilent, 30);
 
-                                       var moveVector = _onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, after);
+                                               _cloneHide(isOwner);
 
-                                       if (moveVector !== false) {
                                                if (moveVector === 1 || moveVector === -1) {
                                                        after = (moveVector === 1);
                                                }
+                                               else if (floating) {
+                                                       var elTop = dragEl.offsetTop,
+                                                               tgTop = target.offsetTop;
 
-                                               _silent = true;
-                                               setTimeout(_unsilent, 30);
-
-                                               _cloneHide(activeSortable, isOwner);
+                                                       if (elTop === tgTop) {
+                                                               after = (target.previousElementSibling === dragEl) && !isWide || halfway && isWide;
+                                                       } else {
+                                                               after = tgTop > elTop;
+                                                       }
+                                               } else {
+                                                       after = (nextSibling !== dragEl) && !isLong || halfway && isLong;
+                                               }
 
                                                if (!dragEl.contains(el)) {
                                                        if (after && !nextSibling) {
                        if (ms) {
                                var currentRect = target.getBoundingClientRect();
 
-                               if (prevRect.nodeType === 1) {
-                                       prevRect = prevRect.getBoundingClientRect();
-                               }
-
                                _css(target, 'transition', 'none');
                                _css(target, 'transform', 'translate3d('
                                        + (prevRect.left - currentRect.left) + 'px,'
                        var ownerDocument = this.el.ownerDocument;
 
                        _off(document, 'touchmove', this._onTouchMove);
-                       _off(document, 'pointermove', this._onTouchMove);
                        _off(ownerDocument, 'mouseup', this._onDrop);
                        _off(ownerDocument, 'touchend', this._onDrop);
-                       _off(ownerDocument, 'pointerup', this._onDrop);
                        _off(ownerDocument, 'touchcancel', this._onDrop);
-                       _off(ownerDocument, 'pointercancel', this._onDrop);
-                       _off(ownerDocument, 'selectstart', this);
                },
 
                _onDrop: function (/**Event*/evt) {
                                        !options.dropBubble && evt.stopPropagation();
                                }
 
-                               ghostEl && ghostEl.parentNode && ghostEl.parentNode.removeChild(ghostEl);
-
-                               if (rootEl === parentEl || Sortable.active.lastPullMode !== 'clone') {
-                                       // Remove clone
-                                       cloneEl && cloneEl.parentNode && cloneEl.parentNode.removeChild(cloneEl);
-                               }
+                               ghostEl && ghostEl.parentNode.removeChild(ghostEl);
 
                                if (dragEl) {
                                        if (this.nativeDraggable) {
                                        }
 
                                        _disableDraggable(dragEl);
-                                       dragEl.style['will-change'] = '';
 
                                        // Remove class's
                                        _toggleClass(dragEl, this.options.ghostClass, false);
                                        _toggleClass(dragEl, this.options.chosenClass, false);
 
-                                       // Drag stop event
-                                       _dispatchEvent(this, rootEl, 'unchoose', dragEl, rootEl, oldIndex);
-
                                        if (rootEl !== parentEl) {
-                                               newIndex = _index(dragEl, options.draggable);
+                                               newIndex = _index(dragEl);
 
                                                if (newIndex >= 0) {
+                                                       // drag from one list and drop into another
+                                                       _dispatchEvent(null, parentEl, 'sort', dragEl, rootEl, oldIndex, newIndex);
+                                                       _dispatchEvent(this, rootEl, 'sort', dragEl, rootEl, oldIndex, newIndex);
+
                                                        // Add event
                                                        _dispatchEvent(null, parentEl, 'add', dragEl, rootEl, oldIndex, newIndex);
 
                                                        // Remove event
                                                        _dispatchEvent(this, rootEl, 'remove', dragEl, rootEl, oldIndex, newIndex);
-
-                                                       // drag from one list and drop into another
-                                                       _dispatchEvent(null, parentEl, 'sort', dragEl, rootEl, oldIndex, newIndex);
-                                                       _dispatchEvent(this, rootEl, 'sort', dragEl, rootEl, oldIndex, newIndex);
                                                }
                                        }
                                        else {
+                                               // Remove clone
+                                               cloneEl && cloneEl.parentNode.removeChild(cloneEl);
+
                                                if (dragEl.nextSibling !== nextEl) {
                                                        // Get the index of the dragged element within its parent
-                                                       newIndex = _index(dragEl, options.draggable);
+                                                       newIndex = _index(dragEl);
 
                                                        if (newIndex >= 0) {
                                                                // drag & drop within the same list
                                        }
 
                                        if (Sortable.active) {
-                                               /* jshint eqnull:true */
-                                               if (newIndex == null || newIndex === -1) {
+                                               if (newIndex === null || newIndex === -1) {
                                                        newIndex = oldIndex;
                                                }
 
                                        }
                                }
 
-                       }
-
-                       this._nulling();
-               },
-
-               _nulling: function() {
-                       rootEl =
-                       dragEl =
-                       parentEl =
-                       ghostEl =
-                       nextEl =
-                       cloneEl =
-                       lastDownEl =
+                               // Nulling
+                               rootEl =
+                               dragEl =
+                               parentEl =
+                               ghostEl =
+                               nextEl =
+                               cloneEl =
 
-                       scrollEl =
-                       scrollParentEl =
+                               scrollEl =
+                               scrollParentEl =
 
-                       tapEvt =
-                       touchEvt =
+                               tapEvt =
+                               touchEvt =
 
-                       moved =
-                       newIndex =
+                               moved =
+                               newIndex =
 
-                       lastEl =
-                       lastCSS =
+                               lastEl =
+                               lastCSS =
 
-                       putSortable =
-                       activeGroup =
-                       Sortable.active = null;
-
-                       savedInputChecked.forEach(function (el) {
-                               el.checked = true;
-                       });
-                       savedInputChecked.length = 0;
+                               activeGroup =
+                               Sortable.active = null;
+                       }
                },
 
+
                handleEvent: function (/**Event*/evt) {
-                       switch (evt.type) {
-                               case 'drop':
-                               case 'dragend':
-                                       this._onDrop(evt);
-                                       break;
-
-                               case 'dragover':
-                               case 'dragenter':
-                                       if (dragEl) {
-                                               this._onDragOver(evt);
-                                               _globalDragOver(evt);
-                                       }
-                                       break;
+                       var type = evt.type;
 
-                               case 'selectstart':
-                                       evt.preventDefault();
-                                       break;
+                       if (type === 'dragover' || type === 'dragenter') {
+                               if (dragEl) {
+                                       this._onDragOver(evt);
+                                       _globalDragOver(evt);
+                               }
+                       }
+                       else if (type === 'drop' || type === 'dragend') {
+                               this._onDrop(evt);
                        }
                },
 
 
                        _off(el, 'mousedown', this._onTapStart);
                        _off(el, 'touchstart', this._onTapStart);
-                       _off(el, 'pointerdown', this._onTapStart);
 
                        if (this.nativeDraggable) {
                                _off(el, 'dragover', this);
        };
 
 
-       function _cloneHide(sortable, state) {
-               if (sortable.lastPullMode !== 'clone') {
-                       state = true;
-               }
-
+       function _cloneHide(state) {
                if (cloneEl && (cloneEl.state !== state)) {
                        _css(cloneEl, 'display', state ? 'none' : '');
-
-                       if (!state) {
-                               if (cloneEl.state) {
-                                       if (sortable.options.group.revertClone) {
-                                               rootEl.insertBefore(cloneEl, nextEl);
-                                               sortable._animate(dragEl, cloneEl);
-                                       } else {
-                                               rootEl.insertBefore(cloneEl, dragEl);
-                                       }
-                               }
-                       }
-
+                       !state && cloneEl.state && rootEl.insertBefore(cloneEl, dragEl);
                        cloneEl.state = state;
                }
        }
        function _closest(/**HTMLElement*/el, /**String*/selector, /**HTMLElement*/ctx) {
                if (el) {
                        ctx = ctx || document;
+                       selector = selector.split('.');
+
+                       var tag = selector.shift().toUpperCase(),
+                               re = new RegExp('\\s(' + selector.join('|') + ')(?=\\s)', 'g');
 
                        do {
-                               if ((selector === '>*' && el.parentNode === ctx) || _matches(el, selector)) {
+                               if (
+                                       (tag === '>*' && el.parentNode === ctx) || (
+                                               (tag === '' || el.nodeName.toUpperCase() == tag) &&
+                                               (!selector.length || ((' ' + el.className + ' ').match(re) || []).length == selector.length)
+                                       )
+                               ) {
                                        return el;
                                }
-                               /* jshint boss:true */
-                       } while (el = _getParentOrHost(el));
+                       }
+                       while (el !== ctx && (el = el.parentNode));
                }
 
                return null;
        }
 
 
-       function _getParentOrHost(el) {
-               var parent = el.host;
-
-               return (parent && parent.nodeType) ? parent : el.parentNode;
-       }
-
-
        function _globalDragOver(/**Event*/evt) {
                if (evt.dataTransfer) {
                        evt.dataTransfer.dropEffect = 'move';
 
 
        function _on(el, event, fn) {
-               el.addEventListener(event, fn, captureMode);
+               el.addEventListener(event, fn, false);
        }
 
 
        function _off(el, event, fn) {
-               el.removeEventListener(event, fn, captureMode);
+               el.removeEventListener(event, fn, false);
        }
 
 
                                el.classList[state ? 'add' : 'remove'](name);
                        }
                        else {
-                               var className = (' ' + el.className + ' ').replace(R_SPACE, ' ').replace(' ' + name + ' ', ' ');
-                               el.className = (className + (state ? ' ' + name : '')).replace(R_SPACE, ' ');
+                               var className = (' ' + el.className + ' ').replace(RSPACE, ' ').replace(' ' + name + ' ', ' ');
+                               el.className = (className + (state ? ' ' + name : '')).replace(RSPACE, ' ');
                        }
                }
        }
 
 
        function _dispatchEvent(sortable, rootEl, name, targetEl, fromEl, startIndex, newIndex) {
-               sortable = (sortable || rootEl[expando]);
-
                var evt = document.createEvent('Event'),
-                       options = sortable.options,
+                       options = (sortable || rootEl[expando]).options,
                        onName = 'on' + name.charAt(0).toUpperCase() + name.substr(1);
 
                evt.initEvent(name, true, true);
        }
 
 
-       function _onMove(fromEl, toEl, dragEl, dragRect, targetEl, targetRect, originalEvt, willInsertAfter) {
+       function _onMove(fromEl, toEl, dragEl, dragRect, targetEl, targetRect) {
                var evt,
                        sortable = fromEl[expando],
                        onMoveFn = sortable.options.onMove,
                evt.draggedRect = dragRect;
                evt.related = targetEl || toEl;
                evt.relatedRect = targetRect || toEl.getBoundingClientRect();
-               evt.willInsertAfter = willInsertAfter;
 
                fromEl.dispatchEvent(evt);
 
                if (onMoveFn) {
-                       retVal = onMoveFn.call(sortable, evt, originalEvt);
+                       retVal = onMoveFn.call(sortable, evt);
                }
 
                return retVal;
        /** @returns {HTMLElement|false} */
        function _ghostIsLast(el, evt) {
                var lastEl = el.lastElementChild,
-                       rect = lastEl.getBoundingClientRect();
+                               rect = lastEl.getBoundingClientRect();
 
-               // 5 — min delta
-               // abs — нельзя добавлять, а то глюки при наведении сверху
-               return (evt.clientY - (rect.top + rect.height) > 5) ||
-                       (evt.clientX - (rect.left + rect.width) > 5);
+               return ((evt.clientY - (rect.top + rect.height) > 5) || (evt.clientX - (rect.right + rect.width) > 5)) && lastEl; // min delta
        }
 
 
        }
 
        /**
-        * Returns the index of an element within its parent for a selected set of
-        * elements
+        * Returns the index of an element within its parent
         * @param  {HTMLElement} el
-        * @param  {selector} selector
         * @return {number}
         */
-       function _index(el, selector) {
+       function _index(el) {
                var index = 0;
 
                if (!el || !el.parentNode) {
                }
 
                while (el && (el = el.previousElementSibling)) {
-                       if ((el.nodeName.toUpperCase() !== 'TEMPLATE') && (selector === '>*' || _matches(el, selector))) {
+                       if (el.nodeName.toUpperCase() !== 'TEMPLATE') {
                                index++;
                        }
                }
                return index;
        }
 
-       function _matches(/**HTMLElement*/el, /**String*/selector) {
-               if (el) {
-                       selector = selector.split('.');
-
-                       var tag = selector.shift().toUpperCase(),
-                               re = new RegExp('\\s(' + selector.join('|') + ')(?=\\s)', 'g');
-
-                       return (
-                               (tag === '' || el.nodeName.toUpperCase() == tag) &&
-                               (!selector.length || ((' ' + el.className + ' ').match(re) || []).length == selector.length)
-                       );
-               }
-
-               return false;
-       }
-
        function _throttle(callback, ms) {
                var args, _this;
 
                return dst;
        }
 
-       function _clone(el) {
-               return $
-                       ? $(el).clone(true)[0]
-                       : (Polymer && Polymer.dom
-                               ? Polymer.dom(el).cloneNode(true)
-                               : el.cloneNode(true)
-                       );
-       }
-
-       function _saveInputCheckedState(root) {
-               var inputs = root.getElementsByTagName('input');
-               var idx = inputs.length;
-
-               while (idx--) {
-                       var el = inputs[idx];
-                       el.checked && savedInputChecked.push(el);
-               }
-       }
-
-       // Fixed #973: 
-       _on(document, 'touchmove', function (evt) {
-               if (Sortable.active) {
-                       evt.preventDefault();
-               }
-       });
-
-       try {
-               window.addEventListener('test', null, Object.defineProperty({}, 'passive', {
-                       get: function () {
-                               captureMode = {
-                                       capture: false,
-                                       passive: false
-                               };
-                       }
-               }));
-       } catch (err) {}
 
        // Export utils
        Sortable.utils = {
                throttle: _throttle,
                closest: _closest,
                toggleClass: _toggleClass,
-               clone: _clone,
                index: _index
        };
 
 
 
        // Export
-       Sortable.version = '1.6.0';
+       Sortable.version = '1.4.2';
        return Sortable;
 });