var Droppables={drops:[],remove:function(element){this.drops=this.drops.reject(function(d){return d.element==$(element)})},add:function(element){element=$(element);var options=Object.extend({greedy:true,hoverclass:null},arguments[1]||{});if(options.containment){options._containers=[];var containment=options.containment;if((typeof containment=='object')&&(containment.constructor==Array)){containment.each(function(c){options._containers.push($(c))})}else{options._containers.push($(containment))}}if(options.accept)options.accept=[options.accept].flatten();Element.makePositioned(element);options.element=element;this.drops.push(options)},isContained:function(element,drop){var parentNode=element.parentNode;return drop._containers.detect(function(c){return parentNode==c})},isAffected:function(point,element,drop){return((drop.element!=element)&&((!drop._containers)||this.isContained(element,drop))&&((!drop.accept)||(Element.classNames(element).detect(function(v){return drop.accept.include(v)})))&&Position.within(drop.element,point[0],point[1]))},deactivate:function(drop){if(drop.hoverclass)Element.removeClassName(drop.element,drop.hoverclass);this.last_active=null},activate:function(drop){if(drop.hoverclass)Element.addClassName(drop.element,drop.hoverclass);this.last_active=drop},show:function(point,element){if(!this.drops.length)return;if(this.last_active)this.deactivate(this.last_active);this.drops.each(function(drop){if(Droppables.isAffected(point,element,drop)){if(drop.onHover)drop.onHover(element,drop.element,Position.overlap(drop.overlap,drop.element));if(drop.greedy){Droppables.activate(drop);throw $break;}}})},fire:function(event,element){if(!this.last_active)return;Position.prepare();if(this.isAffected([Event.pointerX(event),Event.pointerY(event)],element,this.last_active))if(this.last_active.onDrop)this.last_active.onDrop(element,this.last_active.element,event)},reset:function(){if(this.last_active)this.deactivate(this.last_active)}}var Draggables={drags:[],observers:[],register:function(draggable){if(this.drags.length==0){this.eventMouseUp=this.endDrag.bindAsEventListener(this);this.eventMouseMove=this.updateDrag.bindAsEventListener(this);this.eventKeypress=this.keyPress.bindAsEventListener(this);Event.observe(document,"mouseup",this.eventMouseUp);Event.observe(document,"mousemove",this.eventMouseMove);Event.observe(document,"keypress",this.eventKeypress)}this.drags.push(draggable)},unregister:function(draggable){this.drags=this.drags.reject(function(d){return d==draggable});if(this.drags.length==0){Event.stopObserving(document,"mouseup",this.eventMouseUp);Event.stopObserving(document,"mousemove",this.eventMouseMove);Event.stopObserving(document,"keypress",this.eventKeypress)}},activate:function(draggable){window.focus();this.activeDraggable=draggable},deactivate:function(){this.activeDraggable=null},updateDrag:function(event){if(!this.activeDraggable)return;var pointer=[Event.pointerX(event),Event.pointerY(event)];if(this._lastPointer&&(this._lastPointer.inspect()==pointer.inspect()))return;this._lastPointer=pointer;this.activeDraggable.updateDrag(event,pointer)},endDrag:function(event){if(!this.activeDraggable)return;this._lastPointer=null;this.activeDraggable.endDrag(event);this.activeDraggable=null},keyPress:function(event){if(this.activeDraggable)this.activeDraggable.keyPress(event)},addObserver:function(observer){this.observers.push(observer);this._cacheObserverCallbacks()},removeObserver:function(element){this.observers=this.observers.reject(function(o){return o.element==element});this._cacheObserverCallbacks()},notify:function(eventName,draggable,event){if(this[eventName+'Count']>0)this.observers.each(function(o){if(o[eventName])o[eventName](eventName,draggable,event)})},_cacheObserverCallbacks:function(){['onStart','onEnd','onDrag'].each(function(eventName){Draggables[eventName+'Count']=Draggables.observers.select(function(o){return o[eventName]}).length})}}var Draggable=Class.create();Draggable.prototype={initialize:function(element){var options=Object.extend({handle:false,starteffect:function(element){new Effect.Opacity(element,{duration:0.2,from:1.0,to:0.7})},reverteffect:function(element,top_offset,left_offset){var dur=Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*0.02;element._revert=new Effect.Move(element,{x:-left_offset,y:-top_offset,duration:dur})},endeffect:function(element){new Effect.Opacity(element,{duration:0.2,from:0.7,to:1.0})},zindex:1000,revert:false,scroll:false,scrollSensitivity:20,scrollSpeed:15,snap:false},arguments[1]||{});this.element=$(element);if(options.handle&&(typeof options.handle=='string'))this.handle=Element.childrenWithClassName(this.element,options.handle)[0];if(!this.handle)this.handle=$(options.handle);if(!this.handle)this.handle=this.element;if(options.scroll)options.scroll=$(options.scroll);Element.makePositioned(this.element);this.delta=this.currentDelta();this.options=options;this.dragging=false;this.eventMouseDown=this.initDrag.bindAsEventListener(this);Event.observe(this.handle,"mousedown",this.eventMouseDown);Draggables.register(this)},destroy:function(){Event.stopObserving(this.handle,"mousedown",this.eventMouseDown);Draggables.unregister(this)},currentDelta:function(){return([parseInt(Element.getStyle(this.element,'left')||'0'),parseInt(Element.getStyle(this.element,'top')||'0')])},initDrag:function(event){if(Event.isLeftClick(event)){var src=Event.element(event);if(src.tagName&&(src.tagName=='INPUT'||src.tagName=='SELECT'||src.tagName=='OPTION'||src.tagName=='BUTTON'||src.tagName=='TEXTAREA'))return;if(this.element._revert){this.element._revert.cancel();this.element._revert=null}var pointer=[Event.pointerX(event),Event.pointerY(event)];var pos=Position.cumulativeOffset(this.element);this.offset=[0,1].map(function(i){return(pointer[i]-pos[i])});Draggables.activate(this);Event.stop(event)}},startDrag:function(event){this.dragging=true;if(this.options.zindex){this.originalZ=parseInt(Element.getStyle(this.element,'z-index')||0);this.element.style.zIndex=this.options.zindex}if(this.options.ghosting){this._clone=this.element.cloneNode(true);Position.absolutize(this.element);this.element.parentNode.insertBefore(this._clone,this.element)}if(this.options.scroll){this.originalScrollLeft=this.options.scroll.scrollLeft;this.originalScrollTop=this.options.scroll.scrollTop}Draggables.notify('onStart',this,event);if(this.options.starteffect)this.options.starteffect(this.element)},updateDrag:function(event,pointer){if(!this.dragging)this.startDrag(event);Position.prepare();Droppables.show(pointer,this.element);Draggables.notify('onDrag',this,event);this.draw(pointer);if(this.options.change)this.options.change(this);if(this.options.scroll){this.stopScrolling();var p=Position.page(this.options.scroll);p[0]+=this.options.scroll.scrollLeft;p[1]+=this.options.scroll.scrollTop;p.push(p[0]+this.options.scroll.offsetWidth);p.push(p[1]+this.options.scroll.offsetHeight);var speed=[0,0];if(pointer[0]<(p[0]+this.options.scrollSensitivity))speed[0]=pointer[0]-(p[0]+this.options.scrollSensitivity);if(pointer[1]<(p[1]+this.options.scrollSensitivity))speed[1]=pointer[1]-(p[1]+this.options.scrollSensitivity);if(pointer[0]>(p[2]-this.options.scrollSensitivity))speed[0]=pointer[0]-(p[2]-this.options.scrollSensitivity);if(pointer[1]>(p[3]-this.options.scrollSensitivity))speed[1]=pointer[1]-(p[3]-this.options.scrollSensitivity);this.startScrolling(speed)}if(navigator.appVersion.indexOf('AppleWebKit')>0)window.scrollBy(0,0);Event.stop(event)},finishDrag:function(event,success){this.dragging=false;if(this.options.ghosting){Position.relativize(this.element);Element.remove(this._clone);this._clone=null}if(success)Droppables.fire(event,this.element);Draggables.notify('onEnd',this,event);var revert=this.options.revert;if(revert&&typeof revert=='function')revert=revert(this.element);var d=this.currentDelta();if(revert&&this.options.reverteffect){this.options.reverteffect(this.element,d[1]-this.delta[1],d[0]-this.delta[0])}else{this.delta=d}if(this.options.zindex)this.element.style.zIndex=this.originalZ;if(this.options.endeffect)this.options.endeffect(this.element);Draggables.deactivate(this);Droppables.reset()},keyPress:function(event){if(event.keyCode!=Event.KEY_ESC)return;this.finishDrag(event,false);Event.stop(event)},endDrag:function(event){if(!this.dragging)return;this.stopScrolling();this.finishDrag(event,true);Event.stop(event)},draw:function(point){var pos=Position.cumulativeOffset(this.element);var d=this.currentDelta();pos[0]-=d[0];pos[1]-=d[1];if(this.options.scroll){pos[0]-=this.options.scroll.scrollLeft-this.originalScrollLeft;pos[1]-=this.options.scroll.scrollTop-this.originalScrollTop}var p=[0,1].map(function(i){return(point[i]-pos[i]-this.offset[i])}.bind(this));if(this.options.snap){if(typeof this.options.snap=='function'){p=this.options.snap(p[0],p[1])}else{if(this.options.snap instanceof Array){p=p.map(function(v,i){return Math.round(v/this.options.snap[i])*this.options.snap[i]}.bind(this))}else{p=p.map(function(v){return Math.round(v/this.options.snap)*this.options.snap}.bind(this))}}}var style=this.element.style;if((!this.options.constraint)||(this.options.constraint=='horizontal'))style.left=p[0]+"px";if((!this.options.constraint)||(this.options.constraint=='vertical'))style.top=p[1]+"px";if(style.visibility=="hidden")style.visibility=""},stopScrolling:function(){if(this.scrollInterval){clearInterval(this.scrollInterval);this.scrollInterval=null}},startScrolling:function(speed){this.scrollSpeed=[speed[0]*this.options.scrollSpeed,speed[1]*this.options.scrollSpeed];this.lastScrolled=new Date();this.scrollInterval=setInterval(this.scroll.bind(this),10)},scroll:function(){var current=new Date();var delta=current-this.lastScrolled;this.lastScrolled=current;this.options.scroll.scrollLeft+=this.scrollSpeed[0]*delta/1000;this.options.scroll.scrollTop+=this.scrollSpeed[1]*delta/1000;Position.prepare();Droppables.show(Draggables._lastPointer,this.element);Draggables.notify('onDrag',this);this.draw(Draggables._lastPointer);if(this.options.change)this.options.change(this)}}var SortableObserver=Class.create();SortableObserver.prototype={initialize:function(element,observer){this.element=$(element);this.observer=observer;this.lastValue=Sortable.serialize(this.element)},onStart:function(){this.lastValue=Sortable.serialize(this.element)},onEnd:function(){Sortable.unmark();if(this.lastValue!=Sortable.serialize(this.element))this.observer(this.element)}}var Sortable={sortables:new Array(),options:function(element){element=$(element);return this.sortables.detect(function(s){return s.element==element})},destroy:function(element){element=$(element);this.sortables.findAll(function(s){return s.element==element}).each(function(s){Draggables.removeObserver(s.element);s.droppables.each(function(d){Droppables.remove(d)});s.draggables.invoke('destroy')});this.sortables=this.sortables.reject(function(s){return s.element==element})},create:function(element){element=$(element);var options=Object.extend({element:element,tag:'li',dropOnEmpty:false,tree:false,overlap:'vertical',constraint:'vertical',containment:element,handle:false,only:false,hoverclass:null,ghosting:false,scroll:false,format:/^[^_]*_(.*)$/,onChange:Prototype.emptyFunction,onUpdate:Prototype.emptyFunction},arguments[1]||{});this.destroy(element);var options_for_draggable={revert:true,scroll:options.scroll,ghosting:options.ghosting,constraint:options.constraint,handle:options.handle};if(options.starteffect)options_for_draggable.starteffect=options.starteffect;if(options.reverteffect)options_for_draggable.reverteffect=options.reverteffect;else if(options.ghosting)options_for_draggable.reverteffect=function(element){element.style.top=0;element.style.left=0};if(options.endeffect)options_for_draggable.endeffect=options.endeffect;if(options.zindex)options_for_draggable.zindex=options.zindex;var options_for_droppable={overlap:options.overlap,containment:options.containment,hoverclass:options.hoverclass,onHover:Sortable.onHover,greedy:!options.dropOnEmpty}Element.cleanWhitespace(element);options.draggables=[];options.droppables=[];if(options.dropOnEmpty){Droppables.add(element,{containment:options.containment,onHover:Sortable.onEmptyHover,greedy:false});options.droppables.push(element)}(this.findElements(element,options)||[]).each(function(e){var handle=options.handle?Element.childrenWithClassName(e,options.handle)[0]:e;options.draggables.push(new Draggable(e,Object.extend(options_for_draggable,{handle:handle})));Droppables.add(e,options_for_droppable);options.droppables.push(e)});this.sortables.push(options);Draggables.addObserver(new SortableObserver(element,options.onUpdate))},findElements:function(element,options){if(!element.hasChildNodes())return null;var elements=[];$A(element.childNodes).each(function(e){if(e.tagName&&e.tagName.toUpperCase()==options.tag.toUpperCase()&&(!options.only||(Element.hasClassName(e,options.only))))elements.push(e);if(options.tree){var grandchildren=this.findElements(e,options);if(grandchildren)elements.push(grandchildren)}});return(elements.length>0?elements.flatten():null)},onHover:function(element,dropon,overlap){if(overlap>0.5){Sortable.mark(dropon,'before');if(dropon.previousSibling!=element){var oldParentNode=element.parentNode;element.style.visibility="hidden";dropon.parentNode.insertBefore(element,dropon);if(dropon.parentNode!=oldParentNode)Sortable.options(oldParentNode).onChange(element);Sortable.options(dropon.parentNode).onChange(element)}}else{Sortable.mark(dropon,'after');var nextElement=dropon.nextSibling||null;if(nextElement!=element){var oldParentNode=element.parentNode;element.style.visibility="hidden";dropon.parentNode.insertBefore(element,nextElement);if(dropon.parentNode!=oldParentNode)Sortable.options(oldParentNode).onChange(element);Sortable.options(dropon.parentNode).onChange(element)}}},onEmptyHover:function(element,dropon){if(element.parentNode!=dropon){var oldParentNode=element.parentNode;dropon.appendChild(element);Sortable.options(oldParentNode).onChange(element);Sortable.options(dropon).onChange(element)}},unmark:function(){if(Sortable._marker)Element.hide(Sortable._marker)},mark:function(dropon,position){var sortable=Sortable.options(dropon.parentNode);if(sortable&&!sortable.ghosting)return;if(!Sortable._marker){Sortable._marker=$('dropmarker')||document.createElement('DIV');Element.hide(Sortable._marker);Element.addClassName(Sortable._marker,'dropmarker');Sortable._marker.style.position='absolute';document.getElementsByTagName("body").item(0).appendChild(Sortable._marker)}var offsets=Position.cumulativeOffset(dropon);Sortable._marker.style.left=offsets[0]+'px';Sortable._marker.style.top=offsets[1]+'px';if(position=='after')if(sortable.overlap=='horizontal')Sortable._marker.style.left=(offsets[0]+dropon.clientWidth)+'px';else Sortable._marker.style.top=(offsets[1]+dropon.clientHeight)+'px';Element.show(Sortable._marker)},sequence:function(element){element=$(element);var options=Object.extend(this.options(element),arguments[1]||{});return $(this.findElements(element,options)||[]).map(function(item){return item.id.match(options.format)?item.id.match(options.format)[1]:''})},setSequence:function(element,new_sequence){element=$(element);var options=Object.extend(this.options(element),arguments[2]||{});var nodeMap={};this.findElements(element,options).each(function(n){if(n.id.match(options.format))nodeMap[n.id.match(options.format)[1]]=[n,n.parentNode];n.parentNode.removeChild(n)});new_sequence.each(function(ident){var n=nodeMap[ident];if(n){n[1].appendChild(n[0]);delete nodeMap[ident]}})},serialize:function(element){element=$(element);var name=encodeURIComponent((arguments[1]&&arguments[1].name)?arguments[1].name:element.id);return Sortable.sequence(element,arguments[1]).map(function(item){return name+"[]="+encodeURIComponent(item)}).join('&')}}