@livenetworks/ashlar 2.0.2 → 2.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- var LnAshlarComponent=(function(y){"use strict";function L(){return typeof window>"u"?!1:window.lnDebug===!0||window.lnCore&&window.lnCore._debugSink?!0:typeof document<"u"&&document.body?document.body.hasAttribute("data-ln-debug")||document.body.querySelector("[data-ln-debug]")!==null:!1}function A(t){if(typeof window>"u")return!1;if(window.lnDebug===!0)return!0;if(window.lnCore&&window.lnCore._debugIsContained)return t?window.lnCore._debugIsContained(t):window.lnCore._debugSink!==null;if(t&&t.closest){const e=t.closest("[data-ln-debug]");return!(!e||typeof document<"u"&&e===document.documentElement)}return typeof document<"u"&&document.body?document.body.hasAttribute("data-ln-debug"):!1}if(typeof window<"u"&&(window.lnCore=window.lnCore||{},!window.lnCore._warnBound)){window.lnCore._warnBound=!0;const t=console.warn;console.warn=function(...e){if(typeof e[0]=="string"&&(e[0].startsWith("[ln-")||e[0].startsWith("[lnCore"))){let a=null;for(let r=1;r<e.length;r++)if(e[r]&&e[r].nodeType===1){a=e[r];break}if(!A(a))return}t.apply(console,e)}}function Y(t,e){window.lnCore=window.lnCore||{},window.lnCore._debugSink=t,window.lnCore._debugIsContained=e||null}function Z(t,e,n){const a=n||{};window.lnCore._debugSink&&window.lnCore._debugSink("event",e,t,a),t.dispatchEvent(new CustomEvent(e,{bubbles:!0,detail:a}))}function p(t,e){if(!document.body){document.addEventListener("DOMContentLoaded",function(){p(t,e)}),console.warn("["+e+'] Script loaded before <body> — add "defer" to your <script> tag');return}t()}const M={};function tt(t,e){M[t]=e}function et(t){return M[t]||{ingress:e=>e,egress:e=>e}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerDataMapper=tt,window.lnCore.getDataMapper=et);function nt(){typeof window>"u"||(window.lnCore=window.lnCore||{},!window.lnCore._localeObserverBound&&(window.lnCore._localeObserverBound=!0,p(function(){new MutationObserver(function(){Z(document,"ln-core:locale-change",{})}).observe(document.documentElement,{attributes:!0,attributeFilter:["lang"],subtree:!0})},"ln-core")))}const R={};function at(t,e){if(!t||typeof e!="object")return;const n=t.toLowerCase().split("-")[0];R[n]=e}function lt(t){if(!t)return null;const e=t.toLowerCase().split("-")[0];return R[e]||null}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerLocaleFallback=at,window.lnCore.getLocaleFallback=lt,window.lnCore.ensureLocaleObserver=nt);const S={};function ot(t,e){S[t]||(S[t]=document.querySelector('[data-ln-template="'+t+'"]'));const n=S[t];return n?n.content.cloneNode(!0):(console.warn("["+(e||"ln-core")+'] Template "'+t+'" not found'),null)}function W(t,e){if(!t||!e)return t;const n=t.querySelectorAll("[data-ln-field]");for(let o=0;o<n.length;o++){const d=n[o],i=d.getAttribute("data-ln-field");e[i]!=null&&(d.textContent=e[i])}const a=t.querySelectorAll("[data-ln-attr]");for(let o=0;o<a.length;o++){const d=a[o],i=d.getAttribute("data-ln-attr").split(",");for(let s=0;s<i.length;s++){const c=i[s].trim().split(":");if(c.length!==2)continue;const u=c[0].trim(),f=c[1].trim();e[f]!=null&&d.setAttribute(u,e[f])}}const r=t.querySelectorAll("[data-ln-show]");for(let o=0;o<r.length;o++){const d=r[o],i=d.getAttribute("data-ln-show");i in e&&d.classList.toggle("hidden",!e[i])}const l=t.querySelectorAll("[data-ln-class]");for(let o=0;o<l.length;o++){const d=l[o],i=d.getAttribute("data-ln-class").split(",");for(let s=0;s<i.length;s++){const c=i[s].trim().split(":");if(c.length!==2)continue;const u=c[0].trim(),f=c[1].trim();f in e&&d.classList.toggle(u,!!e[f])}}return t}function rt(t,e){t.matches&&t.matches("[data-ln-form], [data-ln-fillable]")&&(window.lnCore._debugSink&&window.lnCore._debugSink("event","ln-fill",t,e??null),t.dispatchEvent(new CustomEvent("ln-fill",{detail:e??null,bubbles:!0})));const n=t.querySelectorAll("[data-ln-form], [data-ln-fillable]");for(let a=0;a<n.length;a++)window.lnCore._debugSink&&window.lnCore._debugSink("event","ln-fill",n[a],e??null),n[a].dispatchEvent(new CustomEvent("ln-fill",{detail:e??null,bubbles:!0}));return t}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore._fillBound||(window.lnCore._fillBound=!0,document.addEventListener("ln-fill",function(t){if(!(!t.target.matches||!t.target.matches("[data-ln-fillable]")))if(t.detail)W(t.target,t.detail);else{const e=t.target.querySelectorAll("[data-ln-field]");for(let n=0;n<e.length;n++)e[n].textContent=""}})));function j(t,e){if(!t||!e)return t;const n=document.createTreeWalker(t,NodeFilter.SHOW_TEXT);for(;n.nextNode();){const l=n.currentNode;l.textContent.indexOf("{{")!==-1&&(l.textContent=l.textContent.replace(/\{\{\s*(\w+)\s*\}\}/g,function(o,d){return e[d]!==void 0?e[d]:""}))}const a=function(l,o){return e[o]!==void 0?e[o]:""},r=Array.from(t.querySelectorAll("*"));t.nodeType===1&&r.push(t);for(let l=0;l<r.length;l++){const o=r[l],d=o.attributes;for(let i=0;i<d.length;i++){const s=d[i];s.value.indexOf("{{")!==-1&&o.setAttribute(s.name,s.value.replace(/\{\{\s*(\w+)\s*\}\}/g,a))}}return t}function it(t,e,n,a,r,l){const o={};for(let i=0;i<t.children.length;i++){const s=t.children[i],c=s.getAttribute("data-ln-render-key");c&&(o[c]=s)}const d=document.createDocumentFragment();for(let i=0;i<e.length;i++){const s=e[i],c=String(a(s));let u=o[c];if(u)r(u,s,i);else{const f=ot(n,l);if(!f||(j(f,s),u=f.firstElementChild,!u))continue;u.setAttribute("data-ln-render-key",c),r(u,s,i)}d.appendChild(u)}t.textContent="",t.appendChild(d)}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.fillTemplate=j,window.lnCore.fill=W,window.lnCore.lnFill=rt,window.lnCore.renderList=it);function B(t,e,n,a,r){if(!t||e===null)return!0;const l=a||"ln-component",o=t.type;if(o==="trigger"||o==="marker"||o==="string"||o==="list"||!o||e===""&&t.fallback!==void 0)return!0;const d=i=>{r?console.warn(i,r):console.warn(i)};if(o==="boolean"){const i=e.trim().toLowerCase();return i!==""&&i!=="true"&&i!=="false"&&i!=="1"&&i!=="0"?(d(`[${l}] Invalid value "${e}" for boolean attribute "${n}". Allowed: "true", "false", or presence-only.`),!1):!0}if(o==="enum"){const i=t.values||[];return i.includes(e)?!0:(d(`[${l}] Invalid value "${e}" for attribute "${n}". Allowed: ${i.join(", ")}. Fallback: "${t.fallback}".`),!1)}if(o==="integer"){if(!/^-?\d+$/.test(e))return d(`[${l}] Invalid integer "${e}" for attribute "${n}". Fallback: ${t.fallback}.`),!1;const i=parseInt(e,10);return t.min!==void 0&&i<t.min?(d(`[${l}] Value ${i} for attribute "${n}" is less than min (${t.min}).`),!1):t.max!==void 0&&i>t.max?(d(`[${l}] Value ${i} for attribute "${n}" is greater than max (${t.max}).`),!1):!0}if(o==="float")return isNaN(Number(e))?(d(`[${l}] Invalid float "${e}" for attribute "${n}". Fallback: ${t.fallback}.`),!1):!0;if(o==="json")try{return JSON.parse(e),!0}catch(i){return d(`[${l}] Invalid JSON for attribute "${n}": ${i.message}. Fallback: ${t.fallback}.`),!1}return!0}function dt(t){const e={};for(const n in t){const a=t[n];a&&a.effect&&(e[n]=a.effect)}return Object.keys(e).length?e:null}function st(t){if(t.onAttrChange&&!t.declared)return null;const e=new Set;if(t.effects)for(const n in t.effects)e.add(n);if(t.onAttrChange&&t.declared)for(const n of t.declared)e.add(n);return e}function _(t,e,n,a){if(t.nodeType!==1)return;const l=e.indexOf("[")!==-1||e.indexOf(".")!==-1||e.indexOf("#")!==-1?e:"["+e+"]",o=Array.from(t.querySelectorAll(l));t.matches&&t.matches(l)&&o.push(t);for(const d of o)if(!d[n]){window.lnCore._persistSink&&d.hasAttribute("data-ln-persist")&&window.lnCore._persistSink(d,e);try{d[n]=new a(d)}catch(i){console.error("["+n+"] init failed",d,i)}}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore._bootHolds=window.lnCore._bootHolds||0,window.lnCore._bootQueue=window.lnCore._bootQueue||[]);function N(){return typeof window<"u"&&window.lnCore&&window.lnCore._bootHolds||0}function F(t){typeof window<"u"?(window.lnCore=window.lnCore||{},window.lnCore._bootHolds=window.lnCore._bootHolds||0,window.lnCore._bootQueue=window.lnCore._bootQueue||[],window.lnCore._bootHolds>0?window.lnCore._bootQueue.push(t):setTimeout(t,0)):t()}function V(){window.lnCore=window.lnCore||{};const t=window.lnCore._attrRegistry=window.lnCore._attrRegistry||{byAttr:new Map,reactive:[],persist:[]};return t.byReactive=t.byReactive||new Map,t.reactiveWildcard=t.reactiveWildcard||[],t}function H(t){const e=V(),n=t.observed||[];for(let a=0;a<n.length;a++){const r=n[a];e.byAttr.has(r)||e.byAttr.set(r,[]),e.byAttr.get(r).push(t)}if(e.byDeclaredAttr=e.byDeclaredAttr||new Map,t.attributes)for(const a in t.attributes){e.byDeclaredAttr.has(a)||e.byDeclaredAttr.set(a,[]);const r=e.byDeclaredAttr.get(a);r.some(l=>l.componentTag===t.componentTag)||r.push({spec:t.attributes[a],componentTag:t.componentTag})}if(t.onAttrChange||t.effects){e.reactive.push(t);const a=st(t);if(a===null)e.reactiveWildcard.push(t);else for(const r of a)e.byReactive.has(r)||e.byReactive.set(r,[]),e.byReactive.get(r).push(t)}t.persist&&e.persist.push(t)}function U(t,e,n,a){for(let r=0;r<t.length;r++){const l=t[r];if(!e[l.attribute])continue;const o=l.effects&&l.effects[n];o?o(e,n,a):l.onAttrChange&&(!l.declared||l.declared.has(n))&&l.onAttrChange(e,n,a)}}function ct(t){const e=t.target,n=t.attributeName;if(t.oldValue===e.getAttribute(n))return;const a=V(),r=a.byAttr.get(n);if(L()&&a.byDeclaredAttr&&a.byDeclaredAttr.has(n)&&A(e)){const l=a.byDeclaredAttr.get(n),o=e.getAttribute(n);for(let d=0;d<l.length;d++)B(l[d].spec,o,n,l[d].componentTag,e)}if(window.lnCore._debugSink&&(n.indexOf("data-ln-")===0||r)&&window.lnCore._debugSink("attr",n,e,{oldValue:t.oldValue,newValue:e.getAttribute(n)}),n.indexOf("data-ln-")===0){const l=a.byReactive.get(n);l&&U(l,e,n,t.oldValue),a.reactiveWildcard.length&&U(a.reactiveWildcard,e,n,t.oldValue)}if(r)for(let l=0;l<r.length;l++){const o=r[l];if(o.handler){o.handler(e,n,t.oldValue);continue}o.onAttributeChange&&e[o.attribute]?o.onAttributeChange(e,n):(_(e,o.selector,o.attribute,o.ComponentFn),o.onInit&&o.onInit(e))}}function z(){window.lnCore=window.lnCore||{},!window.lnCore._attrObserverBound&&(window.lnCore._attrObserverBound=!0,p(function(){new MutationObserver(function(e){for(let n=0;n<e.length;n++)try{ct(e[n])}catch(a){console.error("[ln-core] mutation handler failed",e[n].target,a)}}).observe(document.body,{attributes:!0,subtree:!0,attributeOldValue:!0})},"ln-core"))}function G(){return window.lnCore=window.lnCore||{},window.lnCore._lifecycleRegistry=window.lnCore._lifecycleRegistry||[]}function ut(t){const e=G();if(e.length){if(t.target)for(let n=0;n<e.length;n++){const a=e[n];if(a.onSubtreeChange){const r=a.query,l=t.target.nodeType===1?t.target.matches(r)?t.target:t.target.closest(r):t.target.parentElement?t.target.parentElement.closest(r):null;l&&a.onSubtreeChange(l,t)}}for(let n=0;n<t.addedNodes.length;n++){const a=t.addedNodes[n];if(a.nodeType===1)for(let r=0;r<e.length;r++){const l=e[r];_(a,l.selector,l.attribute,l.ComponentFn),l.onInit&&l.onInit(a)}}for(let n=0;n<t.removedNodes.length;n++){const a=t.removedNodes[n];if(a.nodeType===1)for(let r=0;r<e.length;r++){const l=e[r],o=l.query,d=Array.from(a.querySelectorAll(o));a.matches&&a.matches(o)&&d.push(a);for(let i=0;i<d.length;i++){const s=d[i];if(!document.contains(s)){const c=s[l.attribute];if(c&&typeof c.destroy=="function")try{c.destroy()}catch(u){console.error("["+l.attribute+"] destroy failed",s,u)}delete s[l.attribute]}}}}}}function ft(){window.lnCore=window.lnCore||{},!window.lnCore._lifecycleObserverBound&&(window.lnCore._lifecycleObserverBound=!0,p(function(){new MutationObserver(function(e){for(let n=0;n<e.length;n++){const a=e[n];if(a.type==="childList")try{ut(a)}catch(r){console.error("[ln-core] lifecycle handler failed",a.target,r)}}}).observe(document.body,{childList:!0,subtree:!0})},"ln-core"))}function wt(t,e){H({observed:t,handler:e}),z()}function bt(t,e,n,a,r={}){const l=r.extraAttributes||[],o=r.onAttributeChange||null,d=r.onSubtreeChange||null,i=r.onInit||null,s=r.onAttrChange||null,c=r.effects||null,u=r.attributes||null,f=u?dt(u):c,D=u?new Set(Object.keys(u)):null,qt=r.persist||null;function v(E){const w=E||document.body;if(_(w,t,e,n),u&&L())for(const g in u){const Mt=u[g],O=Array.from(w.querySelectorAll("["+g+"]"));w.matches&&w.matches("["+g+"]")&&O.push(w);for(let T=0;T<O.length;T++){const q=O[T];A(q)&&B(Mt,q.getAttribute(g),g,a,q)}}i&&i(w)}const I=[];if(t.indexOf("[")!==-1){const E=/\[([\w-]+)/g;let w;for(;(w=E.exec(t))!==null;)I.push(w[1])}else I.push(t);H({selector:t,attribute:e,componentTag:a,attributes:u,ComponentFn:n,onInit:i,observed:I.concat(l),onAttributeChange:o,onAttrChange:s,effects:f,declared:D,persist:qt}),z();const Lt=t.indexOf("[")!==-1||t.indexOf(".")!==-1||t.indexOf("#")!==-1?t:"["+t+"]";G().push({selector:t,attribute:e,ComponentFn:n,onInit:i,onSubtreeChange:d,query:Lt}),ft(),window[e]=v;function X(){N()>0?F(function(){v(document.body)}):v(document.body)}return document.readyState==="loading"?document.addEventListener("DOMContentLoaded",X):X(),v}function Q(t){return(t||"").replace(/^#/,"")}function k(t){const e=t===void 0?location.hash:t,n={},a=Q(e);if(!a)return n;const r=a.split("&");for(let l=0;l<r.length;l++){const o=r[l];if(!o)continue;const d=o.indexOf(":"),i=d>-1?o.slice(0,d):o,s=d>-1?o.slice(d+1):"";if(i)try{n[i]=decodeURIComponent(s)}catch{n[i]=s}}return n}function pt(t){if(!t)return null;const e=k();return t in e?e[t]:null}function ht(t,e){if(!t)return;const n=k();e==null?delete n[t]:n[t]=String(e);const r=Object.keys(n).map(function(l){const o=n[l];return o===""?l:l+":"+encodeURIComponent(o)}).join("&");Q(location.hash)!==r&&(location.hash=r)}function mt(t){return t.button===1||t.ctrlKey||t.metaKey||t.shiftKey?!1:(t.preventDefault(),!0)}function gt(t,e){if(!t||!t.hasAttribute("data-ln-hash"))return null;const n=t.getAttribute("data-ln-hash");if(n&&n.trim()!=="")return n.trim();const a=t.getAttribute("data-ln-sort")||t.getAttribute("data-ln-search-for")||t.getAttribute("data-ln-search")||t.getAttribute("data-ln-filter")||t.id;return a?e?a+"-"+e:a:e||null}function yt(t,e){return!e||e==="none"||t===null||t===void 0?null:String(t)+"."+e}function Ct(t){return!t||typeof t!="string"?null:t.endsWith(".asc")?{fieldOrColumn:t.slice(0,-4),direction:"asc"}:t.endsWith(".desc")?{fieldOrColumn:t.slice(0,-5),direction:"desc"}:null}function vt(t,e){return!t||!Array.isArray(e)||e.length===0?null:t+":"+e.map(encodeURIComponent).join(",")}function At(t){if(!t||typeof t!="string")return null;const e=t.indexOf(":");if(e===-1)return null;const n=t.slice(0,e),a=t.slice(e+1),r=a?a.split(",").map(function(l){try{return decodeURIComponent(l)}catch{return l}}).filter(Boolean):[];return{key:n,values:r}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.hashParse=k,window.lnCore.hashGet=pt,window.lnCore.hashSet=ht,window.lnCore.hashLinkClick=mt,window.lnCore.resolveHashNamespace=gt,window.lnCore.hashSortEncode=yt,window.lnCore.hashSortDecode=Ct,window.lnCore.hashFilterEncode=vt,window.lnCore.hashFilterDecode=At);const x=new Set(["data-ln-accordion","data-ln-ajax","data-ln-api-base-url","data-ln-api-connector","data-ln-api-connector-query-debounce","data-ln-api-headers","data-ln-api-param-limit","data-ln-api-param-offset","data-ln-api-param-search","data-ln-api-param-sort-dir","data-ln-api-param-sort-field","data-ln-api-path","data-ln-api-queue","data-ln-api-queue-online","data-ln-attr","data-ln-autoresize","data-ln-autosave","data-ln-autosave-clear","data-ln-autosave-debounce-input","data-ln-autosave-exclude","data-ln-chart","data-ln-chart-area","data-ln-chart-count","data-ln-chart-empty","data-ln-chart-labels","data-ln-chart-line","data-ln-chart-max","data-ln-chart-min","data-ln-chart-padding","data-ln-chart-plot","data-ln-chart-sort","data-ln-chart-source","data-ln-chart-type","data-ln-chart-x","data-ln-chart-y","data-ln-chart-zero","data-ln-circular-progress","data-ln-circular-progress-label","data-ln-circular-progress-max","data-ln-class","data-ln-col","data-ln-confirm","data-ln-confirm-active","data-ln-confirm-announcer","data-ln-confirm-idle","data-ln-confirm-state","data-ln-confirm-timeout","data-ln-couchdb-auth","data-ln-couchdb-connector","data-ln-couchdb-db","data-ln-couchdb-headers","data-ln-couchdb-url","data-ln-data-coordinator","data-ln-data-coordinator-dict","data-ln-data-coordinator-filters","data-ln-data-coordinator-mapper","data-ln-data-coordinator-no-autosync","data-ln-data-coordinator-scope","data-ln-data-coordinator-search","data-ln-data-coordinator-sort-direction","data-ln-data-coordinator-sort-field","data-ln-data-coordinator-stale","data-ln-data-store","data-ln-data-store-frozen","data-ln-data-store-indexes","data-ln-data-store-no-autosync","data-ln-data-store-no-local-query","data-ln-data-store-search-fields","data-ln-data-store-stale","data-ln-data-store-window","data-ln-data-store-window-page","data-ln-date","data-ln-date-dict","data-ln-date-dict-key","data-ln-date-field","data-ln-date-format","data-ln-date-label","data-ln-date-locale","data-ln-debug","data-ln-dropdown","data-ln-dropdown-menu","data-ln-dropdown-placement","data-ln-dropdown-position","data-ln-editor","data-ln-editor-action","data-ln-editor-source","data-ln-empty","data-ln-empty-state","data-ln-empty-when","data-ln-error","data-ln-external-link","data-ln-field","data-ln-fill-as","data-ln-fill-form","data-ln-fill-id","data-ln-fillable","data-ln-filter","data-ln-filter-col","data-ln-filter-hide","data-ln-filter-key","data-ln-filter-options","data-ln-filter-reset","data-ln-filter-search","data-ln-filter-value","data-ln-filter-values","data-ln-form","data-ln-form-action-edit","data-ln-form-action-method","data-ln-hash","data-ln-include","data-ln-item","data-ln-item-action","data-ln-item-id","data-ln-item-select","data-ln-key","data-ln-key-allow-input","data-ln-key-for","data-ln-key-modifier","data-ln-key-target","data-ln-link","data-ln-list","data-ln-list-body","data-ln-list-count","data-ln-list-empty","data-ln-list-field","data-ln-list-filtered","data-ln-list-select-all","data-ln-list-selectable","data-ln-list-selected","data-ln-list-source","data-ln-list-total","data-ln-list-window","data-ln-list-window-page","data-ln-list-window-threshold","data-ln-mapper","data-ln-modal","data-ln-modal-close","data-ln-modal-for","data-ln-modal-mode","data-ln-modal-when","data-ln-nav","data-ln-nav-exact","data-ln-number","data-ln-number-decimals","data-ln-number-max","data-ln-number-min","data-ln-obfuscator","data-ln-obfuscator-codec","data-ln-obfuscator-key","data-ln-options","data-ln-options-label","data-ln-options-value","data-ln-outlet","data-ln-panel","data-ln-persist","data-ln-persist-scope","data-ln-picklist","data-ln-picklist-list","data-ln-picklist-max","data-ln-popover","data-ln-popover-for","data-ln-popover-placement","data-ln-popover-position","data-ln-progress","data-ln-progress-max","data-ln-render-key","data-ln-route","data-ln-route-keep","data-ln-route-target","data-ln-route-title","data-ln-router-hydrate","data-ln-scroll","data-ln-scroll-behavior","data-ln-scroll-block","data-ln-scroll-delay","data-ln-scroll-focus","data-ln-scroll-set","data-ln-scroll-update-hash","data-ln-search","data-ln-search-clear","data-ln-search-clear-for","data-ln-search-exclude","data-ln-search-fields","data-ln-search-for","data-ln-search-hide","data-ln-search-items","data-ln-show","data-ln-slug-from","data-ln-sort","data-ln-sort-dir","data-ln-sort-exclude","data-ln-sort-field","data-ln-sort-icon","data-ln-sort-items","data-ln-sort-state","data-ln-sortable","data-ln-sortable-handle","data-ln-stat","data-ln-stat-card","data-ln-stat-filter","data-ln-stat-label","data-ln-stat-trend","data-ln-stat-value","data-ln-step","data-ln-step-label","data-ln-stepper","data-ln-store","data-ln-tab","data-ln-table","data-ln-table-body","data-ln-table-cell-attr","data-ln-table-clear","data-ln-table-clear-all","data-ln-table-col","data-ln-table-col-filter","data-ln-table-col-select","data-ln-table-col-sort","data-ln-table-coordinator","data-ln-table-count","data-ln-table-dict","data-ln-table-empty","data-ln-table-empty-when","data-ln-table-filter-col","data-ln-table-filtered","data-ln-table-row","data-ln-table-row-action","data-ln-table-row-id","data-ln-table-row-select","data-ln-table-select-all-label","data-ln-table-selectable","data-ln-table-selected","data-ln-table-sort","data-ln-table-source","data-ln-table-total","data-ln-table-window","data-ln-table-window-page","data-ln-table-window-threshold","data-ln-tabs","data-ln-tabs-active","data-ln-tabs-default","data-ln-tabs-focus","data-ln-tabs-key","data-ln-template","data-ln-time","data-ln-time-locale","data-ln-toast","data-ln-toast-close","data-ln-toast-item","data-ln-toast-max","data-ln-toast-timeout","data-ln-toast-when","data-ln-toggle","data-ln-toggle-action","data-ln-toggle-for","data-ln-tooltip","data-ln-tooltip-enhance","data-ln-tooltip-enhanced","data-ln-tooltip-placement","data-ln-tooltip-position","data-ln-translatable","data-ln-translatable-lang","data-ln-translations","data-ln-translations-active","data-ln-translations-add","data-ln-translations-default","data-ln-translations-lang","data-ln-translations-locales","data-ln-translations-placeholder","data-ln-translations-prefix","data-ln-translations-remove-label","data-ln-ui-coordinator","data-ln-ui-coordinator-dict","data-ln-upload","data-ln-upload-accept","data-ln-upload-action","data-ln-upload-delete","data-ln-upload-dict","data-ln-upload-ext","data-ln-upload-file-field","data-ln-upload-id","data-ln-upload-ids-field","data-ln-upload-item","data-ln-upload-list","data-ln-upload-local-id","data-ln-upload-max-files","data-ln-upload-max-size","data-ln-upload-progress","data-ln-upload-size","data-ln-upload-state","data-ln-upload-zone","data-ln-validate","data-ln-validate-error","data-ln-validate-errors","data-ln-value","data-ln-websocket-connector","data-ln-websocket-connector-url"]);function St(t,e){if(t===e)return 0;if(!t.length)return e.length;if(!e.length)return t.length;const n=[];for(let a=0;a<=e.length;a++)n[a]=[a];for(let a=0;a<=t.length;a++)n[0][a]=a;for(let a=1;a<=e.length;a++)for(let r=1;r<=t.length;r++)e.charAt(a-1)===t.charAt(r-1)?n[a][r]=n[a-1][r-1]:n[a][r]=Math.min(n[a-1][r-1]+1,n[a][r-1]+1,n[a-1][r]+1);return n[e.length][t.length]}function _t(t,e=x){if(e.has(t))return null;let n=null,a=1/0;for(const l of e){const o=St(t,l);o<a&&(a=o,n=l)}const r=Math.max(3,Math.floor(t.length*.4));return a<=r?n:null}function K(t){return typeof CSS<"u"&&CSS.escape?CSS.escape(t):t.replace(/([!"#$%&'()*+,.\/:;<=>?@[\\\]^`{|}~])/g,"\\$1")}function kt(t=document){const e=t.ownerDocument||t,n=t.nodeType===9?t.body||t.documentElement:t;if(!n)return[];const a=[],r=[n,...n.querySelectorAll("*")];for(let l=0;l<r.length;l++){const o=r[l];if(o.attributes)for(let d=0;d<o.attributes.length;d++){const i=o.attributes[d];if(i.name.startsWith("data-ln-")&&i.name.endsWith("-for")){const s=(i.value||"").trim();if(!s){a.push({type:"id-empty",element:o,attribute:i.name,targetId:"",message:`[ln-debug] Empty ID reference in <${o.tagName.toLowerCase()} ${i.name}="">.`});continue}e.getElementById(s)||e.querySelector("#"+K(s))||a.push({type:"id-unresolved",element:o,attribute:i.name,targetId:s,message:`[ln-debug] Unresolved ID reference: <${o.tagName.toLowerCase()} ${i.name}="${s}"> targets "#${s}", but no element with id="${s}" exists in the document.`})}}}return a}function xt(t=document){const e=t.ownerDocument||t,n=t.nodeType===9?t.body||t.documentElement:t;if(!n)return[];const a=[],r=[n,...n.querySelectorAll("*")];for(let l=0;l<r.length;l++){const o=r[l];if(o.attributes)for(let d=0;d<o.attributes.length;d++){const i=o.attributes[d];if(i.name.startsWith("data-ln-")&&(i.name.endsWith("-source")||i.name.endsWith("-store"))&&i.name!=="data-ln-data-store"){const c=(i.value||"").trim();if(!c){a.push({type:"store-empty",element:o,attribute:i.name,storeName:"",message:`[ln-debug] Empty store reference in <${o.tagName.toLowerCase()} ${i.name}="">.`});continue}const u=K(c),f=e.querySelector(`[data-ln-data-store="${u}"], [data-ln-store="${u}"]`),D=typeof window<"u"&&window.lnDataStore&&typeof window.lnDataStore.getStore=="function"&&window.lnDataStore.getStore(c);!f&&!D&&a.push({type:"store-unresolved",element:o,attribute:i.name,storeName:c,message:`[ln-debug] Unresolved store reference: <${o.tagName.toLowerCase()} ${i.name}="${c}"> targets store "${c}", but no [data-ln-data-store="${c}"] exists in the document.`})}}}return a}function $t(t=document){t.ownerDocument;const e=t.nodeType===9?t.body||t.documentElement:t;if(!e)return[];const n=[],a=Array.from(e.querySelectorAll("[data-ln-data-store]"));e.hasAttribute&&e.hasAttribute("data-ln-data-store")&&a.unshift(e);const r=new Map;for(let l=0;l<a.length;l++){const o=a[l],d=(o.getAttribute("data-ln-data-store")||"").trim();d&&(r.has(d)||r.set(d,[]),r.get(d).push(o))}for(const[l,o]of r.entries())o.length>1&&n.push({type:"store-duplicate",storeName:l,elements:o,message:`[ln-debug] Duplicate store name: Multiple elements declare data-ln-data-store="${l}". Store names must be unique across the document.`});return n}function Dt(t=document,e=x){const n=t.nodeType===9?t.body||t.documentElement:t;if(!n)return[];const a=[],r=[n,...n.querySelectorAll("*")];for(let l=0;l<r.length;l++){const o=r[l];if(o.attributes)for(let d=0;d<o.attributes.length;d++){const i=o.attributes[d];if(i.name.startsWith("data-ln-")&&!e.has(i.name)){const s=_t(i.name,e),c=s?` Did you mean "${s}"?`:"";a.push({type:"attribute-unknown",element:o,attribute:i.name,suggestion:s,message:`[ln-debug] Unknown attribute "${i.name}" on <${o.tagName.toLowerCase()}>.${c}`})}}}return a}function C(t=typeof document<"u"?document:null,e={}){if(!t)return{idIssues:[],storeIssues:[],uniquenessIssues:[],spellingIssues:[],total:0};const n=e.validAttributes||x,a=kt(t),r=xt(t),l=$t(t),o=Dt(t,n),d=[...a,...r,...l,...o];if(!e.silent)for(let i=0;i<d.length;i++)console.warn(d[i].message);return{idIssues:a,storeIssues:r,uniquenessIssues:l,spellingIssues:o,total:d.length}}let h=null;function m(t=typeof document<"u"?document:null,e=50,n=null){if(!t)return;h&&(clearTimeout(h),h=null);function a(){h=setTimeout(()=>{h=null;const r=C(t);n&&n(r)},e)}N()>0?F(a):a()}function It(t,e,n,a){t==="event"?(console.groupCollapsed("[ln-debug] event",e),console.log("target",n),console.log("detail",a),console.groupEnd()):t==="attr"&&(console.groupCollapsed("[ln-debug] attr",e),console.log("target",n),console.log("old → new",a.oldValue,"→",a.newValue),console.groupEnd())}let b=[];function Et(){b=Array.from(document.body.querySelectorAll("[data-ln-debug]")),document.body.hasAttribute("data-ln-debug")&&b.push(document.body)}function J(t){if(t===window||t===document)return b.indexOf(document.body)!==-1;for(let e=0;e<b.length;e++)if(b[e].contains(t))return!0;return!1}function Ot(t,e,n,a){J(n)&&It(t,e,n,a)}function $(){Et(),Y(b.length>0?Ot:null,b.length>0?J:null)}function P(){$()}function Tt(){typeof window>"u"||(window.lnCore=window.lnCore||{},!window.lnCore._debugGateBound&&(window.lnCore._debugGateBound=!0,p(function(){$(),wt(["data-ln-debug"],$)},"ln-debug")))}return(function(){const t="data-ln-debug",e="lnDebug";if(typeof window<"u"&&window[e]!==void 0)return;const n={"data-ln-debug":{type:"marker",description:"Enables developer diagnostics overlay, live validation badges, and inspection logging"}};Tt();function a(l){return this.dom=l,m(l.ownerDocument||document),P(),this}a.prototype.verify=function(l,o){return C(l||(this.dom?this.dom.ownerDocument||this.dom:document),o)},a.prototype.destroy=function(){delete this.dom[e],P()};const r=bt(t,e,a,"ln-debug",{attributes:n,onInit:function(l){typeof document<"u"&&m(l&&l.ownerDocument?l.ownerDocument:document)},onSubtreeChange:function(l){typeof document<"u"&&m(l&&l.ownerDocument?l.ownerDocument:document)}});r.verify=function(l,o){return C(l||document,o)},r.schedule=function(l,o,d){return m(l||document,o,d)}})(),y.scheduleVerification=m,y.verifyDOM=C,Object.defineProperty(y,Symbol.toStringTag,{value:"Module"}),y})({});
1
+ var LnAshlarComponent=(function(y){"use strict";function L(){return typeof window>"u"?!1:window.lnDebug===!0||window.lnCore&&window.lnCore._debugSink?!0:typeof document<"u"&&document.body?document.body.hasAttribute("data-ln-debug")||document.body.querySelector("[data-ln-debug]")!==null:!1}function A(t){if(typeof window>"u")return!1;if(window.lnDebug===!0)return!0;if(window.lnCore&&window.lnCore._debugIsContained)return t?window.lnCore._debugIsContained(t):window.lnCore._debugSink!==null;if(t&&t.closest){const e=t.closest("[data-ln-debug]");return!(!e||typeof document<"u"&&e===document.documentElement)}return typeof document<"u"&&document.body?document.body.hasAttribute("data-ln-debug"):!1}if(typeof window<"u"&&(window.lnCore=window.lnCore||{},!window.lnCore._warnBound)){window.lnCore._warnBound=!0;const t=console.warn;console.warn=function(...e){if(typeof e[0]=="string"&&(e[0].startsWith("[ln-")||e[0].startsWith("[lnCore"))){let a=null;for(let r=1;r<e.length;r++)if(e[r]&&e[r].nodeType===1){a=e[r];break}if(!A(a))return}t.apply(console,e)}}function Y(t,e){window.lnCore=window.lnCore||{},window.lnCore._debugSink=t,window.lnCore._debugIsContained=e||null}function Z(t,e,n){const a=n||{};window.lnCore._debugSink&&window.lnCore._debugSink("event",e,t,a),t.dispatchEvent(new CustomEvent(e,{bubbles:!0,detail:a}))}function p(t,e){if(!document.body){document.addEventListener("DOMContentLoaded",function(){p(t,e)}),console.warn("["+e+'] Script loaded before <body> — add "defer" to your <script> tag');return}t()}const M={};function tt(t,e){M[t]=e}function et(t){return M[t]||{ingress:e=>e,egress:e=>e}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerDataMapper=tt,window.lnCore.getDataMapper=et);function nt(){typeof window>"u"||(window.lnCore=window.lnCore||{},!window.lnCore._localeObserverBound&&(window.lnCore._localeObserverBound=!0,p(function(){new MutationObserver(function(){Z(document,"ln-core:locale-change",{})}).observe(document.documentElement,{attributes:!0,attributeFilter:["lang"],subtree:!0})},"ln-core")))}const R={};function at(t,e){if(!t||typeof e!="object")return;const n=t.toLowerCase().split("-")[0];R[n]=e}function lt(t){if(!t)return null;const e=t.toLowerCase().split("-")[0];return R[e]||null}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerLocaleFallback=at,window.lnCore.getLocaleFallback=lt,window.lnCore.ensureLocaleObserver=nt);const S={};function ot(t,e){S[t]||(S[t]=document.querySelector('[data-ln-template="'+t+'"]'));const n=S[t];return n?n.content.cloneNode(!0):(console.warn("["+(e||"ln-core")+'] Template "'+t+'" not found'),null)}function W(t,e){if(!t||!e)return t;const n=t.querySelectorAll("[data-ln-field]");for(let o=0;o<n.length;o++){const d=n[o],i=d.getAttribute("data-ln-field");e[i]!=null&&(d.textContent=e[i])}const a=t.querySelectorAll("[data-ln-attr]");for(let o=0;o<a.length;o++){const d=a[o],i=d.getAttribute("data-ln-attr").split(",");for(let s=0;s<i.length;s++){const c=i[s].trim().split(":");if(c.length!==2)continue;const u=c[0].trim(),f=c[1].trim();e[f]!=null&&d.setAttribute(u,e[f])}}const r=t.querySelectorAll("[data-ln-show]");for(let o=0;o<r.length;o++){const d=r[o],i=d.getAttribute("data-ln-show");i in e&&d.classList.toggle("hidden",!e[i])}const l=t.querySelectorAll("[data-ln-class]");for(let o=0;o<l.length;o++){const d=l[o],i=d.getAttribute("data-ln-class").split(",");for(let s=0;s<i.length;s++){const c=i[s].trim().split(":");if(c.length!==2)continue;const u=c[0].trim(),f=c[1].trim();f in e&&d.classList.toggle(u,!!e[f])}}return t}function rt(t,e){t.matches&&t.matches("[data-ln-form], [data-ln-fillable]")&&(window.lnCore._debugSink&&window.lnCore._debugSink("event","ln-fill",t,e??null),t.dispatchEvent(new CustomEvent("ln-fill",{detail:e??null,bubbles:!0})));const n=t.querySelectorAll("[data-ln-form], [data-ln-fillable]");for(let a=0;a<n.length;a++)window.lnCore._debugSink&&window.lnCore._debugSink("event","ln-fill",n[a],e??null),n[a].dispatchEvent(new CustomEvent("ln-fill",{detail:e??null,bubbles:!0}));return t}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore._fillBound||(window.lnCore._fillBound=!0,document.addEventListener("ln-fill",function(t){if(!(!t.target.matches||!t.target.matches("[data-ln-fillable]")))if(t.detail)W(t.target,t.detail);else{const e=t.target.querySelectorAll("[data-ln-field]");for(let n=0;n<e.length;n++)e[n].textContent=""}})));function j(t,e){if(!t||!e)return t;const n=document.createTreeWalker(t,NodeFilter.SHOW_TEXT);for(;n.nextNode();){const l=n.currentNode;l.textContent.indexOf("{{")!==-1&&(l.textContent=l.textContent.replace(/\{\{\s*(\w+)\s*\}\}/g,function(o,d){return e[d]!==void 0?e[d]:""}))}const a=function(l,o){return e[o]!==void 0?e[o]:""},r=Array.from(t.querySelectorAll("*"));t.nodeType===1&&r.push(t);for(let l=0;l<r.length;l++){const o=r[l],d=o.attributes;for(let i=0;i<d.length;i++){const s=d[i];s.value.indexOf("{{")!==-1&&o.setAttribute(s.name,s.value.replace(/\{\{\s*(\w+)\s*\}\}/g,a))}}return t}function it(t,e,n,a,r,l){const o={};for(let i=0;i<t.children.length;i++){const s=t.children[i],c=s.getAttribute("data-ln-render-key");c&&(o[c]=s)}const d=document.createDocumentFragment();for(let i=0;i<e.length;i++){const s=e[i],c=String(a(s));let u=o[c];if(u)r(u,s,i);else{const f=ot(n,l);if(!f||(j(f,s),u=f.firstElementChild,!u))continue;u.setAttribute("data-ln-render-key",c),r(u,s,i)}d.appendChild(u)}t.textContent="",t.appendChild(d)}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.fillTemplate=j,window.lnCore.fill=W,window.lnCore.lnFill=rt,window.lnCore.renderList=it);function B(t,e,n,a,r){if(!t||e===null)return!0;const l=a||"ln-component",o=t.type;if(o==="trigger"||o==="marker"||o==="string"||o==="list"||!o||e===""&&t.fallback!==void 0)return!0;const d=i=>{r?console.warn(i,r):console.warn(i)};if(o==="boolean"){const i=e.trim().toLowerCase();return i!==""&&i!=="true"&&i!=="false"&&i!=="1"&&i!=="0"?(d(`[${l}] Invalid value "${e}" for boolean attribute "${n}". Allowed: "true", "false", or presence-only.`),!1):!0}if(o==="enum"){const i=t.values||[];return i.includes(e)?!0:(d(`[${l}] Invalid value "${e}" for attribute "${n}". Allowed: ${i.join(", ")}. Fallback: "${t.fallback}".`),!1)}if(o==="integer"){if(!/^-?\d+$/.test(e))return d(`[${l}] Invalid integer "${e}" for attribute "${n}". Fallback: ${t.fallback}.`),!1;const i=parseInt(e,10);return t.min!==void 0&&i<t.min?(d(`[${l}] Value ${i} for attribute "${n}" is less than min (${t.min}).`),!1):t.max!==void 0&&i>t.max?(d(`[${l}] Value ${i} for attribute "${n}" is greater than max (${t.max}).`),!1):!0}if(o==="float")return isNaN(Number(e))?(d(`[${l}] Invalid float "${e}" for attribute "${n}". Fallback: ${t.fallback}.`),!1):!0;if(o==="json")try{return JSON.parse(e),!0}catch(i){return d(`[${l}] Invalid JSON for attribute "${n}": ${i.message}. Fallback: ${t.fallback}.`),!1}return!0}function dt(t){const e={};for(const n in t){const a=t[n];a&&a.effect&&(e[n]=a.effect)}return Object.keys(e).length?e:null}function st(t){if(t.onAttrChange&&!t.declared)return null;const e=new Set;if(t.effects)for(const n in t.effects)e.add(n);if(t.onAttrChange&&t.declared)for(const n of t.declared)e.add(n);return e}function _(t,e,n,a){if(t.nodeType!==1)return;const l=e.indexOf("[")!==-1||e.indexOf(".")!==-1||e.indexOf("#")!==-1?e:"["+e+"]",o=Array.from(t.querySelectorAll(l));t.matches&&t.matches(l)&&o.push(t);for(const d of o)if(!d[n]){window.lnCore._persistSink&&d.hasAttribute("data-ln-persist")&&window.lnCore._persistSink(d,e);try{d[n]=new a(d)}catch(i){console.error("["+n+"] init failed",d,i)}}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore._bootHolds=window.lnCore._bootHolds||0,window.lnCore._bootQueue=window.lnCore._bootQueue||[]);function N(){return typeof window<"u"&&window.lnCore&&window.lnCore._bootHolds||0}function F(t){typeof window<"u"?(window.lnCore=window.lnCore||{},window.lnCore._bootHolds=window.lnCore._bootHolds||0,window.lnCore._bootQueue=window.lnCore._bootQueue||[],window.lnCore._bootHolds>0?window.lnCore._bootQueue.push(t):setTimeout(t,0)):t()}function V(){window.lnCore=window.lnCore||{};const t=window.lnCore._attrRegistry=window.lnCore._attrRegistry||{byAttr:new Map,reactive:[],persist:[]};return t.byReactive=t.byReactive||new Map,t.reactiveWildcard=t.reactiveWildcard||[],t}function H(t){const e=V(),n=t.observed||[];for(let a=0;a<n.length;a++){const r=n[a];e.byAttr.has(r)||e.byAttr.set(r,[]),e.byAttr.get(r).push(t)}if(e.byDeclaredAttr=e.byDeclaredAttr||new Map,t.attributes)for(const a in t.attributes){e.byDeclaredAttr.has(a)||e.byDeclaredAttr.set(a,[]);const r=e.byDeclaredAttr.get(a);r.some(l=>l.componentTag===t.componentTag)||r.push({spec:t.attributes[a],componentTag:t.componentTag})}if(t.onAttrChange||t.effects){e.reactive.push(t);const a=st(t);if(a===null)e.reactiveWildcard.push(t);else for(const r of a)e.byReactive.has(r)||e.byReactive.set(r,[]),e.byReactive.get(r).push(t)}t.persist&&e.persist.push(t)}function U(t,e,n,a){for(let r=0;r<t.length;r++){const l=t[r];if(!e[l.attribute])continue;const o=l.effects&&l.effects[n];o?o(e,n,a):l.onAttrChange&&(!l.declared||l.declared.has(n))&&l.onAttrChange(e,n,a)}}function ct(t){const e=t.target,n=t.attributeName;if(t.oldValue===e.getAttribute(n))return;const a=V(),r=a.byAttr.get(n);if(L()&&a.byDeclaredAttr&&a.byDeclaredAttr.has(n)&&A(e)){const l=a.byDeclaredAttr.get(n),o=e.getAttribute(n);for(let d=0;d<l.length;d++)B(l[d].spec,o,n,l[d].componentTag,e)}if(window.lnCore._debugSink&&(n.indexOf("data-ln-")===0||r)&&window.lnCore._debugSink("attr",n,e,{oldValue:t.oldValue,newValue:e.getAttribute(n)}),n.indexOf("data-ln-")===0){const l=a.byReactive.get(n);l&&U(l,e,n,t.oldValue),a.reactiveWildcard.length&&U(a.reactiveWildcard,e,n,t.oldValue)}if(r)for(let l=0;l<r.length;l++){const o=r[l];if(o.handler){o.handler(e,n,t.oldValue);continue}o.onAttributeChange&&e[o.attribute]?o.onAttributeChange(e,n):(_(e,o.selector,o.attribute,o.ComponentFn),o.onInit&&o.onInit(e))}}function z(){window.lnCore=window.lnCore||{},!window.lnCore._attrObserverBound&&(window.lnCore._attrObserverBound=!0,p(function(){new MutationObserver(function(e){for(let n=0;n<e.length;n++)try{ct(e[n])}catch(a){console.error("[ln-core] mutation handler failed",e[n].target,a)}}).observe(document.body,{attributes:!0,subtree:!0,attributeOldValue:!0})},"ln-core"))}function G(){return window.lnCore=window.lnCore||{},window.lnCore._lifecycleRegistry=window.lnCore._lifecycleRegistry||[]}function ut(t){const e=G();if(e.length){if(t.target)for(let n=0;n<e.length;n++){const a=e[n];if(a.onSubtreeChange){const r=a.query,l=t.target.nodeType===1?t.target.matches(r)?t.target:t.target.closest(r):t.target.parentElement?t.target.parentElement.closest(r):null;l&&a.onSubtreeChange(l,t)}}for(let n=0;n<t.addedNodes.length;n++){const a=t.addedNodes[n];if(a.nodeType===1)for(let r=0;r<e.length;r++){const l=e[r];_(a,l.selector,l.attribute,l.ComponentFn),l.onInit&&l.onInit(a)}}for(let n=0;n<t.removedNodes.length;n++){const a=t.removedNodes[n];if(a.nodeType===1)for(let r=0;r<e.length;r++){const l=e[r],o=l.query,d=Array.from(a.querySelectorAll(o));a.matches&&a.matches(o)&&d.push(a);for(let i=0;i<d.length;i++){const s=d[i];if(!document.contains(s)){const c=s[l.attribute];if(c&&typeof c.destroy=="function")try{c.destroy()}catch(u){console.error("["+l.attribute+"] destroy failed",s,u)}delete s[l.attribute]}}}}}}function ft(){window.lnCore=window.lnCore||{},!window.lnCore._lifecycleObserverBound&&(window.lnCore._lifecycleObserverBound=!0,p(function(){new MutationObserver(function(e){for(let n=0;n<e.length;n++){const a=e[n];if(a.type==="childList")try{ut(a)}catch(r){console.error("[ln-core] lifecycle handler failed",a.target,r)}}}).observe(document.body,{childList:!0,subtree:!0})},"ln-core"))}function wt(t,e){H({observed:t,handler:e}),z()}function bt(t,e,n,a,r={}){const l=r.extraAttributes||[],o=r.onAttributeChange||null,d=r.onSubtreeChange||null,i=r.onInit||null,s=r.onAttrChange||null,c=r.effects||null,u=r.attributes||null,f=u?dt(u):c,D=u?new Set(Object.keys(u)):null,qt=r.persist||null;function v(E){const w=E||document.body;if(_(w,t,e,n),u&&L())for(const g in u){const Mt=u[g],O=Array.from(w.querySelectorAll("["+g+"]"));w.matches&&w.matches("["+g+"]")&&O.push(w);for(let T=0;T<O.length;T++){const q=O[T];A(q)&&B(Mt,q.getAttribute(g),g,a,q)}}i&&i(w)}const I=[];if(t.indexOf("[")!==-1){const E=/\[([\w-]+)/g;let w;for(;(w=E.exec(t))!==null;)I.push(w[1])}else I.push(t);H({selector:t,attribute:e,componentTag:a,attributes:u,ComponentFn:n,onInit:i,observed:I.concat(l),onAttributeChange:o,onAttrChange:s,effects:f,declared:D,persist:qt}),z();const Lt=t.indexOf("[")!==-1||t.indexOf(".")!==-1||t.indexOf("#")!==-1?t:"["+t+"]";G().push({selector:t,attribute:e,ComponentFn:n,onInit:i,onSubtreeChange:d,query:Lt}),ft(),window[e]=v;function X(){N()>0?F(function(){v(document.body)}):v(document.body)}return document.readyState==="loading"?document.addEventListener("DOMContentLoaded",X):X(),v}function Q(t){return(t||"").replace(/^#/,"")}function k(t){const e=t===void 0?location.hash:t,n={},a=Q(e);if(!a)return n;const r=a.split("&");for(let l=0;l<r.length;l++){const o=r[l];if(!o)continue;const d=o.indexOf(":"),i=d>-1?o.slice(0,d):o,s=d>-1?o.slice(d+1):"";if(i)try{n[i]=decodeURIComponent(s)}catch{n[i]=s}}return n}function pt(t){if(!t)return null;const e=k();return t in e?e[t]:null}function ht(t,e){if(!t)return;const n=k();e==null?delete n[t]:n[t]=String(e);const r=Object.keys(n).map(function(l){const o=n[l];return o===""?l:l+":"+encodeURIComponent(o)}).join("&");Q(location.hash)!==r&&(location.hash=r)}function mt(t){return t.button===1||t.ctrlKey||t.metaKey||t.shiftKey?!1:(t.preventDefault(),!0)}function gt(t,e){if(!t||!t.hasAttribute("data-ln-hash"))return null;const n=t.getAttribute("data-ln-hash");if(n&&n.trim()!=="")return n.trim();const a=t.getAttribute("data-ln-sort")||t.getAttribute("data-ln-search-for")||t.getAttribute("data-ln-search")||t.getAttribute("data-ln-filter")||t.id;return a?e?a+"-"+e:a:e||null}function yt(t,e){return!e||e==="none"||t===null||t===void 0?null:String(t)+"."+e}function Ct(t){return!t||typeof t!="string"?null:t.endsWith(".asc")?{fieldOrColumn:t.slice(0,-4),direction:"asc"}:t.endsWith(".desc")?{fieldOrColumn:t.slice(0,-5),direction:"desc"}:null}function vt(t,e){return!t||!Array.isArray(e)||e.length===0?null:t+":"+e.map(encodeURIComponent).join(",")}function At(t){if(!t||typeof t!="string")return null;const e=t.indexOf(":");if(e===-1)return null;const n=t.slice(0,e),a=t.slice(e+1),r=a?a.split(",").map(function(l){try{return decodeURIComponent(l)}catch{return l}}).filter(Boolean):[];return{key:n,values:r}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.hashParse=k,window.lnCore.hashGet=pt,window.lnCore.hashSet=ht,window.lnCore.hashLinkClick=mt,window.lnCore.resolveHashNamespace=gt,window.lnCore.hashSortEncode=yt,window.lnCore.hashSortDecode=Ct,window.lnCore.hashFilterEncode=vt,window.lnCore.hashFilterDecode=At);const x=new Set(["data-ln-accordion","data-ln-ajax","data-ln-api-base-url","data-ln-api-connector","data-ln-api-connector-query-debounce","data-ln-api-headers","data-ln-api-param-limit","data-ln-api-param-offset","data-ln-api-param-search","data-ln-api-param-sort-dir","data-ln-api-param-sort-field","data-ln-api-path","data-ln-api-queue","data-ln-api-queue-online","data-ln-attr","data-ln-autoresize","data-ln-autosave","data-ln-autosave-clear","data-ln-autosave-debounce-input","data-ln-autosave-exclude","data-ln-chart","data-ln-chart-area","data-ln-chart-count","data-ln-chart-empty","data-ln-chart-labels","data-ln-chart-line","data-ln-chart-max","data-ln-chart-min","data-ln-chart-padding","data-ln-chart-plot","data-ln-chart-sort","data-ln-chart-source","data-ln-chart-type","data-ln-chart-x","data-ln-chart-y","data-ln-chart-zero","data-ln-circular-progress","data-ln-circular-progress-label","data-ln-circular-progress-max","data-ln-class","data-ln-col","data-ln-confirm","data-ln-confirm-active","data-ln-confirm-announcer","data-ln-confirm-idle","data-ln-confirm-state","data-ln-confirm-timeout","data-ln-couchdb-auth","data-ln-couchdb-connector","data-ln-couchdb-db","data-ln-couchdb-headers","data-ln-couchdb-url","data-ln-data-coordinator","data-ln-data-coordinator-dict","data-ln-data-coordinator-filters","data-ln-data-coordinator-mapper","data-ln-data-coordinator-no-autosync","data-ln-data-coordinator-scope","data-ln-data-coordinator-search","data-ln-data-coordinator-sort-direction","data-ln-data-coordinator-sort-field","data-ln-data-coordinator-stale","data-ln-data-store","data-ln-data-store-frozen","data-ln-data-store-indexes","data-ln-data-store-no-autosync","data-ln-data-store-no-local-query","data-ln-data-store-search-fields","data-ln-data-store-stale","data-ln-data-store-window","data-ln-data-store-window-page","data-ln-date","data-ln-date-dict","data-ln-date-dict-key","data-ln-date-field","data-ln-date-format","data-ln-date-label","data-ln-date-locale","data-ln-debug","data-ln-dropdown","data-ln-dropdown-menu","data-ln-dropdown-placement","data-ln-dropdown-position","data-ln-editor","data-ln-editor-action","data-ln-editor-source","data-ln-empty","data-ln-empty-state","data-ln-empty-when","data-ln-error","data-ln-external-link","data-ln-field","data-ln-fill-as","data-ln-fill-form","data-ln-fill-id","data-ln-fillable","data-ln-filter","data-ln-filter-col","data-ln-filter-hide","data-ln-filter-key","data-ln-filter-options","data-ln-filter-reset","data-ln-filter-search","data-ln-filter-value","data-ln-filter-values","data-ln-form","data-ln-form-action-edit","data-ln-form-action-method","data-ln-hash","data-ln-include","data-ln-item","data-ln-item-action","data-ln-item-id","data-ln-item-select","data-ln-key","data-ln-key-allow-input","data-ln-key-for","data-ln-key-modifier","data-ln-key-target","data-ln-link","data-ln-list","data-ln-list-body","data-ln-list-count","data-ln-list-empty","data-ln-list-field","data-ln-list-filtered","data-ln-list-select-all","data-ln-list-selectable","data-ln-list-selected","data-ln-list-source","data-ln-list-total","data-ln-list-window","data-ln-list-window-page","data-ln-list-window-threshold","data-ln-mapper","data-ln-modal","data-ln-modal-close","data-ln-modal-for","data-ln-modal-mode","data-ln-modal-when","data-ln-nav","data-ln-nav-exact","data-ln-number","data-ln-number-decimals","data-ln-number-max","data-ln-number-min","data-ln-obfuscator","data-ln-obfuscator-codec","data-ln-obfuscator-key","data-ln-options","data-ln-options-label","data-ln-options-value","data-ln-outlet","data-ln-panel","data-ln-persist","data-ln-persist-scope","data-ln-picklist","data-ln-picklist-list","data-ln-picklist-max","data-ln-popover","data-ln-popover-for","data-ln-popover-placement","data-ln-popover-position","data-ln-progress","data-ln-progress-max","data-ln-render-key","data-ln-route","data-ln-route-keep","data-ln-route-target","data-ln-route-title","data-ln-router-base","data-ln-router-hydrate","data-ln-scroll","data-ln-scroll-behavior","data-ln-scroll-block","data-ln-scroll-delay","data-ln-scroll-focus","data-ln-scroll-set","data-ln-scroll-update-hash","data-ln-search","data-ln-search-clear","data-ln-search-clear-for","data-ln-search-exclude","data-ln-search-fields","data-ln-search-for","data-ln-search-hide","data-ln-search-items","data-ln-show","data-ln-slug-from","data-ln-sort","data-ln-sort-dir","data-ln-sort-exclude","data-ln-sort-field","data-ln-sort-icon","data-ln-sort-items","data-ln-sort-state","data-ln-sortable","data-ln-sortable-handle","data-ln-stat","data-ln-stat-card","data-ln-stat-filter","data-ln-stat-label","data-ln-stat-trend","data-ln-stat-value","data-ln-step","data-ln-step-label","data-ln-stepper","data-ln-store","data-ln-tab","data-ln-table","data-ln-table-body","data-ln-table-cell-attr","data-ln-table-clear","data-ln-table-clear-all","data-ln-table-col","data-ln-table-col-filter","data-ln-table-col-select","data-ln-table-col-sort","data-ln-table-coordinator","data-ln-table-count","data-ln-table-dict","data-ln-table-empty","data-ln-table-empty-when","data-ln-table-filter-col","data-ln-table-filtered","data-ln-table-row","data-ln-table-row-action","data-ln-table-row-id","data-ln-table-row-select","data-ln-table-select-all-label","data-ln-table-selectable","data-ln-table-selected","data-ln-table-sort","data-ln-table-source","data-ln-table-total","data-ln-table-window","data-ln-table-window-page","data-ln-table-window-threshold","data-ln-tabs","data-ln-tabs-active","data-ln-tabs-default","data-ln-tabs-focus","data-ln-tabs-key","data-ln-template","data-ln-time","data-ln-time-locale","data-ln-toast","data-ln-toast-close","data-ln-toast-item","data-ln-toast-max","data-ln-toast-timeout","data-ln-toast-when","data-ln-toggle","data-ln-toggle-action","data-ln-toggle-for","data-ln-tooltip","data-ln-tooltip-enhance","data-ln-tooltip-enhanced","data-ln-tooltip-placement","data-ln-tooltip-position","data-ln-translatable","data-ln-translatable-lang","data-ln-translations","data-ln-translations-active","data-ln-translations-add","data-ln-translations-default","data-ln-translations-lang","data-ln-translations-locales","data-ln-translations-placeholder","data-ln-translations-prefix","data-ln-translations-remove-label","data-ln-ui-coordinator","data-ln-ui-coordinator-dict","data-ln-upload","data-ln-upload-accept","data-ln-upload-action","data-ln-upload-delete","data-ln-upload-dict","data-ln-upload-ext","data-ln-upload-file-field","data-ln-upload-id","data-ln-upload-ids-field","data-ln-upload-item","data-ln-upload-list","data-ln-upload-local-id","data-ln-upload-max-files","data-ln-upload-max-size","data-ln-upload-progress","data-ln-upload-size","data-ln-upload-state","data-ln-upload-zone","data-ln-validate","data-ln-validate-error","data-ln-validate-errors","data-ln-value","data-ln-websocket-connector","data-ln-websocket-connector-url"]);function St(t,e){if(t===e)return 0;if(!t.length)return e.length;if(!e.length)return t.length;const n=[];for(let a=0;a<=e.length;a++)n[a]=[a];for(let a=0;a<=t.length;a++)n[0][a]=a;for(let a=1;a<=e.length;a++)for(let r=1;r<=t.length;r++)e.charAt(a-1)===t.charAt(r-1)?n[a][r]=n[a-1][r-1]:n[a][r]=Math.min(n[a-1][r-1]+1,n[a][r-1]+1,n[a-1][r]+1);return n[e.length][t.length]}function _t(t,e=x){if(e.has(t))return null;let n=null,a=1/0;for(const l of e){const o=St(t,l);o<a&&(a=o,n=l)}const r=Math.max(3,Math.floor(t.length*.4));return a<=r?n:null}function K(t){return typeof CSS<"u"&&CSS.escape?CSS.escape(t):t.replace(/([!"#$%&'()*+,.\/:;<=>?@[\\\]^`{|}~])/g,"\\$1")}function kt(t=document){const e=t.ownerDocument||t,n=t.nodeType===9?t.body||t.documentElement:t;if(!n)return[];const a=[],r=[n,...n.querySelectorAll("*")];for(let l=0;l<r.length;l++){const o=r[l];if(o.attributes)for(let d=0;d<o.attributes.length;d++){const i=o.attributes[d];if(i.name.startsWith("data-ln-")&&i.name.endsWith("-for")){const s=(i.value||"").trim();if(!s){a.push({type:"id-empty",element:o,attribute:i.name,targetId:"",message:`[ln-debug] Empty ID reference in <${o.tagName.toLowerCase()} ${i.name}="">.`});continue}e.getElementById(s)||e.querySelector("#"+K(s))||a.push({type:"id-unresolved",element:o,attribute:i.name,targetId:s,message:`[ln-debug] Unresolved ID reference: <${o.tagName.toLowerCase()} ${i.name}="${s}"> targets "#${s}", but no element with id="${s}" exists in the document.`})}}}return a}function xt(t=document){const e=t.ownerDocument||t,n=t.nodeType===9?t.body||t.documentElement:t;if(!n)return[];const a=[],r=[n,...n.querySelectorAll("*")];for(let l=0;l<r.length;l++){const o=r[l];if(o.attributes)for(let d=0;d<o.attributes.length;d++){const i=o.attributes[d];if(i.name.startsWith("data-ln-")&&(i.name.endsWith("-source")||i.name.endsWith("-store"))&&i.name!=="data-ln-data-store"){const c=(i.value||"").trim();if(!c){a.push({type:"store-empty",element:o,attribute:i.name,storeName:"",message:`[ln-debug] Empty store reference in <${o.tagName.toLowerCase()} ${i.name}="">.`});continue}const u=K(c),f=e.querySelector(`[data-ln-data-store="${u}"], [data-ln-store="${u}"]`),D=typeof window<"u"&&window.lnDataStore&&typeof window.lnDataStore.getStore=="function"&&window.lnDataStore.getStore(c);!f&&!D&&a.push({type:"store-unresolved",element:o,attribute:i.name,storeName:c,message:`[ln-debug] Unresolved store reference: <${o.tagName.toLowerCase()} ${i.name}="${c}"> targets store "${c}", but no [data-ln-data-store="${c}"] exists in the document.`})}}}return a}function $t(t=document){t.ownerDocument;const e=t.nodeType===9?t.body||t.documentElement:t;if(!e)return[];const n=[],a=Array.from(e.querySelectorAll("[data-ln-data-store]"));e.hasAttribute&&e.hasAttribute("data-ln-data-store")&&a.unshift(e);const r=new Map;for(let l=0;l<a.length;l++){const o=a[l],d=(o.getAttribute("data-ln-data-store")||"").trim();d&&(r.has(d)||r.set(d,[]),r.get(d).push(o))}for(const[l,o]of r.entries())o.length>1&&n.push({type:"store-duplicate",storeName:l,elements:o,message:`[ln-debug] Duplicate store name: Multiple elements declare data-ln-data-store="${l}". Store names must be unique across the document.`});return n}function Dt(t=document,e=x){const n=t.nodeType===9?t.body||t.documentElement:t;if(!n)return[];const a=[],r=[n,...n.querySelectorAll("*")];for(let l=0;l<r.length;l++){const o=r[l];if(o.attributes)for(let d=0;d<o.attributes.length;d++){const i=o.attributes[d];if(i.name.startsWith("data-ln-")&&!e.has(i.name)){const s=_t(i.name,e),c=s?` Did you mean "${s}"?`:"";a.push({type:"attribute-unknown",element:o,attribute:i.name,suggestion:s,message:`[ln-debug] Unknown attribute "${i.name}" on <${o.tagName.toLowerCase()}>.${c}`})}}}return a}function C(t=typeof document<"u"?document:null,e={}){if(!t)return{idIssues:[],storeIssues:[],uniquenessIssues:[],spellingIssues:[],total:0};const n=e.validAttributes||x,a=kt(t),r=xt(t),l=$t(t),o=Dt(t,n),d=[...a,...r,...l,...o];if(!e.silent)for(let i=0;i<d.length;i++)console.warn(d[i].message);return{idIssues:a,storeIssues:r,uniquenessIssues:l,spellingIssues:o,total:d.length}}let h=null;function m(t=typeof document<"u"?document:null,e=50,n=null){if(!t)return;h&&(clearTimeout(h),h=null);function a(){h=setTimeout(()=>{h=null;const r=C(t);n&&n(r)},e)}N()>0?F(a):a()}function It(t,e,n,a){t==="event"?(console.groupCollapsed("[ln-debug] event",e),console.log("target",n),console.log("detail",a),console.groupEnd()):t==="attr"&&(console.groupCollapsed("[ln-debug] attr",e),console.log("target",n),console.log("old → new",a.oldValue,"→",a.newValue),console.groupEnd())}let b=[];function Et(){b=Array.from(document.body.querySelectorAll("[data-ln-debug]")),document.body.hasAttribute("data-ln-debug")&&b.push(document.body)}function J(t){if(t===window||t===document)return b.indexOf(document.body)!==-1;for(let e=0;e<b.length;e++)if(b[e].contains(t))return!0;return!1}function Ot(t,e,n,a){J(n)&&It(t,e,n,a)}function $(){Et(),Y(b.length>0?Ot:null,b.length>0?J:null)}function P(){$()}function Tt(){typeof window>"u"||(window.lnCore=window.lnCore||{},!window.lnCore._debugGateBound&&(window.lnCore._debugGateBound=!0,p(function(){$(),wt(["data-ln-debug"],$)},"ln-debug")))}return(function(){const t="data-ln-debug",e="lnDebug";if(typeof window<"u"&&window[e]!==void 0)return;const n={"data-ln-debug":{type:"marker",description:"Enables developer diagnostics overlay, live validation badges, and inspection logging"}};Tt();function a(l){return this.dom=l,m(l.ownerDocument||document),P(),this}a.prototype.verify=function(l,o){return C(l||(this.dom?this.dom.ownerDocument||this.dom:document),o)},a.prototype.destroy=function(){delete this.dom[e],P()};const r=bt(t,e,a,"ln-debug",{attributes:n,onInit:function(l){typeof document<"u"&&m(l&&l.ownerDocument?l.ownerDocument:document)},onSubtreeChange:function(l){typeof document<"u"&&m(l&&l.ownerDocument?l.ownerDocument:document)}});r.verify=function(l,o){return C(l||document,o)},r.schedule=function(l,o,d){return m(l||document,o,d)}})(),y.scheduleVerification=m,y.verifyDOM=C,Object.defineProperty(y,Symbol.toStringTag,{value:"Module"}),y})({});
@@ -170,6 +170,7 @@ export const VALID_ATTRIBUTES = new Set([
170
170
  'data-ln-route-keep',
171
171
  'data-ln-route-target',
172
172
  'data-ln-route-title',
173
+ 'data-ln-router-base',
173
174
  'data-ln-router-hydrate',
174
175
  'data-ln-scroll',
175
176
  'data-ln-scroll-behavior',
@@ -80,6 +80,38 @@ Route templates and outlets are declared in HTML. Triggers are plain same-origin
80
80
  </template>
81
81
  ```
82
82
 
83
+ ### Base URL & Subdirectory Deployment (`<base href="...">` / `data-ln-router-base`)
84
+
85
+ When deploying an SPA inside a subdirectory or virtual path (e.g. `https://example.com/spa/`, `https://example.com/admin/`), client-side routing should remain clean and decoupled from server path prefixes.
86
+
87
+ You declare the base URL using standard HTML in `<head>`:
88
+
89
+ ```html
90
+ <head>
91
+ <base href="/spa/">
92
+ </head>
93
+ ```
94
+
95
+ Or declaratively via `data-ln-router-base` on the outlet:
96
+
97
+ ```html
98
+ <main data-ln-outlet data-ln-router-base="/spa"></main>
99
+ ```
100
+
101
+ #### How Base URL Resolution Works:
102
+ 1. **Relative Route Authoring**: Route templates declare relative patterns without repeating the base prefix:
103
+ ```html
104
+ <template data-ln-route="/">...</template>
105
+ <template data-ln-route="/packages">...</template>
106
+ <template data-ln-route="/tenants/:id">...</template>
107
+ ```
108
+ 2. **Path Matching**: When matching the browser URL (`/spa/packages`), `ln-router` strips the base URL (`/spa`), matching cleanly against `/packages`.
109
+ 3. **Absolute History URLs**: When navigating (`router.navigate('/packages')` or clicking `<a href="/packages">` / `<a href="packages">`), `ln-router` automatically prepends the base URL, pushing the absolute `/spa/packages` path to the browser history (`history.pushState`).
110
+ 4. **Anchor Interception**: Both relative links (`<a href="packages">`, `<a href="/packages">`) and pre-prefixed links (`<a href="/spa/packages">`) are intercepted and resolved against the base URL.
111
+ 5. **Programmatic API**:
112
+ - `router.base()` returns the active normalized base URL (e.g. `"/spa"` or `""`).
113
+ - `router.toUrl(relPath)` converts a relative route path to its full absolute URL with base prefix (e.g. `router.toUrl('/packages')` → `"/spa/packages"`).
114
+
83
115
  ---
84
116
 
85
117
  ## 3. The Declarative API & State Contract
@@ -131,6 +163,7 @@ If the **primary** outlet cannot be resolved, the router logs a `console.warn` a
131
163
  - `data-ln-route-target="id"`: Sets an explicit element ID to render this route into. Templates with no `data-ln-route-target` belong to the **primary region** (default outlet).
132
164
  - `data-ln-route-title="text"`: Sets `document.title` on successful navigation (primary region only).
133
165
  - `data-ln-outlet`: Marks the default outlet element (falls back to the first `<main>` element if omitted).
166
+ - `data-ln-router-base="path"`: Declares a base URL prefix for subdirectory hosting (e.g. `"/spa"`). Can also be declared via `<base href="/spa/">` in `<head>`.
134
167
  - `data-ln-router-hydrate`: Placed on the outlet element to signal that initial SSR (Server-Side Rendered) content is already present, letting the router skip the initial clone and register events cleanly.
135
168
  - `data-ln-route-keep`: Placed on a **target element** (not a template). When present, the router skips teardown and DOM swap for that region if the matched template is the same as the one currently mounted — surviving param-only URL changes while preserving DOM state (inputs, scroll, open panels). When the matched template changes, teardown and swap proceed normally. `data-ln-route-keep` also opts an auxiliary region out of auto-clear: without it, a region left unmatched by the current URL is emptied automatically; with it, unmatched content is left in place. Ignored on the primary outlet (the primary always re-renders).
136
169
 
@@ -1 +1 @@
1
- var LnAshlarComponent=(function(v){"use strict";function j(){return typeof window>"u"?!1:window.lnDebug===!0||window.lnCore&&window.lnCore._debugSink?!0:typeof document<"u"&&document.body?document.body.hasAttribute("data-ln-debug")||document.body.querySelector("[data-ln-debug]")!==null:!1}function S(e){if(typeof window>"u")return!1;if(window.lnDebug===!0)return!0;if(window.lnCore&&window.lnCore._debugIsContained)return e?window.lnCore._debugIsContained(e):window.lnCore._debugSink!==null;if(e&&e.closest){const t=e.closest("[data-ln-debug]");return!(!t||typeof document<"u"&&t===document.documentElement)}return typeof document<"u"&&document.body?document.body.hasAttribute("data-ln-debug"):!1}if(typeof window<"u"&&(window.lnCore=window.lnCore||{},!window.lnCore._warnBound)){window.lnCore._warnBound=!0;const e=console.warn;console.warn=function(...t){if(typeof t[0]=="string"&&(t[0].startsWith("[ln-")||t[0].startsWith("[lnCore"))){let r=null;for(let o=1;o<t.length;o++)if(t[o]&&t[o].nodeType===1){r=t[o];break}if(!S(r))return}e.apply(console,t)}}function k(e,t,n){const r=n||{};window.lnCore._debugSink&&window.lnCore._debugSink("event",t,e,r),e.dispatchEvent(new CustomEvent(t,{bubbles:!0,detail:r}))}function de(e,t,n){const r=n||{};window.lnCore._debugSink&&window.lnCore._debugSink("event",t,e,r);const o=new CustomEvent(t,{bubbles:!0,cancelable:!0,detail:r});return e.dispatchEvent(o),o}function y(e,t){if(!document.body){document.addEventListener("DOMContentLoaded",function(){y(e,t)}),console.warn("["+t+'] Script loaded before <body> — add "defer" to your <script> tag');return}e()}function fe(e,t){if(e.ctrlKey||e.metaKey||e.shiftKey||e.altKey||e.button!==0||!t)return!1;const n=t.getAttribute("href");return!(!n||t.getAttribute("target")==="_blank"||t.hasAttribute("download")||n.startsWith("mailto:")||n.startsWith("tel:")||n==="#"||n.startsWith("#")||t.hostname&&t.hostname!==window.location.hostname)}const B={};function we(e,t){B[e]=t}function he(e){return B[e]||{ingress:t=>t,egress:t=>t}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerDataMapper=we,window.lnCore.getDataMapper=he);function ge(){typeof window>"u"||(window.lnCore=window.lnCore||{},!window.lnCore._localeObserverBound&&(window.lnCore._localeObserverBound=!0,y(function(){new MutationObserver(function(){k(document,"ln-core:locale-change",{})}).observe(document.documentElement,{attributes:!0,attributeFilter:["lang"],subtree:!0})},"ln-core")))}const F={};function pe(e,t){if(!e||typeof t!="object")return;const n=e.toLowerCase().split("-")[0];F[n]=t}function be(e){if(!e)return null;const t=e.toLowerCase().split("-")[0];return F[t]||null}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerLocaleFallback=pe,window.lnCore.getLocaleFallback=be,window.lnCore.ensureLocaleObserver=ge);const E={};function ye(e,t){E[e]||(E[e]=document.querySelector('[data-ln-template="'+e+'"]'));const n=E[e];return n?n.content.cloneNode(!0):(console.warn("["+(t||"ln-core")+'] Template "'+e+'" not found'),null)}function H(e,t){if(!e||!t)return e;const n=e.querySelectorAll("[data-ln-field]");for(let l=0;l<n.length;l++){const a=n[l],s=a.getAttribute("data-ln-field");t[s]!=null&&(a.textContent=t[s])}const r=e.querySelectorAll("[data-ln-attr]");for(let l=0;l<r.length;l++){const a=r[l],s=a.getAttribute("data-ln-attr").split(",");for(let c=0;c<s.length;c++){const d=s[c].trim().split(":");if(d.length!==2)continue;const f=d[0].trim(),u=d[1].trim();t[u]!=null&&a.setAttribute(f,t[u])}}const o=e.querySelectorAll("[data-ln-show]");for(let l=0;l<o.length;l++){const a=o[l],s=a.getAttribute("data-ln-show");s in t&&a.classList.toggle("hidden",!t[s])}const i=e.querySelectorAll("[data-ln-class]");for(let l=0;l<i.length;l++){const a=i[l],s=a.getAttribute("data-ln-class").split(",");for(let c=0;c<s.length;c++){const d=s[c].trim().split(":");if(d.length!==2)continue;const f=d[0].trim(),u=d[1].trim();u in t&&a.classList.toggle(f,!!t[u])}}return e}function me(e,t){e.matches&&e.matches("[data-ln-form], [data-ln-fillable]")&&(window.lnCore._debugSink&&window.lnCore._debugSink("event","ln-fill",e,t??null),e.dispatchEvent(new CustomEvent("ln-fill",{detail:t??null,bubbles:!0})));const n=e.querySelectorAll("[data-ln-form], [data-ln-fillable]");for(let r=0;r<n.length;r++)window.lnCore._debugSink&&window.lnCore._debugSink("event","ln-fill",n[r],t??null),n[r].dispatchEvent(new CustomEvent("ln-fill",{detail:t??null,bubbles:!0}));return e}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore._fillBound||(window.lnCore._fillBound=!0,document.addEventListener("ln-fill",function(e){if(!(!e.target.matches||!e.target.matches("[data-ln-fillable]")))if(e.detail)H(e.target,e.detail);else{const t=e.target.querySelectorAll("[data-ln-field]");for(let n=0;n<t.length;n++)t[n].textContent=""}})));function P(e,t){if(!e||!t)return e;const n=document.createTreeWalker(e,NodeFilter.SHOW_TEXT);for(;n.nextNode();){const i=n.currentNode;i.textContent.indexOf("{{")!==-1&&(i.textContent=i.textContent.replace(/\{\{\s*(\w+)\s*\}\}/g,function(l,a){return t[a]!==void 0?t[a]:""}))}const r=function(i,l){return t[l]!==void 0?t[l]:""},o=Array.from(e.querySelectorAll("*"));e.nodeType===1&&o.push(e);for(let i=0;i<o.length;i++){const l=o[i],a=l.attributes;for(let s=0;s<a.length;s++){const c=a[s];c.value.indexOf("{{")!==-1&&l.setAttribute(c.name,c.value.replace(/\{\{\s*(\w+)\s*\}\}/g,r))}}return e}function Ce(e,t,n,r,o,i){const l={};for(let s=0;s<e.children.length;s++){const c=e.children[s],d=c.getAttribute("data-ln-render-key");d&&(l[d]=c)}const a=document.createDocumentFragment();for(let s=0;s<t.length;s++){const c=t[s],d=String(r(c));let f=l[d];if(f)o(f,c,s);else{const u=ye(n,i);if(!u||(P(u,c),f=u.firstElementChild,!f))continue;f.setAttribute("data-ln-render-key",d),o(f,c,s)}a.appendChild(f)}e.textContent="",e.appendChild(a)}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.fillTemplate=P,window.lnCore.fill=H,window.lnCore.lnFill=me,window.lnCore.renderList=Ce);function V(e,t,n,r,o){if(!e||t===null)return!0;const i=r||"ln-component",l=e.type;if(l==="trigger"||l==="marker"||l==="string"||l==="list"||!l||t===""&&e.fallback!==void 0)return!0;const a=s=>{o?console.warn(s,o):console.warn(s)};if(l==="boolean"){const s=t.trim().toLowerCase();return s!==""&&s!=="true"&&s!=="false"&&s!=="1"&&s!=="0"?(a(`[${i}] Invalid value "${t}" for boolean attribute "${n}". Allowed: "true", "false", or presence-only.`),!1):!0}if(l==="enum"){const s=e.values||[];return s.includes(t)?!0:(a(`[${i}] Invalid value "${t}" for attribute "${n}". Allowed: ${s.join(", ")}. Fallback: "${e.fallback}".`),!1)}if(l==="integer"){if(!/^-?\d+$/.test(t))return a(`[${i}] Invalid integer "${t}" for attribute "${n}". Fallback: ${e.fallback}.`),!1;const s=parseInt(t,10);return e.min!==void 0&&s<e.min?(a(`[${i}] Value ${s} for attribute "${n}" is less than min (${e.min}).`),!1):e.max!==void 0&&s>e.max?(a(`[${i}] Value ${s} for attribute "${n}" is greater than max (${e.max}).`),!1):!0}if(l==="float")return isNaN(Number(t))?(a(`[${i}] Invalid float "${t}" for attribute "${n}". Fallback: ${e.fallback}.`),!1):!0;if(l==="json")try{return JSON.parse(t),!0}catch(s){return a(`[${i}] Invalid JSON for attribute "${n}": ${s.message}. Fallback: ${e.fallback}.`),!1}return!0}function _e(e){const t={};for(const n in e){const r=e[n];r&&r.effect&&(t[n]=r.effect)}return Object.keys(t).length?t:null}function Ae(e){if(e.onAttrChange&&!e.declared)return null;const t=new Set;if(e.effects)for(const n in e.effects)t.add(n);if(e.onAttrChange&&e.declared)for(const n of e.declared)t.add(n);return t}function O(e,t,n,r){if(e.nodeType!==1)return;const i=t.indexOf("[")!==-1||t.indexOf(".")!==-1||t.indexOf("#")!==-1?t:"["+t+"]",l=Array.from(e.querySelectorAll(i));e.matches&&e.matches(i)&&l.push(e);for(const a of l)if(!a[n]){window.lnCore._persistSink&&a.hasAttribute("data-ln-persist")&&window.lnCore._persistSink(a,t);try{a[n]=new r(a)}catch(s){console.error("["+n+"] init failed",a,s)}}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore._bootHolds=window.lnCore._bootHolds||0,window.lnCore._bootQueue=window.lnCore._bootQueue||[]);function ve(){return typeof window<"u"&&window.lnCore&&window.lnCore._bootHolds||0}function Se(e){typeof window<"u"?(window.lnCore=window.lnCore||{},window.lnCore._bootHolds=window.lnCore._bootHolds||0,window.lnCore._bootQueue=window.lnCore._bootQueue||[],window.lnCore._bootHolds>0?window.lnCore._bootQueue.push(e):setTimeout(e,0)):e()}function U(){window.lnCore=window.lnCore||{};const e=window.lnCore._attrRegistry=window.lnCore._attrRegistry||{byAttr:new Map,reactive:[],persist:[]};return e.byReactive=e.byReactive||new Map,e.reactiveWildcard=e.reactiveWildcard||[],e}function ke(e){const t=U(),n=e.observed||[];for(let r=0;r<n.length;r++){const o=n[r];t.byAttr.has(o)||t.byAttr.set(o,[]),t.byAttr.get(o).push(e)}if(t.byDeclaredAttr=t.byDeclaredAttr||new Map,e.attributes)for(const r in e.attributes){t.byDeclaredAttr.has(r)||t.byDeclaredAttr.set(r,[]);const o=t.byDeclaredAttr.get(r);o.some(i=>i.componentTag===e.componentTag)||o.push({spec:e.attributes[r],componentTag:e.componentTag})}if(e.onAttrChange||e.effects){t.reactive.push(e);const r=Ae(e);if(r===null)t.reactiveWildcard.push(e);else for(const o of r)t.byReactive.has(o)||t.byReactive.set(o,[]),t.byReactive.get(o).push(e)}e.persist&&t.persist.push(e)}function Q(e,t,n,r){for(let o=0;o<e.length;o++){const i=e[o];if(!t[i.attribute])continue;const l=i.effects&&i.effects[n];l?l(t,n,r):i.onAttrChange&&(!i.declared||i.declared.has(n))&&i.onAttrChange(t,n,r)}}function Ee(e){const t=e.target,n=e.attributeName;if(e.oldValue===t.getAttribute(n))return;const r=U(),o=r.byAttr.get(n);if(j()&&r.byDeclaredAttr&&r.byDeclaredAttr.has(n)&&S(t)){const i=r.byDeclaredAttr.get(n),l=t.getAttribute(n);for(let a=0;a<i.length;a++)V(i[a].spec,l,n,i[a].componentTag,t)}if(window.lnCore._debugSink&&(n.indexOf("data-ln-")===0||o)&&window.lnCore._debugSink("attr",n,t,{oldValue:e.oldValue,newValue:t.getAttribute(n)}),n.indexOf("data-ln-")===0){const i=r.byReactive.get(n);i&&Q(i,t,n,e.oldValue),r.reactiveWildcard.length&&Q(r.reactiveWildcard,t,n,e.oldValue)}if(o)for(let i=0;i<o.length;i++){const l=o[i];if(l.handler){l.handler(t,n,e.oldValue);continue}l.onAttributeChange&&t[l.attribute]?l.onAttributeChange(t,n):(O(t,l.selector,l.attribute,l.ComponentFn),l.onInit&&l.onInit(t))}}function Oe(){window.lnCore=window.lnCore||{},!window.lnCore._attrObserverBound&&(window.lnCore._attrObserverBound=!0,y(function(){new MutationObserver(function(t){for(let n=0;n<t.length;n++)try{Ee(t[n])}catch(r){console.error("[ln-core] mutation handler failed",t[n].target,r)}}).observe(document.body,{attributes:!0,subtree:!0,attributeOldValue:!0})},"ln-core"))}function z(){return window.lnCore=window.lnCore||{},window.lnCore._lifecycleRegistry=window.lnCore._lifecycleRegistry||[]}function xe(e){const t=z();if(t.length){if(e.target)for(let n=0;n<t.length;n++){const r=t[n];if(r.onSubtreeChange){const o=r.query,i=e.target.nodeType===1?e.target.matches(o)?e.target:e.target.closest(o):e.target.parentElement?e.target.parentElement.closest(o):null;i&&r.onSubtreeChange(i,e)}}for(let n=0;n<e.addedNodes.length;n++){const r=e.addedNodes[n];if(r.nodeType===1)for(let o=0;o<t.length;o++){const i=t[o];O(r,i.selector,i.attribute,i.ComponentFn),i.onInit&&i.onInit(r)}}for(let n=0;n<e.removedNodes.length;n++){const r=e.removedNodes[n];if(r.nodeType===1)for(let o=0;o<t.length;o++){const i=t[o],l=i.query,a=Array.from(r.querySelectorAll(l));r.matches&&r.matches(l)&&a.push(r);for(let s=0;s<a.length;s++){const c=a[s];if(!document.contains(c)){const d=c[i.attribute];if(d&&typeof d.destroy=="function")try{d.destroy()}catch(f){console.error("["+i.attribute+"] destroy failed",c,f)}delete c[i.attribute]}}}}}}function Re(){window.lnCore=window.lnCore||{},!window.lnCore._lifecycleObserverBound&&(window.lnCore._lifecycleObserverBound=!0,y(function(){new MutationObserver(function(t){for(let n=0;n<t.length;n++){const r=t[n];if(r.type==="childList")try{xe(r)}catch(o){console.error("[ln-core] lifecycle handler failed",r.target,o)}}}).observe(document.body,{childList:!0,subtree:!0})},"ln-core"))}function De(e,t,n,r,o={}){const i=o.extraAttributes||[],l=o.onAttributeChange||null,a=o.onSubtreeChange||null,s=o.onInit||null,c=o.onAttrChange||null,d=o.effects||null,f=o.attributes||null,u=f?_e(f):d,w=f?new Set(Object.keys(f)):null,h=o.persist||null;function p(L){const b=L||document.body;if(O(b,e,t,n),f&&j())for(const C in f){const Ve=f[C],W=Array.from(b.querySelectorAll("["+C+"]"));b.matches&&b.matches("["+C+"]")&&W.push(b);for(let K=0;K<W.length;K++){const N=W[K];S(N)&&V(Ve,N.getAttribute(C),C,r,N)}}s&&s(b)}const I=[];if(e.indexOf("[")!==-1){const L=/\[([\w-]+)/g;let b;for(;(b=L.exec(e))!==null;)I.push(b[1])}else I.push(e);ke({selector:e,attribute:t,componentTag:r,attributes:f,ComponentFn:n,onInit:s,observed:I.concat(i),onAttributeChange:l,onAttrChange:c,effects:u,declared:w,persist:h}),Oe();const Pe=e.indexOf("[")!==-1||e.indexOf(".")!==-1||e.indexOf("#")!==-1?e:"["+e+"]";z().push({selector:e,attribute:t,ComponentFn:n,onInit:s,onSubtreeChange:a,query:Pe}),Re(),window[t]=p;function ue(){ve()>0?Se(function(){p(document.body)}):p(document.body)}return document.readyState==="loading"?document.addEventListener("DOMContentLoaded",ue):ue(),p}function G(e){return(e||"").replace(/^#/,"")}function x(e){const t=e===void 0?location.hash:e,n={},r=G(t);if(!r)return n;const o=r.split("&");for(let i=0;i<o.length;i++){const l=o[i];if(!l)continue;const a=l.indexOf(":"),s=a>-1?l.slice(0,a):l,c=a>-1?l.slice(a+1):"";if(s)try{n[s]=decodeURIComponent(c)}catch{n[s]=c}}return n}function Me(e){if(!e)return null;const t=x();return e in t?t[e]:null}function $e(e,t){if(!e)return;const n=x();t==null?delete n[e]:n[e]=String(t);const o=Object.keys(n).map(function(i){const l=n[i];return l===""?i:i+":"+encodeURIComponent(l)}).join("&");G(location.hash)!==o&&(location.hash=o)}function Te(e){return e.button===1||e.ctrlKey||e.metaKey||e.shiftKey?!1:(e.preventDefault(),!0)}function qe(e,t){if(!e||!e.hasAttribute("data-ln-hash"))return null;const n=e.getAttribute("data-ln-hash");if(n&&n.trim()!=="")return n.trim();const r=e.getAttribute("data-ln-sort")||e.getAttribute("data-ln-search-for")||e.getAttribute("data-ln-search")||e.getAttribute("data-ln-filter")||e.id;return r?t?r+"-"+t:r:t||null}function Ie(e,t){return!t||t==="none"||e===null||e===void 0?null:String(e)+"."+t}function Le(e){return!e||typeof e!="string"?null:e.endsWith(".asc")?{fieldOrColumn:e.slice(0,-4),direction:"asc"}:e.endsWith(".desc")?{fieldOrColumn:e.slice(0,-5),direction:"desc"}:null}function We(e,t){return!e||!Array.isArray(t)||t.length===0?null:e+":"+t.map(encodeURIComponent).join(",")}function Ke(e){if(!e||typeof e!="string")return null;const t=e.indexOf(":");if(t===-1)return null;const n=e.slice(0,t),r=e.slice(t+1),o=r?r.split(",").map(function(i){try{return decodeURIComponent(i)}catch{return i}}).filter(Boolean):[];return{key:n,values:o}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.hashParse=x,window.lnCore.hashGet=Me,window.lnCore.hashSet=$e,window.lnCore.hashLinkClick=Te,window.lnCore.resolveHashNamespace=qe,window.lnCore.hashSortEncode=Ie,window.lnCore.hashSortDecode=Le,window.lnCore.hashFilterEncode=We,window.lnCore.hashFilterDecode=Ke);function Ne(e,{isHydration:t=!1,hasPrimaryRegion:n=!1,primaryMatch:r=null}={}){const o=n?!r:!e.some(c=>c.match),i=[],l=[];for(const c of e)if(!(!c.targetEl&&!c.isPending)){if(!c.match){const d=t&&c.hasHydrate&&c.hasChildren;!c.hasKeep&&c.hasChildren&&!d&&c.targetEl&&i.push(c);continue}c.hasKeep&&c.mountedTemplate===c.match.route.templateNode||l.push(Object.assign({},c,{skipMount:t&&c.hasHydrate&&c.hasChildren}))}l.sort((c,d)=>c.regionKey==="__primary__"?-1:d.regionKey==="__primary__"?1:0);const s=l.find(c=>c.regionKey==="__primary__")||l[0]||null;return{notFound:o,clears:i,swaps:l,owner:s}}const R={navigate:function(e){m(e,{historyAction:"push"})},replace:function(e){m(e,{historyAction:"replace"})},current:function(){return _===null?null:{path:_,params:Z,query:ee,route:te,regions:X}}},D="data-ln-route",J="lnRoute";typeof window<"u"&&(window.lnRouter=R);function M(e){ae(e),se(e),g.size>0&&le()}const je={"data-ln-route":{effect:M,type:"string",description:"URL path pattern matched by this route template"},"data-ln-route-target":{effect:M,type:"string",description:"Target outlet element selector where route content is rendered"},"data-ln-route-title":{effect:M,type:"string",description:"Document title template set when route is activated"},"data-ln-route-keep":{type:"boolean",fallback:!1,description:"Preserve mounted DOM nodes in memory instead of rebuilding"},"data-ln-router-hydrate":{type:"boolean",fallback:!1,description:"Hydrate existing DOM content on initial router boot"}},g=new Map,$=new WeakMap;let X=new Map,Y=!1,_=null,Z={},ee={},te=null,T=!1;function ne(e,t,n){T?queueMicrotask(function(){k(e,t,n)}):k(e,t,n)}function A(e){try{const i=new URL(e,window.location.origin);e=i.pathname+i.search+i.hash}catch{}let[t]=e.split("#"),[n,r]=t.split("?");const o={};if(r){const i=new URLSearchParams(r);for(const[l,a]of i.entries())o[l]=a}return n=n.replace(/\/+$/,""),n===""&&(n="/"),{path:n,query:o}}function re(e,t){if(e.pattern==="*")return 1;if(t.pattern==="*")return-1;const n=e.segments,r=t.segments,o=Math.max(n.length,r.length);for(let i=0;i<o;i++){const l=n[i],a=r[i];if(l===void 0)return 1;if(a===void 0)return-1;if(l==="*")return 1;if(a==="*")return-1;const s=l.startsWith(":"),c=a.startsWith(":");if(s&&!c)return 1;if(!s&&c)return-1}return 0}function oe(e,t){const n=e.split("/").filter(Boolean);for(const r of t){if(r.pattern==="*")return{route:r,params:{wildcard:e}};const o=r.segments,i={};let l=!0;if(!(n.length>o.length&&o[o.length-1]!=="*")){for(let a=0;a<o.length;a++){const s=o[a],c=n[a];if(s==="*"){i.wildcard=n.slice(a).join("/");break}if(c===void 0){l=!1;break}if(s.startsWith(":"))i[s.slice(1)]=decodeURIComponent(c);else if(s!==c){l=!1;break}}if(l&&(o.indexOf("*")!==-1||n.length<=o.length))return{route:r,params:i}}}return null}function q(e,t={}){const n=t.warn!==!1;if(e!=="__primary__"){const o=document.getElementById(e);return!o&&n&&console.warn(`[ln-router] Explicit target element #${e} not found in DOM`),o}const r=document.querySelector("[data-ln-outlet]")||document.querySelector("main");return!r&&n&&console.warn("[ln-router] Default outlet (element with [data-ln-outlet] or <main>) not found in DOM"),r}function ie(e){if(!e)return;const t=Array.from(e.querySelectorAll("*")),n=[e].concat(t);for(const o of n)for(const i of Object.keys(o))if(i.startsWith("ln")&&o[i]&&typeof o[i].destroy=="function")try{o[i].destroy()}catch(l){console.error(`[ln-router] Error destroying component ${i} on element:`,o,l)}const r=document.querySelectorAll('[data-ln-popover="open"]');for(const o of r){const i=o.lnPopover;if(i&&i.trigger&&e.contains(i.trigger))try{i.destroy()}catch(l){console.error("[ln-router] Error destroying open popover:",l)}}}function m(e,t={}){const{path:n,query:r}=A(e),o=new Map;for(const[u,w]of g)o.set(u,oe(n,w.sorted));const i=o.get("__primary__")||null,l=q("__primary__",{warn:!!i}),a=g.has("__primary__"),s=[];for(const[u,w]of o){const h=u==="__primary__"?l:q(u,{warn:!1}),p=!h&&!!(i&&i.route&&i.route.templateNode&&i.route.templateNode.content&&i.route.templateNode.content.querySelector("#"+CSS.escape(u)));!h&&!p&&w&&console.warn(`[ln-router] Explicit target element #${u} not found in DOM`),s.push({regionKey:u,match:w,targetEl:h,isPending:p,hasKeep:!!h&&h.hasAttribute("data-ln-route-keep"),hasHydrate:!!h&&h.hasAttribute("data-ln-router-hydrate"),hasChildren:!!h&&h.children.length>0,mountedTemplate:h&&$.get(h)||null})}const c=Ne(s,{isHydration:!!t.isHydration,hasPrimaryRegion:a,primaryMatch:i});if(c.notFound){ne(document.body,"ln-router:not-found",{path:n});return}if(de(l||document.body,"ln-router:before-navigate",{from:_,to:e,params:i?i.params:{},query:r}).defaultPrevented)return;t.historyAction==="push"?window.history.pushState(null,"",e):t.historyAction==="replace"&&window.history.replaceState(null,"",e);const f=function(){for(const u of c.clears)ie(u.targetEl),u.targetEl.replaceChildren(),$.delete(u.targetEl);for(const u of c.swaps){if((u.isPending||!u.targetEl||!document.contains(u.targetEl))&&(u.targetEl=u.regionKey==="__primary__"?l:document.getElementById(u.regionKey)),!u.targetEl){console.warn(`[ln-router] Target element #${u.regionKey} could not be resolved`);continue}if(u.skipMount||(ie(u.targetEl),u.targetEl.replaceChildren(u.match.route.templateNode.content.cloneNode(!0))),$.set(u.targetEl,u.match.route.templateNode),c.owner&&u.regionKey===c.owner.regionKey){if(u.match.route.title){let w=u.match.route.title;if(u.match.params)for(const[h,p]of Object.entries(u.match.params))w=w.replace(new RegExp("\\{\\{\\s*"+h+"\\s*\\}\\}","g"),p);document.title=w}if(!t.isHydration){u.targetEl.hasAttribute("tabindex")||u.targetEl.setAttribute("tabindex","-1");const w=u.targetEl.querySelector("h1, h2, h3, h4, h5, h6");w?(w.setAttribute("tabindex","-1"),w.focus()):u.targetEl.focus(),u.regionKey==="__primary__"&&u.targetEl.scrollIntoView({block:"start",behavior:"instant"})}}ne(u.targetEl,"ln-router:navigated",{path:e,params:u.match.params,query:r,route:u.match.route,target:u.targetEl,region:u.regionKey})}_=e,ee=r,te=i?i.route:null,Z=i?i.params:{},X=new Map(Array.from(o.entries()).map(([u,w])=>[u,w?{route:w.route,params:w.params}:null]))};document.startViewTransition&&!t.isHydration?document.startViewTransition(f):f()}function Be(e){const t=e.target.closest("a");if(!t||!fe(e,t))return;const n=t.getAttribute("href"),{path:r}=A(n);for(const o of g.values())if(oe(r,o.sorted)){e.preventDefault(),m(n,{historyAction:"push"});return}}function Fe(e,t){const n=Object.keys(e),r=Object.keys(t);if(n.length!==r.length)return!1;for(let o=0;o<n.length;o++){const i=n[o];if(e[i]!==t[i])return!1}return!0}function He(){const e=window.location.pathname+window.location.search,t=R.current();if(t&&t.path!=null){const n=A(e);if(A(t.path).path===n.path&&Fe(t.query,n.query))return}m(e,{historyAction:"skip"})}function le(){Y||(Y=!0,y(function(){document.addEventListener("click",Be),window.addEventListener("popstate",He),T=!0;const e=window.location.pathname+window.location.search+window.location.hash;m(e,{historyAction:"replace",isHydration:!0}),T=!1},"ln-router"))}function se(e){const t=e.getAttribute(D);if(!t)return;const n=e.getAttribute("data-ln-route-target")||null;if(n==="__primary__"){console.warn(`[ln-router] "__primary__" is a reserved region key and cannot be used as data-ln-route-target. Route "${t}" rejected.`);return}const r=n||"__primary__";g.has(r)||g.set(r,{routes:new Map,sorted:[]});const o=g.get(r);if(o.routes.has(t)){console.warn(`[ln-router] Duplicate route pattern registered: "${t}" in region "${r}"`);return}const i=e.getAttribute("data-ln-route-title"),l=t.split("/").filter(Boolean),a={pattern:t,segments:l,target:n,title:i,templateNode:e},s=q(r);s&&s.contains(e)&&console.warn(`[ln-router] Route template with pattern "${t}" is declared inside its own outlet element:`,e),o.routes.set(t,a),o.sorted=Array.from(o.routes.values()).sort(re)}function ae(e){const t=e.getAttribute(D);if(!t)return;const r=e.getAttribute("data-ln-route-target")||null||"__primary__",o=g.get(r);o&&(o.routes.delete(t),o.sorted=Array.from(o.routes.values()).sort(re),o.routes.size===0&&g.delete(r))}function ce(e){return this.dom=e,se(e),this}return ce.prototype.destroy=function(){ae(this.dom),delete this.dom[J]},De(D,J,ce,"ln-router",{attributes:je,onInit:function(){g.size>0&&le()}}),v.router=R,Object.defineProperty(v,Symbol.toStringTag,{value:"Module"}),v})({});
1
+ var LnAshlarComponent=(function(k){"use strict";function N(){return typeof window>"u"?!1:window.lnDebug===!0||window.lnCore&&window.lnCore._debugSink?!0:typeof document<"u"&&document.body?document.body.hasAttribute("data-ln-debug")||document.body.querySelector("[data-ln-debug]")!==null:!1}function E(e){if(typeof window>"u")return!1;if(window.lnDebug===!0)return!0;if(window.lnCore&&window.lnCore._debugIsContained)return e?window.lnCore._debugIsContained(e):window.lnCore._debugSink!==null;if(e&&e.closest){const t=e.closest("[data-ln-debug]");return!(!t||typeof document<"u"&&t===document.documentElement)}return typeof document<"u"&&document.body?document.body.hasAttribute("data-ln-debug"):!1}if(typeof window<"u"&&(window.lnCore=window.lnCore||{},!window.lnCore._warnBound)){window.lnCore._warnBound=!0;const e=console.warn;console.warn=function(...t){if(typeof t[0]=="string"&&(t[0].startsWith("[ln-")||t[0].startsWith("[lnCore"))){let r=null;for(let o=1;o<t.length;o++)if(t[o]&&t[o].nodeType===1){r=t[o];break}if(!E(r))return}e.apply(console,t)}}function O(e,t,n){const r=n||{};window.lnCore._debugSink&&window.lnCore._debugSink("event",t,e,r),e.dispatchEvent(new CustomEvent(t,{bubbles:!0,detail:r}))}function be(e,t,n){const r=n||{};window.lnCore._debugSink&&window.lnCore._debugSink("event",t,e,r);const o=new CustomEvent(t,{bubbles:!0,cancelable:!0,detail:r});return e.dispatchEvent(o),o}function y(e,t){if(!document.body){document.addEventListener("DOMContentLoaded",function(){y(e,t)}),console.warn("["+t+'] Script loaded before <body> — add "defer" to your <script> tag');return}e()}function ye(e,t){if(e.ctrlKey||e.metaKey||e.shiftKey||e.altKey||e.button!==0||!t)return!1;const n=t.getAttribute("href");return!(!n||t.getAttribute("target")==="_blank"||t.hasAttribute("download")||n.startsWith("mailto:")||n.startsWith("tel:")||n==="#"||n.startsWith("#")||t.hostname&&t.hostname!==window.location.hostname)}const H={};function me(e,t){H[e]=t}function Ce(e){return H[e]||{ingress:t=>t,egress:t=>t}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerDataMapper=me,window.lnCore.getDataMapper=Ce);function _e(){typeof window>"u"||(window.lnCore=window.lnCore||{},!window.lnCore._localeObserverBound&&(window.lnCore._localeObserverBound=!0,y(function(){new MutationObserver(function(){O(document,"ln-core:locale-change",{})}).observe(document.documentElement,{attributes:!0,attributeFilter:["lang"],subtree:!0})},"ln-core")))}const U={};function Ae(e,t){if(!e||typeof t!="object")return;const n=e.toLowerCase().split("-")[0];U[n]=t}function ve(e){if(!e)return null;const t=e.toLowerCase().split("-")[0];return U[t]||null}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerLocaleFallback=Ae,window.lnCore.getLocaleFallback=ve,window.lnCore.ensureLocaleObserver=_e);const x={};function Se(e,t){x[e]||(x[e]=document.querySelector('[data-ln-template="'+e+'"]'));const n=x[e];return n?n.content.cloneNode(!0):(console.warn("["+(t||"ln-core")+'] Template "'+e+'" not found'),null)}function V(e,t){if(!e||!t)return e;const n=e.querySelectorAll("[data-ln-field]");for(let l=0;l<n.length;l++){const s=n[l],a=s.getAttribute("data-ln-field");t[a]!=null&&(s.textContent=t[a])}const r=e.querySelectorAll("[data-ln-attr]");for(let l=0;l<r.length;l++){const s=r[l],a=s.getAttribute("data-ln-attr").split(",");for(let u=0;u<a.length;u++){const d=a[u].trim().split(":");if(d.length!==2)continue;const f=d[0].trim(),g=d[1].trim();t[g]!=null&&s.setAttribute(f,t[g])}}const o=e.querySelectorAll("[data-ln-show]");for(let l=0;l<o.length;l++){const s=o[l],a=s.getAttribute("data-ln-show");a in t&&s.classList.toggle("hidden",!t[a])}const i=e.querySelectorAll("[data-ln-class]");for(let l=0;l<i.length;l++){const s=i[l],a=s.getAttribute("data-ln-class").split(",");for(let u=0;u<a.length;u++){const d=a[u].trim().split(":");if(d.length!==2)continue;const f=d[0].trim(),g=d[1].trim();g in t&&s.classList.toggle(f,!!t[g])}}return e}function ke(e,t){e.matches&&e.matches("[data-ln-form], [data-ln-fillable]")&&(window.lnCore._debugSink&&window.lnCore._debugSink("event","ln-fill",e,t??null),e.dispatchEvent(new CustomEvent("ln-fill",{detail:t??null,bubbles:!0})));const n=e.querySelectorAll("[data-ln-form], [data-ln-fillable]");for(let r=0;r<n.length;r++)window.lnCore._debugSink&&window.lnCore._debugSink("event","ln-fill",n[r],t??null),n[r].dispatchEvent(new CustomEvent("ln-fill",{detail:t??null,bubbles:!0}));return e}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore._fillBound||(window.lnCore._fillBound=!0,document.addEventListener("ln-fill",function(e){if(!(!e.target.matches||!e.target.matches("[data-ln-fillable]")))if(e.detail)V(e.target,e.detail);else{const t=e.target.querySelectorAll("[data-ln-field]");for(let n=0;n<t.length;n++)t[n].textContent=""}})));function Q(e,t){if(!e||!t)return e;const n=document.createTreeWalker(e,NodeFilter.SHOW_TEXT);for(;n.nextNode();){const i=n.currentNode;i.textContent.indexOf("{{")!==-1&&(i.textContent=i.textContent.replace(/\{\{\s*(\w+)\s*\}\}/g,function(l,s){return t[s]!==void 0?t[s]:""}))}const r=function(i,l){return t[l]!==void 0?t[l]:""},o=Array.from(e.querySelectorAll("*"));e.nodeType===1&&o.push(e);for(let i=0;i<o.length;i++){const l=o[i],s=l.attributes;for(let a=0;a<s.length;a++){const u=s[a];u.value.indexOf("{{")!==-1&&l.setAttribute(u.name,u.value.replace(/\{\{\s*(\w+)\s*\}\}/g,r))}}return e}function Ee(e,t,n,r,o,i){const l={};for(let a=0;a<e.children.length;a++){const u=e.children[a],d=u.getAttribute("data-ln-render-key");d&&(l[d]=u)}const s=document.createDocumentFragment();for(let a=0;a<t.length;a++){const u=t[a],d=String(r(u));let f=l[d];if(f)o(f,u,a);else{const g=Se(n,i);if(!g||(Q(g,u),f=g.firstElementChild,!f))continue;f.setAttribute("data-ln-render-key",d),o(f,u,a)}s.appendChild(f)}e.textContent="",e.appendChild(s)}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.fillTemplate=Q,window.lnCore.fill=V,window.lnCore.lnFill=ke,window.lnCore.renderList=Ee);function z(e,t,n,r,o){if(!e||t===null)return!0;const i=r||"ln-component",l=e.type;if(l==="trigger"||l==="marker"||l==="string"||l==="list"||!l||t===""&&e.fallback!==void 0)return!0;const s=a=>{o?console.warn(a,o):console.warn(a)};if(l==="boolean"){const a=t.trim().toLowerCase();return a!==""&&a!=="true"&&a!=="false"&&a!=="1"&&a!=="0"?(s(`[${i}] Invalid value "${t}" for boolean attribute "${n}". Allowed: "true", "false", or presence-only.`),!1):!0}if(l==="enum"){const a=e.values||[];return a.includes(t)?!0:(s(`[${i}] Invalid value "${t}" for attribute "${n}". Allowed: ${a.join(", ")}. Fallback: "${e.fallback}".`),!1)}if(l==="integer"){if(!/^-?\d+$/.test(t))return s(`[${i}] Invalid integer "${t}" for attribute "${n}". Fallback: ${e.fallback}.`),!1;const a=parseInt(t,10);return e.min!==void 0&&a<e.min?(s(`[${i}] Value ${a} for attribute "${n}" is less than min (${e.min}).`),!1):e.max!==void 0&&a>e.max?(s(`[${i}] Value ${a} for attribute "${n}" is greater than max (${e.max}).`),!1):!0}if(l==="float")return isNaN(Number(t))?(s(`[${i}] Invalid float "${t}" for attribute "${n}". Fallback: ${e.fallback}.`),!1):!0;if(l==="json")try{return JSON.parse(t),!0}catch(a){return s(`[${i}] Invalid JSON for attribute "${n}": ${a.message}. Fallback: ${e.fallback}.`),!1}return!0}function Oe(e){const t={};for(const n in e){const r=e[n];r&&r.effect&&(t[n]=r.effect)}return Object.keys(t).length?t:null}function xe(e){if(e.onAttrChange&&!e.declared)return null;const t=new Set;if(e.effects)for(const n in e.effects)t.add(n);if(e.onAttrChange&&e.declared)for(const n of e.declared)t.add(n);return t}function R(e,t,n,r){if(e.nodeType!==1)return;const i=t.indexOf("[")!==-1||t.indexOf(".")!==-1||t.indexOf("#")!==-1?t:"["+t+"]",l=Array.from(e.querySelectorAll(i));e.matches&&e.matches(i)&&l.push(e);for(const s of l)if(!s[n]){window.lnCore._persistSink&&s.hasAttribute("data-ln-persist")&&window.lnCore._persistSink(s,t);try{s[n]=new r(s)}catch(a){console.error("["+n+"] init failed",s,a)}}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore._bootHolds=window.lnCore._bootHolds||0,window.lnCore._bootQueue=window.lnCore._bootQueue||[]);function Re(){return typeof window<"u"&&window.lnCore&&window.lnCore._bootHolds||0}function $e(e){typeof window<"u"?(window.lnCore=window.lnCore||{},window.lnCore._bootHolds=window.lnCore._bootHolds||0,window.lnCore._bootQueue=window.lnCore._bootQueue||[],window.lnCore._bootHolds>0?window.lnCore._bootQueue.push(e):setTimeout(e,0)):e()}function G(){window.lnCore=window.lnCore||{};const e=window.lnCore._attrRegistry=window.lnCore._attrRegistry||{byAttr:new Map,reactive:[],persist:[]};return e.byReactive=e.byReactive||new Map,e.reactiveWildcard=e.reactiveWildcard||[],e}function qe(e){const t=G(),n=e.observed||[];for(let r=0;r<n.length;r++){const o=n[r];t.byAttr.has(o)||t.byAttr.set(o,[]),t.byAttr.get(o).push(e)}if(t.byDeclaredAttr=t.byDeclaredAttr||new Map,e.attributes)for(const r in e.attributes){t.byDeclaredAttr.has(r)||t.byDeclaredAttr.set(r,[]);const o=t.byDeclaredAttr.get(r);o.some(i=>i.componentTag===e.componentTag)||o.push({spec:e.attributes[r],componentTag:e.componentTag})}if(e.onAttrChange||e.effects){t.reactive.push(e);const r=xe(e);if(r===null)t.reactiveWildcard.push(e);else for(const o of r)t.byReactive.has(o)||t.byReactive.set(o,[]),t.byReactive.get(o).push(e)}e.persist&&t.persist.push(e)}function J(e,t,n,r){for(let o=0;o<e.length;o++){const i=e[o];if(!t[i.attribute])continue;const l=i.effects&&i.effects[n];l?l(t,n,r):i.onAttrChange&&(!i.declared||i.declared.has(n))&&i.onAttrChange(t,n,r)}}function De(e){const t=e.target,n=e.attributeName;if(e.oldValue===t.getAttribute(n))return;const r=G(),o=r.byAttr.get(n);if(N()&&r.byDeclaredAttr&&r.byDeclaredAttr.has(n)&&E(t)){const i=r.byDeclaredAttr.get(n),l=t.getAttribute(n);for(let s=0;s<i.length;s++)z(i[s].spec,l,n,i[s].componentTag,t)}if(window.lnCore._debugSink&&(n.indexOf("data-ln-")===0||o)&&window.lnCore._debugSink("attr",n,t,{oldValue:e.oldValue,newValue:t.getAttribute(n)}),n.indexOf("data-ln-")===0){const i=r.byReactive.get(n);i&&J(i,t,n,e.oldValue),r.reactiveWildcard.length&&J(r.reactiveWildcard,t,n,e.oldValue)}if(o)for(let i=0;i<o.length;i++){const l=o[i];if(l.handler){l.handler(t,n,e.oldValue);continue}l.onAttributeChange&&t[l.attribute]?l.onAttributeChange(t,n):(R(t,l.selector,l.attribute,l.ComponentFn),l.onInit&&l.onInit(t))}}function Me(){window.lnCore=window.lnCore||{},!window.lnCore._attrObserverBound&&(window.lnCore._attrObserverBound=!0,y(function(){new MutationObserver(function(t){for(let n=0;n<t.length;n++)try{De(t[n])}catch(r){console.error("[ln-core] mutation handler failed",t[n].target,r)}}).observe(document.body,{attributes:!0,subtree:!0,attributeOldValue:!0})},"ln-core"))}function X(){return window.lnCore=window.lnCore||{},window.lnCore._lifecycleRegistry=window.lnCore._lifecycleRegistry||[]}function Ie(e){const t=X();if(t.length){if(e.target)for(let n=0;n<t.length;n++){const r=t[n];if(r.onSubtreeChange){const o=r.query,i=e.target.nodeType===1?e.target.matches(o)?e.target:e.target.closest(o):e.target.parentElement?e.target.parentElement.closest(o):null;i&&r.onSubtreeChange(i,e)}}for(let n=0;n<e.addedNodes.length;n++){const r=e.addedNodes[n];if(r.nodeType===1)for(let o=0;o<t.length;o++){const i=t[o];R(r,i.selector,i.attribute,i.ComponentFn),i.onInit&&i.onInit(r)}}for(let n=0;n<e.removedNodes.length;n++){const r=e.removedNodes[n];if(r.nodeType===1)for(let o=0;o<t.length;o++){const i=t[o],l=i.query,s=Array.from(r.querySelectorAll(l));r.matches&&r.matches(l)&&s.push(r);for(let a=0;a<s.length;a++){const u=s[a];if(!document.contains(u)){const d=u[i.attribute];if(d&&typeof d.destroy=="function")try{d.destroy()}catch(f){console.error("["+i.attribute+"] destroy failed",u,f)}delete u[i.attribute]}}}}}}function Te(){window.lnCore=window.lnCore||{},!window.lnCore._lifecycleObserverBound&&(window.lnCore._lifecycleObserverBound=!0,y(function(){new MutationObserver(function(t){for(let n=0;n<t.length;n++){const r=t[n];if(r.type==="childList")try{Ie(r)}catch(o){console.error("[ln-core] lifecycle handler failed",r.target,o)}}}).observe(document.body,{childList:!0,subtree:!0})},"ln-core"))}function Le(e,t,n,r,o={}){const i=o.extraAttributes||[],l=o.onAttributeChange||null,s=o.onSubtreeChange||null,a=o.onInit||null,u=o.onAttrChange||null,d=o.effects||null,f=o.attributes||null,g=f?Oe(f):d,S=f?new Set(Object.keys(f)):null,c=o.persist||null;function h(K){const b=K||document.body;if(R(b,e,t,n),f&&N())for(const A in f){const Ye=f[A],P=Array.from(b.querySelectorAll("["+A+"]"));b.matches&&b.matches("["+A+"]")&&P.push(b);for(let j=0;j<P.length;j++){const F=P[j];E(F)&&z(Ye,F.getAttribute(A),A,r,F)}}a&&a(b)}const w=[];if(e.indexOf("[")!==-1){const K=/\[([\w-]+)/g;let b;for(;(b=K.exec(e))!==null;)w.push(b[1])}else w.push(e);qe({selector:e,attribute:t,componentTag:r,attributes:f,ComponentFn:n,onInit:a,observed:w.concat(i),onAttributeChange:l,onAttrChange:u,effects:g,declared:S,persist:c}),Me();const Xe=e.indexOf("[")!==-1||e.indexOf(".")!==-1||e.indexOf("#")!==-1?e:"["+e+"]";X().push({selector:e,attribute:t,ComponentFn:n,onInit:a,onSubtreeChange:s,query:Xe}),Te(),window[t]=h;function pe(){Re()>0?$e(function(){h(document.body)}):h(document.body)}return document.readyState==="loading"?document.addEventListener("DOMContentLoaded",pe):pe(),h}function Y(e){return(e||"").replace(/^#/,"")}function $(e){const t=e===void 0?location.hash:e,n={},r=Y(t);if(!r)return n;const o=r.split("&");for(let i=0;i<o.length;i++){const l=o[i];if(!l)continue;const s=l.indexOf(":"),a=s>-1?l.slice(0,s):l,u=s>-1?l.slice(s+1):"";if(a)try{n[a]=decodeURIComponent(u)}catch{n[a]=u}}return n}function We(e){if(!e)return null;const t=$();return e in t?t[e]:null}function Be(e,t){if(!e)return;const n=$();t==null?delete n[e]:n[e]=String(t);const o=Object.keys(n).map(function(i){const l=n[i];return l===""?i:i+":"+encodeURIComponent(l)}).join("&");Y(location.hash)!==o&&(location.hash=o)}function Ke(e){return e.button===1||e.ctrlKey||e.metaKey||e.shiftKey?!1:(e.preventDefault(),!0)}function Pe(e,t){if(!e||!e.hasAttribute("data-ln-hash"))return null;const n=e.getAttribute("data-ln-hash");if(n&&n.trim()!=="")return n.trim();const r=e.getAttribute("data-ln-sort")||e.getAttribute("data-ln-search-for")||e.getAttribute("data-ln-search")||e.getAttribute("data-ln-filter")||e.id;return r?t?r+"-"+t:r:t||null}function je(e,t){return!t||t==="none"||e===null||e===void 0?null:String(e)+"."+t}function Fe(e){return!e||typeof e!="string"?null:e.endsWith(".asc")?{fieldOrColumn:e.slice(0,-4),direction:"asc"}:e.endsWith(".desc")?{fieldOrColumn:e.slice(0,-5),direction:"desc"}:null}function Ne(e,t){return!e||!Array.isArray(t)||t.length===0?null:e+":"+t.map(encodeURIComponent).join(",")}function He(e){if(!e||typeof e!="string")return null;const t=e.indexOf(":");if(t===-1)return null;const n=e.slice(0,t),r=e.slice(t+1),o=r?r.split(",").map(function(i){try{return decodeURIComponent(i)}catch{return i}}).filter(Boolean):[];return{key:n,values:o}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.hashParse=$,window.lnCore.hashGet=We,window.lnCore.hashSet=Be,window.lnCore.hashLinkClick=Ke,window.lnCore.resolveHashNamespace=Pe,window.lnCore.hashSortEncode=je,window.lnCore.hashSortDecode=Fe,window.lnCore.hashFilterEncode=Ne,window.lnCore.hashFilterDecode=He);function Ue(e,{isHydration:t=!1,hasPrimaryRegion:n=!1,primaryMatch:r=null}={}){const o=n?!r:!e.some(u=>u.match),i=[],l=[];for(const u of e)if(!(!u.targetEl&&!u.isPending)){if(!u.match){const d=t&&u.hasHydrate&&u.hasChildren;!u.hasKeep&&u.hasChildren&&!d&&u.targetEl&&i.push(u);continue}u.hasKeep&&u.mountedTemplate===u.match.route.templateNode||l.push(Object.assign({},u,{skipMount:t&&u.hasHydrate&&u.hasChildren}))}l.sort((u,d)=>u.regionKey==="__primary__"?-1:d.regionKey==="__primary__"?1:0);const a=l.find(u=>u.regionKey==="__primary__")||l[0]||null;return{notFound:o,clears:i,swaps:l,owner:a}}function m(e){if(!e||typeof e!="string")return"";let t=e.trim().replace(/\/+$/,"");return!t||t==="/"?"":t.startsWith("/")?t:"/"+t}function Ve(e,t){const n=m(t);if(!n)return e&&e.replace(/\/+$/,"")||"/";const r=(e||"/").replace(/\/+$/,"")||"/";return r===n?"/":r.startsWith(n+"/")?r.slice(n.length).replace(/\/+$/,"")||"/":r}function Z(e,t){const n=m(t);if(!n)return e||"/";const r=e||"/",o=r.indexOf("#"),i=o!==-1?r.slice(0,o):r,l=o!==-1?r.slice(o):"",s=i.indexOf("?"),a=s!==-1?i.slice(0,s):i,u=s!==-1?i.slice(s):"";let d;if(a===n)d=n+"/";else if(a.startsWith(n+"/"))d=a;else{const f=a.startsWith("/")?a:"/"+a;d=f==="/"?n+"/":n+f}return d+u+l}function q(){if(typeof document>"u")return"";const e=document.querySelector("[data-ln-outlet]")||document.querySelector("[data-ln-router-base]");if(e&&e.hasAttribute("data-ln-router-base"))return m(e.getAttribute("data-ln-router-base"));const t=document.querySelector("base[href]");if(t)try{const n=new URL(t.getAttribute("href"),window.location.origin);return m(n.pathname)}catch{return m(t.getAttribute("href"))}return""}const D={navigate:function(e){C(e,{historyAction:"push"})},replace:function(e){C(e,{historyAction:"replace"})},base:function(){return q()},toUrl:function(e){return Z(e,q())},current:function(){return v===null?null:{path:v,fullPath:re,base:oe,params:ie,query:le,route:se,regions:te}}},M="data-ln-route",ee="lnRoute";typeof window<"u"&&(window.lnRouter=D);function I(e){we(e),he(e),p.size>0&&fe()}const Qe={"data-ln-route":{effect:I,type:"string",description:"URL path pattern matched by this route template"},"data-ln-route-target":{effect:I,type:"string",description:"Target outlet element selector where route content is rendered"},"data-ln-route-title":{effect:I,type:"string",description:"Document title template set when route is activated"},"data-ln-route-keep":{type:"boolean",fallback:!1,description:"Preserve mounted DOM nodes in memory instead of rebuilding"},"data-ln-router-base":{type:"string",description:'Base URL prefix for subdirectory routing (e.g. "/spa")'},"data-ln-router-hydrate":{type:"boolean",fallback:!1,description:"Hydrate existing DOM content on initial router boot"}},p=new Map,T=new WeakMap;let te=new Map,ne=!1,v=null,re=null,oe="",ie={},le={},se=null,L=!1;function ae(e,t,n){L?queueMicrotask(function(){O(e,t,n)}):O(e,t,n)}function W(e){try{const s=new URL(e,window.location.origin);e=s.pathname+s.search+s.hash}catch{}let[t]=e.split("#"),[n,r]=t.split("?");const o={};if(r){const s=new URLSearchParams(r);for(const[a,u]of s.entries())o[a]=u}const i=q();return{path:Ve(n,i),query:o,base:i}}function ue(e,t){if(e.pattern==="*")return 1;if(t.pattern==="*")return-1;const n=e.segments,r=t.segments,o=Math.max(n.length,r.length);for(let i=0;i<o;i++){const l=n[i],s=r[i];if(l===void 0)return 1;if(s===void 0)return-1;if(l==="*")return 1;if(s==="*")return-1;const a=l.startsWith(":"),u=s.startsWith(":");if(a&&!u)return 1;if(!a&&u)return-1}return 0}function ce(e,t){const n=e.split("/").filter(Boolean);for(const r of t){if(r.pattern==="*")return{route:r,params:{wildcard:e}};const o=r.segments,i={};let l=!0;if(!(n.length>o.length&&o[o.length-1]!=="*")){for(let s=0;s<o.length;s++){const a=o[s],u=n[s];if(a==="*"){i.wildcard=n.slice(s).join("/");break}if(u===void 0){l=!1;break}if(a.startsWith(":"))i[a.slice(1)]=decodeURIComponent(u);else if(a!==u){l=!1;break}}if(l&&(o.indexOf("*")!==-1||n.length<=o.length))return{route:r,params:i}}}return null}function B(e,t={}){const n=t.warn!==!1;if(e!=="__primary__"){const o=document.getElementById(e);return!o&&n&&console.warn(`[ln-router] Explicit target element #${e} not found in DOM`),o}const r=document.querySelector("[data-ln-outlet]")||document.querySelector("main");return!r&&n&&console.warn("[ln-router] Default outlet (element with [data-ln-outlet] or <main>) not found in DOM"),r}function de(e){if(!e)return;const t=Array.from(e.querySelectorAll("*")),n=[e].concat(t);for(const o of n)for(const i of Object.keys(o))if(i.startsWith("ln")&&o[i]&&typeof o[i].destroy=="function")try{o[i].destroy()}catch(l){console.error(`[ln-router] Error destroying component ${i} on element:`,o,l)}const r=document.querySelectorAll('[data-ln-popover="open"]');for(const o of r){const i=o.lnPopover;if(i&&i.trigger&&e.contains(i.trigger))try{i.destroy()}catch(l){console.error("[ln-router] Error destroying open popover:",l)}}}function C(e,t={}){const{path:n,query:r,base:o}=W(e),i=Z(e,o),l=new Map;for(const[c,h]of p)l.set(c,ce(n,h.sorted));const s=l.get("__primary__")||null,a=B("__primary__",{warn:!!s}),u=p.has("__primary__"),d=[];for(const[c,h]of l){const w=c==="__primary__"?a:B(c,{warn:!1}),_=!w&&!!(s&&s.route&&s.route.templateNode&&s.route.templateNode.content&&s.route.templateNode.content.querySelector("#"+CSS.escape(c)));!w&&!_&&h&&console.warn(`[ln-router] Explicit target element #${c} not found in DOM`),d.push({regionKey:c,match:h,targetEl:w,isPending:_,hasKeep:!!w&&w.hasAttribute("data-ln-route-keep"),hasHydrate:!!w&&w.hasAttribute("data-ln-router-hydrate"),hasChildren:!!w&&w.children.length>0,mountedTemplate:w&&T.get(w)||null})}const f=Ue(d,{isHydration:!!t.isHydration,hasPrimaryRegion:u,primaryMatch:s});if(f.notFound){ae(document.body,"ln-router:not-found",{path:n});return}if(be(a||document.body,"ln-router:before-navigate",{from:v,to:i,path:n,params:s?s.params:{},query:r}).defaultPrevented)return;t.historyAction==="push"?window.history.pushState(null,"",i):t.historyAction==="replace"&&window.history.replaceState(null,"",i);const S=function(){for(const c of f.clears)de(c.targetEl),c.targetEl.replaceChildren(),T.delete(c.targetEl);for(const c of f.swaps){if((c.isPending||!c.targetEl||!document.contains(c.targetEl))&&(c.targetEl=c.regionKey==="__primary__"?a:document.getElementById(c.regionKey)),!c.targetEl){console.warn(`[ln-router] Target element #${c.regionKey} could not be resolved`);continue}if(c.skipMount||(de(c.targetEl),c.targetEl.replaceChildren(c.match.route.templateNode.content.cloneNode(!0))),T.set(c.targetEl,c.match.route.templateNode),f.owner&&c.regionKey===f.owner.regionKey){if(c.match.route.title){let h=c.match.route.title;if(c.match.params)for(const[w,_]of Object.entries(c.match.params))h=h.replace(new RegExp("\\{\\{\\s*"+w+"\\s*\\}\\}","g"),_);document.title=h}if(!t.isHydration){c.targetEl.hasAttribute("tabindex")||c.targetEl.setAttribute("tabindex","-1");const h=c.targetEl.querySelector("h1, h2, h3, h4, h5, h6");h?(h.setAttribute("tabindex","-1"),h.focus()):c.targetEl.focus(),c.regionKey==="__primary__"&&c.targetEl.scrollIntoView({block:"start",behavior:"instant"})}}ae(c.targetEl,"ln-router:navigated",{path:n,fullPath:i,base:o,params:c.match.params,query:r,route:c.match.route,target:c.targetEl,region:c.regionKey})}v=n,re=i,oe=o,le=r,se=s?s.route:null,ie=s?s.params:{},te=new Map(Array.from(l.entries()).map(([c,h])=>[c,h?{route:h.route,params:h.params}:null]))};document.startViewTransition&&!t.isHydration?document.startViewTransition(S):S()}function ze(e){const t=e.target.closest("a");if(!t||!ye(e,t))return;const n=t.getAttribute("href"),{path:r}=W(n);for(const o of p.values())if(ce(r,o.sorted)){e.preventDefault(),C(n,{historyAction:"push"});return}}function Ge(e,t){const n=Object.keys(e),r=Object.keys(t);if(n.length!==r.length)return!1;for(let o=0;o<n.length;o++){const i=n[o];if(e[i]!==t[i])return!1}return!0}function Je(){const e=window.location.pathname+window.location.search,t=D.current();if(t&&t.path!=null){const n=W(e);if(t.path===n.path&&Ge(t.query,n.query))return}C(e,{historyAction:"skip"})}function fe(){ne||(ne=!0,y(function(){document.addEventListener("click",ze),window.addEventListener("popstate",Je),L=!0;const e=window.location.pathname+window.location.search+window.location.hash;C(e,{historyAction:"replace",isHydration:!0}),L=!1},"ln-router"))}function he(e){const t=e.getAttribute(M);if(!t)return;const n=e.getAttribute("data-ln-route-target")||null;if(n==="__primary__"){console.warn(`[ln-router] "__primary__" is a reserved region key and cannot be used as data-ln-route-target. Route "${t}" rejected.`);return}const r=n||"__primary__";p.has(r)||p.set(r,{routes:new Map,sorted:[]});const o=p.get(r);if(o.routes.has(t)){console.warn(`[ln-router] Duplicate route pattern registered: "${t}" in region "${r}"`);return}const i=e.getAttribute("data-ln-route-title"),l=t.split("/").filter(Boolean),s={pattern:t,segments:l,target:n,title:i,templateNode:e},a=B(r);a&&a.contains(e)&&console.warn(`[ln-router] Route template with pattern "${t}" is declared inside its own outlet element:`,e),o.routes.set(t,s),o.sorted=Array.from(o.routes.values()).sort(ue)}function we(e){const t=e.getAttribute(M);if(!t)return;const r=e.getAttribute("data-ln-route-target")||null||"__primary__",o=p.get(r);o&&(o.routes.delete(t),o.sorted=Array.from(o.routes.values()).sort(ue),o.routes.size===0&&p.delete(r))}function ge(e){return this.dom=e,he(e),this}return ge.prototype.destroy=function(){we(this.dom),delete this.dom[ee]},Le(M,ee,ge,"ln-router",{attributes:Qe,onInit:function(){p.size>0&&fe()}}),k.router=D,Object.defineProperty(k,Symbol.toStringTag,{value:"Module"}),k})({});
@@ -55,6 +55,14 @@
55
55
  "type": "string",
56
56
  "description": "Document title template set when route is activated"
57
57
  },
58
+ "data-ln-router-base": {
59
+ "direction": "author",
60
+ "sources": [
61
+ "src/ln-router.js"
62
+ ],
63
+ "type": "string",
64
+ "description": "Base URL prefix for subdirectory routing (e.g. "
65
+ },
58
66
  "data-ln-router-hydrate": {
59
67
  "direction": "author",
60
68
  "sources": [
@@ -1,7 +1,25 @@
1
1
  import {
2
2
  registerComponent, dispatch, dispatchCancelable, guardBody, findElements, shouldInterceptLink
3
3
  } from '../../ln-core';
4
- import { planRegions } from './router-model.js';
4
+ import { planRegions, normalizeBase, stripBase, toAbsoluteUrl } from './router-model.js';
5
+
6
+ function _getBase() {
7
+ if (typeof document === 'undefined') return '';
8
+ const outlet = document.querySelector('[data-ln-outlet]') || document.querySelector('[data-ln-router-base]');
9
+ if (outlet && outlet.hasAttribute('data-ln-router-base')) {
10
+ return normalizeBase(outlet.getAttribute('data-ln-router-base'));
11
+ }
12
+ const baseEl = document.querySelector('base[href]');
13
+ if (baseEl) {
14
+ try {
15
+ const u = new URL(baseEl.getAttribute('href'), window.location.origin);
16
+ return normalizeBase(u.pathname);
17
+ } catch (e) {
18
+ return normalizeBase(baseEl.getAttribute('href'));
19
+ }
20
+ }
21
+ return '';
22
+ }
5
23
 
6
24
  // Singleton router implementation
7
25
  export const router = {
@@ -11,10 +29,18 @@ export const router = {
11
29
  replace: function (fullPath) {
12
30
  _navigate(fullPath, { historyAction: 'replace' });
13
31
  },
32
+ base: function () {
33
+ return _getBase();
34
+ },
35
+ toUrl: function (relPath) {
36
+ return toAbsoluteUrl(relPath, _getBase());
37
+ },
14
38
  current: function () {
15
39
  if (currentPath === null) return null;
16
40
  return {
17
41
  path: currentPath,
42
+ fullPath: currentFullPath,
43
+ base: currentBase,
18
44
  params: currentParams,
19
45
  query: currentQuery,
20
46
  route: currentRoute,
@@ -42,6 +68,7 @@ const ATTRIBUTES = {
42
68
  'data-ln-route-target': { effect: _reRegisterRoute, type: 'string', description: 'Target outlet element selector where route content is rendered' },
43
69
  'data-ln-route-title': { effect: _reRegisterRoute, type: 'string', description: 'Document title template set when route is activated' },
44
70
  'data-ln-route-keep': { type: 'boolean', fallback: false, description: 'Preserve mounted DOM nodes in memory instead of rebuilding' },
71
+ 'data-ln-router-base': { type: 'string', description: 'Base URL prefix for subdirectory routing (e.g. "/spa")' },
45
72
  'data-ln-router-hydrate': { type: 'boolean', fallback: false, description: 'Hydrate existing DOM content on initial router boot' }
46
73
  };
47
74
 
@@ -57,6 +84,8 @@ let currentRegions = new Map();
57
84
 
58
85
  let booted = false;
59
86
  let currentPath = null;
87
+ let currentFullPath = null;
88
+ let currentBase = '';
60
89
  let currentParams = {};
61
90
  let currentQuery = {};
62
91
  let currentRoute = null;
@@ -77,7 +106,7 @@ function _dispatchMaybeDeferred(target, name, detail) {
77
106
  }
78
107
 
79
108
  /**
80
- * Normalize path: collapse trailing slash, strip query/hash, parse query.
109
+ * Normalize path: collapse trailing slash, strip query/hash, parse query, strip base.
81
110
  */
82
111
  function _normalizePath(fullPath) {
83
112
  // Absolute same-origin URLs (route() helpers, anchor.href) → reduce to
@@ -90,7 +119,7 @@ function _normalizePath(fullPath) {
90
119
  } catch (e) { /* not a parseable URL — use fullPath as-is */ }
91
120
 
92
121
  let [pathAndQuery] = fullPath.split('#');
93
- let [path, queryString] = pathAndQuery.split('?');
122
+ let [rawPath, queryString] = pathAndQuery.split('?');
94
123
 
95
124
  const query = {};
96
125
  if (queryString) {
@@ -100,12 +129,10 @@ function _normalizePath(fullPath) {
100
129
  }
101
130
  }
102
131
 
103
- path = path.replace(/\/+$/, '');
104
- if (path === '') {
105
- path = '/';
106
- }
132
+ const base = _getBase();
133
+ const path = stripBase(rawPath, base);
107
134
 
108
- return { path, query };
135
+ return { path, query, base };
109
136
  }
110
137
 
111
138
  /**
@@ -261,7 +288,8 @@ function _teardownOutlet(target) {
261
288
  * swaps all regions that need it inside a single view transition.
262
289
  */
263
290
  function _navigate(fullPath, opts = {}) {
264
- const { path, query } = _normalizePath(fullPath);
291
+ const { path, query, base } = _normalizePath(fullPath);
292
+ const historyPath = toAbsoluteUrl(fullPath, base);
265
293
 
266
294
  // 1. Per-region match
267
295
  const regionMatches = new Map();
@@ -329,7 +357,8 @@ function _navigate(fullPath, opts = {}) {
329
357
  // one match, regardless of whether the primary is among them.
330
358
  const beforeEvent = dispatchCancelable(primaryTarget || document.body, 'ln-router:before-navigate', {
331
359
  from: currentPath,
332
- to: fullPath,
360
+ to: historyPath,
361
+ path: path,
333
362
  params: primaryMatch ? primaryMatch.params : {},
334
363
  query
335
364
  });
@@ -337,9 +366,9 @@ function _navigate(fullPath, opts = {}) {
337
366
 
338
367
  // 7. History update (once per navigation)
339
368
  if (opts.historyAction === 'push') {
340
- window.history.pushState(null, '', fullPath);
369
+ window.history.pushState(null, '', historyPath);
341
370
  } else if (opts.historyAction === 'replace') {
342
- window.history.replaceState(null, '', fullPath);
371
+ window.history.replaceState(null, '', historyPath);
343
372
  }
344
373
 
345
374
  // 8. Atomic swap — one view transition wraps every region clear/mount.
@@ -395,7 +424,9 @@ function _navigate(fullPath, opts = {}) {
395
424
  }
396
425
 
397
426
  _dispatchMaybeDeferred(d.targetEl, 'ln-router:navigated', {
398
- path: fullPath,
427
+ path: path,
428
+ fullPath: historyPath,
429
+ base: base,
399
430
  params: d.match.params,
400
431
  query,
401
432
  route: d.match.route,
@@ -406,10 +437,12 @@ function _navigate(fullPath, opts = {}) {
406
437
 
407
438
  // State is read off the primary match — currentRoute is null on an
408
439
  // aux-only navigation, which is what current() === null now hinges on.
409
- currentPath = fullPath;
410
- currentQuery = query;
411
- currentRoute = primaryMatch ? primaryMatch.route : null;
412
- currentParams = primaryMatch ? primaryMatch.params : {};
440
+ currentPath = path;
441
+ currentFullPath = historyPath;
442
+ currentBase = base;
443
+ currentQuery = query;
444
+ currentRoute = primaryMatch ? primaryMatch.route : null;
445
+ currentParams = primaryMatch ? primaryMatch.params : {};
413
446
 
414
447
  // currentRegions reflects every region's match (null when unmatched).
415
448
  // Built from regionMatches — never from the loop variable `match`.
@@ -455,20 +488,10 @@ function _queryEqual(a, b) {
455
488
 
456
489
  function _onPopState() {
457
490
  const fullPath = window.location.pathname + window.location.search;
458
- // Fragment-only popstate guard: when Back/Forward changes ONLY the hash
459
- // (path + query identical to the current SPA state), skip navigation so the
460
- // primary outlet is not torn down and re-cloned. Hash-bound components
461
- // (e.g. ln-modal) react to the accompanying hashchange independently.
462
- //
463
- // cur.query is the authoritative already-parsed query for the active route
464
- // (currentQuery), so compare target.query against it directly. cur.path is
465
- // the raw fullPath (retains the query string), so normalize it for the
466
- // pathname comparison only — do NOT re-parse it for the query.
467
491
  const cur = router.current();
468
492
  if (cur && cur.path != null) {
469
493
  const target = _normalizePath(fullPath);
470
- const currentPathNorm = _normalizePath(cur.path).path;
471
- if (currentPathNorm === target.path && _queryEqual(cur.query, target.query)) {
494
+ if (cur.path === target.path && _queryEqual(cur.query, target.query)) {
472
495
  return;
473
496
  }
474
497
  }
@@ -48,3 +48,88 @@ export function planRegions(descriptors, { isHydration = false, hasPrimaryRegion
48
48
 
49
49
  return { notFound, clears, swaps, owner };
50
50
  }
51
+
52
+ /**
53
+ * Normalizes a base URL string:
54
+ * - ensures leading slash
55
+ * - strips trailing slash
56
+ * - returns empty string if root '/' or empty
57
+ * e.g. '/spa/' -> '/spa', 'spa' -> '/spa', '/' -> '', '' -> ''
58
+ *
59
+ * @param {string|null|undefined} base
60
+ * @returns {string}
61
+ */
62
+ export function normalizeBase(base) {
63
+ if (!base || typeof base !== 'string') return '';
64
+ let b = base.trim().replace(/\/+$/, '');
65
+ if (!b || b === '/') return '';
66
+ return b.startsWith('/') ? b : '/' + b;
67
+ }
68
+
69
+ /**
70
+ * Strips the base URL prefix from a pathname, returning the clean relative path.
71
+ * e.g. with base '/spa':
72
+ * '/spa/packages' -> '/packages'
73
+ * '/spa' -> '/'
74
+ * '/spa/' -> '/'
75
+ * '/packages' -> '/packages' (already relative)
76
+ * '/' -> '/'
77
+ *
78
+ * @param {string} path
79
+ * @param {string} [base]
80
+ * @returns {string}
81
+ */
82
+ export function stripBase(path, base) {
83
+ const b = normalizeBase(base);
84
+ if (!b) return (path && path.replace(/\/+$/, '')) || '/';
85
+
86
+ const normalizedPath = (path || '/').replace(/\/+$/, '') || '/';
87
+
88
+ if (normalizedPath === b) {
89
+ return '/';
90
+ }
91
+ if (normalizedPath.startsWith(b + '/')) {
92
+ const rel = normalizedPath.slice(b.length);
93
+ return rel.replace(/\/+$/, '') || '/';
94
+ }
95
+ return normalizedPath;
96
+ }
97
+
98
+ /**
99
+ * Converts a relative path into an absolute path prefixed with base.
100
+ * Preserves query strings and hashes.
101
+ * e.g. with base '/spa':
102
+ * '/packages' -> '/spa/packages'
103
+ * '/' -> '/spa/'
104
+ * 'packages' -> '/spa/packages'
105
+ * '/spa/packages' -> '/spa/packages' (already prefixed)
106
+ *
107
+ * @param {string} relPath
108
+ * @param {string} [base]
109
+ * @returns {string}
110
+ */
111
+ export function toAbsoluteUrl(relPath, base) {
112
+ const b = normalizeBase(base);
113
+ if (!b) return relPath || '/';
114
+
115
+ const str = relPath || '/';
116
+ const hashIdx = str.indexOf('#');
117
+ const pathAndQuery = hashIdx !== -1 ? str.slice(0, hashIdx) : str;
118
+ const hash = hashIdx !== -1 ? str.slice(hashIdx) : '';
119
+
120
+ const queryIdx = pathAndQuery.indexOf('?');
121
+ const pathname = queryIdx !== -1 ? pathAndQuery.slice(0, queryIdx) : pathAndQuery;
122
+ const queryString = queryIdx !== -1 ? pathAndQuery.slice(queryIdx) : '';
123
+
124
+ let absPath;
125
+ if (pathname === b) {
126
+ absPath = b + '/';
127
+ } else if (pathname.startsWith(b + '/')) {
128
+ absPath = pathname;
129
+ } else {
130
+ const cleanRel = pathname.startsWith('/') ? pathname : '/' + pathname;
131
+ absPath = cleanRel === '/' ? b + '/' : b + cleanRel;
132
+ }
133
+
134
+ return absPath + queryString + hash;
135
+ }