class InforDraggable extends HTMLElement{static callbacks={};constructor(){super();this.grabbed_item=null;this.grabbed_copy=null;this.offset_x=0;this.offset_y=0;this.container=null;this.movement_x_delta=0;this.movement_y_delta=0;this.appendStyle();this.onMouseDown=this.onMouseDown.bind(this);this.onMouseMove=this.onMouseMove.bind(this);this.onMouseUp=this.onMouseUp.bind(this)} static get observedAttributes(){return['id','onchange','wire:onchange']} connectedCallback(){if(!this.id){this.id='infor-draggable-'+Math.random().toString(36).substring(2,15)} this.addEventListener('mousedown',this.onMouseDown)} disconnectedCallback(){this.removeEventListener('mousedown',this.onMouseDown)} onMouseDown(event){if(event.button!==0){return} const item=event.target.closest('infor-draggable-item');if(!item){return} const parent=item.parentElement;if(parent.tagName!=='INFOR-DRAGGABLE'||parent!==this){return} event.preventDefault();event.stopPropagation();const container=parent const rect=item.getBoundingClientRect();this.offset_x=event.clientX-rect.left;this.offset_y=event.clientY-rect.top;this.container=container;this.grabbed_item=item;document.addEventListener('mousemove',this.onMouseMove);document.addEventListener('mouseup',this.onMouseUp);this.current_values=this.values;this.createDraggableCopy() this.updateDraggableCopyPosition(event)} onMouseMove(event){this.setMoveDelta(event);this.updateDraggableCopyPosition(event);this.placeItemIntoBestPosition()} onMouseUp(){document.removeEventListener('mousemove',this.onMouseMove);document.removeEventListener('mouseup',this.onMouseUp);this.destroyDraggableCopy();if(this.valuesChanged()){this.callback(this.values,this.id);this.onchange(this.values,this.id);this.livewireCallback(this.values,this.id)}} appendStyle(){if(InforDraggable.style_appended){return} InforDraggable.style_appended=!0;const style=document.createElement('style');style.textContent=` infor-draggable{ position: relative; display: flex; flex-direction: column; gap: .5rem; } infor-draggable-item{ display: block; cursor: grab; } `;document.head.appendChild(style)} get values(){return this.items.map(el=>el.value)} get items(){return Array.from(this.children).filter(el=>{return el.tagName==='INFOR-DRAGGABLE-ITEM'&&!el.hasAttribute('data-copy')})} set current_values(values){this._current_values=values} get current_values(){return this._current_values} valuesChanged(){return JSON.stringify(this.current_values)!==JSON.stringify(this.values)} get id(){return this.getAttribute('id')} set id(id){this.setAttribute('id',id)} get callback(){return InforDraggable.callbacks[this.id]||((values)=>{})} get onchange(){const onchange=this.getAttribute('onchange');if(!onchange||typeof window[onchange]!=='function'){return(values)=>{}} return window[onchange]} get livewireCallback(){const onchange=this.getAttribute('wire:onchange');if(!window.Livewire||!onchange){return(values)=>{}} return(values,id)=>{window.Livewire.emit(onchange,values,id)}} setMoveDelta(event){this.movement_x_delta=event.movementX;this.movement_y_delta=event.movementY} createDraggableCopy(){const copy=this.grabbed_item.cloneNode(!0);const rect=this.grabbed_item.getBoundingClientRect();const width=rect.width;const height=rect.height;copy.style.position='absolute';copy.style.width=`${width}px`;copy.style.height=`${height}px`;copy.style.cursor='grabbing';copy.setAttribute('data-copy','true');this.container.appendChild(copy);this.grabbed_copy=copy;this.grabbed_item.style.opacity='0'} destroyDraggableCopy(){this.grabbed_copy.remove();this.grabbed_copy=null;this.grabbed_item.style.opacity='1'} updateDraggableCopyPosition(event){const container_rect=this.container.getBoundingClientRect();const container_left=container_rect.left+window.scrollX;const container_top=container_rect.top+window.scrollY;const container_width=this.container.clientWidth;const container_height=this.container.clientHeight;const container_style=getComputedStyle(this.container);const container_padding_left=parseFloat(container_style.paddingLeft);const container_padding_top=parseFloat(container_style.paddingTop);const item_rect=this.grabbed_item.getBoundingClientRect();const item_width=item_rect.width;const item_height=item_rect.height;let x=event.pageX-container_left-this.offset_x;let y=event.pageY-container_top-this.offset_y;if(x+item_width>container_width+container_padding_left){x=container_width-item_width+container_padding_left}else if(xcontainer_height+container_padding_top){y=container_height-item_height+container_padding_top}else if(yel!==this.grabbed_item);const copy_bounding_rect=this.grabbed_copy.getBoundingClientRect();if(this.movement_y_delta<0){items=items.reverse()} items.forEach((item,index)=>{const item_bounding_rect=item.getBoundingClientRect();const distance_below=Math.abs(copy_bounding_rect.bottom-item_bounding_rect.top);const distance_above=Math.abs(copy_bounding_rect.top-item_bounding_rect.bottom);if(this.movement_y_delta>0&©_bounding_rect.bottom>item_bounding_rect.top&&distance_below>5){item.after(this.grabbed_item)} if(this.movement_y_delta<0&©_bounding_rect.top5){item.before(this.grabbed_item)}})} static onChange(id,callback){InforDraggable.callbacks[id]=callback} static values(id){return document.getElementById(id).values}} class InforDraggableItem extends HTMLElement{constructor(){super()} static get observedAttributes(){return['value']} get value(){return this.getAttribute('value')} set value(val){this.setAttribute('value',val)}} customElements.define('infor-draggable',InforDraggable);customElements.define('infor-draggable-item',InforDraggableItem)