diff --git a/__tests__/dnd-host.test.js b/__tests__/dnd-host.test.js new file mode 100644 index 0000000..ccaafb4 --- /dev/null +++ b/__tests__/dnd-host.test.js @@ -0,0 +1,288 @@ +import NoJSElements from '../src/index.js'; +import { isHostBackend } from '../src/_host.js'; +import { _dndState, resetDndState } from '../src/dnd/state.js'; +import { dndContract } from '../src/dnd/contract.js'; + +// Host backend (NoJS-Server compiled sites): directives receive +// `init(el, host)` and only do DOM mechanics. Expressions were compiled +// server-side: `drag` carries a sealed token, `drop` a binding key, and +// *-disabled / drop-max delivered JSON values. + +function createHostRegistrar() { + const directives = new Map(); + return { + hostApi: 1, + directives, + directive(name, def) { directives.set(name, def); }, + filter() {}, + validator() {}, + global() {}, + config() {}, + }; +} + +function createHost() { + const disposers = []; + const watchers = []; + return { + exec: jest.fn(), + warn: jest.fn(), + value(el, attr) { + const raw = el.getAttribute(attr); + return raw == null || raw === '' ? null : JSON.parse(raw); + }, + watch: jest.fn((el, attr, cb) => { + watchers.push({ el, attr, cb }); + return () => {}; + }), + onDispose(el, fn) { disposers.push(fn); }, + dispose() { disposers.splice(0).reverse().forEach((fn) => fn()); }, + watchers, + }; +} + +let registrar; + +beforeEach(() => { + registrar = createHostRegistrar(); + NoJSElements.install(registrar); + resetDndState(); +}); + +afterEach(() => { + document.body.innerHTML = ''; + resetDndState(); +}); + +function init(name, el, host) { + registrar.directives.get(name).init(el, host); +} + +function buildList(count = 3) { + const ul = document.createElement('ul'); + ul.setAttribute('drop', 'np-0123456789abcdef0123'); + ul.setAttribute('drop-sort', 'vertical'); + for (let i = 0; i < count; i++) { + const li = document.createElement('li'); + li.setAttribute('drag', `v1.token-${i}`); + li.textContent = `Item ${i}`; + ul.appendChild(li); + } + document.body.appendChild(ul); + // jsdom has no layout: give each li a 20px-tall box stacked vertically. + [...ul.children].forEach((li, i) => { + li.getBoundingClientRect = () => ({ top: i * 20, bottom: i * 20 + 20, height: 20, left: 0, right: 100, width: 100, x: 0, y: i * 20 }); + }); + return ul; +} + +function dragEvent(type, clientY = 0) { + const evt = new Event(type, { bubbles: true, cancelable: true }); + evt.clientX = 10; + evt.clientY = clientY; + return evt; +} + +describe('dual-backend seam', () => { + test('isHostBackend detects the integrator registrar by hostApi', () => { + expect(isHostBackend({ hostApi: 1 })).toBe(true); + expect(isHostBackend({ hostApi: 0 })).toBe(false); + expect(isHostBackend({ evaluate() {}, internals: {} })).toBe(false); + expect(isHostBackend(null)).toBe(false); + }); + + test('host install registers drag and drop, warn stubs for unmigrated directives', () => { + expect(registrar.directives.has('drag')).toBe(true); + expect(registrar.directives.has('drop')).toBe(true); + for (const name of ['drag-list', 'drag-multiple', 'validate', 'modal', 'tabs']) { + expect(registrar.directives.has(name)).toBe(true); + } + const host = createHost(); + const el = document.createElement('div'); + init('drag-list', el, host); + expect(host.warn).toHaveBeenCalledWith(expect.stringContaining('"drag-list" is not yet available')); + }); + + test('the plugin exposes the dnd attribute contract', () => { + expect(NoJSElements.contract.directives.drop.attrs.drop).toBe('statement'); + expect(NoJSElements.contract.directives.drag.attrs.drag).toEqual({ type: 'expression', deliver: 'sealed' }); + expect(NoJSElements.contract.directives).toEqual(dndContract); + }); +}); + +describe('drag (host)', () => { + test('sets the same a11y attributes as the core backend', () => { + const ul = buildList(1); + const li = ul.firstElementChild; + init('drag', li, createHost()); + expect(li.draggable).toBe(true); + expect(li.getAttribute('aria-roledescription')).toBe('draggable item'); + expect(li.getAttribute('role')).toBe('button'); + expect(li.getAttribute('tabindex')).toBe('0'); + }); + + test('dragstart records the sealed token as the dragged item, read at event time', () => { + const ul = buildList(2); + const li = ul.children[1]; + init('drag', li, createHost()); + li.setAttribute('drag', 'v1.re-rendered'); + + li.dispatchEvent(dragEvent('dragstart')); + + expect(_dndState.dragging.item).toBe('v1.re-rendered'); + expect(_dndState.dragging.sourceCtx).toBeNull(); + expect(li.classList.contains('nojs-dragging')).toBe(true); + }); + + test('a delivered drag-disabled=true cancels dragstart', () => { + const ul = buildList(1); + const li = ul.firstElementChild; + li.setAttribute('drag-disabled', 'true'); + init('drag', li, createHost()); + + const evt = dragEvent('dragstart'); + li.dispatchEvent(evt); + + expect(evt.defaultPrevented).toBe(true); + expect(_dndState.dragging).toBeNull(); + }); + + test('watches drag-disabled and toggles draggable on change', () => { + const ul = buildList(1); + const li = ul.firstElementChild; + li.setAttribute('drag-disabled', 'false'); + const host = createHost(); + init('drag', li, host); + expect(host.watch).toHaveBeenCalledWith(li, 'drag-disabled', expect.any(Function)); + + li.setAttribute('drag-disabled', 'true'); + host.watchers[0].cb('true', 'false'); + expect(li.draggable).toBe(false); + }); + + test('listeners are removed through host.onDispose', () => { + const ul = buildList(1); + const li = ul.firstElementChild; + const host = createHost(); + init('drag', li, host); + host.dispose(); + + li.dispatchEvent(dragEvent('dragstart')); + expect(_dndState.dragging).toBeNull(); + }); +}); + +describe('drop (host)', () => { + function setup(count = 3) { + const ul = buildList(count); + const host = createHost(); + init('drop', ul, host); + for (const li of ul.children) init('drag', li, createHost()); + return { ul, host }; + } + + test('dropping reports the implicit variables as the action payload via host.exec', () => { + const { ul, host } = setup(3); + ul.children[0].dispatchEvent(dragEvent('dragstart')); + + ul.dispatchEvent(dragEvent('drop', 55)); + + expect(host.exec).toHaveBeenCalledWith('np-0123456789abcdef0123', { + $drag: 'v1.token-0', + $dragType: 'default', + $dragEffect: 'move', + $dropIndex: 3, + $source: { index: null }, + $target: { index: 3 }, + }); + expect(_dndState.dragging).toBeNull(); + }); + + test('the payload never contains DOM elements', () => { + const { ul, host } = setup(2); + ul.children[1].dispatchEvent(dragEvent('dragstart')); + ul.dispatchEvent(dragEvent('drop', 1)); + const payload = host.exec.mock.calls[0][1]; + expect(JSON.parse(JSON.stringify(payload))).toEqual(payload); + expect(payload.$dropIndex).toBe(0); + }); + + test('dragover shows the placeholder at the computed index (client mechanics)', () => { + const { ul } = setup(3); + ul.setAttribute('drop-placeholder', 'auto'); + // re-init so drop-placeholder is read + const host = createHost(); + init('drop', ul, host); + ul.children[0].dispatchEvent(dragEvent('dragstart')); + + ul.dispatchEvent(dragEvent('dragover', 25)); + + const ph = ul.querySelector('.nojs-drop-placeholder'); + expect(ph).not.toBeNull(); + expect([...ul.children].indexOf(ph)).toBe(1); + }); + + test('a delivered drop-disabled=true blocks the drop', () => { + const ul = buildList(2); + ul.setAttribute('drop-disabled', 'true'); + const host = createHost(); + init('drop', ul, host); + init('drag', ul.children[0], createHost()); + ul.children[0].dispatchEvent(dragEvent('dragstart')); + + ul.dispatchEvent(dragEvent('drop', 30)); + + expect(host.exec).not.toHaveBeenCalled(); + }); + + test('a delivered drop-max blocks drops at capacity', () => { + const ul = buildList(2); + ul.setAttribute('drop-max', '2'); + const host = createHost(); + init('drop', ul, host); + init('drag', ul.children[0], createHost()); + ul.children[0].dispatchEvent(dragEvent('dragstart')); + + ul.dispatchEvent(dragEvent('drop', 30)); + + expect(host.exec).not.toHaveBeenCalled(); + }); + + test('keyboard drop (Enter) also dispatches through host.exec', () => { + const { ul, host } = setup(2); + ul.children[0].dispatchEvent(new KeyboardEvent('keydown', { key: ' ', bubbles: true })); + ul.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true })); + expect(host.exec).toHaveBeenCalledTimes(1); + expect(host.exec.mock.calls[0][1].$drag).toBe('v1.token-0'); + }); +}); + +describe('drop-disabled watcher (host)', () => { + test('turning drop-disabled true mid-drag clears drag-over state and placeholder', () => { + const ul = buildList(2); + ul.setAttribute('drop-disabled', 'false'); + ul.setAttribute('drop-placeholder', 'auto'); + const host = createHost(); + init('drop', ul, host); + init('drag', ul.children[0], createHost()); + ul.children[0].dispatchEvent(dragEvent('dragstart')); + ul.dispatchEvent(dragEvent('dragenter', 5)); + ul.dispatchEvent(dragEvent('dragover', 5)); + expect(ul.classList.contains('nojs-drag-over')).toBe(true); + expect(ul.querySelector('.nojs-drop-placeholder')).not.toBeNull(); + + ul.setAttribute('drop-disabled', 'true'); + const w = host.watchers.find((x) => x.attr === 'drop-disabled'); + w.cb('true', 'false'); + + expect(ul.classList.contains('nojs-drag-over')).toBe(false); + expect(ul.querySelector('.nojs-drop-placeholder')).toBeNull(); + }); + + test('no watcher is registered when drop-disabled is not declared on the element', () => { + const ul = buildList(1); + const host = createHost(); + init('drop', ul, host); + expect(host.watchers.find((x) => x.attr === 'drop-disabled')).toBeUndefined(); + }); +}); diff --git a/__tests__/dnd.test.js b/__tests__/dnd.test.js index cd8be6f..e3b25f4 100644 --- a/__tests__/dnd.test.js +++ b/__tests__/dnd.test.js @@ -627,3 +627,50 @@ describe('DnD Cleanup', () => { expect(_dndState.selected.get('dispose-grp').size).toBe(0); }); }); + +describe('Expression capture (no re-read of mutated attributes)', () => { + afterEach(() => { document.body.innerHTML = ''; resetDndState(); }); + + test('drag-disabled mutated after init is not evaluated at dragstart', () => { + const { wrapper, el } = setupDrag("'item1'", { dragDisabled: 'false', state: { hits: 0 } }); + el.setAttribute('drag-disabled', 'hits = hits + 1'); + const evt = new Event('dragstart', { bubbles: true, cancelable: true }); + evt.dataTransfer = { setData() {}, effectAllowed: '' }; + el.dispatchEvent(evt); + expect(NoJS.findContext(wrapper).hits).toBe(0); + expect(evt.defaultPrevented).toBe(false); + }); + + test('drop-disabled / drop-max mutated after init are not evaluated on drop', () => { + const { wrapper: dw, el: dragEl } = setupDrag("'item1'"); + const { wrapper, el } = setupDrop('', { state: { hits: 0 } }); + el.setAttribute('drop-disabled', 'hits = hits + 1'); + el.setAttribute('drop-max', 'hits = hits + 100'); + const start = new Event('dragstart', { bubbles: true }); + start.dataTransfer = { setData() {}, effectAllowed: '' }; + dragEl.dispatchEvent(start); + for (const type of ['dragenter', 'dragover', 'drop']) { + const e = new Event(type, { bubbles: true, cancelable: true }); + e.dataTransfer = { dropEffect: '' }; + el.dispatchEvent(e); + } + expect(NoJS.findContext(wrapper).hits).toBe(0); + void dw; + }); +}); + +describe('Drop implicit lists (core reference semantics)', () => { + afterEach(() => { document.body.innerHTML = ''; resetDndState(); }); + + test('a `drag` source gives $source.list === null and $target.list === null', () => { + const { el: dragEl } = setupDrag("'item1'"); + const { wrapper, el } = setupDrop('seen = [$source.list, $target.list, $source.index, $target.index]', { state: { seen: 'unset' } }); + const start = new Event('dragstart', { bubbles: true }); + start.dataTransfer = { setData() {}, effectAllowed: '' }; + dragEl.dispatchEvent(start); + const drop = new Event('drop', { bubbles: true, cancelable: true }); + drop.dataTransfer = { dropEffect: '' }; + el.dispatchEvent(drop); + expect(NoJS.findContext(wrapper).seen).toEqual([null, null, null, 0]); + }); +}); diff --git a/__tests__/install-rebind.test.js b/__tests__/install-rebind.test.js index 9de91db..e00fc5a 100644 --- a/__tests__/install-rebind.test.js +++ b/__tests__/install-rebind.test.js @@ -83,3 +83,44 @@ describe('Safe internals accessor (_internal)', () => { expect(_internal(fake, 'disposeTree')()).toBe('ok'); }); }); + +describe('Init-hook re-bind: correctly bound dnd nodes are left alone', () => { + function buildDropList() { + const wrapper = document.createElement('div'); + wrapper.setAttribute('state', "{ items: [{ id: 1, name: 'A' }, { id: 2, name: 'B' }, { id: 3, name: 'C' }] }"); + wrapper.innerHTML = + '
Ve!==I);P.ctx.$set(P.listPath,de),P.el.dispatchEvent(new CustomEvent("nojs:dnd-remove",{bubbles:!0,detail:{list:de,item:M,index:I}}))}}e.dispatchEvent(new CustomEvent("nojs:dnd-receive",{bubbles:!0,detail:{list:J,item:M,from:I,fromList:P?t.resolve(P.listPath,P.ctx):null}}))}let ue=w.dragging?.sourceEl?.firstElementChild?.getAttribute("aria-label")||w.dragging?.sourceEl?.firstElementChild?.textContent?.trim()?.slice(0,50)||"Item",ut=F&&I{let R=[...e.children][F&&Ide.classList.add(be)),de.addEventListener("animationend",()=>{_.split(/\s+/).filter(Boolean).forEach(be=>de.classList.remove(be))},{once:!0})}}),w.dragging=null},z=T=>{if(w.dragging&&ve(w.dragging.type,m)&&(T.key==="Enter"||T.key===" ")){T.preventDefault();let M=e.querySelector(":focus");if(M){let I=(M.style?.display==="contents"&&M.firstElementChild||M).getBoundingClientRect(),q={preventDefault(){},stopPropagation(){},clientX:I.left+I.width/2,clientY:I.top+I.height+1,dataTransfer:null};X(q)}}};e.addEventListener("dragover",A),e.addEventListener("dragenter",$),e.addEventListener("dragleave",V),e.addEventListener("drop",X),e.addEventListener("keydown",z),ce(e,()=>{e.removeEventListener("dragover",A),e.removeEventListener("dragenter",$),e.removeEventListener("dragleave",V),e.removeEventListener("drop",X),e.removeEventListener("keydown",z)});let re=n.$watch(S);ce(e,re),S()}})}function Ot(t){Ye(t,"drag-multiple"),t.directive("drag-multiple",{priority:16,init(e,r){let o=t.findContext(e),n=e.getAttribute("drag-group"),i=e.getAttribute("drag-multiple-class")||"nojs-selected";if(!n){(K(t,"warn")||console.warn)("drag-multiple requires drag-group attribute");return}w.selected.has(n)||w.selected.set(n,new Set);let c=w.selected.get(n),a=d=>{let m=e.getAttribute("drag"),f={item:m?t.evaluate(m,o):null,el:e,ctx:o};if(d.ctrlKey||d.metaKey){let u=[...c].find(p=>p.el===e);u?(c.delete(u),i.split(/\s+/).filter(Boolean).forEach(p=>e.classList.remove(p))):(c.add(f),i.split(/\s+/).filter(Boolean).forEach(p=>e.classList.add(p)))}else{for(let u of c)i.split(/\s+/).filter(Boolean).forEach(p=>u.el.classList.remove(p));c.clear(),c.add(f),i.split(/\s+/).filter(Boolean).forEach(u=>e.classList.add(u))}};e.addEventListener("click",a),ce(e,()=>{e.removeEventListener("click",a);let d=[...c].find(m=>m.el===e);d&&c.delete(d)});let s=d=>{if(d.key==="Escape"){for(let m of c)i.split(/\s+/).filter(Boolean).forEach(l=>m.el.classList.remove(l));c.clear()}};window.addEventListener("keydown",s),ce(e,()=>window.removeEventListener("keydown",s))}})}function Vt(t,e={}){Rt(t),zt(t),Ft(t),Ot(t)}function Nt(){Mt()}var Wt=[["valueMissing","required"],["typeMismatch",null],["tooShort","minlength"],["tooLong","maxlength"],["patternMismatch","pattern"],["rangeUnderflow","min"],["rangeOverflow","max"],["stepMismatch","step"]],gt=["required","email","url","number","date","time","datetime-local","month","week","tel","minlength","maxlength","pattern","min","max","step"];function ie(t,e){t.__disposers=t.__disposers||[],t.__disposers.push(e)}var ye,Xt,Xe,bt,ht,Ut,Ke,vt,Gt;function jo(t){let e=document.createTreeWalker(t,NodeFilter.SHOW_ELEMENT);for(;e.nextNode();)e.currentNode.__declared=!1}function Lo(t){return(t.getAttribute("type")||"text").toLowerCase()}function ko(t,e){let r=[],o=new Set,n=t.getAttribute("validate");if(n){let c=n.split("|").map(a=>a.trim());for(let a of c){let[s,...d]=a.split(":"),m=ye[s];if(m){let l=m(t.value,...d,e);l!==!0&&l&&(r.push({rule:s,message:l}),o.add(s))}else{let l=t.value,f=null;switch(s){case"required":(l==null||String(l).trim()==="")&&(f="Required");break;case"email":l&&!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(l)&&(f="Invalid email");break;case"url":try{new URL(l)}catch{f="Invalid URL"}break;case"min":Number(l)Number(d[0])&&(f=`Maximum value is ${d[0]}`);break;case"custom":if(d[0]&&ye[d[0]]){let u=ye[d[0]](l,e);u!==!0&&u&&(f=u)}break}f&&(r.push({rule:s,message:f}),o.add(s))}}}let i=t.validity;if(i&&!i.valid){for(let[c,a]of Wt)if(i[c]){let s=a||Lo(t);o.has(s)||(r.push({rule:s,message:t.validationMessage}),o.add(s))}}return r}function Co(t,e,r){let o=t.getAttribute(`error-${e}`);if(o)return o;let n=t.getAttribute("error");return n&&!n.startsWith("#")?n:r}function So(t,e){if(!t.length)return null;let o=[...t].sort((n,i)=>{let c=gt.indexOf(n.rule),a=gt.indexOf(i.rule);return(c===-1?999:c)-(a===-1?999:a)})[0];return{rule:o.rule,message:Co(e,o.rule,o.message)}}function Zt(t){let e=t.closest("form");if(e){for(let r of e.querySelectorAll('div[style="display: contents;"]'))if(r.__errorTemplateFor===t)return r}for(let r of document.querySelectorAll('div[style="display: contents;"]'))if(r.__errorTemplateFor===t)return r;return null}function To(t,e,r,o,n){let i=Zt(o);if(i){if(i.__ctx?.$error===e&&i.__ctx?.$rule===r)return;vt(i),i.remove()}let c=document.querySelector(t);if(!c)return;let a=c.content.cloneNode(!0),s=document.createElement("div");s.style.display="contents",s.setAttribute("aria-live","polite"),s.__errorTemplateFor=o;let d=Xe({$error:e,$rule:r},n);s.__ctx=d,s.appendChild(a),c.parentNode.insertBefore(s,c.nextSibling),jo(s),ht(s)}function Yt(t){let e=Zt(t);e&&(vt(e),e.remove())}function Do(t,e){let r=t.getAttribute("validate-if");if(!r)return!0;try{return!!Xt(r,e)}catch{return!0}}function Kt(t,e){let r=t.getAttribute("validate-on");if(r)return r.split(/\s+/);let o=e?e.getAttribute("validate-on"):null;return o?o.split(/\s+/):["input","focusout"]}function Io(t,e,r){let o=e.split("|").map(n=>n.trim());for(let n of o){let[i,...c]=n.split(":"),a=ye[i];if(a){let s=a(t,...c,r);if(s!==!0&&s)return s}else switch(i){case"required":if(t==null||String(t).trim()==="")return"Required";break;case"email":if(t&&!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t))return"Invalid email";break;case"url":try{new URL(t)}catch{return"Invalid URL"}break;case"min":if(Number(t) Number(c[0]))return`Maximum value is ${c[0]}`;break;case"custom":if(c[0]&&ye[c[0]]){let s=ye[c[0]](t,r);if(s!==!0&&s)return s}break}}return null}function Ho(t){if(t.__ctx)return t.__ctx;for(let r=t.parentElement;r;r=r.parentElement)if(r.__ctx)return bt(t);let e=Xe({},null);return t.__ctx=e,e}function Qt(t){ye=K(t,"validators")||{},Xt=t.evaluate,Xe=t.createContext,bt=t.findContext,ht=t.processTree,Ut=K(t,"cloneTemplate")||(()=>null),Ke=K(t,"disposeChildren")||(()=>{}),vt=K(t,"disposeTree")||Ke,Gt=K(t,"warn")||console.warn;let e=K(t,"removeCoreDirective");typeof e=="function"?e("validate"):Gt('[nojs-elements] core too old (<1.13.0): cannot remove "validate" stub; update NoJS core to 1.13.0+.'),t.directive("validate",{priority:30,init(r,o,n){if(r.tagName==="FORM"){let f=function(){c&&typeof c.$notify=="function"&&c.$notify();let y=document.createTreeWalker(r,NodeFilter.SHOW_ELEMENT);for(;y.nextNode();){let x=y.currentNode.__ctx;x&&x!==c&&typeof x.$notify=="function"&&x.$notify()}},u=function(){return r.querySelectorAll("input, textarea, select")},p=function(){let y={},_={},x={},L=!0,k=null,j=0,S=!1;for(let A of u())A.name&&(A.type==="checkbox"?_[A.name]=A.checked:A.type==="radio"?A.checked?_[A.name]=A.value:A.name in _||(_[A.name]=""):_[A.name]=A.value);for(let A of u()){if(!A.name)continue;let $=s.has(A.name),V=d.has(A.name);if(!Do(A,c)){x[A.name]={valid:!0,dirty:V,touched:$,error:null,value:_[A.name]};continue}let X=ko(A,_),z=So(X,A),re=!z,T=Kt(A,r),M=T.includes("input"),P=T.includes("blur")||T.includes("focusout")||T.includes("submit"),I;!A.hasAttribute("validate-on")&&!r.hasAttribute("validate-on")?I=$||V:I=M&&V||P&&$,re||(L=!1),!re&&I&&(y[A.name]=z.message,j++,k||(k=z.message)),x[A.name]={valid:re,dirty:V,touched:$,error:z?z.message:null,value:_[A.name]},!re&&I?A.setAttribute("aria-invalid","true"):A.removeAttribute("aria-invalid");let q=A.getAttribute("error-class")||a;if(q){let F=q.split(/\s+/);!re&&I?A.classList.add(...F):A.classList.remove(...F)}if(z&&I){let F=A.getAttribute(`error-${z.rule}`),J=A.getAttribute("error"),ue=(F&&F.startsWith("#")?F:null)||(J&&J.startsWith("#")?J:null);ue?To(ue,z.message,z.rule,A,c):Yt(A)}else Yt(A);let N=A.getAttribute("as");N&&c.$set(N,x[A.name])}m.size>0&&(S=!0),l.valid=L,l.errors=y,l.values=_,l.fields=x,l.firstError=k,l.errorCount=j,l.pending=S,c.$set("$form",{...l}),f(),v(r)},v=function(y){let _=l.valid&&!l.pending&&!l.submitting,x=y.querySelectorAll('button:not([type="button"]), input[type="submit"]');for(let L of x){if(L.hasAttribute("disabled")&&L.getAttribute("disabled")!==""){let k=L.getAttribute("disabled");if(k!=="disabled"&&k!=="true"&&k!=="false")continue}L.disabled=!_,L.__autoDisabled=!0}},h=function(y){if(!y.name)return;let _=Kt(y,r),x=()=>{d.add(y.name),l.dirty=!0,p()},L=()=>{s.add(y.name),l.touched=!0,p()};if(_.includes("input"))y.addEventListener("input",x),ie(r,()=>y.removeEventListener("input",x));else{let k=()=>{d.add(y.name),l.dirty=!0,p()};y.addEventListener("input",k),ie(r,()=>y.removeEventListener("input",k))}if(_.includes("blur")||_.includes("focusout")){let k=()=>{L(),_.includes("blur")&&x()};y.addEventListener("focusout",k),ie(r,()=>y.removeEventListener("focusout",k))}else y.addEventListener("focusout",L),ie(r,()=>y.removeEventListener("focusout",L));_.includes("submit")&&(y.addEventListener("focusout",L),ie(r,()=>y.removeEventListener("focusout",L)))},c=Ho(r);r.setAttribute("novalidate","");let a=r.getAttribute("error-class"),s=new Set,d=new Set,m=new Map,l={valid:!1,dirty:!1,touched:!1,submitting:!1,pending:!1,errors:{},values:{},firstError:null,errorCount:0,fields:{},reset:()=>{l.dirty=!1,l.touched=!1,l.pending=!1,l.submitting=!1,s.clear(),d.clear(),r.reset(),p()},endSubmit:()=>{l.submitting=!1,p()}};c.$set("$form",l);let g=r.hasAttribute("validate-on"),b=[...u()].some(y=>y.hasAttribute("validate-on"));if(!g&&!b){let y=x=>{let L=x.target;L&&L.name&&d.add(L.name),l.dirty=!0,p()};r.addEventListener("input",y),ie(r,()=>r.removeEventListener("input",y)),r.addEventListener("change",y),ie(r,()=>r.removeEventListener("change",y));let _=x=>{x.target&&x.target.name&&s.add(x.target.name),l.touched=!0,p()};r.addEventListener("focusout",_),ie(r,()=>r.removeEventListener("focusout",_))}else for(let y of u())h(y);let E=y=>{for(let _ of u())_.name&&s.add(_.name);if(l.touched=!0,p(),!l.valid||l.pending){y.preventDefault(),y.stopImmediatePropagation();return}l.submitting=!0,v(r),c.$set("$form",{...l}),f()};r.addEventListener("submit",E,!0),ie(r,()=>r.removeEventListener("submit",E,!0)),r.__nojsResetSubmitting=()=>{l.submitting=!1,p()},ie(r,()=>{delete r.__nojsResetSubmitting}),requestAnimationFrame(p);return}let i=bt(r);if(n&&(r.tagName==="INPUT"||r.tagName==="TEXTAREA"||r.tagName==="SELECT")){let c=r.getAttribute("error"),a=()=>{let s=Io(r.value,n,{});if(s?r.setAttribute("aria-invalid","true"):r.removeAttribute("aria-invalid"),s&&c){let d=r.nextElementSibling?.__validationError?r.nextElementSibling:null;d||(d=document.createElement("div"),d.__validationError=!0,d.style.display="contents",r.parentNode.insertBefore(d,r.nextSibling));let m=Ut(c);if(m){let l=Xe({err:{message:s}},i);Ke(d),d.innerHTML="",d.__ctx=l,d.appendChild(m),ht(d)}}else{let d=r.nextElementSibling?.__validationError?r.nextElementSibling:null;d&&(Ke(d),d.innerHTML="")}};r.addEventListener("input",a),ie(r,()=>r.removeEventListener("input",a))}}})}function Jt(t,e={}){Qt(t)}function er(){}var je=new Map,ee=new Map;function tr(){let t=Array.from(je.keys());for(let e of t){let r=e&&e.__disposers;if(r){for(let o of r)try{o()}catch{}e.__disposers=[]}}for(let e of ee.values())clearTimeout(e);ee.clear();for(let e of je.values())e.remove();je.clear()}function rr(){if(typeof document>"u"||document.querySelector("style[data-nojs-tooltip]"))return;let t=` +`.trim(),e=document.createElement("style");e.setAttribute("data-nojs-dnd",""),e.textContent=t,document.head.appendChild(e)}function X(t,e){let r=t&&t.internals;return r&&typeof r[e]<"u"?r[e]:void 0}function ze(t,e){t.__nojsElBoundCtx=e}function de(t){return!!(t&&typeof t.hostApi=="number"&&t.hostApi>=1)}function Ze(t,e){let r=X(t,"removeCoreDirective");typeof r=="function"?r(e):(X(t,"warn")||console.warn)(`[nojs-elements] core too old (<1.13.0): cannot remove "${e}" stub; update NoJS core to 1.13.0+.`)}function le(t,e){t.__disposers=t.__disposers||[],t.__disposers.push(e)}function Ke(t){let e=0;for(let r of t.children){if(r.classList.contains("nojs-drop-placeholder"))continue;(r.style||{}).display==="contents"?e+=Ke(r):e++}return e}function Xe(t,e,r,o){let n=[...t.children].filter(i=>!i.classList.contains("nojs-drop-placeholder"));if(n.length===0)return 0;for(let i=0;i 0&&(n.style.height=s.height+"px"),s.width>0&&(n.style.width=s.width+"px")}}else{let c=document.getElementById(r.startsWith("#")?r.slice(1):r);c&&c.content?(n=document.createElement("div"),n.style.display="contents",n.className=o||"nojs-drop-placeholder",n.appendChild(c.content.cloneNode(!0))):(n=document.createElement("div"),n.className=o||"nojs-drop-placeholder")}n.classList.add("nojs-drop-placeholder");let i=[...t.children].filter(c=>!c.classList.contains("nojs-drop-placeholder"));e>=i.length?t.appendChild(n):t.insertBefore(n,i[e]),_.placeholder=n}function re(){_.placeholder&&(_.placeholder.remove(),_.placeholder=null)}function xe(t,e){return!e||e==="*"?!0:e.split(",").map(o=>o.trim()).includes(t)}function Io(t,e){let r=document.createElement("div");r.style.cssText="position:fixed;top:-9999px;left:-9999px;pointer-events:none;z-index:99999;";let o=t.style&&t.style.display==="contents"&&t.firstElementChild||t,n=o.getBoundingClientRect(),i=n.width,c=n.height,s=getComputedStyle(o),a=Math.min(e,3);for(let g=a-1;g>=0;g--){let u=document.createElement("div"),f=g*4;if(u.style.cssText="position:absolute;top:"+f+"px;left:"+f+"px;width:"+i+"px;height:"+c+"px;border-radius:"+s.borderRadius+";box-shadow:0 1px 4px rgba(0,0,0,0.12);overflow:hidden;box-sizing:border-box;",g===0){let p=o.cloneNode(!0);for(;p.firstChild;)u.appendChild(p.firstChild);u.style.background=s.backgroundColor||"#fff",u.style.border=s.border,u.style.padding=s.padding,u.style.fontSize=s.fontSize,u.style.color=s.color,u.style.fontFamily=s.fontFamily}else u.style.background=s.backgroundColor||"#fff",u.style.border=s.border||"1px solid #ddd";r.appendChild(u)}let d=document.createElement("div");return d.textContent=e,d.style.cssText="position:absolute;top:-6px;right:-6px;min-width:22px;height:22px;padding:0 5px;background:#3b82f6;color:#fff;border-radius:11px;display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:700;border:2px solid #fff;box-shadow:0 1px 3px rgba(0,0,0,0.2);",r.appendChild(d),r.style.width=i+(a-1)*4+"px",r.style.height=c+(a-1)*4+"px",r}var oe=null;function Bo(){return oe&&oe.isConnected?oe:typeof document>"u"||!document.body?null:(oe=document.createElement("div"),oe.setAttribute("aria-live","assertive"),oe.setAttribute("aria-atomic","true"),oe.setAttribute("role","status"),oe.className="nojs-dnd-live-region",oe.style.cssText="position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;padding:0;margin:-1px;",document.body.appendChild(oe),oe)}function ce(t){let e=Bo();e&&(e.textContent="",typeof requestAnimationFrame<"u"?requestAnimationFrame(()=>{e.textContent=t}):e.textContent=t)}function Gt(t){if(de(t)){t.directive("drag",{priority:15,init(e,r){ke(),Vt(e,$o(e,r))}});return}Ze(t,"drag"),t.directive("drag",{priority:15,init(e,r,o){ke(),Vt(e,Ho(t,e,o))}})}function Ho(t,e,r){let o=t.findContext(e);ze(e,o);let n=e.getAttribute("drag-disabled");return{ctx:o,value:()=>t.evaluate(r,o),disabled:()=>n?t.evaluate(n,o):!1,watchDisabled:i=>le(e,o.$watch(i)),onDispose:i=>le(e,i)}}function $o(t,e){return{ctx:null,value:()=>t.getAttribute("drag"),disabled:()=>e.value(t,"drag-disabled"),watchDisabled:r=>e.watch(t,"drag-disabled",r),onDispose:r=>e.onDispose(t,r)}}function Vt(t,e){let r=t.getAttribute("drag-type")||"default",o=t.getAttribute("drag-effect")||"move",n=t.getAttribute("drag-handle"),i=t.getAttribute("drag-image"),c=t.getAttribute("drag-image-offset")||"0,0",s=t.getAttribute("drag-disabled"),a=t.getAttribute("drag-class")||"nojs-dragging",d=t.getAttribute("drag-ghost-class");t.draggable=!0,t.setAttribute("aria-roledescription","draggable item"),t.getAttribute("role")||t.setAttribute("role","button"),t.getAttribute("tabindex")||t.setAttribute("tabindex","0");let g=!0;if(n){let l=b=>{g=!!b.target.closest(n)};t.addEventListener("mousedown",l),e.onDispose(()=>t.removeEventListener("mousedown",l))}let u=l=>{if(n&&!g){l.preventDefault();return}if(s&&e.disabled()){l.preventDefault();return}let b=e.value(),h=t.getAttribute("drag-group"),m=b;if(h&&_.selected.has(h)){let y=_.selected.get(h);y.size>0&&[...y].some(j=>j.el===t)&&(m=[...y].map(j=>j.item))}if(_.dragging={item:m,type:r,effect:o,sourceEl:t,sourceCtx:e.ctx,sourceList:null,sourceIndex:null,listDirective:null},l.dataTransfer){if(l.dataTransfer.effectAllowed=o,l.dataTransfer.setData("text/plain",""),Array.isArray(m)&&m.length>1&&l.dataTransfer.setDragImage){let y=Io(t,m.length);document.body.appendChild(y);let x=t.getBoundingClientRect();l.dataTransfer.setDragImage(y,x.width/2,x.height/2),requestAnimationFrame(()=>y.remove())}else if(i&&l.dataTransfer.setDragImage)if(i==="none"){let y=document.createElement("div");y.style.cssText="width:1px;height:1px;opacity:0;position:fixed;top:-999px",document.body.appendChild(y);let[x,j]=c.split(",").map(Number);l.dataTransfer.setDragImage(y,x||0,j||0),requestAnimationFrame(()=>y.remove())}else{let y=t.querySelector(i);if(y){let[x,j]=c.split(",").map(Number);d&&y.classList.add(d),l.dataTransfer.setDragImage(y,x||0,j||0)}}}if(a.split(/\s+/).filter(Boolean).forEach(y=>t.classList.add(y)),Array.isArray(m)&&h&&_.selected.has(h))for(let y of _.selected.get(h))y.el!==t&&a.split(/\s+/).filter(Boolean).forEach(x=>y.el.classList.add(x));let v=t.getAttribute("aria-label")||t.textContent?.trim()?.slice(0,50)||"Item";ce(`Grabbed ${v}. Use arrow keys to move.`),t.dispatchEvent(new CustomEvent("nojs:dnd-start",{bubbles:!0,detail:{item:m,index:_.dragging.sourceIndex,el:t}}))},f=()=>{a.split(/\s+/).filter(Boolean).forEach(b=>t.classList.remove(b));let l=t.getAttribute("drag-group");if(l&&_.selected.has(l))for(let b of _.selected.get(l))a.split(/\s+/).filter(Boolean).forEach(h=>b.el.classList.remove(h));if(d&&i&&i!=="none"){let b=t.querySelector(i);b&&b.classList.remove(d)}t.dispatchEvent(new CustomEvent("nojs:dnd-end",{bubbles:!0,detail:{item:_.dragging?.item,index:_.dragging?.sourceIndex,dropped:_.dragging===null}})),_.dragging=null,re()};if(t.addEventListener("dragstart",u),t.addEventListener("dragend",f),e.onDispose(()=>{t.removeEventListener("dragstart",u),t.removeEventListener("dragend",f)}),s){let l=function(){let b=!!e.disabled();t.draggable=!b,b?t.removeAttribute("aria-roledescription"):t.setAttribute("aria-roledescription","draggable item")};e.watchDisabled(l)}let p=l=>{if(_.dragging&&!_.dragging.sourceEl.isConnected&&(_.dragging=null),l.key===" "&&!_.dragging){l.preventDefault();let b=e.value();_.dragging={item:b,type:r,effect:o,sourceEl:t,sourceCtx:e.ctx,sourceList:null,sourceIndex:null,listDirective:null},a.split(/\s+/).filter(Boolean).forEach(m=>t.classList.add(m));let h=t.getAttribute("aria-label")||t.textContent?.trim()?.slice(0,50)||"Item";ce(`Grabbed ${h}. Use arrow keys to move.`),t.dispatchEvent(new CustomEvent("nojs:dnd-start",{bubbles:!0,detail:{item:b,index:null,el:t}}))}else l.key==="Escape"&&_.dragging&&_.dragging.sourceEl===t&&(l.preventDefault(),a.split(/\s+/).filter(Boolean).forEach(b=>t.classList.remove(b)),ce("Drag cancelled."),_.dragging=null,re())};t.addEventListener("keydown",p),e.onDispose(()=>t.removeEventListener("keydown",p))}function Ut(t){if(de(t)){t.directive("drop",{priority:15,init(e,r){ke(),Wt(e,Mo(e,r)),Po(e,r)}});return}Ze(t,"drop"),t.directive("drop",{priority:15,init(e,r,o){ke(),Wt(e,qo(t,e,o))}})}function qo(t,e,r){let o=t.findContext(e);ze(e,o);let n=e.getAttribute("drop-disabled"),i=e.getAttribute("drop-max");return{disabled:()=>n?t.evaluate(n,o):!1,max:()=>i?t.evaluate(i,o):void 0,run(c){let s=X(t,"execStatement");typeof s=="function"?s(r,o,c):(X(t,"warn")||console.warn)("[nojs-elements] core too old (<1.13.0): internals.execStatement unavailable; drop expression skipped.")},onDispose:c=>le(e,c)}}function Mo(t,e){return{disabled:()=>e.value(t,"drop-disabled"),max:()=>e.value(t,"drop-max"),run(r){e.exec(t.getAttribute("drop"),{$drag:r.$drag,$dragType:r.$dragType,$dragEffect:r.$dragEffect,$dropIndex:r.$dropIndex,$source:{index:r.$source.index},$target:{index:r.$target.index}})},onDispose:r=>e.onDispose(t,r)}}function Po(t,e){t.hasAttribute("drop-disabled")&&e.watch(t,"drop-disabled",()=>{if(!e.value(t,"drop-disabled"))return;let r=t.getAttribute("drop-class")||"nojs-drag-over",o=t.getAttribute("drop-reject-class")||"nojs-drop-reject";r.split(/\s+/).filter(Boolean).forEach(n=>t.classList.remove(n)),o.split(/\s+/).filter(Boolean).forEach(n=>t.classList.remove(n)),_.placeholder&&t.contains(_.placeholder)&&re()})}function Wt(t,e){let r=t.getAttribute("drop-accept")||"default",o=t.getAttribute("drop-effect")||"move",n=t.getAttribute("drop-class")||"nojs-drag-over",i=t.getAttribute("drop-reject-class")||"nojs-drop-reject",c=t.getAttribute("drop-disabled"),s=t.getAttribute("drop-max"),a=t.getAttribute("drop-sort"),d=t.getAttribute("drop-placeholder"),g=t.getAttribute("drop-placeholder-class");t.setAttribute("aria-dropeffect",o);let u=0,f=m=>{if(!_.dragging||c&&e.disabled())return;let v=xe(_.dragging.type,r),y=!0;if(s){let x=e.max(),j=Ke(t);typeof x=="number"&&j>=x&&(y=!1)}if(!v||!y){i.split(/\s+/).filter(Boolean).forEach(x=>t.classList.add(x)),n.split(/\s+/).filter(Boolean).forEach(x=>t.classList.remove(x)),re();return}if(i.split(/\s+/).filter(Boolean).forEach(x=>t.classList.remove(x)),m.preventDefault(),m.dataTransfer&&(m.dataTransfer.dropEffect=o),a){let x=Xe(t,m.clientX,m.clientY,a);d&&Nt(t,x,d,g),t.dispatchEvent(new CustomEvent("nojs:dnd-over",{bubbles:!1,detail:{item:_.dragging.item,index:x}}))}},p=m=>{if(_.dragging&&!(c&&e.disabled())&&(u++,u===1)){let v=xe(_.dragging.type,r),y=!0;if(s){let x=e.max(),j=Ke(t);typeof x=="number"&&j>=x&&(y=!1)}v&&y?(n.split(/\s+/).filter(Boolean).forEach(x=>t.classList.add(x)),t.dispatchEvent(new CustomEvent("nojs:dnd-enter",{bubbles:!1,detail:{item:_.dragging.item,type:_.dragging.type}}))):i.split(/\s+/).filter(Boolean).forEach(x=>t.classList.add(x))}},l=m=>{_.dragging&&(u--,u<=0&&(u=0,n.split(/\s+/).filter(Boolean).forEach(v=>t.classList.remove(v)),i.split(/\s+/).filter(Boolean).forEach(v=>t.classList.remove(v)),re(),t.dispatchEvent(new CustomEvent("nojs:dnd-leave",{bubbles:!1,detail:{item:_.dragging.item}}))))},b=m=>{if(m.preventDefault(),m.stopPropagation(),u=0,!_.dragging||c&&e.disabled()||!xe(_.dragging.type,r))return;if(s){let L=e.max(),w=Ke(t);if(typeof L=="number"&&w>=L)return}let v=_.dragging.item,y=_.dragging.type,x=_.dragging.effect,j=0;a&&(j=Xe(t,m.clientX,m.clientY,a)),n.split(/\s+/).filter(Boolean).forEach(L=>t.classList.remove(L)),i.split(/\s+/).filter(Boolean).forEach(L=>t.classList.remove(L)),re();let E={$drag:v,$dragType:y,$dragEffect:x,$dropIndex:j,$source:{list:_.dragging.sourceList,index:_.dragging.sourceIndex,el:_.dragging.sourceEl},$target:{list:null,index:j,el:t},$el:t};e.run(E),_.dragging=null,t.dispatchEvent(new CustomEvent("nojs:dnd-drop",{bubbles:!1,detail:{item:v,index:j,source:E.$source,target:E.$target,effect:x}}))},h=m=>{_.dragging&&(m.key==="Enter"||m.key===" ")&&(m.preventDefault(),b(m))};t.addEventListener("dragover",f),t.addEventListener("dragenter",p),t.addEventListener("dragleave",l),t.addEventListener("drop",b),t.addEventListener("keydown",h),e.onDispose(()=>{t.removeEventListener("dragover",f),t.removeEventListener("dragenter",p),t.removeEventListener("dragleave",l),t.removeEventListener("drop",b),t.removeEventListener("keydown",h)})}function Yt(t){Ze(t,"drag-list"),t.directive("drag-list",{priority:10,init(e,r,o){ke();let n=t.findContext(e);ze(e,n);let i=e.getAttribute("template"),c=e.getAttribute("drag-list-key"),s=e.getAttribute("drag-list-item")||"item",a=e.getAttribute("drop-sort")||"vertical",d=e.getAttribute("drag-type")||"__draglist_"+o,g=e.getAttribute("drop-accept")||d,u=e.hasAttribute("drag-list-copy"),f=e.hasAttribute("drag-list-remove"),p=e.getAttribute("drag-disabled"),l=e.getAttribute("drop-disabled"),b=e.getAttribute("drop-max"),h=e.getAttribute("drop-placeholder"),m=e.getAttribute("drop-placeholder-class"),v=e.getAttribute("drag-class")||"nojs-dragging",y=e.getAttribute("drop-class")||"nojs-drag-over",x=e.getAttribute("drop-reject-class")||"nojs-drop-reject",j=e.getAttribute("drop-settle-class")||"nojs-drop-settle",E=e.getAttribute("drop-empty-class")||"nojs-drag-list-empty";e.setAttribute("role","listbox"),e.setAttribute("aria-dropeffect",u?"copy":"move");let L={listPath:o,ctx:n,el:e};Ye.set(e,L),le(e,()=>Ye.delete(e));let w=0,A=null;function C(){let S=t.resolve(o,n);if(!Array.isArray(S))return;if(S===A&&S.length>0&&e.children.length>0){for(let F of e.children)F.__ctx&&F.__ctx.$notify&&F.__ctx.$notify();return}A=S;let $=i?document.getElementById(i):null;if(!$)return;let P=X(t,"disposeChildren");typeof P=="function"&&P(e),e.innerHTML="";let R=S.length;S.forEach((F,K)=>{let ee={[s]:F,$index:K,$count:R,$first:K===0,$last:K===R-1,$even:K%2===0,$odd:K%2!==0},te=t.createContext(ee,n),he=$.content.cloneNode(!0),B=document.createElement("div");B.style.display="contents",B.__ctx=te,B.appendChild(he),e.appendChild(B);let z=B.firstElementChild||B;z.draggable=!0,z.setAttribute("role","option"),z.setAttribute("aria-roledescription","draggable item"),z.getAttribute("tabindex")||z.setAttribute("tabindex","0");let ae=W=>{if(p&&t.evaluate(p,n)){W.preventDefault();return}_.dragging={item:F,type:d,effect:u?"copy":"move",sourceEl:B,sourceCtx:te,sourceList:S,sourceIndex:K,listDirective:{el:e,listPath:o,ctx:n,keyProp:c,copyMode:u,removeMode:f}},W.dataTransfer&&(W.dataTransfer.effectAllowed=u?"copy":"move",W.dataTransfer.setData("text/plain","")),v.split(/\s+/).filter(Boolean).forEach(ye=>z.classList.add(ye));let Z=z.getAttribute("aria-label")||z.textContent?.trim()?.slice(0,50)||"Item";ce(`Grabbed ${Z}. Use arrow keys to reorder.`),e.dispatchEvent(new CustomEvent("nojs:dnd-start",{bubbles:!0,detail:{item:F,index:K,el:z}}))},ve=()=>{v.split(/\s+/).filter(Boolean).forEach(W=>z.classList.remove(W)),_.dragging&&_.dragging.sourceEl===B&&(_.dragging=null),re()};B.addEventListener("dragstart",ae),B.addEventListener("dragend",ve);let Ue=W=>{if(W.key===" "&&!_.dragging){W.preventDefault(),W.stopPropagation(),_.dragging={item:F,type:d,effect:u?"copy":"move",sourceEl:B,sourceCtx:te,sourceList:S,sourceIndex:K,listDirective:{el:e,listPath:o,ctx:n,keyProp:c,copyMode:u,removeMode:f}},v.split(/\s+/).filter(Boolean).forEach(ye=>z.classList.add(ye));let Z=z.getAttribute("aria-label")||z.textContent?.trim()?.slice(0,50)||"Item";ce(`Grabbed ${Z}. Use arrow keys to reorder.`)}else if(W.key==="Escape"&&_.dragging){W.preventDefault(),W.stopPropagation();let Z=e.querySelector(`.${v.split(/\s+/)[0]}`)||z;v.split(/\s+/).filter(Boolean).forEach(ye=>Z.classList.remove(ye)),ce("Reorder cancelled."),_.dragging=null,re()}else if((W.key==="ArrowDown"||W.key==="ArrowRight")&&_.dragging&&_.dragging.sourceEl===B){W.preventDefault();let Z=B.nextElementSibling;if(Z){(Z.firstElementChild||Z).focus();let Re=[...e.children].filter(bt=>!bt.classList.contains("nojs-drop-placeholder")),gt=Re.indexOf(Z)+1;ce(`Moved to position ${gt} of ${Re.length}.`)}}else if((W.key==="ArrowUp"||W.key==="ArrowLeft")&&_.dragging&&_.dragging.sourceEl===B){W.preventDefault();let Z=B.previousElementSibling;if(Z){(Z.firstElementChild||Z).focus();let Re=[...e.children].filter(bt=>!bt.classList.contains("nojs-drop-placeholder")),gt=Re.indexOf(Z)+1;ce(`Moved to position ${gt} of ${Re.length}.`)}}};B.addEventListener("keydown",Ue),B.__disposers=B.__disposers||[],B.__disposers.push(()=>B.removeEventListener("dragstart",ae),()=>B.removeEventListener("dragend",ve),()=>B.removeEventListener("keydown",Ue)),t.processTree(B)});let M=S.length===0;E.split(/\s+/).filter(Boolean).forEach(F=>e.classList.toggle(F,M))}let D=S=>{if(!_.dragging||l&&t.evaluate(l,n))return;let $=xe(_.dragging.type,g),P=!0;if(b){let M=t.evaluate(b,n),F=t.resolve(o,n);typeof M=="number"&&Array.isArray(F)&&F.length>=M&&(P=!1)}if(!$||!P){x.split(/\s+/).filter(Boolean).forEach(M=>e.classList.add(M)),y.split(/\s+/).filter(Boolean).forEach(M=>e.classList.remove(M)),re();return}x.split(/\s+/).filter(Boolean).forEach(M=>e.classList.remove(M)),S.preventDefault(),S.dataTransfer&&(S.dataTransfer.dropEffect=u?"copy":"move");let R=Xe(e,S.clientX,S.clientY,a);h&&Nt(e,R,h,m)},H=S=>{if(_.dragging&&!(l&&t.evaluate(l,n))&&(w++,w===1)){let $=xe(_.dragging.type,g),P=!0;if(b){let R=t.evaluate(b,n),M=t.resolve(o,n);typeof R=="number"&&Array.isArray(M)&&M.length>=R&&(P=!1)}$&&P?(y.split(/\s+/).filter(Boolean).forEach(R=>e.classList.add(R)),e.dispatchEvent(new CustomEvent("nojs:dnd-enter",{bubbles:!1,detail:{item:_.dragging.item,type:_.dragging.type}}))):x.split(/\s+/).filter(Boolean).forEach(R=>e.classList.add(R))}},k=()=>{_.dragging&&(w--,w<=0&&(w=0,y.split(/\s+/).filter(Boolean).forEach(S=>e.classList.remove(S)),x.split(/\s+/).filter(Boolean).forEach(S=>e.classList.remove(S)),re(),e.dispatchEvent(new CustomEvent("nojs:dnd-leave",{bubbles:!1,detail:{item:_.dragging?.item}}))))},U=S=>{if(S.preventDefault(),S.stopPropagation(),w=0,!_.dragging||l&&t.evaluate(l,n)||!xe(_.dragging.type,g))return;if(b){let B=t.evaluate(b,n),z=t.resolve(o,n);if(typeof B=="number"&&Array.isArray(z)&&z.length>=B)return}let $=_.dragging.item,P=_.dragging.listDirective,R=_.dragging.sourceIndex,M=Xe(e,S.clientX,S.clientY,a);y.split(/\s+/).filter(Boolean).forEach(B=>e.classList.remove(B)),x.split(/\s+/).filter(Boolean).forEach(B=>e.classList.remove(B)),re();let F=t.resolve(o,n);if(!Array.isArray(F))return;let K=P&&P.el===e;if(K&&R===M){_.dragging=null;return}if(K&&R+1===M){_.dragging=null;return}let ee=[...F];if(K){let[B]=ee.splice(R,1),z=R Ue!==R);P.ctx.$set(P.listPath,ae),P.el.dispatchEvent(new CustomEvent("nojs:dnd-remove",{bubbles:!0,detail:{list:ae,item:$,index:R}}))}}e.dispatchEvent(new CustomEvent("nojs:dnd-receive",{bubbles:!0,detail:{list:ee,item:$,from:R,fromList:P?t.resolve(P.listPath,P.ctx):null}}))}let te=_.dragging?.sourceEl?.firstElementChild?.getAttribute("aria-label")||_.dragging?.sourceEl?.firstElementChild?.textContent?.trim()?.slice(0,50)||"Item",he=K&&R {let z=[...e.children][K&&R ae.classList.add(ve)),ae.addEventListener("animationend",()=>{j.split(/\s+/).filter(Boolean).forEach(ve=>ae.classList.remove(ve))},{once:!0})}}),_.dragging=null},V=S=>{if(_.dragging&&xe(_.dragging.type,g)&&(S.key==="Enter"||S.key===" ")){S.preventDefault();let $=e.querySelector(":focus");if($){let R=($.style?.display==="contents"&&$.firstElementChild||$).getBoundingClientRect(),M={preventDefault(){},stopPropagation(){},clientX:R.left+R.width/2,clientY:R.top+R.height+1,dataTransfer:null};U(M)}}};e.addEventListener("dragover",D),e.addEventListener("dragenter",H),e.addEventListener("dragleave",k),e.addEventListener("drop",U),e.addEventListener("keydown",V),le(e,()=>{e.removeEventListener("dragover",D),e.removeEventListener("dragenter",H),e.removeEventListener("dragleave",k),e.removeEventListener("drop",U),e.removeEventListener("keydown",V)});let be=n.$watch(C);le(e,be),C()}})}function Kt(t){Ze(t,"drag-multiple"),t.directive("drag-multiple",{priority:16,init(e,r){let o=t.findContext(e);ze(e,o);let n=e.getAttribute("drag-group"),i=e.getAttribute("drag-multiple-class")||"nojs-selected";if(!n){(X(t,"warn")||console.warn)("drag-multiple requires drag-group attribute");return}_.selected.has(n)||_.selected.set(n,new Set);let c=_.selected.get(n),s=d=>{let g=e.getAttribute("drag"),f={item:g?t.evaluate(g,o):null,el:e,ctx:o};if(d.ctrlKey||d.metaKey){let p=[...c].find(l=>l.el===e);p?(c.delete(p),i.split(/\s+/).filter(Boolean).forEach(l=>e.classList.remove(l))):(c.add(f),i.split(/\s+/).filter(Boolean).forEach(l=>e.classList.add(l)))}else{for(let p of c)i.split(/\s+/).filter(Boolean).forEach(l=>p.el.classList.remove(l));c.clear(),c.add(f),i.split(/\s+/).filter(Boolean).forEach(p=>e.classList.add(p))}};e.addEventListener("click",s),le(e,()=>{e.removeEventListener("click",s);let d=[...c].find(g=>g.el===e);d&&c.delete(d)});let a=d=>{if(d.key==="Escape"){for(let g of c)i.split(/\s+/).filter(Boolean).forEach(u=>g.el.classList.remove(u));c.clear()}};window.addEventListener("keydown",a),le(e,()=>window.removeEventListener("keydown",a))}})}var Xt=["drag","drop"];function vt(t,e={}){Gt(t),Ut(t),!de(t)&&(Yt(t),Kt(t))}function Zt(){Ot()}var Qt=[["valueMissing","required"],["typeMismatch",null],["tooShort","minlength"],["tooLong","maxlength"],["patternMismatch","pattern"],["rangeUnderflow","min"],["rangeOverflow","max"],["stepMismatch","step"]],yt=["required","email","url","number","date","time","datetime-local","month","week","tel","minlength","maxlength","pattern","min","max","step"];function ue(t,e){t.__disposers=t.__disposers||[],t.__disposers.push(e)}var Ee,nr,Je,et,xt,Jt,Qe,_t,er,Et;function Ro(t){let e=document.createTreeWalker(t,NodeFilter.SHOW_ELEMENT);for(;e.nextNode();)e.currentNode.__declared=!1}function zo(t){return(t.getAttribute("type")||"text").toLowerCase()}function Fo(t,e){let r=[],o=new Set,n=t.getAttribute("validate");if(n){let c=n.split("|").map(s=>s.trim());for(let s of c){let[a,...d]=s.split(":"),g=Ee[a];if(g){let u=g(t.value,...d,e);u!==!0&&u&&(r.push({rule:a,message:u}),o.add(a))}else{let u=t.value,f=null;switch(a){case"required":(u==null||String(u).trim()==="")&&(f="Required");break;case"email":u&&!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(u)&&(f="Invalid email");break;case"url":try{new URL(u)}catch{f="Invalid URL"}break;case"min":Number(u) Number(d[0])&&(f=`Maximum value is ${d[0]}`);break;case"custom":if(d[0]&&Ee[d[0]]){let p=Ee[d[0]](u,e);p!==!0&&p&&(f=p)}break}f&&(r.push({rule:a,message:f}),o.add(a))}}}let i=t.validity;if(i&&!i.valid){for(let[c,s]of Qt)if(i[c]){let a=s||zo(t);o.has(a)||(r.push({rule:a,message:t.validationMessage}),o.add(a))}}return r}function Oo(t,e,r){let o=t.getAttribute(`error-${e}`);if(o)return o;let n=t.getAttribute("error");return n&&!n.startsWith("#")?n:r}function Vo(t,e){if(!t.length)return null;let o=[...t].sort((n,i)=>{let c=yt.indexOf(n.rule),s=yt.indexOf(i.rule);return(c===-1?999:c)-(s===-1?999:s)})[0];return{rule:o.rule,message:Oo(e,o.rule,o.message)}}function or(t){let e=t.closest("form");if(e){for(let r of e.querySelectorAll('div[style="display: contents;"]'))if(r.__errorTemplateFor===t)return r}for(let r of document.querySelectorAll('div[style="display: contents;"]'))if(r.__errorTemplateFor===t)return r;return null}function Wo(t,e,r,o,n){let i=or(o);if(i){if(i.__ctx?.$error===e&&i.__ctx?.$rule===r)return;_t(i),i.remove()}let c=document.querySelector(t);if(!c)return;let s=c.content.cloneNode(!0),a=document.createElement("div");a.style.display="contents",a.setAttribute("aria-live","polite"),a.__errorTemplateFor=o;let d=Je({$error:e,$rule:r},n);a.__ctx=d,a.appendChild(s),c.parentNode.insertBefore(a,c.nextSibling),Ro(a),xt(a)}function tr(t){let e=or(t);e&&(_t(e),e.remove())}function No(t,e){let r=t.getAttribute("validate-if");if(!r)return!0;try{return!!nr(r,e)}catch{return!0}}function rr(t,e){let r=t.getAttribute("validate-on");if(r)return r.split(/\s+/);let o=e?e.getAttribute("validate-on"):null;return o?o.split(/\s+/):["input","focusout"]}function Go(t){return t.hasAttribute("model")?t.tagName==="SELECT"||t.type==="checkbox"||t.type==="radio"?"change":"input":null}function Uo(t,e){return()=>{let r=t.getAttribute("model"),o=t.__gatedDirs&&t.__gatedDirs.some(n=>n.name==="model");if(r&&!o&&Et&&(t.type!=="radio"||t.checked)){let n=t.type==="checkbox"?t.checked:t.value;Et(`${r} = __val`,et(t),{__val:n})}e()}}function Yo(t,e,r){let o=e.split("|").map(n=>n.trim());for(let n of o){let[i,...c]=n.split(":"),s=Ee[i];if(s){let a=s(t,...c,r);if(a!==!0&&a)return a}else switch(i){case"required":if(t==null||String(t).trim()==="")return"Required";break;case"email":if(t&&!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t))return"Invalid email";break;case"url":try{new URL(t)}catch{return"Invalid URL"}break;case"min":if(Number(t) Number(c[0]))return`Maximum value is ${c[0]}`;break;case"custom":if(c[0]&&Ee[c[0]]){let a=Ee[c[0]](t,r);if(a!==!0&&a)return a}break}}return null}function Ko(t){if(t.__ctx)return t.__ctx;for(let r=t.parentElement;r;r=r.parentElement)if(r.__ctx)return et(t);let e=Je({},null);return t.__ctx=e,e}function ir(t){Ee=X(t,"validators")||{},nr=t.evaluate,Je=t.createContext,et=t.findContext,xt=t.processTree,Jt=X(t,"cloneTemplate")||(()=>null),Qe=X(t,"disposeChildren")||(()=>{}),_t=X(t,"disposeTree")||Qe,er=X(t,"warn")||console.warn,Et=X(t,"execStatement");let e=X(t,"removeCoreDirective");typeof e=="function"?e("validate"):er('[nojs-elements] core too old (<1.13.0): cannot remove "validate" stub; update NoJS core to 1.13.0+.'),t.directive("validate",{priority:30,init(r,o,n){if(r.tagName==="FORM"){let f=function(){c&&typeof c.$notify=="function"&&c.$notify();let E=document.createTreeWalker(r,NodeFilter.SHOW_ELEMENT);for(;E.nextNode();){let w=E.currentNode.__ctx;w&&w!==c&&typeof w.$notify=="function"&&w.$notify()}},p=function(){return r.querySelectorAll("input, textarea, select")},l=function(){let E={},L={},w={},A=!0,C=null,D=0,H=!1;for(let k of p())k.name&&(k.type==="checkbox"?L[k.name]=k.checked:k.type==="radio"?k.checked?L[k.name]=k.value:k.name in L||(L[k.name]=""):L[k.name]=k.value);for(let k of p()){if(!k.name)continue;let U=a.has(k.name),V=d.has(k.name);if(!No(k,c)){w[k.name]={valid:!0,dirty:V,touched:U,error:null,value:L[k.name]};continue}let be=Fo(k,L),S=Vo(be,k),$=!S,P=rr(k,r),R=P.includes("input"),M=P.includes("blur")||P.includes("focusout")||P.includes("submit"),F;!k.hasAttribute("validate-on")&&!r.hasAttribute("validate-on")?F=U||V:F=R&&V||M&&U,$||(A=!1),!$&&F&&(E[k.name]=S.message,D++,C||(C=S.message)),w[k.name]={valid:$,dirty:V,touched:U,error:S?S.message:null,value:L[k.name]},!$&&F?k.setAttribute("aria-invalid","true"):k.removeAttribute("aria-invalid");let K=k.getAttribute("error-class")||s;if(K){let te=K.split(/\s+/);!$&&F?k.classList.add(...te):k.classList.remove(...te)}if(S&&F){let te=k.getAttribute(`error-${S.rule}`),he=k.getAttribute("error"),B=(te&&te.startsWith("#")?te:null)||(he&&he.startsWith("#")?he:null);B?Wo(B,S.message,S.rule,k,c):tr(k)}else tr(k);let ee=k.getAttribute("as");ee&&c.$set(ee,w[k.name])}g.size>0&&(H=!0),u.valid=A,u.errors=E,u.values=L,u.fields=w,u.firstError=C,u.errorCount=D,u.pending=H,c.$set("$form",{...u}),f(),b(r)},b=function(E){let L=u.valid&&!u.pending&&!u.submitting,w=E.querySelectorAll('button:not([type="button"]), input[type="submit"]');for(let A of w){if(A.hasAttribute("disabled")&&A.getAttribute("disabled")!==""){let C=A.getAttribute("disabled");if(C!=="disabled"&&C!=="true"&&C!=="false")continue}A.disabled=!L,A.__autoDisabled=!0}},m=function(E,L,w){E.addEventListener(L,w),ue(r,()=>E.removeEventListener(L,w))},v=function(E){if(!E.name)return;let L=rr(E,r),w=Go(E),A=H=>{if(w==="change"){m(E,"input",Uo(E,H));return}m(E,"input",H),w&&h.push([E,"input",H])},C=()=>{d.add(E.name),u.dirty=!0,l()},D=()=>{a.add(E.name),u.touched=!0,l()};L.includes("input")?A(C):A(()=>{d.add(E.name),u.dirty=!0,l()}),L.includes("blur")||L.includes("focusout")?m(E,"focusout",()=>{D(),L.includes("blur")&&C()}):m(E,"focusout",D),L.includes("submit")&&m(E,"focusout",D)},c=Ko(r);r.setAttribute("novalidate","");let s=r.getAttribute("error-class"),a=new Set,d=new Set,g=new Map,u={valid:!1,dirty:!1,touched:!1,submitting:!1,pending:!1,errors:{},values:{},firstError:null,errorCount:0,fields:{},reset:()=>{u.dirty=!1,u.touched=!1,u.pending=!1,u.submitting=!1,a.clear(),d.clear(),r.reset(),l()},endSubmit:()=>{u.submitting=!1,l()}};c.$set("$form",u);let h=[],y=r.hasAttribute("validate-on"),x=[...p()].some(E=>E.hasAttribute("validate-on"));if(!y&&!x){let E=w=>{let A=w.target;A&&A.name&&d.add(A.name),u.dirty=!0,l()};r.addEventListener("input",E),ue(r,()=>r.removeEventListener("input",E)),r.addEventListener("change",E),ue(r,()=>r.removeEventListener("change",E));let L=w=>{w.target&&w.target.name&&a.add(w.target.name),u.touched=!0,l()};r.addEventListener("focusout",L),ue(r,()=>r.removeEventListener("focusout",L))}else{for(let E of p())v(E);if(h.length){let E=!1;ue(r,()=>{E=!0}),queueMicrotask(()=>{if(!E){for(let[L,w,A]of h)L.removeEventListener(w,A),L.addEventListener(w,A);h.length=0}})}}let j=E=>{for(let L of p())L.name&&a.add(L.name);if(u.touched=!0,l(),!u.valid||u.pending){E.preventDefault(),E.stopImmediatePropagation();return}u.submitting=!0,b(r),c.$set("$form",{...u}),f()};r.addEventListener("submit",j,!0),ue(r,()=>r.removeEventListener("submit",j,!0)),r.__nojsResetSubmitting=()=>{u.submitting=!1,l()},ue(r,()=>{delete r.__nojsResetSubmitting}),requestAnimationFrame(l);return}let i=et(r);if(n&&(r.tagName==="INPUT"||r.tagName==="TEXTAREA"||r.tagName==="SELECT")){let c=r.getAttribute("error"),s=()=>{let a=Yo(r.value,n,{});if(a?r.setAttribute("aria-invalid","true"):r.removeAttribute("aria-invalid"),a&&c){let d=r.nextElementSibling?.__validationError?r.nextElementSibling:null;d||(d=document.createElement("div"),d.__validationError=!0,d.style.display="contents",r.parentNode.insertBefore(d,r.nextSibling));let g=Jt(c);if(g){let u=Je({err:{message:a}},i);Qe(d),d.innerHTML="",d.__ctx=u,d.appendChild(g),xt(d)}}else{let d=r.nextElementSibling?.__validationError?r.nextElementSibling:null;d&&(Qe(d),d.innerHTML="")}};r.addEventListener("input",s),ue(r,()=>r.removeEventListener("input",s))}}})}function sr(t,e={}){ir(t)}function ar(){}var Ce=new Map,J=new Map;function cr(){let t=Array.from(Ce.keys());for(let e of t){let r=e&&e.__disposers;if(r){for(let o of r)try{o()}catch{}e.__disposers=[]}}for(let e of J.values())clearTimeout(e);J.clear();for(let e of Ce.values())e.remove();Ce.clear()}function dr(){if(typeof document>"u"||document.querySelector("style[data-nojs-tooltip]"))return;let t=` .nojs-tooltip { position: fixed; z-index: 9999; @@ -66,7 +66,7 @@ var mt=Object.defineProperty;var ho=Object.getOwnPropertyDescriptor;var vo=Objec opacity: 1; transform: translateY(0); } -`.trim(),e=document.createElement("style");e.setAttribute("data-nojs-tooltip",""),e.textContent=t,document.head.appendChild(e)}function Bo(t,e){t.__disposers=t.__disposers||[],t.__disposers.push(e)}var Ze=8;function or(t,e,r){let o=e.getBoundingClientRect(),n=t.getBoundingClientRect(),i=window.innerWidth,c=window.innerHeight,a,s;switch(r){case"bottom":a=o.bottom+Ze,s=o.left+(o.width-n.width)/2;break;case"left":a=o.top+(o.height-n.height)/2,s=o.left-n.width-Ze;break;case"right":a=o.top+(o.height-n.height)/2,s=o.right+Ze;break;default:a=o.top-n.height-Ze,s=o.left+(o.width-n.width)/2;break}s<4&&(s=4),s+n.width>i-4&&(s=i-n.width-4),a<4&&(a=4),a+n.height>c-4&&(a=c-n.height-4),t.style.top=`${a}px`,t.style.left=`${s}px`}var $o=0;function qo(t,e,r){document.body.appendChild(e),or(e,t,r),e.setAttribute("aria-hidden","false")}function nr(t,e){e.setAttribute("aria-hidden","true"),e.remove()}function Mo(t,e){t&&typeof t._warn=="function"?t._warn(e):console.warn(e)}function ir(t){t.directive("tooltip",{priority:20,init(e,r,o){rr();let n=o;if(!n){Mo(t,"[tooltip] attribute value (tooltip text) is required.");return}let i=e.getAttribute("tooltip-position")||"top",c=parseInt(e.getAttribute("tooltip-delay"),10),a=Number.isNaN(c)?300:c,s=e.getAttribute("tooltip-disabled"),d=s?t.findContext(e):null,m=()=>{if(!s||!d)return!1;try{return!!t.evaluate(s,d)}catch{return!1}},l=`nojs-tooltip-${++$o}`,f=document.createElement("div");f.className="nojs-tooltip",f.setAttribute("role","tooltip"),f.setAttribute("id",l),f.setAttribute("aria-hidden","true"),f.textContent=n,e.setAttribute("aria-describedby",l),je.set(e,f);let u=!1,p=0,v=()=>{!u||!e.isConnected||p||(p=requestAnimationFrame(()=>{p=0,!(!u||!e.isConnected)&&or(f,e,i)}))},h=()=>{window.addEventListener("scroll",v,!0),window.addEventListener("resize",v)},g=()=>{window.removeEventListener("scroll",v,!0),window.removeEventListener("resize",v),p&&(cancelAnimationFrame(p),p=0)},b=()=>{u||(qo(e,f,i),u=!0,h())},E=()=>{if(!u){nr(e,f);return}g(),nr(e,f),u=!1},y=()=>{if(m())return;ee.has(e)&&clearTimeout(ee.get(e));let $=setTimeout(()=>{ee.delete(e),!m()&&e.isConnected&&b()},a);ee.set(e,$)},_=()=>{ee.has(e)&&(clearTimeout(ee.get(e)),ee.delete(e)),E()},x=()=>y(),L=()=>_(),k=()=>y(),j=()=>_(),S=$=>{$.key==="Escape"&&f.getAttribute("aria-hidden")==="false"&&_()};e.addEventListener("mouseenter",x),e.addEventListener("mouseleave",L),e.addEventListener("focusin",k),e.addEventListener("focusout",j),e.addEventListener("keydown",S);let A=null;if(s&&d&&typeof d.$watch=="function"){let $=()=>{u&&m()&&E()};A=d.$watch($)}Bo(e,()=>{e.removeEventListener("mouseenter",x),e.removeEventListener("mouseleave",L),e.removeEventListener("focusin",k),e.removeEventListener("focusout",j),e.removeEventListener("keydown",S),A&&(A(),A=null),g(),ee.has(e)&&(clearTimeout(ee.get(e)),ee.delete(e)),u=!1,f.remove(),je.delete(e)})}})}function sr(t,e={}){ir(t)}function ar(){tr()}var Y=new Map;function cr(){Y.clear()}function Qe(){if(typeof document>"u"||document.querySelector("style[data-nojs-popover]"))return;let t=` +`.trim(),e=document.createElement("style");e.setAttribute("data-nojs-tooltip",""),e.textContent=t,document.head.appendChild(e)}function Xo(t,e){t.__disposers=t.__disposers||[],t.__disposers.push(e)}var tt=8;function ur(t,e,r){let o=e.getBoundingClientRect(),n=t.getBoundingClientRect(),i=window.innerWidth,c=window.innerHeight,s,a;switch(r){case"bottom":s=o.bottom+tt,a=o.left+(o.width-n.width)/2;break;case"left":s=o.top+(o.height-n.height)/2,a=o.left-n.width-tt;break;case"right":s=o.top+(o.height-n.height)/2,a=o.right+tt;break;default:s=o.top-n.height-tt,a=o.left+(o.width-n.width)/2;break}a<4&&(a=4),a+n.width>i-4&&(a=i-n.width-4),s<4&&(s=4),s+n.height>c-4&&(s=c-n.height-4),t.style.top=`${s}px`,t.style.left=`${a}px`}var Zo=0;function Qo(t,e,r){document.body.appendChild(e),ur(e,t,r),e.setAttribute("aria-hidden","false")}function lr(t,e){e.setAttribute("aria-hidden","true"),e.remove()}function Jo(t,e){t&&typeof t._warn=="function"?t._warn(e):console.warn(e)}function pr(t){t.directive("tooltip",{priority:20,init(e,r,o){dr();let n=o;if(!n){Jo(t,"[tooltip] attribute value (tooltip text) is required.");return}let i=e.getAttribute("tooltip-position")||"top",c=parseInt(e.getAttribute("tooltip-delay"),10),s=Number.isNaN(c)?300:c,a=e.getAttribute("tooltip-disabled"),d=a?t.findContext(e):null,g=()=>{if(!a||!d)return!1;try{return!!t.evaluate(a,d)}catch{return!1}},u=`nojs-tooltip-${++Zo}`,f=document.createElement("div");f.className="nojs-tooltip",f.setAttribute("role","tooltip"),f.setAttribute("id",u),f.setAttribute("aria-hidden","true"),f.textContent=n,e.setAttribute("aria-describedby",u),Ce.set(e,f);let p=!1,l=0,b=()=>{!p||!e.isConnected||l||(l=requestAnimationFrame(()=>{l=0,!(!p||!e.isConnected)&&ur(f,e,i)}))},h=()=>{window.addEventListener("scroll",b,!0),window.addEventListener("resize",b)},m=()=>{window.removeEventListener("scroll",b,!0),window.removeEventListener("resize",b),l&&(cancelAnimationFrame(l),l=0)},v=()=>{p||(Qo(e,f,i),p=!0,h())},y=()=>{if(!p){lr(e,f);return}m(),lr(e,f),p=!1},x=()=>{if(g())return;J.has(e)&&clearTimeout(J.get(e));let H=setTimeout(()=>{J.delete(e),!g()&&e.isConnected&&v()},s);J.set(e,H)},j=()=>{J.has(e)&&(clearTimeout(J.get(e)),J.delete(e)),y()},E=()=>x(),L=()=>j(),w=()=>x(),A=()=>j(),C=H=>{H.key==="Escape"&&f.getAttribute("aria-hidden")==="false"&&j()};e.addEventListener("mouseenter",E),e.addEventListener("mouseleave",L),e.addEventListener("focusin",w),e.addEventListener("focusout",A),e.addEventListener("keydown",C);let D=null;if(a&&d&&typeof d.$watch=="function"){let H=()=>{p&&g()&&y()};D=d.$watch(H)}Xo(e,()=>{e.removeEventListener("mouseenter",E),e.removeEventListener("mouseleave",L),e.removeEventListener("focusin",w),e.removeEventListener("focusout",A),e.removeEventListener("keydown",C),D&&(D(),D=null),m(),J.has(e)&&(clearTimeout(J.get(e)),J.delete(e)),p=!1,f.remove(),Ce.delete(e)})}})}function fr(t,e={}){pr(t)}function mr(){cr()}var Y=new Map;function gr(){Y.clear()}function rt(){if(typeof document>"u"||document.querySelector("style[data-nojs-popover]"))return;let t=` .nojs-popover { position: fixed; z-index: 9998; @@ -80,7 +80,7 @@ var mt=Object.defineProperty;var ho=Object.getOwnPropertyDescriptor;var vo=Objec .nojs-popover:popover-open { display: block; } -`.trim(),e=document.createElement("style");e.setAttribute("data-nojs-popover",""),e.textContent=t,document.head.appendChild(e)}function yt(t,e){t.__disposers=t.__disposers||[],t.__disposers.push(e)}function Le(t,e="togglePopover"){return!!t&&typeof t[e]=="function"}function Et(t){try{return t.matches(":popover-open")}catch{return!1}}var pe=8;function Je(t,e,r){let o=e.getBoundingClientRect(),n=t.getBoundingClientRect(),i=window.innerWidth,c=window.innerHeight,a,s;switch(r){case"top":a=o.top-n.height-pe,s=o.left+(o.width-n.width)/2;break;case"left":a=o.top+(o.height-n.height)/2,s=o.left-n.width-pe;break;case"right":a=o.top+(o.height-n.height)/2,s=o.right+pe;break;default:a=o.bottom+pe,s=o.left+(o.width-n.width)/2;break}r==="bottom"&&a+n.height>c&&(a=o.top-n.height-pe),r==="top"&&a<0&&(a=o.bottom+pe),r==="right"&&s+n.width>i&&(s=o.left-n.width-pe),r==="left"&&s<0&&(s=o.right+pe),s<4&&(s=4),s+n.width>i-4&&(s=i-n.width-4),a<4&&(a=4),a+n.height>c-4&&(a=c-n.height-4),t.style.top=`${a}px`,t.style.left=`${s}px`}function xt(t,e){t._untrack&&t._untrack();let r=0,o=()=>{r=0;let c=t.popoverEl;if(!c||!c.isConnected){i();return}if(!Et(c)){i();return}Je(c,e,t.position)},n=()=>{r||(r=requestAnimationFrame(o))},i=()=>{r&&(cancelAnimationFrame(r),r=0),window.removeEventListener("scroll",n,!0),window.removeEventListener("resize",n),t._untrack=null};return window.addEventListener("scroll",n,!0),window.addEventListener("resize",n),t._untrack=i,i}function xe(t){t&&t._untrack&&t._untrack()}function dr(t){t.directive("popover",{priority:20,init(r,o,n){Qe();let i=n||r.getAttribute("id")||`nojs-popover-${Date.now()}-${Math.random().toString(36).slice(2,7)}`;r.setAttribute("data-popover-id",i),r.id||(r.id=i),r.setAttribute("popover","auto"),r.getAttribute("role")||r.setAttribute("role","dialog"),r.classList.add("nojs-popover");let c=r.getAttribute("popover-position")||"bottom";if(!Y.has(i))Y.set(i,{popoverEl:r,triggerEls:new Set,position:c,open:!1,_untrack:null});else{let s=Y.get(i);s.popoverEl=r,s.position=c}let a=s=>{let d=Y.get(i);if(!d)return;let m=s.newState==="open";d.open=m;for(let l of d.triggerEls)l.setAttribute("aria-expanded",String(m));m||(r.style.visibility="",xe(d))};r.addEventListener("toggle",a),yt(r,()=>{r.removeEventListener("toggle",a);let s=Y.get(i);s&&(xe(s),s.popoverEl===r&&(s.popoverEl=null,s.open=!1),!s.popoverEl&&s.triggerEls.size===0&&Y.delete(i))})}}),t.directive("popover-trigger",{priority:20,init(r,o,n){Qe();let i=n;if(!i){let s=r.closest("[use]")||r.parentElement,d=s?.querySelector("[data-popover-id]")||s?.querySelector("[popover]");if(d&&(i=d.getAttribute("data-popover-id")||d.id),!i){console.warn("[popover-trigger] attribute value (popover ID) is required.");return}}r.setAttribute("aria-haspopup","dialog"),r.setAttribute("aria-expanded","false"),r.setAttribute("aria-controls",i),Y.has(i)||Y.set(i,{popoverEl:null,triggerEls:new Set,position:"bottom",open:!1,_untrack:null}),Y.get(i).triggerEls.add(r);let c=s=>{let d=Y.get(i);if(!d||!d.popoverEl){console.warn(`[popover-trigger] no popover found with id "${i}".`);return}if(Le(d.popoverEl)){d.popoverEl.style.visibility="hidden";try{d.popoverEl.togglePopover(),Et(d.popoverEl)?(Je(d.popoverEl,r,d.position),xt(d,r)):xe(d)}finally{d.popoverEl.style.visibility=""}}};r.addEventListener("click",c);let a=s=>{let d=Y.get(i);s.key==="Escape"&&d?.open&&(Le(d.popoverEl,"hidePopover")&&d.popoverEl.hidePopover(),xe(d),r.focus())};document.addEventListener("keydown",a),yt(r,()=>{r.removeEventListener("click",c),document.removeEventListener("keydown",a);let s=Y.get(i);s&&(s.triggerEls.delete(r),!s.popoverEl&&s.triggerEls.size===0&&(xe(s),Y.delete(i)))})}}),t.directive("popover-dismiss",{priority:20,init(r){Qe();let o=()=>{let n=r.closest(".nojs-popover");!n||!Le(n,"hidePopover")||n.hidePopover()};r.addEventListener("click",o),yt(r,()=>r.removeEventListener("click",o))}});let e=(r,o)=>e.open(r,o);e.open=(r,o)=>{let n=Y.get(r);if(!n||!n.popoverEl||!Le(n.popoverEl,"showPopover"))return!1;n.popoverEl.style.visibility="hidden";try{n.popoverEl.showPopover();let i=o||[...n.triggerEls][0];i&&(Je(n.popoverEl,i,n.position),xt(n,i))}catch{return!1}finally{n.popoverEl.style.visibility=""}return!0},e.close=r=>{let o=Y.get(r);if(!o||!o.popoverEl||!Le(o.popoverEl,"hidePopover"))return!1;try{o.popoverEl.hidePopover()}catch{}return xe(o),!0},e.toggle=(r,o)=>{let n=Y.get(r);if(!n||!n.popoverEl||!Le(n.popoverEl))return!1;n.popoverEl.style.visibility="hidden";try{n.popoverEl.togglePopover();let i=o||[...n.triggerEls][0];i&&Et(n.popoverEl)?(Je(n.popoverEl,i,n.position),xt(n,i)):xe(n)}finally{n.popoverEl.style.visibility=""}return!0},t.popover=e}function lr(t,e={}){dr(t)}function ur(){cr()}var U=[],se=new Map,Po=1e4;function pr(){return Po+U.length}function fr(){U.length=0,se.clear()}function ke(){if(typeof document>"u"||document.querySelector("style[data-nojs-modal]"))return;let t=` +`.trim(),e=document.createElement("style");e.setAttribute("data-nojs-popover",""),e.textContent=t,document.head.appendChild(e)}function At(t,e){t.__disposers=t.__disposers||[],t.__disposers.push(e)}function Se(t,e="togglePopover"){return!!t&&typeof t[e]=="function"}function jt(t){try{return t.matches(":popover-open")}catch{return!1}}var pe=8;function nt(t,e,r){let o=e.getBoundingClientRect(),n=t.getBoundingClientRect(),i=window.innerWidth,c=window.innerHeight,s,a;switch(r){case"top":s=o.top-n.height-pe,a=o.left+(o.width-n.width)/2;break;case"left":s=o.top+(o.height-n.height)/2,a=o.left-n.width-pe;break;case"right":s=o.top+(o.height-n.height)/2,a=o.right+pe;break;default:s=o.bottom+pe,a=o.left+(o.width-n.width)/2;break}r==="bottom"&&s+n.height>c&&(s=o.top-n.height-pe),r==="top"&&s<0&&(s=o.bottom+pe),r==="right"&&a+n.width>i&&(a=o.left-n.width-pe),r==="left"&&a<0&&(a=o.right+pe),a<4&&(a=4),a+n.width>i-4&&(a=i-n.width-4),s<4&&(s=4),s+n.height>c-4&&(s=c-n.height-4),t.style.top=`${s}px`,t.style.left=`${a}px`}function wt(t,e){t._untrack&&t._untrack();let r=0,o=()=>{r=0;let c=t.popoverEl;if(!c||!c.isConnected){i();return}if(!jt(c)){i();return}nt(c,e,t.position)},n=()=>{r||(r=requestAnimationFrame(o))},i=()=>{r&&(cancelAnimationFrame(r),r=0),window.removeEventListener("scroll",n,!0),window.removeEventListener("resize",n),t._untrack=null};return window.addEventListener("scroll",n,!0),window.addEventListener("resize",n),t._untrack=i,i}function _e(t){t&&t._untrack&&t._untrack()}function br(t){t.directive("popover",{priority:20,init(r,o,n){rt();let i=n||r.getAttribute("id")||`nojs-popover-${Date.now()}-${Math.random().toString(36).slice(2,7)}`;r.setAttribute("data-popover-id",i),r.id||(r.id=i),r.setAttribute("popover","auto"),r.getAttribute("role")||r.setAttribute("role","dialog"),r.classList.add("nojs-popover");let c=r.getAttribute("popover-position")||"bottom";if(!Y.has(i))Y.set(i,{popoverEl:r,triggerEls:new Set,position:c,open:!1,_untrack:null});else{let a=Y.get(i);a.popoverEl=r,a.position=c}let s=a=>{let d=Y.get(i);if(!d)return;let g=a.newState==="open";d.open=g;for(let u of d.triggerEls)u.setAttribute("aria-expanded",String(g));g||(r.style.visibility="",_e(d))};r.addEventListener("toggle",s),At(r,()=>{r.removeEventListener("toggle",s);let a=Y.get(i);a&&(_e(a),a.popoverEl===r&&(a.popoverEl=null,a.open=!1),!a.popoverEl&&a.triggerEls.size===0&&Y.delete(i))})}}),t.directive("popover-trigger",{priority:20,init(r,o,n){rt();let i=n;if(!i){let a=r.closest("[use]")||r.parentElement,d=a?.querySelector("[data-popover-id]")||a?.querySelector("[popover]");if(d&&(i=d.getAttribute("data-popover-id")||d.id),!i){console.warn("[popover-trigger] attribute value (popover ID) is required.");return}}r.setAttribute("aria-haspopup","dialog"),r.setAttribute("aria-expanded","false"),r.setAttribute("aria-controls",i),Y.has(i)||Y.set(i,{popoverEl:null,triggerEls:new Set,position:"bottom",open:!1,_untrack:null}),Y.get(i).triggerEls.add(r);let c=a=>{let d=Y.get(i);if(!d||!d.popoverEl){console.warn(`[popover-trigger] no popover found with id "${i}".`);return}if(Se(d.popoverEl)){d.popoverEl.style.visibility="hidden";try{d.popoverEl.togglePopover(),jt(d.popoverEl)?(nt(d.popoverEl,r,d.position),wt(d,r)):_e(d)}finally{d.popoverEl.style.visibility=""}}};r.addEventListener("click",c);let s=a=>{let d=Y.get(i);a.key==="Escape"&&d?.open&&(Se(d.popoverEl,"hidePopover")&&d.popoverEl.hidePopover(),_e(d),r.focus())};document.addEventListener("keydown",s),At(r,()=>{r.removeEventListener("click",c),document.removeEventListener("keydown",s);let a=Y.get(i);a&&(a.triggerEls.delete(r),!a.popoverEl&&a.triggerEls.size===0&&(_e(a),Y.delete(i)))})}}),t.directive("popover-dismiss",{priority:20,init(r){rt();let o=()=>{let n=r.closest(".nojs-popover");!n||!Se(n,"hidePopover")||n.hidePopover()};r.addEventListener("click",o),At(r,()=>r.removeEventListener("click",o))}});let e=(r,o)=>e.open(r,o);e.open=(r,o)=>{let n=Y.get(r);if(!n||!n.popoverEl||!Se(n.popoverEl,"showPopover"))return!1;n.popoverEl.style.visibility="hidden";try{n.popoverEl.showPopover();let i=o||[...n.triggerEls][0];i&&(nt(n.popoverEl,i,n.position),wt(n,i))}catch{return!1}finally{n.popoverEl.style.visibility=""}return!0},e.close=r=>{let o=Y.get(r);if(!o||!o.popoverEl||!Se(o.popoverEl,"hidePopover"))return!1;try{o.popoverEl.hidePopover()}catch{}return _e(o),!0},e.toggle=(r,o)=>{let n=Y.get(r);if(!n||!n.popoverEl||!Se(n.popoverEl))return!1;n.popoverEl.style.visibility="hidden";try{n.popoverEl.togglePopover();let i=o||[...n.triggerEls][0];i&&jt(n.popoverEl)?(nt(n.popoverEl,i,n.position),wt(n,i)):_e(n)}finally{n.popoverEl.style.visibility=""}return!0},t.popover=e}function hr(t,e={}){br(t)}function vr(){gr()}var N=[],ie=new Map,ei=1e4;function yr(){return ei+N.length}function xr(){N.length=0,ie.clear()}function De(){if(typeof document>"u"||document.querySelector("style[data-nojs-modal]"))return;let t=` .nojs-modal { position: fixed; inset: 0; @@ -108,7 +108,7 @@ var mt=Object.defineProperty;var ho=Object.getOwnPropertyDescriptor;var vo=Objec .nojs-modal[data-nojs-no-backdrop]::backdrop { background: transparent; } -`.trim(),e=document.createElement("style");e.setAttribute("data-nojs-modal",""),e.textContent=t,document.head.appendChild(e)}function Ro(t,e){t.__disposers=t.__disposers||[],t.__disposers.push(e)}var gr='a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])',_t=new WeakMap;function zo(t){let e=r=>{if(r.key!=="Tab")return;let o=[...t.querySelectorAll(gr)].filter(c=>c.offsetParent!==null);if(o.length===0){r.preventDefault();return}let n=o[0],i=o[o.length-1];r.shiftKey?document.activeElement===n&&(r.preventDefault(),i.focus()):document.activeElement===i&&(r.preventDefault(),n.focus())};t.addEventListener("keydown",e),_t.set(t,e)}function mr(t){let e=_t.get(t);e&&(t.removeEventListener("keydown",e),_t.delete(t))}var Me=new WeakMap;function br(t){t.directive("modal",{priority:10,init(r,o,n){ke();let i=n||`nojs-modal-${Date.now()}-${Math.random().toString(36).slice(2,7)}`;r.setAttribute("popover","manual"),r.classList.add("nojs-modal"),r.id=r.id||`nojs-modal-${i}`,r.setAttribute("data-modal-id",i),r.setAttribute("role","dialog"),r.setAttribute("aria-modal","true");let c=r.querySelector("h1, h2, h3, h4, h5, h6");c&&(c.id||(c.id=`nojs-modal-heading-${i}`),r.setAttribute("aria-labelledby",c.id));let a=r.getAttribute("modal-backdrop");a==="false"&&r.setAttribute("data-nojs-no-backdrop","");let s=r.getAttribute("modal-class"),d=r.getAttribute("modal-escape"),m=f=>{f.target===r&&a!=="false"&&d!=="false"&&Ce(r,i)};r.addEventListener("click",m),se.set(i,r);let l=f=>{if(f.newState==="open"){if(r.style.zIndex=String(pr()),s&&s.split(/\s+/).filter(Boolean).forEach(u=>r.classList.add(u)),requestAnimationFrame(()=>{if(!r.isConnected||!U.some(p=>p.el===r))return;let u=r.querySelector(gr);u?u.focus():r.focus()}),zo(r),d!=="false"){let u=p=>{p.key==="Escape"&&(p.stopPropagation(),Ce(r,i))};r.addEventListener("keydown",u),Me.set(r,u)}}else if(f.newState==="closed"){s&&s.split(/\s+/).filter(Boolean).forEach(v=>r.classList.remove(v)),mr(r);let u=Me.get(r);u&&(r.removeEventListener("keydown",u),Me.delete(r));let p=U.findIndex(v=>v.el===r);if(p===-1&&(p=U.findIndex(v=>v.id===i)),p!==-1){let v=U[p];U.splice(p,1),v.triggerEl&&requestAnimationFrame(()=>{v.triggerEl.focus()})}}};r.addEventListener("toggle",l),Ro(r,()=>{r.removeEventListener("click",m),r.removeEventListener("toggle",l),mr(r);let f=Me.get(r);f&&(r.removeEventListener("keydown",f),Me.delete(r)),se.delete(i);let u=U.findIndex(p=>p.el===r);u===-1&&(u=U.findIndex(p=>p.id===i)),u!==-1&&U.splice(u,1)})}});let e=r=>e.open(r);e.open=r=>{let o=se.get(r);if(!o)return!1;try{o.showPopover()}catch{return!1}return U.some(n=>n.id===r)||U.push({id:r,el:o,triggerEl:null}),!0},e.close=r=>{let o=se.get(r);return o?(Ce(o,r),!0):!1},e.closeAll=()=>{for(let r=U.length-1;r>=0;r--)Ce(U[r].el,U[r].id)},t.modal=e}function Ce(t,e){try{t.hidePopover()}catch{}}function hr(t,e){t.__disposers=t.__disposers||[],t.__disposers.push(e)}function Fo(t){let e=document.querySelectorAll("[data-modal-id]");for(let r of e)if(r.getAttribute("data-modal-id")===t)return r;return null}function vr(t){t.directive("modal-open",{priority:10,init(e,r,o){ke();let n=o;if(!n){let l=(e.closest("[use]")||e.parentElement)?.querySelector("[data-modal-id]");if(l&&(n=l.getAttribute("data-modal-id")),!n){console.warn('[modal-open] requires a target modal ID, e.g. modal-open="my-dialog"');return}}e.setAttribute("aria-haspopup","dialog"),e.setAttribute("aria-expanded","false");let i=()=>{let m=se.get(n)||Fo(n);if(!m){console.warn(`[modal-open] modal "${n}" not found`);return}let l=U.some(f=>f.id===n);m.id&&e.setAttribute("aria-controls",m.id);try{m.showPopover()}catch{console.warn(`[modal-open] failed to open modal "${n}"`);return}l||U.push({id:n,el:m,triggerEl:e}),e.setAttribute("aria-expanded","true")},c=()=>{e.setAttribute("aria-expanded","false")},a=null,s=null,d=()=>{let m=se.get(n);return m?(s=m,a=l=>{l.newState==="closed"&&e.setAttribute("aria-expanded","false")},m.addEventListener("toggle",a),!0):!1};if(!d()){let m=requestAnimationFrame(d);hr(e,()=>cancelAnimationFrame(m))}e.addEventListener("click",i),hr(e,()=>{e.removeEventListener("click",i),s&&a&&s.removeEventListener("toggle",a)})}})}function Oo(t,e){t.__disposers=t.__disposers||[],t.__disposers.push(e)}function yr(t){t.directive("modal-close",{priority:10,init(e,r,o){ke();let n=()=>{let i,c;if(o){if(c=o,i=se.get(c),!i){console.warn(`[modal-close] modal "${c}" not found`);return}}else{if(i=e.closest("[modal]"),!i){console.warn("[modal-close] no parent modal found");return}c=i.getAttribute("modal")}Ce(i,c)};e.addEventListener("click",n),Oo(e,()=>{e.removeEventListener("click",n)})}})}function xr(t,e={}){br(t),vr(t),yr(t)}function Er(){fr()}var te={openMenus:new Map},O={installed:!1,instanceCount:0,outsideClickHandler:null,escHandler:null};function _r(){te.openMenus.clear(),O.installed=!1,O.instanceCount=0,O.outsideClickHandler=null,O.escHandler=null}function Se(){if(typeof document>"u"||document.querySelector("style[data-nojs-dropdown]"))return;let t=` +`.trim(),e=document.createElement("style");e.setAttribute("data-nojs-modal",""),e.textContent=t,document.head.appendChild(e)}function ti(t,e){t.__disposers=t.__disposers||[],t.__disposers.push(e)}var _r='a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])',Lt=new WeakMap;function ri(t){let e=r=>{if(r.key!=="Tab")return;let o=[...t.querySelectorAll(_r)].filter(c=>c.offsetParent!==null);if(o.length===0){r.preventDefault();return}let n=o[0],i=o[o.length-1];r.shiftKey?document.activeElement===n&&(r.preventDefault(),i.focus()):document.activeElement===i&&(r.preventDefault(),n.focus())};t.addEventListener("keydown",e),Lt.set(t,e)}function Er(t){let e=Lt.get(t);e&&(t.removeEventListener("keydown",e),Lt.delete(t))}var Fe=new WeakMap;function Ar(t){t.directive("modal",{priority:10,init(r,o,n){De();let i=n||`nojs-modal-${Date.now()}-${Math.random().toString(36).slice(2,7)}`;r.setAttribute("popover","manual"),r.classList.add("nojs-modal"),r.id=r.id||`nojs-modal-${i}`,r.setAttribute("data-modal-id",i),r.setAttribute("role","dialog"),r.setAttribute("aria-modal","true");let c=r.querySelector("h1, h2, h3, h4, h5, h6");c&&(c.id||(c.id=`nojs-modal-heading-${i}`),r.setAttribute("aria-labelledby",c.id));let s=r.getAttribute("modal-backdrop");s==="false"&&r.setAttribute("data-nojs-no-backdrop","");let a=r.getAttribute("modal-class"),d=r.getAttribute("modal-escape"),g=f=>{f.target===r&&s!=="false"&&d!=="false"&&Te(r,i)};r.addEventListener("click",g),ie.set(i,r);let u=f=>{if(f.newState==="open"){if(r.style.zIndex=String(yr()),a&&a.split(/\s+/).filter(Boolean).forEach(p=>r.classList.add(p)),requestAnimationFrame(()=>{if(!r.isConnected||!N.some(l=>l.el===r))return;let p=r.querySelector(_r);p?p.focus():r.focus()}),ri(r),d!=="false"){let p=l=>{l.key==="Escape"&&(l.stopPropagation(),Te(r,i))};r.addEventListener("keydown",p),Fe.set(r,p)}}else if(f.newState==="closed"){a&&a.split(/\s+/).filter(Boolean).forEach(b=>r.classList.remove(b)),Er(r);let p=Fe.get(r);p&&(r.removeEventListener("keydown",p),Fe.delete(r));let l=N.findIndex(b=>b.el===r);if(l===-1&&(l=N.findIndex(b=>b.id===i)),l!==-1){let b=N[l];N.splice(l,1),b.triggerEl&&requestAnimationFrame(()=>{b.triggerEl.focus()})}}};r.addEventListener("toggle",u),ti(r,()=>{r.removeEventListener("click",g),r.removeEventListener("toggle",u),Er(r);let f=Fe.get(r);f&&(r.removeEventListener("keydown",f),Fe.delete(r)),ie.delete(i);let p=N.findIndex(l=>l.el===r);p===-1&&(p=N.findIndex(l=>l.id===i)),p!==-1&&N.splice(p,1)})}});let e=r=>e.open(r);e.open=r=>{let o=ie.get(r);if(!o)return!1;try{o.showPopover()}catch{return!1}return N.some(n=>n.id===r)||N.push({id:r,el:o,triggerEl:null}),!0},e.close=r=>{let o=ie.get(r);return o?(Te(o,r),!0):!1},e.closeAll=()=>{for(let r=N.length-1;r>=0;r--)Te(N[r].el,N[r].id)},t.modal=e}function Te(t,e){try{t.hidePopover()}catch{}}function wr(t,e){t.__disposers=t.__disposers||[],t.__disposers.push(e)}function ni(t){let e=document.querySelectorAll("[data-modal-id]");for(let r of e)if(r.getAttribute("data-modal-id")===t)return r;return null}function jr(t){t.directive("modal-open",{priority:10,init(e,r,o){De();let n=o;if(!n){let u=(e.closest("[use]")||e.parentElement)?.querySelector("[data-modal-id]");if(u&&(n=u.getAttribute("data-modal-id")),!n){console.warn('[modal-open] requires a target modal ID, e.g. modal-open="my-dialog"');return}}e.setAttribute("aria-haspopup","dialog"),e.setAttribute("aria-expanded","false");let i=()=>{let g=ie.get(n)||ni(n);if(!g){console.warn(`[modal-open] modal "${n}" not found`);return}let u=N.some(f=>f.id===n);g.id&&e.setAttribute("aria-controls",g.id);try{g.showPopover()}catch{console.warn(`[modal-open] failed to open modal "${n}"`);return}u||N.push({id:n,el:g,triggerEl:e}),e.setAttribute("aria-expanded","true")},c=()=>{e.setAttribute("aria-expanded","false")},s=null,a=null,d=()=>{let g=ie.get(n);return g?(a=g,s=u=>{u.newState==="closed"&&e.setAttribute("aria-expanded","false")},g.addEventListener("toggle",s),!0):!1};if(!d()){let g=requestAnimationFrame(d);wr(e,()=>cancelAnimationFrame(g))}e.addEventListener("click",i),wr(e,()=>{e.removeEventListener("click",i),a&&s&&a.removeEventListener("toggle",s)})}})}function oi(t,e){t.__disposers=t.__disposers||[],t.__disposers.push(e)}function Lr(t){t.directive("modal-close",{priority:10,init(e,r,o){De();let n=()=>{let i,c;if(o){if(c=o,i=ie.get(c),!i){console.warn(`[modal-close] modal "${c}" not found`);return}}else{if(i=e.closest("[modal]"),!i){console.warn("[modal-close] no parent modal found");return}c=i.getAttribute("modal")}Te(i,c)};e.addEventListener("click",n),oi(e,()=>{e.removeEventListener("click",n)})}})}function kr(t,e={}){Ar(t),jr(t),Lr(t)}function Cr(){xr()}var ne={openMenus:new Map},O={installed:!1,instanceCount:0,outsideClickHandler:null,escHandler:null};function Sr(){ne.openMenus.clear(),O.installed=!1,O.instanceCount=0,O.outsideClickHandler=null,O.escHandler=null}function Ie(){if(typeof document>"u"||document.querySelector("style[data-nojs-dropdown]"))return;let t=` .nojs-dropdown-menu { position: fixed; z-index: 9999; @@ -153,7 +153,7 @@ var mt=Object.defineProperty;var ho=Object.getOwnPropertyDescriptor;var vo=Objec outline: 2px solid #0EA5E9; outline-offset: -2px; } -`.trim(),e=document.createElement("style");e.setAttribute("data-nojs-dropdown",""),e.textContent=t,document.head.appendChild(e)}var Vo=0;function No(t,e){t.__disposers=t.__disposers||[],t.__disposers.push(e)}function Wo(){O.installed||(O.outsideClickHandler=t=>{let e=[...te.openMenus.entries()];for(let[r,{toggle:o,wrapper:n}]of e)if(!n.contains(t.target)){if(r.removeAttribute("data-open"),o.setAttribute("aria-expanded","false"),typeof r.hidePopover=="function")try{r.hidePopover()}catch{}te.openMenus.delete(r)}},O.escHandler=t=>{if(t.key!=="Escape")return;let e=[...te.openMenus.entries()];for(let[r,{toggle:o}]of e){if(r.removeAttribute("data-open"),o.setAttribute("aria-expanded","false"),typeof r.hidePopover=="function")try{r.hidePopover()}catch{}o.focus()}te.openMenus.clear()},document.addEventListener("click",O.outsideClickHandler,!0),document.addEventListener("keydown",O.escHandler),O.installed=!0)}function At(){O.installed&&(document.removeEventListener("click",O.outsideClickHandler,!0),document.removeEventListener("keydown",O.escHandler),O.outsideClickHandler=null,O.escHandler=null,O.installed=!1)}function wr(t,e,r){let o=r.getAttribute("dropdown-position")||"bottom",n=r.getAttribute("dropdown-align")||"start";t.style.top="",t.style.left="";let i=e.getBoundingClientRect(),c=t.getBoundingClientRect(),a=window.innerHeight,s=window.innerWidth,d,m;switch(o){case"top":d=i.top-c.height,m=i.left;break;case"left":d=i.top,m=i.left-c.width;break;case"right":d=i.top,m=i.right;break;default:d=i.bottom,m=i.left}o==="bottom"||o==="top"?n==="end"&&(m=i.right-c.width):n==="end"&&(d=i.bottom-c.height),o==="bottom"&&d+c.height>a&&i.top-c.height>0?d=i.top-c.height:o==="top"&&d<0&&i.bottom+c.height<=a&&(d=i.bottom),m<4&&(m=4),m+c.width>s-4&&(m=s-c.width-4),t.style.top=`${d}px`,t.style.left=`${m}px`}function jt(t){return[...t.querySelectorAll("[dropdown-item]")].filter(e=>!e.hasAttribute("disabled")&&e.getAttribute("aria-disabled")!=="true")}function wt(t){let e=jt(t);e.length&&e[0].focus()}function Ar(t){let e=jt(t);e.length&&e[e.length-1].focus()}function jr(t){t.directive("dropdown",{priority:15,init(r){Se()}}),t.directive("dropdown-toggle",{priority:15,init(r){Se();let o=r.closest("[dropdown]");if(!o)return;let n=o.querySelector("[dropdown-menu]");if(!n)return;r.setAttribute("aria-haspopup","menu"),r.setAttribute("aria-expanded","false"),n.classList.add("nojs-dropdown-menu"),n.setAttribute("role","menu"),n.setAttribute("popover","auto"),n.id||(n.id=`nojs-dd-menu-${Date.now()}-${Vo++}`),r.setAttribute("aria-controls",n.id);let i=!1,c=typeof n.showPopover=="function"&&typeof n.hidePopover=="function";function a(){if(n.setAttribute("data-open",""),c&&!i)try{n.showPopover(),i=!0}catch{i=!1}r.setAttribute("aria-expanded","true"),wr(n,r,o),te.openMenus.set(n,{toggle:r,wrapper:o})}function s(){if(c&&i){i=!1;try{n.hidePopover()}catch{}}n.removeAttribute("data-open"),r.setAttribute("aria-expanded","false"),te.openMenus.delete(n)}function d(){return r.getAttribute("aria-expanded")==="true"}let m=v=>{v.newState==="closed"&&d()&&s()};n.addEventListener("toggle",m);let l=v=>{v.preventDefault(),v.stopPropagation(),d()?s():a()};r.addEventListener("click",l),O.instanceCount++,Wo();let f=v=>{switch(v.key){case"Enter":case" ":v.preventDefault(),a(),wt(n);break;case"ArrowDown":v.preventDefault(),a(),wt(n);break;case"ArrowUp":v.preventDefault(),a(),Ar(n);break}};r.addEventListener("keydown",f);let u=v=>{if(!(!d()||jt(n).find(b=>b===document.activeElement)))switch(v.key){case"ArrowDown":v.preventDefault(),wt(n);break;case"ArrowUp":v.preventDefault(),Ar(n);break}};n.addEventListener("keydown",u);let p=()=>{d()&&wr(n,r,o)};window.addEventListener("scroll",p,!0),window.addEventListener("resize",p),No(r,()=>{r.removeEventListener("click",l),r.removeEventListener("keydown",f),n.removeEventListener("keydown",u),n.removeEventListener("toggle",m),window.removeEventListener("scroll",p,!0),window.removeEventListener("resize",p),te.openMenus.delete(n),O.instanceCount--,O.instanceCount<=0&&(O.instanceCount=0,At())})}}),t.directive("dropdown-menu",{priority:15,init(r){Se(),r.hasAttribute("role")||r.setAttribute("role","menu")}});let e=r=>e.open(r);e.open=r=>{let o=document.getElementById(r);if(!o)return!1;let i=o.closest("[dropdown]")?.querySelector("[dropdown-toggle]");return!i||i.getAttribute("aria-expanded")==="true"?!1:(i.click(),!0)},e.close=r=>{let o=document.getElementById(r);if(!o)return!1;let i=o.closest("[dropdown]")?.querySelector("[dropdown-toggle]");return!i||i.getAttribute("aria-expanded")!=="true"?!1:(i.click(),!0)},t.dropdown=e}function Lr(t,e){t.__disposers=t.__disposers||[],t.__disposers.push(e)}function Uo(t){return[...t.querySelectorAll("[dropdown-item]")].filter(e=>!e.hasAttribute("disabled")&&e.getAttribute("aria-disabled")!=="true")}function Lt(t,e){if(!t)return;if(typeof t.hidePopover=="function")try{t.hidePopover()}catch{}t.removeAttribute("data-open");let r=e&&e.querySelector("[dropdown-toggle]");r&&r.setAttribute("aria-expanded","false"),te.openMenus.has(t)&&te.openMenus.delete(t)}function kr(t){t.directive("dropdown-item",{priority:15,init(e){Se();let r=e.closest("[dropdown-menu]"),o=e.closest("[dropdown]");e.setAttribute("role","menuitem"),e.setAttribute("tabindex","-1"),e.classList.add("nojs-dropdown-item"),e.hasAttribute("disabled")&&e.setAttribute("aria-disabled","true");let n=c=>{if(!r)return;let a=Uo(r),s=a.indexOf(e);switch(c.key){case"ArrowDown":{c.preventDefault(),(s+1 =0?a[s-1]:a[a.length-1]).focus();break}case"Home":{c.preventDefault(),a.length&&a[0].focus();break}case"End":{c.preventDefault(),a.length&&a[a.length-1].focus();break}case"Enter":{c.preventDefault(),e.click();break}case"Escape":{if(c.preventDefault(),Lt(r,o),o){let d=o.querySelector("[dropdown-toggle]");d&&d.focus()}break}case"Tab":{Lt(r,o);break}}};e.addEventListener("keydown",n),Lr(e,()=>e.removeEventListener("keydown",n));let i=()=>{if(Lt(r,o),o){let c=o.querySelector("[dropdown-toggle]");c&&c.focus()}};e.addEventListener("click",i),Lr(e,()=>e.removeEventListener("click",i))}})}function Cr(t,e={}){jr(t),kr(t)}function Sr(){At(),_r()}var ae=new Map,Te=new Set,Tr=0;function Dr(){return++Tr}function Ir(){for(let t of Te)clearTimeout(t);Te.clear();for(let t of ae.values())t.remove();ae.clear(),Tr=0}function Hr(){if(typeof document>"u"||document.querySelector("style[data-nojs-toast]"))return;let t=` +`.trim(),e=document.createElement("style");e.setAttribute("data-nojs-dropdown",""),e.textContent=t,document.head.appendChild(e)}var ii=0;function si(t,e){t.__disposers=t.__disposers||[],t.__disposers.push(e)}function ai(){O.installed||(O.outsideClickHandler=t=>{let e=[...ne.openMenus.entries()];for(let[r,{toggle:o,wrapper:n}]of e)if(!n.contains(t.target)){if(r.removeAttribute("data-open"),o.setAttribute("aria-expanded","false"),typeof r.hidePopover=="function")try{r.hidePopover()}catch{}ne.openMenus.delete(r)}},O.escHandler=t=>{if(t.key!=="Escape")return;let e=[...ne.openMenus.entries()];for(let[r,{toggle:o}]of e){if(r.removeAttribute("data-open"),o.setAttribute("aria-expanded","false"),typeof r.hidePopover=="function")try{r.hidePopover()}catch{}o.focus()}ne.openMenus.clear()},document.addEventListener("click",O.outsideClickHandler,!0),document.addEventListener("keydown",O.escHandler),O.installed=!0)}function Ct(){O.installed&&(document.removeEventListener("click",O.outsideClickHandler,!0),document.removeEventListener("keydown",O.escHandler),O.outsideClickHandler=null,O.escHandler=null,O.installed=!1)}function Dr(t,e,r){let o=r.getAttribute("dropdown-position")||"bottom",n=r.getAttribute("dropdown-align")||"start";t.style.top="",t.style.left="";let i=e.getBoundingClientRect(),c=t.getBoundingClientRect(),s=window.innerHeight,a=window.innerWidth,d,g;switch(o){case"top":d=i.top-c.height,g=i.left;break;case"left":d=i.top,g=i.left-c.width;break;case"right":d=i.top,g=i.right;break;default:d=i.bottom,g=i.left}o==="bottom"||o==="top"?n==="end"&&(g=i.right-c.width):n==="end"&&(d=i.bottom-c.height),o==="bottom"&&d+c.height>s&&i.top-c.height>0?d=i.top-c.height:o==="top"&&d<0&&i.bottom+c.height<=s&&(d=i.bottom),g<4&&(g=4),g+c.width>a-4&&(g=a-c.width-4),t.style.top=`${d}px`,t.style.left=`${g}px`}function St(t){return[...t.querySelectorAll("[dropdown-item]")].filter(e=>!e.hasAttribute("disabled")&&e.getAttribute("aria-disabled")!=="true")}function kt(t){let e=St(t);e.length&&e[0].focus()}function Tr(t){let e=St(t);e.length&&e[e.length-1].focus()}function Ir(t){t.directive("dropdown",{priority:15,init(r){Ie()}}),t.directive("dropdown-toggle",{priority:15,init(r){Ie();let o=r.closest("[dropdown]");if(!o)return;let n=o.querySelector("[dropdown-menu]");if(!n)return;r.setAttribute("aria-haspopup","menu"),r.setAttribute("aria-expanded","false"),n.classList.add("nojs-dropdown-menu"),n.setAttribute("role","menu"),n.setAttribute("popover","auto"),n.id||(n.id=`nojs-dd-menu-${Date.now()}-${ii++}`),r.setAttribute("aria-controls",n.id);let i=!1,c=typeof n.showPopover=="function"&&typeof n.hidePopover=="function";function s(){if(n.setAttribute("data-open",""),c&&!i)try{n.showPopover(),i=!0}catch{i=!1}r.setAttribute("aria-expanded","true"),Dr(n,r,o),ne.openMenus.set(n,{toggle:r,wrapper:o})}function a(){if(c&&i){i=!1;try{n.hidePopover()}catch{}}n.removeAttribute("data-open"),r.setAttribute("aria-expanded","false"),ne.openMenus.delete(n)}function d(){return r.getAttribute("aria-expanded")==="true"}let g=b=>{b.newState==="closed"&&d()&&a()};n.addEventListener("toggle",g);let u=b=>{b.preventDefault(),b.stopPropagation(),d()?a():s()};r.addEventListener("click",u),O.instanceCount++,ai();let f=b=>{switch(b.key){case"Enter":case" ":b.preventDefault(),s(),kt(n);break;case"ArrowDown":b.preventDefault(),s(),kt(n);break;case"ArrowUp":b.preventDefault(),s(),Tr(n);break}};r.addEventListener("keydown",f);let p=b=>{if(!(!d()||St(n).find(v=>v===document.activeElement)))switch(b.key){case"ArrowDown":b.preventDefault(),kt(n);break;case"ArrowUp":b.preventDefault(),Tr(n);break}};n.addEventListener("keydown",p);let l=()=>{d()&&Dr(n,r,o)};window.addEventListener("scroll",l,!0),window.addEventListener("resize",l),si(r,()=>{r.removeEventListener("click",u),r.removeEventListener("keydown",f),n.removeEventListener("keydown",p),n.removeEventListener("toggle",g),window.removeEventListener("scroll",l,!0),window.removeEventListener("resize",l),ne.openMenus.delete(n),O.instanceCount--,O.instanceCount<=0&&(O.instanceCount=0,Ct())})}}),t.directive("dropdown-menu",{priority:15,init(r){Ie(),r.hasAttribute("role")||r.setAttribute("role","menu")}});let e=r=>e.open(r);e.open=r=>{let o=document.getElementById(r);if(!o)return!1;let i=o.closest("[dropdown]")?.querySelector("[dropdown-toggle]");return!i||i.getAttribute("aria-expanded")==="true"?!1:(i.click(),!0)},e.close=r=>{let o=document.getElementById(r);if(!o)return!1;let i=o.closest("[dropdown]")?.querySelector("[dropdown-toggle]");return!i||i.getAttribute("aria-expanded")!=="true"?!1:(i.click(),!0)},t.dropdown=e}function Br(t,e){t.__disposers=t.__disposers||[],t.__disposers.push(e)}function ci(t){return[...t.querySelectorAll("[dropdown-item]")].filter(e=>!e.hasAttribute("disabled")&&e.getAttribute("aria-disabled")!=="true")}function Dt(t,e){if(!t)return;if(typeof t.hidePopover=="function")try{t.hidePopover()}catch{}t.removeAttribute("data-open");let r=e&&e.querySelector("[dropdown-toggle]");r&&r.setAttribute("aria-expanded","false"),ne.openMenus.has(t)&&ne.openMenus.delete(t)}function Hr(t){t.directive("dropdown-item",{priority:15,init(e){Ie();let r=e.closest("[dropdown-menu]"),o=e.closest("[dropdown]");e.setAttribute("role","menuitem"),e.setAttribute("tabindex","-1"),e.classList.add("nojs-dropdown-item"),e.hasAttribute("disabled")&&e.setAttribute("aria-disabled","true");let n=c=>{if(!r)return;let s=ci(r),a=s.indexOf(e);switch(c.key){case"ArrowDown":{c.preventDefault(),(a+1 =0?s[a-1]:s[s.length-1]).focus();break}case"Home":{c.preventDefault(),s.length&&s[0].focus();break}case"End":{c.preventDefault(),s.length&&s[s.length-1].focus();break}case"Enter":{c.preventDefault(),e.click();break}case"Escape":{if(c.preventDefault(),Dt(r,o),o){let d=o.querySelector("[dropdown-toggle]");d&&d.focus()}break}case"Tab":{Dt(r,o);break}}};e.addEventListener("keydown",n),Br(e,()=>e.removeEventListener("keydown",n));let i=()=>{if(Dt(r,o),o){let c=o.querySelector("[dropdown-toggle]");c&&c.focus()}};e.addEventListener("click",i),Br(e,()=>e.removeEventListener("click",i))}})}function $r(t,e={}){Ir(t),Hr(t)}function qr(){Ct(),Sr()}var se=new Map,Be=new Set,Mr=0;function Pr(){return++Mr}function Rr(){for(let t of Be)clearTimeout(t);Be.clear();for(let t of se.values())t.remove();se.clear(),Mr=0}function zr(){if(typeof document>"u"||document.querySelector("style[data-nojs-toast]"))return;let t=` .nojs-toast-container { position: fixed; z-index: 10001; @@ -208,7 +208,7 @@ var mt=Object.defineProperty;var ho=Object.getOwnPropertyDescriptor;var vo=Objec from { opacity: 0; transform: translateY(-0.5rem); } to { opacity: 1; transform: translateY(0); } } -`.trim(),e=document.createElement("style");e.setAttribute("data-nojs-toast",""),e.textContent=t,document.head.appendChild(e)}function kt(t,e){t.__disposers=t.__disposers||[],t.__disposers.push(e)}var Go=new Set(["top-right","top-left","bottom-right","bottom-left","top-center","bottom-center"]);function Ct(){return ae.size>0?ae.values().next().value:Yo("top-right")}function Yo(t){if(ae.has(t))return ae.get(t);let e=document.createElement("div");return e.classList.add("nojs-toast-container"),e.setAttribute("data-position",t),e.setAttribute("role","log"),e.setAttribute("aria-live","polite"),e.setAttribute("aria-relevant","additions"),document.body.appendChild(e),ae.set(t,e),e}function Ko(t){return t.startsWith("top")}function St(t,e,r,o,n){let i=Dr(),c=t.getAttribute("data-position")||"top-right",a=document.createElement("div");a.classList.add("nojs-toast"),a.setAttribute("data-toast-id",i),a.setAttribute("data-type",r),r==="error"&&a.setAttribute("aria-live","assertive");let s=document.createElement("span");if(s.textContent=e,a.appendChild(s),n){let d=document.createElement("button");d.type="button",d.classList.add("nojs-toast-dismiss"),d.setAttribute("aria-label","Dismiss"),d.textContent="\xD7",d.addEventListener("click",()=>et(a)),a.appendChild(d)}if(Ko(c)&&t.firstChild?t.insertBefore(a,t.firstChild):t.appendChild(a),o>0){let d=setTimeout(()=>{Te.delete(d),a.isConnected&&et(a)},o);Te.add(d),a._toastTimerId=d}return a}function et(t){!t||!t.isConnected||(t._toastTimerId!=null&&(clearTimeout(t._toastTimerId),Te.delete(t._toastTimerId)),t.remove())}function Br(t){Hr(),t.directive("toast-container",{priority:10,init(r,o,n){let i=n&&Go.has(n)?n:"top-right";r.classList.add("nojs-toast-container"),r.setAttribute("data-position",i),r.setAttribute("role","log"),r.setAttribute("aria-live","polite"),r.setAttribute("aria-relevant","additions"),ae.set(i,r),kt(r,()=>{ae.get(i)===r&&ae.delete(i)})}}),t.directive("toast",{priority:10,init(r,o,n){if(!n)return;let i=r.getAttribute("toast-type")||"info",c=parseInt(r.getAttribute("toast-duration"),10),a=Number.isNaN(c)?3e3:c,s=r.getAttribute("toast-dismiss")!=="false";if(r.tagName==="BUTTON"||r.tagName==="A"||r.hasAttribute("on:click")){let p=()=>{let v=Ct();St(v,n,i,a,s)};r.addEventListener("click",p),kt(r,()=>r.removeEventListener("click",p));return}let m=t.findContext(r);if(!m||typeof m.$watch!="function"){console.warn("[toast] reactive toast requires a parent [state] or [use] context \u2014 element will be inert");return}let l;function f(){let p=t.evaluate(n,m);if(p&&p!==l){let v=typeof p=="string"?p:String(p),h=Ct();St(h,v,i,a,s),l=p}else l=p}let u=m.$watch(f);kt(r,u)}});let e=(r,o="info",n=3e3)=>{if(typeof document>"u")return;let i=!0,c=Ct();return St(c,String(r),o,n,i)};e.dismiss=r=>{let o=typeof CSS<"u"&&CSS.escape?CSS.escape(String(r)):String(r).replace(/["\\\]]/g,"\\$&"),n=document.querySelector(`[data-toast-id="${o}"]`);n&&et(n)},e.dismissAll=()=>{document.querySelectorAll(".nojs-toast").forEach(r=>et(r))},t.toast=e,t.global("toast",e)}function $r(t,e={}){Br(t)}function qr(){Ir()}var Ee={containers:new Map};function Mr(){Ee.containers.clear()}function Pr(){if(typeof document>"u"||document.querySelector("style[data-nojs-tabs]"))return;let t=` +`.trim(),e=document.createElement("style");e.setAttribute("data-nojs-toast",""),e.textContent=t,document.head.appendChild(e)}function Tt(t,e){t.__disposers=t.__disposers||[],t.__disposers.push(e)}var di=new Set(["top-right","top-left","bottom-right","bottom-left","top-center","bottom-center"]);function It(){return se.size>0?se.values().next().value:li("top-right")}function li(t){if(se.has(t))return se.get(t);let e=document.createElement("div");return e.classList.add("nojs-toast-container"),e.setAttribute("data-position",t),e.setAttribute("role","log"),e.setAttribute("aria-live","polite"),e.setAttribute("aria-relevant","additions"),document.body.appendChild(e),se.set(t,e),e}function ui(t){return t.startsWith("top")}function Bt(t,e,r,o,n){let i=Pr(),c=t.getAttribute("data-position")||"top-right",s=document.createElement("div");s.classList.add("nojs-toast"),s.setAttribute("data-toast-id",i),s.setAttribute("data-type",r),r==="error"&&s.setAttribute("aria-live","assertive");let a=document.createElement("span");if(a.textContent=e,s.appendChild(a),n){let d=document.createElement("button");d.type="button",d.classList.add("nojs-toast-dismiss"),d.setAttribute("aria-label","Dismiss"),d.textContent="\xD7",d.addEventListener("click",()=>ot(s)),s.appendChild(d)}if(ui(c)&&t.firstChild?t.insertBefore(s,t.firstChild):t.appendChild(s),o>0){let d=setTimeout(()=>{Be.delete(d),s.isConnected&&ot(s)},o);Be.add(d),s._toastTimerId=d}return s}function ot(t){!t||!t.isConnected||(t._toastTimerId!=null&&(clearTimeout(t._toastTimerId),Be.delete(t._toastTimerId)),t.remove())}function Fr(t){zr(),t.directive("toast-container",{priority:10,init(r,o,n){let i=n&&di.has(n)?n:"top-right";r.classList.add("nojs-toast-container"),r.setAttribute("data-position",i),r.setAttribute("role","log"),r.setAttribute("aria-live","polite"),r.setAttribute("aria-relevant","additions"),se.set(i,r),Tt(r,()=>{se.get(i)===r&&se.delete(i)})}}),t.directive("toast",{priority:10,init(r,o,n){if(!n)return;let i=r.getAttribute("toast-type")||"info",c=parseInt(r.getAttribute("toast-duration"),10),s=Number.isNaN(c)?3e3:c,a=r.getAttribute("toast-dismiss")!=="false";if(r.tagName==="BUTTON"||r.tagName==="A"||r.hasAttribute("on:click")){let l=()=>{let b=It();Bt(b,n,i,s,a)};r.addEventListener("click",l),Tt(r,()=>r.removeEventListener("click",l));return}let g=t.findContext(r);if(!g||typeof g.$watch!="function"){console.warn("[toast] reactive toast requires a parent [state] or [use] context \u2014 element will be inert");return}let u;function f(){let l=t.evaluate(n,g);if(l&&l!==u){let b=typeof l=="string"?l:String(l),h=It();Bt(h,b,i,s,a),u=l}else u=l}let p=g.$watch(f);Tt(r,p)}});let e=(r,o="info",n=3e3)=>{if(typeof document>"u")return;let i=!0,c=It();return Bt(c,String(r),o,n,i)};e.dismiss=r=>{let o=typeof CSS<"u"&&CSS.escape?CSS.escape(String(r)):String(r).replace(/["\\\]]/g,"\\$&"),n=document.querySelector(`[data-toast-id="${o}"]`);n&&ot(n)},e.dismissAll=()=>{document.querySelectorAll(".nojs-toast").forEach(r=>ot(r))},t.toast=e,t.global("toast",e)}function Or(t,e={}){Fr(t)}function Vr(){Rr()}var Ae={containers:new Map};function Wr(){Ae.containers.clear()}function Nr(){if(typeof document>"u"||document.querySelector("style[data-nojs-tabs]"))return;let t=` .nojs-tabs { display: flex; flex-direction: column; @@ -292,7 +292,7 @@ var mt=Object.defineProperty;var ho=Object.getOwnPropertyDescriptor;var vo=Objec .nojs-panel[aria-hidden="true"] { display: none; } -`.trim(),e=document.createElement("style");e.setAttribute("data-nojs-tabs",""),e.textContent=t,document.head.appendChild(e)}function Xo(t,e){t.__disposers=t.__disposers||[],t.__disposers.push(e)}var Zo=0;function Rr(t){return`${t}-${++Zo}`}function Pe(t,e,r=!1){let o=Ee.containers.get(t);if(!o)return;let{tabs:n,panels:i}=o;if(!(e<0||e>=n.length)&&!(!r&&n[e].getAttribute("aria-disabled")==="true")){for(let c=0;c {let E=!1;try{E=!!t.evaluate(b,m)}catch{E=!1}E?g.setAttribute("aria-disabled","true"):g.removeAttribute("aria-disabled")};for(let g=0;g f(b,E));l.push(y)}}let u=0;if(o&&o.trim()!==""){let g=parseInt(o,10);!isNaN(g)&&g>=0&&g{let b=Ee.containers.get(e);if(!b)return;let E=g.target;if(E.getAttribute("role")!=="tab")return;let{tabs:y}=b,_=y.indexOf(E);if(_===-1)return;let x=-1;switch(g.key){case"ArrowRight":case"ArrowDown":x=Re(y,_,1);break;case"ArrowLeft":case"ArrowUp":x=Re(y,_,-1);break;case"Home":x=Re(y,y.length-1,1);break;case"End":x=Re(y,0,-1);break;case"Tab":return;default:return}x!==-1&&x!==_&&(g.preventDefault(),Pe(e,x),y[x].focus())};a.addEventListener("keydown",v);let h=g=>{let b=g.target.closest("[role='tab']");if(!b)return;let E=Ee.containers.get(e);if(!E)return;let y=E.tabs.indexOf(b);y!==-1&&b.getAttribute("aria-disabled")!=="true"&&(Pe(e,y),b.focus())};a.addEventListener("click",h),Xo(e,()=>{a.removeEventListener("keydown",v),a.removeEventListener("click",h);for(let g of l)g&&g();l.length=0,Ee.containers.delete(e)})}})}function Fr(t){t.directive("tab",{priority:11,init(){}}),t.directive("tab-disabled",{priority:11,init(){}}),t.directive("tab-position",{priority:11,init(){}})}function Or(t){t.directive("panel",{priority:11,init(){}})}function Vr(t,e={}){zr(t),Fr(t),Or(t)}function Nr(){Mr()}var B={branches:new Map,selectedItem:null,typeahead:"",typeaheadTimer:null};function Wr(){B.branches.clear(),B.selectedItem=null,B.typeahead="",B.typeaheadTimer&&(clearTimeout(B.typeaheadTimer),B.typeaheadTimer=null)}function De(){if(typeof document>"u"||document.querySelector("style[data-nojs-tree]"))return;let t=` +`.trim(),e=document.createElement("style");e.setAttribute("data-nojs-tabs",""),e.textContent=t,document.head.appendChild(e)}function pi(t,e){t.__disposers=t.__disposers||[],t.__disposers.push(e)}var fi=0;function Gr(t){return`${t}-${++fi}`}function Oe(t,e,r=!1){let o=Ae.containers.get(t);if(!o)return;let{tabs:n,panels:i}=o;if(!(e<0||e>=n.length)&&!(!r&&n[e].getAttribute("aria-disabled")==="true")){for(let c=0;c{let y=!1;try{y=!!t.evaluate(v,g)}catch{y=!1}y?m.setAttribute("aria-disabled","true"):m.removeAttribute("aria-disabled")};for(let m=0;mf(v,y));u.push(x)}}let p=0;if(o&&o.trim()!==""){let m=parseInt(o,10);!isNaN(m)&&m>=0&&m{let v=Ae.containers.get(e);if(!v)return;let y=m.target;if(y.getAttribute("role")!=="tab")return;let{tabs:x}=v,j=x.indexOf(y);if(j===-1)return;let E=-1;switch(m.key){case"ArrowRight":case"ArrowDown":E=Ve(x,j,1);break;case"ArrowLeft":case"ArrowUp":E=Ve(x,j,-1);break;case"Home":E=Ve(x,x.length-1,1);break;case"End":E=Ve(x,0,-1);break;case"Tab":return;default:return}E!==-1&&E!==j&&(m.preventDefault(),Oe(e,E),x[E].focus())};s.addEventListener("keydown",b);let h=m=>{let v=m.target.closest("[role='tab']");if(!v)return;let y=Ae.containers.get(e);if(!y)return;let x=y.tabs.indexOf(v);x!==-1&&v.getAttribute("aria-disabled")!=="true"&&(Oe(e,x),v.focus())};s.addEventListener("click",h),pi(e,()=>{s.removeEventListener("keydown",b),s.removeEventListener("click",h);for(let m of u)m&&m();u.length=0,Ae.containers.delete(e)})}})}function Yr(t){t.directive("tab",{priority:11,init(){}}),t.directive("tab-disabled",{priority:11,init(){}}),t.directive("tab-position",{priority:11,init(){}})}function Kr(t){t.directive("panel",{priority:11,init(){}})}function Xr(t,e={}){Ur(t),Yr(t),Kr(t)}function Zr(){Wr()}var q={branches:new Map,selectedItem:null,typeahead:"",typeaheadTimer:null};function Qr(){q.branches.clear(),q.selectedItem=null,q.typeahead="",q.typeaheadTimer&&(clearTimeout(q.typeaheadTimer),q.typeaheadTimer=null)}function He(){if(typeof document>"u"||document.querySelector("style[data-nojs-tree]"))return;let t=` .nojs-tree { list-style: none; padding-left: 0; @@ -398,7 +398,7 @@ var mt=Object.defineProperty;var ho=Object.getOwnPropertyDescriptor;var vo=Objec opacity: 0.4; cursor: grabbing !important; } -`.trim(),e=document.createElement("style");e.setAttribute("data-nojs-tree",""),e.textContent=t,document.head.appendChild(e)}function Ie(t,e){t.__disposers=t.__disposers||[],t.__disposers.push(e)}function Ur(t){let e=[],r=document.createTreeWalker(t,NodeFilter.SHOW_ELEMENT,{acceptNode(n){return n.matches&&n.matches('.nojs-subtree[aria-hidden="true"]')?NodeFilter.FILTER_REJECT:n.getAttribute("role")==="treeitem"?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIP}}),o;for(;o=r.nextNode();)e.push(o);return e}function Gr(t){return t.closest('[role="tree"]')}function Qo(t){let e=t.parentElement?.closest('[role="group"], .nojs-subtree');if(e){let r=e.parentElement?.closest('[role="treeitem"]');if(r)return r;let o=e.previousElementSibling;if(o?.matches?.('[role="treeitem"]'))return o}return t.parentElement?.closest('[role="treeitem"]')||null}function Jo(t){let e=t.cloneNode(!0);return e.querySelectorAll('[role="group"]').forEach(o=>o.remove()),(e.textContent||"").trim().toLowerCase()}function Tt(t){let e=B.selectedItem;e&&e!==t&&(e.classList.remove("nojs-branch-selected"),e.setAttribute("aria-selected","false")),t.classList.add("nojs-branch-selected"),t.setAttribute("aria-selected","true"),B.selectedItem=t}function Yr(t){let e=B.branches.get(t);!e||!e.subtreeEl||(e.expanded=!e.expanded,t.setAttribute("aria-expanded",String(e.expanded)),e.subtreeEl.setAttribute("aria-hidden",String(!e.expanded)))}function ei(t){let e=B.branches.get(t);!e||!e.subtreeEl||e.expanded||(e.expanded=!0,t.setAttribute("aria-expanded","true"),e.subtreeEl.setAttribute("aria-hidden","false"))}function ti(t){let e=B.branches.get(t);!e||!e.subtreeEl||!e.expanded||(e.expanded=!1,t.setAttribute("aria-expanded","false"),e.subtreeEl.setAttribute("aria-hidden","true"))}function Kr(t,e){let r=Gr(e);if(!r)return;let o=Ur(r),n=o.indexOf(e);if(n<0)return;let i=B.branches.get(e),c=i&&i.subtreeEl;switch(t.key){case"ArrowRight":if(t.preventDefault(),c&&!i.expanded)ei(e);else if(c&&i.expanded){let a=i.subtreeEl.querySelector('[role="treeitem"]');a&&_e(a,o)}break;case"ArrowLeft":if(t.preventDefault(),c&&i.expanded)ti(e);else{let a=Qo(e);a&&_e(a,Ur(r))}break;case"ArrowDown":t.preventDefault(),n 0&&_e(o[n-1],o);break;case"Enter":case" ":t.preventDefault(),Tt(e),c&&Yr(e);break;case"Home":t.preventDefault(),o.length>0&&_e(o[0],o);break;case"End":t.preventDefault(),o.length>0&&_e(o[o.length-1],o);break;default:if(t.key.length===1&&!t.ctrlKey&&!t.altKey&&!t.metaKey){t.preventDefault(),B.typeahead+=t.key.toLowerCase(),B.typeaheadTimer&&clearTimeout(B.typeaheadTimer),B.typeaheadTimer=setTimeout(()=>{B.typeahead="",B.typeaheadTimer=null},500);let a=n+1;for(let s=0;s {if(c)return;let d=e.querySelector(":scope > [subtree], :scope > .nojs-subtree")||(e.nextElementSibling?.matches?.("[subtree], .nojs-subtree")?e.nextElementSibling:null);d?(B.branches.set(e,{expanded:n,subtreeEl:d}),d.setAttribute("aria-hidden",String(!n))):B.branches.set(e,{expanded:n,subtreeEl:null})});let a=d=>{d.target.closest?.('[role="treeitem"]')===e&&(d.stopPropagation(),Tt(e),Yr(e))};e.addEventListener("click",a),Ie(e,()=>e.removeEventListener("click",a));let s=d=>{Kr(d,e)};e.addEventListener("keydown",s),Ie(e,()=>e.removeEventListener("keydown",s)),Ie(e,()=>{c=!0,B.branches.delete(e),B.selectedItem===e&&(B.selectedItem=null),B.typeaheadTimer&&(clearTimeout(B.typeaheadTimer),B.typeaheadTimer=null,B.typeahead="")})}})}function _e(t,e){for(let r of e)r.setAttribute("tabindex",r===t?"0":"-1");t.focus()}function Qr(t){t.directive("subtree",{priority:16,init(e){De(),e.classList.add("nojs-subtree"),e.classList.add("nojs-tree"),e.setAttribute("role","group");for(let o of e.children)if(o.tagName==="LI"&&!o.querySelector("[branch], .nojs-branch")){o.setAttribute("role","treeitem"),o.setAttribute("tabindex","-1"),o.classList.add("nojs-tree-leaf");let n=c=>{c.stopPropagation(),Tt(o)};o.addEventListener("click",n),Ie(o,()=>o.removeEventListener("click",n));let i=c=>{Kr(c,o)};o.addEventListener("keydown",i),Ie(o,()=>o.removeEventListener("keydown",i)),Ie(o,()=>{B.selectedItem===o&&(B.selectedItem=null)})}let r=e.parentElement?.matches?.('[role="treeitem"]')?e.parentElement:e.previousElementSibling?.matches?.('[role="treeitem"]')?e.previousElementSibling:null;if(r){let o=B.branches.get(r);o?(e.setAttribute("aria-hidden",String(!o.expanded)),o.subtreeEl=e):e.setAttribute("aria-hidden","true")}else e.setAttribute("aria-hidden","true")}})}function Jr(t,e){t.__disposers=t.__disposers||[],t.__disposers.push(e)}function Dt(t){return t.closest('[role="treeitem"]')}function ri(t){return t.closest('[role="tree"]')}function ni(t){let e=t.parentElement;return e?[...e.children].filter(r=>r.getAttribute("role")==="treeitem"):[]}function oi(t){return ni(t).indexOf(t)}function ii(t,e,r){let o=t.getBoundingClientRect(),n=e-o.top,i=o.height;return r==="reparent"?"on":r==="reorder"?ni*.75?"after":"on"}function en(t,e){let r=t.parentElement;for(;r;){if(r===e)return!0;r=r.parentElement}return!1}var D={dragging:null,indicator:null,currentTarget:null,currentPosition:null};function He(){D.indicator&&(D.indicator.remove(),D.indicator=null)}function ze(t){if(!t)return;let e=t.querySelectorAll(".nojs-tree-drag-over");for(let r of e)r.classList.remove("nojs-tree-drag-over")}function si(){let t=document.createElement("div");return t.className="nojs-tree-drag-indicator",t.setAttribute("aria-hidden","true"),t}function ai(t,e){He();let r=si(),o=t.getBoundingClientRect(),n=ri(t);if(!n)return;let i=n.getBoundingClientRect();r.style.position="absolute",r.style.left=o.left-i.left+"px",r.style.width=o.width+"px",e==="before"?r.style.top=o.top-i.top-1+"px":r.style.top=o.bottom-i.top-1+"px",getComputedStyle(n).position==="static"&&(n.style.position="relative"),n.appendChild(r),D.indicator=r}function tn(t){t.directive("tree-drag-mode",{priority:15,init(e,r,o){if(De(),o!=="reparent"&&o!=="reorder"&&o!=="both")return;let n=0,i=f=>{let u=Dt(f.target);if(u&&e.contains(u)){if(u.hasAttribute("tree-drag-disabled")){f.preventDefault();return}D.dragging={el:u,treeRoot:e},f.dataTransfer&&(f.dataTransfer.effectAllowed="move",f.dataTransfer.setData("text/plain","")),u.classList.add("nojs-dragging"),u.dispatchEvent(new CustomEvent("tree:drag-start",{bubbles:!0,detail:{node:u}}))}},c=f=>{if(!D.dragging||D.dragging.treeRoot!==e)return;let u=Dt(f.target);if(!u||!e.contains(u)||u===D.dragging.el||en(u,D.dragging.el))return;f.preventDefault(),f.dataTransfer&&(f.dataTransfer.dropEffect="move");let p=ii(u,f.clientY,o);(D.currentTarget!==u||D.currentPosition!==p)&&(ze(e),He(),D.currentTarget=u,D.currentPosition=p,p==="on"?u.classList.add("nojs-tree-drag-over"):ai(u,p))},a=f=>{D.dragging&&D.dragging.treeRoot===e&&n++},s=f=>{D.dragging&&(n--,n<=0&&(n=0,ze(e),He(),D.currentTarget=null,D.currentPosition=null))},d=f=>{if(f.preventDefault(),f.stopPropagation(),n=0,!D.dragging||D.dragging.treeRoot!==e)return;let u=D.dragging.el,p=D.currentTarget,v=D.currentPosition;if(ze(e),He(),!p||!v){D.dragging=null,D.currentTarget=null,D.currentPosition=null;return}if(p===u||en(p,u)){D.dragging=null,D.currentTarget=null,D.currentPosition=null;return}if(v==="on"){let h=p.querySelector(':scope > [role="group"]');h||(h=p.nextElementSibling?.matches?.('[role="group"]')?p.nextElementSibling:null),h?h.setAttribute("aria-hidden","false"):(h=document.createElement("ul"),h.setAttribute("role","group"),h.setAttribute("subtree",""),h.classList.add("nojs-subtree","nojs-tree"),h.setAttribute("aria-hidden","false"),p.appendChild(h));let g=B.branches.get(p);g&&(g.expanded=!0,g.subtreeEl=h,p.setAttribute("aria-expanded","true")),h.appendChild(u),e.dispatchEvent(new CustomEvent("tree:reparent",{bubbles:!0,detail:{node:u,newParent:p}}))}else{let h=p.parentElement;if(!h){D.dragging=null,D.currentTarget=null,D.currentPosition=null;return}if(v==="before")h.insertBefore(u,p);else{let b=p.nextElementSibling,E=b?.matches?.('[role="group"]')?b.nextElementSibling:b;E?h.insertBefore(u,E):h.appendChild(u)}let g=oi(u);e.dispatchEvent(new CustomEvent("tree:reorder",{bubbles:!0,detail:{node:u,newIndex:g}}))}D.dragging=null,D.currentTarget=null,D.currentPosition=null},m=f=>{let u=Dt(f.target);u&&u.classList.remove("nojs-dragging"),ze(e),He(),n=0,D.dragging&&D.dragging.el.dispatchEvent(new CustomEvent("tree:drag-end",{bubbles:!0,detail:{node:D.dragging.el}})),D.dragging=null,D.currentTarget=null,D.currentPosition=null};e.addEventListener("dragstart",i),e.addEventListener("dragover",c),e.addEventListener("dragenter",a),e.addEventListener("dragleave",s),e.addEventListener("drop",d),e.addEventListener("dragend",m),Jr(e,()=>{e.removeEventListener("dragstart",i),e.removeEventListener("dragover",c),e.removeEventListener("dragenter",a),e.removeEventListener("dragleave",s),e.removeEventListener("drop",d),e.removeEventListener("dragend",m),ze(e),He()}),ci(e);let l=new MutationObserver(f=>{for(let u of f)for(let p of u.addedNodes){if(p.nodeType!==1)continue;p.getAttribute("role")==="treeitem"&&It(p);let v=p.querySelectorAll?.('[role="treeitem"]');if(v)for(let h of v)It(h)}});l.observe(e,{childList:!0,subtree:!0}),Jr(e,()=>l.disconnect())}})}function It(t){if(t.hasAttribute("tree-drag-disabled")){t.draggable=!1;return}t.draggable=!0}function ci(t){let e=t.querySelectorAll('[role="treeitem"]');for(let r of e)It(r)}function rn(t,e={}){Xr(t),Zr(t),Qr(t),tn(t)}function nn(){Wr()}var tt=new Map;function on(){tt.clear()}function rt(){if(typeof document>"u"||document.querySelector("style[data-nojs-stepper]"))return;let t=` +`.trim(),e=document.createElement("style");e.setAttribute("data-nojs-tree",""),e.textContent=t,document.head.appendChild(e)}function $e(t,e){t.__disposers=t.__disposers||[],t.__disposers.push(e)}function Jr(t){let e=[],r=document.createTreeWalker(t,NodeFilter.SHOW_ELEMENT,{acceptNode(n){return n.matches&&n.matches('.nojs-subtree[aria-hidden="true"]')?NodeFilter.FILTER_REJECT:n.getAttribute("role")==="treeitem"?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIP}}),o;for(;o=r.nextNode();)e.push(o);return e}function en(t){return t.closest('[role="tree"]')}function mi(t){let e=t.parentElement?.closest('[role="group"], .nojs-subtree');if(e){let r=e.parentElement?.closest('[role="treeitem"]');if(r)return r;let o=e.previousElementSibling;if(o?.matches?.('[role="treeitem"]'))return o}return t.parentElement?.closest('[role="treeitem"]')||null}function gi(t){let e=t.cloneNode(!0);return e.querySelectorAll('[role="group"]').forEach(o=>o.remove()),(e.textContent||"").trim().toLowerCase()}function Ht(t){let e=q.selectedItem;e&&e!==t&&(e.classList.remove("nojs-branch-selected"),e.setAttribute("aria-selected","false")),t.classList.add("nojs-branch-selected"),t.setAttribute("aria-selected","true"),q.selectedItem=t}function tn(t){let e=q.branches.get(t);!e||!e.subtreeEl||(e.expanded=!e.expanded,t.setAttribute("aria-expanded",String(e.expanded)),e.subtreeEl.setAttribute("aria-hidden",String(!e.expanded)))}function bi(t){let e=q.branches.get(t);!e||!e.subtreeEl||e.expanded||(e.expanded=!0,t.setAttribute("aria-expanded","true"),e.subtreeEl.setAttribute("aria-hidden","false"))}function hi(t){let e=q.branches.get(t);!e||!e.subtreeEl||!e.expanded||(e.expanded=!1,t.setAttribute("aria-expanded","false"),e.subtreeEl.setAttribute("aria-hidden","true"))}function rn(t,e){let r=en(e);if(!r)return;let o=Jr(r),n=o.indexOf(e);if(n<0)return;let i=q.branches.get(e),c=i&&i.subtreeEl;switch(t.key){case"ArrowRight":if(t.preventDefault(),c&&!i.expanded)bi(e);else if(c&&i.expanded){let s=i.subtreeEl.querySelector('[role="treeitem"]');s&&we(s,o)}break;case"ArrowLeft":if(t.preventDefault(),c&&i.expanded)hi(e);else{let s=mi(e);s&&we(s,Jr(r))}break;case"ArrowDown":t.preventDefault(),n 0&&we(o[n-1],o);break;case"Enter":case" ":t.preventDefault(),Ht(e),c&&tn(e);break;case"Home":t.preventDefault(),o.length>0&&we(o[0],o);break;case"End":t.preventDefault(),o.length>0&&we(o[o.length-1],o);break;default:if(t.key.length===1&&!t.ctrlKey&&!t.altKey&&!t.metaKey){t.preventDefault(),q.typeahead+=t.key.toLowerCase(),q.typeaheadTimer&&clearTimeout(q.typeaheadTimer),q.typeaheadTimer=setTimeout(()=>{q.typeahead="",q.typeaheadTimer=null},500);let s=n+1;for(let a=0;a {if(c)return;let d=e.querySelector(":scope > [subtree], :scope > .nojs-subtree")||(e.nextElementSibling?.matches?.("[subtree], .nojs-subtree")?e.nextElementSibling:null);d?(q.branches.set(e,{expanded:n,subtreeEl:d}),d.setAttribute("aria-hidden",String(!n))):q.branches.set(e,{expanded:n,subtreeEl:null})});let s=d=>{d.target.closest?.('[role="treeitem"]')===e&&(d.stopPropagation(),Ht(e),tn(e))};e.addEventListener("click",s),$e(e,()=>e.removeEventListener("click",s));let a=d=>{rn(d,e)};e.addEventListener("keydown",a),$e(e,()=>e.removeEventListener("keydown",a)),$e(e,()=>{c=!0,q.branches.delete(e),q.selectedItem===e&&(q.selectedItem=null),q.typeaheadTimer&&(clearTimeout(q.typeaheadTimer),q.typeaheadTimer=null,q.typeahead="")})}})}function we(t,e){for(let r of e)r.setAttribute("tabindex",r===t?"0":"-1");t.focus()}function sn(t){t.directive("subtree",{priority:16,init(e){He(),e.classList.add("nojs-subtree"),e.classList.add("nojs-tree"),e.setAttribute("role","group");for(let o of e.children)if(o.tagName==="LI"&&!o.querySelector("[branch], .nojs-branch")){o.setAttribute("role","treeitem"),o.setAttribute("tabindex","-1"),o.classList.add("nojs-tree-leaf");let n=c=>{c.stopPropagation(),Ht(o)};o.addEventListener("click",n),$e(o,()=>o.removeEventListener("click",n));let i=c=>{rn(c,o)};o.addEventListener("keydown",i),$e(o,()=>o.removeEventListener("keydown",i)),$e(o,()=>{q.selectedItem===o&&(q.selectedItem=null)})}let r=e.parentElement?.matches?.('[role="treeitem"]')?e.parentElement:e.previousElementSibling?.matches?.('[role="treeitem"]')?e.previousElementSibling:null;if(r){let o=q.branches.get(r);o?(e.setAttribute("aria-hidden",String(!o.expanded)),o.subtreeEl=e):e.setAttribute("aria-hidden","true")}else e.setAttribute("aria-hidden","true")}})}function an(t,e){t.__disposers=t.__disposers||[],t.__disposers.push(e)}function $t(t){return t.closest('[role="treeitem"]')}function vi(t){return t.closest('[role="tree"]')}function yi(t){let e=t.parentElement;return e?[...e.children].filter(r=>r.getAttribute("role")==="treeitem"):[]}function xi(t){return yi(t).indexOf(t)}function Ei(t,e,r){let o=t.getBoundingClientRect(),n=e-o.top,i=o.height;return r==="reparent"?"on":r==="reorder"?ni*.75?"after":"on"}function cn(t,e){let r=t.parentElement;for(;r;){if(r===e)return!0;r=r.parentElement}return!1}var I={dragging:null,indicator:null,currentTarget:null,currentPosition:null};function qe(){I.indicator&&(I.indicator.remove(),I.indicator=null)}function We(t){if(!t)return;let e=t.querySelectorAll(".nojs-tree-drag-over");for(let r of e)r.classList.remove("nojs-tree-drag-over")}function _i(){let t=document.createElement("div");return t.className="nojs-tree-drag-indicator",t.setAttribute("aria-hidden","true"),t}function Ai(t,e){qe();let r=_i(),o=t.getBoundingClientRect(),n=vi(t);if(!n)return;let i=n.getBoundingClientRect();r.style.position="absolute",r.style.left=o.left-i.left+"px",r.style.width=o.width+"px",e==="before"?r.style.top=o.top-i.top-1+"px":r.style.top=o.bottom-i.top-1+"px",getComputedStyle(n).position==="static"&&(n.style.position="relative"),n.appendChild(r),I.indicator=r}function dn(t){t.directive("tree-drag-mode",{priority:15,init(e,r,o){if(He(),o!=="reparent"&&o!=="reorder"&&o!=="both")return;let n=0,i=f=>{let p=$t(f.target);if(p&&e.contains(p)){if(p.hasAttribute("tree-drag-disabled")){f.preventDefault();return}I.dragging={el:p,treeRoot:e},f.dataTransfer&&(f.dataTransfer.effectAllowed="move",f.dataTransfer.setData("text/plain","")),p.classList.add("nojs-dragging"),p.dispatchEvent(new CustomEvent("tree:drag-start",{bubbles:!0,detail:{node:p}}))}},c=f=>{if(!I.dragging||I.dragging.treeRoot!==e)return;let p=$t(f.target);if(!p||!e.contains(p)||p===I.dragging.el||cn(p,I.dragging.el))return;f.preventDefault(),f.dataTransfer&&(f.dataTransfer.dropEffect="move");let l=Ei(p,f.clientY,o);(I.currentTarget!==p||I.currentPosition!==l)&&(We(e),qe(),I.currentTarget=p,I.currentPosition=l,l==="on"?p.classList.add("nojs-tree-drag-over"):Ai(p,l))},s=f=>{I.dragging&&I.dragging.treeRoot===e&&n++},a=f=>{I.dragging&&(n--,n<=0&&(n=0,We(e),qe(),I.currentTarget=null,I.currentPosition=null))},d=f=>{if(f.preventDefault(),f.stopPropagation(),n=0,!I.dragging||I.dragging.treeRoot!==e)return;let p=I.dragging.el,l=I.currentTarget,b=I.currentPosition;if(We(e),qe(),!l||!b){I.dragging=null,I.currentTarget=null,I.currentPosition=null;return}if(l===p||cn(l,p)){I.dragging=null,I.currentTarget=null,I.currentPosition=null;return}if(b==="on"){let h=l.querySelector(':scope > [role="group"]');h||(h=l.nextElementSibling?.matches?.('[role="group"]')?l.nextElementSibling:null),h?h.setAttribute("aria-hidden","false"):(h=document.createElement("ul"),h.setAttribute("role","group"),h.setAttribute("subtree",""),h.classList.add("nojs-subtree","nojs-tree"),h.setAttribute("aria-hidden","false"),l.appendChild(h));let m=q.branches.get(l);m&&(m.expanded=!0,m.subtreeEl=h,l.setAttribute("aria-expanded","true")),h.appendChild(p),e.dispatchEvent(new CustomEvent("tree:reparent",{bubbles:!0,detail:{node:p,newParent:l}}))}else{let h=l.parentElement;if(!h){I.dragging=null,I.currentTarget=null,I.currentPosition=null;return}if(b==="before")h.insertBefore(p,l);else{let v=l.nextElementSibling,y=v?.matches?.('[role="group"]')?v.nextElementSibling:v;y?h.insertBefore(p,y):h.appendChild(p)}let m=xi(p);e.dispatchEvent(new CustomEvent("tree:reorder",{bubbles:!0,detail:{node:p,newIndex:m}}))}I.dragging=null,I.currentTarget=null,I.currentPosition=null},g=f=>{let p=$t(f.target);p&&p.classList.remove("nojs-dragging"),We(e),qe(),n=0,I.dragging&&I.dragging.el.dispatchEvent(new CustomEvent("tree:drag-end",{bubbles:!0,detail:{node:I.dragging.el}})),I.dragging=null,I.currentTarget=null,I.currentPosition=null};e.addEventListener("dragstart",i),e.addEventListener("dragover",c),e.addEventListener("dragenter",s),e.addEventListener("dragleave",a),e.addEventListener("drop",d),e.addEventListener("dragend",g),an(e,()=>{e.removeEventListener("dragstart",i),e.removeEventListener("dragover",c),e.removeEventListener("dragenter",s),e.removeEventListener("dragleave",a),e.removeEventListener("drop",d),e.removeEventListener("dragend",g),We(e),qe()}),wi(e);let u=new MutationObserver(f=>{for(let p of f)for(let l of p.addedNodes){if(l.nodeType!==1)continue;l.getAttribute("role")==="treeitem"&&qt(l);let b=l.querySelectorAll?.('[role="treeitem"]');if(b)for(let h of b)qt(h)}});u.observe(e,{childList:!0,subtree:!0}),an(e,()=>u.disconnect())}})}function qt(t){if(t.hasAttribute("tree-drag-disabled")){t.draggable=!1;return}t.draggable=!0}function wi(t){let e=t.querySelectorAll('[role="treeitem"]');for(let r of e)qt(r)}function ln(t,e={}){nn(t),on(t),sn(t),dn(t)}function un(){Qr()}var it=new Map;function pn(){it.clear()}function st(){if(typeof document>"u"||document.querySelector("style[data-nojs-stepper]"))return;let t=` .nojs-stepper-indicator { display: flex; align-items: center; @@ -471,7 +471,7 @@ var mt=Object.defineProperty;var ho=Object.getOwnPropertyDescriptor;var vo=Objec justify-content: space-between; gap: 0.5rem; } -`.trim(),e=document.createElement("style");e.setAttribute("data-nojs-stepper",""),e.textContent=t,document.head.appendChild(e)}function sn(t,e){if(!t.hasAttribute("stepper-validate"))return!0;let r=t.querySelector("form[validate]");if(!r)return!0;let n=e(r)?.$form;return n?!!n.valid:!0}function an(t){let e=t.querySelectorAll("input, textarea, select");for(let r of e)r.dispatchEvent(new Event("focusout",{bubbles:!0}))}function cn(t,e,r){t.dispatchEvent(new CustomEvent("stepper:validation-blocked",{bubbles:!0,detail:{step:e,form:r}}))}function Fe(t,e){t.__disposers=t.__disposers||[],t.__disposers.push(e)}function dn(t){t.directive("stepper",{priority:14,init(e,r,o){rt();let n=t.findContext(e),i=Array.from(e.querySelectorAll("[step]"));if(!i.length){console.warn("[stepper] No [step] children found.");return}let c=o&&parseInt(o,10)||0,a=e.getAttribute("stepper-mode")||"linear",s=e.getAttribute("stepper-indicator")!=="false",d=e.getAttribute("stepper-nav")!=="false",m=e.getAttribute("aria-label")||"Stepper",l=Math.max(0,Math.min(c,i.length-1));e.setAttribute("role","group"),e.setAttribute("aria-label",m),e.classList.add("nojs-stepper");let f=null,u=[];if(s){f=document.createElement("div"),f.className="nojs-stepper-indicator",f.setAttribute("role","tablist"),f.setAttribute("aria-label","Progress"),i.forEach((j,S)=>{if(S>0){let z=document.createElement("div");z.className="nojs-stepper-separator",z.setAttribute("aria-hidden","true"),f.appendChild(z)}let A=document.createElement("button");A.type="button",A.className="nojs-stepper-indicator-item",A.setAttribute("role","tab"),A.setAttribute("aria-selected",S===l?"true":"false");let $=j.getAttribute("step-label")||`Step ${S+1}`,V=document.createElement("span");V.textContent=$,A.appendChild(V),A.setAttribute("aria-label",$);let X=`nojs-stepper-tab-${di++}`;if(A.id=X,a==="free"){A.setAttribute("data-clickable","");let z=()=>_(S);A.addEventListener("click",z),Fe(e,()=>A.removeEventListener("click",z))}else A.setAttribute("tabindex","-1");f.appendChild(A),u.push(A)});let k=j=>{if(!["ArrowLeft","ArrowRight","Home","End"].includes(j.key))return;j.preventDefault();let S=l;j.key==="ArrowRight"?S=Math.min(l+1,i.length-1):j.key==="ArrowLeft"?S=Math.max(l-1,0):j.key==="Home"?S=0:j.key==="End"&&(S=i.length-1),a==="free"?(_(S),u[S]?.focus()):u[l]?.focus()};f.addEventListener("keydown",k),Fe(e,()=>f.removeEventListener("keydown",k)),e.insertBefore(f,e.firstChild)}let p=null,v=null,h=null;if(d){p=document.createElement("div"),p.className="nojs-stepper-nav",p.setAttribute("aria-hidden","true"),v=document.createElement("button"),v.type="button",v.className="nojs-stepper-prev",v.textContent="Previous";let k=()=>y();v.addEventListener("click",k),Fe(e,()=>v.removeEventListener("click",k)),h=document.createElement("button"),h.type="button",h.className="nojs-stepper-next",h.textContent="Next";let j=()=>E();h.addEventListener("click",j),Fe(e,()=>h.removeEventListener("click",j)),p.appendChild(v),p.appendChild(h),e.appendChild(p)}function g(k){let j=i[k];if(!j)return!0;if(!sn(j,t.findContext)){let $=j.querySelector("form[validate]");return $&&(an($),u[k]&&u[k].classList.add("nojs-step-invalid"),cn(e,j,$)),!1}u[k]&&u[k].classList.remove("nojs-step-invalid");let S=j.querySelectorAll("[required]");for(let $ of S)if(typeof $.checkValidity=="function"&&!$.checkValidity())return $.reportValidity(),!1;let A=j.getAttribute("step-validate");if(A)try{if(!t.evaluate(A,n))return!1}catch($){return console.warn(`[stepper] step-validate error: ${$.message}`),!1}return!0}function b(k){if(i.forEach((j,S)=>{let A=S===l;j.setAttribute("aria-hidden",A?"false":"true"),A?(j.removeAttribute("inert"),j.setAttribute("aria-current","step")):(j.setAttribute("inert",""),j.removeAttribute("aria-current"))}),u.length&&u.forEach((j,S)=>{j.setAttribute("aria-selected",S===l?"true":"false"),S j.focus())}e.dispatchEvent(new CustomEvent("nojs:stepper-change",{bubbles:!k,detail:{current:l,total:i.length}}))}function E(){return l>=i.length-1?(a==="linear"&&!g(l)||e.dispatchEvent(new CustomEvent("nojs:stepper-complete",{bubbles:!0,detail:{current:l,total:i.length}})),!1):a==="linear"&&!g(l)?!1:(l++,b(),L(),!0)}function y(){return l<=0?!1:(l--,b(),L(),!0)}function _(k){if(k<0||k>=i.length||k===l)return!1;if(a==="linear"&&k>l){for(let j=l;j {tt.delete(e),f&&f.parentNode&&f.remove(),p&&p.parentNode&&p.remove(),delete n.$stepper})}})}var di=0;var li=0;function ln(t){t.directive("step",{priority:13,init(e,r,o){rt(),e.classList.add("nojs-step"),e.setAttribute("role","tabpanel"),e.id||(e.id=`nojs-stepper-panel-${li++}`),e.setAttribute("tabindex","0")}})}function un(t,e={}){ln(t),dn(t)}function pn(){on()}function fn(){if(typeof document>"u"||document.querySelector("style[data-nojs-skeleton]"))return;let t=` +`.trim(),e=document.createElement("style");e.setAttribute("data-nojs-stepper",""),e.textContent=t,document.head.appendChild(e)}function fn(t,e){if(!t.hasAttribute("stepper-validate"))return!0;let r=t.querySelector("form[validate]");if(!r)return!0;let n=e(r)?.$form;return n?!!n.valid:!0}function mn(t){let e=t.querySelectorAll("input, textarea, select");for(let r of e)r.dispatchEvent(new Event("focusout",{bubbles:!0}))}function gn(t,e,r){t.dispatchEvent(new CustomEvent("stepper:validation-blocked",{bubbles:!0,detail:{step:e,form:r}}))}function Ne(t,e){t.__disposers=t.__disposers||[],t.__disposers.push(e)}function bn(t){t.directive("stepper",{priority:14,init(e,r,o){st();let n=t.findContext(e),i=Array.from(e.querySelectorAll("[step]"));if(!i.length){console.warn("[stepper] No [step] children found.");return}let c=o&&parseInt(o,10)||0,s=e.getAttribute("stepper-mode")||"linear",a=e.getAttribute("stepper-indicator")!=="false",d=e.getAttribute("stepper-nav")!=="false",g=e.getAttribute("aria-label")||"Stepper",u=Math.max(0,Math.min(c,i.length-1));e.setAttribute("role","group"),e.setAttribute("aria-label",g),e.classList.add("nojs-stepper");let f=null,p=[];if(a){f=document.createElement("div"),f.className="nojs-stepper-indicator",f.setAttribute("role","tablist"),f.setAttribute("aria-label","Progress"),i.forEach((A,C)=>{if(C>0){let V=document.createElement("div");V.className="nojs-stepper-separator",V.setAttribute("aria-hidden","true"),f.appendChild(V)}let D=document.createElement("button");D.type="button",D.className="nojs-stepper-indicator-item",D.setAttribute("role","tab"),D.setAttribute("aria-selected",C===u?"true":"false");let H=A.getAttribute("step-label")||`Step ${C+1}`,k=document.createElement("span");k.textContent=H,D.appendChild(k),D.setAttribute("aria-label",H);let U=`nojs-stepper-tab-${ji++}`;if(D.id=U,s==="free"){D.setAttribute("data-clickable","");let V=()=>j(C);D.addEventListener("click",V),Ne(e,()=>D.removeEventListener("click",V))}else D.setAttribute("tabindex","-1");f.appendChild(D),p.push(D)});let w=A=>{if(!["ArrowLeft","ArrowRight","Home","End"].includes(A.key))return;A.preventDefault();let C=u;A.key==="ArrowRight"?C=Math.min(u+1,i.length-1):A.key==="ArrowLeft"?C=Math.max(u-1,0):A.key==="Home"?C=0:A.key==="End"&&(C=i.length-1),s==="free"?(j(C),p[C]?.focus()):p[u]?.focus()};f.addEventListener("keydown",w),Ne(e,()=>f.removeEventListener("keydown",w)),e.insertBefore(f,e.firstChild)}let l=null,b=null,h=null;if(d){l=document.createElement("div"),l.className="nojs-stepper-nav",l.setAttribute("aria-hidden","true"),b=document.createElement("button"),b.type="button",b.className="nojs-stepper-prev",b.textContent="Previous";let w=()=>x();b.addEventListener("click",w),Ne(e,()=>b.removeEventListener("click",w)),h=document.createElement("button"),h.type="button",h.className="nojs-stepper-next",h.textContent="Next";let A=()=>y();h.addEventListener("click",A),Ne(e,()=>h.removeEventListener("click",A)),l.appendChild(b),l.appendChild(h),e.appendChild(l)}function m(w){let A=i[w];if(!A)return!0;if(!fn(A,t.findContext)){let H=A.querySelector("form[validate]");return H&&(mn(H),p[w]&&p[w].classList.add("nojs-step-invalid"),gn(e,A,H)),!1}p[w]&&p[w].classList.remove("nojs-step-invalid");let C=A.querySelectorAll("[required]");for(let H of C)if(typeof H.checkValidity=="function"&&!H.checkValidity())return H.reportValidity(),!1;let D=A.getAttribute("step-validate");if(D)try{if(!t.evaluate(D,n))return!1}catch(H){return console.warn(`[stepper] step-validate error: ${H.message}`),!1}return!0}function v(w){if(i.forEach((A,C)=>{let D=C===u;A.setAttribute("aria-hidden",D?"false":"true"),D?(A.removeAttribute("inert"),A.setAttribute("aria-current","step")):(A.setAttribute("inert",""),A.removeAttribute("aria-current"))}),p.length&&p.forEach((A,C)=>{A.setAttribute("aria-selected",C===u?"true":"false"),CA.focus())}e.dispatchEvent(new CustomEvent("nojs:stepper-change",{bubbles:!w,detail:{current:u,total:i.length}}))}function y(){return u>=i.length-1?(s==="linear"&&!m(u)||e.dispatchEvent(new CustomEvent("nojs:stepper-complete",{bubbles:!0,detail:{current:u,total:i.length}})),!1):s==="linear"&&!m(u)?!1:(u++,v(),L(),!0)}function x(){return u<=0?!1:(u--,v(),L(),!0)}function j(w){if(w<0||w>=i.length||w===u)return!1;if(s==="linear"&&w>u){for(let A=u;A {it.delete(e),f&&f.parentNode&&f.remove(),l&&l.parentNode&&l.remove(),delete n.$stepper})}})}var ji=0;var Li=0;function hn(t){t.directive("step",{priority:13,init(e,r,o){st(),e.classList.add("nojs-step"),e.setAttribute("role","tabpanel"),e.id||(e.id=`nojs-stepper-panel-${Li++}`),e.setAttribute("tabindex","0")}})}function vn(t,e={}){hn(t),bn(t)}function yn(){pn()}function xn(){if(typeof document>"u"||document.querySelector("style[data-nojs-skeleton]"))return;let t=` .nojs-skeleton { position: relative; overflow: hidden; @@ -516,7 +516,7 @@ var mt=Object.defineProperty;var ho=Object.getOwnPropertyDescriptor;var vo=Objec .nojs-skeleton-line:last-child { width: 60%; } -`.trim(),e=document.createElement("style");e.setAttribute("data-nojs-skeleton",""),e.textContent=t,document.head.appendChild(e)}function mn(t,e){t.__disposers=t.__disposers||[],t.__disposers.push(e)}function gn(t){t.directive("skeleton",{priority:10,init(e,r,o){fn();let n=t.findContext(e),i=e.getAttribute("skeleton-type")||"text",c=e.getAttribute("skeleton-lines"),a=e.getAttribute("skeleton-size"),s=[];function d(g){m();for(let b=0;b 0&&d(g)}e.setAttribute("aria-busy","true")}let f=null;function u(){f&&f(),e.classList.add("nojs-skeleton-fade"),e.classList.remove("nojs-skeleton"),e.classList.remove("nojs-skeleton-circle"),m(),a&&(i==="circle"||i==="rect")&&(e.style.width="",e.style.height=""),e.removeAttribute("aria-busy");let g=!1,b=null,E=()=>{g||(g=!0,e.isConnected&&e.classList.remove("nojs-skeleton-fade"),e.removeEventListener("transitionend",E),b!==null&&clearTimeout(b),f=null)};e.addEventListener("transitionend",E),b=setTimeout(E,0),f=()=>{e.removeEventListener("transitionend",E),b!==null&&clearTimeout(b),g=!0,f=null}}let p=!1;function v(){let g=!!t.evaluate(o,n);g&&!p?(p=!0,l()):!g&&p&&(p=!1,u())}v();let h=n.$watch(v);mn(e,h),mn(e,()=>{f&&f(),p&&(e.classList.remove("nojs-skeleton","nojs-skeleton-circle","nojs-skeleton-fade"),e.removeAttribute("aria-busy"),m(),a&&(i==="circle"||i==="rect")&&(e.style.width="",e.style.height=""))})}})}function bn(t,e={}){gn(t)}var we=new Map,G=new Map,C={active:!1,splitEl:null,gutterEl:null,prevPane:null,nextPane:null,direction:null,startPos:0,startPrevSize:0,startNextSize:0,containerSize:0};function hn(){we.clear(),G.clear(),C.active=!1,C.splitEl=null,C.gutterEl=null,C.prevPane=null,C.nextPane=null,C.direction=null,C.startPos=0,C.startPrevSize=0,C.startNextSize=0,C.containerSize=0}function nt(){if(typeof document>"u"||document.querySelector("style[data-nojs-split]"))return;let t=` +`.trim(),e=document.createElement("style");e.setAttribute("data-nojs-skeleton",""),e.textContent=t,document.head.appendChild(e)}function En(t,e){t.__disposers=t.__disposers||[],t.__disposers.push(e)}function _n(t){t.directive("skeleton",{priority:10,init(e,r,o){xn();let n=t.findContext(e),i=e.getAttribute("skeleton-type")||"text",c=e.getAttribute("skeleton-lines"),s=e.getAttribute("skeleton-size"),a=[];function d(m){g();for(let v=0;v 0&&d(m)}e.setAttribute("aria-busy","true")}let f=null;function p(){f&&f(),e.classList.add("nojs-skeleton-fade"),e.classList.remove("nojs-skeleton"),e.classList.remove("nojs-skeleton-circle"),g(),s&&(i==="circle"||i==="rect")&&(e.style.width="",e.style.height=""),e.removeAttribute("aria-busy");let m=!1,v=null,y=()=>{m||(m=!0,e.isConnected&&e.classList.remove("nojs-skeleton-fade"),e.removeEventListener("transitionend",y),v!==null&&clearTimeout(v),f=null)};e.addEventListener("transitionend",y),v=setTimeout(y,0),f=()=>{e.removeEventListener("transitionend",y),v!==null&&clearTimeout(v),m=!0,f=null}}let l=!1;function b(){let m=!!t.evaluate(o,n);m&&!l?(l=!0,u()):!m&&l&&(l=!1,p())}b();let h=n.$watch(b);En(e,h),En(e,()=>{f&&f(),l&&(e.classList.remove("nojs-skeleton","nojs-skeleton-circle","nojs-skeleton-fade"),e.removeAttribute("aria-busy"),g(),s&&(i==="circle"||i==="rect")&&(e.style.width="",e.style.height=""))})}})}function An(t,e={}){_n(t)}var je=new Map,G=new Map,T={active:!1,splitEl:null,gutterEl:null,prevPane:null,nextPane:null,direction:null,startPos:0,startPrevSize:0,startNextSize:0,containerSize:0};function wn(){je.clear(),G.clear(),T.active=!1,T.splitEl=null,T.gutterEl=null,T.prevPane=null,T.nextPane=null,T.direction=null,T.startPos=0,T.startPrevSize=0,T.startNextSize=0,T.containerSize=0}function at(){if(typeof document>"u"||document.querySelector("style[data-nojs-split]"))return;let t=` .nojs-split { display: flex; overflow: hidden; @@ -554,7 +554,7 @@ var mt=Object.defineProperty;var ho=Object.getOwnPropertyDescriptor;var vo=Objec .nojs-pane[data-collapsed="true"] { overflow: hidden; } -`.trim(),e=document.createElement("style");e.setAttribute("data-nojs-split",""),e.textContent=t,document.head.appendChild(e)}function ui(t,e){t.__disposers=t.__disposers||[],t.__disposers.push(e)}function vn(t){return t==="horizontal"?"clientX":"clientY"}function Q(t,e){let r=t.getBoundingClientRect?t.getBoundingClientRect():null,o=r&&(e==="horizontal"?r.width:r.height);return o||(e==="horizontal"?t.offsetWidth:t.offsetHeight)}function yn(t,e){if(e!=="horizontal")return 1;try{return(t.closest&&t.closest("[dir]")?.getAttribute("dir")||(typeof getComputedStyle=="function"?getComputedStyle(t).direction:""))==="rtl"?-1:1}catch{return 1}}function pi(t,e){let o=(we.get(t)?.gutters||[]).reduce((n,i)=>n+Q(i,e),0);return Q(t,e)-o}function fi(t,e){if(!t)return null;let r=parseFloat(t);return Number.isNaN(r)?null:typeof t=="string"&&t.trim().endsWith("%")?r/100*e:r}function Oe(t,e){let r=G.get(e);return r?r.min!=null&&t r.max?r.max:t:t}function ot(t,e,r,o){let n=Q(e,o),i=Q(r,o),c=G.get(e),a=G.get(r);t.setAttribute("aria-valuenow",Math.round(n)),t.setAttribute("aria-valuemin",c?.min||0),t.setAttribute("aria-valuemax",Math.round(n+i-(a?.min||0)))}function Ht(t){let e=t.getAttribute("split-persist");if(!e)return;let r=we.get(t);if(!r)return;let o=r.panes.map(n=>n.style.flexBasis||"");try{localStorage.setItem(`nojs-split:${e}`,JSON.stringify(o))}catch{}}function mi(t){let e=t.getAttribute("split-persist");if(!e)return!1;try{let r=localStorage.getItem(`nojs-split:${e}`);if(!r)return!1;let o=JSON.parse(r),n=we.get(t);return!n||o.length!==n.panes.length?!1:(o.forEach((i,c)=>{i&&(n.panes[c].style.flexBasis=i,n.panes[c].style.flexGrow="0")}),!0)}catch{return!1}}function gi(t,e,r,o,n){let i=document.createElement("div");i.className="nojs-gutter",i.setAttribute("role","separator"),i.setAttribute("tabindex","0"),i.setAttribute("aria-orientation",e==="horizontal"?"vertical":"horizontal"),i.setAttribute("aria-label","Resize"),n!==6&&i.style.setProperty("--nojs-gutter-size",`${n}px`);let c=u=>{if(u.button!==0)return;u.preventDefault();let p=pi(t,e);C.active=!0,C.splitEl=t,C.gutterEl=i,C.prevPane=r,C.nextPane=o,C.direction=e,C.startPos=u[vn(e)],C.startPrevSize=Q(r,e),C.startNextSize=Q(o,e),C.containerSize=p,C.sign=yn(t,e),document.body.style.cursor=e==="horizontal"?"col-resize":"row-resize",document.body.style.userSelect="none",i.setPointerCapture(u.pointerId)},a=u=>{if(!C.active||C.gutterEl!==i)return;let p=(u[vn(C.direction)]-C.startPos)*(C.sign||1),v=Oe(C.startPrevSize+p,C.prevPane),h=Oe(C.startNextSize-p,C.nextPane),g=C.startPrevSize+C.startNextSize;v+h!==g&&(v!==C.startPrevSize+p?h=g-v:v=g-h),C.prevPane.style.flexBasis=`${v}px`,C.prevPane.style.flexGrow="0",C.nextPane.style.flexBasis=`${h}px`,C.nextPane.style.flexGrow="0",ot(i,C.prevPane,C.nextPane,C.direction)},s=()=>{!C.active||C.gutterEl!==i||(C.active=!1,document.body.style.cursor="",document.body.style.userSelect="",Ht(t),t.dispatchEvent(new CustomEvent("split-resize",{bubbles:!0,detail:{prevPane:r,nextPane:o}})))};i.addEventListener("pointerdown",c),i.addEventListener("pointermove",a),i.addEventListener("pointerup",s),i.addEventListener("pointercancel",s);let d=10,m=u=>{let p=e==="horizontal",v=yn(t,e),h=0;if(p&&u.key==="ArrowRight"||!p&&u.key==="ArrowDown")h=d*v;else if(p&&u.key==="ArrowLeft"||!p&&u.key==="ArrowUp")h=-d*v;else if(u.key==="Home")h=(G.get(r)?.min||0)-Q(r,e);else if(u.key==="End"){let x=G.get(o);h=Q(r,e)+Q(o,e)-(x?.min||0)-Q(r,e)}else return;u.preventDefault();let g=Q(r,e),b=Q(o,e),E=g+b,y=Oe(g+h,r),_=Oe(E-y,o);y=E-_,y=Oe(y,r),_=E-y,r.style.flexBasis=`${y}px`,r.style.flexGrow="0",o.style.flexBasis=`${_}px`,o.style.flexGrow="0",ot(i,r,o,e),Ht(t)};i.addEventListener("keydown",m);let l=()=>{let u=G.get(r),p=G.get(o),v=u?.collapsible?r:p?.collapsible?o:null;if(!v)return;let h=G.get(v);if(!h)return;let g=v===r?o:r,b=Q(r,e)+Q(o,e);if(h.collapsed){h.collapsed=!1,v.removeAttribute("data-collapsed");let E=h.preCollapseSize||`${Math.round(b/2)}px`,y=fi(E,b)??b/2,_=Math.min(y,b);v.style.flexBasis=`${_}px`,v.style.flexGrow="0",g.style.flexBasis=`${b-_}px`,g.style.flexGrow="0"}else h.preCollapseSize=v.style.flexBasis||`${Q(v,e)}px`,h.collapsed=!0,v.setAttribute("data-collapsed","true"),v.style.flexBasis="0px",v.style.flexGrow="0",g.style.flexBasis=`${b}px`,g.style.flexGrow="0";ot(i,r,o,e),Ht(t),t.dispatchEvent(new CustomEvent("split-collapse",{bubbles:!0,detail:{pane:v,collapsed:h.collapsed}}))};return i.addEventListener("dblclick",l),{gutter:i,cleanup:()=>{i.removeEventListener("pointerdown",c),i.removeEventListener("pointermove",a),i.removeEventListener("pointerup",s),i.removeEventListener("pointercancel",s),i.removeEventListener("keydown",m),i.removeEventListener("dblclick",l)}}}function xn(t){t.directive("split",{priority:14,init(e,r,o){nt();let n=(o||"horizontal").trim()==="vertical"?"vertical":"horizontal",i=parseInt(e.getAttribute("split-gutter"),10)||6;e.classList.add("nojs-split"),e.setAttribute("data-direction",n);let c=Array.from(e.children).filter(m=>m.hasAttribute("pane"));if(c.length<2){console.warn(`[split] Container requires at least 2 [pane] children, found ${c.length}.`);return}c.forEach(m=>{G.get(m)||G.set(m,{size:m.getAttribute("pane")||null,min:parseInt(m.getAttribute("pane-min"),10)||0,max:parseInt(m.getAttribute("pane-max"),10)||1/0,collapsible:m.getAttribute("pane-collapsible")==="true",collapsed:!1,preCollapseSize:null})});let a=[],s=[];for(let m=0;m {let f=G.get(m)?.size;f?(m.style.flexBasis=f,m.style.flexGrow="0"):(m.style.flexGrow="1",m.style.flexBasis="0")}),requestAnimationFrame(()=>{a.forEach((m,l)=>{ot(m,c[l],c[l+1],n)})}),ui(e,()=>{s.forEach(m=>m()),a.forEach(m=>m.remove()),we.delete(e),c.forEach(m=>G.delete(m)),e.classList.remove("nojs-split"),e.removeAttribute("data-direction")})}})}function bi(t,e){t.__disposers=t.__disposers||[],t.__disposers.push(e)}function En(t){t.directive("pane",{priority:15,init(e,r,o){nt(),e.classList.add("nojs-pane"),G.has(e)||G.set(e,{size:o||null,min:parseInt(e.getAttribute("pane-min"),10)||0,max:parseInt(e.getAttribute("pane-max"),10)||1/0,collapsible:e.getAttribute("pane-collapsible")==="true",collapsed:!1,preCollapseSize:null});let n=G.get(e),i=e.closest("[data-direction='vertical']")?"height":"width";n.min&&(e.style[`min${i==="width"?"Width":"Height"}`]=`${n.min}px`),n.max&&n.max!==1/0&&(e.style[`max${i==="width"?"Width":"Height"}`]=`${n.max}px`),bi(e,()=>{e.classList.remove("nojs-pane"),G.delete(e),e.style.removeProperty("min-width"),e.style.removeProperty("min-height"),e.style.removeProperty("max-width"),e.style.removeProperty("max-height"),e.style.removeProperty("flex-basis"),e.style.removeProperty("flex-grow")})}})}function _n(t,e={}){xn(t),En(t)}function wn(){hn()}var fe={sorts:new Map};function An(){fe.sorts.clear()}function Ae(){if(typeof document>"u"||document.querySelector("style[data-nojs-table]"))return;let t=` +`.trim(),e=document.createElement("style");e.setAttribute("data-nojs-split",""),e.textContent=t,document.head.appendChild(e)}function ki(t,e){t.__disposers=t.__disposers||[],t.__disposers.push(e)}function jn(t){return t==="horizontal"?"clientX":"clientY"}function Q(t,e){let r=t.getBoundingClientRect?t.getBoundingClientRect():null,o=r&&(e==="horizontal"?r.width:r.height);return o||(e==="horizontal"?t.offsetWidth:t.offsetHeight)}function Ln(t,e){if(e!=="horizontal")return 1;try{return(t.closest&&t.closest("[dir]")?.getAttribute("dir")||(typeof getComputedStyle=="function"?getComputedStyle(t).direction:""))==="rtl"?-1:1}catch{return 1}}function Ci(t,e){let o=(je.get(t)?.gutters||[]).reduce((n,i)=>n+Q(i,e),0);return Q(t,e)-o}function Si(t,e){if(!t)return null;let r=parseFloat(t);return Number.isNaN(r)?null:typeof t=="string"&&t.trim().endsWith("%")?r/100*e:r}function Ge(t,e){let r=G.get(e);return r?r.min!=null&&t r.max?r.max:t:t}function ct(t,e,r,o){let n=Q(e,o),i=Q(r,o),c=G.get(e),s=G.get(r);t.setAttribute("aria-valuenow",Math.round(n)),t.setAttribute("aria-valuemin",c?.min||0),t.setAttribute("aria-valuemax",Math.round(n+i-(s?.min||0)))}function Mt(t){let e=t.getAttribute("split-persist");if(!e)return;let r=je.get(t);if(!r)return;let o=r.panes.map(n=>n.style.flexBasis||"");try{localStorage.setItem(`nojs-split:${e}`,JSON.stringify(o))}catch{}}function Di(t){let e=t.getAttribute("split-persist");if(!e)return!1;try{let r=localStorage.getItem(`nojs-split:${e}`);if(!r)return!1;let o=JSON.parse(r),n=je.get(t);return!n||o.length!==n.panes.length?!1:(o.forEach((i,c)=>{i&&(n.panes[c].style.flexBasis=i,n.panes[c].style.flexGrow="0")}),!0)}catch{return!1}}function Ti(t,e,r,o,n){let i=document.createElement("div");i.className="nojs-gutter",i.setAttribute("role","separator"),i.setAttribute("tabindex","0"),i.setAttribute("aria-orientation",e==="horizontal"?"vertical":"horizontal"),i.setAttribute("aria-label","Resize"),n!==6&&i.style.setProperty("--nojs-gutter-size",`${n}px`);let c=p=>{if(p.button!==0)return;p.preventDefault();let l=Ci(t,e);T.active=!0,T.splitEl=t,T.gutterEl=i,T.prevPane=r,T.nextPane=o,T.direction=e,T.startPos=p[jn(e)],T.startPrevSize=Q(r,e),T.startNextSize=Q(o,e),T.containerSize=l,T.sign=Ln(t,e),document.body.style.cursor=e==="horizontal"?"col-resize":"row-resize",document.body.style.userSelect="none",i.setPointerCapture(p.pointerId)},s=p=>{if(!T.active||T.gutterEl!==i)return;let l=(p[jn(T.direction)]-T.startPos)*(T.sign||1),b=Ge(T.startPrevSize+l,T.prevPane),h=Ge(T.startNextSize-l,T.nextPane),m=T.startPrevSize+T.startNextSize;b+h!==m&&(b!==T.startPrevSize+l?h=m-b:b=m-h),T.prevPane.style.flexBasis=`${b}px`,T.prevPane.style.flexGrow="0",T.nextPane.style.flexBasis=`${h}px`,T.nextPane.style.flexGrow="0",ct(i,T.prevPane,T.nextPane,T.direction)},a=()=>{!T.active||T.gutterEl!==i||(T.active=!1,document.body.style.cursor="",document.body.style.userSelect="",Mt(t),t.dispatchEvent(new CustomEvent("split-resize",{bubbles:!0,detail:{prevPane:r,nextPane:o}})))};i.addEventListener("pointerdown",c),i.addEventListener("pointermove",s),i.addEventListener("pointerup",a),i.addEventListener("pointercancel",a);let d=10,g=p=>{let l=e==="horizontal",b=Ln(t,e),h=0;if(l&&p.key==="ArrowRight"||!l&&p.key==="ArrowDown")h=d*b;else if(l&&p.key==="ArrowLeft"||!l&&p.key==="ArrowUp")h=-d*b;else if(p.key==="Home")h=(G.get(r)?.min||0)-Q(r,e);else if(p.key==="End"){let E=G.get(o);h=Q(r,e)+Q(o,e)-(E?.min||0)-Q(r,e)}else return;p.preventDefault();let m=Q(r,e),v=Q(o,e),y=m+v,x=Ge(m+h,r),j=Ge(y-x,o);x=y-j,x=Ge(x,r),j=y-x,r.style.flexBasis=`${x}px`,r.style.flexGrow="0",o.style.flexBasis=`${j}px`,o.style.flexGrow="0",ct(i,r,o,e),Mt(t)};i.addEventListener("keydown",g);let u=()=>{let p=G.get(r),l=G.get(o),b=p?.collapsible?r:l?.collapsible?o:null;if(!b)return;let h=G.get(b);if(!h)return;let m=b===r?o:r,v=Q(r,e)+Q(o,e);if(h.collapsed){h.collapsed=!1,b.removeAttribute("data-collapsed");let y=h.preCollapseSize||`${Math.round(v/2)}px`,x=Si(y,v)??v/2,j=Math.min(x,v);b.style.flexBasis=`${j}px`,b.style.flexGrow="0",m.style.flexBasis=`${v-j}px`,m.style.flexGrow="0"}else h.preCollapseSize=b.style.flexBasis||`${Q(b,e)}px`,h.collapsed=!0,b.setAttribute("data-collapsed","true"),b.style.flexBasis="0px",b.style.flexGrow="0",m.style.flexBasis=`${v}px`,m.style.flexGrow="0";ct(i,r,o,e),Mt(t),t.dispatchEvent(new CustomEvent("split-collapse",{bubbles:!0,detail:{pane:b,collapsed:h.collapsed}}))};return i.addEventListener("dblclick",u),{gutter:i,cleanup:()=>{i.removeEventListener("pointerdown",c),i.removeEventListener("pointermove",s),i.removeEventListener("pointerup",a),i.removeEventListener("pointercancel",a),i.removeEventListener("keydown",g),i.removeEventListener("dblclick",u)}}}function kn(t){t.directive("split",{priority:14,init(e,r,o){at();let n=(o||"horizontal").trim()==="vertical"?"vertical":"horizontal",i=parseInt(e.getAttribute("split-gutter"),10)||6;e.classList.add("nojs-split"),e.setAttribute("data-direction",n);let c=Array.from(e.children).filter(g=>g.hasAttribute("pane"));if(c.length<2){console.warn(`[split] Container requires at least 2 [pane] children, found ${c.length}.`);return}c.forEach(g=>{G.get(g)||G.set(g,{size:g.getAttribute("pane")||null,min:parseInt(g.getAttribute("pane-min"),10)||0,max:parseInt(g.getAttribute("pane-max"),10)||1/0,collapsible:g.getAttribute("pane-collapsible")==="true",collapsed:!1,preCollapseSize:null})});let s=[],a=[];for(let g=0;g {let f=G.get(g)?.size;f?(g.style.flexBasis=f,g.style.flexGrow="0"):(g.style.flexGrow="1",g.style.flexBasis="0")}),requestAnimationFrame(()=>{s.forEach((g,u)=>{ct(g,c[u],c[u+1],n)})}),ki(e,()=>{a.forEach(g=>g()),s.forEach(g=>g.remove()),je.delete(e),c.forEach(g=>G.delete(g)),e.classList.remove("nojs-split"),e.removeAttribute("data-direction")})}})}function Ii(t,e){t.__disposers=t.__disposers||[],t.__disposers.push(e)}function Cn(t){t.directive("pane",{priority:15,init(e,r,o){at(),e.classList.add("nojs-pane"),G.has(e)||G.set(e,{size:o||null,min:parseInt(e.getAttribute("pane-min"),10)||0,max:parseInt(e.getAttribute("pane-max"),10)||1/0,collapsible:e.getAttribute("pane-collapsible")==="true",collapsed:!1,preCollapseSize:null});let n=G.get(e),i=e.closest("[data-direction='vertical']")?"height":"width";n.min&&(e.style[`min${i==="width"?"Width":"Height"}`]=`${n.min}px`),n.max&&n.max!==1/0&&(e.style[`max${i==="width"?"Width":"Height"}`]=`${n.max}px`),Ii(e,()=>{e.classList.remove("nojs-pane"),G.delete(e),e.style.removeProperty("min-width"),e.style.removeProperty("min-height"),e.style.removeProperty("max-width"),e.style.removeProperty("max-height"),e.style.removeProperty("flex-basis"),e.style.removeProperty("flex-grow")})}})}function Sn(t,e={}){kn(t),Cn(t)}function Dn(){wn()}var fe={sorts:new Map};function Tn(){fe.sorts.clear()}function Le(){if(typeof document>"u"||document.querySelector("style[data-nojs-table]"))return;let t=` .nojs-sortable th[data-sortable] { cursor: pointer; user-select: none; @@ -607,7 +607,7 @@ var mt=Object.defineProperty;var ho=Object.getOwnPropertyDescriptor;var vo=Objec [table-reorder-handle] { cursor: grab; } -`.trim(),e=document.createElement("style");e.setAttribute("data-nojs-table",""),e.textContent=t,document.head.appendChild(e)}function hi(t,e){t.__disposers=t.__disposers||[],t.__disposers.push(e)}function vi(t,e){let r=t.querySelector("tbody");if(!r)return null;let o=r.querySelector(":scope > [each]")||r.querySelector(":scope > [foreach]")||r.querySelector(":scope > [for]");if(!o)return null;let n=o.getAttribute("each")||o.getAttribute("foreach")||o.getAttribute("for");if(!n)return null;let i=n.match(/^\s*(\w+)\s+(?:in|of)\s+(.+)\s*$/);return i?{iteratorVar:i[1],arrayPath:i[2].trim()}:null}function yi(t,e){let r=e.split("."),o=t;for(let n of r){if(o==null)return;o=o[n]}return o}function jn(t,e,r){let o=e.split("."),n=t;for(let i=0;i e?1:0}function Cn(t,e,r){if(t==null&&e==null)return 0;if(t==null)return-1;if(e==null)return 1;switch(r){case"number":return Ln(Number(t),Number(e));case"date":return Ln(new Date(t).getTime(),new Date(e).getTime());default:return String(t).localeCompare(String(e))}}function xi(t){let e=t.querySelectorAll("th[data-sortable]");for(let r of e)r.removeAttribute("data-sort-dir"),r.setAttribute("aria-sort","none")}function Sn(t){t.directive("sortable",{priority:10,init(e){Ae(),e.classList.add("nojs-sortable")}})}function Tn(t){t.directive("sort",{priority:11,init(e,r,o){Ae();let n=o;if(!n)return;let i=e.getAttribute("sort-type")||"string",c=e.getAttribute("sort-default");e.setAttribute("data-sortable",""),e.setAttribute("aria-sort","none"),e.getAttribute("tabindex")||e.setAttribute("tabindex","0");let a=e.closest("table");if(!a)return;fe.sorts.has(a)||fe.sorts.set(a,{column:null,direction:null}),(c==="asc"||c==="desc")&&(fe.sorts.get(a).column||kn(e,a,n,i,c,t));let s=()=>{let m=fe.sorts.get(a),l;m.column!==n?l="asc":m.direction==="asc"?l="desc":m.direction==="desc"?l=null:l="asc",kn(e,a,n,i,l,t)},d=m=>{(m.key==="Enter"||m.key===" ")&&(m.preventDefault(),s())};e.addEventListener("click",s),e.addEventListener("keydown",d),hi(e,()=>{e.removeEventListener("click",s),e.removeEventListener("keydown",d),a&&!a.isConnected&&(fe.sorts.delete(a),delete a._nojsOriginalOrder,delete a._nojsOriginalRows)})}})}function kn(t,e,r,o,n,i){let c=fe.sorts.get(e);xi(e),n?(t.setAttribute("data-sort-dir",n),t.setAttribute("aria-sort",n==="asc"?"ascending":"descending"),c.column=r,c.direction=n):(c.column=null,c.direction=null);let a=vi(e,i);if(a){let s=i.findContext(e),d=s?yi(s,a.arrayPath):null;if(Array.isArray(d)){if(!n){let l=e._nojsOriginalOrder;if(l){let f=new Set(d),u=l.filter(p=>f.has(p));for(let p of d)l.includes(p)||u.push(p);jn(s,a.arrayPath,u)}return}e._nojsOriginalOrder||(e._nojsOriginalOrder=[...d]);let m=[...d].sort((l,f)=>{let u=l!=null?l[r]:null,p=f!=null?f[r]:null,v=Cn(u,p,o);return n==="desc"?-v:v});jn(s,a.arrayPath,m);return}}Ei(e,t,r,o,n)}function Ei(t,e,r,o,n){let i=t.querySelector("tbody");if(!i)return;let s=[...e.closest("tr").children].indexOf(e);if(s<0)return;let d=[...i.querySelectorAll(":scope > tr")];if(t._nojsOriginalRows||(t._nojsOriginalRows=[...d]),!n){let f=document.createDocumentFragment();for(let u of t._nojsOriginalRows)f.appendChild(u);i.appendChild(f);return}let m=f=>{let u=f.replace(/[^0-9.\-]/g,"");return u===""||u==="-"?NaN:parseFloat(u)};d.sort((f,u)=>{let p=f.children[s]?.textContent?.trim()||"",v=u.children[s]?.textContent?.trim()||"",h=Cn(o==="number"?m(p):p,o==="number"?m(v):v,o);return n==="desc"?-h:h});let l=document.createDocumentFragment();for(let f of d)l.appendChild(f);i.appendChild(l)}function Dn(t){t.directive("fixed-header",{priority:10,init(e){Ae(),e.classList.add("nojs-fixed-header")}})}function In(t){t.directive("fixed-col",{priority:10,init(e){Ae(),e.classList.add("nojs-fixed-col")}})}function Bt(t,e){t.__disposers=t.__disposers||[],t.__disposers.push(e)}function Hn(t){let e=t.querySelector("tbody");if(!e)return null;let r=e.querySelector(":scope > [each]")||e.querySelector(":scope > [foreach]")||e.querySelector(":scope > [for]");if(!r)return null;let o=r.getAttribute("each")||r.getAttribute("foreach")||r.getAttribute("for");if(!o)return null;let n=o.match(/^\s*(\w+)\s+(?:in|of)\s+(.+)\s*$/);return n?{iteratorVar:n[1],arrayPath:n[2].trim(),eachEl:r}:null}function Bn(t,e){let r=e.split("."),o=t;for(let n of r){if(o==null)return;o=o[n]}return o}function $n(t,e,r){let o=e.split("."),n=t;for(let i=0;i tr");for(let g=0;g {E=!!S.target.closest(n)};b.addEventListener("mousedown",j),Bt(b,()=>b.removeEventListener("mousedown",j))}let y=j=>{if(n&&!E){j.preventDefault();return}a=[...r.querySelectorAll(":scope > tr")].indexOf(b),s=b,j.dataTransfer&&(j.dataTransfer.effectAllowed="move",j.dataTransfer.setData("text/plain","")),i.split(/\s+/).filter(Boolean).forEach(A=>b.classList.add(A))},_=j=>{if(s==null)return;j.preventDefault(),j.dataTransfer&&(j.dataTransfer.dropEffect="move");let S=b.getBoundingClientRect(),A=S.top+S.height/2,V=[...r.querySelectorAll(":scope > tr")].indexOf(b);l(),V!==a&&(j.clientY{b.classList.remove("nojs-reorder-insert-before"),b.classList.remove("nojs-reorder-insert-after"),d===b&&(d=null)},L=j=>{if(j.preventDefault(),j.stopPropagation(),s==null||a==null)return;let S=[...r.querySelectorAll(":scope > tr")],A=b.getBoundingClientRect(),$=A.top+A.height/2,V=S.indexOf(b);j.clientY>=$&&V++;let X=a;if(X===V||X+1===V){f();return}let z=X {f()};b.addEventListener("dragstart",y),b.addEventListener("dragover",_),b.addEventListener("dragleave",x),b.addEventListener("drop",L),b.addEventListener("dragend",k),Bt(b,()=>{b.removeEventListener("dragstart",y),b.removeEventListener("dragover",_),b.removeEventListener("dragleave",x),b.removeEventListener("drop",L),b.removeEventListener("dragend",k),b._nojsReorderSetup=!1})}}function l(){d&&(d.classList.remove("nojs-reorder-insert-before"),d.classList.remove("nojs-reorder-insert-after"),d=null)}function f(){s&&i.split(/\s+/).filter(Boolean).forEach(g=>s.classList.remove(g)),l(),a=null,s=null;let h=r.querySelectorAll(":scope > tr");for(let g of h)g.classList.remove("nojs-reorder-insert-before"),g.classList.remove("nojs-reorder-insert-after"),c.split(/\s+/).filter(Boolean).forEach(b=>g.classList.remove(b))}let u=h=>{s!=null&&(h.preventDefault(),h.dataTransfer&&(h.dataTransfer.dropEffect="move"))},p=h=>{if(s==null||h.target!==r)return;h.preventDefault(),h.stopPropagation();let g=a,E=[...r.querySelectorAll(":scope > tr")].length-1;if(g===E){f();return}let y=Hn(e);if(y&&o){let _=Bn(o,y.arrayPath);if(Array.isArray(_)){let x=[..._],[L]=x.splice(g,1);x.push(L),$n(o,y.arrayPath,x),e._nojsOriginalOrder&&(e._nojsOriginalOrder=[...x]),e.dispatchEvent(new CustomEvent("table:reorder",{bubbles:!0,detail:{from:g,to:x.length-1,item:L}}))}}f()};r.addEventListener("dragover",u),r.addEventListener("drop",p);let v=new MutationObserver(()=>{m()});v.observe(r,{childList:!0}),m(),Bt(e,()=>{v.disconnect(),r.removeEventListener("dragover",u),r.removeEventListener("drop",p),f()})}})}function Mn(t,e={}){Sn(t),Tn(t),Dn(t),In(t),qn(t)}function Pn(){An()}var me={containers:new Map};function Rn(){for(let[,t]of me.containers)typeof t.unsub=="function"&&t.unsub();me.containers.clear()}function zn(){if(typeof document>"u"||document.querySelector("style[data-nojs-breadcrumb]"))return;let t=` +`.trim(),e=document.createElement("style");e.setAttribute("data-nojs-table",""),e.textContent=t,document.head.appendChild(e)}function Bi(t,e){t.__disposers=t.__disposers||[],t.__disposers.push(e)}function Hi(t,e){let r=t.querySelector("tbody");if(!r)return null;let o=r.querySelector(":scope > [each]")||r.querySelector(":scope > [foreach]")||r.querySelector(":scope > [for]");if(!o)return null;let n=o.getAttribute("each")||o.getAttribute("foreach")||o.getAttribute("for");if(!n)return null;let i=n.match(/^\s*(\w+)\s+(?:in|of)\s+(.+)\s*$/);return i?{iteratorVar:i[1],arrayPath:i[2].trim()}:null}function $i(t,e){let r=e.split("."),o=t;for(let n of r){if(o==null)return;o=o[n]}return o}function In(t,e,r){let o=e.split("."),n=t;for(let i=0;i e?1:0}function $n(t,e,r){if(t==null&&e==null)return 0;if(t==null)return-1;if(e==null)return 1;switch(r){case"number":return Bn(Number(t),Number(e));case"date":return Bn(new Date(t).getTime(),new Date(e).getTime());default:return String(t).localeCompare(String(e))}}function qi(t){let e=t.querySelectorAll("th[data-sortable]");for(let r of e)r.removeAttribute("data-sort-dir"),r.setAttribute("aria-sort","none")}function qn(t){t.directive("sortable",{priority:10,init(e){Le(),e.classList.add("nojs-sortable")}})}function Mn(t){t.directive("sort",{priority:11,init(e,r,o){Le();let n=o;if(!n)return;let i=e.getAttribute("sort-type")||"string",c=e.getAttribute("sort-default");e.setAttribute("data-sortable",""),e.setAttribute("aria-sort","none"),e.getAttribute("tabindex")||e.setAttribute("tabindex","0");let s=e.closest("table");if(!s)return;fe.sorts.has(s)||fe.sorts.set(s,{column:null,direction:null}),(c==="asc"||c==="desc")&&(fe.sorts.get(s).column||Hn(e,s,n,i,c,t));let a=()=>{let g=fe.sorts.get(s),u;g.column!==n?u="asc":g.direction==="asc"?u="desc":g.direction==="desc"?u=null:u="asc",Hn(e,s,n,i,u,t)},d=g=>{(g.key==="Enter"||g.key===" ")&&(g.preventDefault(),a())};e.addEventListener("click",a),e.addEventListener("keydown",d),Bi(e,()=>{e.removeEventListener("click",a),e.removeEventListener("keydown",d),s&&!s.isConnected&&(fe.sorts.delete(s),delete s._nojsOriginalOrder,delete s._nojsOriginalRows)})}})}function Hn(t,e,r,o,n,i){let c=fe.sorts.get(e);qi(e),n?(t.setAttribute("data-sort-dir",n),t.setAttribute("aria-sort",n==="asc"?"ascending":"descending"),c.column=r,c.direction=n):(c.column=null,c.direction=null);let s=Hi(e,i);if(s){let a=i.findContext(e),d=a?$i(a,s.arrayPath):null;if(Array.isArray(d)){if(!n){let u=e._nojsOriginalOrder;if(u){let f=new Set(d),p=u.filter(l=>f.has(l));for(let l of d)u.includes(l)||p.push(l);In(a,s.arrayPath,p)}return}e._nojsOriginalOrder||(e._nojsOriginalOrder=[...d]);let g=[...d].sort((u,f)=>{let p=u!=null?u[r]:null,l=f!=null?f[r]:null,b=$n(p,l,o);return n==="desc"?-b:b});In(a,s.arrayPath,g);return}}Mi(e,t,r,o,n)}function Mi(t,e,r,o,n){let i=t.querySelector("tbody");if(!i)return;let a=[...e.closest("tr").children].indexOf(e);if(a<0)return;let d=[...i.querySelectorAll(":scope > tr")];if(t._nojsOriginalRows||(t._nojsOriginalRows=[...d]),!n){let f=document.createDocumentFragment();for(let p of t._nojsOriginalRows)f.appendChild(p);i.appendChild(f);return}let g=f=>{let p=f.replace(/[^0-9.\-]/g,"");return p===""||p==="-"?NaN:parseFloat(p)};d.sort((f,p)=>{let l=f.children[a]?.textContent?.trim()||"",b=p.children[a]?.textContent?.trim()||"",h=$n(o==="number"?g(l):l,o==="number"?g(b):b,o);return n==="desc"?-h:h});let u=document.createDocumentFragment();for(let f of d)u.appendChild(f);i.appendChild(u)}function Pn(t){t.directive("fixed-header",{priority:10,init(e){Le(),e.classList.add("nojs-fixed-header")}})}function Rn(t){t.directive("fixed-col",{priority:10,init(e){Le(),e.classList.add("nojs-fixed-col")}})}function Pt(t,e){t.__disposers=t.__disposers||[],t.__disposers.push(e)}function zn(t){let e=t.querySelector("tbody");if(!e)return null;let r=e.querySelector(":scope > [each]")||e.querySelector(":scope > [foreach]")||e.querySelector(":scope > [for]");if(!r)return null;let o=r.getAttribute("each")||r.getAttribute("foreach")||r.getAttribute("for");if(!o)return null;let n=o.match(/^\s*(\w+)\s+(?:in|of)\s+(.+)\s*$/);return n?{iteratorVar:n[1],arrayPath:n[2].trim(),eachEl:r}:null}function Fn(t,e){let r=e.split("."),o=t;for(let n of r){if(o==null)return;o=o[n]}return o}function On(t,e,r){let o=e.split("."),n=t;for(let i=0;i tr");for(let m=0;m {y=!!C.target.closest(n)};v.addEventListener("mousedown",A),Pt(v,()=>v.removeEventListener("mousedown",A))}let x=A=>{if(n&&!y){A.preventDefault();return}s=[...r.querySelectorAll(":scope > tr")].indexOf(v),a=v,A.dataTransfer&&(A.dataTransfer.effectAllowed="move",A.dataTransfer.setData("text/plain","")),i.split(/\s+/).filter(Boolean).forEach(D=>v.classList.add(D))},j=A=>{if(a==null)return;A.preventDefault(),A.dataTransfer&&(A.dataTransfer.dropEffect="move");let C=v.getBoundingClientRect(),D=C.top+C.height/2,k=[...r.querySelectorAll(":scope > tr")].indexOf(v);u(),k!==s&&(A.clientY {v.classList.remove("nojs-reorder-insert-before"),v.classList.remove("nojs-reorder-insert-after"),d===v&&(d=null)},L=A=>{if(A.preventDefault(),A.stopPropagation(),a==null||s==null)return;let C=[...r.querySelectorAll(":scope > tr")],D=v.getBoundingClientRect(),H=D.top+D.height/2,k=C.indexOf(v);A.clientY>=H&&k++;let U=s;if(U===k||U+1===k){f();return}let V=U {f()};v.addEventListener("dragstart",x),v.addEventListener("dragover",j),v.addEventListener("dragleave",E),v.addEventListener("drop",L),v.addEventListener("dragend",w),Pt(v,()=>{v.removeEventListener("dragstart",x),v.removeEventListener("dragover",j),v.removeEventListener("dragleave",E),v.removeEventListener("drop",L),v.removeEventListener("dragend",w),v._nojsReorderSetup=!1})}}function u(){d&&(d.classList.remove("nojs-reorder-insert-before"),d.classList.remove("nojs-reorder-insert-after"),d=null)}function f(){a&&i.split(/\s+/).filter(Boolean).forEach(m=>a.classList.remove(m)),u(),s=null,a=null;let h=r.querySelectorAll(":scope > tr");for(let m of h)m.classList.remove("nojs-reorder-insert-before"),m.classList.remove("nojs-reorder-insert-after"),c.split(/\s+/).filter(Boolean).forEach(v=>m.classList.remove(v))}let p=h=>{a!=null&&(h.preventDefault(),h.dataTransfer&&(h.dataTransfer.dropEffect="move"))},l=h=>{if(a==null||h.target!==r)return;h.preventDefault(),h.stopPropagation();let m=s,y=[...r.querySelectorAll(":scope > tr")].length-1;if(m===y){f();return}let x=zn(e);if(x&&o){let j=Fn(o,x.arrayPath);if(Array.isArray(j)){let E=[...j],[L]=E.splice(m,1);E.push(L),On(o,x.arrayPath,E),e._nojsOriginalOrder&&(e._nojsOriginalOrder=[...E]),e.dispatchEvent(new CustomEvent("table:reorder",{bubbles:!0,detail:{from:m,to:E.length-1,item:L}}))}}f()};r.addEventListener("dragover",p),r.addEventListener("drop",l);let b=new MutationObserver(()=>{g()});b.observe(r,{childList:!0}),g(),Pt(e,()=>{b.disconnect(),r.removeEventListener("dragover",p),r.removeEventListener("drop",l),f()})}})}function Wn(t,e={}){qn(t),Mn(t),Pn(t),Rn(t),Vn(t)}function Nn(){Tn()}var me={containers:new Map};function Gn(){for(let[,t]of me.containers)typeof t.unsub=="function"&&t.unsub();me.containers.clear()}function Un(){if(typeof document>"u"||document.querySelector("style[data-nojs-breadcrumb]"))return;let t=` .nojs-breadcrumb { display: flex; align-items: center; @@ -643,7 +643,7 @@ var mt=Object.defineProperty;var ho=Object.getOwnPropertyDescriptor;var vo=Objec font-weight: 500; pointer-events: none; } -`.trim(),e=document.createElement("style");e.setAttribute("data-nojs-breadcrumb",""),e.textContent=t,document.head.appendChild(e)}function Fn(t,e){t.__disposers=t.__disposers||[],t.__disposers.push(e)}function _i(t){let e=t.getAttribute("breadcrumb");if(e&&e.trim()!=="")return e.trim();let r=t.getAttribute("title");return r&&r.trim()!==""?r.trim():(t.textContent||"").trim()}function wi(t){return t&&t.charAt(0).toUpperCase()+t.slice(1)}function On(t,e){let r=t.querySelector("ol.nojs-breadcrumb");r&&r.remove();let o=document.createElement("ol");o.classList.add("nojs-breadcrumb");for(let i=0;i !(a.tagName==="OL"&&a.classList.contains("nojs-breadcrumb"))),i=t.router,c=!n&&i;if(me.containers.set(e,{unsub:null,crumbs:[]}),c){let a=()=>{let s=i.current,d=s?s.path:"/",m=ji(d);On(e,m)};if(a(),typeof i.on=="function"){let s=i.on(a),d=me.containers.get(e);d&&(d.unsub=s),Fn(e,()=>{typeof s=="function"&&s();let m=me.containers.get(e);m&&(m.unsub=null)})}}else{let a=Ai(e);for(let s of Array.from(e.children))s.tagName==="OL"&&s.classList.contains("nojs-breadcrumb")||(s.style.display="none");On(e,a)}Fn(e,()=>{me.containers.delete(e)})}})}function Nn(t,e={}){Vn(t)}function Wn(){Rn()}var it={containers:new Map};function Un(){it.containers.clear()}function Gn(){if(typeof document>"u"||document.querySelector("style[data-nojs-accordion]"))return;let t=` +`.trim(),e=document.createElement("style");e.setAttribute("data-nojs-breadcrumb",""),e.textContent=t,document.head.appendChild(e)}function Yn(t,e){t.__disposers=t.__disposers||[],t.__disposers.push(e)}function Pi(t){let e=t.getAttribute("breadcrumb");if(e&&e.trim()!=="")return e.trim();let r=t.getAttribute("title");return r&&r.trim()!==""?r.trim():(t.textContent||"").trim()}function Ri(t){return t&&t.charAt(0).toUpperCase()+t.slice(1)}function Kn(t,e){let r=t.querySelector("ol.nojs-breadcrumb");r&&r.remove();let o=document.createElement("ol");o.classList.add("nojs-breadcrumb");for(let i=0;i !(s.tagName==="OL"&&s.classList.contains("nojs-breadcrumb"))),i=t.router,c=!n&&i;if(me.containers.set(e,{unsub:null,crumbs:[]}),c){let s=()=>{let a=i.current,d=a?a.path:"/",g=Fi(d);Kn(e,g)};if(s(),typeof i.on=="function"){let a=i.on(s),d=me.containers.get(e);d&&(d.unsub=a),Yn(e,()=>{typeof a=="function"&&a();let g=me.containers.get(e);g&&(g.unsub=null)})}}else{let s=zi(e);for(let a of Array.from(e.children))a.tagName==="OL"&&a.classList.contains("nojs-breadcrumb")||(a.style.display="none");Kn(e,s)}Yn(e,()=>{me.containers.delete(e)})}})}function Zn(t,e={}){Xn(t)}function Qn(){Gn()}var dt={containers:new Map};function Jn(){dt.containers.clear()}function eo(){if(typeof document>"u"||document.querySelector("style[data-nojs-accordion]"))return;let t=` [accordion] { display: flex; flex-direction: column; @@ -686,7 +686,7 @@ var mt=Object.defineProperty;var ho=Object.getOwnPropertyDescriptor;var vo=Objec [accordion] > details > summary::marker { content: none; } -`.trim(),e=document.createElement("style");e.setAttribute("data-nojs-accordion",""),e.textContent=t,document.head.appendChild(e)}function Li(t,e){t.__disposers=t.__disposers||[],t.__disposers.push(e)}var st=null;function ki(){return st!==null||(st=typeof CSS<"u"&&typeof CSS.supports=="function"&&CSS.supports("interpolate-size","allow-keywords")),st}function Yn(t){let e=t.querySelector(":scope > summary");if(!e)return null;let r=t.querySelector(":scope > .nojs-accordion-content");if(r)return r;r=document.createElement("div"),r.classList.add("nojs-accordion-content");let o=Array.from(t.children),n=!1;for(let i of o){if(i===e){n=!0;continue}n&&r.appendChild(i)}return t.appendChild(r),r}function Ci(t,e){if(!e)return;let r=e.scrollHeight;e.style.height="0px",t.open=!0,requestAnimationFrame(()=>{e.style.height=r+"px";let o=()=>{e.style.height="",e.removeEventListener("transitionend",o)};e.addEventListener("transitionend",o)})}function Xn(t,e){if(!e){t.open=!1;return}let r=e.scrollHeight;e.style.height=r+"px",requestAnimationFrame(()=>{e.style.height="0px";let o=()=>{t.open=!1,e.style.height="",e.removeEventListener("transitionend",o)};e.addEventListener("transitionend",o)})}function Kn(t,e){if(t.open)if(e){let r=t.querySelector(":scope > .nojs-accordion-content");Xn(t,r)}else t.open=!1}function at(t,e,r,o){let n=new CustomEvent("nojs:accordion-change",{bubbles:!0,detail:{element:e,open:r,index:o}});t.dispatchEvent(n)}function Be(t){let e=[];for(let r of t.children)r.tagName==="DETAILS"&&e.push(r);return e}function Zn(t){t.directive("accordion",{priority:10,init(e,r,o){Gn();let n=(o||"").trim().toLowerCase()==="multi"?"multi":"single",i=!ki();e.setAttribute("role","group");let c=Be(e);if(c.length===0)return;if(i)for(let f of c)Yn(f);let a=[],s=new MutationObserver(f=>{for(let u of f)for(let p of u.addedNodes)p.nodeType!==1||p.tagName!=="DETAILS"||p.parentElement===e&&m(p)});s.observe(e,{childList:!0});let d=0,m=f=>{i&&Yn(f);let u=f.querySelector(":scope > summary");if(u){let h=`nojs-accordion-panel-${Date.now()}-${d++}`,g=f.querySelector(":scope > .nojs-accordion-content");g?(g.id=g.id||h,g.setAttribute("role","region"),h=g.id):(f.id||(f.id=h),h=f.id),u.setAttribute("aria-expanded",f.open?"true":"false"),u.setAttribute("aria-controls",h)}let p=h=>{let g=Be(e),b=g.indexOf(f),E=f.querySelector(":scope > summary");if(E&&E.setAttribute("aria-expanded",f.open?"true":"false"),f.open){if(n==="single")for(let y of g)y!==f&&y.open&&Kn(y,i);at(e,f,!0,b)}else at(e,f,!1,b)},v=null;if(i){let h=f.querySelector(":scope > summary");h&&(v=g=>{g.preventDefault();let b=f.querySelector(":scope > .nojs-accordion-content");if(f.open)Xn(f,b),h.setAttribute("aria-expanded","false"),at(e,f,!1,Be(e).indexOf(f));else{if(n==="single"){let E=Be(e);for(let y of E)if(y!==f&&y.open){Kn(y,!0);let _=y.querySelector(":scope > summary");_&&_.setAttribute("aria-expanded","false")}}Ci(f,b),h.setAttribute("aria-expanded","true"),at(e,f,!0,Be(e).indexOf(f))}},h.addEventListener("click",v))}f.addEventListener("toggle",p),a.push({details:f,toggleHandler:p,clickHandler:v})};for(let f of c)m(f);let l=f=>{let u=f.target;if(u.tagName!=="SUMMARY")return;let p=u.parentElement;if(!p||p.parentElement!==e)return;let h=Be(e).map(E=>E.querySelector(":scope > summary")).filter(Boolean),g=h.indexOf(u);if(g===-1)return;let b=-1;switch(f.key){case"ArrowDown":case"ArrowRight":b=(g+1)%h.length;break;case"ArrowUp":case"ArrowLeft":b=(g-1+h.length)%h.length;break;case"Home":b=0;break;case"End":b=h.length-1;break;default:return}b!==-1&&b!==g&&(f.preventDefault(),h[b].focus())};e.addEventListener("keydown",l),it.containers.set(e,{mode:n,listeners:a,observer:s}),Li(e,()=>{e.removeEventListener("keydown",l),s.disconnect();for(let f of a)if(f.details.removeEventListener("toggle",f.toggleHandler),f.clickHandler){let u=f.details.querySelector(":scope > summary");u&&u.removeEventListener("click",f.clickHandler)}a.length=0,it.containers.delete(e)})}})}function Qn(t,e={}){Zn(t)}function Jn(){Un()}var $e=new Map;function eo(){let t=Array.from($e.keys());for(let e of t){let r=$e.get(e);if(r){if(r.resizeObserver){try{r.resizeObserver.disconnect()}catch{}r.resizeObserver=null}if(r.scrollHandler){try{e.removeEventListener("scroll",r.scrollHandler)}catch{}r.scrollHandler=null}if(r.spacerTop&&r.spacerTop.parentNode&&r.spacerTop.remove(),r.spacerBottom&&r.spacerBottom.parentNode&&r.spacerBottom.remove(),r.renderedNodes){for(let[o,n]of r.renderedNodes){if(n.__disposers){for(let i of n.__disposers)try{i()}catch{}n.__disposers=null}n.parentNode&&n.remove()}r.renderedNodes.clear()}r.disposed=!0}}$e.clear()}function to(){if(typeof document>"u"||document.querySelector("style[data-nojs-virtual-list]"))return;let t=` +`.trim(),e=document.createElement("style");e.setAttribute("data-nojs-accordion",""),e.textContent=t,document.head.appendChild(e)}function Oi(t,e){t.__disposers=t.__disposers||[],t.__disposers.push(e)}var lt=null;function Vi(){return lt!==null||(lt=typeof CSS<"u"&&typeof CSS.supports=="function"&&CSS.supports("interpolate-size","allow-keywords")),lt}function to(t){let e=t.querySelector(":scope > summary");if(!e)return null;let r=t.querySelector(":scope > .nojs-accordion-content");if(r)return r;r=document.createElement("div"),r.classList.add("nojs-accordion-content");let o=Array.from(t.children),n=!1;for(let i of o){if(i===e){n=!0;continue}n&&r.appendChild(i)}return t.appendChild(r),r}function Wi(t,e){if(!e)return;let r=e.scrollHeight;e.style.height="0px",t.open=!0,requestAnimationFrame(()=>{e.style.height=r+"px";let o=()=>{e.style.height="",e.removeEventListener("transitionend",o)};e.addEventListener("transitionend",o)})}function no(t,e){if(!e){t.open=!1;return}let r=e.scrollHeight;e.style.height=r+"px",requestAnimationFrame(()=>{e.style.height="0px";let o=()=>{t.open=!1,e.style.height="",e.removeEventListener("transitionend",o)};e.addEventListener("transitionend",o)})}function ro(t,e){if(t.open)if(e){let r=t.querySelector(":scope > .nojs-accordion-content");no(t,r)}else t.open=!1}function ut(t,e,r,o){let n=new CustomEvent("nojs:accordion-change",{bubbles:!0,detail:{element:e,open:r,index:o}});t.dispatchEvent(n)}function Me(t){let e=[];for(let r of t.children)r.tagName==="DETAILS"&&e.push(r);return e}function oo(t){t.directive("accordion",{priority:10,init(e,r,o){eo();let n=(o||"").trim().toLowerCase()==="multi"?"multi":"single",i=!Vi();e.setAttribute("role","group");let c=Me(e);if(c.length===0)return;if(i)for(let f of c)to(f);let s=[],a=new MutationObserver(f=>{for(let p of f)for(let l of p.addedNodes)l.nodeType!==1||l.tagName!=="DETAILS"||l.parentElement===e&&g(l)});a.observe(e,{childList:!0});let d=0,g=f=>{i&&to(f);let p=f.querySelector(":scope > summary");if(p){let h=`nojs-accordion-panel-${Date.now()}-${d++}`,m=f.querySelector(":scope > .nojs-accordion-content");m?(m.id=m.id||h,m.setAttribute("role","region"),h=m.id):(f.id||(f.id=h),h=f.id),p.setAttribute("aria-expanded",f.open?"true":"false"),p.setAttribute("aria-controls",h)}let l=h=>{let m=Me(e),v=m.indexOf(f),y=f.querySelector(":scope > summary");if(y&&y.setAttribute("aria-expanded",f.open?"true":"false"),f.open){if(n==="single")for(let x of m)x!==f&&x.open&&ro(x,i);ut(e,f,!0,v)}else ut(e,f,!1,v)},b=null;if(i){let h=f.querySelector(":scope > summary");h&&(b=m=>{m.preventDefault();let v=f.querySelector(":scope > .nojs-accordion-content");if(f.open)no(f,v),h.setAttribute("aria-expanded","false"),ut(e,f,!1,Me(e).indexOf(f));else{if(n==="single"){let y=Me(e);for(let x of y)if(x!==f&&x.open){ro(x,!0);let j=x.querySelector(":scope > summary");j&&j.setAttribute("aria-expanded","false")}}Wi(f,v),h.setAttribute("aria-expanded","true"),ut(e,f,!0,Me(e).indexOf(f))}},h.addEventListener("click",b))}f.addEventListener("toggle",l),s.push({details:f,toggleHandler:l,clickHandler:b})};for(let f of c)g(f);let u=f=>{let p=f.target;if(p.tagName!=="SUMMARY")return;let l=p.parentElement;if(!l||l.parentElement!==e)return;let h=Me(e).map(y=>y.querySelector(":scope > summary")).filter(Boolean),m=h.indexOf(p);if(m===-1)return;let v=-1;switch(f.key){case"ArrowDown":case"ArrowRight":v=(m+1)%h.length;break;case"ArrowUp":case"ArrowLeft":v=(m-1+h.length)%h.length;break;case"Home":v=0;break;case"End":v=h.length-1;break;default:return}v!==-1&&v!==m&&(f.preventDefault(),h[v].focus())};e.addEventListener("keydown",u),dt.containers.set(e,{mode:n,listeners:s,observer:a}),Oi(e,()=>{e.removeEventListener("keydown",u),a.disconnect();for(let f of s)if(f.details.removeEventListener("toggle",f.toggleHandler),f.clickHandler){let p=f.details.querySelector(":scope > summary");p&&p.removeEventListener("click",f.clickHandler)}s.length=0,dt.containers.delete(e)})}})}function io(t,e={}){oo(t)}function so(){Jn()}var Pe=new Map;function ao(){let t=Array.from(Pe.keys());for(let e of t){let r=Pe.get(e);if(r){if(r.resizeObserver){try{r.resizeObserver.disconnect()}catch{}r.resizeObserver=null}if(r.scrollHandler){try{e.removeEventListener("scroll",r.scrollHandler)}catch{}r.scrollHandler=null}if(r.spacerTop&&r.spacerTop.parentNode&&r.spacerTop.remove(),r.spacerBottom&&r.spacerBottom.parentNode&&r.spacerBottom.remove(),r.renderedNodes){for(let[o,n]of r.renderedNodes){if(n.__disposers){for(let i of n.__disposers)try{i()}catch{}n.__disposers=null}n.parentNode&&n.remove()}r.renderedNodes.clear()}r.disposed=!0}}Pe.clear()}function co(){if(typeof document>"u"||document.querySelector("style[data-nojs-virtual-list]"))return;let t=` [data-nojs-virtual] { overflow-y: auto; position: relative; @@ -717,10 +717,10 @@ dl[data-nojs-virtual] .nojs-virtual-spacer { display: list-item; list-style: none; } -`.trim(),e=document.createElement("style");e.setAttribute("data-nojs-virtual-list",""),e.textContent=t,document.head.appendChild(e)}function Si(t,e){t.__disposers=t.__disposers||[],t.__disposers.push(e)}function Ti(t){for(let e of t.children)for(let r of["each","foreach","for"])if(e.hasAttribute(r)){let o=Di(e.getAttribute(r));if(o)return{eachEl:e,...o}}return null}function Di(t){if(!t)return null;let e=t.match(/^\s*(\w+)\s+(?:in|of)\s+(.+)\s*$/);return e?{iteratorVar:e[1],arrayPath:e[2].trim()}:null}function Ii(t,e){let r=e.split("."),o=t;for(let n of r){if(o==null)return;o=o[n]}return o}function ro(t){let e=t.tagName.toLowerCase(),r;if(e==="tbody"||e==="table"||e==="thead"||e==="tfoot"){r=document.createElement("tr"),r.classList.add("nojs-virtual-spacer");let o=document.createElement("td"),n=e==="table"?t:t.closest("table"),i=n?n.querySelector("tr:not(.nojs-virtual-spacer)"):null,c=i?i.children.length:1;o.setAttribute("colspan",String(c)),o.style.padding="0",o.style.border="none",r.appendChild(o)}else e==="ul"||e==="ol"?(r=document.createElement("li"),r.classList.add("nojs-virtual-spacer"),r.style.listStyle="none"):(r=document.createElement("div"),r.classList.add("nojs-virtual-spacer"));return r.setAttribute("aria-hidden","true"),r.style.height="0px",r}function ct(t,e){if(t.tagName.toLowerCase()==="tr"){let r=t.querySelector("td");r&&(r.style.height=e+"px"),t.style.height=e+"px"}else t.style.height=e+"px"}function Hi(t,e){return t*e}function oo(t){let e=t.totalItems,r=new Array(e+1),o=t.estimatedHeight||50;r[0]=0;for(let n=1;n<=e;n++)r[n]=r[n-1]+(t.heights[n-1]||o);t.prefixSums=r}function io(t,e){let r=0,o=t.length-2;for(;r<=o;){let n=r+o>>>1;t[n]<=e?r=n+1:o=n-1}return Math.max(0,o)}function no(t){if(t.prefixSums&&t.prefixSums.length===t.totalItems+1)return t.prefixSums[t.totalItems];let e=0,r=t.estimatedHeight||50;for(let o=0;o e)return n;r+=i}return Math.max(0,t.totalItems-1)}function $i(t,e,r){if(t.prefixSums&&t.prefixSums.length===t.totalItems+1)return io(t.prefixSums,e+r);let o=e+r,n=0,i=t.estimatedHeight||50;for(let c=0;c =o)return c;return t.totalItems-1}function qi(t,e,r){if(t.totalItems===0)return{start:0,end:-1};let o,n;return t.itemHeight!=="auto"?(o=Math.floor(e/t.itemHeight),n=Math.ceil((e+r)/t.itemHeight)-1):(o=Bi(t,e),n=$i(t,e,r)),o=Math.max(0,o-t.buffer),n=Math.min(t.totalItems-1,n+t.buffer),{start:o,end:n}}function $t(t,e){if(t.disposed)return;let r=t.container,o=r,n=o.scrollTop,i=o.clientHeight,{start:c,end:a}=qi(t,n,i);if(c===t.startIndex&&a===t.endIndex&&!t.dirty)return;t.startIndex=c,t.endIndex=a,t.dirty=!1;let s=dt(t,c),d=t.itemHeight!=="auto"?Hi(t.totalItems,t.itemHeight):no(t),m=a>=0?dt(t,a+1):0,l=Math.max(0,d-m);ct(t.spacerTop,s),ct(t.spacerBottom,l);let f=new Set;for(let p=c;p<=a;p++)f.add(p);for(let[p,v]of t.renderedNodes)f.has(p)||(v.remove(),t.renderedNodes.delete(p));let u=[];for(let p=c;p<=a;p++){if(t.renderedNodes.has(p))continue;let v=t.dataArray[p];if(v===void 0)continue;let h=t.template.cloneNode(!0),g={};g[t.iteratorVar]=v,g.$index=p,g.$count=t.totalItems,g.$first=p===0,g.$last=p===t.totalItems-1,g.$even=p%2===0,g.$odd=p%2!==0,h.setAttribute("role","option"),h.setAttribute("aria-setsize",String(t.totalItems)),h.setAttribute("aria-posinset",String(p+1)),h.setAttribute("tabindex","-1"),h.__ctx=Object.create(e.findContext?e.findContext(r)||{}:{},Object.getOwnPropertyDescriptors(g)),h.__declared=!1,u.push({index:p,node:h}),t.renderedNodes.set(p,h)}if(u.length>0){u.sort((p,v)=>p.index-v.index);for(let{index:p,node:v}of u){let h=null;for(let[g,b]of t.renderedNodes)g>p&&b.parentNode===r&&(!h||g 0&&t.heights[v]!==g&&(t.heights[v]=g,p=!0)}if(p){oo(t);let v=no(t),h=dt(t,c),g=a>=0?dt(t,a+1):0,b=Math.max(0,v-g);ct(t.spacerTop,h),ct(t.spacerBottom,b)}}}function Mi(t,e){for(let[r,o]of e.renderedNodes)if(o===t)return r;return 1/0}function Pi(t,e,r){if(t.disposed)return;let o=t.container.scrollTop;t.dataArray=e||[],t.totalItems=t.dataArray.length,t.dirty=!0,t.itemHeight==="auto"&&t.heights.length>t.totalItems&&(t.heights.length=t.totalItems),t.itemHeight==="auto"&&oo(t);for(let[n,i]of t.renderedNodes){if(i.__disposers){for(let c of i.__disposers)try{c()}catch{}i.__disposers=null}i.remove()}t.renderedNodes.clear(),t.container.scrollTop=o,$t(t,r)}function so(t){t.directive("virtual",{priority:10,init(e,r,o){to(),e.setAttribute("data-nojs-virtual",""),e.setAttribute("role","listbox"),e.getAttribute("tabindex")||e.setAttribute("tabindex","0");let n=e.getAttribute("virtual-height")||"50",i=e.getAttribute("virtual-buffer")||"5",c=n==="auto"?"auto":parseInt(n,10),a=parseInt(i,10)||5;if(c!=="auto"&&(isNaN(c)||c<=0)){console.warn("[virtual] virtual-height must be a positive number or 'auto'.");return}let s=Ti(e),d=null;if(s)d=s.eachEl;else for(let _ of e.children)if(!_.classList.contains("nojs-virtual-spacer")){d=_;break}if(!d){console.warn("[virtual] No child template found.");return}let m=d.cloneNode(!0);for(m.removeAttribute("each"),m.removeAttribute("foreach"),m.removeAttribute("for"),m.__declared=!1,m.__disposers=null,m.__ctx=null,s&&(s.eachEl.removeAttribute("each"),s.eachEl.removeAttribute("foreach"),s.eachEl.removeAttribute("for"));e.firstChild;)e.removeChild(e.firstChild);let l=ro(e),f=ro(e);e.appendChild(l),e.appendChild(f);let u={container:e,itemHeight:c,buffer:a,totalItems:0,heights:[],prefixSums:[0],estimatedHeight:c==="auto"?50:c,startIndex:-1,endIndex:-1,scrollTop:0,template:m,spacerTop:l,spacerBottom:f,resizeObserver:null,scrollHandler:null,renderedNodes:new Map,iteratorVar:s?s.iteratorVar:"item",arrayPath:s?s.arrayPath:null,dataArray:[],dirty:!0,disposed:!1};$e.set(e,u);let p=_=>{let x=[...e.querySelectorAll('[role="option"]')];if(!x.length)return;let L=e.querySelector('[role="option"]:focus'),k=L?x.indexOf(L):-1,j=-1;switch(_.key){case"ArrowDown":_.preventDefault(),j=k 0?k-1:0;break;case"Home":_.preventDefault(),j=0;break;case"End":_.preventDefault(),j=x.length-1;break;default:return}j>=0&&j {v||(v=requestAnimationFrame(()=>{v=null,$t(u,t)}))};if(u.scrollHandler=h,e.addEventListener("scroll",h,{passive:!0}),typeof ResizeObserver<"u"){let _=new ResizeObserver(()=>{u.dirty=!0,$t(u,t)});_.observe(e),u.resizeObserver=_}let g=null,b=-1,E=null,y=()=>{if(!u.disposed){if(u.arrayPath){let _=t.findContext?t.findContext(e):null;if(_){let x=Ii(_,u.arrayPath);Array.isArray(x)&&(x!==g||x.length!==b)&&(g=x,b=x.length,Pi(u,x,t))}}E=setTimeout(y,100)}};E=setTimeout(y,100),Si(e,()=>{u.disposed=!0,v&&(cancelAnimationFrame(v),v=null),E&&(clearTimeout(E),E=null),e.removeEventListener("scroll",h),e.removeEventListener("keydown",p),u.resizeObserver&&(u.resizeObserver.disconnect(),u.resizeObserver=null);for(let[_,x]of u.renderedNodes){if(x.__disposers){for(let L of x.__disposers)try{L()}catch{}x.__disposers=null}x.remove()}u.renderedNodes.clear(),u.spacerTop&&u.spacerTop.parentNode&&u.spacerTop.remove(),u.spacerBottom&&u.spacerBottom.parentNode&&u.spacerBottom.remove(),$e.delete(e)})}})}function ao(t,e={}){so(t)}function co(){eo()}var ge=new Map,lt=new Map;function lo(){for(let[t,e]of ge){if(e.observer)try{e.observer.disconnect()}catch{}for(let r of e.spyEntries){let o=r.el&&r.el.__disposers;if(o){for(let n of o)try{n()}catch{}r.el.__disposers=[]}}}ge.clear(),lt.clear()}function uo(){if(typeof document>"u"||document.querySelector("style[data-nojs-scroll-spy]"))return;let t=` +`.trim(),e=document.createElement("style");e.setAttribute("data-nojs-virtual-list",""),e.textContent=t,document.head.appendChild(e)}function Ni(t,e){t.__disposers=t.__disposers||[],t.__disposers.push(e)}function Gi(t){for(let e of t.children)for(let r of["each","foreach","for"])if(e.hasAttribute(r)){let o=Ui(e.getAttribute(r));if(o)return{eachEl:e,...o}}return null}function Ui(t){if(!t)return null;let e=t.match(/^\s*(\w+)\s+(?:in|of)\s+(.+)\s*$/);return e?{iteratorVar:e[1],arrayPath:e[2].trim()}:null}function Yi(t,e){let r=e.split("."),o=t;for(let n of r){if(o==null)return;o=o[n]}return o}function lo(t){let e=t.tagName.toLowerCase(),r;if(e==="tbody"||e==="table"||e==="thead"||e==="tfoot"){r=document.createElement("tr"),r.classList.add("nojs-virtual-spacer");let o=document.createElement("td"),n=e==="table"?t:t.closest("table"),i=n?n.querySelector("tr:not(.nojs-virtual-spacer)"):null,c=i?i.children.length:1;o.setAttribute("colspan",String(c)),o.style.padding="0",o.style.border="none",r.appendChild(o)}else e==="ul"||e==="ol"?(r=document.createElement("li"),r.classList.add("nojs-virtual-spacer"),r.style.listStyle="none"):(r=document.createElement("div"),r.classList.add("nojs-virtual-spacer"));return r.setAttribute("aria-hidden","true"),r.style.height="0px",r}function pt(t,e){if(t.tagName.toLowerCase()==="tr"){let r=t.querySelector("td");r&&(r.style.height=e+"px"),t.style.height=e+"px"}else t.style.height=e+"px"}function Ki(t,e){return t*e}function po(t){let e=t.totalItems,r=new Array(e+1),o=t.estimatedHeight||50;r[0]=0;for(let n=1;n<=e;n++)r[n]=r[n-1]+(t.heights[n-1]||o);t.prefixSums=r}function fo(t,e){let r=0,o=t.length-2;for(;r<=o;){let n=r+o>>>1;t[n]<=e?r=n+1:o=n-1}return Math.max(0,o)}function uo(t){if(t.prefixSums&&t.prefixSums.length===t.totalItems+1)return t.prefixSums[t.totalItems];let e=0,r=t.estimatedHeight||50;for(let o=0;o e)return n;r+=i}return Math.max(0,t.totalItems-1)}function Zi(t,e,r){if(t.prefixSums&&t.prefixSums.length===t.totalItems+1)return fo(t.prefixSums,e+r);let o=e+r,n=0,i=t.estimatedHeight||50;for(let c=0;c =o)return c;return t.totalItems-1}function Qi(t,e,r){if(t.totalItems===0)return{start:0,end:-1};let o,n;return t.itemHeight!=="auto"?(o=Math.floor(e/t.itemHeight),n=Math.ceil((e+r)/t.itemHeight)-1):(o=Xi(t,e),n=Zi(t,e,r)),o=Math.max(0,o-t.buffer),n=Math.min(t.totalItems-1,n+t.buffer),{start:o,end:n}}function Rt(t,e){if(t.disposed)return;let r=t.container,o=r,n=o.scrollTop,i=o.clientHeight,{start:c,end:s}=Qi(t,n,i);if(c===t.startIndex&&s===t.endIndex&&!t.dirty)return;t.startIndex=c,t.endIndex=s,t.dirty=!1;let a=ft(t,c),d=t.itemHeight!=="auto"?Ki(t.totalItems,t.itemHeight):uo(t),g=s>=0?ft(t,s+1):0,u=Math.max(0,d-g);pt(t.spacerTop,a),pt(t.spacerBottom,u);let f=new Set;for(let l=c;l<=s;l++)f.add(l);for(let[l,b]of t.renderedNodes)f.has(l)||(b.remove(),t.renderedNodes.delete(l));let p=[];for(let l=c;l<=s;l++){if(t.renderedNodes.has(l))continue;let b=t.dataArray[l];if(b===void 0)continue;let h=t.template.cloneNode(!0),m={};m[t.iteratorVar]=b,m.$index=l,m.$count=t.totalItems,m.$first=l===0,m.$last=l===t.totalItems-1,m.$even=l%2===0,m.$odd=l%2!==0,h.setAttribute("role","option"),h.setAttribute("aria-setsize",String(t.totalItems)),h.setAttribute("aria-posinset",String(l+1)),h.setAttribute("tabindex","-1"),h.__ctx=Object.create(e.findContext?e.findContext(r)||{}:{},Object.getOwnPropertyDescriptors(m)),h.__declared=!1,p.push({index:l,node:h}),t.renderedNodes.set(l,h)}if(p.length>0){p.sort((l,b)=>l.index-b.index);for(let{index:l,node:b}of p){let h=null;for(let[m,v]of t.renderedNodes)m>l&&v.parentNode===r&&(!h||m 0&&t.heights[b]!==m&&(t.heights[b]=m,l=!0)}if(l){po(t);let b=uo(t),h=ft(t,c),m=s>=0?ft(t,s+1):0,v=Math.max(0,b-m);pt(t.spacerTop,h),pt(t.spacerBottom,v)}}}function Ji(t,e){for(let[r,o]of e.renderedNodes)if(o===t)return r;return 1/0}function es(t,e,r){if(t.disposed)return;let o=t.container.scrollTop;t.dataArray=e||[],t.totalItems=t.dataArray.length,t.dirty=!0,t.itemHeight==="auto"&&t.heights.length>t.totalItems&&(t.heights.length=t.totalItems),t.itemHeight==="auto"&&po(t);for(let[n,i]of t.renderedNodes){if(i.__disposers){for(let c of i.__disposers)try{c()}catch{}i.__disposers=null}i.remove()}t.renderedNodes.clear(),t.container.scrollTop=o,Rt(t,r)}function mo(t){t.directive("virtual",{priority:10,init(e,r,o){co(),e.setAttribute("data-nojs-virtual",""),e.setAttribute("role","listbox"),e.getAttribute("tabindex")||e.setAttribute("tabindex","0");let n=e.getAttribute("virtual-height")||"50",i=e.getAttribute("virtual-buffer")||"5",c=n==="auto"?"auto":parseInt(n,10),s=parseInt(i,10)||5;if(c!=="auto"&&(isNaN(c)||c<=0)){console.warn("[virtual] virtual-height must be a positive number or 'auto'.");return}let a=Gi(e),d=null;if(a)d=a.eachEl;else for(let j of e.children)if(!j.classList.contains("nojs-virtual-spacer")){d=j;break}if(!d){console.warn("[virtual] No child template found.");return}let g=d.cloneNode(!0);for(g.removeAttribute("each"),g.removeAttribute("foreach"),g.removeAttribute("for"),g.__declared=!1,g.__disposers=null,g.__ctx=null,a&&(a.eachEl.removeAttribute("each"),a.eachEl.removeAttribute("foreach"),a.eachEl.removeAttribute("for"));e.firstChild;)e.removeChild(e.firstChild);let u=lo(e),f=lo(e);e.appendChild(u),e.appendChild(f);let p={container:e,itemHeight:c,buffer:s,totalItems:0,heights:[],prefixSums:[0],estimatedHeight:c==="auto"?50:c,startIndex:-1,endIndex:-1,scrollTop:0,template:g,spacerTop:u,spacerBottom:f,resizeObserver:null,scrollHandler:null,renderedNodes:new Map,iteratorVar:a?a.iteratorVar:"item",arrayPath:a?a.arrayPath:null,dataArray:[],dirty:!0,disposed:!1};Pe.set(e,p);let l=j=>{let E=[...e.querySelectorAll('[role="option"]')];if(!E.length)return;let L=e.querySelector('[role="option"]:focus'),w=L?E.indexOf(L):-1,A=-1;switch(j.key){case"ArrowDown":j.preventDefault(),A=w 0?w-1:0;break;case"Home":j.preventDefault(),A=0;break;case"End":j.preventDefault(),A=E.length-1;break;default:return}A>=0&&A {b||(b=requestAnimationFrame(()=>{b=null,Rt(p,t)}))};if(p.scrollHandler=h,e.addEventListener("scroll",h,{passive:!0}),typeof ResizeObserver<"u"){let j=new ResizeObserver(()=>{p.dirty=!0,Rt(p,t)});j.observe(e),p.resizeObserver=j}let m=null,v=-1,y=null,x=()=>{if(!p.disposed){if(p.arrayPath){let j=t.findContext?t.findContext(e):null;if(j){let E=Yi(j,p.arrayPath);Array.isArray(E)&&(E!==m||E.length!==v)&&(m=E,v=E.length,es(p,E,t))}}y=setTimeout(x,100)}};y=setTimeout(x,100),Ni(e,()=>{p.disposed=!0,b&&(cancelAnimationFrame(b),b=null),y&&(clearTimeout(y),y=null),e.removeEventListener("scroll",h),e.removeEventListener("keydown",l),p.resizeObserver&&(p.resizeObserver.disconnect(),p.resizeObserver=null);for(let[j,E]of p.renderedNodes){if(E.__disposers){for(let L of E.__disposers)try{L()}catch{}E.__disposers=null}E.remove()}p.renderedNodes.clear(),p.spacerTop&&p.spacerTop.parentNode&&p.spacerTop.remove(),p.spacerBottom&&p.spacerBottom.parentNode&&p.spacerBottom.remove(),Pe.delete(e)})}})}function go(t,e={}){mo(t)}function bo(){ao()}var ge=new Map,mt=new Map;function ho(){for(let[t,e]of ge){if(e.observer)try{e.observer.disconnect()}catch{}for(let r of e.spyEntries){let o=r.el&&r.el.__disposers;if(o){for(let n of o)try{n()}catch{}r.el.__disposers=[]}}}ge.clear(),mt.clear()}function vo(){if(typeof document>"u"||document.querySelector("style[data-nojs-scroll-spy]"))return;let t=` [spy].active, a[href^="#"].active { font-weight: 600; } -`.trim(),e=document.createElement("style");e.setAttribute("data-nojs-scroll-spy",""),e.textContent=t,document.head.appendChild(e)}function Ri(t,e){t.__disposers=t.__disposers||[],t.__disposers.push(e)}function zi(t){if(t.tagName==="A"){let r=t.getAttribute("href")||"";if(r.startsWith("#")&&r.length>1)return r.slice(1)}let e=t.getAttribute("spy")||"";return e.startsWith("#")&&e.length>1?e.slice(1):e.length>0?e:null}function Fi(t){let e=t.getAttribute("spy-offset");if(e===null||e==="")return 0;let r=parseInt(e,10);return Number.isNaN(r)?0:r}function Oi(t){let e=t.getAttribute("spy-threshold");if(e===null||e==="")return .1;let r=parseFloat(e);return Number.isNaN(r)||r<0||r>1?.1:r}function Vi(){return document.documentElement}function Ni(t){t.classList.add("active"),t.setAttribute("aria-current","true")}function po(t){t.classList.remove("active"),t.removeAttribute("aria-current")}function qt(t){let e=ge.get(t);if(!e)return;e.observer&&(e.observer.disconnect(),e.observer=null);let r=e.offset,o=e.threshold,n=new Set,i=`-${r}px 0px 0px 0px`,c=new IntersectionObserver(s=>{for(let l of s)l.isIntersecting?n.add(l.target.id):n.delete(l.target.id);let d=null,m=1/0;for(let l of n){let f=document.getElementById(l);if(!f)continue;let u=f.getBoundingClientRect();u.top .');return}let i=Fi(e),c=Oi(e),a=Vi();ge.has(a)||ge.set(a,{observer:null,spyEntries:[],activeEl:null,offset:i,threshold:c});let s=ge.get(a),d={el:e,targetId:n};s.spyEntries.push(d),lt.set(e,a),qt(a),!s.mutObserver&&typeof MutationObserver<"u"&&(s.mutObserver=new MutationObserver(()=>{qt(a)}),s.mutObserver.observe(document.body,{childList:!0,subtree:!0})),Ri(e,()=>{let m=s.spyEntries.indexOf(d);m!==-1&&s.spyEntries.splice(m,1),lt.delete(e),po(e),s.spyEntries.length===0?(s.observer&&(s.observer.disconnect(),s.observer=null),s.mutObserver&&(s.mutObserver.disconnect(),s.mutObserver=null),ge.delete(a)):qt(a)})}})}function mo(t,e={}){fo(t)}function go(){lo()}var Ui="[validate],[drag],[drop],[drag-list],[drag-multiple]";function bo(t){if(typeof document>"u")return;let e=document.querySelectorAll(Ui);for(let r of e){if(!r.__declared)continue;let o=K(t,"disposeTree");typeof o=="function"?o(r):(r.__disposers&&(r.__disposers.forEach(i=>i()),r.__disposers=null),r.__declared=!1);let n=t.findContext?t.findContext(r):null;n&&delete n.$form,t.processTree(r)}}var Gi=["tooltip","popover","popover-trigger","popover-dismiss","modal","modal-open","modal-close","dropdown","dropdown-toggle","dropdown-menu","dropdown-item","toast","toast-container","tabs","tab","tab-disabled","tab-position","tree","branch","subtree","stepper","step","skeleton","split","pane","panel","sortable","sort","fixed-header","fixed-col","breadcrumb","accordion","virtual","virtual-height","virtual-buffer","spy","spy-offset","spy-threshold"],Yi={name:"nojs-elements",install(t,e={}){Vt(t,e),Jt(t,e),sr(t,e),lr(t,e),xr(t,e),Cr(t,e),$r(t,e),Vr(t,e),rn(t,e),un(t,e),bn(t,e),_n(t,e),Mn(t,e),Nn(t,e),Qn(t,e),ao(t,e),mo(t,e),bo(t)},init(t){if(bo(t),typeof document>"u"||!document.body)return;let e=Gi.map(o=>`[${o}]`).join(","),r;try{r=document.body.querySelectorAll(e)}catch{return}for(let o of r)o.__declared&&!o.__disposers&&!o.__ctx&&(o.__declared=!1);try{t.processTree(document.body)}catch(o){t.internals?.warn?.("nojs-elements init re-process error:",o.message)}},dispose(t){Nt(),er(),ar(),ur(),Er(),Sr(),qr(),Nr(),nn(),pn(),wn(),Pn(),Wn(),Jn(),co(),go()}},Ki=Yi; +`.trim(),e=document.createElement("style");e.setAttribute("data-nojs-scroll-spy",""),e.textContent=t,document.head.appendChild(e)}function ts(t,e){t.__disposers=t.__disposers||[],t.__disposers.push(e)}function rs(t){if(t.tagName==="A"){let r=t.getAttribute("href")||"";if(r.startsWith("#")&&r.length>1)return r.slice(1)}let e=t.getAttribute("spy")||"";return e.startsWith("#")&&e.length>1?e.slice(1):e.length>0?e:null}function ns(t){let e=t.getAttribute("spy-offset");if(e===null||e==="")return 0;let r=parseInt(e,10);return Number.isNaN(r)?0:r}function os(t){let e=t.getAttribute("spy-threshold");if(e===null||e==="")return .1;let r=parseFloat(e);return Number.isNaN(r)||r<0||r>1?.1:r}function is(){return document.documentElement}function ss(t){t.classList.add("active"),t.setAttribute("aria-current","true")}function yo(t){t.classList.remove("active"),t.removeAttribute("aria-current")}function zt(t){let e=ge.get(t);if(!e)return;e.observer&&(e.observer.disconnect(),e.observer=null);let r=e.offset,o=e.threshold,n=new Set,i=`-${r}px 0px 0px 0px`,c=new IntersectionObserver(a=>{for(let u of a)u.isIntersecting?n.add(u.target.id):n.delete(u.target.id);let d=null,g=1/0;for(let u of n){let f=document.getElementById(u);if(!f)continue;let p=f.getBoundingClientRect();p.top .');return}let i=ns(e),c=os(e),s=is();ge.has(s)||ge.set(s,{observer:null,spyEntries:[],activeEl:null,offset:i,threshold:c});let a=ge.get(s),d={el:e,targetId:n};a.spyEntries.push(d),mt.set(e,s),zt(s),!a.mutObserver&&typeof MutationObserver<"u"&&(a.mutObserver=new MutationObserver(()=>{zt(s)}),a.mutObserver.observe(document.body,{childList:!0,subtree:!0})),ts(e,()=>{let g=a.spyEntries.indexOf(d);g!==-1&&a.spyEntries.splice(g,1),mt.delete(e),yo(e),a.spyEntries.length===0?(a.observer&&(a.observer.disconnect(),a.observer=null),a.mutObserver&&(a.mutObserver.disconnect(),a.mutObserver=null),ge.delete(s)):zt(s)})}})}function Eo(t,e={}){xo(t)}function _o(){ho()}var Ft="it is a DOM element; client mechanics never send DOM nodes",Ao={drag:{attrs:{drag:{type:"expression",deliver:"sealed"},"drag-disabled":"expression","drag-type":"literal","drag-effect":"literal","drag-handle":"literal","drag-image":"literal","drag-image-offset":"literal","drag-class":"literal","drag-ghost-class":"literal","drag-group":"literal"}},drop:{attrs:{drop:"statement","drop-disabled":"expression","drop-max":"expression","drop-accept":"literal","drop-effect":"literal","drop-class":"literal","drop-reject-class":"literal","drop-sort":"literal","drop-placeholder":"literal","drop-placeholder-class":"literal"},implicit:{$drag:{sealed:!0},$dragType:{schema:{type:"string",maxLength:256}},$dragEffect:{schema:{type:"string",maxLength:32}},$dropIndex:{schema:{type:"integer",minimum:0,maximum:1e6}},$source:{schema:{type:"object",properties:{index:{type:["integer","null"],minimum:0}},required:["index"],additionalProperties:!1},members:{el:Ft},fixed:{list:null}},$target:{schema:{type:"object",properties:{index:{type:"integer",minimum:0}},required:["index"],additionalProperties:!1},members:{el:Ft},fixed:{list:null}},$el:{unavailable:Ft}}}};var cs="[validate],[drag],[drop],[drag-list],[drag-multiple]";function wo(t){if(typeof document>"u")return;let e=document.querySelectorAll(cs);for(let r of e){if(!r.__declared||r.__nojsElBoundCtx!==void 0&&t.findContext&&r.__nojsElBoundCtx===t.findContext(r))continue;let o=X(t,"disposeTree");typeof o=="function"?o(r):(r.__disposers&&(r.__disposers.forEach(i=>i()),r.__disposers=null),r.__declared=!1);let n=t.findContext?t.findContext(r):null;n&&delete n.$form,t.processTree(r)}}var jo=["tooltip","popover","popover-trigger","popover-dismiss","modal","modal-open","modal-close","dropdown","dropdown-toggle","dropdown-menu","dropdown-item","toast","toast-container","tabs","tab","tab-disabled","tab-position","tree","branch","subtree","stepper","step","skeleton","split","pane","panel","sortable","sort","fixed-header","fixed-col","breadcrumb","accordion","virtual","virtual-height","virtual-buffer","spy","spy-offset","spy-threshold"],ds=["validate","drag-list","drag-multiple",...jo].filter(t=>!Xt.includes(t));function ls(t,e){vt(t,e);for(let r of ds)t.directive(r,{priority:30,init(o,n){n.warn(`"${r}" is not yet available on NoJS-Server compiled sites (host API migration pending); the element is not initialized.`)}})}var us={name:"nojs-elements",contract:{directives:{...Ao}},install(t,e={}){if(de(t)){ls(t,e);return}vt(t,e),sr(t,e),fr(t,e),hr(t,e),kr(t,e),$r(t,e),Or(t,e),Xr(t,e),ln(t,e),vn(t,e),An(t,e),Sn(t,e),Wn(t,e),Zn(t,e),io(t,e),go(t,e),Eo(t,e),wo(t)},init(t){if(de(t)||(wo(t),typeof document>"u"||!document.body))return;let e=jo.map(o=>`[${o}]`).join(","),r;try{r=document.body.querySelectorAll(e)}catch{return}for(let o of r)o.__declared&&!o.__disposers&&!o.__ctx&&(o.__declared=!1);try{t.processTree(document.body)}catch(o){t.internals?.warn?.("nojs-elements init re-process error:",o.message)}},dispose(t){Zt(),ar(),mr(),vr(),Cr(),qr(),Vr(),Zr(),un(),yn(),Dn(),Nn(),Qn(),so(),bo(),_o()}},ps=us; //# sourceMappingURL=nojs-elements.js.map diff --git a/dist/cjs/nojs-elements.js.map b/dist/cjs/nojs-elements.js.map index f2c1c5d..a316094 100644 --- a/dist/cjs/nojs-elements.js.map +++ b/dist/cjs/nojs-elements.js.map @@ -1,7 +1,7 @@ { "version": 3, - "sources": ["../../src/index.js", "../../src/dnd/state.js", "../../src/dnd/styles.js", "../../src/_compat.js", "../../src/dnd/element.js", "../../src/dnd/index.js", "../../src/validate/state.js", "../../src/validate/element.js", "../../src/validate/index.js", "../../src/tooltip/state.js", "../../src/tooltip/styles.js", "../../src/tooltip/tooltip.js", "../../src/tooltip/index.js", "../../src/popover/state.js", "../../src/popover/styles.js", "../../src/popover/popover.js", "../../src/popover/index.js", "../../src/modal/state.js", "../../src/modal/styles.js", "../../src/modal/modal.js", "../../src/modal/modal-open.js", "../../src/modal/modal-close.js", "../../src/modal/index.js", "../../src/dropdown/state.js", "../../src/dropdown/styles.js", "../../src/dropdown/dropdown.js", "../../src/dropdown/item.js", "../../src/dropdown/index.js", "../../src/toast/state.js", "../../src/toast/styles.js", "../../src/toast/toast.js", "../../src/toast/index.js", "../../src/tabs/state.js", "../../src/tabs/styles.js", "../../src/tabs/tabs.js", "../../src/tabs/tab.js", "../../src/tabs/index.js", "../../src/tree/state.js", "../../src/tree/styles.js", "../../src/tree/tree.js", "../../src/tree/drag.js", "../../src/tree/index.js", "../../src/stepper/state.js", "../../src/stepper/styles.js", "../../src/stepper/validation.js", "../../src/stepper/stepper.js", "../../src/stepper/step.js", "../../src/stepper/index.js", "../../src/skeleton/styles.js", "../../src/skeleton/skeleton.js", "../../src/skeleton/index.js", "../../src/split/state.js", "../../src/split/styles.js", "../../src/split/split.js", "../../src/split/pane.js", "../../src/split/index.js", "../../src/table/state.js", "../../src/table/styles.js", "../../src/table/table.js", "../../src/table/reorder.js", "../../src/table/index.js", "../../src/breadcrumb/state.js", "../../src/breadcrumb/styles.js", "../../src/breadcrumb/breadcrumb.js", "../../src/breadcrumb/index.js", "../../src/accordion/state.js", "../../src/accordion/styles.js", "../../src/accordion/accordion.js", "../../src/accordion/index.js", "../../src/virtual-list/state.js", "../../src/virtual-list/styles.js", "../../src/virtual-list/virtual-list.js", "../../src/virtual-list/index.js", "../../src/scroll-spy/state.js", "../../src/scroll-spy/styles.js", "../../src/scroll-spy/scroll-spy.js", "../../src/scroll-spy/index.js"], - "sourcesContent": ["import { registerDnd, cleanupDnd } from \"./dnd/index.js\";\nimport { registerValidation, cleanupValidation } from \"./validate/index.js\";\nimport { registerTooltipModule, cleanupTooltip } from \"./tooltip/index.js\";\nimport { registerPopover, cleanupPopover } from \"./popover/index.js\";\nimport { registerModal, cleanupModal } from \"./modal/index.js\";\nimport { registerDropdown, cleanupDropdown } from \"./dropdown/index.js\";\nimport { registerToast, cleanupToast } from \"./toast/index.js\";\nimport { registerTabs, cleanupTabs } from \"./tabs/index.js\";\nimport { registerTree, cleanupTree } from \"./tree/index.js\";\nimport { registerStepperModule, cleanupStepper } from \"./stepper/index.js\";\nimport { registerSkeleton, cleanupSkeleton } from \"./skeleton/index.js\";\nimport { registerSplit, cleanupSplit } from \"./split/index.js\";\nimport { registerTable, cleanupTable } from \"./table/index.js\";\nimport { registerBreadcrumb, cleanupBreadcrumb } from \"./breadcrumb/index.js\";\nimport { registerAccordion, cleanupAccordion } from \"./accordion/index.js\";\nimport { registerVirtualList, cleanupVirtualList } from \"./virtual-list/index.js\";\nimport { registerScrollSpy, cleanupScrollSpy } from \"./scroll-spy/index.js\";\nimport { _internal } from \"./_compat.js\";\n\n// Elements whose core stubs this plugin replaces with full implementations.\nconst SWAPPED = '[validate],[drag],[drop],[drag-list],[drag-multiple]';\n\n// Re-bind any [validate]/[drag]/... node that core already processed (against the\n// removed stub) so it re-runs against the real directive and the live root context.\n//\n// This covers TWO load orders:\n// 1. Core IIFE auto-init runs processTree() BEFORE this plugin installs \u2192 nodes are\n// __declared with stub bindings (static $form, blocking submit handler).\n// 2. Plugin installs BEFORE core init \u2192 at processTree time the real `validate`\n// binds, but the root context may not exist yet, so $form lands on an orphan\n// context. Running this AFTER core init (via the plugin `init` hook, once the\n// root context is established) re-binds it onto the real context.\nfunction _rebindSwappedNodes(NoJS) {\n if (typeof document === 'undefined') return;\n const nodes = document.querySelectorAll(SWAPPED);\n for (const el of nodes) {\n if (!el.__declared) continue; // not yet processed \u2192 real directive will catch it\n const disposeTree = _internal(NoJS, 'disposeTree');\n if (typeof disposeTree === 'function') {\n disposeTree(el); // fires stub disposers, resets __declared, clears listeners\n } else {\n if (el.__disposers) { el.__disposers.forEach(fn => fn()); el.__disposers = null; }\n el.__declared = false;\n }\n const ctx = NoJS.findContext ? NoJS.findContext(el) : null;\n if (ctx) delete ctx.$form; // drop stub's / orphan's static $form\n NoJS.processTree(el); // re-bind with real directive + live context\n }\n}\n\n// Attribute names of every directive registered by this plugin. Used by the\n// `init` hook to re-process DOM that core already walked before Elements was\n// installed (core marks every walked element `__declared`, even when no\n// directive matched, so a plain re-walk would skip them).\nconst ELEMENT_DIRECTIVE_ATTRS = [\n \"tooltip\",\n \"popover\", \"popover-trigger\", \"popover-dismiss\",\n \"modal\", \"modal-open\", \"modal-close\",\n \"dropdown\", \"dropdown-toggle\", \"dropdown-menu\", \"dropdown-item\",\n \"toast\", \"toast-container\",\n \"tabs\", \"tab\", \"tab-disabled\", \"tab-position\",\n \"tree\", \"branch\", \"subtree\",\n \"stepper\", \"step\",\n \"skeleton\",\n \"split\", \"pane\", \"panel\",\n \"sortable\", \"sort\", \"fixed-header\", \"fixed-col\",\n \"breadcrumb\",\n \"accordion\",\n \"virtual\", \"virtual-height\", \"virtual-buffer\",\n \"spy\", \"spy-offset\", \"spy-threshold\",\n];\n\nconst NoJSElements = {\n name: \"nojs-elements\",\n\n install(NoJS, options = {}) {\n // Core extracted modules (register first \u2014 other elements may integrate)\n registerDnd(NoJS, options);\n registerValidation(NoJS, options);\n\n // UI elements\n registerTooltipModule(NoJS, options);\n registerPopover(NoJS, options);\n registerModal(NoJS, options);\n registerDropdown(NoJS, options);\n registerToast(NoJS, options);\n registerTabs(NoJS, options);\n registerTree(NoJS, options);\n registerStepperModule(NoJS, options);\n registerSkeleton(NoJS, options);\n registerSplit(NoJS, options);\n registerTable(NoJS, options);\n registerBreadcrumb(NoJS, options);\n registerAccordion(NoJS, options);\n registerVirtualList(NoJS, options);\n registerScrollSpy(NoJS, options);\n\n // Load order 1: core auto-init already processed these nodes with stubs.\n _rebindSwappedNodes(NoJS);\n },\n\n // Runs after core init() has built the root context + processed the tree.\n //\n // Two responsibilities, both required:\n // 1. Load order 2 (validate/drag/drop/...): re-bind any swapped node that was\n // bound against a not-yet-ready context so it picks up the live root context.\n // 2. Late install: when Elements loads after core already walked the DOM, the\n // directives registered in install() would never apply to the existing,\n // already-walked tree. Re-clear the premature `__declared` flag on elements\n // bearing Elements directives and re-process them. (Safety Rule #11:\n // registers cleanly, only re-runs over its own directive attributes \u2014\n // never overrides core.)\n init(NoJS) {\n _rebindSwappedNodes(NoJS);\n\n if (typeof document === \"undefined\" || !document.body) return;\n const selector = ELEMENT_DIRECTIVE_ATTRS.map((a) => `[${a}]`).join(\",\");\n let nodes;\n try {\n nodes = document.body.querySelectorAll(selector);\n } catch {\n return;\n }\n for (const node of nodes) {\n // Only reset elements core marked declared but on which nothing ran\n // (no disposers / no context) \u2014 i.e. directives that were skipped because\n // Elements was not yet registered when core walked the tree.\n if (node.__declared && !node.__disposers && !node.__ctx) {\n node.__declared = false;\n }\n }\n try {\n NoJS.processTree(document.body);\n } catch (e) {\n NoJS.internals?.warn?.(\"nojs-elements init re-process error:\", e.message);\n }\n },\n\n dispose(NoJS) {\n cleanupDnd();\n cleanupValidation();\n cleanupTooltip();\n cleanupPopover();\n cleanupModal();\n cleanupDropdown();\n cleanupToast();\n cleanupTabs();\n cleanupTree();\n cleanupStepper();\n cleanupSkeleton();\n cleanupSplit();\n cleanupTable();\n cleanupBreadcrumb();\n cleanupAccordion();\n cleanupVirtualList();\n cleanupScrollSpy();\n },\n};\n\nexport default NoJSElements;\n", "// \u2500\u2500\u2500 Module-scoped DnD coordination state \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Shared drag-and-drop state tracking.\n * @type {{ dragging: object|null, selected: Map , placeholder: HTMLElement|null }}\n */\nexport const _dndState = {\n dragging: null, // { item, type, effect, sourceEl, sourceCtx, sourceList, sourceIndex, listDirective }\n selected: new Map(), // group \u2192 Set<{ item, el, ctx }>\n placeholder: null, // current placeholder DOM element\n};\n\n/**\n * Registry of drag-list elements for cross-list communication.\n * @type {Map }\n */\nexport const _dragListRegistry = new Map();\n\n/**\n * Reset all DnD state (used by cleanupDnd).\n */\nexport function resetDndState() {\n _dndState.dragging = null;\n _dndState.selected.clear();\n if (_dndState.placeholder) {\n _dndState.placeholder.remove();\n _dndState.placeholder = null;\n }\n _dragListRegistry.clear();\n}\n", "// \u2500\u2500\u2500 Inject built-in DnD styles (once) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport function _injectDndStyles() {\n if (typeof document === \"undefined\") return;\n if (document.querySelector(\"style[data-nojs-dnd]\")) return;\n\n const css = `\n.nojs-dragging {\n opacity: 0.5;\n cursor: grabbing !important;\n}\n.nojs-drag-over {\n outline: 2px dashed #3b82f6;\n outline-offset: -2px;\n}\n.nojs-drop-placeholder {\n border: 2px dashed #3b82f6;\n border-radius: 6px;\n background: color-mix(in srgb, #3b82f6 6%, transparent);\n box-sizing: border-box;\n min-height: 2.5rem;\n transition: all 0.15s ease;\n pointer-events: none;\n}\n.nojs-drop-reject {\n outline: 2px dashed #ef4444;\n outline-offset: -2px;\n background: color-mix(in srgb, #ef4444 4%, transparent);\n}\n.nojs-selected {\n outline: 2px solid #3b82f6;\n outline-offset: 1px;\n}\n[drag-axis=\"x\"] { touch-action: pan-y; }\n[drag-axis=\"y\"] { touch-action: pan-x; }\n@keyframes nojs-drop-settle {\n from { transform: scale(1.05); opacity: 0.8; }\n to { transform: scale(1); opacity: 1; }\n}\n.nojs-drop-settle {\n animation: nojs-drop-settle 0.2s ease-out;\n}\n.nojs-drag-list-empty {\n min-height: 3rem;\n}\n`.trim();\n\n const style = document.createElement(\"style\");\n style.setAttribute(\"data-nojs-dnd\", \"\");\n style.textContent = css;\n document.head.appendChild(style);\n}\n", "// Safe internals accessor \u2014 tolerates older cores missing internals or a member.\nexport function _internal(NoJS, key) {\n const i = NoJS && NoJS.internals;\n return i && typeof i[key] !== 'undefined' ? i[key] : undefined;\n}\n", "import { _dndState, _dragListRegistry } from \"./state.js\";\nimport { _injectDndStyles } from \"./styles.js\";\nimport { _internal } from \"../_compat.js\";\n\n// Guarded helper: remove a core directive stub, warn on old cores that lack the API.\nfunction _removeCoreStub(NoJS, name) {\n const removeCore = _internal(NoJS, 'removeCoreDirective');\n if (typeof removeCore === 'function') {\n removeCore(name);\n } else {\n (_internal(NoJS, 'warn') || console.warn)(\n `[nojs-elements] core too old (<1.13.0): cannot remove \"${name}\" stub; update NoJS core to 1.13.0+.`\n );\n }\n}\n\nfunction addDisposer(el, fn) {\n el.__disposers = el.__disposers || [];\n el.__disposers.push(fn);\n}\n\n// \u2500\u2500\u2500 Helper: count visible children, recursing through display:contents wrappers\nfunction _countVisibleChildren(el) {\n let count = 0;\n for (const child of el.children) {\n if (child.classList.contains(\"nojs-drop-placeholder\")) continue;\n const style = child.style || {};\n if (style.display === \"contents\") {\n count += _countVisibleChildren(child);\n } else {\n count++;\n }\n }\n return count;\n}\n\n// \u2500\u2500\u2500 Helper: calculate drop index from mouse position \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nfunction _calcDropIndex(el, mouseX, mouseY, sortDir) {\n const children = [...el.children].filter(\n (c) => !c.classList.contains(\"nojs-drop-placeholder\")\n );\n if (children.length === 0) return 0;\n\n for (let i = 0; i < children.length; i++) {\n // Use first visible child for display:contents wrappers\n const measured = children[i].style && children[i].style.display === \"contents\"\n ? (children[i].firstElementChild || children[i])\n : children[i];\n const rect = measured.getBoundingClientRect();\n if (sortDir === \"horizontal\") {\n const midX = rect.left + rect.width / 2;\n if (mouseX < midX) return i;\n } else if (sortDir === \"grid\") {\n const midX = rect.left + rect.width / 2;\n const midY = rect.top + rect.height / 2;\n if (mouseY < midY && mouseX < midX) return i;\n if (mouseY < rect.top + rect.height && mouseX < midX) return i;\n } else {\n // vertical (default)\n const midY = rect.top + rect.height / 2;\n if (mouseY < midY) return i;\n }\n }\n return children.length;\n}\n\n// \u2500\u2500\u2500 Helper: manage placeholder \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nfunction _insertPlaceholder(el, index, placeholderAttr, placeholderClass) {\n _removePlaceholder();\n\n let ph;\n if (placeholderAttr === \"auto\") {\n ph = document.createElement(\"div\");\n ph.className = placeholderClass || \"nojs-drop-placeholder\";\n // Size placeholder to match the dragged item\n if (_dndState.dragging && _dndState.dragging.sourceEl) {\n const srcEl = _dndState.dragging.sourceEl.firstElementChild || _dndState.dragging.sourceEl;\n const rect = srcEl.getBoundingClientRect();\n if (rect.height > 0) ph.style.height = rect.height + \"px\";\n if (rect.width > 0) ph.style.width = rect.width + \"px\";\n }\n } else {\n // Template ID\n const tpl = document.getElementById(\n placeholderAttr.startsWith(\"#\") ? placeholderAttr.slice(1) : placeholderAttr\n );\n if (tpl && tpl.content) {\n ph = document.createElement(\"div\");\n ph.style.display = \"contents\";\n ph.className = placeholderClass || \"nojs-drop-placeholder\";\n ph.appendChild(tpl.content.cloneNode(true));\n } else {\n ph = document.createElement(\"div\");\n ph.className = placeholderClass || \"nojs-drop-placeholder\";\n }\n }\n\n ph.classList.add(\"nojs-drop-placeholder\");\n const children = [...el.children].filter(\n (c) => !c.classList.contains(\"nojs-drop-placeholder\")\n );\n\n if (index >= children.length) {\n el.appendChild(ph);\n } else {\n el.insertBefore(ph, children[index]);\n }\n _dndState.placeholder = ph;\n}\n\nfunction _removePlaceholder() {\n if (_dndState.placeholder) {\n _dndState.placeholder.remove();\n _dndState.placeholder = null;\n }\n}\n\n// \u2500\u2500\u2500 Helper: check if type is accepted \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nfunction _isTypeAccepted(dragType, acceptAttr) {\n if (!acceptAttr || acceptAttr === \"*\") return true;\n const accepted = acceptAttr.split(\",\").map((s) => s.trim());\n return accepted.includes(dragType);\n}\n\n// \u2500\u2500\u2500 Helper: build stacked-cards ghost for multi-drag \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nfunction _buildStackGhost(sourceEl, count) {\n const ghost = document.createElement(\"div\");\n ghost.style.cssText = \"position:fixed;top:-9999px;left:-9999px;pointer-events:none;z-index:99999;\";\n\n const measured = sourceEl.style && sourceEl.style.display === \"contents\"\n ? (sourceEl.firstElementChild || sourceEl) : sourceEl;\n const rect = measured.getBoundingClientRect();\n const w = rect.width;\n const h = rect.height;\n const cs = getComputedStyle(measured);\n const maxStack = Math.min(count, 3);\n\n // Stack layers (back to front)\n for (let i = maxStack - 1; i >= 0; i--) {\n const layer = document.createElement(\"div\");\n const offset = i * 4;\n layer.style.cssText =\n \"position:absolute;\" +\n \"top:\" + offset + \"px;left:\" + offset + \"px;\" +\n \"width:\" + w + \"px;height:\" + h + \"px;\" +\n \"border-radius:\" + cs.borderRadius + \";\" +\n \"box-shadow:0 1px 4px rgba(0,0,0,0.12);\" +\n \"overflow:hidden;box-sizing:border-box;\";\n\n if (i === 0) {\n // Top card: clone content (cloneNode avoids re-parsing HTML which\n // would execute inline event handlers like onerror on tags).\n // Use while-loop to drain the clone \u2014 childNodes is a live NodeList\n // so for-of would skip every other child as appendChild mutates it.\n const clone = measured.cloneNode(true);\n while (clone.firstChild) {\n layer.appendChild(clone.firstChild);\n }\n layer.style.background = cs.backgroundColor || \"#fff\";\n layer.style.border = cs.border;\n layer.style.padding = cs.padding;\n layer.style.fontSize = cs.fontSize;\n layer.style.color = cs.color;\n layer.style.fontFamily = cs.fontFamily;\n } else {\n // Back cards: solid fill\n layer.style.background = cs.backgroundColor || \"#fff\";\n layer.style.border = cs.border || \"1px solid #ddd\";\n }\n ghost.appendChild(layer);\n }\n\n // Count badge\n const badge = document.createElement(\"div\");\n badge.textContent = count;\n badge.style.cssText =\n \"position:absolute;top:-6px;right:-6px;\" +\n \"min-width:22px;height:22px;padding:0 5px;\" +\n \"background:#3b82f6;color:#fff;border-radius:11px;\" +\n \"display:flex;align-items:center;justify-content:center;\" +\n \"font-size:11px;font-weight:700;border:2px solid #fff;\" +\n \"box-shadow:0 1px 3px rgba(0,0,0,0.2);\";\n ghost.appendChild(badge);\n\n // Container size\n ghost.style.width = (w + (maxStack - 1) * 4) + \"px\";\n ghost.style.height = (h + (maxStack - 1) * 4) + \"px\";\n\n return ghost;\n}\n\n// \u2500\u2500 Shared aria-live region singleton for DnD announcements (WCAG 4.1.3) \u2500\u2500\nlet _liveRegion = null;\n\nfunction _getOrCreateLiveRegion() {\n if (_liveRegion && _liveRegion.isConnected) return _liveRegion;\n if (typeof document === \"undefined\" || !document.body) return null;\n _liveRegion = document.createElement(\"div\");\n _liveRegion.setAttribute(\"aria-live\", \"assertive\");\n _liveRegion.setAttribute(\"aria-atomic\", \"true\");\n _liveRegion.setAttribute(\"role\", \"status\");\n _liveRegion.className = \"nojs-dnd-live-region\";\n _liveRegion.style.cssText =\n \"position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;padding:0;margin:-1px;\";\n document.body.appendChild(_liveRegion);\n return _liveRegion;\n}\n\nfunction _announce(message) {\n const region = _getOrCreateLiveRegion();\n if (!region) return;\n // Clear then set: forces screen readers to re-announce even if text is identical\n region.textContent = \"\";\n if (typeof requestAnimationFrame !== \"undefined\") {\n requestAnimationFrame(() => { region.textContent = message; });\n } else {\n region.textContent = message;\n }\n}\n\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n// DRAG DIRECTIVE\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\nexport function registerDrag(NoJS) {\n _removeCoreStub(NoJS, \"drag\");\n\n NoJS.directive(\"drag\", {\n priority: 15,\n init(el, name, expr) {\n _injectDndStyles();\n const ctx = NoJS.findContext(el);\n\n const type = el.getAttribute(\"drag-type\") || \"default\";\n const effect = el.getAttribute(\"drag-effect\") || \"move\";\n const handleSel = el.getAttribute(\"drag-handle\");\n const imageSel = el.getAttribute(\"drag-image\");\n const imageOffsetAttr = el.getAttribute(\"drag-image-offset\") || \"0,0\";\n const disabledExpr = el.getAttribute(\"drag-disabled\");\n const dragClass = el.getAttribute(\"drag-class\") || \"nojs-dragging\";\n const ghostClass = el.getAttribute(\"drag-ghost-class\");\n\n // Set draggable\n el.draggable = true;\n\n // Accessibility (WCAG 4.1.2 \u2014 aria-grabbed is deprecated, use aria-roledescription)\n el.setAttribute(\"aria-roledescription\", \"draggable item\");\n if (!el.getAttribute(\"role\")) el.setAttribute(\"role\", \"button\");\n if (!el.getAttribute(\"tabindex\")) el.setAttribute(\"tabindex\", \"0\");\n\n // Handle restriction: prevent drag from non-handle areas\n let _handleAllowed = true;\n if (handleSel) {\n const mousedownHandler = (e) => {\n _handleAllowed = !!e.target.closest(handleSel);\n };\n el.addEventListener(\"mousedown\", mousedownHandler);\n addDisposer(el, () => el.removeEventListener(\"mousedown\", mousedownHandler));\n }\n\n // Drag start\n const dragstartHandler = (e) => {\n // Handle check\n if (handleSel && !_handleAllowed) {\n e.preventDefault();\n return;\n }\n\n // Disabled check\n if (disabledExpr && NoJS.evaluate(disabledExpr, ctx)) {\n e.preventDefault();\n return;\n }\n\n const item = NoJS.evaluate(expr, ctx);\n\n // Check for multi-select\n const group = el.getAttribute(\"drag-group\");\n let dragItem = item;\n if (group && _dndState.selected.has(group)) {\n const selectedSet = _dndState.selected.get(group);\n if (selectedSet.size > 0) {\n // If this element is selected, drag all selected items\n const hasThis = [...selectedSet].some((s) => s.el === el);\n if (hasThis) {\n dragItem = [...selectedSet].map((s) => s.item);\n }\n }\n }\n\n // Store dragging state\n _dndState.dragging = {\n item: dragItem,\n type,\n effect,\n sourceEl: el,\n sourceCtx: ctx,\n sourceList: null,\n sourceIndex: null,\n listDirective: null,\n };\n\n // Set dataTransfer\n if (e.dataTransfer) {\n e.dataTransfer.effectAllowed = effect;\n e.dataTransfer.setData(\"text/plain\", \"\");\n\n // Multi-select: stacked cards drag image\n if (Array.isArray(dragItem) && dragItem.length > 1 && e.dataTransfer.setDragImage) {\n const ghost = _buildStackGhost(el, dragItem.length);\n document.body.appendChild(ghost);\n const rect = el.getBoundingClientRect();\n e.dataTransfer.setDragImage(ghost, rect.width / 2, rect.height / 2);\n requestAnimationFrame(() => ghost.remove());\n } else if (imageSel && e.dataTransfer.setDragImage) {\n // Custom drag image\n if (imageSel === \"none\") {\n const empty = document.createElement(\"div\");\n empty.style.cssText = \"width:1px;height:1px;opacity:0;position:fixed;top:-999px\";\n document.body.appendChild(empty);\n const [ox, oy] = imageOffsetAttr.split(\",\").map(Number);\n e.dataTransfer.setDragImage(empty, ox || 0, oy || 0);\n requestAnimationFrame(() => empty.remove());\n } else {\n const imgEl = el.querySelector(imageSel);\n if (imgEl) {\n const [ox, oy] = imageOffsetAttr.split(\",\").map(Number);\n if (ghostClass) imgEl.classList.add(ghostClass);\n e.dataTransfer.setDragImage(imgEl, ox || 0, oy || 0);\n }\n }\n }\n }\n\n // Apply drag class to dragged element (and all selected items if multi-select)\n dragClass.split(/\\s+/).filter(Boolean).forEach((c) => el.classList.add(c));\n if (Array.isArray(dragItem) && group && _dndState.selected.has(group)) {\n for (const s of _dndState.selected.get(group)) {\n if (s.el !== el) dragClass.split(/\\s+/).filter(Boolean).forEach((c) => s.el.classList.add(c));\n }\n }\n\n // Screen reader announcement (WCAG 4.1.3)\n const dragLabel = el.getAttribute(\"aria-label\") || el.textContent?.trim()?.slice(0, 50) || \"Item\";\n _announce(`Grabbed ${dragLabel}. Use arrow keys to move.`);\n\n // Dispatch custom event\n el.dispatchEvent(\n new CustomEvent(\"nojs:dnd-start\", {\n bubbles: true,\n detail: { item: dragItem, index: _dndState.dragging.sourceIndex, el },\n })\n );\n };\n\n // Drag end\n const dragendHandler = () => {\n // Remove drag class from this element and all selected items\n dragClass.split(/\\s+/).filter(Boolean).forEach((c) => el.classList.remove(c));\n const group = el.getAttribute(\"drag-group\");\n if (group && _dndState.selected.has(group)) {\n for (const s of _dndState.selected.get(group)) {\n dragClass.split(/\\s+/).filter(Boolean).forEach((c) => s.el.classList.remove(c));\n }\n }\n\n // Ghost class cleanup\n if (ghostClass && imageSel && imageSel !== \"none\") {\n const imgEl = el.querySelector(imageSel);\n if (imgEl) imgEl.classList.remove(ghostClass);\n }\n\n // Dispatch custom event\n el.dispatchEvent(\n new CustomEvent(\"nojs:dnd-end\", {\n bubbles: true,\n detail: {\n item: _dndState.dragging?.item,\n index: _dndState.dragging?.sourceIndex,\n dropped: _dndState.dragging === null,\n },\n })\n );\n\n // Clear dragging state\n _dndState.dragging = null;\n _removePlaceholder();\n };\n\n el.addEventListener(\"dragstart\", dragstartHandler);\n el.addEventListener(\"dragend\", dragendHandler);\n addDisposer(el, () => {\n el.removeEventListener(\"dragstart\", dragstartHandler);\n el.removeEventListener(\"dragend\", dragendHandler);\n });\n\n // Reactive disabled toggle\n if (disabledExpr) {\n function updateDisabled() {\n const disabled = !!NoJS.evaluate(disabledExpr, ctx);\n el.draggable = !disabled;\n if (disabled) el.removeAttribute(\"aria-roledescription\");\n else el.setAttribute(\"aria-roledescription\", \"draggable item\");\n }\n const unwatchDisabled = ctx.$watch(updateDisabled);\n addDisposer(el, unwatchDisabled);\n }\n\n // Keyboard DnD support\n const keydownHandler = (e) => {\n // Clear stale state from elements removed from DOM\n if (_dndState.dragging && !_dndState.dragging.sourceEl.isConnected) {\n _dndState.dragging = null;\n }\n if (e.key === \" \" && !_dndState.dragging) {\n e.preventDefault();\n const item = NoJS.evaluate(expr, ctx);\n _dndState.dragging = {\n item,\n type,\n effect,\n sourceEl: el,\n sourceCtx: ctx,\n sourceList: null,\n sourceIndex: null,\n listDirective: null,\n };\n dragClass.split(/\\s+/).filter(Boolean).forEach((c) => el.classList.add(c));\n const kbLabel = el.getAttribute(\"aria-label\") || el.textContent?.trim()?.slice(0, 50) || \"Item\";\n _announce(`Grabbed ${kbLabel}. Use arrow keys to move.`);\n el.dispatchEvent(\n new CustomEvent(\"nojs:dnd-start\", {\n bubbles: true,\n detail: { item, index: null, el },\n })\n );\n } else if (e.key === \"Escape\" && _dndState.dragging && _dndState.dragging.sourceEl === el) {\n e.preventDefault();\n dragClass.split(/\\s+/).filter(Boolean).forEach((c) => el.classList.remove(c));\n _announce(\"Drag cancelled.\");\n _dndState.dragging = null;\n _removePlaceholder();\n }\n };\n el.addEventListener(\"keydown\", keydownHandler);\n addDisposer(el, () => el.removeEventListener(\"keydown\", keydownHandler));\n },\n });\n}\n\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n// DROP DIRECTIVE\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\nexport function registerDrop(NoJS) {\n _removeCoreStub(NoJS, \"drop\");\n\n NoJS.directive(\"drop\", {\n priority: 15,\n init(el, name, expr) {\n _injectDndStyles();\n const ctx = NoJS.findContext(el);\n\n const acceptAttr = el.getAttribute(\"drop-accept\") || \"default\";\n const dropEffect = el.getAttribute(\"drop-effect\") || \"move\";\n const dropClass = el.getAttribute(\"drop-class\") || \"nojs-drag-over\";\n const rejectClass = el.getAttribute(\"drop-reject-class\") || \"nojs-drop-reject\";\n const disabledExpr = el.getAttribute(\"drop-disabled\");\n const maxExpr = el.getAttribute(\"drop-max\");\n const sortDir = el.getAttribute(\"drop-sort\");\n const placeholderAttr = el.getAttribute(\"drop-placeholder\");\n const placeholderClass = el.getAttribute(\"drop-placeholder-class\");\n\n // Accessibility\n el.setAttribute(\"aria-dropeffect\", dropEffect);\n\n // Track dragenter/dragleave depth for nested elements\n let _enterDepth = 0;\n\n const dragoverHandler = (e) => {\n if (!_dndState.dragging) return;\n\n // Disabled check\n if (disabledExpr && NoJS.evaluate(disabledExpr, ctx)) return;\n\n const typeOk = _isTypeAccepted(_dndState.dragging.type, acceptAttr);\n let maxOk = true;\n if (maxExpr) {\n const max = NoJS.evaluate(maxExpr, ctx);\n const childCount = _countVisibleChildren(el);\n if (typeof max === \"number\" && childCount >= max) maxOk = false;\n }\n\n if (!typeOk || !maxOk) {\n rejectClass.split(/\\s+/).filter(Boolean).forEach((c) => el.classList.add(c));\n dropClass.split(/\\s+/).filter(Boolean).forEach((c) => el.classList.remove(c));\n _removePlaceholder();\n return;\n }\n\n rejectClass.split(/\\s+/).filter(Boolean).forEach((c) => el.classList.remove(c));\n\n e.preventDefault();\n if (e.dataTransfer) e.dataTransfer.dropEffect = dropEffect;\n\n // Sortable: calculate index and show placeholder\n if (sortDir) {\n const idx = _calcDropIndex(el, e.clientX, e.clientY, sortDir);\n if (placeholderAttr) {\n _insertPlaceholder(el, idx, placeholderAttr, placeholderClass);\n }\n // Dispatch throttled drag-over event\n el.dispatchEvent(\n new CustomEvent(\"nojs:dnd-over\", {\n bubbles: false,\n detail: { item: _dndState.dragging.item, index: idx },\n })\n );\n }\n };\n\n const dragenterHandler = (e) => {\n if (!_dndState.dragging) return;\n if (disabledExpr && NoJS.evaluate(disabledExpr, ctx)) return;\n\n _enterDepth++;\n if (_enterDepth === 1) {\n const typeOk = _isTypeAccepted(_dndState.dragging.type, acceptAttr);\n let maxOk = true;\n if (maxExpr) {\n const max = NoJS.evaluate(maxExpr, ctx);\n const childCount = _countVisibleChildren(el);\n if (typeof max === \"number\" && childCount >= max) maxOk = false;\n }\n\n if (typeOk && maxOk) {\n dropClass.split(/\\s+/).filter(Boolean).forEach((c) => el.classList.add(c));\n el.dispatchEvent(\n new CustomEvent(\"nojs:dnd-enter\", {\n bubbles: false,\n detail: { item: _dndState.dragging.item, type: _dndState.dragging.type },\n })\n );\n } else {\n rejectClass.split(/\\s+/).filter(Boolean).forEach((c) => el.classList.add(c));\n }\n }\n };\n\n const dragleaveHandler = (e) => {\n if (!_dndState.dragging) return;\n\n _enterDepth--;\n if (_enterDepth <= 0) {\n _enterDepth = 0;\n dropClass.split(/\\s+/).filter(Boolean).forEach((c) => el.classList.remove(c));\n rejectClass.split(/\\s+/).filter(Boolean).forEach((c) => el.classList.remove(c));\n _removePlaceholder();\n\n el.dispatchEvent(\n new CustomEvent(\"nojs:dnd-leave\", {\n bubbles: false,\n detail: { item: _dndState.dragging.item },\n })\n );\n }\n };\n\n const dropHandler = (e) => {\n e.preventDefault();\n e.stopPropagation();\n _enterDepth = 0;\n\n if (!_dndState.dragging) return;\n if (disabledExpr && NoJS.evaluate(disabledExpr, ctx)) return;\n if (!_isTypeAccepted(_dndState.dragging.type, acceptAttr)) return;\n\n // Max capacity check\n if (maxExpr) {\n const max = NoJS.evaluate(maxExpr, ctx);\n const childCount = _countVisibleChildren(el);\n if (typeof max === \"number\" && childCount >= max) return;\n }\n\n const dragItem = _dndState.dragging.item;\n const dragType = _dndState.dragging.type;\n const dragEffect = _dndState.dragging.effect;\n\n // Calculate drop index\n let dropIndex = 0;\n if (sortDir) {\n dropIndex = _calcDropIndex(el, e.clientX, e.clientY, sortDir);\n }\n\n // Remove visual feedback\n dropClass.split(/\\s+/).filter(Boolean).forEach((c) => el.classList.remove(c));\n rejectClass.split(/\\s+/).filter(Boolean).forEach((c) => el.classList.remove(c));\n _removePlaceholder();\n\n // Execute drop expression with implicit variables\n const extraVars = {\n $drag: dragItem,\n $dragType: dragType,\n $dragEffect: dragEffect,\n $dropIndex: dropIndex,\n $source: {\n list: _dndState.dragging.sourceList,\n index: _dndState.dragging.sourceIndex,\n el: _dndState.dragging.sourceEl,\n },\n $target: { list: null, index: dropIndex, el },\n $el: el,\n };\n\n const execStatement = _internal(NoJS, 'execStatement');\n if (typeof execStatement === 'function') {\n execStatement(expr, ctx, extraVars);\n } else {\n (_internal(NoJS, 'warn') || console.warn)(\n '[nojs-elements] core too old (<1.13.0): internals.execStatement unavailable; drop expression skipped.'\n );\n }\n\n // Clear dragging state BEFORE dispatch to prevent re-entry\n _dndState.dragging = null;\n\n // Dispatch custom event after expression runs\n el.dispatchEvent(\n new CustomEvent(\"nojs:dnd-drop\", {\n bubbles: false,\n detail: {\n item: dragItem,\n index: dropIndex,\n source: extraVars.$source,\n target: extraVars.$target,\n effect: dragEffect,\n },\n })\n );\n };\n\n // Keyboard: Enter/Space to drop when item is grabbed\n const keydownHandler = (e) => {\n if (!_dndState.dragging) return;\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n dropHandler(e);\n }\n };\n\n el.addEventListener(\"dragover\", dragoverHandler);\n el.addEventListener(\"dragenter\", dragenterHandler);\n el.addEventListener(\"dragleave\", dragleaveHandler);\n el.addEventListener(\"drop\", dropHandler);\n el.addEventListener(\"keydown\", keydownHandler);\n addDisposer(el, () => {\n el.removeEventListener(\"dragover\", dragoverHandler);\n el.removeEventListener(\"dragenter\", dragenterHandler);\n el.removeEventListener(\"dragleave\", dragleaveHandler);\n el.removeEventListener(\"drop\", dropHandler);\n el.removeEventListener(\"keydown\", keydownHandler);\n });\n },\n });\n}\n\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n// DRAG-LIST DIRECTIVE (Sortable List Shorthand)\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\nexport function registerDragList(NoJS) {\n _removeCoreStub(NoJS, \"drag-list\");\n\n NoJS.directive(\"drag-list\", {\n priority: 10,\n init(el, name, listPath) {\n _injectDndStyles();\n const ctx = NoJS.findContext(el);\n\n const tplId = el.getAttribute(\"template\");\n const keyProp = el.getAttribute(\"drag-list-key\");\n const itemName = el.getAttribute(\"drag-list-item\") || \"item\";\n const sortDir = el.getAttribute(\"drop-sort\") || \"vertical\";\n const type = el.getAttribute(\"drag-type\") || (\"__draglist_\" + listPath);\n const acceptAttr = el.getAttribute(\"drop-accept\") || type;\n const copyMode = el.hasAttribute(\"drag-list-copy\");\n const removeMode = el.hasAttribute(\"drag-list-remove\");\n const disabledDragExpr = el.getAttribute(\"drag-disabled\");\n const disabledDropExpr = el.getAttribute(\"drop-disabled\");\n const maxExpr = el.getAttribute(\"drop-max\");\n const placeholderAttr = el.getAttribute(\"drop-placeholder\");\n const placeholderClass = el.getAttribute(\"drop-placeholder-class\");\n const dragClass = el.getAttribute(\"drag-class\") || \"nojs-dragging\";\n const dropClass = el.getAttribute(\"drop-class\") || \"nojs-drag-over\";\n const rejectClass = el.getAttribute(\"drop-reject-class\") || \"nojs-drop-reject\";\n const settleClass = el.getAttribute(\"drop-settle-class\") || \"nojs-drop-settle\";\n const emptyClass = el.getAttribute(\"drop-empty-class\") || \"nojs-drag-list-empty\";\n\n // Accessibility\n el.setAttribute(\"role\", \"listbox\");\n el.setAttribute(\"aria-dropeffect\", copyMode ? \"copy\" : \"move\");\n\n // Register for cross-list communication\n const listInfo = { listPath, ctx, el };\n _dragListRegistry.set(el, listInfo);\n addDisposer(el, () => _dragListRegistry.delete(el));\n\n let _enterDepth = 0;\n let _prevList = null;\n\n // \u2500\u2500\u2500 Render items \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n function renderItems() {\n const list = NoJS.resolve(listPath, ctx);\n if (!Array.isArray(list)) return;\n\n // Same reference & items already rendered \u2014 propagate to children\n // without rebuilding the DOM (preserves focus, input state, etc.)\n if (list === _prevList && list.length > 0 && el.children.length > 0) {\n for (const child of el.children) {\n if (child.__ctx && child.__ctx.$notify) child.__ctx.$notify();\n }\n return;\n }\n _prevList = list;\n\n const tpl = tplId ? document.getElementById(tplId) : null;\n if (!tpl) return;\n\n const disposeChildren = _internal(NoJS, 'disposeChildren');\n if (typeof disposeChildren === 'function') disposeChildren(el);\n el.innerHTML = \"\";\n const count = list.length;\n\n list.forEach((item, i) => {\n const childData = {\n [itemName]: item,\n $index: i,\n $count: count,\n $first: i === 0,\n $last: i === count - 1,\n $even: i % 2 === 0,\n $odd: i % 2 !== 0,\n };\n const childCtx = NoJS.createContext(childData, ctx);\n\n const clone = tpl.content.cloneNode(true);\n const wrapper = document.createElement(\"div\");\n wrapper.style.display = \"contents\";\n wrapper.__ctx = childCtx;\n // role=\"option\" goes on the rendered, focusable item (dragEl) below \u2014\n // the display:contents wrapper is not a perceivable a11y node.\n\n // Append clone first so we can access the visible child\n wrapper.appendChild(clone);\n el.appendChild(wrapper);\n\n // The drag source is the first visible child\n // (display:contents wrapper has no box, so draggable must be on a rendered element)\n const dragEl = wrapper.firstElementChild || wrapper;\n dragEl.draggable = true;\n dragEl.setAttribute(\"role\", \"option\");\n dragEl.setAttribute(\"aria-roledescription\", \"draggable item\");\n if (!dragEl.getAttribute(\"tabindex\")) dragEl.setAttribute(\"tabindex\", \"0\");\n\n // Per-item drag handlers (on wrapper so events from dragEl bubble up to them)\n const itemDragstart = (e) => {\n if (disabledDragExpr && NoJS.evaluate(disabledDragExpr, ctx)) {\n e.preventDefault();\n return;\n }\n _dndState.dragging = {\n item,\n type,\n effect: copyMode ? \"copy\" : \"move\",\n sourceEl: wrapper,\n sourceCtx: childCtx,\n sourceList: list,\n sourceIndex: i,\n listDirective: { el, listPath, ctx, keyProp, copyMode, removeMode },\n };\n if (e.dataTransfer) {\n e.dataTransfer.effectAllowed = copyMode ? \"copy\" : \"move\";\n e.dataTransfer.setData(\"text/plain\", \"\");\n }\n dragClass.split(/\\s+/).filter(Boolean).forEach((c) => dragEl.classList.add(c));\n const dlItemLabel = dragEl.getAttribute(\"aria-label\") || dragEl.textContent?.trim()?.slice(0, 50) || \"Item\";\n _announce(`Grabbed ${dlItemLabel}. Use arrow keys to reorder.`);\n\n el.dispatchEvent(\n new CustomEvent(\"nojs:dnd-start\", {\n bubbles: true,\n detail: { item, index: i, el: dragEl },\n })\n );\n };\n\n const itemDragend = () => {\n dragClass.split(/\\s+/).filter(Boolean).forEach((c) => dragEl.classList.remove(c));\n\n // If drag-list-remove and item was NOT dropped in a target, no action\n // If dragging state is still set, it wasn't dropped\n if (_dndState.dragging && _dndState.dragging.sourceEl === wrapper) {\n _dndState.dragging = null;\n }\n _removePlaceholder();\n };\n\n wrapper.addEventListener(\"dragstart\", itemDragstart);\n wrapper.addEventListener(\"dragend\", itemDragend);\n\n // Keyboard DnD on items\n const itemKeydown = (e) => {\n if (e.key === \" \" && !_dndState.dragging) {\n e.preventDefault();\n // Stop the grab keypress from bubbling to the list container's\n // Enter/Space drop handler, which would otherwise immediately drop\n // the item we just grabbed (grab + drop in one keystroke).\n e.stopPropagation();\n _dndState.dragging = {\n item,\n type,\n effect: copyMode ? \"copy\" : \"move\",\n sourceEl: wrapper,\n sourceCtx: childCtx,\n sourceList: list,\n sourceIndex: i,\n listDirective: { el, listPath, ctx, keyProp, copyMode, removeMode },\n };\n dragClass.split(/\\s+/).filter(Boolean).forEach((c) => dragEl.classList.add(c));\n const kbDlItemLabel = dragEl.getAttribute(\"aria-label\") || dragEl.textContent?.trim()?.slice(0, 50) || \"Item\";\n _announce(`Grabbed ${kbDlItemLabel}. Use arrow keys to reorder.`);\n } else if (e.key === \"Escape\" && _dndState.dragging) {\n e.preventDefault();\n e.stopPropagation();\n // Reset the grabbed item's visual state. Resolve by the live DOM\n // (nojs-dragging class within this list) so a re-render that swapped\n // the wrapper between grab and cancel can't strand the dragging flag.\n const grabbedEl =\n el.querySelector(`.${dragClass.split(/\\s+/)[0]}`) || dragEl;\n dragClass.split(/\\s+/).filter(Boolean).forEach((c) => grabbedEl.classList.remove(c));\n _announce(\"Reorder cancelled.\");\n _dndState.dragging = null;\n _removePlaceholder();\n } else if ((e.key === \"ArrowDown\" || e.key === \"ArrowRight\") && _dndState.dragging && _dndState.dragging.sourceEl === wrapper) {\n e.preventDefault();\n // Navigate to next item via wrapper siblings\n const nextWrapper = wrapper.nextElementSibling;\n if (nextWrapper) {\n const nextEl = nextWrapper.firstElementChild || nextWrapper;\n nextEl.focus();\n const siblings = [...el.children].filter(c => !c.classList.contains(\"nojs-drop-placeholder\"));\n const pos = siblings.indexOf(nextWrapper) + 1;\n _announce(`Moved to position ${pos} of ${siblings.length}.`);\n }\n } else if ((e.key === \"ArrowUp\" || e.key === \"ArrowLeft\") && _dndState.dragging && _dndState.dragging.sourceEl === wrapper) {\n e.preventDefault();\n const prevWrapper = wrapper.previousElementSibling;\n if (prevWrapper) {\n const prevEl = prevWrapper.firstElementChild || prevWrapper;\n prevEl.focus();\n const siblings = [...el.children].filter(c => !c.classList.contains(\"nojs-drop-placeholder\"));\n const pos = siblings.indexOf(prevWrapper) + 1;\n _announce(`Moved to position ${pos} of ${siblings.length}.`);\n }\n }\n };\n wrapper.addEventListener(\"keydown\", itemKeydown);\n\n // Register cleanup on wrapper so disposers run when disposeChildren(el) is called\n wrapper.__disposers = wrapper.__disposers || [];\n wrapper.__disposers.push(\n () => wrapper.removeEventListener(\"dragstart\", itemDragstart),\n () => wrapper.removeEventListener(\"dragend\", itemDragend),\n () => wrapper.removeEventListener(\"keydown\", itemKeydown),\n );\n\n NoJS.processTree(wrapper);\n });\n\n // Toggle empty class so the container remains a viable drop target\n const isEmpty = list.length === 0;\n emptyClass.split(/\\s+/).filter(Boolean).forEach((c) => el.classList.toggle(c, isEmpty));\n }\n\n // \u2500\u2500\u2500 Drop zone handlers on the list container \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const dragoverHandler = (e) => {\n if (!_dndState.dragging) return;\n if (disabledDropExpr && NoJS.evaluate(disabledDropExpr, ctx)) return;\n\n const typeOk = _isTypeAccepted(_dndState.dragging.type, acceptAttr);\n let maxOk = true;\n if (maxExpr) {\n const max = NoJS.evaluate(maxExpr, ctx);\n const list = NoJS.resolve(listPath, ctx);\n if (typeof max === \"number\" && Array.isArray(list) && list.length >= max) maxOk = false;\n }\n\n if (!typeOk || !maxOk) {\n rejectClass.split(/\\s+/).filter(Boolean).forEach((c) => el.classList.add(c));\n dropClass.split(/\\s+/).filter(Boolean).forEach((c) => el.classList.remove(c));\n _removePlaceholder();\n return;\n }\n\n rejectClass.split(/\\s+/).filter(Boolean).forEach((c) => el.classList.remove(c));\n\n e.preventDefault();\n if (e.dataTransfer) e.dataTransfer.dropEffect = copyMode ? \"copy\" : \"move\";\n\n const idx = _calcDropIndex(el, e.clientX, e.clientY, sortDir);\n if (placeholderAttr) {\n _insertPlaceholder(el, idx, placeholderAttr, placeholderClass);\n }\n };\n\n const dragenterHandler = (e) => {\n if (!_dndState.dragging) return;\n if (disabledDropExpr && NoJS.evaluate(disabledDropExpr, ctx)) return;\n\n _enterDepth++;\n if (_enterDepth === 1) {\n const typeOk = _isTypeAccepted(_dndState.dragging.type, acceptAttr);\n let maxOk = true;\n if (maxExpr) {\n const max = NoJS.evaluate(maxExpr, ctx);\n const list = NoJS.resolve(listPath, ctx);\n if (typeof max === \"number\" && Array.isArray(list) && list.length >= max) maxOk = false;\n }\n\n if (typeOk && maxOk) {\n dropClass.split(/\\s+/).filter(Boolean).forEach((c) => el.classList.add(c));\n el.dispatchEvent(\n new CustomEvent(\"nojs:dnd-enter\", {\n bubbles: false,\n detail: { item: _dndState.dragging.item, type: _dndState.dragging.type },\n })\n );\n } else {\n rejectClass.split(/\\s+/).filter(Boolean).forEach((c) => el.classList.add(c));\n }\n }\n };\n\n const dragleaveHandler = () => {\n if (!_dndState.dragging) return;\n _enterDepth--;\n if (_enterDepth <= 0) {\n _enterDepth = 0;\n dropClass.split(/\\s+/).filter(Boolean).forEach((c) => el.classList.remove(c));\n rejectClass.split(/\\s+/).filter(Boolean).forEach((c) => el.classList.remove(c));\n _removePlaceholder();\n el.dispatchEvent(\n new CustomEvent(\"nojs:dnd-leave\", {\n bubbles: false,\n detail: { item: _dndState.dragging?.item },\n })\n );\n }\n };\n\n const dropHandler = (e) => {\n e.preventDefault();\n e.stopPropagation();\n _enterDepth = 0;\n\n if (!_dndState.dragging) return;\n if (disabledDropExpr && NoJS.evaluate(disabledDropExpr, ctx)) return;\n if (!_isTypeAccepted(_dndState.dragging.type, acceptAttr)) return;\n\n // Max check\n if (maxExpr) {\n const max = NoJS.evaluate(maxExpr, ctx);\n const list = NoJS.resolve(listPath, ctx);\n if (typeof max === \"number\" && Array.isArray(list) && list.length >= max) return;\n }\n\n const dragItem = _dndState.dragging.item;\n const sourceInfo = _dndState.dragging.listDirective;\n const sourceIndex = _dndState.dragging.sourceIndex;\n\n const dropIndex = _calcDropIndex(el, e.clientX, e.clientY, sortDir);\n\n // Remove visual feedback\n dropClass.split(/\\s+/).filter(Boolean).forEach((c) => el.classList.remove(c));\n rejectClass.split(/\\s+/).filter(Boolean).forEach((c) => el.classList.remove(c));\n _removePlaceholder();\n\n const targetList = NoJS.resolve(listPath, ctx);\n if (!Array.isArray(targetList)) return;\n\n // Self-drop check: same list, same position\n const isSameList = sourceInfo && sourceInfo.el === el;\n if (isSameList && sourceIndex === dropIndex) {\n _dndState.dragging = null;\n return;\n }\n // Same list, but adjacent position (effectively same position)\n if (isSameList && sourceIndex + 1 === dropIndex) {\n _dndState.dragging = null;\n return;\n }\n\n // Perform the list mutation\n let newTargetList = [...targetList];\n\n if (isSameList) {\n // Same-list reorder\n const [moved] = newTargetList.splice(sourceIndex, 1);\n const insertAt = sourceIndex < dropIndex ? dropIndex - 1 : dropIndex;\n newTargetList.splice(insertAt, 0, moved);\n ctx.$set(listPath, newTargetList);\n\n el.dispatchEvent(\n new CustomEvent(\"nojs:dnd-reorder\", {\n bubbles: true,\n detail: { list: newTargetList, item: dragItem, from: sourceIndex, to: insertAt },\n })\n );\n } else {\n // Cross-list transfer\n const itemToInsert = copyMode ? (typeof dragItem === \"object\" ? { ...dragItem } : dragItem) : dragItem;\n newTargetList.splice(dropIndex, 0, itemToInsert);\n ctx.$set(listPath, newTargetList);\n\n // Remove from source if move mode\n if (sourceInfo && !sourceInfo.copyMode && (removeMode || sourceInfo.removeMode)) {\n const sourceList = NoJS.resolve(sourceInfo.listPath, sourceInfo.ctx);\n if (Array.isArray(sourceList) && sourceIndex != null) {\n const newSourceList = sourceList.filter((_, idx) => idx !== sourceIndex);\n sourceInfo.ctx.$set(sourceInfo.listPath, newSourceList);\n\n sourceInfo.el.dispatchEvent(\n new CustomEvent(\"nojs:dnd-remove\", {\n bubbles: true,\n detail: { list: newSourceList, item: dragItem, index: sourceIndex },\n })\n );\n }\n }\n\n el.dispatchEvent(\n new CustomEvent(\"nojs:dnd-receive\", {\n bubbles: true,\n detail: {\n list: newTargetList,\n item: dragItem,\n from: sourceIndex,\n fromList: sourceInfo ? NoJS.resolve(sourceInfo.listPath, sourceInfo.ctx) : null,\n },\n })\n );\n }\n\n // Announce drop for screen readers (WCAG 4.1.3)\n const dlDropLabel =\n (_dndState.dragging?.sourceEl?.firstElementChild?.getAttribute(\"aria-label\") ||\n _dndState.dragging?.sourceEl?.firstElementChild?.textContent?.trim()?.slice(0, 50)) || \"Item\";\n const finalPos = isSameList ? (sourceIndex < dropIndex ? dropIndex : dropIndex + 1) : dropIndex + 1;\n _announce(`Dropped ${dlDropLabel} at position ${finalPos}.`);\n\n // Settle animation (apply to visible child, not display:contents wrapper)\n requestAnimationFrame(() => {\n const children = [...el.children];\n const targetChild = children[isSameList ? (sourceIndex < dropIndex ? dropIndex - 1 : dropIndex) : dropIndex];\n if (targetChild) {\n const animEl = targetChild.firstElementChild || targetChild;\n settleClass.split(/\\s+/).filter(Boolean).forEach((c) => animEl.classList.add(c));\n animEl.addEventListener(\"animationend\", () => {\n settleClass.split(/\\s+/).filter(Boolean).forEach((c) => animEl.classList.remove(c));\n }, { once: true });\n }\n });\n\n // Clear dragging state\n _dndState.dragging = null;\n };\n\n // Keyboard: Enter/Space to drop\n const keydownHandler = (e) => {\n if (!_dndState.dragging) return;\n if (!_isTypeAccepted(_dndState.dragging.type, acceptAttr)) return;\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n // Simulate drop at the focused element's position\n const focused = el.querySelector(\":focus\");\n if (focused) {\n const measured = focused.style?.display === \"contents\"\n ? (focused.firstElementChild || focused) : focused;\n const rect = measured.getBoundingClientRect();\n const fakeEvent = {\n preventDefault() {},\n stopPropagation() {},\n clientX: rect.left + rect.width / 2,\n clientY: rect.top + rect.height + 1,\n dataTransfer: null,\n };\n dropHandler(fakeEvent);\n }\n }\n };\n\n el.addEventListener(\"dragover\", dragoverHandler);\n el.addEventListener(\"dragenter\", dragenterHandler);\n el.addEventListener(\"dragleave\", dragleaveHandler);\n el.addEventListener(\"drop\", dropHandler);\n el.addEventListener(\"keydown\", keydownHandler);\n addDisposer(el, () => {\n el.removeEventListener(\"dragover\", dragoverHandler);\n el.removeEventListener(\"dragenter\", dragenterHandler);\n el.removeEventListener(\"dragleave\", dragleaveHandler);\n el.removeEventListener(\"drop\", dropHandler);\n el.removeEventListener(\"keydown\", keydownHandler);\n });\n\n // \u2500\u2500\u2500 Reactive rendering \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const unwatchList = ctx.$watch(renderItems);\n addDisposer(el, unwatchList);\n renderItems();\n },\n });\n}\n\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n// DRAG-MULTIPLE DIRECTIVE\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\nexport function registerDragMultiple(NoJS) {\n _removeCoreStub(NoJS, \"drag-multiple\");\n\n NoJS.directive(\"drag-multiple\", {\n priority: 16,\n init(el, name) {\n const ctx = NoJS.findContext(el);\n const group = el.getAttribute(\"drag-group\");\n const selectClass = el.getAttribute(\"drag-multiple-class\") || \"nojs-selected\";\n\n if (!group) {\n (_internal(NoJS, 'warn') || console.warn)(\"drag-multiple requires drag-group attribute\");\n return;\n }\n\n // Initialize group set if needed\n if (!_dndState.selected.has(group)) {\n _dndState.selected.set(group, new Set());\n }\n const selectedSet = _dndState.selected.get(group);\n\n const clickHandler = (e) => {\n const dragExpr = el.getAttribute(\"drag\");\n const item = dragExpr ? NoJS.evaluate(dragExpr, ctx) : null;\n const entry = { item, el, ctx };\n\n if (e.ctrlKey || e.metaKey) {\n // Additive selection\n const existing = [...selectedSet].find((s) => s.el === el);\n if (existing) {\n selectedSet.delete(existing);\n selectClass.split(/\\s+/).filter(Boolean).forEach((c) => el.classList.remove(c));\n } else {\n selectedSet.add(entry);\n selectClass.split(/\\s+/).filter(Boolean).forEach((c) => el.classList.add(c));\n }\n } else {\n // Replace selection\n for (const s of selectedSet) {\n selectClass.split(/\\s+/).filter(Boolean).forEach((c) => s.el.classList.remove(c));\n }\n selectedSet.clear();\n selectedSet.add(entry);\n selectClass.split(/\\s+/).filter(Boolean).forEach((c) => el.classList.add(c));\n }\n };\n\n el.addEventListener(\"click\", clickHandler);\n addDisposer(el, () => {\n el.removeEventListener(\"click\", clickHandler);\n // Remove this element from the selection set\n const existing = [...selectedSet].find((s) => s.el === el);\n if (existing) selectedSet.delete(existing);\n });\n\n // Escape clears selection for this group\n const escHandler = (e) => {\n if (e.key === \"Escape\") {\n for (const s of selectedSet) {\n selectClass.split(/\\s+/).filter(Boolean).forEach((c) => s.el.classList.remove(c));\n }\n selectedSet.clear();\n }\n };\n window.addEventListener(\"keydown\", escHandler);\n addDisposer(el, () => window.removeEventListener(\"keydown\", escHandler));\n },\n });\n}\n", "import { registerDrag, registerDrop, registerDragList, registerDragMultiple } from \"./element.js\";\nimport { resetDndState } from \"./state.js\";\n\nexport function registerDnd(NoJS, options = {}) {\n registerDrag(NoJS);\n registerDrop(NoJS);\n registerDragList(NoJS);\n registerDragMultiple(NoJS);\n}\n\nexport function cleanupDnd() {\n resetDndState();\n}\n", "// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n// Module-scoped state for validate directive\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\n// \u2500\u2500 ValidityState \u2192 rule name mapping \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport const _validityMap = [\n [\"valueMissing\", \"required\"],\n [\"typeMismatch\", null], // resolved to input type at runtime\n [\"tooShort\", \"minlength\"],\n [\"tooLong\", \"maxlength\"],\n [\"patternMismatch\", \"pattern\"],\n [\"rangeUnderflow\", \"min\"],\n [\"rangeOverflow\", \"max\"],\n [\"stepMismatch\", \"step\"],\n];\n\n// \u2500\u2500 Priority order for error display \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport const _rulePriority = [\n \"required\", \"email\", \"url\", \"number\", \"date\", \"time\",\n \"datetime-local\", \"month\", \"week\", \"tel\",\n \"minlength\", \"maxlength\", \"pattern\", \"min\", \"max\", \"step\",\n];\n\nexport function resetValidateState() {\n // _validityMap and _rulePriority are static constants \u2014 nothing to reset.\n // This function exists for API consistency with other modules and to\n // allow future mutable state (e.g. pending async validators) to be\n // cleaned up here.\n}\n", "// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n// DIRECTIVE: validate (priority 30)\n// Extracted from NoJS Core \u2014 full form + field-level validation.\n// HELPERS: _validateField, _getValidityErrors, _resolveErrorMessage\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\nimport { _validityMap, _rulePriority } from \"./state.js\";\nimport { _internal } from \"../_compat.js\";\n\n// \u2500\u2500 Disposer helper (Elements pattern) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nfunction addDisposer(el, fn) {\n el.__disposers = el.__disposers || [];\n el.__disposers.push(fn);\n}\n\n// \u2500\u2500 Kept at module scope so helpers can reference them after init \u2500\u2500\u2500\u2500\u2500\nlet _validators;\nlet _evaluate;\nlet _createContext;\nlet _findContext;\nlet _processTree;\nlet _cloneTemplate;\nlet _disposeChildren;\nlet _disposeTree;\nlet _warn;\n\n// \u2500\u2500 Reset the __declared marker so processTree re-processes a subtree \u2500\u2500\n// Mirrors core's dom._clearDeclared (not exposed on internals). On a fresh\n// clone this is a no-op; it is the safety net for the dispose-before-reprocess\n// path so re-rendered wrappers get fully re-bound.\nfunction _clearDeclared(el) {\n const walker = document.createTreeWalker(el, NodeFilter.SHOW_ELEMENT);\n while (walker.nextNode()) walker.currentNode.__declared = false;\n}\n\n// \u2500\u2500 Helper: get field input type \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nfunction _getFieldType(field) {\n return (field.getAttribute(\"type\") || \"text\").toLowerCase();\n}\n\n// \u2500\u2500 Get all failing rules from ValidityState + NoJS validators \u2500\u2500\u2500\u2500\u2500\u2500\u2500\nfunction _getValidityErrors(field, allValues) {\n const errors = [];\n const seenRules = new Set();\n\n // First, check NoJS-specific validators from validate=\"\" attribute\n // (these take priority over native ValidityState messages)\n const rules = field.getAttribute(\"validate\");\n if (rules) {\n const ruleList = rules.split(\"|\").map((r) => r.trim());\n for (const rule of ruleList) {\n const [name, ...args] = rule.split(\":\");\n const fn = _validators[name];\n if (fn) {\n const result = fn(field.value, ...args, allValues);\n if (result !== true && result) {\n errors.push({ rule: name, message: result });\n seenRules.add(name);\n }\n } else {\n // Built-in NoJS validators (backward compat + NoJS-only)\n const value = field.value;\n let msg = null;\n switch (name) {\n case \"required\":\n if (value == null || String(value).trim() === \"\") msg = \"Required\";\n break;\n case \"email\":\n if (value && !/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(value)) msg = \"Invalid email\";\n break;\n case \"url\":\n try { new URL(value); } catch { msg = \"Invalid URL\"; }\n break;\n case \"min\":\n if (Number(value) < Number(args[0])) msg = `Minimum value is ${args[0]}`;\n break;\n case \"max\":\n if (Number(value) > Number(args[0])) msg = `Maximum value is ${args[0]}`;\n break;\n case \"custom\":\n if (args[0] && _validators[args[0]]) {\n const result = _validators[args[0]](value, allValues);\n if (result !== true && result) msg = result;\n }\n break;\n }\n if (msg) {\n errors.push({ rule: name, message: msg });\n seenRules.add(name);\n }\n }\n }\n }\n\n // Then, check native ValidityState (skip rules already covered by NoJS validators)\n const validity = field.validity;\n if (validity && !validity.valid) {\n for (const [prop, ruleName] of _validityMap) {\n if (validity[prop]) {\n const name = ruleName || _getFieldType(field);\n if (!seenRules.has(name)) {\n errors.push({ rule: name, message: field.validationMessage });\n seenRules.add(name);\n }\n }\n }\n }\n\n return errors;\n}\n\n// \u2500\u2500 Resolve error message: error-{rule} attr \u2192 error attr \u2192 default \u2500\u2500\nfunction _resolveErrorMessage(field, ruleName, defaultMsg) {\n const perRule = field.getAttribute(`error-${ruleName}`);\n if (perRule) return perRule;\n const generic = field.getAttribute(\"error\");\n if (generic && !generic.startsWith(\"#\")) return generic;\n return defaultMsg;\n}\n\n// \u2500\u2500 Pick the highest-priority error from a list \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nfunction _pickError(errors, field) {\n if (!errors.length) return null;\n\n // Sort by priority\n const sorted = [...errors].sort((a, b) => {\n const ai = _rulePriority.indexOf(a.rule);\n const bi = _rulePriority.indexOf(b.rule);\n return (ai === -1 ? 999 : ai) - (bi === -1 ? 999 : bi);\n });\n\n const top = sorted[0];\n return {\n rule: top.rule,\n message: _resolveErrorMessage(field, top.rule, top.message),\n };\n}\n\n// \u2500\u2500 Find the rendered error wrapper for a field \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Prefer the closest