@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.
- package/components/ln-confirm/README.md +2 -2
- package/components/ln-confirm/ln-confirm.js +1 -1
- package/components/ln-confirm/src/ln-confirm.js +1 -3
- package/components/ln-core/attrs.js +273 -273
- package/components/ln-core/events.js +122 -122
- package/components/ln-core/lifecycle.js +403 -403
- package/components/ln-debug/ln-debug.js +1 -1
- package/components/ln-debug/src/generated-attributes.js +1 -0
- package/components/ln-router/README.md +33 -0
- package/components/ln-router/ln-router.js +1 -1
- package/components/ln-router/ln-router.schema.json +8 -0
- package/components/ln-router/src/ln-router.js +51 -28
- package/components/ln-router/src/router-model.js +85 -0
- package/ln-ashlar.html-data.json +4 -0
- package/package.json +1 -1
- package/web-types.json +7 -0
|
@@ -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})({});
|
|
@@ -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 [
|
|
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
|
-
|
|
104
|
-
|
|
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:
|
|
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, '',
|
|
369
|
+
window.history.pushState(null, '', historyPath);
|
|
341
370
|
} else if (opts.historyAction === 'replace') {
|
|
342
|
-
window.history.replaceState(null, '',
|
|
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:
|
|
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
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
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
|
-
|
|
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
|
+
}
|