!function(factory){"use strict";"function"==typeof define&&define.amd?define(["angular","./Sortable"],factory):"function"==typeof require&&"object"==typeof exports&&"object"==typeof module?(require("angular"),factory(angular,require("./Sortable")),module.exports="ng-sortable"):window.angular&&window.Sortable&&factory(angular,Sortable)}(function(angular,Sortable){"use strict";var expando="Sortable:ng-sortable";angular.module("ng-sortable",[]).constant("ngSortableVersion","0.4.0").constant("ngSortableConfig",{}).directive("ngSortable",["$parse","ngSortableConfig",function($parse,ngSortableConfig){var removed,nextSibling,getSourceFactory=function(el,scope){var ngRepeat=[].filter.call(el.childNodes,function(node){return 8===node.nodeType&&-1!==node.nodeValue.indexOf("ngRepeat:")})[0];if(!ngRepeat)return function(){return null};ngRepeat=ngRepeat.nodeValue.match(/ngRepeat:\s*(?:\(.*?,\s*)?([^\s)]+)[\s)]+in\s+([^\s|]+)/);var itemsExpr=$parse(ngRepeat[2]);return function(){return itemsExpr(scope.$parent)||[]}};return{restrict:"AC",scope:{ngSortable:"=?"},link:function(scope,$el){function _emitEvent(evt,item){var name="on"+evt.type.charAt(0).toUpperCase()+evt.type.substr(1),source=getSource();options[name]&&options[name]({model:item||source[evt.newIndex],models:source,oldIndex:evt.oldIndex,newIndex:evt.newIndex})}function _sync(evt){var items=getSource();if(items){var oldIndex=evt.oldIndex,newIndex=evt.newIndex;if(el!==evt.from){var prevItems=evt.from[expando]();removed=prevItems[oldIndex],evt.clone?(removed=angular.copy(removed),prevItems.splice(Sortable.utils.index(evt.clone),0,prevItems.splice(oldIndex,1)[0]),evt.from.removeChild(evt.clone)):prevItems.splice(oldIndex,1),items.splice(newIndex,0,removed),evt.from.insertBefore(evt.item,nextSibling)}else items.splice(newIndex,0,items.splice(oldIndex,1)[0]);scope.$apply()}}var sortable,el=$el[0],options=angular.extend(scope.ngSortable||{},ngSortableConfig),watchers=[],getSource=getSourceFactory(el,scope);el[expando]=getSource,sortable=Sortable.create(el,Object.keys(options).reduce(function(opts,name){return opts[name]=opts[name]||options[name],opts},{onStart:function(evt){nextSibling=evt.item.nextSibling,_emitEvent(evt),scope.$apply()},onEnd:function(evt){_emitEvent(evt,removed),scope.$apply()},onAdd:function(evt){_sync(evt),_emitEvent(evt,removed),scope.$apply()},onUpdate:function(evt){_sync(evt),_emitEvent(evt)},onRemove:function(evt){_emitEvent(evt,removed)},onSort:function(evt){_emitEvent(evt)}})),$el.on("$destroy",function(){angular.forEach(watchers,function(unwatch){unwatch()}),sortable.destroy(),el[expando]=null,el=null,watchers=null,sortable=null,nextSibling=null}),angular.forEach(["sort","disabled","draggable","handle","animation","group","ghostClass","filter","onStart","onEnd","onAdd","onUpdate","onRemove","onSort"],function(name){watchers.push(scope.$watch("ngSortable."+name,function(value){void 0!==value&&(options[name]=value,/^on[A-Z]/.test(name)||sortable.option(name,value))}))})}}}])});