@timlassiter11/yatl 0.1.8 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- "use strict";var yatl=(()=>{var bt=Object.defineProperty;var Yt=Object.getOwnPropertyDescriptor;var Zt=Object.getOwnPropertyNames,_t=Object.getOwnPropertySymbols;var $t=Object.prototype.hasOwnProperty,Qt=Object.prototype.propertyIsEnumerable;var Wt=d=>{throw TypeError(d)};var Nt=(d,n,e)=>n in d?bt(d,n,{enumerable:!0,configurable:!0,writable:!0,value:e}):d[n]=e,et=(d,n)=>{for(var e in n||(n={}))$t.call(n,e)&&Nt(d,e,n[e]);if(_t)for(var e of _t(n))Qt.call(n,e)&&Nt(d,e,n[e]);return d};var te=(d,n)=>{for(var e in n)bt(d,e,{get:n[e],enumerable:!0})},ee=(d,n,e,s)=>{if(n&&typeof n=="object"||typeof n=="function")for(let r of Zt(n))!$t.call(d,r)&&r!==e&&bt(d,r,{get:()=>n[r],enumerable:!(s=Yt(n,r))||s.enumerable});return d};var re=d=>ee(bt({},"__esModule",{value:!0}),d);var Dt=(d,n,e)=>n.has(d)||Wt("Cannot "+e);var t=(d,n,e)=>(Dt(d,n,"read from private field"),e?e.call(d):n.get(d)),c=(d,n,e)=>n.has(d)?Wt("Cannot add the same private member more than once"):n instanceof WeakSet?n.add(d):n.set(d,e),u=(d,n,e,s)=>(Dt(d,n,"write to private field"),s?s.call(d,e):n.set(d,e),e),f=(d,n,e)=>(Dt(d,n,"access private method"),e);var Ht=(d,n,e,s)=>({set _(r){u(d,n,r,e)},get _(){return t(d,n,s)}});var se={};te(se,{DataTable:()=>Rt,LocalStorageAdapter:()=>Pt});var x=d=>{if(typeof d=="string"&&d!=="")return d.split(" ");if(Array.isArray(d))return d;if(!d)return[];throw new TypeError("classes must be string or array of strings")},Ut=d=>d.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,n=>n.toUpperCase()),jt=d=>String(d).toLowerCase().replace(/[^\w\s]/g," ").trim().split(/\s+/);var ot,H,S,rt,$,W,at,X,Y,lt,dt,ht,wt,Xt,it=class it{constructor({container:n,element:e,generator:s,nodePadding:r=10}){c(this,wt);c(this,H);c(this,S);c(this,rt);c(this,$,0);c(this,W,0);c(this,at,2);c(this,X,0);c(this,Y,!1);c(this,lt,0);c(this,dt,()=>{t(this,H).scrollTop!==t(this,lt)&&(u(this,lt,t(this,H).scrollTop),t(this,X)&&cancelAnimationFrame(t(this,X)),u(this,X,requestAnimationFrame(()=>this.renderChunk())))});c(this,ht,()=>{this.renderChunk()});u(this,H,n),u(this,S,e),u(this,rt,s),u(this,at,r),new IntersectionObserver(o=>{for(let h of o)h.intersectionRatio===1&&this.renderChunk()}).observe(t(this,S))}get rowHeight(){return t(this,W)||f(this,wt,Xt).call(this),t(this,W)}get started(){return t(this,Y)}scrollToIndex(n){if(n<0||n>=t(this,$))throw new RangeError("Index out of bounds.");this.scrollToPx(this.rowHeight*n)}scrollToPx(n){t(this,H).scrollTop=n,this.renderChunk()}start(n){t(this,Y)||(t(this,H).addEventListener("scroll",t(this,dt)),window.addEventListener("resize",t(this,ht)),u(this,Y,!0)),t(this,H).classList.add("dt-virtual-scroll"),u(this,$,n),this.renderChunk()}stop(){t(this,X)&&cancelAnimationFrame(t(this,X)),t(this,H).classList.remove("dt-virtual-scroll"),t(this,H).removeEventListener("scroll",t(this,dt)),window.removeEventListener("resize",t(this,ht)),u(this,Y,!1)}renderChunk(){let n=t(this,H).scrollTop,e=t(this,$),s=this.rowHeight,r=t(this,at);if(!this.started||!t(this,S).checkVisibility()||!e||!s)return;let i=s*e;t(this,S).innerHTML=`<div style="height: ${i}px;"></div>`;let o=t(this,S).offsetHeight,h=t(this,H).offsetHeight;!t(it,ot)&&o<Math.round(i-1)&&(u(it,ot,!0),console.error("Max element height exceeded. Virtual scroll may not work."));let a=Math.floor(n/s)-r;a=Math.max(0,a);let m=Math.ceil(h/s)+2*r;m=Math.min(e-a,m),a%2===1&&a--;let b=a*s,L=i-(b+m*s);try{t(this,S).innerHTML="";let F=new Array(m).fill(null).map((N,gt)=>t(this,rt).call(this,gt+a)),V=document.createElement("div"),D=document.createElement("div");V.style.visibility="hidden",V.style.height=b+"px",D.style.visibility="hidden",D.style.height=L+"px",t(this,S).append(V),t(this,S).append(...F),t(this,S).append(D)}catch(F){F instanceof RangeError&&console.log(F)}}};ot=new WeakMap,H=new WeakMap,S=new WeakMap,rt=new WeakMap,$=new WeakMap,W=new WeakMap,at=new WeakMap,X=new WeakMap,Y=new WeakMap,lt=new WeakMap,dt=new WeakMap,ht=new WeakMap,wt=new WeakSet,Xt=function(){if(t(this,$)===0||!t(this,S).checkVisibility()){u(this,W,0);return}let e=Math.min(1e3,t(this,$)),s=[];for(let r=0;r<e;++r)s.push(t(this,rt).call(this,r));if(t(this,S).innerHTML="",t(this,S).append(...s),u(this,W,t(this,S).offsetHeight/e),t(this,W)<=0)throw new nt(`First ${e} rows had no rendered height. Virtual scroll can't be used.`);t(this,W)*t(this,$)>33554400&&console.warn("Virtual scroll height exceeded maximum known element height.")},c(it,ot,!1);var vt=it,nt=class extends Error{constructor(n){super(n)}};var E,P,k,y,v,M,C,_,G,O,ft,A,I,p,U,l,Gt,Et,zt,Kt,q,Bt,yt,ct,Tt,At,Jt,It,ut,Vt,Ct,mt,pt,Lt,xt,St,Ot,kt,Mt,Ft,z=class z extends EventTarget{constructor(e,s={}){var a,m,b,L,F,V,D,N,gt;super();c(this,l);c(this,E);c(this,P);c(this,k);c(this,y);c(this,v,new Map);c(this,M,new Map);c(this,C,[]);c(this,_);c(this,G);c(this,O);c(this,ft,0);c(this,A);c(this,I);c(this,p);c(this,U,!1);c(this,Ct,e=>{if(!(e.target instanceof HTMLElement)||!e.target.classList.contains("dt-resizer")||!(e.currentTarget instanceof HTMLElement)||!e.currentTarget.dataset.dtField)return;e.stopImmediatePropagation(),e.preventDefault();let s=e.currentTarget.dataset.dtField,r=t(this,v).get(s);r&&(u(this,I,r),r.resizeStartX=e.clientX,r.resizeStartWidth=r.header.offsetWidth,document.addEventListener("mousemove",t(this,mt)),document.addEventListener("mouseup",t(this,pt)))});c(this,mt,e=>{if(!t(this,I))return;e.stopImmediatePropagation(),e.preventDefault();let s=e.clientX-t(this,I).resizeStartX,r=t(this,I).resizeStartWidth+s;f(this,l,Vt).call(this,t(this,I),r)});c(this,pt,e=>{if(!t(this,I))return;e.stopImmediatePropagation(),e.preventDefault(),document.removeEventListener("mousemove",t(this,mt)),document.removeEventListener("mouseup",t(this,pt));let s=new CustomEvent("dt.col.resize",{cancelable:!1,detail:{column:t(this,I).field,width:t(this,I).header.offsetWidth}});this.dispatchEvent(s),u(this,I,void 0)});c(this,Lt,e=>{if(!(e.target instanceof HTMLElement)||!e.target.classList.contains("dt-resizer")||!(e.currentTarget instanceof HTMLElement)||!e.currentTarget.dataset.dtField)return;let s=e.currentTarget.dataset.dtField;s&&f(this,l,Vt).call(this,s)});c(this,xt,e=>{let r=e.target.dataset.dtField;e.dataTransfer&&r&&(e.dataTransfer.effectAllowed="move",e.dataTransfer.setData("text/plain",r))});c(this,St,e=>(e.preventDefault(),e.dataTransfer&&(e.dataTransfer.dropEffect="move"),!1));c(this,Ot,e=>{e.target.classList.add("dt-drag-over")});c(this,kt,e=>{e.target.classList.remove("dt-drag-over")});c(this,Mt,e=>{var m;let s=(m=e.dataTransfer)==null?void 0:m.getData("text/plain"),i=e.currentTarget.dataset.dtField;if(!s||!i)return;e.preventDefault(),e.stopPropagation();let o=[...t(this,v).values()],h=o.findIndex(b=>b.field===s),a=o.findIndex(b=>b.field===i);if(h>-1&&a>-1){let[b]=o.splice(h,1),L=t(this,v).get(i);if(!L)return;o.splice(a,0,b);let F=o.map(D=>D.field),V=new CustomEvent("dt.col.reorder",{cancelable:!0,detail:{draggedColumn:b.field,dropColumn:L.field,order:F}});if(!this.dispatchEvent(V))return;this.setColumnOrder(F)}});c(this,Ft,()=>{let e=document.querySelectorAll(".dt-drag-over");for(let s of e)s.classList.remove("dt-drag-over")});if(u(this,p,et(et({columns:[],data:[]},z.DEFAULT_OPTIONS),s)),typeof e=="string"){let g=document.querySelector(e);if(!g)throw new SyntaxError(`Failed to find table using selector ${e}`);u(this,E,g)}else u(this,E,e);if(!(t(this,E)instanceof HTMLTableElement))throw new TypeError("Invalid table element type. Must be HTMLTableElement");if(!Array.isArray(t(this,p).columns))throw new TypeError("columns must be a list of columns");u(this,A,{scroller:[...x(t(this,p).classes.scroller),...x(z.DEFAULT_OPTIONS.classes.scroller)],thead:[...x(t(this,p).classes.thead),...x(z.DEFAULT_OPTIONS.classes.thead)],tbody:[...x(t(this,p).classes.tbody),...x(z.DEFAULT_OPTIONS.classes.tbody)],tfoot:[...x(t(this,p).classes.tfoot),...x(z.DEFAULT_OPTIONS.classes.tfoot)],tr:[...x(t(this,p).classes.tr),...x(z.DEFAULT_OPTIONS.classes.tr)],th:[...x(t(this,p).classes.th),...x(z.DEFAULT_OPTIONS.classes.th)],td:[...x(t(this,p).classes.td),...x(z.DEFAULT_OPTIONS.classes.td)],mark:[...x(t(this,p).classes.mark),...x(z.DEFAULT_OPTIONS.classes.mark)]}),t(this,E).classList.add("data-table"),u(this,y,document.createElement("div")),t(this,y).classList.add(...t(this,A).scroller),t(this,y).style.overflow="auto",t(this,y).style.height="100%",t(this,E).style.height!==""&&(t(this,y).style.height=t(this,E).style.height,t(this,E).style.height=""),(a=t(this,E).parentElement)==null||a.insertBefore(t(this,y),t(this,E)),t(this,y).append(t(this,E)),t(this,E).querySelectorAll("thead").length>1&&console.warn("Multiple theads found in table. Using last one."),t(this,E).querySelectorAll("tbody").length>1&&console.warn("Multiple tbodys found in table. Using first one.");let r=t(this,E).querySelector("thead:last-of-type");r?u(this,P,r):(u(this,P,document.createElement("thead")),t(this,E).insertBefore(t(this,P),t(this,E).firstChild)),t(this,P).classList.add(...t(this,A).thead);let i=t(this,P).querySelector("tr:last-of-type");i||(i=document.createElement("tr"),t(this,P).append(i)),i.classList.add(...t(this,A).tr),i.innerHTML="";let o=t(this,E).querySelector("tbody:first-of-type");o?u(this,k,o):(u(this,k,document.createElement("tbody")),t(this,E).append(t(this,k))),t(this,k).classList.add(...t(this,A).tbody),t(this,k).addEventListener("click",g=>{var j;if((j=window.getSelection())!=null&&j.toString())return;let T,w,B;if(g.target instanceof HTMLTableCellElement?(w=g.target,T=w.parentElement,B=w.dataset.dtField):g.target instanceof HTMLTableRowElement&&(T=g.target),T){let J=parseInt(T.dataset.dtIndex||"");if(!isNaN(J)){let st=t(this,C).find(tt=>tt._metadata.index===J);if(st){let tt=new CustomEvent("dt.row.clicked",{cancelable:!1,detail:{row:st,index:J,column:B,originalEvent:g}});this.dispatchEvent(tt)}}}});let h=!1;for(let g of t(this,p).columns){let T={field:g.field,title:g.title||Ut(g.field),header:document.createElement("th"),headerContent:document.createElement("div"),visible:(m=g.visible)!=null?m:!0,sortable:(b=g.sortable)!=null?b:t(this,p).sortable,searchable:(L=g.searchable)!=null?L:t(this,p).searchable,tokenize:(F=g.tokenize)!=null?F:t(this,p).tokenize,sortOrder:(V=g.sortOrder)!=null?V:null,sortPriority:(D=g.sortPriority)!=null?D:0,resizeStartWidth:null,resizeStartX:null,valueFormatter:g.valueFormatter,elementFormatter:g.elementFormatter,comparatorCallback:g.sorter,filterCallback:g.filter,sortValueCallback:g.sortValue};t(this,v).set(g.field,T);let w=T.header;w.classList.add(...t(this,A).th),w.dataset.dtField=g.field,w.hidden=!T.visible;let B=T.headerContent;B.classList.add("dt-header-content"),w.append(B);let j=document.createElement("div");j.classList.add("dt-header-title-wrapper"),B.append(j);let J=document.createElement("span");J.classList.add("dt-header-title"),J.innerHTML=T.title,j.append(J);let st=document.createElement("div");st.classList.add("dt-sort-icon"),j.append(st);let tt=document.createElement("div");tt.classList.add("dt-resizer"),B.append(tt),i.append(w),T.visible&&(h=!0),T.sortable&&w.classList.add("dt-sortable"),t(this,p).rearrangeable&&(w.draggable=!0),((N=g.resizable)!=null?N:t(this,p).resizable)&&w.classList.add("dt-resizable"),j.addEventListener("click",()=>{w.classList.contains("dt-sortable")&&(T.sortOrder?T.sortOrder==="asc"?this.sort(T.field,"desc"):T.sortOrder&&this.sort(T.field,null):this.sort(T.field,"asc"))}),w.addEventListener("dragstart",t(this,xt)),w.addEventListener("dragenter",t(this,Ot)),w.addEventListener("dragover",t(this,St)),w.addEventListener("dragleave",t(this,kt)),w.addEventListener("drop",t(this,Mt)),w.addEventListener("dragend",t(this,Ft)),w.addEventListener("mousedown",t(this,Ct)),w.addEventListener("dblclick",t(this,Lt)),typeof g.width=="number"?w.style.width=g.width+"px":typeof g.width=="string"&&(w.style.width=g.width)}if(t(this,v).size===0)console.warn("No columns found. At least one column is required.");else if(!h){console.warn("At least a single column must be visible. Showing the first column.");let g=t(this,v).keys().next().value;this.showColumn(g)}this.virtualScroll=t(this,p).virtualScroll,this.loadData((gt=t(this,p).data)!=null?gt:[])}get columnStates(){return[...t(this,v).values()].map(e=>({field:e.field,title:e.title,visible:e.visible,sortOrder:e.sortOrder,sortPriority:e.sortPriority,width:e.header.style.width}))}set columnStates(e){var s,r,i,o;for(let h of e){let a=t(this,v).get(h.field);if(!a){console.warn(`Attempting to restore state for non-existent column ${h.field}`);continue}a.visible=(s=h.visible)!=null?s:a.visible,a.sortOrder=(r=h.sortOrder)!=null?r:a.sortOrder,a.sortPriority=(i=h.sortPriority)!=null?i:a.sortPriority,a.header.style.width=(o=h.width)!=null?o:a.header.style.width}this.refresh()}get rows(){return[...t(this,C)]}get data(){return[...t(this,M).values()]}get length(){return t(this,C)?t(this,C).length:0}get table(){return t(this,E)}get virtualScroll(){return!!t(this,O)}set virtualScroll(e){var s;e!=this.virtualScroll&&(e?u(this,O,new vt({container:t(this,y),element:t(this,k),generator:r=>f(this,l,It).call(this,r)})):((s=t(this,O))==null||s.stop(),u(this,O,void 0)),f(this,l,Tt).call(this))}get scoring(){return t(this,p).scoring}set scoring(e){e!==t(this,p).scoring&&(t(this,p).scoring=e,t(this,_)&&f(this,l,q).call(this))}loadData(e,s={}){var h;let r=t(this,y).scrollTop,i=t(this,y).scrollLeft;s.append||(t(this,M).clear(),u(this,C,[]));let o=t(this,M).size;for(let a of e){let m=f(this,l,Gt).call(this,a,o);t(this,M).set(o,m),o++}f(this,l,ct).call(this),f(this,l,q).call(this),s.keepScroll&&(t(this,y).scrollTop=r,t(this,y).scrollLeft=i,(h=t(this,O))==null||h.renderChunk())}showMessage(e,s){Array.isArray(s)?s=s.join(" "):typeof s!="string"&&(s="");let r=t(this,v).size;t(this,k).innerHTML=`<tr class="${s}"><td colSpan=${r}>${e}</td></tr>`}clearMessage(){f(this,l,Tt).call(this)}search(e){if(e===""&&(e=void 0),typeof e=="string"){let s=t(this,p).tokenizer(e.trim()).join("|");u(this,_,new RegExp(`${s}`,"gi"))}else u(this,_,e);f(this,l,q).call(this)}filter(e){if(e!=null||(e={}),typeof e!="object"&&typeof e!="function")throw new TypeError("filters must be object or function");u(this,G,e),f(this,l,q).call(this)}sort(e,s){var a;let r=t(this,v).get(e);if(!r){console.warn(`Attempting to sort non-existent column ${e}`);return}s!=r.sortOrder&&(s==="asc"||s==="desc"?r.sortPriority===Number.MAX_VALUE&&(r.sortPriority=Ht(this,ft)._++):(r.sortPriority=Number.MAX_VALUE,Ht(this,ft)._--),r.sortOrder=s);let i=new CustomEvent("dt.col.sort",{cancelable:!0,detail:{column:r.field,order:r.sortOrder}});if(!this.dispatchEvent(i))return;let o=t(this,y).scrollTop,h=t(this,y).scrollLeft;f(this,l,ct).call(this),f(this,l,yt).call(this),t(this,y).scrollTop=o,t(this,y).scrollLeft=h,(a=t(this,O))==null||a.renderChunk()}setColumnVisibility(e,s){let r=t(this,v).get(e);if(!r){console.warn(`Attempting to ${s?"show":"hide"} non-existent column ${e}`);return}if(r.visible===s)return;let i=new CustomEvent("dt.col.visibility",{cancelable:!0,detail:{column:r.field,visible:s}});this.dispatchEvent(i)&&(r.visible=s,f(this,l,ct).call(this),f(this,l,yt).call(this))}showColumn(e){this.setColumnVisibility(e,!0)}hideColumn(e){this.setColumnVisibility(e,!1)}export(e,s=!1){let i=[...(s?t(this,M):t(this,C)).values()],o=[...t(this,v).values()].filter(L=>s||L.visible).map(L=>`"${L.title}"`).join(","),h=i.map(L=>{let F=[];for(let V of Object.keys(L)){let D=t(this,v).get(V);if(!D)continue;let N=L[V];(s||!D.header.hidden)&&(typeof D.valueFormatter=="function"&&(N=D.valueFormatter(N,L)),N=String(N).replace('"','""'),F.push(`"${N}"`))}return F.join(",")}).join(`
1
+ "use strict";var yatl=(()=>{var bt=Object.defineProperty;var Yt=Object.getOwnPropertyDescriptor;var Zt=Object.getOwnPropertyNames,_t=Object.getOwnPropertySymbols;var $t=Object.prototype.hasOwnProperty,Qt=Object.prototype.propertyIsEnumerable;var Wt=d=>{throw TypeError(d)};var Nt=(d,n,e)=>n in d?bt(d,n,{enumerable:!0,configurable:!0,writable:!0,value:e}):d[n]=e,et=(d,n)=>{for(var e in n||(n={}))$t.call(n,e)&&Nt(d,e,n[e]);if(_t)for(var e of _t(n))Qt.call(n,e)&&Nt(d,e,n[e]);return d};var te=(d,n)=>{for(var e in n)bt(d,e,{get:n[e],enumerable:!0})},ee=(d,n,e,r)=>{if(n&&typeof n=="object"||typeof n=="function")for(let s of Zt(n))!$t.call(d,s)&&s!==e&&bt(d,s,{get:()=>n[s],enumerable:!(r=Yt(n,s))||r.enumerable});return d};var re=d=>ee(bt({},"__esModule",{value:!0}),d);var Dt=(d,n,e)=>n.has(d)||Wt("Cannot "+e);var t=(d,n,e)=>(Dt(d,n,"read from private field"),e?e.call(d):n.get(d)),c=(d,n,e)=>n.has(d)?Wt("Cannot add the same private member more than once"):n instanceof WeakSet?n.add(d):n.set(d,e),u=(d,n,e,r)=>(Dt(d,n,"write to private field"),r?r.call(d,e):n.set(d,e),e),f=(d,n,e)=>(Dt(d,n,"access private method"),e);var Ht=(d,n,e,r)=>({set _(s){u(d,n,s,e)},get _(){return t(d,n,r)}});var se={};te(se,{DataTable:()=>Rt,LocalStorageAdapter:()=>Pt});var x=d=>{if(typeof d=="string"&&d!=="")return d.split(" ");if(Array.isArray(d))return d;if(!d)return[];throw new TypeError("classes must be string or array of strings")},Ut=d=>d.replace(/_/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,n=>n.toUpperCase()),jt=d=>{let n=/"[^"]*"|\S+/g;return(d.match(n)||[]).map(r=>r.startsWith('"')&&r.endsWith('"')?r.slice(1,-1):r)};var ot,H,S,rt,$,W,at,X,Y,lt,dt,ht,wt,Xt,it=class it{constructor({container:n,element:e,generator:r,nodePadding:s=10}){c(this,wt);c(this,H);c(this,S);c(this,rt);c(this,$,0);c(this,W,0);c(this,at,2);c(this,X,0);c(this,Y,!1);c(this,lt,0);c(this,dt,()=>{t(this,H).scrollTop!==t(this,lt)&&(u(this,lt,t(this,H).scrollTop),t(this,X)&&cancelAnimationFrame(t(this,X)),u(this,X,requestAnimationFrame(()=>this.renderChunk())))});c(this,ht,()=>{this.renderChunk()});u(this,H,n),u(this,S,e),u(this,rt,r),u(this,at,s),new IntersectionObserver(o=>{for(let h of o)h.intersectionRatio===1&&this.renderChunk()}).observe(t(this,S))}get rowHeight(){return t(this,W)||f(this,wt,Xt).call(this),t(this,W)}get started(){return t(this,Y)}scrollToIndex(n){if(n<0||n>=t(this,$))throw new RangeError("Index out of bounds.");this.scrollToPx(this.rowHeight*n)}scrollToPx(n){t(this,H).scrollTop=n,this.renderChunk()}start(n){t(this,Y)||(t(this,H).addEventListener("scroll",t(this,dt)),window.addEventListener("resize",t(this,ht)),u(this,Y,!0)),t(this,H).classList.add("dt-virtual-scroll"),u(this,$,n),this.renderChunk()}stop(){t(this,X)&&cancelAnimationFrame(t(this,X)),t(this,H).classList.remove("dt-virtual-scroll"),t(this,H).removeEventListener("scroll",t(this,dt)),window.removeEventListener("resize",t(this,ht)),u(this,Y,!1)}renderChunk(){let n=t(this,H).scrollTop,e=t(this,$),r=this.rowHeight,s=t(this,at);if(!this.started||!t(this,S).checkVisibility()||!e||!r)return;let i=r*e;t(this,S).innerHTML=`<div style="height: ${i}px;"></div>`;let o=t(this,S).offsetHeight,h=t(this,H).offsetHeight;!t(it,ot)&&o<Math.round(i-1)&&(u(it,ot,!0),console.error("Max element height exceeded. Virtual scroll may not work."));let a=Math.floor(n/r)-s;a=Math.max(0,a);let m=Math.ceil(h/r)+2*s;m=Math.min(e-a,m),a%2===1&&a--;let b=a*r,L=i-(b+m*r);try{t(this,S).innerHTML="";let F=new Array(m).fill(null).map((N,gt)=>t(this,rt).call(this,gt+a)),V=document.createElement("div"),D=document.createElement("div");V.style.visibility="hidden",V.style.height=b+"px",D.style.visibility="hidden",D.style.height=L+"px",t(this,S).append(V),t(this,S).append(...F),t(this,S).append(D)}catch(F){F instanceof RangeError&&console.log(F)}}};ot=new WeakMap,H=new WeakMap,S=new WeakMap,rt=new WeakMap,$=new WeakMap,W=new WeakMap,at=new WeakMap,X=new WeakMap,Y=new WeakMap,lt=new WeakMap,dt=new WeakMap,ht=new WeakMap,wt=new WeakSet,Xt=function(){if(t(this,$)===0||!t(this,S).checkVisibility()){u(this,W,0);return}let e=Math.min(1e3,t(this,$)),r=[];for(let s=0;s<e;++s)r.push(t(this,rt).call(this,s));if(t(this,S).innerHTML="",t(this,S).append(...r),u(this,W,t(this,S).offsetHeight/e),t(this,W)<=0)throw new nt(`First ${e} rows had no rendered height. Virtual scroll can't be used.`);t(this,W)*t(this,$)>33554400&&console.warn("Virtual scroll height exceeded maximum known element height.")},c(it,ot,!1);var vt=it,nt=class extends Error{constructor(n){super(n)}};var E,P,k,y,v,M,C,_,G,O,ft,A,I,p,U,l,Gt,Et,zt,Kt,q,Bt,yt,ct,Tt,At,Jt,It,ut,Vt,Ct,mt,pt,Lt,xt,St,Ot,kt,Mt,Ft,z=class z extends EventTarget{constructor(e,r={}){var a,m,b,L,F,V,D,N,gt;super();c(this,l);c(this,E);c(this,P);c(this,k);c(this,y);c(this,v,new Map);c(this,M,new Map);c(this,C,[]);c(this,_);c(this,G);c(this,O);c(this,ft,0);c(this,A);c(this,I);c(this,p);c(this,U,!1);c(this,Ct,e=>{if(!(e.target instanceof HTMLElement)||!e.target.classList.contains("dt-resizer")||!(e.currentTarget instanceof HTMLElement)||!e.currentTarget.dataset.dtField)return;e.stopImmediatePropagation(),e.preventDefault();let r=e.currentTarget.dataset.dtField,s=t(this,v).get(r);s&&(u(this,I,s),s.resizeStartX=e.clientX,s.resizeStartWidth=s.header.offsetWidth,document.addEventListener("mousemove",t(this,mt)),document.addEventListener("mouseup",t(this,pt)))});c(this,mt,e=>{if(!t(this,I))return;e.stopImmediatePropagation(),e.preventDefault();let r=e.clientX-t(this,I).resizeStartX,s=t(this,I).resizeStartWidth+r;f(this,l,Vt).call(this,t(this,I),s)});c(this,pt,e=>{if(!t(this,I))return;e.stopImmediatePropagation(),e.preventDefault(),document.removeEventListener("mousemove",t(this,mt)),document.removeEventListener("mouseup",t(this,pt));let r=new CustomEvent("dt.col.resize",{cancelable:!1,detail:{column:t(this,I).field,width:t(this,I).header.offsetWidth}});this.dispatchEvent(r),u(this,I,void 0)});c(this,Lt,e=>{if(!(e.target instanceof HTMLElement)||!e.target.classList.contains("dt-resizer")||!(e.currentTarget instanceof HTMLElement)||!e.currentTarget.dataset.dtField)return;let r=e.currentTarget.dataset.dtField;r&&f(this,l,Vt).call(this,r)});c(this,xt,e=>{let s=e.target.dataset.dtField;e.dataTransfer&&s&&(e.dataTransfer.effectAllowed="move",e.dataTransfer.setData("text/plain",s))});c(this,St,e=>(e.preventDefault(),e.dataTransfer&&(e.dataTransfer.dropEffect="move"),!1));c(this,Ot,e=>{e.target.classList.add("dt-drag-over")});c(this,kt,e=>{e.target.classList.remove("dt-drag-over")});c(this,Mt,e=>{var m;let r=(m=e.dataTransfer)==null?void 0:m.getData("text/plain"),i=e.currentTarget.dataset.dtField;if(!r||!i)return;e.preventDefault(),e.stopPropagation();let o=[...t(this,v).values()],h=o.findIndex(b=>b.field===r),a=o.findIndex(b=>b.field===i);if(h>-1&&a>-1){let[b]=o.splice(h,1),L=t(this,v).get(i);if(!L)return;o.splice(a,0,b);let F=o.map(D=>D.field),V=new CustomEvent("dt.col.reorder",{cancelable:!0,detail:{draggedColumn:b.field,dropColumn:L.field,order:F}});if(!this.dispatchEvent(V))return;this.setColumnOrder(F)}});c(this,Ft,()=>{let e=document.querySelectorAll(".dt-drag-over");for(let r of e)r.classList.remove("dt-drag-over")});if(u(this,p,et(et({columns:[],data:[]},z.DEFAULT_OPTIONS),r)),typeof e=="string"){let g=document.querySelector(e);if(!g)throw new SyntaxError(`Failed to find table using selector ${e}`);u(this,E,g)}else u(this,E,e);if(!(t(this,E)instanceof HTMLTableElement))throw new TypeError("Invalid table element type. Must be HTMLTableElement");if(!Array.isArray(t(this,p).columns))throw new TypeError("columns must be a list of columns");u(this,A,{scroller:[...x(t(this,p).classes.scroller),...x(z.DEFAULT_OPTIONS.classes.scroller)],thead:[...x(t(this,p).classes.thead),...x(z.DEFAULT_OPTIONS.classes.thead)],tbody:[...x(t(this,p).classes.tbody),...x(z.DEFAULT_OPTIONS.classes.tbody)],tfoot:[...x(t(this,p).classes.tfoot),...x(z.DEFAULT_OPTIONS.classes.tfoot)],tr:[...x(t(this,p).classes.tr),...x(z.DEFAULT_OPTIONS.classes.tr)],th:[...x(t(this,p).classes.th),...x(z.DEFAULT_OPTIONS.classes.th)],td:[...x(t(this,p).classes.td),...x(z.DEFAULT_OPTIONS.classes.td)],mark:[...x(t(this,p).classes.mark),...x(z.DEFAULT_OPTIONS.classes.mark)]}),t(this,E).classList.add("data-table"),u(this,y,document.createElement("div")),t(this,y).classList.add(...t(this,A).scroller),t(this,y).style.overflow="auto",t(this,y).style.height="100%",t(this,E).style.height!==""&&(t(this,y).style.height=t(this,E).style.height,t(this,E).style.height=""),(a=t(this,E).parentElement)==null||a.insertBefore(t(this,y),t(this,E)),t(this,y).append(t(this,E)),t(this,E).querySelectorAll("thead").length>1&&console.warn("Multiple theads found in table. Using last one."),t(this,E).querySelectorAll("tbody").length>1&&console.warn("Multiple tbodys found in table. Using first one.");let s=t(this,E).querySelector("thead:last-of-type");s?u(this,P,s):(u(this,P,document.createElement("thead")),t(this,E).insertBefore(t(this,P),t(this,E).firstChild)),t(this,P).classList.add(...t(this,A).thead);let i=t(this,P).querySelector("tr:last-of-type");i||(i=document.createElement("tr"),t(this,P).append(i)),i.classList.add(...t(this,A).tr),i.innerHTML="";let o=t(this,E).querySelector("tbody:first-of-type");o?u(this,k,o):(u(this,k,document.createElement("tbody")),t(this,E).append(t(this,k))),t(this,k).classList.add(...t(this,A).tbody),t(this,k).addEventListener("click",g=>{var j;if((j=window.getSelection())!=null&&j.toString())return;let T,w,B;if(g.target instanceof HTMLTableCellElement?(w=g.target,T=w.parentElement,B=w.dataset.dtField):g.target instanceof HTMLTableRowElement&&(T=g.target),T){let J=parseInt(T.dataset.dtIndex||"");if(!isNaN(J)){let st=t(this,C).find(tt=>tt._metadata.index===J);if(st){let tt=new CustomEvent("dt.row.clicked",{cancelable:!1,detail:{row:st,index:J,column:B,originalEvent:g}});this.dispatchEvent(tt)}}}});let h=!1;for(let g of t(this,p).columns){let T={field:g.field,title:g.title||Ut(g.field),header:document.createElement("th"),headerContent:document.createElement("div"),visible:(m=g.visible)!=null?m:!0,sortable:(b=g.sortable)!=null?b:t(this,p).sortable,searchable:(L=g.searchable)!=null?L:t(this,p).searchable,tokenize:(F=g.tokenize)!=null?F:t(this,p).tokenize,sortOrder:(V=g.sortOrder)!=null?V:null,sortPriority:(D=g.sortPriority)!=null?D:0,resizeStartWidth:null,resizeStartX:null,valueFormatter:g.valueFormatter,elementFormatter:g.elementFormatter,comparatorCallback:g.sorter,filterCallback:g.filter,sortValueCallback:g.sortValue};t(this,v).set(g.field,T);let w=T.header;w.classList.add(...t(this,A).th),w.dataset.dtField=g.field,w.hidden=!T.visible;let B=T.headerContent;B.classList.add("dt-header-content"),w.append(B);let j=document.createElement("div");j.classList.add("dt-header-title-wrapper"),B.append(j);let J=document.createElement("span");J.classList.add("dt-header-title"),J.innerHTML=T.title,j.append(J);let st=document.createElement("div");st.classList.add("dt-sort-icon"),j.append(st);let tt=document.createElement("div");tt.classList.add("dt-resizer"),B.append(tt),i.append(w),T.visible&&(h=!0),T.sortable&&w.classList.add("dt-sortable"),t(this,p).rearrangeable&&(w.draggable=!0),((N=g.resizable)!=null?N:t(this,p).resizable)&&w.classList.add("dt-resizable"),j.addEventListener("click",()=>{w.classList.contains("dt-sortable")&&(T.sortOrder?T.sortOrder==="asc"?this.sort(T.field,"desc"):T.sortOrder&&this.sort(T.field,null):this.sort(T.field,"asc"))}),w.addEventListener("dragstart",t(this,xt)),w.addEventListener("dragenter",t(this,Ot)),w.addEventListener("dragover",t(this,St)),w.addEventListener("dragleave",t(this,kt)),w.addEventListener("drop",t(this,Mt)),w.addEventListener("dragend",t(this,Ft)),w.addEventListener("mousedown",t(this,Ct)),w.addEventListener("dblclick",t(this,Lt)),typeof g.width=="number"?w.style.width=g.width+"px":typeof g.width=="string"&&(w.style.width=g.width)}if(t(this,v).size===0)console.warn("No columns found. At least one column is required.");else if(!h){console.warn("At least a single column must be visible. Showing the first column.");let g=t(this,v).keys().next().value;this.showColumn(g)}this.virtualScroll=t(this,p).virtualScroll,this.loadData((gt=t(this,p).data)!=null?gt:[])}get columnStates(){return[...t(this,v).values()].map(e=>({field:e.field,title:e.title,visible:e.visible,sortOrder:e.sortOrder,sortPriority:e.sortPriority,width:e.header.style.width}))}set columnStates(e){var r,s,i,o;for(let h of e){let a=t(this,v).get(h.field);if(!a){console.warn(`Attempting to restore state for non-existent column ${h.field}`);continue}a.visible=(r=h.visible)!=null?r:a.visible,a.sortOrder=(s=h.sortOrder)!=null?s:a.sortOrder,a.sortPriority=(i=h.sortPriority)!=null?i:a.sortPriority,a.header.style.width=(o=h.width)!=null?o:a.header.style.width}this.refresh()}get rows(){return[...t(this,C)]}get data(){return[...t(this,M).values()]}get length(){return t(this,C)?t(this,C).length:0}get table(){return t(this,E)}get virtualScroll(){return!!t(this,O)}set virtualScroll(e){var r;e!=this.virtualScroll&&(e?u(this,O,new vt({container:t(this,y),element:t(this,k),generator:s=>f(this,l,It).call(this,s)})):((r=t(this,O))==null||r.stop(),u(this,O,void 0)),f(this,l,Tt).call(this))}get scoring(){return t(this,p).scoring}set scoring(e){e!==t(this,p).scoring&&(t(this,p).scoring=e,t(this,_)&&f(this,l,q).call(this))}loadData(e,r={}){var h;let s=t(this,y).scrollTop,i=t(this,y).scrollLeft;r.append||(t(this,M).clear(),u(this,C,[]));let o=t(this,M).size;for(let a of e){let m=f(this,l,Gt).call(this,a,o);t(this,M).set(o,m),o++}f(this,l,ct).call(this),f(this,l,q).call(this),r.keepScroll&&(t(this,y).scrollTop=s,t(this,y).scrollLeft=i,(h=t(this,O))==null||h.renderChunk())}showMessage(e,r){Array.isArray(r)?r=r.join(" "):typeof r!="string"&&(r="");let s=t(this,v).size;t(this,k).innerHTML=`<tr class="${r}"><td colSpan=${s}>${e}</td></tr>`}clearMessage(){f(this,l,Tt).call(this)}search(e){if(e===""&&(e=void 0),typeof e=="string"){e=e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&").trim();let r=t(this,p).tokenizer(e).join("|");u(this,_,new RegExp(`${r}`,"gi"))}else u(this,_,e);f(this,l,q).call(this)}filter(e){if(e!=null||(e={}),typeof e!="object"&&typeof e!="function")throw new TypeError("filters must be object or function");u(this,G,e),f(this,l,q).call(this)}sort(e,r){var a;let s=t(this,v).get(e);if(!s){console.warn(`Attempting to sort non-existent column ${e}`);return}r!=s.sortOrder&&(r==="asc"||r==="desc"?s.sortPriority===Number.MAX_VALUE&&(s.sortPriority=Ht(this,ft)._++):(s.sortPriority=Number.MAX_VALUE,Ht(this,ft)._--),s.sortOrder=r);let i=new CustomEvent("dt.col.sort",{cancelable:!0,detail:{column:s.field,order:s.sortOrder}});if(!this.dispatchEvent(i))return;let o=t(this,y).scrollTop,h=t(this,y).scrollLeft;f(this,l,ct).call(this),f(this,l,yt).call(this),t(this,y).scrollTop=o,t(this,y).scrollLeft=h,(a=t(this,O))==null||a.renderChunk()}setColumnVisibility(e,r){let s=t(this,v).get(e);if(!s){console.warn(`Attempting to ${r?"show":"hide"} non-existent column ${e}`);return}if(s.visible===r)return;let i=new CustomEvent("dt.col.visibility",{cancelable:!0,detail:{column:s.field,visible:r}});this.dispatchEvent(i)&&(s.visible=r,f(this,l,ct).call(this),f(this,l,yt).call(this))}showColumn(e){this.setColumnVisibility(e,!0)}hideColumn(e){this.setColumnVisibility(e,!1)}export(e,r=!1){let i=[...(r?t(this,M):t(this,C)).values()],o=[...t(this,v).values()].filter(L=>r||L.visible).map(L=>`"${L.title}"`).join(","),h=i.map(L=>{let F=[];for(let V of Object.keys(L)){let D=t(this,v).get(V);if(!D)continue;let N=L[V];(r||!D.header.hidden)&&(typeof D.valueFormatter=="function"&&(N=D.valueFormatter(N,L)),N=String(N).replace('"','""'),F.push(`"${N}"`))}return F.join(",")}).join(`
2
2
  `),a=o+`
3
- `+h,m=new Blob([a],{type:"text/csv;charset=utf-8,"}),b=document.createElement("a");b.style.display="none",b.href=URL.createObjectURL(m),b.download=`${e}.csv`,document.body.append(b),b.click(),b.remove()}scrollToRow(e){var i;let r=(i=e._metadata)==null?void 0:i.index;if(typeof r=="number")this.scrollToOriginalIndex(r);else throw new TypeError("Invalid row")}scrollToOriginalIndex(e){let s=t(this,M).get(e);if(s){let r=t(this,C).indexOf(s);if(r>=0){this.scrollToFilteredIndex(r);return}else throw new Error("Cannot scroll to filtered out row")}else throw new RangeError(`Row index ${e} out of range`)}scrollToFilteredIndex(e){let s=t(this,C)[e];if(!s)throw new RangeError(`Row index ${e} out of range`);if(t(this,O))t(this,O).scrollToIndex(e);else{let r=t(this,k).querySelector(`tr[data-dt-index="${s._metadata.index}"]`);if(r){r.scrollIntoView(!0);let i=parseFloat(getComputedStyle(t(this,P)).height);t(this,y).scrollTop-=i}}}scrollToPx(e){if(t(this,O))t(this,O).scrollToPx(e);else{let s=parseFloat(getComputedStyle(t(this,P)).height);t(this,y).scrollTop-=s}}setColumnOrder(e){if(!Array.isArray(e))throw new TypeError("fields must be an array of field names");let s=new Map;for(let r of e){let i=t(this,v).get(r);i&&s.set(r,i)}for(let[r,i]of t(this,v))s.has(r)||s.set(r,i);u(this,v,s),this.refresh()}refresh(){f(this,l,ct).call(this),f(this,l,q).call(this)}indexOf(e,s){let i=[...t(this,M).values()].find(o=>{if(e in o)return o[e]===s});return i?i._metadata.index:-1}updateRow(e,s){let r=t(this,M).get(e);r&&(Object.assign(r,s),f(this,l,q).call(this))}deleteRow(e){t(this,M).delete(e),f(this,l,q).call(this)}withoutUpdates(e){u(this,U,!0);try{e(this)}finally{u(this,U,!1),this.refresh()}}addEventListener(e,s,r){super.addEventListener(e,s,r)}};E=new WeakMap,P=new WeakMap,k=new WeakMap,y=new WeakMap,v=new WeakMap,M=new WeakMap,C=new WeakMap,_=new WeakMap,G=new WeakMap,O=new WeakMap,ft=new WeakMap,A=new WeakMap,I=new WeakMap,p=new WeakMap,U=new WeakMap,l=new WeakSet,Gt=function(e,s){let r={index:s++,tokens:{},sortValues:{}};e._metadata=r;for(let[i,o]of t(this,v)){let h=f(this,l,ut).call(this,e,i);typeof o.sortValueCallback=="function"?r.sortValues[i]=o.sortValueCallback(h):h instanceof String?r.sortValues[i]=h.toLocaleLowerCase():r.sortValues[i]=h,o.searchable&&o.tokenize&&h&&(r.tokens[i]=[String(h),...t(this,p).tokenizer(h)])}return e},Et=function(e,s){if(Array.isArray(e))return t(this,p).scoring?e.map(r=>f(this,l,Et).call(this,r,s)).reduce((r,i)=>r+i,0):e.some(r=>f(this,l,Et).call(this,r,s))?1:0;if(t(this,p).scoring){let r=e.match(s);if(r)return r.reduce((i,o)=>i+o.length,0)}else return s.test(e)?1:0;return 0},zt=function(e,s,r){if(Array.isArray(s)){for(let i of s)if(f(this,l,zt).call(this,e,i))return!0;return!1}return typeof r=="function"?r(e,s):s instanceof RegExp?s.test(String(e)):s===e},Kt=function(e,s){if(typeof t(this,G)=="function")return t(this,G).call(this,e,s);for(let r of Object.keys(t(this,G)||{})){let i=t(this,G)[r];if(i==null)continue;let o=f(this,l,ut).call(this,e,r);if(typeof i=="function"){if(!i(o))return!1}else{let h=t(this,v).get(r),a=h?h.filterCallback:void 0;if(!f(this,l,zt).call(this,o,i,a))return!1}}return!0},q=function(){if(t(this,U))return;let e=[...t(this,M).values()];u(this,C,e.filter((r,i)=>{if(r._metadata.searchScore=0,!f(this,l,Kt).call(this,r,i))return!1;if(!t(this,_))return!0;let h=[...[...t(this,v).values()].filter(a=>a.searchable).map(a=>a.field),...t(this,p).extraSearchFields];for(let a of h){let m=t(this,v).get(a),b;m&&a in r._metadata.tokens?b=r._metadata.tokens[a]:b=String(f(this,l,ut).call(this,r,a));let L=f(this,l,Et).call(this,b,t(this,_));r._metadata.searchScore+=L}return r._metadata.searchScore>0})),f(this,l,yt).call(this);let s=new CustomEvent("dt.rows.changed",{cancelable:!1,detail:{dataTable:this}});this.dispatchEvent(s)},Bt=function(e,s,r){let i,o;if(r.sortOrder==="asc"?(i=e._metadata.sortValues[r.field],o=s._metadata.sortValues[r.field]):r.sortOrder==="desc"&&(i=s._metadata.sortValues[r.field],o=e._metadata.sortValues[r.field]),typeof r.sorter=="function"){let h=r.sorter(i,o);if(h!==0)return h}return i<o?-1:i>o?1:0},yt=function(){if(t(this,U))return;let e=[...t(this,v).values()].filter(s=>!s.header.hidden&&s.sortOrder).sort((s,r)=>s.sortPriority-r.sortPriority);t(this,C).sort((s,r)=>{if(this.scoring&&t(this,_)){let i=s._metadata.searchScore||0,o=r._metadata.searchScore||0;if(i>o)return-1;if(i<o)return 1}for(let i of e){let o=f(this,l,Bt).call(this,s,r,i);if(o!==0)return o}return s._metadata.index-r._metadata.index}),f(this,l,Tt).call(this)},ct=function(){var e,s,r,i,o,h,a;if(!t(this,U))for(let m of t(this,v).values())(e=m.header.parentElement)==null||e.append(m.header),m.header.hidden=!m.visible,m.sortOrder==="asc"?((s=m.header)==null||s.classList.add("dt-ascending"),(r=m.header)==null||r.classList.remove("dt-descending")):m.sortOrder==="desc"?((i=m.header)==null||i.classList.add("dt-descending"),(o=m.header)==null||o.classList.remove("dt-ascending")):((h=m.header)==null||h.classList.remove("dt-ascending"),(a=m.header)==null||a.classList.remove("dt-descending"))},Tt=function(){if(!t(this,U)){if(t(this,k).innerHTML="",t(this,O))try{t(this,O).start(t(this,C).length)}catch(e){e instanceof nt&&(console.warn("Failed to start virtual scroll... falling back to standard rendering"),console.warn(e.stack))}else{if(t(this,C).length>qt){let s=qt.toLocaleString();console.warn(`Virtual scroll disabled with more than ${s} rows... Good luck with that!`)}let e=t(this,C).map((s,r)=>f(this,l,It).call(this,r));t(this,k).append(...e)}t(this,M).size===0?this.showMessage(t(this,p).noDataText,"dt-empty"):t(this,C).length===0&&this.showMessage(t(this,p).noMatchText,"dt-empty")}},At=function(e,s){if(e.children.length===0){let r=e.innerText,i=t(this,A).mark.join(" ");r=r.replace(s,o=>`<mark class="${i}">${o}</mark>`),e.innerHTML=r}else for(let r of e.children)r instanceof HTMLElement&&f(this,l,At).call(this,r,s)},Jt=function(e,s,r,i){typeof r.valueFormatter=="function"&&(s=r.valueFormatter(s,i)),e.innerText=s==null?"-":s,typeof r.elementFormatter=="function"&&r.elementFormatter(s,i,e),t(this,p).highlightSearch&&t(this,_)&&r.searchable&&f(this,l,At).call(this,e,t(this,_)),e.hidden=!r.visible},It=function(e){let s=t(this,C)[e],r=document.createElement("tr");r.classList.add(...t(this,A).tr),r.dataset.dtIndex=String(s._metadata.index);for(let[i,o]of t(this,v)){let h=f(this,l,ut).call(this,s,i),a=document.createElement("td");a.classList.add(...t(this,A).td),a.dataset.dtField=i;let m=o.header.style.width;m&&m!=="0px"&&(a.style.maxWidth=m),f(this,l,Jt).call(this,a,h,o,s),r.append(a)}if(typeof t(this,p).rowFormatter=="function")try{t(this,p).rowFormatter(s,r)}catch(i){console.error("Row formatter callback failed with the following error"),console.error(i)}return r},ut=function(e,s){let r=s.split("."),i=e;for(let o of r)if(i&&typeof i=="object")i=i[o];else return;return i},Vt=function(e,s){if(typeof e=="string"){let b=t(this,v).get(e);if(!b)throw new Error("Column not found");e=b}let r,i;s==null?(r="",i=""):s<=0?(r="0px",i=""):(r=`${s}px`,i=`${s}px`);let o=e.header.offsetWidth;e.header.style.width=r,e.header.style.maxWidth=r;let h=t(this,k).querySelectorAll(`td[data-dt-field="${e.field}"]`);for(let b of h)b.style.maxWidth=i;let a=e.header.offsetWidth-o,m=t(this,E).offsetWidth+a;t(this,E).style.width=`${m}px`},Ct=new WeakMap,mt=new WeakMap,pt=new WeakMap,Lt=new WeakMap,xt=new WeakMap,St=new WeakMap,Ot=new WeakMap,kt=new WeakMap,Mt=new WeakMap,Ft=new WeakMap,z.DEFAULT_OPTIONS={virtualScroll:!0,highlightSearch:!0,sortable:!0,searchable:!1,tokenize:!1,scoring:!0,resizable:!0,rearrangeable:!0,extraSearchFields:[],noDataText:"No records found",noMatchText:"No matching records found",classes:{scroller:"dt-scroller",thead:"dt-headers",tbody:"",tfoot:"",tr:"",th:"",td:""},tokenizer:jt};var Rt=z,qt=1e4;var K,Z,R,Q,Pt=class{constructor(n,e,s){c(this,K);c(this,Z);c(this,R,{saveColumnSorting:!0,saveColumnVisibility:!0,saveColumnWidth:!0,saveColumnOrder:!0});c(this,Q,()=>setTimeout(()=>this.saveState(),0));u(this,K,n),u(this,Z,e),u(this,R,et(et({},t(this,R)),s)),this.restoreState(),t(this,R).saveColumnSorting&&n.addEventListener("dt.col.sort",t(this,Q)),t(this,R).saveColumnVisibility&&n.addEventListener("dt.col.visibility",t(this,Q)),t(this,R).saveColumnWidth&&n.addEventListener("dt.col.resize",t(this,Q)),t(this,R).saveColumnOrder&&n.addEventListener("dt.col.reorder",t(this,Q))}saveState(){let n=t(this,K).columnStates;for(let e of n)t(this,R).saveColumnSorting||(e.sortOrder=void 0,e.sortPriority=void 0),t(this,R).saveColumnVisibility||(e.visible=void 0),t(this,R).saveColumnWidth||(e.width=void 0);localStorage.setItem(t(this,Z),JSON.stringify(t(this,K).columnStates))}restoreState(){let n=localStorage.getItem(t(this,Z));if(n)try{let e=JSON.parse(n);t(this,K).columnStates=e,t(this,R).saveColumnOrder&&t(this,K).setColumnOrder(e.map(s=>s.field))}catch(e){console.error("Failed to restore DataTable state:",e)}}clearState(){localStorage.removeItem(t(this,Z))}};K=new WeakMap,Z=new WeakMap,R=new WeakMap,Q=new WeakMap;return re(se);})();
3
+ `+h,m=new Blob([a],{type:"text/csv;charset=utf-8,"}),b=document.createElement("a");b.style.display="none",b.href=URL.createObjectURL(m),b.download=`${e}.csv`,document.body.append(b),b.click(),b.remove()}scrollToRow(e){var i;let s=(i=e._metadata)==null?void 0:i.index;if(typeof s=="number")this.scrollToOriginalIndex(s);else throw new TypeError("Invalid row")}scrollToOriginalIndex(e){let r=t(this,M).get(e);if(r){let s=t(this,C).indexOf(r);if(s>=0){this.scrollToFilteredIndex(s);return}else throw new Error("Cannot scroll to filtered out row")}else throw new RangeError(`Row index ${e} out of range`)}scrollToFilteredIndex(e){let r=t(this,C)[e];if(!r)throw new RangeError(`Row index ${e} out of range`);if(t(this,O))t(this,O).scrollToIndex(e);else{let s=t(this,k).querySelector(`tr[data-dt-index="${r._metadata.index}"]`);if(s){s.scrollIntoView(!0);let i=parseFloat(getComputedStyle(t(this,P)).height);t(this,y).scrollTop-=i}}}scrollToPx(e){if(t(this,O))t(this,O).scrollToPx(e);else{let r=parseFloat(getComputedStyle(t(this,P)).height);t(this,y).scrollTop-=r}}setColumnOrder(e){if(!Array.isArray(e))throw new TypeError("fields must be an array of field names");let r=new Map;for(let s of e){let i=t(this,v).get(s);i&&r.set(s,i)}for(let[s,i]of t(this,v))r.has(s)||r.set(s,i);u(this,v,r),this.refresh()}refresh(){f(this,l,ct).call(this),f(this,l,q).call(this)}indexOf(e,r){let i=[...t(this,M).values()].find(o=>{if(e in o)return o[e]===r});return i?i._metadata.index:-1}updateRow(e,r){let s=t(this,M).get(e);s&&(Object.assign(s,r),f(this,l,q).call(this))}deleteRow(e){t(this,M).delete(e),f(this,l,q).call(this)}withoutUpdates(e){u(this,U,!0);try{e(this)}finally{u(this,U,!1),this.refresh()}}addEventListener(e,r,s){super.addEventListener(e,r,s)}};E=new WeakMap,P=new WeakMap,k=new WeakMap,y=new WeakMap,v=new WeakMap,M=new WeakMap,C=new WeakMap,_=new WeakMap,G=new WeakMap,O=new WeakMap,ft=new WeakMap,A=new WeakMap,I=new WeakMap,p=new WeakMap,U=new WeakMap,l=new WeakSet,Gt=function(e,r){let s={index:r++,tokens:{},sortValues:{}};e._metadata=s;for(let[i,o]of t(this,v)){let h=f(this,l,ut).call(this,e,i);typeof o.sortValueCallback=="function"?s.sortValues[i]=o.sortValueCallback(h):h instanceof String?s.sortValues[i]=h.toLocaleLowerCase():s.sortValues[i]=h,o.searchable&&o.tokenize&&h&&(s.tokens[i]=[String(h),...t(this,p).tokenizer(h)])}return e},Et=function(e,r){if(Array.isArray(e))return t(this,p).scoring?e.map(s=>f(this,l,Et).call(this,s,r)).reduce((s,i)=>s+i,0):e.some(s=>f(this,l,Et).call(this,s,r))?1:0;if(t(this,p).scoring){let s=e.match(r);if(s)return s.reduce((i,o)=>i+o.length,0)}else return r.test(e)?1:0;return 0},zt=function(e,r,s){if(Array.isArray(r)){for(let i of r)if(f(this,l,zt).call(this,e,i))return!0;return!1}return typeof s=="function"?s(e,r):r instanceof RegExp?r.test(String(e)):r===e},Kt=function(e,r){if(typeof t(this,G)=="function")return t(this,G).call(this,e,r);for(let s of Object.keys(t(this,G)||{})){let i=t(this,G)[s];if(i==null)continue;let o=f(this,l,ut).call(this,e,s);if(typeof i=="function"){if(!i(o))return!1}else{let h=t(this,v).get(s),a=h?h.filterCallback:void 0;if(!f(this,l,zt).call(this,o,i,a))return!1}}return!0},q=function(){if(t(this,U))return;let e=[...t(this,M).values()];u(this,C,e.filter((s,i)=>{if(s._metadata.searchScore=0,!f(this,l,Kt).call(this,s,i))return!1;if(!t(this,_))return!0;let h=[...[...t(this,v).values()].filter(a=>a.searchable).map(a=>a.field),...t(this,p).extraSearchFields];for(let a of h){let m=t(this,v).get(a),b;m&&a in s._metadata.tokens?b=s._metadata.tokens[a]:b=String(f(this,l,ut).call(this,s,a));let L=f(this,l,Et).call(this,b,t(this,_));s._metadata.searchScore+=L}return s._metadata.searchScore>0})),f(this,l,yt).call(this);let r=new CustomEvent("dt.rows.changed",{cancelable:!1,detail:{dataTable:this}});this.dispatchEvent(r)},Bt=function(e,r,s){let i,o;if(s.sortOrder==="asc"?(i=e._metadata.sortValues[s.field],o=r._metadata.sortValues[s.field]):s.sortOrder==="desc"&&(i=r._metadata.sortValues[s.field],o=e._metadata.sortValues[s.field]),typeof s.sorter=="function"){let h=s.sorter(i,o);if(h!==0)return h}return i<o?-1:i>o?1:0},yt=function(){if(t(this,U))return;let e=[...t(this,v).values()].filter(r=>!r.header.hidden&&r.sortOrder).sort((r,s)=>r.sortPriority-s.sortPriority);t(this,C).sort((r,s)=>{if(this.scoring&&t(this,_)){let i=r._metadata.searchScore||0,o=s._metadata.searchScore||0;if(i>o)return-1;if(i<o)return 1}for(let i of e){let o=f(this,l,Bt).call(this,r,s,i);if(o!==0)return o}return r._metadata.index-s._metadata.index}),f(this,l,Tt).call(this)},ct=function(){var e,r,s,i,o,h,a;if(!t(this,U))for(let m of t(this,v).values())(e=m.header.parentElement)==null||e.append(m.header),m.header.hidden=!m.visible,m.sortOrder==="asc"?((r=m.header)==null||r.classList.add("dt-ascending"),(s=m.header)==null||s.classList.remove("dt-descending")):m.sortOrder==="desc"?((i=m.header)==null||i.classList.add("dt-descending"),(o=m.header)==null||o.classList.remove("dt-ascending")):((h=m.header)==null||h.classList.remove("dt-ascending"),(a=m.header)==null||a.classList.remove("dt-descending"))},Tt=function(){if(!t(this,U)){if(t(this,k).innerHTML="",t(this,O))try{t(this,O).start(t(this,C).length)}catch(e){e instanceof nt&&(console.warn("Failed to start virtual scroll... falling back to standard rendering"),console.warn(e.stack))}else{if(t(this,C).length>qt){let r=qt.toLocaleString();console.warn(`Virtual scroll disabled with more than ${r} rows... Good luck with that!`)}let e=t(this,C).map((r,s)=>f(this,l,It).call(this,s));t(this,k).append(...e)}t(this,M).size===0?this.showMessage(t(this,p).noDataText,"dt-empty"):t(this,C).length===0&&this.showMessage(t(this,p).noMatchText,"dt-empty")}},At=function(e,r){if(e.children.length===0){let s=e.innerText,i=t(this,A).mark.join(" ");s=s.replace(r,o=>`<mark class="${i}">${o}</mark>`),e.innerHTML=s}else for(let s of e.children)s instanceof HTMLElement&&f(this,l,At).call(this,s,r)},Jt=function(e,r,s,i){typeof s.valueFormatter=="function"&&(r=s.valueFormatter(r,i)),e.innerText=r==null?"-":r,typeof s.elementFormatter=="function"&&s.elementFormatter(r,i,e),t(this,p).highlightSearch&&t(this,_)&&s.searchable&&f(this,l,At).call(this,e,t(this,_)),e.hidden=!s.visible},It=function(e){let r=t(this,C)[e],s=document.createElement("tr");s.classList.add(...t(this,A).tr),s.dataset.dtIndex=String(r._metadata.index);for(let[i,o]of t(this,v)){let h=f(this,l,ut).call(this,r,i),a=document.createElement("td");a.classList.add(...t(this,A).td),a.dataset.dtField=i;let m=o.header.style.width;m&&m!=="0px"&&(a.style.maxWidth=m),f(this,l,Jt).call(this,a,h,o,r),s.append(a)}if(typeof t(this,p).rowFormatter=="function")try{t(this,p).rowFormatter(r,s)}catch(i){console.error("Row formatter callback failed with the following error"),console.error(i)}return s},ut=function(e,r){let s=r.split("."),i=e;for(let o of s)if(i&&typeof i=="object")i=i[o];else return;return i},Vt=function(e,r){if(typeof e=="string"){let b=t(this,v).get(e);if(!b)throw new Error("Column not found");e=b}let s,i;r==null?(s="",i=""):r<=0?(s="0px",i=""):(s=`${r}px`,i=`${r}px`);let o=e.header.offsetWidth;e.header.style.width=s,e.header.style.maxWidth=s;let h=t(this,k).querySelectorAll(`td[data-dt-field="${e.field}"]`);for(let b of h)b.style.maxWidth=i;let a=e.header.offsetWidth-o,m=t(this,E).offsetWidth+a;t(this,E).style.width=`${m}px`},Ct=new WeakMap,mt=new WeakMap,pt=new WeakMap,Lt=new WeakMap,xt=new WeakMap,St=new WeakMap,Ot=new WeakMap,kt=new WeakMap,Mt=new WeakMap,Ft=new WeakMap,z.DEFAULT_OPTIONS={virtualScroll:!0,highlightSearch:!0,sortable:!0,searchable:!1,tokenize:!1,scoring:!0,resizable:!0,rearrangeable:!0,extraSearchFields:[],noDataText:"No records found",noMatchText:"No matching records found",classes:{scroller:"dt-scroller",thead:"dt-headers",tbody:"",tfoot:"",tr:"",th:"",td:""},tokenizer:jt};var Rt=z,qt=1e4;var K,Z,R,Q,Pt=class{constructor(n,e,r){c(this,K);c(this,Z);c(this,R,{saveColumnSorting:!0,saveColumnVisibility:!0,saveColumnWidth:!0,saveColumnOrder:!0});c(this,Q,()=>setTimeout(()=>this.saveState(),0));u(this,K,n),u(this,Z,e),u(this,R,et(et({},t(this,R)),r)),this.restoreState(),t(this,R).saveColumnSorting&&n.addEventListener("dt.col.sort",t(this,Q)),t(this,R).saveColumnVisibility&&n.addEventListener("dt.col.visibility",t(this,Q)),t(this,R).saveColumnWidth&&n.addEventListener("dt.col.resize",t(this,Q)),t(this,R).saveColumnOrder&&n.addEventListener("dt.col.reorder",t(this,Q))}saveState(){let n=t(this,K).columnStates;for(let e of n)t(this,R).saveColumnSorting||(e.sortOrder=void 0,e.sortPriority=void 0),t(this,R).saveColumnVisibility||(e.visible=void 0),t(this,R).saveColumnWidth||(e.width=void 0);localStorage.setItem(t(this,Z),JSON.stringify(t(this,K).columnStates))}restoreState(){let n=localStorage.getItem(t(this,Z));if(n)try{let e=JSON.parse(n);t(this,K).columnStates=e,t(this,R).saveColumnOrder&&t(this,K).setColumnOrder(e.map(r=>r.field))}catch(e){console.error("Failed to restore DataTable state:",e)}}clearState(){localStorage.removeItem(t(this,Z))}};K=new WeakMap,Z=new WeakMap,R=new WeakMap,Q=new WeakMap;return re(se);})();
4
4
  //# sourceMappingURL=datatable.global.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/utils.ts","../src/virtualScroll.ts","../src/datatable.ts","../src/plugins/localStorageAdapter.ts"],"sourcesContent":["export * from './types';\nexport * from './datatable';\nexport * from './plugins/localStorageAdapter';\n","export const classesToArray = (classes: string[] | string | undefined) => {\n if (typeof classes === 'string' && classes !== '') {\n return classes.split(' ');\n } else if (Array.isArray(classes)) {\n return classes;\n } else if (!classes) {\n return [];\n }\n throw new TypeError('classes must be string or array of strings');\n};\n\n/*\n * Converts a string to a human-readable format.\n * - Replaces underscores with spaces\n * - Inserts spaces before uppercase letters (for camelCase)\n * - Capitalizes the first letter of each word\n *\n * @param {string} str - The input string to convert.\n * @returns {string} - The converted human-readable string.\n */\nexport const toHumanReadable = (str: string) => {\n return (\n str\n // Replace underscores with spaces\n .replace(/_/g, ' ')\n // Insert spaces before uppercase letters (for camelCase)\n .replace(/([a-z])([A-Z])/g, '$1 $2')\n // Capitalize the first letter of each word\n .replace(/\\b\\w/g, char => char.toUpperCase())\n );\n};\n\n/**\n * Tokenizes a string into an array of lowercase words separated by whitespace.\n */\nexport const whitespaceTokenizer = (value: string) =>\n String(value)\n .toLowerCase()\n .replace(/[^\\w\\s]/g, ' ')\n .trim()\n .split(/\\s+/);\n","const MAX_ELEMENT_HEIGHT = 33554400;\n\nexport class VirtualScroll {\n static #warned = false;\n\n #container;\n #element;\n #generator;\n #rowCount = 0;\n #rowHeight = 0;\n #padding = 2;\n #animationFrame = 0;\n #started = false;\n #scrollTop = 0;\n\n constructor({\n container,\n element,\n generator,\n nodePadding = 10,\n }: VirtualScrollOptions) {\n this.#container = container;\n this.#element = element;\n this.#generator = generator;\n this.#padding = nodePadding;\n\n // Watch for visual changes on our virtual scroll element.\n // This allows us to avoid rendering when the element isn't\n // shown since it can't do the calculations and then start\n // rendering once the element comes into view.\n const observer = new IntersectionObserver(entries => {\n for (const entry of entries) {\n if (entry.intersectionRatio === 1) {\n this.renderChunk();\n }\n }\n });\n observer.observe(this.#element);\n }\n\n get rowHeight() {\n if (!this.#rowHeight) {\n this.#updateRowHeight();\n }\n return this.#rowHeight;\n }\n\n get started() {\n return this.#started;\n }\n\n /*\n * Scroll to a specific index in the virtual scroll.\n * @param index The index to scroll to.\n * @throws RangeError if the index is out of bounds.\n */\n scrollToIndex(index: number) {\n if (index < 0 || index >= this.#rowCount) {\n throw new RangeError('Index out of bounds.');\n }\n this.scrollToPx(this.rowHeight * index);\n }\n\n /**\n * @param px\n */\n scrollToPx(px: number) {\n this.#container.scrollTop = px;\n this.renderChunk();\n }\n\n #scrollCallback = () => {\n // Only update if we are vertically scrolling.\n // Fixes horizontal scroll bug.\n if (this.#container.scrollTop !== this.#scrollTop) {\n this.#scrollTop = this.#container.scrollTop;\n if (this.#animationFrame) {\n cancelAnimationFrame(this.#animationFrame);\n }\n this.#animationFrame = requestAnimationFrame(() => this.renderChunk());\n }\n };\n\n #renderCallback = () => {\n this.renderChunk();\n };\n\n start(rowCount: number) {\n if (!this.#started) {\n this.#container.addEventListener('scroll', this.#scrollCallback);\n window.addEventListener('resize', this.#renderCallback);\n this.#started = true;\n }\n this.#container.classList.add(\"dt-virtual-scroll\");\n this.#rowCount = rowCount;\n this.renderChunk();\n }\n\n stop() {\n if (this.#animationFrame) {\n cancelAnimationFrame(this.#animationFrame);\n }\n\n this.#container.classList.remove(\"dt-virtual-scroll\");\n this.#container.removeEventListener('scroll', this.#scrollCallback);\n window.removeEventListener('resize', this.#renderCallback);\n this.#started = false;\n }\n\n renderChunk() {\n const scrollTop = this.#container.scrollTop;\n const rowCount = this.#rowCount;\n const rowHeight = this.rowHeight;\n const padding = this.#padding;\n\n if (\n !this.started ||\n !this.#element.checkVisibility() ||\n !rowCount ||\n !rowHeight\n ) {\n return;\n }\n\n const totalContentHeight = rowHeight * rowCount;\n // Max out the element height so we can get a real height of the container.\n // This fixes an issue when the parent isn't set to grow causing only a\n // small number of rows to render until you scroll.\n this.#element.innerHTML = `<div style=\"height: ${totalContentHeight}px;\"></div>`;\n const actualHeight = this.#element.offsetHeight;\n const viewHeight = this.#container.offsetHeight;\n\n if (\n !VirtualScroll.#warned &&\n actualHeight < Math.round(totalContentHeight - 1)\n ) {\n VirtualScroll.#warned = true;\n console.error(\n 'Max element height exceeded. Virtual scroll may not work.',\n );\n }\n\n let startNode = Math.floor(scrollTop / rowHeight) - padding;\n startNode = Math.max(0, startNode);\n \n let visibleNodesCount = Math.ceil(viewHeight / rowHeight) + 2 * padding;\n visibleNodesCount = Math.min(rowCount - startNode, visibleNodesCount);\n\n // Always start with an even row.\n // This helps striped tables.\n if (startNode % 2 === 1) {\n startNode--;\n }\n\n \n\n const offsetY = startNode * rowHeight;\n const remainingHeight =\n totalContentHeight - (offsetY + visibleNodesCount * rowHeight);\n\n try {\n this.#element.innerHTML = '';\n const visibleChildren = new Array(visibleNodesCount)\n .fill(null)\n .map((_, index) => this.#generator(index + startNode));\n // We create two empty rows. One at the top and one at the bottom.\n // Resize the rows accordingly to move the rendered rows to where we want.\n const topRow = document.createElement('div');\n const bottomRow = document.createElement('div');\n topRow.style.visibility = 'hidden';\n topRow.style.height = offsetY + 'px';\n bottomRow.style.visibility = 'hidden';\n bottomRow.style.height = remainingHeight + 'px';\n this.#element.append(topRow);\n this.#element.append(...visibleChildren);\n this.#element.append(bottomRow);\n } catch (e) {\n if (e instanceof RangeError) {\n console.log(e);\n }\n }\n }\n\n #updateRowHeight() {\n if (this.#rowCount === 0 || !this.#element.checkVisibility()) {\n this.#rowHeight = 0;\n return;\n }\n\n const AVERAGE_RENDER_COUNT = 1000;\n const renderSize = Math.min(AVERAGE_RENDER_COUNT, this.#rowCount);\n // Create an average row height by rendering the first N rows.\n const elements = [];\n for (let i = 0; i < renderSize; ++i) {\n elements.push(this.#generator(i));\n }\n this.#element.innerHTML = '';\n this.#element.append(...elements);\n this.#rowHeight = this.#element.offsetHeight / renderSize;\n\n if (this.#rowHeight <= 0) {\n throw new VirtualScrollError(\n `First ${renderSize} rows had no rendered height. Virtual scroll can't be used.`,\n );\n } else if (this.#rowHeight * this.#rowCount > MAX_ELEMENT_HEIGHT) {\n // This seems to be Chrome's max height of an element based on some random testing.\n console.warn(\n 'Virtual scroll height exceeded maximum known element height.',\n );\n }\n }\n}\n\nexport class VirtualScrollError extends Error {\n constructor(message: string) {\n super(message);\n }\n}\n\nexport interface VirtualScrollOptions {\n container: HTMLElement;\n element: HTMLElement;\n generator: (index: number) => HTMLElement;\n nodePadding?: number;\n}\n","import './datatable.css';\n\nimport {\n CellFormatterCallback,\n ColumnFilterCallback,\n ColumnOptions,\n ColumnState,\n ComparatorCallback,\n FilterCallback,\n LoadOptions,\n SortOrder,\n SortValueCallback,\n TableOptions,\n ValueFormatterCallback,\n} from './types';\nimport { classesToArray, toHumanReadable, whitespaceTokenizer } from './utils';\nimport { VirtualScroll, VirtualScrollError } from './virtualScroll';\n\ntype RequiredOptions = Required<Omit<TableOptions, 'columns' | 'data' | 'rowFormatter'>> & Pick<TableOptions, 'rowFormatter' | 'data'>;\ntype FinalOptions = RequiredOptions & Pick<TableOptions, 'columns'>;\n\n/**\n * Represents a dynamic and interactive table with features like sorting, searching, filtering,\n * column resizing, column rearranging, and virtual scrolling.\n *\n * @example\n * ```ts\n * const tableElement = document.getElementById('myTable');\n * const options = {\n * columns: [\n * { field: 'id', title: 'ID', sortable: true },\n * { field: 'name', title: 'Name', searchable: true },\n * { field: 'age', title: 'Age', sortable: true, valueFormatter: (value) => `${value} years` }\n * ],\n * data: [\n * { id: 1, name: 'Alice', age: 30 },\n * { id: 2, name: 'Bob', age: 24 },\n * ],\n * virtualScroll: true,\n * resizable: true,\n * rearrangeable: true,\n * };\n * const dataTable = new DataTable(tableElement, options);\n * ```\n */\nexport class DataTable extends EventTarget {\n // Centralized default options for the DataTable.\n // These are the base values used if not overridden by user-provided options.\n private static readonly DEFAULT_OPTIONS: RequiredOptions = {\n virtualScroll: true,\n highlightSearch: true,\n sortable: true,\n searchable: false,\n tokenize: false,\n scoring: true,\n resizable: true,\n rearrangeable: true,\n extraSearchFields: [],\n noDataText: 'No records found',\n noMatchText: 'No matching records found',\n classes: {\n scroller: 'dt-scroller',\n thead: 'dt-headers',\n tbody: '',\n tfoot: '',\n tr: '',\n th: '',\n td: '',\n },\n tokenizer: whitespaceTokenizer, // Default tokenizer function\n };\n\n // Table elements\n #table!: HTMLTableElement;\n #thead!: HTMLElement;\n #tbody!: HTMLElement;\n #scroller!: HTMLElement;\n\n #columnData: Map<string, ColumnData> = new Map();\n\n // Current data stored by the initial index\n #rows: Map<number, InternalRowData> = new Map();\n #filteredRows: InternalRowData[] = [];\n\n // Search and filter data\n #query?: RegExp;\n #filters!: any | FilterCallback;\n\n #virtualScroll?: VirtualScroll;\n\n // The current sort priority. Incremented when a column is sorted.\n #sortPriority: number = 0;\n\n #classes: Classes;\n #resizingColumn?: ColumnData;\n\n #options: FinalOptions;\n\n #blockUpdates = false;\n\n /**\n * Initializes a new instance of the DataTable.\n * @param table - The HTMLTableElement or a CSS selector string for the table.\n * @param options - Optional configuration options for the DataTable.\n * @throws {SyntaxError} If the table selector does not find an element.\n * @throws {TypeError} If the provided table element is not an HTMLTableElement or if columns option is not an array.\n */\n constructor(table: string | HTMLTableElement, options: TableOptions = {}) {\n super();\n\n this.#options = {\n columns: [],\n data: [],\n ...DataTable.DEFAULT_OPTIONS,\n ...options,\n };\n\n if (typeof table === 'string') {\n const tableElement = document.querySelector(table);\n if (!tableElement)\n throw new SyntaxError(`Failed to find table using selector ${table}`);\n this.#table = tableElement as HTMLTableElement;\n } else {\n this.#table = table;\n }\n\n if (!(this.#table instanceof HTMLTableElement)) {\n throw new TypeError(\n `Invalid table element type. Must be HTMLTableElement`,\n );\n }\n\n if (!Array.isArray(this.#options.columns)) {\n throw new TypeError('columns must be a list of columns');\n }\n\n\n this.#classes = {\n scroller: [\n ...classesToArray(this.#options.classes.scroller),\n ...classesToArray(DataTable.DEFAULT_OPTIONS.classes.scroller),\n ],\n thead: [\n ...classesToArray(this.#options.classes.thead),\n ...classesToArray(DataTable.DEFAULT_OPTIONS.classes.thead),\n ],\n tbody: [\n ...classesToArray(this.#options.classes.tbody),\n ...classesToArray(DataTable.DEFAULT_OPTIONS.classes.tbody),\n ],\n tfoot: [\n ...classesToArray(this.#options.classes.tfoot),\n ...classesToArray(DataTable.DEFAULT_OPTIONS.classes.tfoot),\n ],\n tr: [\n ...classesToArray(this.#options.classes.tr),\n ...classesToArray(DataTable.DEFAULT_OPTIONS.classes.tr),\n ],\n th: [\n ...classesToArray(this.#options.classes.th),\n ...classesToArray(DataTable.DEFAULT_OPTIONS.classes.th),\n ],\n td: [\n ...classesToArray(this.#options.classes.td),\n ...classesToArray(DataTable.DEFAULT_OPTIONS.classes.td),\n ],\n mark: [\n ...classesToArray(this.#options.classes.mark),\n ...classesToArray(DataTable.DEFAULT_OPTIONS.classes.mark),\n ]\n };\n\n this.#table.classList.add('data-table');\n\n // Inner element that handles the virtual scroll.\n this.#scroller = document.createElement('div');\n this.#scroller.classList.add(...this.#classes.scroller);\n this.#scroller.style.overflow = 'auto';\n this.#scroller.style.height = '100%';\n\n // If the user tries to provide a height, we will use that for the scroller.\n if (this.#table.style.height !== '') {\n this.#scroller.style.height = this.#table.style.height;\n this.#table.style.height = '';\n }\n\n // Add the scroller before the table so when we move the\n // table into the scroller it stays in the same place.\n this.#table.parentElement?.insertBefore(this.#scroller, this.#table);\n this.#scroller.append(this.#table);\n\n if (this.#table.querySelectorAll('thead').length > 1) {\n console.warn('Multiple theads found in table. Using last one.');\n }\n\n if (this.#table.querySelectorAll('tbody').length > 1) {\n console.warn('Multiple tbodys found in table. Using first one.');\n }\n\n // Hopefully there isn't more than one header or body\n // but if there is, use the last header and first body\n // since that seems like it would make the most sense.\n const thead = this.#table.querySelector('thead:last-of-type');\n if (thead) {\n this.#thead = thead as HTMLTableElement;\n } else {\n this.#thead = document.createElement('thead');\n this.#table.insertBefore(this.#thead, this.#table.firstChild);\n }\n\n this.#thead.classList.add(...this.#classes.thead);\n\n // Create the row for the thead if there isn't one\n let headerRow = this.#thead.querySelector('tr:last-of-type');\n if (!headerRow) {\n headerRow = document.createElement('tr');\n this.#thead.append(headerRow);\n }\n\n headerRow.classList.add(...this.#classes.tr);\n // Remove any existing header cells\n // TODO: Add ability to use HTML headers provided by the user.\n headerRow.innerHTML = '';\n\n const tbody = this.#table.querySelector('tbody:first-of-type');\n // Create the tbody if it doesn't exists\n if (tbody) {\n this.#tbody = tbody as HTMLTableElement;\n } else {\n this.#tbody = document.createElement('tbody');\n this.#table.append(this.#tbody);\n }\n\n this.#tbody.classList.add(...this.#classes.tbody);\n\n this.#tbody.addEventListener('click', event => {\n // Ignore events if the user is highlighting text\n if (window.getSelection()?.toString()) return;\n\n let tr, td, field;\n if (event.target instanceof HTMLTableCellElement) {\n td = event.target;\n tr = td.parentElement;\n field = td.dataset.dtField;\n } else if (event.target instanceof HTMLTableRowElement) {\n tr = event.target;\n }\n\n if (tr) {\n const index = parseInt(tr.dataset.dtIndex || '');\n if (!isNaN(index)) {\n const row = this.#filteredRows.find(\n value => value._metadata.index === index,\n );\n if (row) {\n const rowEvent = new CustomEvent<\n DataTableEventMap['dt.row.clicked']\n >('dt.row.clicked', {\n cancelable: false,\n detail: {\n row: row,\n index: index,\n column: field,\n originalEvent: event,\n },\n });\n this.dispatchEvent(rowEvent);\n }\n }\n }\n });\n\n let colVisible = false;\n // Initialize columns\n for (const colOptions of this.#options.columns) {\n const colData: ColumnData = {\n field: colOptions.field,\n title: colOptions.title || toHumanReadable(colOptions.field),\n header: document.createElement('th'),\n headerContent: document.createElement('div'),\n visible: colOptions.visible ?? true,\n sortable: colOptions.sortable ?? this.#options.sortable,\n searchable: colOptions.searchable ?? this.#options.searchable,\n tokenize: colOptions.tokenize ?? this.#options.tokenize,\n sortOrder: colOptions.sortOrder ?? null,\n sortPriority: colOptions.sortPriority ?? 0,\n resizeStartWidth: null,\n resizeStartX: null,\n valueFormatter: colOptions.valueFormatter,\n elementFormatter: colOptions.elementFormatter,\n comparatorCallback: colOptions.sorter,\n filterCallback: colOptions.filter,\n sortValueCallback: colOptions.sortValue,\n };\n this.#columnData.set(colOptions.field, colData);\n\n const th = colData.header;\n th.classList.add(...this.#classes.th);\n th.dataset.dtField = colOptions.field;\n th.hidden = !colData.visible;\n\n const headerContent = colData.headerContent;\n headerContent.classList.add('dt-header-content');\n th.append(headerContent);\n\n const titleWrapper = document.createElement('div');\n titleWrapper.classList.add('dt-header-title-wrapper');\n headerContent.append(titleWrapper);\n\n const titleElement = document.createElement('span');\n titleElement.classList.add('dt-header-title');\n titleElement.innerHTML = colData.title;\n titleWrapper.append(titleElement);\n\n const sorter = document.createElement('div');\n sorter.classList.add('dt-sort-icon');\n titleWrapper.append(sorter);\n\n const resizer = document.createElement('div');\n resizer.classList.add('dt-resizer');\n headerContent.append(resizer);\n\n headerRow.append(th);\n\n // We need at least one column visible\n if (colData.visible) {\n colVisible = true;\n }\n\n if (colData.sortable) {\n th.classList.add('dt-sortable');\n }\n\n if (this.#options.rearrangeable) {\n th.draggable = true;\n }\n\n if (colOptions.resizable ?? this.#options.resizable) {\n th.classList.add('dt-resizable');\n }\n\n // Sort event listener\n titleWrapper.addEventListener('click', () => {\n if (!th.classList.contains('dt-sortable')) return;\n\n if (!colData.sortOrder) {\n this.sort(colData.field, 'asc');\n } else if (colData.sortOrder === 'asc') {\n this.sort(colData.field, 'desc');\n } else if (colData.sortOrder) {\n this.sort(colData.field, null);\n }\n });\n\n // Drag and drop event listeners\n th.addEventListener('dragstart', this.#dragColumnStart);\n th.addEventListener('dragenter', this.#dragColumnEnter);\n th.addEventListener('dragover', this.#dragColumnOver);\n th.addEventListener('dragleave', this.#dragColumnLeave);\n th.addEventListener('drop', this.#dragColumnDrop);\n th.addEventListener('dragend', this.#dragColumnEnd);\n // Resize event listeners\n th.addEventListener('mousedown', this.#resizeColumnStart);\n th.addEventListener('dblclick', this.#resizeColumnDoubleClick);\n\n if (typeof colOptions.width === 'number') {\n th.style.width = colOptions.width + 'px';\n } else if (typeof colOptions.width === 'string') {\n th.style.width = colOptions.width;\n }\n }\n\n if (this.#columnData.size === 0) {\n console.warn('No columns found. At least one column is required.');\n } else if (!colVisible) {\n console.warn(\n 'At least a single column must be visible. Showing the first column.',\n );\n const col = this.#columnData.keys().next().value!;\n this.showColumn(col);\n }\n\n this.virtualScroll = this.#options.virtualScroll;\n this.loadData(this.#options.data ?? []);\n }\n\n /**\n * Gets or sets the state of all columns in the table.\n * This can be used to save and restore column configurations like visibility, sort order, and width.\n * When setting, it attempts to apply the states to existing columns.\n */\n get columnStates(): ColumnState[] {\n return [...this.#columnData.values()].map(col => {\n return {\n field: col.field,\n title: col.title,\n visible: col.visible,\n sortOrder: col.sortOrder,\n sortPriority: col.sortPriority,\n width: col.header.style.width,\n } as ColumnState;\n });\n }\n\n set columnStates(states: ColumnState[]) {\n for (const state of states) {\n const column = this.#columnData.get(state.field);\n if (!column) {\n console.warn(\n `Attempting to restore state for non-existent column ${state.field}`,\n );\n continue;\n }\n\n column.visible = state.visible ?? column.visible;\n column.sortOrder = state.sortOrder ?? column.sortOrder;\n column.sortPriority = state.sortPriority ?? column.sortPriority;\n column.header.style.width = state.width ?? column.header.style.width;\n }\n this.refresh();\n }\n\n /**\n * Gets the currently filtered and sorted rows displayed in the table.\n */\n get rows(): any[] {\n return [...this.#filteredRows];\n }\n\n /**\n * Gets the underlying data\n */\n get data(): any[] {\n return [...this.#rows.values()];\n }\n\n /**\n * Gets the total number of currently filtered and sorted rows.\n */\n get length(): number {\n return this.#filteredRows ? this.#filteredRows.length : 0;\n }\n\n /**\n * Gets the underlying HTMLTableElement managed by this DataTable instance.\n */\n get table(): HTMLTableElement {\n return this.#table;\n }\n\n /**\n * Gets or sets the virtual scroll behavior for the table.\n * When `true`, virtual scrolling is enabled, rendering only visible rows for performance with large datasets.\n * When `false`, virtual scrolling is disabled, and all rows are rendered.\n * @default true\n */\n get virtualScroll(): boolean {\n return !!this.#virtualScroll;\n }\n\n set virtualScroll(value) {\n if (value == this.virtualScroll) return;\n\n if (value) {\n this.#virtualScroll = new VirtualScroll({\n container: this.#scroller,\n element: this.#tbody,\n generator: index => this.#createRow(index),\n });\n } else {\n this.#virtualScroll?.stop();\n this.#virtualScroll = undefined;\n }\n\n this.#updateTable();\n }\n\n get scoring(): boolean {\n return this.#options.scoring;\n }\n\n set scoring(value) {\n if (value !== this.#options.scoring) {\n this.#options.scoring = value;\n\n if (this.#query) {\n this.#filterRows();\n }\n }\n }\n\n /**\n * Loads data into the table\n * @param rows - An array of data to be loaded\n * @param options - Configuration for the load operation\n */\n loadData(rows: any[], options: LoadOptions = {}) {\n const scrollTop = this.#scroller.scrollTop;\n const scrollLeft = this.#scroller.scrollLeft;\n\n if (!options.append) {\n this.#rows.clear();\n this.#filteredRows = [];\n }\n\n let index = this.#rows.size;\n for (const row of rows) {\n const internal_row = this.#loadRow(row, index);\n this.#rows.set(index, internal_row);\n index++;\n }\n\n this.#updateHeaders();\n this.#filterRows();\n\n if (options.keepScroll) {\n this.#scroller.scrollTop = scrollTop;\n this.#scroller.scrollLeft = scrollLeft;\n this.#virtualScroll?.renderChunk();\n }\n }\n\n /**\n * Displays a message in the table body, typically used for \"no data\" or \"no results\" states.\n * The message is shown in a single row spanning all columns.\n * @param text - The text or HTML message to display.\n * @param classes - A string or array of strings for CSS classes to apply to the message row.\n */\n showMessage(text: string, classes: string | string[]) {\n if (Array.isArray(classes)) {\n classes = classes.join(' ');\n } else if (typeof classes !== 'string') {\n classes = '';\n }\n\n const colSpan = this.#columnData.size;\n this.#tbody.innerHTML = `<tr class=\"${classes}\"><td colSpan=${colSpan}>${text}</td></tr>`;\n }\n\n /**\n * Clears the current message and dispalsy the normal table data.\n */\n clearMessage() {\n this.#updateTable();\n }\n\n /**\n * Filters rows based on a search query.\n * The search is performed on columns marked as `searchable` and `extraSearchFields`.\n * @param query - The search term (string) or a regular expression. An empty string clears the search.\n */\n search(query?: string | RegExp) {\n // Clear search on empty string\n if (query === \"\") {\n query = undefined;\n }\n\n if (typeof query === 'string') {\n const tokens = this.#options.tokenizer(query.trim()).join(\"|\");\n this.#query = new RegExp(`${tokens}`, 'gi');\n } else {\n this.#query = query;\n }\n\n this.#filterRows();\n }\n\n /**\n * Applies filters to the table rows.\n * Filters can be an object where keys are field names and values are the criteria to filter by,\n * or a callback function that receives a row and its index and returns `true` if the row should be included.\n * @param filters - An object defining field-based filters or a custom filter callback function.\n * @throws {TypeError} If `filters` is not an object or a function.\n */\n filter(filters?: any | FilterCallback) {\n filters ??= {};\n\n if (typeof filters !== 'object' && typeof filters !== 'function') {\n throw new TypeError('filters must be object or function');\n }\n this.#filters = filters;\n this.#filterRows();\n }\n\n /**\n * Sorts the table by a specified column and order.\n * If `order` is `null`, the sort on this column is removed.\n * @param colName - The field name of the column to sort by.\n * @param order - The sort order: 'asc', 'desc', or `null` to remove sorting for this column.\n */\n sort(colName: string, order: SortOrder) {\n const col = this.#columnData.get(colName);\n if (!col) {\n console.warn(`Attempting to sort non-existent column ${colName}`);\n return;\n }\n\n if (order != col.sortOrder) {\n if (order === 'asc' || order === 'desc') {\n // If we are changing the sort order of a column\n // keep it's existing priority.\n if (col.sortPriority === Number.MAX_VALUE) {\n col.sortPriority = this.#sortPriority++;\n }\n } else {\n col.sortPriority = Number.MAX_VALUE;\n this.#sortPriority--;\n }\n col.sortOrder = order;\n }\n\n const sortEvent = new CustomEvent<DataTableEventMap['dt.col.sort']>(\n 'dt.col.sort',\n {\n cancelable: true,\n detail: {\n column: col.field,\n order: col.sortOrder,\n },\n },\n );\n\n if (!this.dispatchEvent(sortEvent)) {\n return;\n }\n\n const scrollTop = this.#scroller.scrollTop;\n const scrollLeft = this.#scroller.scrollLeft;\n\n this.#updateHeaders();\n this.#sortRows();\n\n this.#scroller.scrollTop = scrollTop;\n this.#scroller.scrollLeft = scrollLeft;\n this.#virtualScroll?.renderChunk();\n }\n\n /**\n * Sets the visibility of a specified column.\n * @param colName - The field name of the column.\n * @param visisble - `true` to show the column, `false` to hide it.\n */\n setColumnVisibility(colName: string, visisble: boolean) {\n const col = this.#columnData.get(colName);\n if (!col) {\n console.warn(\n `Attempting to ${visisble ? 'show' : 'hide'\n } non-existent column ${colName}`,\n );\n return;\n }\n\n if (col.visible === visisble) {\n return;\n }\n\n const visibilityEvent = new CustomEvent<\n DataTableEventMap['dt.col.visibility']\n >('dt.col.visibility', {\n cancelable: true,\n detail: {\n column: col.field,\n visible: visisble,\n },\n });\n\n if (!this.dispatchEvent(visibilityEvent)) {\n return;\n }\n\n col.visible = visisble;\n this.#updateHeaders();\n // If we hide a column that has sorting, we need to resort.\n // This will also handle hiding all of the columns elements.\n this.#sortRows();\n }\n\n /**\n * Shows a previously hidden column.\n * @param field - The field name of the column to show.\n */\n showColumn(field: string) {\n this.setColumnVisibility(field, true);\n }\n\n /**\n * Hides a visible column.\n * @param field - The field name of the column to hide.\n */\n hideColumn(field: string) {\n this.setColumnVisibility(field, false);\n }\n\n /**\n * Export the current visible table data to a CSV file.\n * @param filename - The name of the file to save.\n * @param all - If `true`, exports all original data (ignoring filters). If `false` (default), exports only the currently visible (filtered and sorted) rows.\n */\n export(filename: string, all = false) {\n const data = all ? this.#rows : this.#filteredRows;\n const rows = [...data.values()];\n\n const csvHeaders = [...this.#columnData.values()]\n .filter(col => all || col.visible)\n .map(col => `\"${col.title}\"`)\n .join(',');\n\n const csvRows = rows\n .map(row => {\n const list = [];\n for (const key of Object.keys(row)) {\n const col = this.#columnData.get(key);\n if (!col) {\n continue;\n }\n\n let value = row[key];\n if (all || !col.header.hidden) {\n if (typeof col.valueFormatter === 'function') {\n value = col.valueFormatter(value, row);\n }\n\n value = String(value).replace('\"', '\"\"');\n list.push(`\"${value}\"`);\n }\n }\n return list.join(',');\n })\n .join('\\n');\n\n const csvContent = csvHeaders + '\\n' + csvRows;\n const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8,' });\n const a = document.createElement('a');\n a.style.display = 'none';\n a.href = URL.createObjectURL(blob);\n a.download = `${filename}.csv`;\n document.body.append(a);\n a.click();\n a.remove();\n }\n\n scrollToRow(row: any) {\n const rowData = row as InternalRowData;\n const index = rowData._metadata?.index;\n if (typeof index === 'number') {\n this.scrollToOriginalIndex(index);\n } else {\n throw new TypeError('Invalid row');\n }\n }\n\n /**\n * Scrolls the table to bring the row at the specified original index into view.\n * @param index - The original index of the row (from the initial dataset).\n */\n scrollToOriginalIndex(index: number) {\n const rowData = this.#rows.get(index);\n if (rowData) {\n const filteredIndex = this.#filteredRows.indexOf(rowData);\n if (filteredIndex >= 0) {\n this.scrollToFilteredIndex(filteredIndex);\n return;\n } else {\n throw new Error('Cannot scroll to filtered out row');\n }\n } else {\n throw new RangeError(`Row index ${index} out of range`);\n }\n }\n\n scrollToFilteredIndex(index: number) {\n const rowData = this.#filteredRows[index];\n if (!rowData) {\n throw new RangeError(`Row index ${index} out of range`);\n }\n\n if (this.#virtualScroll) {\n this.#virtualScroll.scrollToIndex(index);\n } else {\n const row = this.#tbody.querySelector(\n `tr[data-dt-index=\"${rowData._metadata.index}\"]`,\n );\n if (row) {\n row.scrollIntoView(true);\n const theadHeight = parseFloat(getComputedStyle(this.#thead).height);\n this.#scroller.scrollTop -= theadHeight;\n }\n }\n }\n\n scrollToPx(px: number) {\n if (this.#virtualScroll) {\n this.#virtualScroll.scrollToPx(px);\n } else {\n const theadHeight = parseFloat(getComputedStyle(this.#thead).height);\n this.#scroller.scrollTop -= theadHeight;\n }\n }\n\n /**\n * Sets the display order of the columns in the table.\n *\n * @param fields - An array of field names representing the new order of columns. Columns not included in the array will be placed at the end.\n * @throws {TypeError} If `fields` is not an array.\n */\n setColumnOrder(fields: string[]) {\n if (!Array.isArray(fields)) {\n throw new TypeError('fields must be an array of field names');\n }\n\n const newColumns = new Map<string, ColumnData>();\n for (const field of fields) {\n const col = this.#columnData.get(field);\n if (col) {\n newColumns.set(field, col);\n }\n }\n\n for (const [field, col] of this.#columnData) {\n if (!newColumns.has(field)) {\n newColumns.set(field, col);\n }\n }\n\n this.#columnData = newColumns;\n this.refresh();\n }\n\n /**\n * Refreshes the table display. This re-applies filters, sorting, and updates headers and rows.\n */\n refresh() {\n this.#updateHeaders();\n this.#filterRows();\n }\n\n /**\n * Finds the original index of the first row where the specified field matches the given value.\n * This searches through the original, unfiltered dataset.\n * @param field - The field name within the row data to search.\n * @param value - The value to match against the field's content.\n * @returns The original index of the found row, or -1 if no match is found.\n * @example\n * ```ts\n * const index = dataTable.indexOf('id', 12345);\n * if (index >= 0) {\n * dataTable.updateRow({description: \"Updated description\"}, index);\n * }\n * ```\n */\n indexOf(field: string, value: any) {\n const rows = [...this.#rows.values()];\n const found_row = rows.find(row => {\n if (field in row) {\n return row[field] === value;\n }\n });\n\n if (found_row) {\n return found_row._metadata.index;\n }\n return -1;\n }\n\n /**\n * Updates the data of a row at a specific original index.\n * @param index - The original index of the row to update.\n * @param data - An object containing the new data to assign to the row. Existing fields will be updated, and new fields will be added.\n *\n * @example\n * ```ts\n * const index = dataTable.indexOf('id', 12345);\n * if (index >= 0) {\n * dataTable.updateRow(index, {description: \"Updated description\"});\n * }\n * ```\n */\n updateRow(index: number, data: any) {\n const current_row = this.#rows.get(index);\n if (current_row) {\n Object.assign(current_row, data);\n this.#filterRows();\n }\n }\n\n /**\n * Deletes a row at a specific original index from the table.\n * @param index - The original index of the row to delete.\n */\n deleteRow(index: number) {\n this.#rows.delete(index);\n this.#filterRows();\n }\n\n /**\n * Executes a callback function without triggering table updates (like re-rendering or event dispatches)\n * until the callback has completed. This is useful for batching multiple operations.\n * @param callback - A function to execute. It receives the DataTable instance as its argument.\n * @example dataTable.withoutUpdates(dt => { dt.sort('name', 'asc'); dt.filter({ age: '>30' }); });\n */\n withoutUpdates(callback: (datatable: DataTable) => void) {\n this.#blockUpdates = true;\n try {\n callback(this);\n } finally {\n this.#blockUpdates = false;\n this.refresh();\n }\n }\n\n #loadRow(row: InternalRowData, index: number) {\n // Add the index\n const metadata: RowMetadata = {\n index: index++,\n tokens: {},\n sortValues: {},\n };\n row._metadata = metadata;\n\n for (const [field, col] of this.#columnData) {\n const value = this.#getNestedValue(row, field);\n\n // Cache precomputed values for sorting\n if (typeof col.sortValueCallback === 'function') {\n metadata.sortValues[field] = col.sortValueCallback(value);\n } else if (value instanceof String) {\n metadata.sortValues[field] = value.toLocaleLowerCase();\n } else {\n metadata.sortValues[field] = value;\n }\n\n // Tokenize any searchable columns\n if (col.searchable && col.tokenize && value) {\n metadata.tokens[field] = [String(value), ...this.#options.tokenizer(value)];\n }\n }\n\n return row;\n }\n\n #searchField(value: string | string[], query: RegExp): number {\n if (Array.isArray(value)) {\n if (this.#options.scoring) {\n return value.map(element => this.#searchField(element, query)).reduce((accumulator, currentValue) => accumulator + currentValue, 0);\n } else {\n return value.some(element => this.#searchField(element, query)) ? 1 : 0;\n }\n }\n\n if (this.#options.scoring) {\n const matches = value.match(query);\n if (matches) {\n return matches.reduce((accumulator, value) => accumulator + value.length, 0);\n }\n } else {\n return query.test(value) ? 1 : 0\n }\n\n\n return 0;\n }\n\n #filterField(\n value: any,\n filter: any,\n filterFunction?: ColumnFilterCallback,\n ): boolean {\n if (Array.isArray(filter)) {\n // If it's an array, we will use an OR filter.\n // If any filters in the array match, keep it.\n for (const element of filter) {\n if (this.#filterField(value, element)) {\n return true;\n }\n }\n return false;\n }\n\n if (typeof filterFunction === 'function') {\n return filterFunction(value, filter);\n }\n\n if (filter instanceof RegExp) {\n return filter.test(String(value));\n }\n\n return filter === value;\n }\n\n #filterRow(row: InternalRowData, index: number): boolean {\n if (typeof this.#filters === 'function') {\n return this.#filters(row, index);\n }\n\n for (const field of Object.keys(this.#filters || {})) {\n const filter = this.#filters[field];\n if (filter == null) {\n continue;\n }\n\n const value = this.#getNestedValue(row, field);\n if (typeof filter === 'function') {\n if (!filter(value)) {\n return false;\n }\n } else {\n const col = this.#columnData.get(field);\n const filterCallback = col ? col.filterCallback : undefined;\n if (!this.#filterField(value, filter, filterCallback)) {\n return false;\n }\n }\n }\n return true;\n }\n\n #filterRows() {\n if (this.#blockUpdates) return;\n\n const rows = [...this.#rows.values()];\n this.#filteredRows = rows.filter((row, index) => {\n row._metadata.searchScore = 0;\n // Filter takes precedence over search.\n if (!this.#filterRow(row, index)) {\n return false;\n }\n\n if (!this.#query) {\n return true;\n }\n\n const searchableFields = [...this.#columnData.values()]\n .filter(col => col.searchable)\n .map(c => c.field);\n\n const fields = [...searchableFields, ...this.#options.extraSearchFields];\n\n for (const field of fields) {\n const col = this.#columnData.get(field);\n\n let tokens;\n if (col && field in row._metadata.tokens) {\n tokens = row._metadata.tokens[field];\n } else {\n tokens = String(this.#getNestedValue(row, field));\n\n }\n\n const score = this.#searchField(tokens, this.#query);\n row._metadata.searchScore += score\n }\n\n return row._metadata.searchScore > 0;\n });\n\n this.#sortRows();\n\n const changeEvent = new CustomEvent<DataTableEventMap['dt.rows.changed']>(\n 'dt.rows.changed',\n {\n cancelable: false,\n detail: {\n dataTable: this,\n },\n },\n );\n\n this.dispatchEvent(changeEvent);\n }\n\n #compareRows(\n a: InternalRowData,\n b: InternalRowData,\n col: ColumnOptions,\n ): number {\n let aValue, bValue;\n if (col.sortOrder === 'asc') {\n aValue = a._metadata.sortValues[col.field];\n bValue = b._metadata.sortValues[col.field];\n } else if (col.sortOrder === 'desc') {\n aValue = b._metadata.sortValues[col.field];\n bValue = a._metadata.sortValues[col.field];\n }\n\n if (typeof col.sorter === 'function') {\n const ret = col.sorter(aValue, bValue);\n if (ret !== 0) return ret;\n }\n\n if (aValue < bValue) return -1;\n if (aValue > bValue) return 1;\n return 0;\n }\n\n #sortRows() {\n if (this.#blockUpdates) return;\n\n const sortedColumns = [...this.#columnData.values()]\n // Only sort by visible columns with valid sort priorities\n .filter(col => !col.header.hidden && col.sortOrder)\n // Sort our columns by their sort priority.\n // This is how sorting by multiple columns is handled.\n .sort((a, b) => a.sortPriority - b.sortPriority);\n\n this.#filteredRows.sort((a, b) => {\n\n // Try to sort by search score if we're using scoring and there is a query.\n if (this.scoring && this.#query) {\n const aValue = a._metadata.searchScore || 0;\n const bValue = b._metadata.searchScore || 0;\n if (aValue > bValue) return -1;\n if (aValue < bValue) return 1;\n }\n\n for (const col of sortedColumns) {\n const comp = this.#compareRows(a, b, col);\n if (comp !== 0) {\n return comp;\n }\n }\n\n // Always fall back to the index column\n return a._metadata.index - b._metadata.index;\n });\n this.#updateTable();\n }\n\n #updateHeaders() {\n if (this.#blockUpdates) return;\n\n for (const col of this.#columnData.values()) {\n // Update the order of headers\n col.header.parentElement?.append(col.header);\n col.header.hidden = !col.visible;\n\n if (col.sortOrder === 'asc') {\n col.header?.classList.add('dt-ascending');\n col.header?.classList.remove('dt-descending');\n } else if (col.sortOrder === 'desc') {\n col.header?.classList.add('dt-descending');\n col.header?.classList.remove('dt-ascending');\n } else {\n col.header?.classList.remove('dt-ascending');\n col.header?.classList.remove('dt-descending');\n }\n }\n }\n\n #updateTable() {\n if (this.#blockUpdates) return;\n\n this.#tbody.innerHTML = '';\n if (this.#virtualScroll) {\n try {\n this.#virtualScroll.start(this.#filteredRows.length);\n } catch (error) {\n if (error instanceof VirtualScrollError) {\n console.warn(\n 'Failed to start virtual scroll... falling back to standard rendering',\n );\n console.warn(error.stack);\n }\n }\n } else {\n if (this.#filteredRows.length > WARN_ROW_COUNT) {\n const count = WARN_ROW_COUNT.toLocaleString();\n console.warn(\n `Virtual scroll disabled with more than ${count} rows... Good luck with that!`,\n );\n }\n\n const rowElements = this.#filteredRows.map((_, index) =>\n this.#createRow(index),\n );\n this.#tbody.append(...rowElements);\n }\n\n if (this.#rows.size === 0) {\n this.showMessage(this.#options.noDataText, 'dt-empty');\n } else if (this.#filteredRows.length === 0) {\n this.showMessage(this.#options.noMatchText, 'dt-empty');\n }\n }\n\n #markText(element: HTMLElement, query: RegExp) {\n if (element.children.length === 0) {\n let text = element.innerText;\n const classes = this.#classes.mark.join(\" \");\n text = text.replace(query, match => `<mark class=\"${classes}\">${match}</mark>`);\n element.innerHTML = text;\n } else {\n for (const child of element.children) {\n if (child instanceof HTMLElement) {\n this.#markText(child, query);\n }\n }\n }\n }\n\n #updateCell(\n td: HTMLTableCellElement,\n value: any,\n col: ColumnData,\n row: object,\n ) {\n if (typeof col.valueFormatter === 'function') {\n value = col.valueFormatter(value, row);\n }\n td.innerText = value == null ? '-' : value;\n\n if (typeof col.elementFormatter === 'function') {\n col.elementFormatter(value, row, td);\n }\n\n if (this.#options.highlightSearch && this.#query && col.searchable) {\n this.#markText(td, this.#query);\n }\n\n td.hidden = col.visible ? false : true;\n }\n\n #createRow(index: number): HTMLTableRowElement {\n const row = this.#filteredRows[index];\n const tr = document.createElement('tr');\n tr.classList.add(...this.#classes.tr);\n tr.dataset.dtIndex = String(row._metadata.index);\n\n for (const [field, col] of this.#columnData) {\n const value = this.#getNestedValue(row, field);\n const td = document.createElement('td');\n td.classList.add(...this.#classes.td);\n td.dataset.dtField = field;\n const colWidth = col.header.style.width;\n // If the column has been resized, force the cells to that width.\n if (colWidth && colWidth !== '0px') {\n // We have to set the cells max width to allow text-overflow: ellipsis to work.\n td.style.maxWidth = colWidth;\n }\n\n this.#updateCell(td, value, col, row);\n tr.append(td);\n }\n\n if (typeof this.#options.rowFormatter === 'function') {\n try {\n this.#options.rowFormatter(row, tr);\n } catch (error) {\n console.error('Row formatter callback failed with the following error');\n console.error(error);\n }\n }\n\n return tr;\n }\n\n #getNestedValue(obj: Record<string, any>, path: string) {\n const keys = path.split('.');\n let current = obj;\n\n for (const key of keys) {\n if (current && typeof current === 'object') {\n current = current[key];\n } else {\n return undefined; // Or handle the error as needed\n }\n }\n\n return current;\n }\n\n #resizeColumn(column: string | ColumnData, width?: number) {\n if (typeof column === 'string') {\n const columnData = this.#columnData.get(column);\n if (!columnData) throw new Error('Column not found');\n column = columnData;\n }\n\n let headerWidth, cellWidth;\n if (width == null) {\n headerWidth = '';\n cellWidth = '';\n } else if (width <= 0) {\n headerWidth = '0px';\n cellWidth = '';\n } else {\n headerWidth = `${width}px`;\n cellWidth = `${width}px`;\n }\n ''\n const prevWidth = column.header.offsetWidth;\n column.header.style.width = headerWidth;\n column.header.style.maxWidth = headerWidth;\n\n const cells = this.#tbody.querySelectorAll<HTMLTableCellElement>(\n `td[data-dt-field=\"${column.field}\"]`,\n );\n for (const cell of cells) {\n // If width is 0 it means we want to auto size the columns.\n // To do that we set the width to 0px on the header\n // and clear the max width on all of the cells.\n cell.style.maxWidth = cellWidth;\n }\n\n // Resize the table based on how much the column changed\n const delta = column.header.offsetWidth - prevWidth;\n const tableWidth = this.#table.offsetWidth + delta;\n this.#table.style.width = `${tableWidth}px`;\n }\n\n #resizeColumnStart = (event: MouseEvent) => {\n // If target is not the resizer, we don't care.\n if (!(event.target instanceof HTMLElement)) return;\n if (!event.target.classList.contains('dt-resizer')) return;\n // If the current target isn't the header, we don't care.\n if (!(event.currentTarget instanceof HTMLElement)) return;\n if (!event.currentTarget.dataset.dtField) return;\n\n event.stopImmediatePropagation();\n event.preventDefault();\n\n const field = event.currentTarget.dataset.dtField;\n const col = this.#columnData.get(field);\n if (!col) return;\n this.#resizingColumn = col;\n\n col.resizeStartX = event.clientX;\n col.resizeStartWidth = col.header.offsetWidth;\n\n document.addEventListener('mousemove', this.#resizeColumnMove);\n document.addEventListener('mouseup', this.#resizeColumnEnd);\n };\n\n #resizeColumnMove = (event: MouseEvent) => {\n if (!this.#resizingColumn) return;\n event.stopImmediatePropagation();\n event.preventDefault();\n\n const dx = event.clientX - this.#resizingColumn.resizeStartX!;\n const newWidth = this.#resizingColumn.resizeStartWidth! + dx;\n this.#resizeColumn(this.#resizingColumn, newWidth);\n };\n\n #resizeColumnEnd = (event: MouseEvent) => {\n if (!this.#resizingColumn) return;\n event.stopImmediatePropagation();\n event.preventDefault();\n\n document.removeEventListener('mousemove', this.#resizeColumnMove);\n document.removeEventListener('mouseup', this.#resizeColumnEnd);\n\n const resizeEvent = new CustomEvent<DataTableEventMap['dt.col.resize']>(\n 'dt.col.resize',\n {\n cancelable: false,\n detail: {\n column: this.#resizingColumn.field,\n width: this.#resizingColumn.header.offsetWidth,\n },\n },\n );\n\n this.dispatchEvent(resizeEvent);\n\n this.#resizingColumn = undefined;\n };\n\n #resizeColumnDoubleClick = (event: MouseEvent) => {\n // If target is not the resizer, we don't care.\n if (!(event.target instanceof HTMLElement)) return;\n if (!event.target.classList.contains('dt-resizer')) return;\n // If the current target isn't the header, we don't care.\n if (!(event.currentTarget instanceof HTMLElement)) return;\n if (!event.currentTarget.dataset.dtField) return;\n\n const field = event.currentTarget.dataset.dtField;\n if (!field) return;\n this.#resizeColumn(field);\n };\n\n #dragColumnStart = (event: DragEvent) => {\n const target = event.target as HTMLElement;\n const field = target.dataset.dtField;\n\n if (event.dataTransfer && field) {\n event.dataTransfer.effectAllowed = 'move';\n event.dataTransfer.setData('text/plain', field);\n }\n };\n\n #dragColumnOver = (event: DragEvent) => {\n event.preventDefault();\n if (event.dataTransfer) {\n event.dataTransfer.dropEffect = 'move';\n }\n return false;\n };\n\n #dragColumnEnter = (event: DragEvent) => {\n const target = event.target as HTMLElement;\n target.classList.add('dt-drag-over');\n };\n\n #dragColumnLeave = (event: DragEvent) => {\n const target = event.target as HTMLElement;\n target.classList.remove('dt-drag-over');\n };\n\n #dragColumnDrop = (event: DragEvent) => {\n const dragField = event.dataTransfer?.getData('text/plain');\n const target = event.currentTarget as HTMLElement;\n const dropField = target.dataset.dtField;\n\n if (!dragField || !dropField) return;\n\n event.preventDefault();\n event.stopPropagation();\n\n const columns = [...this.#columnData.values()];\n const dragIndex = columns.findIndex(col => col.field === dragField);\n const dropIndex = columns.findIndex(col => col.field === dropField);\n\n if (dragIndex > -1 && dropIndex > -1) {\n const [draggedColumn] = columns.splice(dragIndex, 1);\n const droppedColumn = this.#columnData.get(dropField);\n if (!droppedColumn) return;\n\n columns.splice(dropIndex, 0, draggedColumn);\n const newColumnOrder = columns.map(col => col.field);\n const reorderEvent = new CustomEvent<DataTableEventMap['dt.col.reorder']>(\n 'dt.col.reorder',\n {\n cancelable: true,\n detail: {\n draggedColumn: draggedColumn.field,\n dropColumn: droppedColumn.field,\n order: newColumnOrder,\n },\n },\n );\n if (!this.dispatchEvent(reorderEvent)) {\n return;\n }\n\n this.setColumnOrder(newColumnOrder);\n }\n };\n\n #dragColumnEnd = () => {\n const elements = document.querySelectorAll('.dt-drag-over');\n for (const element of elements) {\n element.classList.remove('dt-drag-over');\n }\n };\n\n addEventListener<K extends keyof DataTableEventMap>(\n type: K,\n listener: (this: DataTable, ev: CustomEvent<DataTableEventMap[K]>) => any,\n options?: boolean | AddEventListenerOptions,\n ): void;\n\n // This is the generic fallback for any other string event type (e.g., standard DOM events).\n addEventListener(\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ): void;\n\n // The single implementation for both overloads.\n addEventListener(type: any, listener: any, options?: any) {\n super.addEventListener(type, listener, options);\n }\n}\n\ninterface ColumnData {\n field: string;\n title: string;\n sortable: boolean;\n searchable: boolean;\n tokenize: boolean;\n header: HTMLElement;\n headerContent: HTMLElement;\n visible: boolean;\n sortOrder: SortOrder;\n sortPriority: number;\n resizeStartX: number | null;\n resizeStartWidth: number | null;\n valueFormatter?: ValueFormatterCallback;\n elementFormatter?: CellFormatterCallback;\n comparatorCallback?: ComparatorCallback;\n filterCallback?: ColumnFilterCallback;\n sortValueCallback?: SortValueCallback;\n}\n\ninterface InternalRowData extends Record<string, any> {\n _metadata: RowMetadata;\n}\n\ninterface RowMetadata {\n index: number;\n searchScore?: number;\n tokens: Record<string, string[]>;\n sortValues: Record<string, any>;\n}\n\ninterface Classes {\n scroller: string[];\n thead: string[];\n tbody: string[];\n tfoot: string[];\n tr: string[];\n th: string[];\n td: string[];\n mark: string[];\n}\n\nconst WARN_ROW_COUNT = 10_000;\n\n/**\n * Defines the mapping between event names and their detail object types.\n */\nexport interface DataTableEventMap {\n 'dt.row.clicked': {\n row: any;\n index: number;\n column: string | undefined;\n originalEvent: MouseEvent;\n };\n\n 'dt.rows.changed': object;\n\n 'dt.col.sort': {\n column: string;\n order: SortOrder;\n };\n\n 'dt.col.visibility': {\n column: string;\n visible: boolean;\n };\n\n 'dt.col.resize': {\n column: string;\n width: number;\n };\n\n 'dt.col.reorder': {\n draggedColumn: string;\n dropColumn: string;\n order: string[];\n };\n}\n\nexport type * from './types';\n","import { DataTable } from '../datatable';\nimport { ColumnState } from '../types';\n\ninterface Options {\n saveColumnSorting: boolean;\n saveColumnOrder: boolean;\n saveColumnVisibility: boolean;\n saveColumnWidth: boolean;\n}\n\nexport class LocalStorageAdapter {\n #dataTable: DataTable;\n #storageKey: string;\n #options: Options = {\n saveColumnSorting: true,\n saveColumnVisibility: true,\n saveColumnWidth: true,\n saveColumnOrder: true,\n };\n\n /**\n * @param dataTable - The DataTable instance to monitor.\n * @param storageKey - The key to use for saving the state in localStorage.\n * @param options - The key to use for saving the state in localStorage.\n */\n constructor(dataTable: DataTable, storageKey: string, options?: Options) {\n this.#dataTable = dataTable;\n this.#storageKey = storageKey;\n this.#options = { ...this.#options, ...options };\n\n // Restore state before adding the listeners.\n this.restoreState();\n\n if (this.#options.saveColumnSorting) {\n dataTable.addEventListener('dt.col.sort', this.#saveStateAfterEvent);\n }\n\n if (this.#options.saveColumnVisibility) {\n dataTable.addEventListener(\n 'dt.col.visibility',\n this.#saveStateAfterEvent,\n );\n }\n\n if (this.#options.saveColumnWidth) {\n dataTable.addEventListener('dt.col.resize', this.#saveStateAfterEvent);\n }\n\n if (this.#options.saveColumnOrder) {\n dataTable.addEventListener('dt.col.reorder', this.#saveStateAfterEvent);\n }\n }\n\n /**\n * Saves the current column state to localStorage.\n */\n saveState() {\n const states: Partial<ColumnState>[] = this.#dataTable.columnStates;\n for (const state of states) {\n if (!this.#options.saveColumnSorting) {\n state.sortOrder = undefined;\n state.sortPriority = undefined;\n }\n\n if (!this.#options.saveColumnVisibility) {\n state.visible = undefined;\n }\n\n if (!this.#options.saveColumnWidth) {\n state.width = undefined;\n }\n }\n\n localStorage.setItem(\n this.#storageKey,\n JSON.stringify(this.#dataTable.columnStates),\n );\n }\n\n /**\n * Restores the column state from localStorage.\n */\n restoreState() {\n const savedState = localStorage.getItem(this.#storageKey);\n if (!savedState) return;\n\n try {\n const columnStates = JSON.parse(savedState) as ColumnState[];\n this.#dataTable.columnStates = columnStates;\n\n if (this.#options.saveColumnOrder) {\n this.#dataTable.setColumnOrder(\n columnStates.map((col: ColumnState) => col.field),\n );\n }\n } catch (error) {\n console.error('Failed to restore DataTable state:', error);\n }\n }\n\n /**\n * Clears the saved state from localStorage.\n */\n clearState() {\n localStorage.removeItem(this.#storageKey);\n }\n\n #saveStateAfterEvent = () => setTimeout(() => this.saveState(), 0);\n}\n"],"mappings":"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","names":["src_exports","__export","DataTable","LocalStorageAdapter","classesToArray","classes","toHumanReadable","str","char","whitespaceTokenizer","value","_warned","_container","_element","_generator","_rowCount","_rowHeight","_padding","_animationFrame","_started","_scrollTop","_scrollCallback","_renderCallback","_VirtualScroll_instances","updateRowHeight_fn","_VirtualScroll","container","element","generator","nodePadding","__privateAdd","__privateGet","__privateSet","entries","entry","__privateMethod","index","px","rowCount","scrollTop","rowHeight","padding","totalContentHeight","actualHeight","viewHeight","startNode","visibleNodesCount","offsetY","remainingHeight","visibleChildren","_","topRow","bottomRow","e","renderSize","elements","i","VirtualScrollError","VirtualScroll","message","_table","_thead","_tbody","_scroller","_columnData","_rows","_filteredRows","_query","_filters","_virtualScroll","_sortPriority","_classes","_resizingColumn","_options","_blockUpdates","_DataTable_instances","loadRow_fn","searchField_fn","filterField_fn","filterRow_fn","filterRows_fn","compareRows_fn","sortRows_fn","updateHeaders_fn","updateTable_fn","markText_fn","updateCell_fn","createRow_fn","getNestedValue_fn","resizeColumn_fn","_resizeColumnStart","_resizeColumnMove","_resizeColumnEnd","_resizeColumnDoubleClick","_dragColumnStart","_dragColumnOver","_dragColumnEnter","_dragColumnLeave","_dragColumnDrop","_dragColumnEnd","_DataTable","table","options","_a","_b","_c","_d","_e","_f","_g","_h","_i","__privateAdd","event","field","col","__privateGet","__privateSet","dx","newWidth","__privateMethod","resizeEvent","dragField","dropField","columns","dragIndex","dropIndex","draggedColumn","droppedColumn","newColumnOrder","reorderEvent","elements","element","__spreadValues","tableElement","classesToArray","thead","headerRow","tbody","tr","td","index","row","value","rowEvent","colVisible","colOptions","colData","toHumanReadable","th","headerContent","titleWrapper","titleElement","sorter","resizer","states","state","column","VirtualScroll","rows","scrollTop","scrollLeft","internal_row","text","classes","colSpan","query","tokens","filters","colName","order","__privateWrapper","sortEvent","visisble","visibilityEvent","filename","all","csvHeaders","csvRows","list","key","csvContent","blob","a","rowData","filteredIndex","theadHeight","px","fields","newColumns","found_row","data","current_row","callback","type","listener","metadata","accumulator","currentValue","matches","filter","filterFunction","filterCallback","c","score","changeEvent","b","aValue","bValue","ret","sortedColumns","comp","error","VirtualScrollError","WARN_ROW_COUNT","count","rowElements","_","match","child","colWidth","obj","path","keys","current","width","columnData","headerWidth","cellWidth","prevWidth","cells","cell","delta","tableWidth","whitespaceTokenizer","DataTable","_dataTable","_storageKey","_options","_saveStateAfterEvent","LocalStorageAdapter","dataTable","storageKey","options","__privateAdd","__privateSet","__spreadValues","__privateGet","states","state","savedState","columnStates","col","error"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/utils.ts","../src/virtualScroll.ts","../src/datatable.ts","../src/plugins/localStorageAdapter.ts"],"sourcesContent":["export * from './types';\nexport * from './datatable';\nexport * from './plugins/localStorageAdapter';\n","export const classesToArray = (classes: string[] | string | undefined) => {\n if (typeof classes === 'string' && classes !== '') {\n return classes.split(' ');\n } else if (Array.isArray(classes)) {\n return classes;\n } else if (!classes) {\n return [];\n }\n throw new TypeError('classes must be string or array of strings');\n};\n\n/*\n * Converts a string to a human-readable format.\n * - Replaces underscores with spaces\n * - Inserts spaces before uppercase letters (for camelCase)\n * - Capitalizes the first letter of each word\n *\n * @param {string} str - The input string to convert.\n * @returns {string} - The converted human-readable string.\n */\nexport const toHumanReadable = (str: string) => {\n return (\n str\n // Replace underscores with spaces\n .replace(/_/g, ' ')\n // Insert spaces before uppercase letters (for camelCase)\n .replace(/([a-z])([A-Z])/g, '$1 $2')\n // Capitalize the first letter of each word\n .replace(/\\b\\w/g, char => char.toUpperCase())\n );\n};\n\n/**\n * Tokenizes a string into an array of lowercase words separated by whitespace.\n */\nexport const whitespaceTokenizer = (value: string) => {\n const regex = /\"[^\"]*\"|\\S+/g;\n \n // Find all matches, which will include the quotes\n const matches = value.match(regex) || [];\n \n // Clean up the results by removing the surrounding quotes\n return matches.map(token => {\n if (token.startsWith('\"') && token.endsWith('\"')) {\n return token.slice(1, -1);\n }\n return token;\n });\n}\n","const MAX_ELEMENT_HEIGHT = 33554400;\n\nexport class VirtualScroll {\n static #warned = false;\n\n #container;\n #element;\n #generator;\n #rowCount = 0;\n #rowHeight = 0;\n #padding = 2;\n #animationFrame = 0;\n #started = false;\n #scrollTop = 0;\n\n constructor({\n container,\n element,\n generator,\n nodePadding = 10,\n }: VirtualScrollOptions) {\n this.#container = container;\n this.#element = element;\n this.#generator = generator;\n this.#padding = nodePadding;\n\n // Watch for visual changes on our virtual scroll element.\n // This allows us to avoid rendering when the element isn't\n // shown since it can't do the calculations and then start\n // rendering once the element comes into view.\n const observer = new IntersectionObserver(entries => {\n for (const entry of entries) {\n if (entry.intersectionRatio === 1) {\n this.renderChunk();\n }\n }\n });\n observer.observe(this.#element);\n }\n\n get rowHeight() {\n if (!this.#rowHeight) {\n this.#updateRowHeight();\n }\n return this.#rowHeight;\n }\n\n get started() {\n return this.#started;\n }\n\n /*\n * Scroll to a specific index in the virtual scroll.\n * @param index The index to scroll to.\n * @throws RangeError if the index is out of bounds.\n */\n scrollToIndex(index: number) {\n if (index < 0 || index >= this.#rowCount) {\n throw new RangeError('Index out of bounds.');\n }\n this.scrollToPx(this.rowHeight * index);\n }\n\n /**\n * @param px\n */\n scrollToPx(px: number) {\n this.#container.scrollTop = px;\n this.renderChunk();\n }\n\n #scrollCallback = () => {\n // Only update if we are vertically scrolling.\n // Fixes horizontal scroll bug.\n if (this.#container.scrollTop !== this.#scrollTop) {\n this.#scrollTop = this.#container.scrollTop;\n if (this.#animationFrame) {\n cancelAnimationFrame(this.#animationFrame);\n }\n this.#animationFrame = requestAnimationFrame(() => this.renderChunk());\n }\n };\n\n #renderCallback = () => {\n this.renderChunk();\n };\n\n start(rowCount: number) {\n if (!this.#started) {\n this.#container.addEventListener('scroll', this.#scrollCallback);\n window.addEventListener('resize', this.#renderCallback);\n this.#started = true;\n }\n this.#container.classList.add(\"dt-virtual-scroll\");\n this.#rowCount = rowCount;\n this.renderChunk();\n }\n\n stop() {\n if (this.#animationFrame) {\n cancelAnimationFrame(this.#animationFrame);\n }\n\n this.#container.classList.remove(\"dt-virtual-scroll\");\n this.#container.removeEventListener('scroll', this.#scrollCallback);\n window.removeEventListener('resize', this.#renderCallback);\n this.#started = false;\n }\n\n renderChunk() {\n const scrollTop = this.#container.scrollTop;\n const rowCount = this.#rowCount;\n const rowHeight = this.rowHeight;\n const padding = this.#padding;\n\n if (\n !this.started ||\n !this.#element.checkVisibility() ||\n !rowCount ||\n !rowHeight\n ) {\n return;\n }\n\n const totalContentHeight = rowHeight * rowCount;\n // Max out the element height so we can get a real height of the container.\n // This fixes an issue when the parent isn't set to grow causing only a\n // small number of rows to render until you scroll.\n this.#element.innerHTML = `<div style=\"height: ${totalContentHeight}px;\"></div>`;\n const actualHeight = this.#element.offsetHeight;\n const viewHeight = this.#container.offsetHeight;\n\n if (\n !VirtualScroll.#warned &&\n actualHeight < Math.round(totalContentHeight - 1)\n ) {\n VirtualScroll.#warned = true;\n console.error(\n 'Max element height exceeded. Virtual scroll may not work.',\n );\n }\n\n let startNode = Math.floor(scrollTop / rowHeight) - padding;\n startNode = Math.max(0, startNode);\n \n let visibleNodesCount = Math.ceil(viewHeight / rowHeight) + 2 * padding;\n visibleNodesCount = Math.min(rowCount - startNode, visibleNodesCount);\n\n // Always start with an even row.\n // This helps striped tables.\n if (startNode % 2 === 1) {\n startNode--;\n }\n\n \n\n const offsetY = startNode * rowHeight;\n const remainingHeight =\n totalContentHeight - (offsetY + visibleNodesCount * rowHeight);\n\n try {\n this.#element.innerHTML = '';\n const visibleChildren = new Array(visibleNodesCount)\n .fill(null)\n .map((_, index) => this.#generator(index + startNode));\n // We create two empty rows. One at the top and one at the bottom.\n // Resize the rows accordingly to move the rendered rows to where we want.\n const topRow = document.createElement('div');\n const bottomRow = document.createElement('div');\n topRow.style.visibility = 'hidden';\n topRow.style.height = offsetY + 'px';\n bottomRow.style.visibility = 'hidden';\n bottomRow.style.height = remainingHeight + 'px';\n this.#element.append(topRow);\n this.#element.append(...visibleChildren);\n this.#element.append(bottomRow);\n } catch (e) {\n if (e instanceof RangeError) {\n console.log(e);\n }\n }\n }\n\n #updateRowHeight() {\n if (this.#rowCount === 0 || !this.#element.checkVisibility()) {\n this.#rowHeight = 0;\n return;\n }\n\n const AVERAGE_RENDER_COUNT = 1000;\n const renderSize = Math.min(AVERAGE_RENDER_COUNT, this.#rowCount);\n // Create an average row height by rendering the first N rows.\n const elements = [];\n for (let i = 0; i < renderSize; ++i) {\n elements.push(this.#generator(i));\n }\n this.#element.innerHTML = '';\n this.#element.append(...elements);\n this.#rowHeight = this.#element.offsetHeight / renderSize;\n\n if (this.#rowHeight <= 0) {\n throw new VirtualScrollError(\n `First ${renderSize} rows had no rendered height. Virtual scroll can't be used.`,\n );\n } else if (this.#rowHeight * this.#rowCount > MAX_ELEMENT_HEIGHT) {\n // This seems to be Chrome's max height of an element based on some random testing.\n console.warn(\n 'Virtual scroll height exceeded maximum known element height.',\n );\n }\n }\n}\n\nexport class VirtualScrollError extends Error {\n constructor(message: string) {\n super(message);\n }\n}\n\nexport interface VirtualScrollOptions {\n container: HTMLElement;\n element: HTMLElement;\n generator: (index: number) => HTMLElement;\n nodePadding?: number;\n}\n","import './datatable.css';\n\nimport {\n CellFormatterCallback,\n ColumnFilterCallback,\n ColumnOptions,\n ColumnState,\n ComparatorCallback,\n FilterCallback,\n LoadOptions,\n SortOrder,\n SortValueCallback,\n TableOptions,\n ValueFormatterCallback,\n} from './types';\nimport { classesToArray, toHumanReadable, whitespaceTokenizer } from './utils';\nimport { VirtualScroll, VirtualScrollError } from './virtualScroll';\n\ntype RequiredOptions = Required<Omit<TableOptions, 'columns' | 'data' | 'rowFormatter'>> & Pick<TableOptions, 'rowFormatter' | 'data'>;\ntype FinalOptions = RequiredOptions & Pick<TableOptions, 'columns'>;\n\n/**\n * Represents a dynamic and interactive table with features like sorting, searching, filtering,\n * column resizing, column rearranging, and virtual scrolling.\n *\n * @example\n * ```ts\n * const tableElement = document.getElementById('myTable');\n * const options = {\n * columns: [\n * { field: 'id', title: 'ID', sortable: true },\n * { field: 'name', title: 'Name', searchable: true },\n * { field: 'age', title: 'Age', sortable: true, valueFormatter: (value) => `${value} years` }\n * ],\n * data: [\n * { id: 1, name: 'Alice', age: 30 },\n * { id: 2, name: 'Bob', age: 24 },\n * ],\n * virtualScroll: true,\n * resizable: true,\n * rearrangeable: true,\n * };\n * const dataTable = new DataTable(tableElement, options);\n * ```\n */\nexport class DataTable extends EventTarget {\n // Centralized default options for the DataTable.\n // These are the base values used if not overridden by user-provided options.\n private static readonly DEFAULT_OPTIONS: RequiredOptions = {\n virtualScroll: true,\n highlightSearch: true,\n sortable: true,\n searchable: false,\n tokenize: false,\n scoring: true,\n resizable: true,\n rearrangeable: true,\n extraSearchFields: [],\n noDataText: 'No records found',\n noMatchText: 'No matching records found',\n classes: {\n scroller: 'dt-scroller',\n thead: 'dt-headers',\n tbody: '',\n tfoot: '',\n tr: '',\n th: '',\n td: '',\n },\n tokenizer: whitespaceTokenizer, // Default tokenizer function\n };\n\n // Table elements\n #table!: HTMLTableElement;\n #thead!: HTMLElement;\n #tbody!: HTMLElement;\n #scroller!: HTMLElement;\n\n #columnData: Map<string, ColumnData> = new Map();\n\n // Current data stored by the initial index\n #rows: Map<number, InternalRowData> = new Map();\n #filteredRows: InternalRowData[] = [];\n\n // Search and filter data\n #query?: RegExp;\n #filters!: any | FilterCallback;\n\n #virtualScroll?: VirtualScroll;\n\n // The current sort priority. Incremented when a column is sorted.\n #sortPriority: number = 0;\n\n #classes: Classes;\n #resizingColumn?: ColumnData;\n\n #options: FinalOptions;\n\n #blockUpdates = false;\n\n /**\n * Initializes a new instance of the DataTable.\n * @param table - The HTMLTableElement or a CSS selector string for the table.\n * @param options - Optional configuration options for the DataTable.\n * @throws {SyntaxError} If the table selector does not find an element.\n * @throws {TypeError} If the provided table element is not an HTMLTableElement or if columns option is not an array.\n */\n constructor(table: string | HTMLTableElement, options: TableOptions = {}) {\n super();\n\n this.#options = {\n columns: [],\n data: [],\n ...DataTable.DEFAULT_OPTIONS,\n ...options,\n };\n\n if (typeof table === 'string') {\n const tableElement = document.querySelector(table);\n if (!tableElement)\n throw new SyntaxError(`Failed to find table using selector ${table}`);\n this.#table = tableElement as HTMLTableElement;\n } else {\n this.#table = table;\n }\n\n if (!(this.#table instanceof HTMLTableElement)) {\n throw new TypeError(\n `Invalid table element type. Must be HTMLTableElement`,\n );\n }\n\n if (!Array.isArray(this.#options.columns)) {\n throw new TypeError('columns must be a list of columns');\n }\n\n\n this.#classes = {\n scroller: [\n ...classesToArray(this.#options.classes.scroller),\n ...classesToArray(DataTable.DEFAULT_OPTIONS.classes.scroller),\n ],\n thead: [\n ...classesToArray(this.#options.classes.thead),\n ...classesToArray(DataTable.DEFAULT_OPTIONS.classes.thead),\n ],\n tbody: [\n ...classesToArray(this.#options.classes.tbody),\n ...classesToArray(DataTable.DEFAULT_OPTIONS.classes.tbody),\n ],\n tfoot: [\n ...classesToArray(this.#options.classes.tfoot),\n ...classesToArray(DataTable.DEFAULT_OPTIONS.classes.tfoot),\n ],\n tr: [\n ...classesToArray(this.#options.classes.tr),\n ...classesToArray(DataTable.DEFAULT_OPTIONS.classes.tr),\n ],\n th: [\n ...classesToArray(this.#options.classes.th),\n ...classesToArray(DataTable.DEFAULT_OPTIONS.classes.th),\n ],\n td: [\n ...classesToArray(this.#options.classes.td),\n ...classesToArray(DataTable.DEFAULT_OPTIONS.classes.td),\n ],\n mark: [\n ...classesToArray(this.#options.classes.mark),\n ...classesToArray(DataTable.DEFAULT_OPTIONS.classes.mark),\n ]\n };\n\n this.#table.classList.add('data-table');\n\n // Inner element that handles the virtual scroll.\n this.#scroller = document.createElement('div');\n this.#scroller.classList.add(...this.#classes.scroller);\n this.#scroller.style.overflow = 'auto';\n this.#scroller.style.height = '100%';\n\n // If the user tries to provide a height, we will use that for the scroller.\n if (this.#table.style.height !== '') {\n this.#scroller.style.height = this.#table.style.height;\n this.#table.style.height = '';\n }\n\n // Add the scroller before the table so when we move the\n // table into the scroller it stays in the same place.\n this.#table.parentElement?.insertBefore(this.#scroller, this.#table);\n this.#scroller.append(this.#table);\n\n if (this.#table.querySelectorAll('thead').length > 1) {\n console.warn('Multiple theads found in table. Using last one.');\n }\n\n if (this.#table.querySelectorAll('tbody').length > 1) {\n console.warn('Multiple tbodys found in table. Using first one.');\n }\n\n // Hopefully there isn't more than one header or body\n // but if there is, use the last header and first body\n // since that seems like it would make the most sense.\n const thead = this.#table.querySelector('thead:last-of-type');\n if (thead) {\n this.#thead = thead as HTMLTableElement;\n } else {\n this.#thead = document.createElement('thead');\n this.#table.insertBefore(this.#thead, this.#table.firstChild);\n }\n\n this.#thead.classList.add(...this.#classes.thead);\n\n // Create the row for the thead if there isn't one\n let headerRow = this.#thead.querySelector('tr:last-of-type');\n if (!headerRow) {\n headerRow = document.createElement('tr');\n this.#thead.append(headerRow);\n }\n\n headerRow.classList.add(...this.#classes.tr);\n // Remove any existing header cells\n // TODO: Add ability to use HTML headers provided by the user.\n headerRow.innerHTML = '';\n\n const tbody = this.#table.querySelector('tbody:first-of-type');\n // Create the tbody if it doesn't exists\n if (tbody) {\n this.#tbody = tbody as HTMLTableElement;\n } else {\n this.#tbody = document.createElement('tbody');\n this.#table.append(this.#tbody);\n }\n\n this.#tbody.classList.add(...this.#classes.tbody);\n\n this.#tbody.addEventListener('click', event => {\n // Ignore events if the user is highlighting text\n if (window.getSelection()?.toString()) return;\n\n let tr, td, field;\n if (event.target instanceof HTMLTableCellElement) {\n td = event.target;\n tr = td.parentElement;\n field = td.dataset.dtField;\n } else if (event.target instanceof HTMLTableRowElement) {\n tr = event.target;\n }\n\n if (tr) {\n const index = parseInt(tr.dataset.dtIndex || '');\n if (!isNaN(index)) {\n const row = this.#filteredRows.find(\n value => value._metadata.index === index,\n );\n if (row) {\n const rowEvent = new CustomEvent<\n DataTableEventMap['dt.row.clicked']\n >('dt.row.clicked', {\n cancelable: false,\n detail: {\n row: row,\n index: index,\n column: field,\n originalEvent: event,\n },\n });\n this.dispatchEvent(rowEvent);\n }\n }\n }\n });\n\n let colVisible = false;\n // Initialize columns\n for (const colOptions of this.#options.columns) {\n const colData: ColumnData = {\n field: colOptions.field,\n title: colOptions.title || toHumanReadable(colOptions.field),\n header: document.createElement('th'),\n headerContent: document.createElement('div'),\n visible: colOptions.visible ?? true,\n sortable: colOptions.sortable ?? this.#options.sortable,\n searchable: colOptions.searchable ?? this.#options.searchable,\n tokenize: colOptions.tokenize ?? this.#options.tokenize,\n sortOrder: colOptions.sortOrder ?? null,\n sortPriority: colOptions.sortPriority ?? 0,\n resizeStartWidth: null,\n resizeStartX: null,\n valueFormatter: colOptions.valueFormatter,\n elementFormatter: colOptions.elementFormatter,\n comparatorCallback: colOptions.sorter,\n filterCallback: colOptions.filter,\n sortValueCallback: colOptions.sortValue,\n };\n this.#columnData.set(colOptions.field, colData);\n\n const th = colData.header;\n th.classList.add(...this.#classes.th);\n th.dataset.dtField = colOptions.field;\n th.hidden = !colData.visible;\n\n const headerContent = colData.headerContent;\n headerContent.classList.add('dt-header-content');\n th.append(headerContent);\n\n const titleWrapper = document.createElement('div');\n titleWrapper.classList.add('dt-header-title-wrapper');\n headerContent.append(titleWrapper);\n\n const titleElement = document.createElement('span');\n titleElement.classList.add('dt-header-title');\n titleElement.innerHTML = colData.title;\n titleWrapper.append(titleElement);\n\n const sorter = document.createElement('div');\n sorter.classList.add('dt-sort-icon');\n titleWrapper.append(sorter);\n\n const resizer = document.createElement('div');\n resizer.classList.add('dt-resizer');\n headerContent.append(resizer);\n\n headerRow.append(th);\n\n // We need at least one column visible\n if (colData.visible) {\n colVisible = true;\n }\n\n if (colData.sortable) {\n th.classList.add('dt-sortable');\n }\n\n if (this.#options.rearrangeable) {\n th.draggable = true;\n }\n\n if (colOptions.resizable ?? this.#options.resizable) {\n th.classList.add('dt-resizable');\n }\n\n // Sort event listener\n titleWrapper.addEventListener('click', () => {\n if (!th.classList.contains('dt-sortable')) return;\n\n if (!colData.sortOrder) {\n this.sort(colData.field, 'asc');\n } else if (colData.sortOrder === 'asc') {\n this.sort(colData.field, 'desc');\n } else if (colData.sortOrder) {\n this.sort(colData.field, null);\n }\n });\n\n // Drag and drop event listeners\n th.addEventListener('dragstart', this.#dragColumnStart);\n th.addEventListener('dragenter', this.#dragColumnEnter);\n th.addEventListener('dragover', this.#dragColumnOver);\n th.addEventListener('dragleave', this.#dragColumnLeave);\n th.addEventListener('drop', this.#dragColumnDrop);\n th.addEventListener('dragend', this.#dragColumnEnd);\n // Resize event listeners\n th.addEventListener('mousedown', this.#resizeColumnStart);\n th.addEventListener('dblclick', this.#resizeColumnDoubleClick);\n\n if (typeof colOptions.width === 'number') {\n th.style.width = colOptions.width + 'px';\n } else if (typeof colOptions.width === 'string') {\n th.style.width = colOptions.width;\n }\n }\n\n if (this.#columnData.size === 0) {\n console.warn('No columns found. At least one column is required.');\n } else if (!colVisible) {\n console.warn(\n 'At least a single column must be visible. Showing the first column.',\n );\n const col = this.#columnData.keys().next().value!;\n this.showColumn(col);\n }\n\n this.virtualScroll = this.#options.virtualScroll;\n this.loadData(this.#options.data ?? []);\n }\n\n /**\n * Gets or sets the state of all columns in the table.\n * This can be used to save and restore column configurations like visibility, sort order, and width.\n * When setting, it attempts to apply the states to existing columns.\n */\n get columnStates(): ColumnState[] {\n return [...this.#columnData.values()].map(col => {\n return {\n field: col.field,\n title: col.title,\n visible: col.visible,\n sortOrder: col.sortOrder,\n sortPriority: col.sortPriority,\n width: col.header.style.width,\n } as ColumnState;\n });\n }\n\n set columnStates(states: ColumnState[]) {\n for (const state of states) {\n const column = this.#columnData.get(state.field);\n if (!column) {\n console.warn(\n `Attempting to restore state for non-existent column ${state.field}`,\n );\n continue;\n }\n\n column.visible = state.visible ?? column.visible;\n column.sortOrder = state.sortOrder ?? column.sortOrder;\n column.sortPriority = state.sortPriority ?? column.sortPriority;\n column.header.style.width = state.width ?? column.header.style.width;\n }\n this.refresh();\n }\n\n /**\n * Gets the currently filtered and sorted rows displayed in the table.\n */\n get rows(): any[] {\n return [...this.#filteredRows];\n }\n\n /**\n * Gets the underlying data\n */\n get data(): any[] {\n return [...this.#rows.values()];\n }\n\n /**\n * Gets the total number of currently filtered and sorted rows.\n */\n get length(): number {\n return this.#filteredRows ? this.#filteredRows.length : 0;\n }\n\n /**\n * Gets the underlying HTMLTableElement managed by this DataTable instance.\n */\n get table(): HTMLTableElement {\n return this.#table;\n }\n\n /**\n * Gets or sets the virtual scroll behavior for the table.\n * When `true`, virtual scrolling is enabled, rendering only visible rows for performance with large datasets.\n * When `false`, virtual scrolling is disabled, and all rows are rendered.\n * @default true\n */\n get virtualScroll(): boolean {\n return !!this.#virtualScroll;\n }\n\n set virtualScroll(value) {\n if (value == this.virtualScroll) return;\n\n if (value) {\n this.#virtualScroll = new VirtualScroll({\n container: this.#scroller,\n element: this.#tbody,\n generator: index => this.#createRow(index),\n });\n } else {\n this.#virtualScroll?.stop();\n this.#virtualScroll = undefined;\n }\n\n this.#updateTable();\n }\n\n get scoring(): boolean {\n return this.#options.scoring;\n }\n\n set scoring(value) {\n if (value !== this.#options.scoring) {\n this.#options.scoring = value;\n\n if (this.#query) {\n this.#filterRows();\n }\n }\n }\n\n /**\n * Loads data into the table\n * @param rows - An array of data to be loaded\n * @param options - Configuration for the load operation\n */\n loadData(rows: any[], options: LoadOptions = {}) {\n const scrollTop = this.#scroller.scrollTop;\n const scrollLeft = this.#scroller.scrollLeft;\n\n if (!options.append) {\n this.#rows.clear();\n this.#filteredRows = [];\n }\n\n let index = this.#rows.size;\n for (const row of rows) {\n const internal_row = this.#loadRow(row, index);\n this.#rows.set(index, internal_row);\n index++;\n }\n\n this.#updateHeaders();\n this.#filterRows();\n\n if (options.keepScroll) {\n this.#scroller.scrollTop = scrollTop;\n this.#scroller.scrollLeft = scrollLeft;\n this.#virtualScroll?.renderChunk();\n }\n }\n\n /**\n * Displays a message in the table body, typically used for \"no data\" or \"no results\" states.\n * The message is shown in a single row spanning all columns.\n * @param text - The text or HTML message to display.\n * @param classes - A string or array of strings for CSS classes to apply to the message row.\n */\n showMessage(text: string, classes: string | string[]) {\n if (Array.isArray(classes)) {\n classes = classes.join(' ');\n } else if (typeof classes !== 'string') {\n classes = '';\n }\n\n const colSpan = this.#columnData.size;\n this.#tbody.innerHTML = `<tr class=\"${classes}\"><td colSpan=${colSpan}>${text}</td></tr>`;\n }\n\n /**\n * Clears the current message and dispalsy the normal table data.\n */\n clearMessage() {\n this.#updateTable();\n }\n\n /**\n * Filters rows based on a search query.\n * The search is performed on columns marked as `searchable` and `extraSearchFields`.\n * @param query - The search term (string) or a regular expression. An empty string clears the search.\n */\n search(query?: string | RegExp) {\n // Clear search on empty string\n if (query === \"\") {\n query = undefined;\n }\n\n if (typeof query === 'string') {\n // Escape any special RegEx characters\n query = query.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&').trim();\n const tokens = this.#options.tokenizer(query).join(\"|\");\n this.#query = new RegExp(`${tokens}`, 'gi');\n } else {\n this.#query = query;\n }\n\n this.#filterRows();\n }\n\n /**\n * Applies filters to the table rows.\n * Filters can be an object where keys are field names and values are the criteria to filter by,\n * or a callback function that receives a row and its index and returns `true` if the row should be included.\n * @param filters - An object defining field-based filters or a custom filter callback function.\n * @throws {TypeError} If `filters` is not an object or a function.\n */\n filter(filters?: any | FilterCallback) {\n filters ??= {};\n\n if (typeof filters !== 'object' && typeof filters !== 'function') {\n throw new TypeError('filters must be object or function');\n }\n this.#filters = filters;\n this.#filterRows();\n }\n\n /**\n * Sorts the table by a specified column and order.\n * If `order` is `null`, the sort on this column is removed.\n * @param colName - The field name of the column to sort by.\n * @param order - The sort order: 'asc', 'desc', or `null` to remove sorting for this column.\n */\n sort(colName: string, order: SortOrder) {\n const col = this.#columnData.get(colName);\n if (!col) {\n console.warn(`Attempting to sort non-existent column ${colName}`);\n return;\n }\n\n if (order != col.sortOrder) {\n if (order === 'asc' || order === 'desc') {\n // If we are changing the sort order of a column\n // keep it's existing priority.\n if (col.sortPriority === Number.MAX_VALUE) {\n col.sortPriority = this.#sortPriority++;\n }\n } else {\n col.sortPriority = Number.MAX_VALUE;\n this.#sortPriority--;\n }\n col.sortOrder = order;\n }\n\n const sortEvent = new CustomEvent<DataTableEventMap['dt.col.sort']>(\n 'dt.col.sort',\n {\n cancelable: true,\n detail: {\n column: col.field,\n order: col.sortOrder,\n },\n },\n );\n\n if (!this.dispatchEvent(sortEvent)) {\n return;\n }\n\n const scrollTop = this.#scroller.scrollTop;\n const scrollLeft = this.#scroller.scrollLeft;\n\n this.#updateHeaders();\n this.#sortRows();\n\n this.#scroller.scrollTop = scrollTop;\n this.#scroller.scrollLeft = scrollLeft;\n this.#virtualScroll?.renderChunk();\n }\n\n /**\n * Sets the visibility of a specified column.\n * @param colName - The field name of the column.\n * @param visisble - `true` to show the column, `false` to hide it.\n */\n setColumnVisibility(colName: string, visisble: boolean) {\n const col = this.#columnData.get(colName);\n if (!col) {\n console.warn(\n `Attempting to ${visisble ? 'show' : 'hide'\n } non-existent column ${colName}`,\n );\n return;\n }\n\n if (col.visible === visisble) {\n return;\n }\n\n const visibilityEvent = new CustomEvent<\n DataTableEventMap['dt.col.visibility']\n >('dt.col.visibility', {\n cancelable: true,\n detail: {\n column: col.field,\n visible: visisble,\n },\n });\n\n if (!this.dispatchEvent(visibilityEvent)) {\n return;\n }\n\n col.visible = visisble;\n this.#updateHeaders();\n // If we hide a column that has sorting, we need to resort.\n // This will also handle hiding all of the columns elements.\n this.#sortRows();\n }\n\n /**\n * Shows a previously hidden column.\n * @param field - The field name of the column to show.\n */\n showColumn(field: string) {\n this.setColumnVisibility(field, true);\n }\n\n /**\n * Hides a visible column.\n * @param field - The field name of the column to hide.\n */\n hideColumn(field: string) {\n this.setColumnVisibility(field, false);\n }\n\n /**\n * Export the current visible table data to a CSV file.\n * @param filename - The name of the file to save.\n * @param all - If `true`, exports all original data (ignoring filters). If `false` (default), exports only the currently visible (filtered and sorted) rows.\n */\n export(filename: string, all = false) {\n const data = all ? this.#rows : this.#filteredRows;\n const rows = [...data.values()];\n\n const csvHeaders = [...this.#columnData.values()]\n .filter(col => all || col.visible)\n .map(col => `\"${col.title}\"`)\n .join(',');\n\n const csvRows = rows\n .map(row => {\n const list = [];\n for (const key of Object.keys(row)) {\n const col = this.#columnData.get(key);\n if (!col) {\n continue;\n }\n\n let value = row[key];\n if (all || !col.header.hidden) {\n if (typeof col.valueFormatter === 'function') {\n value = col.valueFormatter(value, row);\n }\n\n value = String(value).replace('\"', '\"\"');\n list.push(`\"${value}\"`);\n }\n }\n return list.join(',');\n })\n .join('\\n');\n\n const csvContent = csvHeaders + '\\n' + csvRows;\n const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8,' });\n const a = document.createElement('a');\n a.style.display = 'none';\n a.href = URL.createObjectURL(blob);\n a.download = `${filename}.csv`;\n document.body.append(a);\n a.click();\n a.remove();\n }\n\n scrollToRow(row: any) {\n const rowData = row as InternalRowData;\n const index = rowData._metadata?.index;\n if (typeof index === 'number') {\n this.scrollToOriginalIndex(index);\n } else {\n throw new TypeError('Invalid row');\n }\n }\n\n /**\n * Scrolls the table to bring the row at the specified original index into view.\n * @param index - The original index of the row (from the initial dataset).\n */\n scrollToOriginalIndex(index: number) {\n const rowData = this.#rows.get(index);\n if (rowData) {\n const filteredIndex = this.#filteredRows.indexOf(rowData);\n if (filteredIndex >= 0) {\n this.scrollToFilteredIndex(filteredIndex);\n return;\n } else {\n throw new Error('Cannot scroll to filtered out row');\n }\n } else {\n throw new RangeError(`Row index ${index} out of range`);\n }\n }\n\n scrollToFilteredIndex(index: number) {\n const rowData = this.#filteredRows[index];\n if (!rowData) {\n throw new RangeError(`Row index ${index} out of range`);\n }\n\n if (this.#virtualScroll) {\n this.#virtualScroll.scrollToIndex(index);\n } else {\n const row = this.#tbody.querySelector(\n `tr[data-dt-index=\"${rowData._metadata.index}\"]`,\n );\n if (row) {\n row.scrollIntoView(true);\n const theadHeight = parseFloat(getComputedStyle(this.#thead).height);\n this.#scroller.scrollTop -= theadHeight;\n }\n }\n }\n\n scrollToPx(px: number) {\n if (this.#virtualScroll) {\n this.#virtualScroll.scrollToPx(px);\n } else {\n const theadHeight = parseFloat(getComputedStyle(this.#thead).height);\n this.#scroller.scrollTop -= theadHeight;\n }\n }\n\n /**\n * Sets the display order of the columns in the table.\n *\n * @param fields - An array of field names representing the new order of columns. Columns not included in the array will be placed at the end.\n * @throws {TypeError} If `fields` is not an array.\n */\n setColumnOrder(fields: string[]) {\n if (!Array.isArray(fields)) {\n throw new TypeError('fields must be an array of field names');\n }\n\n const newColumns = new Map<string, ColumnData>();\n for (const field of fields) {\n const col = this.#columnData.get(field);\n if (col) {\n newColumns.set(field, col);\n }\n }\n\n for (const [field, col] of this.#columnData) {\n if (!newColumns.has(field)) {\n newColumns.set(field, col);\n }\n }\n\n this.#columnData = newColumns;\n this.refresh();\n }\n\n /**\n * Refreshes the table display. This re-applies filters, sorting, and updates headers and rows.\n */\n refresh() {\n this.#updateHeaders();\n this.#filterRows();\n }\n\n /**\n * Finds the original index of the first row where the specified field matches the given value.\n * This searches through the original, unfiltered dataset.\n * @param field - The field name within the row data to search.\n * @param value - The value to match against the field's content.\n * @returns The original index of the found row, or -1 if no match is found.\n * @example\n * ```ts\n * const index = dataTable.indexOf('id', 12345);\n * if (index >= 0) {\n * dataTable.updateRow({description: \"Updated description\"}, index);\n * }\n * ```\n */\n indexOf(field: string, value: any) {\n const rows = [...this.#rows.values()];\n const found_row = rows.find(row => {\n if (field in row) {\n return row[field] === value;\n }\n });\n\n if (found_row) {\n return found_row._metadata.index;\n }\n return -1;\n }\n\n /**\n * Updates the data of a row at a specific original index.\n * @param index - The original index of the row to update.\n * @param data - An object containing the new data to assign to the row. Existing fields will be updated, and new fields will be added.\n *\n * @example\n * ```ts\n * const index = dataTable.indexOf('id', 12345);\n * if (index >= 0) {\n * dataTable.updateRow(index, {description: \"Updated description\"});\n * }\n * ```\n */\n updateRow(index: number, data: any) {\n const current_row = this.#rows.get(index);\n if (current_row) {\n Object.assign(current_row, data);\n this.#filterRows();\n }\n }\n\n /**\n * Deletes a row at a specific original index from the table.\n * @param index - The original index of the row to delete.\n */\n deleteRow(index: number) {\n this.#rows.delete(index);\n this.#filterRows();\n }\n\n /**\n * Executes a callback function without triggering table updates (like re-rendering or event dispatches)\n * until the callback has completed. This is useful for batching multiple operations.\n * @param callback - A function to execute. It receives the DataTable instance as its argument.\n * @example dataTable.withoutUpdates(dt => { dt.sort('name', 'asc'); dt.filter({ age: '>30' }); });\n */\n withoutUpdates(callback: (datatable: DataTable) => void) {\n this.#blockUpdates = true;\n try {\n callback(this);\n } finally {\n this.#blockUpdates = false;\n this.refresh();\n }\n }\n\n #loadRow(row: InternalRowData, index: number) {\n // Add the index\n const metadata: RowMetadata = {\n index: index++,\n tokens: {},\n sortValues: {},\n };\n row._metadata = metadata;\n\n for (const [field, col] of this.#columnData) {\n const value = this.#getNestedValue(row, field);\n\n // Cache precomputed values for sorting\n if (typeof col.sortValueCallback === 'function') {\n metadata.sortValues[field] = col.sortValueCallback(value);\n } else if (value instanceof String) {\n metadata.sortValues[field] = value.toLocaleLowerCase();\n } else {\n metadata.sortValues[field] = value;\n }\n\n // Tokenize any searchable columns\n if (col.searchable && col.tokenize && value) {\n metadata.tokens[field] = [String(value), ...this.#options.tokenizer(value)];\n }\n }\n\n return row;\n }\n\n #searchField(value: string | string[], query: RegExp): number {\n if (Array.isArray(value)) {\n if (this.#options.scoring) {\n return value.map(element => this.#searchField(element, query)).reduce((accumulator, currentValue) => accumulator + currentValue, 0);\n } else {\n return value.some(element => this.#searchField(element, query)) ? 1 : 0;\n }\n }\n\n if (this.#options.scoring) {\n const matches = value.match(query);\n if (matches) {\n return matches.reduce((accumulator, value) => accumulator + value.length, 0);\n }\n } else {\n return query.test(value) ? 1 : 0\n }\n\n\n return 0;\n }\n\n #filterField(\n value: any,\n filter: any,\n filterFunction?: ColumnFilterCallback,\n ): boolean {\n if (Array.isArray(filter)) {\n // If it's an array, we will use an OR filter.\n // If any filters in the array match, keep it.\n for (const element of filter) {\n if (this.#filterField(value, element)) {\n return true;\n }\n }\n return false;\n }\n\n if (typeof filterFunction === 'function') {\n return filterFunction(value, filter);\n }\n\n if (filter instanceof RegExp) {\n return filter.test(String(value));\n }\n\n return filter === value;\n }\n\n #filterRow(row: InternalRowData, index: number): boolean {\n if (typeof this.#filters === 'function') {\n return this.#filters(row, index);\n }\n\n for (const field of Object.keys(this.#filters || {})) {\n const filter = this.#filters[field];\n if (filter == null) {\n continue;\n }\n\n const value = this.#getNestedValue(row, field);\n if (typeof filter === 'function') {\n if (!filter(value)) {\n return false;\n }\n } else {\n const col = this.#columnData.get(field);\n const filterCallback = col ? col.filterCallback : undefined;\n if (!this.#filterField(value, filter, filterCallback)) {\n return false;\n }\n }\n }\n return true;\n }\n\n #filterRows() {\n if (this.#blockUpdates) return;\n\n const rows = [...this.#rows.values()];\n this.#filteredRows = rows.filter((row, index) => {\n row._metadata.searchScore = 0;\n // Filter takes precedence over search.\n if (!this.#filterRow(row, index)) {\n return false;\n }\n\n if (!this.#query) {\n return true;\n }\n\n const searchableFields = [...this.#columnData.values()]\n .filter(col => col.searchable)\n .map(c => c.field);\n\n const fields = [...searchableFields, ...this.#options.extraSearchFields];\n\n for (const field of fields) {\n const col = this.#columnData.get(field);\n\n let tokens;\n if (col && field in row._metadata.tokens) {\n tokens = row._metadata.tokens[field];\n } else {\n tokens = String(this.#getNestedValue(row, field));\n\n }\n\n const score = this.#searchField(tokens, this.#query);\n row._metadata.searchScore += score\n }\n\n return row._metadata.searchScore > 0;\n });\n\n this.#sortRows();\n\n const changeEvent = new CustomEvent<DataTableEventMap['dt.rows.changed']>(\n 'dt.rows.changed',\n {\n cancelable: false,\n detail: {\n dataTable: this,\n },\n },\n );\n\n this.dispatchEvent(changeEvent);\n }\n\n #compareRows(\n a: InternalRowData,\n b: InternalRowData,\n col: ColumnOptions,\n ): number {\n let aValue, bValue;\n if (col.sortOrder === 'asc') {\n aValue = a._metadata.sortValues[col.field];\n bValue = b._metadata.sortValues[col.field];\n } else if (col.sortOrder === 'desc') {\n aValue = b._metadata.sortValues[col.field];\n bValue = a._metadata.sortValues[col.field];\n }\n\n if (typeof col.sorter === 'function') {\n const ret = col.sorter(aValue, bValue);\n if (ret !== 0) return ret;\n }\n\n if (aValue < bValue) return -1;\n if (aValue > bValue) return 1;\n return 0;\n }\n\n #sortRows() {\n if (this.#blockUpdates) return;\n\n const sortedColumns = [...this.#columnData.values()]\n // Only sort by visible columns with valid sort priorities\n .filter(col => !col.header.hidden && col.sortOrder)\n // Sort our columns by their sort priority.\n // This is how sorting by multiple columns is handled.\n .sort((a, b) => a.sortPriority - b.sortPriority);\n\n this.#filteredRows.sort((a, b) => {\n\n // Try to sort by search score if we're using scoring and there is a query.\n if (this.scoring && this.#query) {\n const aValue = a._metadata.searchScore || 0;\n const bValue = b._metadata.searchScore || 0;\n if (aValue > bValue) return -1;\n if (aValue < bValue) return 1;\n }\n\n for (const col of sortedColumns) {\n const comp = this.#compareRows(a, b, col);\n if (comp !== 0) {\n return comp;\n }\n }\n\n // Always fall back to the index column\n return a._metadata.index - b._metadata.index;\n });\n this.#updateTable();\n }\n\n #updateHeaders() {\n if (this.#blockUpdates) return;\n\n for (const col of this.#columnData.values()) {\n // Update the order of headers\n col.header.parentElement?.append(col.header);\n col.header.hidden = !col.visible;\n\n if (col.sortOrder === 'asc') {\n col.header?.classList.add('dt-ascending');\n col.header?.classList.remove('dt-descending');\n } else if (col.sortOrder === 'desc') {\n col.header?.classList.add('dt-descending');\n col.header?.classList.remove('dt-ascending');\n } else {\n col.header?.classList.remove('dt-ascending');\n col.header?.classList.remove('dt-descending');\n }\n }\n }\n\n #updateTable() {\n if (this.#blockUpdates) return;\n\n this.#tbody.innerHTML = '';\n if (this.#virtualScroll) {\n try {\n this.#virtualScroll.start(this.#filteredRows.length);\n } catch (error) {\n if (error instanceof VirtualScrollError) {\n console.warn(\n 'Failed to start virtual scroll... falling back to standard rendering',\n );\n console.warn(error.stack);\n }\n }\n } else {\n if (this.#filteredRows.length > WARN_ROW_COUNT) {\n const count = WARN_ROW_COUNT.toLocaleString();\n console.warn(\n `Virtual scroll disabled with more than ${count} rows... Good luck with that!`,\n );\n }\n\n const rowElements = this.#filteredRows.map((_, index) =>\n this.#createRow(index),\n );\n this.#tbody.append(...rowElements);\n }\n\n if (this.#rows.size === 0) {\n this.showMessage(this.#options.noDataText, 'dt-empty');\n } else if (this.#filteredRows.length === 0) {\n this.showMessage(this.#options.noMatchText, 'dt-empty');\n }\n }\n\n #markText(element: HTMLElement, query: RegExp) {\n if (element.children.length === 0) {\n let text = element.innerText;\n const classes = this.#classes.mark.join(\" \");\n text = text.replace(query, match => `<mark class=\"${classes}\">${match}</mark>`);\n element.innerHTML = text;\n } else {\n for (const child of element.children) {\n if (child instanceof HTMLElement) {\n this.#markText(child, query);\n }\n }\n }\n }\n\n #updateCell(\n td: HTMLTableCellElement,\n value: any,\n col: ColumnData,\n row: object,\n ) {\n if (typeof col.valueFormatter === 'function') {\n value = col.valueFormatter(value, row);\n }\n td.innerText = value == null ? '-' : value;\n\n if (typeof col.elementFormatter === 'function') {\n col.elementFormatter(value, row, td);\n }\n\n if (this.#options.highlightSearch && this.#query && col.searchable) {\n this.#markText(td, this.#query);\n }\n\n td.hidden = col.visible ? false : true;\n }\n\n #createRow(index: number): HTMLTableRowElement {\n const row = this.#filteredRows[index];\n const tr = document.createElement('tr');\n tr.classList.add(...this.#classes.tr);\n tr.dataset.dtIndex = String(row._metadata.index);\n\n for (const [field, col] of this.#columnData) {\n const value = this.#getNestedValue(row, field);\n const td = document.createElement('td');\n td.classList.add(...this.#classes.td);\n td.dataset.dtField = field;\n const colWidth = col.header.style.width;\n // If the column has been resized, force the cells to that width.\n if (colWidth && colWidth !== '0px') {\n // We have to set the cells max width to allow text-overflow: ellipsis to work.\n td.style.maxWidth = colWidth;\n }\n\n this.#updateCell(td, value, col, row);\n tr.append(td);\n }\n\n if (typeof this.#options.rowFormatter === 'function') {\n try {\n this.#options.rowFormatter(row, tr);\n } catch (error) {\n console.error('Row formatter callback failed with the following error');\n console.error(error);\n }\n }\n\n return tr;\n }\n\n #getNestedValue(obj: Record<string, any>, path: string) {\n const keys = path.split('.');\n let current = obj;\n\n for (const key of keys) {\n if (current && typeof current === 'object') {\n current = current[key];\n } else {\n return undefined; // Or handle the error as needed\n }\n }\n\n return current;\n }\n\n #resizeColumn(column: string | ColumnData, width?: number) {\n if (typeof column === 'string') {\n const columnData = this.#columnData.get(column);\n if (!columnData) throw new Error('Column not found');\n column = columnData;\n }\n\n let headerWidth, cellWidth;\n if (width == null) {\n headerWidth = '';\n cellWidth = '';\n } else if (width <= 0) {\n headerWidth = '0px';\n cellWidth = '';\n } else {\n headerWidth = `${width}px`;\n cellWidth = `${width}px`;\n }\n ''\n const prevWidth = column.header.offsetWidth;\n column.header.style.width = headerWidth;\n column.header.style.maxWidth = headerWidth;\n\n const cells = this.#tbody.querySelectorAll<HTMLTableCellElement>(\n `td[data-dt-field=\"${column.field}\"]`,\n );\n for (const cell of cells) {\n // If width is 0 it means we want to auto size the columns.\n // To do that we set the width to 0px on the header\n // and clear the max width on all of the cells.\n cell.style.maxWidth = cellWidth;\n }\n\n // Resize the table based on how much the column changed\n const delta = column.header.offsetWidth - prevWidth;\n const tableWidth = this.#table.offsetWidth + delta;\n this.#table.style.width = `${tableWidth}px`;\n }\n\n #resizeColumnStart = (event: MouseEvent) => {\n // If target is not the resizer, we don't care.\n if (!(event.target instanceof HTMLElement)) return;\n if (!event.target.classList.contains('dt-resizer')) return;\n // If the current target isn't the header, we don't care.\n if (!(event.currentTarget instanceof HTMLElement)) return;\n if (!event.currentTarget.dataset.dtField) return;\n\n event.stopImmediatePropagation();\n event.preventDefault();\n\n const field = event.currentTarget.dataset.dtField;\n const col = this.#columnData.get(field);\n if (!col) return;\n this.#resizingColumn = col;\n\n col.resizeStartX = event.clientX;\n col.resizeStartWidth = col.header.offsetWidth;\n\n document.addEventListener('mousemove', this.#resizeColumnMove);\n document.addEventListener('mouseup', this.#resizeColumnEnd);\n };\n\n #resizeColumnMove = (event: MouseEvent) => {\n if (!this.#resizingColumn) return;\n event.stopImmediatePropagation();\n event.preventDefault();\n\n const dx = event.clientX - this.#resizingColumn.resizeStartX!;\n const newWidth = this.#resizingColumn.resizeStartWidth! + dx;\n this.#resizeColumn(this.#resizingColumn, newWidth);\n };\n\n #resizeColumnEnd = (event: MouseEvent) => {\n if (!this.#resizingColumn) return;\n event.stopImmediatePropagation();\n event.preventDefault();\n\n document.removeEventListener('mousemove', this.#resizeColumnMove);\n document.removeEventListener('mouseup', this.#resizeColumnEnd);\n\n const resizeEvent = new CustomEvent<DataTableEventMap['dt.col.resize']>(\n 'dt.col.resize',\n {\n cancelable: false,\n detail: {\n column: this.#resizingColumn.field,\n width: this.#resizingColumn.header.offsetWidth,\n },\n },\n );\n\n this.dispatchEvent(resizeEvent);\n\n this.#resizingColumn = undefined;\n };\n\n #resizeColumnDoubleClick = (event: MouseEvent) => {\n // If target is not the resizer, we don't care.\n if (!(event.target instanceof HTMLElement)) return;\n if (!event.target.classList.contains('dt-resizer')) return;\n // If the current target isn't the header, we don't care.\n if (!(event.currentTarget instanceof HTMLElement)) return;\n if (!event.currentTarget.dataset.dtField) return;\n\n const field = event.currentTarget.dataset.dtField;\n if (!field) return;\n this.#resizeColumn(field);\n };\n\n #dragColumnStart = (event: DragEvent) => {\n const target = event.target as HTMLElement;\n const field = target.dataset.dtField;\n\n if (event.dataTransfer && field) {\n event.dataTransfer.effectAllowed = 'move';\n event.dataTransfer.setData('text/plain', field);\n }\n };\n\n #dragColumnOver = (event: DragEvent) => {\n event.preventDefault();\n if (event.dataTransfer) {\n event.dataTransfer.dropEffect = 'move';\n }\n return false;\n };\n\n #dragColumnEnter = (event: DragEvent) => {\n const target = event.target as HTMLElement;\n target.classList.add('dt-drag-over');\n };\n\n #dragColumnLeave = (event: DragEvent) => {\n const target = event.target as HTMLElement;\n target.classList.remove('dt-drag-over');\n };\n\n #dragColumnDrop = (event: DragEvent) => {\n const dragField = event.dataTransfer?.getData('text/plain');\n const target = event.currentTarget as HTMLElement;\n const dropField = target.dataset.dtField;\n\n if (!dragField || !dropField) return;\n\n event.preventDefault();\n event.stopPropagation();\n\n const columns = [...this.#columnData.values()];\n const dragIndex = columns.findIndex(col => col.field === dragField);\n const dropIndex = columns.findIndex(col => col.field === dropField);\n\n if (dragIndex > -1 && dropIndex > -1) {\n const [draggedColumn] = columns.splice(dragIndex, 1);\n const droppedColumn = this.#columnData.get(dropField);\n if (!droppedColumn) return;\n\n columns.splice(dropIndex, 0, draggedColumn);\n const newColumnOrder = columns.map(col => col.field);\n const reorderEvent = new CustomEvent<DataTableEventMap['dt.col.reorder']>(\n 'dt.col.reorder',\n {\n cancelable: true,\n detail: {\n draggedColumn: draggedColumn.field,\n dropColumn: droppedColumn.field,\n order: newColumnOrder,\n },\n },\n );\n if (!this.dispatchEvent(reorderEvent)) {\n return;\n }\n\n this.setColumnOrder(newColumnOrder);\n }\n };\n\n #dragColumnEnd = () => {\n const elements = document.querySelectorAll('.dt-drag-over');\n for (const element of elements) {\n element.classList.remove('dt-drag-over');\n }\n };\n\n addEventListener<K extends keyof DataTableEventMap>(\n type: K,\n listener: (this: DataTable, ev: CustomEvent<DataTableEventMap[K]>) => any,\n options?: boolean | AddEventListenerOptions,\n ): void;\n\n // This is the generic fallback for any other string event type (e.g., standard DOM events).\n addEventListener(\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ): void;\n\n // The single implementation for both overloads.\n addEventListener(type: any, listener: any, options?: any) {\n super.addEventListener(type, listener, options);\n }\n}\n\ninterface ColumnData {\n field: string;\n title: string;\n sortable: boolean;\n searchable: boolean;\n tokenize: boolean;\n header: HTMLElement;\n headerContent: HTMLElement;\n visible: boolean;\n sortOrder: SortOrder;\n sortPriority: number;\n resizeStartX: number | null;\n resizeStartWidth: number | null;\n valueFormatter?: ValueFormatterCallback;\n elementFormatter?: CellFormatterCallback;\n comparatorCallback?: ComparatorCallback;\n filterCallback?: ColumnFilterCallback;\n sortValueCallback?: SortValueCallback;\n}\n\ninterface InternalRowData extends Record<string, any> {\n _metadata: RowMetadata;\n}\n\ninterface RowMetadata {\n index: number;\n searchScore?: number;\n tokens: Record<string, string[]>;\n sortValues: Record<string, any>;\n}\n\ninterface Classes {\n scroller: string[];\n thead: string[];\n tbody: string[];\n tfoot: string[];\n tr: string[];\n th: string[];\n td: string[];\n mark: string[];\n}\n\nconst WARN_ROW_COUNT = 10_000;\n\n/**\n * Defines the mapping between event names and their detail object types.\n */\nexport interface DataTableEventMap {\n 'dt.row.clicked': {\n row: any;\n index: number;\n column: string | undefined;\n originalEvent: MouseEvent;\n };\n\n 'dt.rows.changed': object;\n\n 'dt.col.sort': {\n column: string;\n order: SortOrder;\n };\n\n 'dt.col.visibility': {\n column: string;\n visible: boolean;\n };\n\n 'dt.col.resize': {\n column: string;\n width: number;\n };\n\n 'dt.col.reorder': {\n draggedColumn: string;\n dropColumn: string;\n order: string[];\n };\n}\n\nexport type * from './types';\n","import { DataTable } from '../datatable';\nimport { ColumnState } from '../types';\n\ninterface Options {\n saveColumnSorting: boolean;\n saveColumnOrder: boolean;\n saveColumnVisibility: boolean;\n saveColumnWidth: boolean;\n}\n\nexport class LocalStorageAdapter {\n #dataTable: DataTable;\n #storageKey: string;\n #options: Options = {\n saveColumnSorting: true,\n saveColumnVisibility: true,\n saveColumnWidth: true,\n saveColumnOrder: true,\n };\n\n /**\n * @param dataTable - The DataTable instance to monitor.\n * @param storageKey - The key to use for saving the state in localStorage.\n * @param options - The key to use for saving the state in localStorage.\n */\n constructor(dataTable: DataTable, storageKey: string, options?: Options) {\n this.#dataTable = dataTable;\n this.#storageKey = storageKey;\n this.#options = { ...this.#options, ...options };\n\n // Restore state before adding the listeners.\n this.restoreState();\n\n if (this.#options.saveColumnSorting) {\n dataTable.addEventListener('dt.col.sort', this.#saveStateAfterEvent);\n }\n\n if (this.#options.saveColumnVisibility) {\n dataTable.addEventListener(\n 'dt.col.visibility',\n this.#saveStateAfterEvent,\n );\n }\n\n if (this.#options.saveColumnWidth) {\n dataTable.addEventListener('dt.col.resize', this.#saveStateAfterEvent);\n }\n\n if (this.#options.saveColumnOrder) {\n dataTable.addEventListener('dt.col.reorder', this.#saveStateAfterEvent);\n }\n }\n\n /**\n * Saves the current column state to localStorage.\n */\n saveState() {\n const states: Partial<ColumnState>[] = this.#dataTable.columnStates;\n for (const state of states) {\n if (!this.#options.saveColumnSorting) {\n state.sortOrder = undefined;\n state.sortPriority = undefined;\n }\n\n if (!this.#options.saveColumnVisibility) {\n state.visible = undefined;\n }\n\n if (!this.#options.saveColumnWidth) {\n state.width = undefined;\n }\n }\n\n localStorage.setItem(\n this.#storageKey,\n JSON.stringify(this.#dataTable.columnStates),\n );\n }\n\n /**\n * Restores the column state from localStorage.\n */\n restoreState() {\n const savedState = localStorage.getItem(this.#storageKey);\n if (!savedState) return;\n\n try {\n const columnStates = JSON.parse(savedState) as ColumnState[];\n this.#dataTable.columnStates = columnStates;\n\n if (this.#options.saveColumnOrder) {\n this.#dataTable.setColumnOrder(\n columnStates.map((col: ColumnState) => col.field),\n );\n }\n } catch (error) {\n console.error('Failed to restore DataTable state:', error);\n }\n }\n\n /**\n * Clears the saved state from localStorage.\n */\n clearState() {\n localStorage.removeItem(this.#storageKey);\n }\n\n #saveStateAfterEvent = () => setTimeout(() => this.saveState(), 0);\n}\n"],"mappings":"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","names":["src_exports","__export","DataTable","LocalStorageAdapter","classesToArray","classes","toHumanReadable","str","char","whitespaceTokenizer","value","regex","token","_warned","_container","_element","_generator","_rowCount","_rowHeight","_padding","_animationFrame","_started","_scrollTop","_scrollCallback","_renderCallback","_VirtualScroll_instances","updateRowHeight_fn","_VirtualScroll","container","element","generator","nodePadding","__privateAdd","__privateGet","__privateSet","entries","entry","__privateMethod","index","px","rowCount","scrollTop","rowHeight","padding","totalContentHeight","actualHeight","viewHeight","startNode","visibleNodesCount","offsetY","remainingHeight","visibleChildren","_","topRow","bottomRow","e","renderSize","elements","i","VirtualScrollError","VirtualScroll","message","_table","_thead","_tbody","_scroller","_columnData","_rows","_filteredRows","_query","_filters","_virtualScroll","_sortPriority","_classes","_resizingColumn","_options","_blockUpdates","_DataTable_instances","loadRow_fn","searchField_fn","filterField_fn","filterRow_fn","filterRows_fn","compareRows_fn","sortRows_fn","updateHeaders_fn","updateTable_fn","markText_fn","updateCell_fn","createRow_fn","getNestedValue_fn","resizeColumn_fn","_resizeColumnStart","_resizeColumnMove","_resizeColumnEnd","_resizeColumnDoubleClick","_dragColumnStart","_dragColumnOver","_dragColumnEnter","_dragColumnLeave","_dragColumnDrop","_dragColumnEnd","_DataTable","table","options","_a","_b","_c","_d","_e","_f","_g","_h","_i","__privateAdd","event","field","col","__privateGet","__privateSet","dx","newWidth","__privateMethod","resizeEvent","dragField","dropField","columns","dragIndex","dropIndex","draggedColumn","droppedColumn","newColumnOrder","reorderEvent","elements","element","__spreadValues","tableElement","classesToArray","thead","headerRow","tbody","tr","td","index","row","value","rowEvent","colVisible","colOptions","colData","toHumanReadable","th","headerContent","titleWrapper","titleElement","sorter","resizer","states","state","column","VirtualScroll","rows","scrollTop","scrollLeft","internal_row","text","classes","colSpan","query","tokens","filters","colName","order","__privateWrapper","sortEvent","visisble","visibilityEvent","filename","all","csvHeaders","csvRows","list","key","csvContent","blob","a","rowData","filteredIndex","theadHeight","px","fields","newColumns","found_row","data","current_row","callback","type","listener","metadata","accumulator","currentValue","matches","filter","filterFunction","filterCallback","c","score","changeEvent","b","aValue","bValue","ret","sortedColumns","comp","error","VirtualScrollError","WARN_ROW_COUNT","count","rowElements","_","match","child","colWidth","obj","path","keys","current","width","columnData","headerWidth","cellWidth","prevWidth","cells","cell","delta","tableWidth","whitespaceTokenizer","DataTable","_dataTable","_storageKey","_options","_saveStateAfterEvent","LocalStorageAdapter","dataTable","storageKey","options","__privateAdd","__privateSet","__spreadValues","__privateGet","states","state","savedState","columnStates","col","error"]}