@livenetworks/ashlar 2.1.9 → 2.1.11
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/COMPONENTS.md +1 -1
- package/components/ln-data-store/README.md +19 -0
- package/components/ln-data-store/ln-data-store.js +1 -1
- package/components/ln-data-store/ln-data-store.schema.json +92 -84
- package/components/ln-data-store/src/data-store-model.js +17 -0
- package/components/ln-data-store/src/ln-data-store.js +77 -1
- package/components/ln-debug/ln-debug.js +1 -1
- package/components/ln-debug/src/generated-attributes.js +2 -3
- package/components/ln-table/README.md +90 -41
- package/components/ln-table/ln-table.js +1 -1
- package/components/ln-table/ln-table.schema.json +19 -35
- package/components/ln-table/src/ln-table.js +370 -411
- package/components/ln-table/src/table-model.js +31 -0
- package/ln-ashlar.html-data.json +10 -15
- package/package.json +1 -1
- package/theme/components/_ln-table.scss +9 -0
- package/theme/config/mixins/_ln-table.scss +18 -10
- package/theme/config/mixins/_table.scss +15 -2
- package/web-types.json +19 -26
package/components/COMPONENTS.md
CHANGED
|
@@ -1000,7 +1000,7 @@ The component calls `_ensureDefaultItemTemplate()` at the top of `_initUpload()`
|
|
|
1000
1000
|
| ln-search | Instance | `data-ln-search` | Generic search (textContent filter) |
|
|
1001
1001
|
| ln-filter | Instance | `data-ln-filter` | Generic filter (data attribute filter) |
|
|
1002
1002
|
| ln-sort | Instance | `data-ln-sort` | Sort control primitive — 3-trigger cycle (none→asc→desc→none), search-precedent cancelable event; targets ln-table, ln-list, or plain lists |
|
|
1003
|
-
| ln-table | Instance | `data-ln-table` | Data table (search, filter, sort,
|
|
1003
|
+
| ln-table | Instance | `data-ln-table` | Data table (search, filter, sort, and viewport row virtualization) |
|
|
1004
1004
|
| ln-chart | Instance | `data-ln-chart` | SVG line/area dataset renderer with `ln-data-coordinator` binding |
|
|
1005
1005
|
| ln-sortable | Instance | `data-ln-sortable` | Drag & drop reorder |
|
|
1006
1006
|
| ln-picklist | Instance | `data-ln-picklist` | Two-list checkbox selection |
|
|
@@ -19,6 +19,24 @@
|
|
|
19
19
|
</ul>
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
+
### ⚡ Server-Rendered (SSR) Instant Seed
|
|
23
|
+
Embed authoritative server data directly in a `<script type="application/json">` child (or point to it via `data-ln-data-store-seed="#my-seed"`). The store parses the array on initialization and serves reads with zero network latency:
|
|
24
|
+
|
|
25
|
+
```html
|
|
26
|
+
<ul id="tenants"
|
|
27
|
+
data-ln-data-store
|
|
28
|
+
data-ln-data-store-indexes="status,package_id"
|
|
29
|
+
data-ln-data-store-search-fields="name,slug"
|
|
30
|
+
hidden>
|
|
31
|
+
<script type="application/json">
|
|
32
|
+
[
|
|
33
|
+
{"id": 1, "name": "Acme Corp", "slug": "acme", "status": "active"},
|
|
34
|
+
{"id": 2, "name": "Globex", "slug": "globex", "status": "pending"}
|
|
35
|
+
]
|
|
36
|
+
</script>
|
|
37
|
+
</ul>
|
|
38
|
+
```
|
|
39
|
+
|
|
22
40
|
---
|
|
23
41
|
|
|
24
42
|
## 🌐 Declarative Attributes
|
|
@@ -27,6 +45,7 @@
|
|
|
27
45
|
|---|---|---|
|
|
28
46
|
| `id="name"` | Unique identifier of the store (the store name). | *Required* |
|
|
29
47
|
| `data-ln-data-store` | Marker attribute to declare the component. | *Required* |
|
|
48
|
+
| `data-ln-data-store-seed="…"` | Selector or element ID of an external seed script block containing an initial JSON records array. | *Optional* |
|
|
30
49
|
| `data-ln-data-store-stale="N"` | Seconds before cache is considered stale. Set to `never` or `-1` to disable staleness. | `300` |
|
|
31
50
|
| `data-ln-data-store-indexes="…"` | Comma-separated list of IndexedDB index fields. | `""` |
|
|
32
51
|
| `data-ln-data-store-search-fields="…"` | Comma-separated list of text-search fields for local query search matching. | `""` |
|
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(){"use strict";function pe(){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 oe(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 i=null;for(let a=1;a<t.length;a++)if(t[a]&&t[a].nodeType===1){i=t[a];break}if(!oe(i))return}e.apply(console,t)}}function A(e,t,r){const i=r||{};window.lnCore._debugSink&&window.lnCore._debugSink("event",t,e,i),e.dispatchEvent(new CustomEvent(t,{bubbles:!0,detail:i}))}function Z(e,t){if(!document.body){document.addEventListener("DOMContentLoaded",function(){Z(e,t)}),console.warn("["+t+'] Script loaded before <body> — add "defer" to your <script> tag');return}e()}function Ue(e){const t=e.querySelector('input[name="_method"]');return((t&&t.value!==""?t.value:e.method)||"").toUpperCase()}function Ge(e,t){const r=!!(t&&t.typed),i=t&&t.exclude,a={},l=e.elements,c={};if(r)for(let d=0;d<l.length;d++){const s=l[d];s.name&&s.type==="checkbox"&&!s.disabled&&(c[s.name]=(c[s.name]||0)+1)}for(let d=0;d<l.length;d++){const s=l[d];if(!(!s.name||s.disabled||s.type==="file"||s.type==="submit"||s.type==="button")&&!(i&&s.matches&&s.matches(i)))if(s.type==="checkbox")r&&c[s.name]===1?a[s.name]=s.checked:(a[s.name]||(a[s.name]=[]),s.checked&&a[s.name].push(s.value));else if(s.type==="radio")s.checked&&(a[s.name]=s.value);else if(s.type==="select-multiple"){a[s.name]=[];for(let w=0;w<s.options.length;w++)s.options[w].selected&&a[s.name].push(s.options[w].value)}else if(r&&s.type==="hidden")a[s.name]=s.value;else if(r&&(s.type==="number"||s.type==="range")){const w=Number(s.value);a[s.name]=s.value===""||isNaN(w)?null:w}else a[s.name]=s.value}return a}function Ve(e){if(typeof e!="string")return!!e;const t=e.trim().toLowerCase();return t!=="false"&&t!=="0"&&t!==""&&t!=="off"&&t!=="no"}function We(e,t){const r=e.elements,i=[],a={};for(let l=0;l<r.length;l++){const c=r[l];c.name&&c.type==="checkbox"&&(a[c.name]=(a[c.name]||0)+1)}for(let l=0;l<r.length;l++){const c=r[l];if(c.type==="file"||c.type==="submit"||c.type==="button")continue;const d=c.getAttribute("data-ln-fill-as")||c.name;if(!d||!(d in t))continue;const s=t[d];if(c.type==="checkbox"){if(Array.isArray(s))c.checked=s.indexOf(c.value)!==-1;else if(a[c.name]>1){const w=String(s).split(",").map(function(b){return b.trim()});c.checked=w.indexOf(c.value)!==-1}else c.checked=Ve(s);i.push(c)}else if(c.type==="radio")c.checked=c.value===String(s),i.push(c);else if(c.type==="select-multiple"){if(Array.isArray(s))for(let w=0;w<c.options.length;w++)c.options[w].selected=s.indexOf(c.options[w].value)!==-1;i.push(c)}else c.value=s,c.tagName==="SELECT"&&s!=null&&c.setAttribute("data-ln-value",s),i.push(c)}return i}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.populateForm=We,window.lnCore.serializeForm=Ge,window.lnCore.resolveFormMethod=Ue);const ge={};function He(e,t){ge[e]=t}function Qe(e){return ge[e]||{ingress:t=>t,egress:t=>t}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerDataMapper=He,window.lnCore.getDataMapper=Qe);function Je(){typeof window>"u"||(window.lnCore=window.lnCore||{},!window.lnCore._localeObserverBound&&(window.lnCore._localeObserverBound=!0,Z(function(){new MutationObserver(function(){A(document,"ln-core:locale-change",{})}).observe(document.documentElement,{attributes:!0,attributeFilter:["lang"],subtree:!0})},"ln-core")))}const me={};function Ze(e,t){if(!e||typeof t!="object")return;const r=e.toLowerCase().split("-")[0];me[r]=t}function Xe(e){if(!e)return null;const t=e.toLowerCase().split("-")[0];return me[t]||null}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerLocaleFallback=Ze,window.lnCore.getLocaleFallback=Xe,window.lnCore.ensureLocaleObserver=Je);const ie={};function Ye(e,t){ie[e]||(ie[e]=document.querySelector('[data-ln-template="'+e+'"]'));const r=ie[e];return r?r.content.cloneNode(!0):(console.warn("["+(t||"ln-core")+'] Template "'+e+'" not found'),null)}function be(e,t){if(!e||!t)return e;const r=e.querySelectorAll("[data-ln-field]");for(let c=0;c<r.length;c++){const d=r[c],s=d.getAttribute("data-ln-field");t[s]!=null&&(d.textContent=t[s])}const i=e.querySelectorAll("[data-ln-attr]");for(let c=0;c<i.length;c++){const d=i[c],s=d.getAttribute("data-ln-attr").split(",");for(let w=0;w<s.length;w++){const b=s[w].trim().split(":");if(b.length!==2)continue;const _=b[0].trim(),x=b[1].trim();t[x]!=null&&d.setAttribute(_,t[x])}}const a=e.querySelectorAll("[data-ln-show]");for(let c=0;c<a.length;c++){const d=a[c],s=d.getAttribute("data-ln-show");s in t&&d.classList.toggle("hidden",!t[s])}const l=e.querySelectorAll("[data-ln-class]");for(let c=0;c<l.length;c++){const d=l[c],s=d.getAttribute("data-ln-class").split(",");for(let w=0;w<s.length;w++){const b=s[w].trim().split(":");if(b.length!==2)continue;const _=b[0].trim(),x=b[1].trim();x in t&&d.classList.toggle(_,!!t[x])}}return e}function et(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 r=e.querySelectorAll("[data-ln-form], [data-ln-fillable]");for(let i=0;i<r.length;i++)window.lnCore._debugSink&&window.lnCore._debugSink("event","ln-fill",r[i],t??null),r[i].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)be(e.target,e.detail);else{const t=e.target.querySelectorAll("[data-ln-field]");for(let r=0;r<t.length;r++)t[r].textContent=""}})));function _e(e,t){if(!e||!t)return e;const r=document.createTreeWalker(e,NodeFilter.SHOW_TEXT);for(;r.nextNode();){const l=r.currentNode;l.textContent.indexOf("{{")!==-1&&(l.textContent=l.textContent.replace(/\{\{\s*(\w+)\s*\}\}/g,function(c,d){return t[d]!==void 0?t[d]:""}))}const i=function(l,c){return t[c]!==void 0?t[c]:""},a=Array.from(e.querySelectorAll("*"));e.nodeType===1&&a.push(e);for(let l=0;l<a.length;l++){const c=a[l],d=c.attributes;for(let s=0;s<d.length;s++){const w=d[s];w.value.indexOf("{{")!==-1&&c.setAttribute(w.name,w.value.replace(/\{\{\s*(\w+)\s*\}\}/g,i))}}return e}function tt(e,t,r,i,a,l){const c={};for(let s=0;s<e.children.length;s++){const w=e.children[s],b=w.getAttribute("data-ln-render-key");b&&(c[b]=w)}const d=document.createDocumentFragment();for(let s=0;s<t.length;s++){const w=t[s],b=String(i(w));let _=c[b];if(_)a(_,w,s);else{const x=Ye(r,l);if(!x||(_e(x,w),_=x.firstElementChild,!_))continue;_.setAttribute("data-ln-render-key",b),a(_,w,s)}d.appendChild(_)}e.textContent="",e.appendChild(d)}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.fillTemplate=_e,window.lnCore.fill=be,window.lnCore.lnFill=et,window.lnCore.renderList=tt);function ae(e,t,r){const i=e.getAttribute(t);return i===null?r:i}function X(e,t,r){const i=parseInt(e.getAttribute(t),10);return isNaN(i)?r:i}function se(e,t,r=!1){const i=e.getAttribute(t);if(i===null)return!!r;const a=i.trim().toLowerCase();return!(a==="false"||a==="0")}function le(e,t){return(e.getAttribute(t)||"").split(",").map(r=>r.trim()).filter(Boolean)}const ce=new Map;function Ce(e,t){const r=(e?e.join("|"):"")+"::"+t;if(ce.has(r))return ce.get(r);const i=new Set(e||[]),a=function(l,c){const d=l.getAttribute(c);return d!==null&&i.has(d)?d:t};return ce.set(r,a),a}function Se(e,t,r){const i=parseFloat(e.getAttribute(t));return isNaN(i)?r:i}function Ae(e,t,r){const i=e.getAttribute(t);if(!i)return r;try{return JSON.parse(i)}catch{return r}}function ve(e,t,r,i,a){if(!e||t===null)return!0;const l=i||"ln-component",c=e.type;if(c==="trigger"||c==="marker"||c==="string"||c==="list"||!c||t===""&&e.fallback!==void 0)return!0;const d=s=>{a?console.warn(s,a):console.warn(s)};if(c==="boolean"){const s=t.trim().toLowerCase();return s!==""&&s!=="true"&&s!=="false"&&s!=="1"&&s!=="0"?(d(`[${l}] Invalid value "${t}" for boolean attribute "${r}". Allowed: "true", "false", or presence-only.`),!1):!0}if(c==="enum"){const s=e.values||[];return s.includes(t)?!0:(d(`[${l}] Invalid value "${t}" for attribute "${r}". Allowed: ${s.join(", ")}. Fallback: "${e.fallback}".`),!1)}if(c==="integer"){if(!/^-?\d+$/.test(t))return d(`[${l}] Invalid integer "${t}" for attribute "${r}". Fallback: ${e.fallback}.`),!1;const s=parseInt(t,10);return e.min!==void 0&&s<e.min?(d(`[${l}] Value ${s} for attribute "${r}" is less than min (${e.min}).`),!1):e.max!==void 0&&s>e.max?(d(`[${l}] Value ${s} for attribute "${r}" is greater than max (${e.max}).`),!1):!0}if(c==="float")return isNaN(Number(t))?(d(`[${l}] Invalid float "${t}" for attribute "${r}". Fallback: ${e.fallback}.`),!1):!0;if(c==="json")try{return JSON.parse(t),!0}catch(s){return d(`[${l}] Invalid JSON for attribute "${r}": ${s.message}. Fallback: ${e.fallback}.`),!1}return!0}function xe(e,t,r){for(const i in r){const[a,l,c]=r[i];Object.defineProperty(e,i,{get:function(){return a(t,l,c)},enumerable:!0,configurable:!0})}return e}function ke(e){const t={};for(const r in e){const i=e[r];if(!i||!i.prop)continue;let a=i.read;if(!a&&i.type)switch(i.type){case"enum":a=Ce(i.values,i.fallback);break;case"integer":a=X;break;case"float":a=Se;break;case"boolean":a=se;break;case"list":a=le;break;case"json":a=Ae;break;case"string":default:a=ae;break}a||(a=ae),t[i.prop]=[a,r,i.fallback]}return t}function nt(e){const t={};for(const r in e){const i=e[r];i&&i.effect&&(t[r]=i.effect)}return Object.keys(t).length?t:null}function rt(e){if(e.onAttrChange&&!e.declared)return null;const t=new Set;if(e.effects)for(const r in e.effects)t.add(r);if(e.onAttrChange&&e.declared)for(const r of e.declared)t.add(r);return t}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.defineAttrs=xe,window.lnCore.attrSpec=ke,window.lnCore.attrStr=ae,window.lnCore.attrInt=X,window.lnCore.attrBool=se,window.lnCore.attrList=le,window.lnCore.attrEnum=Ce,window.lnCore.attrFloat=Se,window.lnCore.attrJson=Ae);function V(e,t){if(!e[t.attribute]){window.lnCore._persistSink&&e.hasAttribute&&e.hasAttribute("data-ln-persist")&&window.lnCore._persistSink(e,t.selector);try{e[t.attribute]=new t.ComponentFn(e)}catch(r){console.error("["+t.attribute+"] init failed",e,r)}}}function qe(e,t,r,i){if(e.nodeType!==1)return;const l=t.indexOf("[")!==-1||t.indexOf(".")!==-1||t.indexOf("#")!==-1?t:"["+t+"]",c={selector:t,attribute:r,ComponentFn:i};if(e.matches&&e.matches(l)&&V(e,c),e.querySelectorAll){const d=e.querySelectorAll(l);for(let s=0;s<d.length;s++)V(d[s],c)}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore._bootHolds=window.lnCore._bootHolds||0,window.lnCore._bootQueue=window.lnCore._bootQueue||[]);function ot(){return typeof window<"u"&&window.lnCore&&window.lnCore._bootHolds||0}function it(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 Ee(){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 at(e){const t=Ee(),r=e.observed||[];for(let i=0;i<r.length;i++){const a=r[i];t.byAttr.has(a)||t.byAttr.set(a,[]),t.byAttr.get(a).push(e)}if(t.byDeclaredAttr=t.byDeclaredAttr||new Map,e.attributes)for(const i in e.attributes){t.byDeclaredAttr.has(i)||t.byDeclaredAttr.set(i,[]);const a=t.byDeclaredAttr.get(i);a.some(l=>l.componentTag===e.componentTag)||a.push({spec:e.attributes[i],componentTag:e.componentTag})}if(e.onAttrChange||e.effects){t.reactive.push(e);const i=rt(e);if(i===null)t.reactiveWildcard.push(e);else for(const a of i)t.byReactive.has(a)||t.byReactive.set(a,[]),t.byReactive.get(a).push(e)}e.persist&&t.persist.push(e)}function Ie(e,t,r,i){for(let a=0;a<e.length;a++){const l=e[a];if(!t[l.attribute])continue;const c=l.effects&&l.effects[r];c?c(t,r,i):l.onAttrChange&&(!l.declared||l.declared.has(r))&&l.onAttrChange(t,r,i)}}function st(e){const t=e.attributeName,r=t.indexOf("data-ln-")===0,i=Ee(),a=i.byAttr.get(t),l=pe()&&i.byDeclaredAttr&&i.byDeclaredAttr.has(t);if(!r&&!a&&!l)return;const c=e.target;if(e.oldValue!==c.getAttribute(t)){if(l&&oe(c)){const d=i.byDeclaredAttr.get(t),s=c.getAttribute(t);for(let w=0;w<d.length;w++)ve(d[w].spec,s,t,d[w].componentTag,c)}if(window.lnCore._debugSink&&(r||a)&&window.lnCore._debugSink("attr",t,c,{oldValue:e.oldValue,newValue:c.getAttribute(t)}),r){const d=i.byReactive.get(t);d&&Ie(d,c,t,e.oldValue),i.reactiveWildcard.length&&Ie(i.reactiveWildcard,c,t,e.oldValue)}if(a)for(let d=0;d<a.length;d++){const s=a[d];if(s.handler){s.handler(c,t,e.oldValue);continue}s.onAttributeChange&&c[s.attribute]?s.onAttributeChange(c,t):(qe(c,s.selector,s.attribute,s.ComponentFn),s.onInit&&s.onInit(c))}}}function lt(){window.lnCore=window.lnCore||{},!window.lnCore._attrObserverBound&&(window.lnCore._attrObserverBound=!0,Z(function(){new MutationObserver(function(t){for(let r=0;r<t.length;r++)try{st(t[r])}catch(i){console.error("[ln-core] mutation handler failed",t[r].target,i)}}).observe(document.body,{attributes:!0,subtree:!0,attributeOldValue:!0})},"ln-core"))}function ue(){return window.lnCore=window.lnCore||{},window.lnCore._lifecycleRegistry=window.lnCore._lifecycleRegistry||[]}function de(){return window.lnCore=window.lnCore||{},window.lnCore._subtreeRegistry=window.lnCore._subtreeRegistry||[]}function fe(e,t){if(!document.contains(e))if(t.attribute){const r=e[t.attribute];if(r&&typeof r.destroy=="function")try{r.destroy()}catch(i){console.error("["+t.attribute+"] destroy failed",e,i)}delete e[t.attribute]}else t.onDestroy&&t.onDestroy(e)}function Le(e){const t=ue();if(!t.length)return;const r=e.target;if(r){const a=r.nodeType===1?r:r.parentElement;if(a&&(a.isContentEditable||a.closest&&a.closest('[contenteditable]:not([contenteditable="false"])')))return}const i=de();if(e.target&&i.length)for(let a=0;a<i.length;a++){const l=i[a],c=l.query,d=e.target.nodeType===1?e.target.matches&&e.target.matches(c)?e.target:e.target.closest?e.target.closest(c):null:e.target.parentElement&&e.target.parentElement.closest?e.target.parentElement.closest(c):null;d&&l.onSubtreeChange(d,e)}for(let a=0;a<e.addedNodes.length;a++){const l=e.addedNodes[a];if(l.nodeType===1){const c=!!(l.firstElementChild||l.children&&l.children.length);for(let d=0;d<t.length;d++){const s=t[d];if(s.selector&&s.attribute&&s.ComponentFn){if(!c)l.matches&&l.matches(s.query)&&V(l,s);else if(l.matches&&l.matches(s.query)&&V(l,s),l.querySelectorAll){const w=l.querySelectorAll(s.query);for(let b=0;b<w.length;b++)V(w[b],s)}}s.onInit&&s.onInit(l)}}}for(let a=0;a<e.removedNodes.length;a++){const l=e.removedNodes[a];if(l.nodeType===1){if(document.contains(l))continue;const c=!!(l.firstElementChild||l.children&&l.children.length);for(let d=0;d<t.length;d++){const s=t[d],w=s.query;if(w){if(!c)l.matches&&l.matches(w)&&fe(l,s);else if(l.matches&&l.matches(w)&&fe(l,s),l.querySelectorAll){const b=l.querySelectorAll(w);for(let _=0;_<b.length;_++)fe(b[_],s)}}}}}}function De(){window.lnCore=window.lnCore||{},!window.lnCore._lifecycleObserverBound&&(window.lnCore._lifecycleObserverBound=!0,Z(function(){const e=new MutationObserver(function(t){for(let r=0;r<t.length;r++){const i=t[r];if(i.type==="childList")try{Le(i)}catch(a){console.error("[ln-core] lifecycle handler failed",i.target,a)}}});window.lnCore._lifecycleObserver=e,e.observe(document.body,{childList:!0,subtree:!0})},"ln-core"))}function ct(e){if(typeof window>"u")return e();window.lnCore=window.lnCore||{};const t=window.lnCore._lifecycleObserver;if(!t)return e();const r=t.takeRecords();for(let i=0;i<r.length;i++){const a=r[i];if(a.type==="childList")try{Le(a)}catch(l){console.error("[ln-core] lifecycle handler failed",a.target,l)}}t.disconnect();try{return e()}finally{t.observe(document.body,{childList:!0,subtree:!0})}}function ut(e){ue().push(e),e.onSubtreeChange&&e.query&&de().push(e),De()}function Ne(e,t,r,i,a={}){const l=a.extraAttributes||[],c=a.onAttributeChange||null,d=a.onSubtreeChange||null,s=a.onInit||null,w=a.onAttrChange||null,b=a.effects||null,_=a.attributes||null,x=_?nt(_):b,j=_?new Set(Object.keys(_)):null,$=a.persist||null;function g(L){const D=L||document.body;if(qe(D,e,t,r),_&&pe())for(const M in _){const we=_[M],U=Array.from(D.querySelectorAll("["+M+"]"));D.matches&&D.matches("["+M+"]")&&U.push(D);for(let P=0;P<U.length;P++){const H=U[P];oe(H)&&ve(we,H.getAttribute(M),M,i,H)}}s&&s(D)}const S=[];if(e.indexOf("[")!==-1){const L=/\[([\w-]+)/g;let D;for(;(D=L.exec(e))!==null;)S.push(D[1])}else S.push(e);at({selector:e,attribute:t,componentTag:i,attributes:_,ComponentFn:r,onInit:s,observed:S.concat(l),onAttributeChange:c,onAttrChange:w,effects:x,declared:j,persist:$}),lt();const I=e.indexOf("[")!==-1||e.indexOf(".")!==-1||e.indexOf("#")!==-1,k=a.subtreeQuery||(I?e:"["+e+"]"),v={selector:e,attribute:t,ComponentFn:r,onInit:s,onSubtreeChange:d,query:k};ue().push(v),d&&k&&de().push(v),De(),window[t]=g,typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerComponent=Ne,window.lnCore.observeLifecycle=ut,window.lnCore.withoutLifecycle=ct);function q(){ot()>0?it(function(){g(document.body)}):g(document.body)}return document.readyState==="loading"?document.addEventListener("DOMContentLoaded",q):q(),g}function dt(e){let t=!1;for(let r=0;r<e.length;r++){const i=e[r];if(!(i===""||i==null)&&(t=!0,!Number.isFinite(Number(i))))return"string"}return t?"number":"string"}function ft(e,t,r,i){if(r==="number"){const c=parseFloat(e),d=parseFloat(t);return(isNaN(c)?0:c)-(isNaN(d)?0:d)}const a=e!=null?String(e):"",l=t!=null?String(t):"";return i?i.compare(a,l):a<l?-1:a>l?1:0}function Te(e){return(e||"").replace(/^#/,"")}function he(e){const t=e===void 0?location.hash:e,r={},i=Te(t);if(!i)return r;const a=i.split("&");for(let l=0;l<a.length;l++){const c=a[l];if(!c)continue;const d=c.indexOf(":"),s=d>-1?c.slice(0,d):c,w=d>-1?c.slice(d+1):"";if(s)try{r[s]=decodeURIComponent(w)}catch{r[s]=w}}return r}function ht(e){if(!e)return null;const t=he();return e in t?t[e]:null}function wt(e,t){if(!e)return;const r=he();t==null?delete r[e]:r[e]=String(t);const a=Object.keys(r).map(function(l){const c=r[l];return c===""?l:l+":"+encodeURIComponent(c)}).join("&");Te(location.hash)!==a&&(location.hash=a)}function yt(e){return e.button===1||e.ctrlKey||e.metaKey||e.shiftKey?!1:(e.preventDefault(),!0)}function pt(e,t){if(!e||!e.hasAttribute("data-ln-hash"))return null;const r=e.getAttribute("data-ln-hash");if(r&&r.trim()!=="")return r.trim();const i=e.getAttribute("data-ln-sort")||e.getAttribute("data-ln-search-for")||e.getAttribute("data-ln-search")||e.getAttribute("data-ln-filter")||e.id;return i?t?i+"-"+t:i:t||null}function gt(e,t){return!t||t==="none"||e===null||e===void 0?null:String(e)+"."+t}function mt(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 bt(e,t){return!e||!Array.isArray(t)||t.length===0?null:e+":"+t.map(encodeURIComponent).join(",")}function _t(e){if(!e||typeof e!="string")return null;const t=e.indexOf(":");if(t===-1)return null;const r=e.slice(0,t),i=e.slice(t+1),a=i?i.split(",").map(function(l){try{return decodeURIComponent(l)}catch{return l}}).filter(Boolean):[];return{key:r,values:a}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.hashParse=he,window.lnCore.hashGet=ht,window.lnCore.hashSet=wt,window.lnCore.hashLinkClick=yt,window.lnCore.resolveHashNamespace=pt,window.lnCore.hashSortEncode=gt,window.lnCore.hashSortDecode=mt,window.lnCore.hashFilterEncode=bt,window.lnCore.hashFilterDecode=_t);function Ct(e){return(e||"").replace(/^\?/,"")}function St(e){const t=e===void 0?typeof window<"u"?window.location.search:"":e,r={},i=Ct(t);if(!i)return r;const a=new URLSearchParams(i);for(const[l,c]of a.entries())r[l]=c;return r}function At(e){if(!e||typeof window>"u")return null;const t=new URLSearchParams(window.location.search);return t.has(e)?t.get(e):null}function vt(e,t){if(!e||typeof window>"u")return;const r=new URL(window.location.href);if(t==null||t===""?r.searchParams.delete(e):r.searchParams.set(e,String(t)),r.search===window.location.search)return;const i=r.pathname+r.search+r.hash;window.history.replaceState(window.history.state,"",i)}function xt(e,t){if(!e||!e.hasAttribute("data-ln-query"))return null;const r=e.getAttribute("data-ln-query");if(r&&r.trim()!=="")return r.trim();const i=e.getAttribute("data-ln-sort")||e.getAttribute("data-ln-search-for")||e.getAttribute("data-ln-search")||e.getAttribute("data-ln-filter")||e.id;return i?t?i+"_"+t:i:t||null}function kt(e,t){return!t||t==="none"||e===null||e===void 0?null:String(e)+"."+t}function qt(e,t){if(e&&typeof e=="string"){if(e.endsWith(".asc"))return{fieldOrColumn:e.slice(0,-4),direction:"asc"};if(e.endsWith(".desc"))return{fieldOrColumn:e.slice(0,-5),direction:"desc"}}if(t&&typeof t=="object"){const r=t.sort_field||t.sort_by;if(r){const i=t.sort_dir&&String(t.sort_dir).toLowerCase()==="desc"?"desc":"asc";return{fieldOrColumn:r,direction:i}}}return null}function Et(e){return!Array.isArray(e)||e.length===0?null:e.map(encodeURIComponent).join(",")}function It(e){return!e||typeof e!="string"?[]:e.split(",").map(function(t){try{return decodeURIComponent(t.trim())}catch{return t.trim()}}).filter(Boolean)}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.queryParse=St,window.lnCore.queryGet=At,window.lnCore.querySet=vt,window.lnCore.resolveQueryParam=xt,window.lnCore.querySortEncode=kt,window.lnCore.querySortDecode=qt,window.lnCore.queryFilterEncode=Et,window.lnCore.queryFilterDecode=It);let W=null;const Lt="ln-ashlar:storage-salt:v1",Re=32768;function ze(e){let t="";const r=e.byteLength;for(let i=0;i<r;i+=Re)t+=String.fromCharCode.apply(null,e.subarray(i,Math.min(i+Re,r)));return btoa(t)}function Oe(e){const t=atob(e),r=t.length,i=new Uint8Array(r);for(let a=0;a<r;a++)i[a]=t.charCodeAt(a);return i}function Fe(e,t){let r=W,i={};return typeof CryptoKey<"u"&&e instanceof CryptoKey?r=e:e&&typeof e=="object"&&(i=e,typeof CryptoKey<"u"&&i.key instanceof CryptoKey&&(r=i.key)),{key:r,options:i}}async function Dt(e,t={}){if(!e)throw new Error("[ln-crypto] Key derivation failed: Secret string is required");const r=t.method||"pbkdf2",i=new TextEncoder;if(r==="sha256"){const s=await crypto.subtle.digest("SHA-256",i.encode(e));return crypto.subtle.importKey("raw",s,{name:"AES-GCM"},!1,["encrypt","decrypt"])}const a=t.salt||Lt,l=typeof a=="string"?i.encode(a):a,c=t.iterations||1e5,d=await crypto.subtle.importKey("raw",i.encode(e),"PBKDF2",!1,["deriveKey"]);return crypto.subtle.deriveKey({name:"PBKDF2",salt:l,iterations:c,hash:"SHA-256"},d,{name:"AES-GCM",length:256},!1,["encrypt","decrypt"])}async function Be(e,t={}){if(!e){W=null;return}try{const r=t.method||"sha256";W=await Dt(e,{...t,method:r})}catch(r){throw console.error("[ln-core/crypto] Key derivation failed:",r),W=null,r}}function B(){return W}async function Nt(e,t,r){const{key:i}=Fe(t);if(e==null)return e;if(!i)throw new Error("[ln-crypto] Encryption failed: No active cryptographic key provided");try{const a=new TextEncoder,l=crypto.getRandomValues(new Uint8Array(12)),c=typeof e=="string"?e:JSON.stringify(e),d=await crypto.subtle.encrypt({name:"AES-GCM",iv:l},i,a.encode(c));return{v:1,alg:"AES-GCM",encrypted:!0,iv:ze(l),data:ze(new Uint8Array(d))}}catch(a){throw console.error("[ln-core/crypto] Encryption failed:",a),new Error("[ln-crypto] Encryption failed: "+(a&&a.message?a.message:String(a)))}}async function Tt(e,t,r){const{key:i,options:a}=Fe(t),l=a.silent===!0;if(!e||!e.encrypted)return e;if(!i){if(l)return{...e,decryptionError:!0};throw new Error("[ln-crypto] Decryption failed: No active cryptographic key provided")}if(!e.iv||!e.data){if(l)return{...e,decryptionError:!0};throw new Error("[ln-crypto] Decryption failed: Malformed envelope (missing iv or data)")}try{const c=new TextDecoder,d=Oe(e.iv),s=Oe(e.data),w=await crypto.subtle.decrypt({name:"AES-GCM",iv:d},i,s),b=c.decode(w);try{return JSON.parse(b)}catch{return b}}catch(c){if(l)return{...e,decryptionError:!0};throw console.error("[ln-core/crypto] Decryption failed. Key may be incorrect or payload tampered:",c),new Error("[ln-crypto] Decryption failed. Key may be incorrect or payload tampered: "+(c&&c.message?c.message:String(c)))}}function Rt(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{const t=Math.random()*16|0;return(e==="x"?t:t&3|8).toString(16)})}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.uuid=Rt);function zt(e){return String(e||"").trim().toLowerCase()}function Ot(e){const t=zt(e);return t?t.split(/\s+/).filter(Boolean):[]}function Ft(e,t){if(!t||t.length===0)return!0;if(!e)return!1;const r=String(e).toLowerCase();for(let i=0;i<t.length;i++)if(r.indexOf(t[i])===-1)return!1;return!0}function Bt(e,t){if(!t||t.length===0)return!0;if(e==null)return!1;const r=String(e).trim().toLowerCase();for(let i=0;i<t.length;i++)if(String(t[i]).trim().toLowerCase()===r)return!0;return!1}function Mt(e={}){let t=e.windowSize>0?e.windowSize:1e3,r=e.pageSize>0?e.pageSize:200,i=e.fetchDebounce!=null?e.fetchDebounce:120;const a=typeof e.requestPage=="function"?e.requestPage:()=>{},l=new Map,c=new Set;let d=0,s=0,w=0,b=!1,_=null;function x(g,S){l.delete(g),l.set(g,S)}function j(){if(l.size<=t)return[];const g=[];for(;l.size>t;){const I=l.keys().next().value;g.push(l.get(I)),l.delete(I)}const S=new Set(l.values());return g.filter(I=>!S.has(I))}function $(g,S){c.add(g),clearTimeout(_),_=setTimeout(()=>a(g,r,S),i)}return{get logicalTotal(){return d},set logicalTotal(g){d=g},get grandTotal(){return s},set grandTotal(g){s=g},get queryGen(){return w},set queryGen(g){w=g},get size(){return l.size},get hasLoaded(){return b},getId:g=>{if(!l.has(g))return;const S=l.get(g);return x(g,S),S},ensure:(g,S,I)=>{if(!b&&!c.has(0))return $(0,I);if(d<=0)return;const k=Math.max(0,g),v=Math.min(d,S);for(let q=k;q<v;q++)if(!l.has(q)){const L=Math.floor(q/r)*r;if(!c.has(L))return $(L,I)}},ingest:(g,S,I,k,v)=>{if(v!=null&&v!==w)return[];b=!0,I!=null&&(s=I),k!=null&&(d=k);for(let q=0;q<S.length;q++)x(g+q,S[q]);return c.delete(g),j()},reset:function(){w++,this.clear()},clear:()=>{b=!1,l.clear(),c.clear(),clearTimeout(_)},configure:(g={})=>{let S=[];return g.windowSize>0&&g.windowSize!==t&&(t=g.windowSize,S=j()),g.pageSize>0&&(r=g.pageSize),g.fetchDebounce>=0&&(i=g.fetchDebounce),S}}}function Pt(e,t,r){if(!Array.isArray(e)||!t||!t.field)return e;const{field:i,direction:a}=t,l=a==="desc",c=e.map(s=>s?s[i]:void 0),d=dt(c);return[...e].sort((s,w)=>{const b=s?s[i]:void 0,_=w?w[i]:void 0,x=ft(b,_,d,r);return l?-x:x})}function Me(e,t){if(!Array.isArray(e)||!t||typeof t!="object")return e;const r=Object.keys(t).filter(i=>Array.isArray(t[i])&&t[i].length>0);return r.length?e.filter(i=>i?r.every(a=>Bt(i[a],t[a])):!1):e}function jt(e,t,r){if(!Array.isArray(e)||!t||!r||!r.length)return e;const i=Ot(t);return i.length?e.filter(a=>a?i.every(l=>r.some(c=>{const d=a[c];return d!=null&&Ft(String(d),[l])})):!1):e}function $t(e,t,r){if(!Array.isArray(e)||!e.length)return 0;if(r==="count")return e.length;const i=e.map(l=>l&&l[t]!=null?parseFloat(l[t]):NaN).filter(l=>Number.isFinite(l)),a=i.reduce((l,c)=>l+c,0);return r==="sum"?a:r==="avg"&&i.length?a/i.length:0}function Kt(e,t={},r=[],i){if(!Array.isArray(e))return{records:[],total:0,filtered:0};const a=e.length;let l=e;t.filters&&(l=Me(l,t.filters)),t.search&&(l=jt(l,t.search,r));const c=l.length;if(t.sort&&(l=Pt(l,t.sort,i)),t.offset||t.limit){const d=t.offset||0,s=t.limit||l.length;l=l.slice(d,d+s)}return{records:l,total:a,filtered:c}}function Ut(e,t){return!Array.isArray(e)||!t||typeof t!="object"?e:e.map(r=>{if(!r)return null;const i={...r};for(const[a,l]of Object.entries(t))if(typeof l=="function")try{i[a]=l(r)}catch{i[a]=void 0}return i})}function Gt(e,t,r,i="_meta"){if(!Array.isArray(e)||!e.includes(i))return!0;for(const a of Object.keys(t||{})){if(!e.includes(a))return!0;const l=t[a]&&t[a].indexes||[],c=r&&r[a]||[];if(l.some(d=>!c.includes(d)))return!0}return!1}function Vt(e){return{ok:!1,error:e&&e.message?e.message:String(e)}}(function(){const e="data-ln-data-store",t="lnDataStore";if(window[t]!==void 0)return;function r(n,o,u){const f=n.getAttribute(o);if(f==="never"||f==="-1")return-1;const h=parseInt(f,10);return isNaN(h)?u:h}const i={"data-ln-data-store":{type:"marker",effect:Ke,description:"Identifies the element as a data-store definition container"},"data-ln-data-store-indexes":{type:"list",effect:Ke,description:"Comma-separated index field names for the IndexedDB store"},"data-ln-data-store-stale":{prop:"_staleThreshold",type:"integer",read:r,fallback:300,description:"Cache staleness threshold in seconds, or -1/never"},"data-ln-data-store-search-fields":{prop:"_searchFields",type:"list",read:le,description:"Record fields to index for client-side search"},"data-ln-data-store-no-local-query":{prop:"noLocalQuery",type:"boolean",read:se,description:"Bypasses local IndexedDB query resolution, forcing remote fetching"},"data-ln-data-store-window":{prop:"_windowSize",type:"integer",read:X,fallback:1e3,min:10,effect:hn,description:"Virtual scrolling cache window size in records"},"data-ln-data-store-window-page":{prop:"_windowPageSize",type:"integer",read:X,fallback:200,min:5,effect:wn,description:"Virtual scrolling slice page size"},"data-ln-data-store-frozen":{type:"marker",description:"Applied at runtime to indicate store schema is locked in IndexedDB"}},a=ke(i),l="ln_app_cache",c="_meta",d="1.0";let s=null,w=null;const b={};function _(n){n&&n.name==="QuotaExceededError"&&A(document,"ln-data-store:quota-exceeded",{error:n})}function x(){const n={};for(const o of document.querySelectorAll(`[${e}]`)){const u=o.id;if(u){const f=o.getAttribute("data-ln-data-store-indexes")||"";n[u]={indexes:f.split(",").map(h=>h.trim()).filter(Boolean)}}}return n}function j(){return w||(w=new Promise(n=>{if(typeof indexedDB>"u")return console.warn("[ln-data-store] IndexedDB is not available in this environment"),n(null);const o=x(),u=Object.keys(o),f=indexedDB.open(l);f.onerror=()=>{console.warn("[ln-data-store] IndexedDB open failed"),n(null)},f.onsuccess=h=>{const y=h.target.result,p=Array.from(y.objectStoreNames),m=u.filter(T=>p.includes(T));let C={};if(m.length>0){const T=y.transaction(m,"readonly");for(const R of m)C[R]=Array.from(T.objectStore(R).indexNames)}if(!Gt(p,o,C,c))return $(y),s=y,n(y);const K=y.version;y.close();const F=indexedDB.open(l,K+1);let z=!1,O=null;F.onblocked=()=>{console.warn("[ln-data-store] Database upgrade blocked — waiting for other tabs to close connection"),A(document,"ln-data-store:blocked",{db:l}),O||(O=setTimeout(()=>{z||(console.warn("[ln-data-store] Database upgrade timed out while blocked"),z=!0,w=null,n(null))},5e3))},F.onerror=()=>{z||(O&&clearTimeout(O),z=!0,w=null,console.warn("[ln-data-store] Database upgrade failed"),n(null))},F.onupgradeneeded=T=>{const R=T.target.result,yn=T.target.transaction;R.objectStoreNames.contains(c)||R.createObjectStore(c,{keyPath:"key"});for(const J of u)if(R.objectStoreNames.contains(J)){const re=yn.objectStore(J);for(const G of o[J].indexes)re.indexNames.contains(G)||re.createIndex(G,G,{unique:!1})}else{const re=R.createObjectStore(J,{keyPath:"id"});for(const G of o[J].indexes)re.createIndex(G,G,{unique:!1})}},F.onsuccess=T=>{if(z){T.target.result&&T.target.result.close();return}O&&clearTimeout(O),z=!0;const R=T.target.result;$(R),s=R,n(R)}}}),w)}function $(n){n.onversionchange=()=>{n.close(),s=null,w=null}}function g(){return s?Promise.resolve(s):(w=null,j())}async function S(n){if(!B()||!n)return n;const o={...n},u=o.id,f=await Nt(o);return!f||!f.encrypted?n:{...f,id:u}}async function I(n){return!n||!n.encrypted||!B()?n:Tt(n,{silent:!0})}const k=(n,o)=>g().then(u=>u?u.transaction(n,o).objectStore(n):null);function v(n){return new Promise((o,u)=>{n.onsuccess=()=>o(n.result),n.onerror=()=>{_(n.error),u(n.error)}})}const q=n=>k(n,"readonly").then(o=>o?v(o.getAll()):[]).then(o=>B()?Promise.all(o.map(u=>I(u))):o),L=(n,o)=>k(n,"readonly").then(u=>u?v(u.get(o)).then(f=>f!==void 0?f:typeof o=="string"&&o.trim()!==""&&!isNaN(Number(o))?v(u.get(Number(o))):typeof o=="number"?v(u.get(String(o))):null):null).then(u=>u?I(u):null),D=(n,o)=>g().then(u=>{if(!u)return[];const h=u.transaction(n,"readonly").objectStore(n),y=o.map(p=>v(h.get(p)).then(m=>m!==void 0?m:typeof p=="string"&&p.trim()!==""&&!isNaN(Number(p))?v(h.get(Number(p))):typeof p=="number"?v(h.get(String(p))):null));return Promise.all(y).then(p=>B()?Promise.all(p.map(m=>m?I(m):null)):p)}),M=(n,o)=>(B()?S(o):Promise.resolve(o)).then(f=>k(n,"readwrite").then(h=>h?v(h.put(f)):null)),we=(n,o)=>k(n,"readwrite").then(u=>u?v(u.delete(o)).then(()=>{if(typeof o=="string"&&o.trim()!==""&&!isNaN(Number(o)))return v(u.delete(Number(o)));if(typeof o=="number")return v(u.delete(String(o)))}):null),U=n=>k(n,"readwrite").then(o=>o?v(o.clear()):null),P=n=>k(n,"readonly").then(o=>o?v(o.count()):0),H=n=>k(c,"readonly").then(o=>o?v(o.get(n)):null),Y=(n,o)=>k(c,"readwrite").then(u=>{if(u)return o.key=n,v(u.put(o))});function N(n){return this.dom=n,this._name=n.id,this._name||console.warn("[ln-data-store] missing id — the store cannot be addressed",n),xe(this,n,a),this._handlers=null,this.isLoaded=!1,this.canServe=!1,this.isInitialized=!1,this.initializationError=null,this.hasCache=!1,this.isSyncing=!1,this.lastSyncedAt=null,this.query={filters:{},search:"",sort:null},n.hasAttribute("data-ln-data-store-window")?this._windowIndex=Mt({windowSize:this._windowSize,pageSize:this._windowPageSize,requestPage:(o,u,f)=>{A(this.dom,"ln-data-store:request-page",{store:this._name,offset:o,limit:u,query:f,queryGen:this._windowIndex.queryGen})}}):this._windowIndex=null,this.windowed=this._windowIndex!==null,this.totalCount=0,this.presenters=null,this._mutationChain=Promise.resolve(),b[this._name]=this,Wt(this),this.ready=Yt(this),this}function Wt(n){n._handlers={create:o=>ee(n,"create",o.detail,()=>Ht(n,o.detail)),update:o=>ee(n,"update",o.detail,()=>Qt(n,o.detail)),delete:o=>ee(n,"delete",o.detail,()=>Jt(n,o.detail)),"bulk-delete":o=>ee(n,"bulk-delete",o.detail,()=>Zt(n,o.detail)),"sync-failed":o=>{n.isSyncing=!1,A(n.dom,"ln-data-store:sync-error",{store:n._name,error:o.detail&&o.detail.error,status:o.detail&&o.detail.status})}};for(const[o,u]of Object.entries(n._handlers))n.dom.addEventListener(`ln-data-store:request-${o}`,u);n._queryHandlers={"ln-search:change":o=>{o.preventDefault();const u=o.detail&&o.detail.term!=null?o.detail.term:"";u!==n.query.search&&(n.query.search=u,ye(n))},"ln-filter:change":o=>{o.preventDefault();const u=o.detail&&o.detail.key;if(!u)return;const f=(o.detail.values||[]).slice(),h=n.query.filters[u];(h?h.length===f.length&&h.every((p,m)=>p===f[m]):!f.length)||(f.length?n.query.filters[u]=f:delete n.query.filters[u],ye(n))},"ln-sort:change":o=>{o.preventDefault();const u=o.detail&&o.detail.field,f=o.detail&&o.detail.direction,h=f&&f!=="none"?{field:u,direction:f}:null,y=n.query.sort;!y&&!h||y&&h&&y.field===h.field&&y.direction===h.direction||(n.query.sort=h,ye(n))}};for(const[o,u]of Object.entries(n._queryHandlers))n.dom.addEventListener(o,u)}function ee(n,o,u,f){const h=u&&u.requestId;return n._mutationChain=n._mutationChain.then(()=>n.ready).then(()=>{if(n.initializationError)throw n.initializationError;return f()}).catch(y=>Xt(n,o,h,y)),n._mutationChain}function te(n,o=0){return P(n._name).then(u=>{if(n._windowIndex||n.windowed){const f=n.totalCount!=null?n.totalCount:u;n.totalCount=Math.max(0,f+o)}else n.totalCount=u;return n.hasCache=!0,n.isLoaded=!0,n.canServe=!0,Y(n._name,{schema_version:d,last_synced_at:n.lastSyncedAt,has_cache:!0,record_count:n.totalCount})})}function Ht(n,{tempId:o,data:u={},requestId:f}={}){const h={...u,id:o};return M(n._name,h).then(()=>te(n,1)).then(()=>{A(n.dom,"ln-data-store:created",{store:n._name,record:h,tempId:o,requestId:f})})}function Qt(n,{id:o,data:u={},requestId:f}={}){return L(n._name,o).then(h=>{if(!h)throw new Error(`Record not found: ${o}`);const y=h.id,p={...h,...u,id:y},m=u.id,C=m!==void 0&&m!==y;return(C?en(n._name,y,{...p,id:m}):M(n._name,p)).then(()=>te(n,0)).then(()=>{A(n.dom,"ln-data-store:updated",{store:n._name,record:C?{...p,id:m}:p,previous:h,requestId:f})})})}function Jt(n,{id:o,requestId:u}={}){return L(n._name,o).then(f=>{if(!f){A(n.dom,"ln-data-store:deleted",{store:n._name,id:o,requestId:u,missing:!0});return}const h=f.id;return we(n._name,h).then(()=>te(n,-1)).then(()=>{A(n.dom,"ln-data-store:deleted",{store:n._name,id:h,requestId:u})})})}function Zt(n,{ids:o=[],requestId:u}={}){return o.length?Promise.all(o.map(f=>L(n._name,f))).then(f=>{const h=f.filter(Boolean).map(y=>y.id);return ne(n._name,h).then(()=>te(n,-h.length)).then(()=>{A(n.dom,"ln-data-store:deleted",{store:n._name,ids:h,requestId:u})})}):(A(n.dom,"ln-data-store:deleted",{store:n._name,ids:[],requestId:u}),Promise.resolve())}function Xt(n,o,u,f){console.error("[ln-data-store] "+o+" failed:",f),A(n.dom,"ln-data-store:mutation-error",{store:n._name,action:o,requestId:u,error:f})}function Yt(n){return j().then(o=>{if(!o)throw new Error("IndexedDB is unavailable");return H(n._name)}).then(o=>{if(n.initializationError=null,o&&o.schema_version===d)n.lastSyncedAt=o.last_synced_at||null,n.totalCount=o.record_count||0,n.hasCache=o.has_cache===!0||n.totalCount>0,n.hasCache&&(n.isLoaded=!0,n.canServe=!0,A(n.dom,"ln-data-store:ready",{store:n._name,count:n.totalCount,source:"cache"})),n.isInitialized=!0,A(n.dom,"ln-data-store:initialized",{store:n._name,hasCache:n.hasCache,lastSyncedAt:n.lastSyncedAt,count:n.totalCount});else{if(o&&o.schema_version!==d)return U(n._name).then(()=>Y(n._name,{schema_version:d,last_synced_at:null,has_cache:!1,record_count:0})).then(()=>{n.isInitialized=!0,n.hasCache=!1,A(n.dom,"ln-data-store:initialized",{store:n._name,hasCache:!1,lastSyncedAt:null,count:0})});n.isInitialized=!0,n.hasCache=!1,A(n.dom,"ln-data-store:initialized",{store:n._name,hasCache:!1,lastSyncedAt:null,count:0})}}).catch(o=>(n.isInitialized=!0,n.isLoaded=!1,n.canServe=!1,n.hasCache=!1,n.isSyncing=!1,n.initializationError=o,A(n.dom,"ln-data-store:initialization-error",{store:n._name,error:o}),{ok:!1,error:o}))}function Pe(n){n.isSyncing=!0,A(n.dom,"ln-data-store:request-remote-sync",{since:n.lastSyncedAt})}function je(n,o){return g().then(u=>u?(B()?Promise.all(o.map(h=>S(h))):Promise.resolve(o)).then(h=>new Promise((y,p)=>{const m=u.transaction(n,"readwrite"),C=m.objectStore(n);h.forEach(E=>C.put(E)),m.oncomplete=()=>y(),m.onerror=()=>{_(m.error),p(m.error)}})):void 0)}function ne(n,o){return g().then(u=>{if(u)return new Promise((f,h)=>{const y=u.transaction(n,"readwrite"),p=y.objectStore(n);o.forEach(m=>{p.delete(m),typeof m=="string"&&m.trim()!==""&&!isNaN(Number(m))?p.delete(Number(m)):typeof m=="number"&&p.delete(String(m))}),y.oncomplete=()=>f(),y.onerror=()=>h(y.error)})})}function en(n,o,u){return(B()?S(u):Promise.resolve(u)).then(h=>g().then(y=>{if(y)return new Promise((p,m)=>{const C=y.transaction(n,"readwrite"),E=C.objectStore(n);E.put(h),E.delete(o),C.oncomplete=()=>p(),C.onerror=()=>{_(C.error),m(C.error)}})}))}const tn=new Intl.Collator(void 0,{numeric:!0,sensitivity:"base"});function nn(n){return n?Object.keys(n).filter(o=>Array.isArray(n[o])&&n[o].length>0):[]}function rn(n,o,u){return o.every(f=>u[f].map(String).includes(String(n[f])))}function on(n){return String(n||"").toLowerCase().split(/\s+/).filter(Boolean)}function an(n,o,u){return o.every(f=>u.some(h=>{const y=n[h];return y!=null&&String(y).toLowerCase().includes(f)}))}function sn(n,o,u){return $t(n,o,u)}function Q(n,o){return Ut(o,n.presenters&&n.presenters.computed)}function ln(n){return!n.sort&&!B()}function cn(n,o,u){const f=nn(o.filters),h=o.search?on(o.search):[],y=n._searchFields,p=h.length>0&&y&&y.length>0;return k(n._name,"readonly").then(m=>m?new Promise((C,E)=>{const K=[],F=m.openCursor();F.onsuccess=()=>{const z=F.result;if(!z||K.length>=u){C(K);return}const O=z.value;(!f.length||rn(O,f,o.filters))&&(!p||an(O,h,y))&&K.push(O),z.continue()},F.onerror=()=>E(F.error)}):[])}function $e(n,o,u){return Kt(o,u,n._searchFields,tn)}function un(n,o,u){const f=[];for(let y=o;y<o+u;y++){const p=n._windowIndex.getId(y);f.push(p)}const h=Array.from(new Set(f.filter(y=>y!==void 0)));return D(n._name,h).then(y=>{const p=new Map;for(let C=0;C<y.length;C++){const E=y[C];E&&p.set(String(E.id),E)}const m=[];for(let C=0;C<f.length;C++){const E=f[C];if(E===void 0)m.push(null);else{const K=p.get(String(E));m.push(K||null)}}return{data:Q(n,m),total:n._windowIndex.grandTotal,filtered:n._windowIndex.logicalTotal,offset:o,queryGen:n._windowIndex.queryGen}})}N.prototype.getAll=function(n={}){const o=this;if(o._windowIndex){const u=n.offset||0,f=n.limit||200;if(o._windowIndex.ensure(u,u+f,n),!o._windowIndex.hasLoaded&&!o.noLocalQuery){const h=u+f,y=p=>({data:Q(o,p),offset:u,queryGen:o._windowIndex.queryGen,provisional:!0});return ln(n)?cn(o,n,h).then(p=>y(p.slice(u,h))):q(o._name).then(p=>y($e(o,p,n).records))}return un(o,u,f)}return q(o._name).then(u=>{const f=$e(o,u,n);return{data:Q(o,f.records),total:f.total,filtered:f.filtered}})},N.prototype.getById=function(n){return L(this._name,n).then(o=>o?Q(this,[o])[0]:null)},N.prototype.count=function(n){return n&&Object.keys(n).length>0?q(this._name).then(u=>Me(u,n).length):this.windowed&&this.totalCount!=null?Promise.resolve(this.totalCount):P(this._name)},N.prototype.aggregate=function(n,o){return q(this._name).then(u=>sn(u,n,o))},N.prototype.setPresenters=function(n){this.presenters=n},N.prototype.applySync=function(n,o,u,f){f=f||{};const h=this;if(h._windowIndex&&f.queryGen!=null&&f.queryGen!==h._windowIndex.queryGen)return Promise.resolve({ok:!0,stale:!0});let y=g().then(p=>{if(!p)throw new Error("IndexedDB unavailable")});return n.length>0&&(y=y.then(()=>je(h._name,n))),o.length>0&&(y=y.then(()=>ne(h._name,o))),y.then(()=>{if(h._windowIndex&&(f.offset!=null||f.total!=null)){const p=f.offset!=null?f.offset:0,m=n.map(E=>E.id),C=h._windowIndex.ingest(p,m,f.total,f.filtered,f.queryGen);if(C&&C.length)return ne(h._name,C)}}).then(()=>P(h._name)).then(p=>(h.totalCount=f.total!==void 0?f.total:p,h.hasCache=!0,Y(h._name,{schema_version:d,last_synced_at:u,has_cache:!0,record_count:h.totalCount}))).then(()=>{const p=!h.isLoaded;return h.isLoaded=!0,h.canServe=!0,h.isSyncing=!1,h.lastSyncedAt=u,p?(A(h.dom,"ln-data-store:loaded",{store:h._name,count:h.totalCount,meta:f}),A(h.dom,"ln-data-store:ready",{store:h._name,count:h.totalCount,source:"server",meta:f})):A(h.dom,"ln-data-store:synced",{store:h._name,added:n.length,deleted:o.length,changed:!0,meta:f}),{ok:!0}}).catch(p=>{h.isSyncing=!1;const m=p&&p.message?p.message:String(p);return console.error("[ln-data-store] applySync failed:",p),A(h.dom,"ln-data-store:sync-error",{store:h._name,error:m}),Vt(p)})},N.prototype.applyQuery=function(n,o){o=o||{};const u=this;let f=Promise.resolve();return n.length>0&&(f=f.then(()=>je(u._name,n))),f.then(()=>P(u._name)).then(h=>(u.totalCount=o.total!==void 0?o.total:h,n.length>0&&(u.canServe=!0),Q(u,n))).catch(h=>(console.error("[ln-data-store] applyQuery failed:",h),[]))},N.prototype.forceSync=function(){this.isSyncing||Pe(this)},N.prototype.fullReload=function(){const n=this;return U(n._name).then(()=>Y(n._name,{schema_version:d,last_synced_at:null,has_cache:!1,record_count:0})).then(()=>{n.isLoaded=!1,n.hasCache=!1,n.lastSyncedAt=null,n.totalCount=0,Pe(n)})},N.prototype.destroy=function(){if(this._windowIndex&&(this._windowIndex.clear(),this._windowIndex=null,this.windowed=!1),this._handlers){for(const[n,o]of Object.entries(this._handlers))this.dom.removeEventListener(`ln-data-store:request-${n}`,o);this._handlers=null}if(this._queryHandlers){for(const[n,o]of Object.entries(this._queryHandlers))this.dom.removeEventListener(n,o);this._queryHandlers=null}delete b[this._name],delete this.dom[t]};function dn(){return g().then(n=>{if(!n)return;const o=Array.from(n.objectStoreNames);return new Promise((u,f)=>{const h=n.transaction(o,"readwrite");o.forEach(y=>h.objectStore(y).clear()),h.oncomplete=()=>u(),h.onerror=()=>f(h.error)})}).then(()=>{Object.values(b).forEach(n=>{n.isLoaded=!1,n.canServe=!1,n.isInitialized=!1,n.initializationError=null,n.hasCache=!1,n.isSyncing=!1,n.lastSyncedAt=null,n.totalCount=0})})}function ye(n){n._windowIndex&&n._windowIndex.reset(),A(n.dom,"ln-data-store:query-changed",{store:n._name,query:{filters:Object.assign({},n.query.filters),search:n.query.search,sort:n.query.sort?Object.assign({},n.query.sort):null}})}const fn="data-ln-data-store-frozen";function Ke(n,o){n.setAttribute(fn,o)}function hn(n){const o=n[t];if(!o._windowIndex)return;const u=o._windowIndex.configure({windowSize:o._windowSize});u.length&&ne(o._name,u).catch(f=>{console.error("[ln-data-store] window shrink eviction failed:",f)})}function wn(n){const o=n[t];o._windowIndex&&o._windowIndex.configure({pageSize:o._windowPageSize})}Ne(e,t,N,"ln-data-store",{attributes:i}),window[t].clearAll=dn,window[t].init=window[t],window[t].setStorageKey=Be,typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.setStorageKey=Be)})()})();
|
|
1
|
+
(function(){"use strict";function be(){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 oe(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 i=null;for(let a=1;a<t.length;a++)if(t[a]&&t[a].nodeType===1){i=t[a];break}if(!oe(i))return}e.apply(console,t)}}function C(e,t,r){const i=r||{};window.lnCore._debugSink&&window.lnCore._debugSink("event",t,e,i),e.dispatchEvent(new CustomEvent(t,{bubbles:!0,detail:i}))}function X(e,t){if(!document.body){document.addEventListener("DOMContentLoaded",function(){X(e,t)}),console.warn("["+t+'] Script loaded before <body> — add "defer" to your <script> tag');return}e()}function Ue(e){const t=e.querySelector('input[name="_method"]');return((t&&t.value!==""?t.value:e.method)||"").toUpperCase()}function Ge(e,t){const r=!!(t&&t.typed),i=t&&t.exclude,a={},l=e.elements,c={};if(r)for(let d=0;d<l.length;d++){const s=l[d];s.name&&s.type==="checkbox"&&!s.disabled&&(c[s.name]=(c[s.name]||0)+1)}for(let d=0;d<l.length;d++){const s=l[d];if(!(!s.name||s.disabled||s.type==="file"||s.type==="submit"||s.type==="button")&&!(i&&s.matches&&s.matches(i)))if(s.type==="checkbox")r&&c[s.name]===1?a[s.name]=s.checked:(a[s.name]||(a[s.name]=[]),s.checked&&a[s.name].push(s.value));else if(s.type==="radio")s.checked&&(a[s.name]=s.value);else if(s.type==="select-multiple"){a[s.name]=[];for(let w=0;w<s.options.length;w++)s.options[w].selected&&a[s.name].push(s.options[w].value)}else if(r&&s.type==="hidden")a[s.name]=s.value;else if(r&&(s.type==="number"||s.type==="range")){const w=Number(s.value);a[s.name]=s.value===""||isNaN(w)?null:w}else a[s.name]=s.value}return a}function Ve(e){if(typeof e!="string")return!!e;const t=e.trim().toLowerCase();return t!=="false"&&t!=="0"&&t!==""&&t!=="off"&&t!=="no"}function We(e,t){const r=e.elements,i=[],a={};for(let l=0;l<r.length;l++){const c=r[l];c.name&&c.type==="checkbox"&&(a[c.name]=(a[c.name]||0)+1)}for(let l=0;l<r.length;l++){const c=r[l];if(c.type==="file"||c.type==="submit"||c.type==="button")continue;const d=c.getAttribute("data-ln-fill-as")||c.name;if(!d||!(d in t))continue;const s=t[d];if(c.type==="checkbox"){if(Array.isArray(s))c.checked=s.indexOf(c.value)!==-1;else if(a[c.name]>1){const w=String(s).split(",").map(function(b){return b.trim()});c.checked=w.indexOf(c.value)!==-1}else c.checked=Ve(s);i.push(c)}else if(c.type==="radio")c.checked=c.value===String(s),i.push(c);else if(c.type==="select-multiple"){if(Array.isArray(s))for(let w=0;w<c.options.length;w++)c.options[w].selected=s.indexOf(c.options[w].value)!==-1;i.push(c)}else c.value=s,c.tagName==="SELECT"&&s!=null&&c.setAttribute("data-ln-value",s),i.push(c)}return i}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.populateForm=We,window.lnCore.serializeForm=Ge,window.lnCore.resolveFormMethod=Ue);const _e={};function He(e,t){_e[e]=t}function Qe(e){return _e[e]||{ingress:t=>t,egress:t=>t}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerDataMapper=He,window.lnCore.getDataMapper=Qe);function Je(){typeof window>"u"||(window.lnCore=window.lnCore||{},!window.lnCore._localeObserverBound&&(window.lnCore._localeObserverBound=!0,X(function(){new MutationObserver(function(){C(document,"ln-core:locale-change",{})}).observe(document.documentElement,{attributes:!0,attributeFilter:["lang"],subtree:!0})},"ln-core")))}const Ce={};function Ze(e,t){if(!e||typeof t!="object")return;const r=e.toLowerCase().split("-")[0];Ce[r]=t}function Xe(e){if(!e)return null;const t=e.toLowerCase().split("-")[0];return Ce[t]||null}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerLocaleFallback=Ze,window.lnCore.getLocaleFallback=Xe,window.lnCore.ensureLocaleObserver=Je);const ie={};function Ye(e,t){ie[e]||(ie[e]=document.querySelector('[data-ln-template="'+e+'"]'));const r=ie[e];return r?r.content.cloneNode(!0):(console.warn("["+(t||"ln-core")+'] Template "'+e+'" not found'),null)}function Se(e,t){if(!e||!t)return e;const r=e.querySelectorAll("[data-ln-field]");for(let c=0;c<r.length;c++){const d=r[c],s=d.getAttribute("data-ln-field");t[s]!=null&&(d.textContent=t[s])}const i=e.querySelectorAll("[data-ln-attr]");for(let c=0;c<i.length;c++){const d=i[c],s=d.getAttribute("data-ln-attr").split(",");for(let w=0;w<s.length;w++){const b=s[w].trim().split(":");if(b.length!==2)continue;const _=b[0].trim(),x=b[1].trim();t[x]!=null&&d.setAttribute(_,t[x])}}const a=e.querySelectorAll("[data-ln-show]");for(let c=0;c<a.length;c++){const d=a[c],s=d.getAttribute("data-ln-show");s in t&&d.classList.toggle("hidden",!t[s])}const l=e.querySelectorAll("[data-ln-class]");for(let c=0;c<l.length;c++){const d=l[c],s=d.getAttribute("data-ln-class").split(",");for(let w=0;w<s.length;w++){const b=s[w].trim().split(":");if(b.length!==2)continue;const _=b[0].trim(),x=b[1].trim();x in t&&d.classList.toggle(_,!!t[x])}}return e}function et(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 r=e.querySelectorAll("[data-ln-form], [data-ln-fillable]");for(let i=0;i<r.length;i++)window.lnCore._debugSink&&window.lnCore._debugSink("event","ln-fill",r[i],t??null),r[i].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)Se(e.target,e.detail);else{const t=e.target.querySelectorAll("[data-ln-field]");for(let r=0;r<t.length;r++)t[r].textContent=""}})));function Ae(e,t){if(!e||!t)return e;const r=document.createTreeWalker(e,NodeFilter.SHOW_TEXT);for(;r.nextNode();){const l=r.currentNode;l.textContent.indexOf("{{")!==-1&&(l.textContent=l.textContent.replace(/\{\{\s*(\w+)\s*\}\}/g,function(c,d){return t[d]!==void 0?t[d]:""}))}const i=function(l,c){return t[c]!==void 0?t[c]:""},a=Array.from(e.querySelectorAll("*"));e.nodeType===1&&a.push(e);for(let l=0;l<a.length;l++){const c=a[l],d=c.attributes;for(let s=0;s<d.length;s++){const w=d[s];w.value.indexOf("{{")!==-1&&c.setAttribute(w.name,w.value.replace(/\{\{\s*(\w+)\s*\}\}/g,i))}}return e}function tt(e,t,r,i,a,l){const c={};for(let s=0;s<e.children.length;s++){const w=e.children[s],b=w.getAttribute("data-ln-render-key");b&&(c[b]=w)}const d=document.createDocumentFragment();for(let s=0;s<t.length;s++){const w=t[s],b=String(i(w));let _=c[b];if(_)a(_,w,s);else{const x=Ye(r,l);if(!x||(Ae(x,w),_=x.firstElementChild,!_))continue;_.setAttribute("data-ln-render-key",b),a(_,w,s)}d.appendChild(_)}e.textContent="",e.appendChild(d)}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.fillTemplate=Ae,window.lnCore.fill=Se,window.lnCore.lnFill=et,window.lnCore.renderList=tt);function ae(e,t,r){const i=e.getAttribute(t);return i===null?r:i}function Y(e,t,r){const i=parseInt(e.getAttribute(t),10);return isNaN(i)?r:i}function se(e,t,r=!1){const i=e.getAttribute(t);if(i===null)return!!r;const a=i.trim().toLowerCase();return!(a==="false"||a==="0")}function le(e,t){return(e.getAttribute(t)||"").split(",").map(r=>r.trim()).filter(Boolean)}const ce=new Map;function ve(e,t){const r=(e?e.join("|"):"")+"::"+t;if(ce.has(r))return ce.get(r);const i=new Set(e||[]),a=function(l,c){const d=l.getAttribute(c);return d!==null&&i.has(d)?d:t};return ce.set(r,a),a}function xe(e,t,r){const i=parseFloat(e.getAttribute(t));return isNaN(i)?r:i}function ke(e,t,r){const i=e.getAttribute(t);if(!i)return r;try{return JSON.parse(i)}catch{return r}}function qe(e,t,r,i,a){if(!e||t===null)return!0;const l=i||"ln-component",c=e.type;if(c==="trigger"||c==="marker"||c==="string"||c==="list"||!c||t===""&&e.fallback!==void 0)return!0;const d=s=>{a?console.warn(s,a):console.warn(s)};if(c==="boolean"){const s=t.trim().toLowerCase();return s!==""&&s!=="true"&&s!=="false"&&s!=="1"&&s!=="0"?(d(`[${l}] Invalid value "${t}" for boolean attribute "${r}". Allowed: "true", "false", or presence-only.`),!1):!0}if(c==="enum"){const s=e.values||[];return s.includes(t)?!0:(d(`[${l}] Invalid value "${t}" for attribute "${r}". Allowed: ${s.join(", ")}. Fallback: "${e.fallback}".`),!1)}if(c==="integer"){if(!/^-?\d+$/.test(t))return d(`[${l}] Invalid integer "${t}" for attribute "${r}". Fallback: ${e.fallback}.`),!1;const s=parseInt(t,10);return e.min!==void 0&&s<e.min?(d(`[${l}] Value ${s} for attribute "${r}" is less than min (${e.min}).`),!1):e.max!==void 0&&s>e.max?(d(`[${l}] Value ${s} for attribute "${r}" is greater than max (${e.max}).`),!1):!0}if(c==="float")return isNaN(Number(t))?(d(`[${l}] Invalid float "${t}" for attribute "${r}". Fallback: ${e.fallback}.`),!1):!0;if(c==="json")try{return JSON.parse(t),!0}catch(s){return d(`[${l}] Invalid JSON for attribute "${r}": ${s.message}. Fallback: ${e.fallback}.`),!1}return!0}function Ee(e,t,r){for(const i in r){const[a,l,c]=r[i];Object.defineProperty(e,i,{get:function(){return a(t,l,c)},enumerable:!0,configurable:!0})}return e}function Ie(e){const t={};for(const r in e){const i=e[r];if(!i||!i.prop)continue;let a=i.read;if(!a&&i.type)switch(i.type){case"enum":a=ve(i.values,i.fallback);break;case"integer":a=Y;break;case"float":a=xe;break;case"boolean":a=se;break;case"list":a=le;break;case"json":a=ke;break;case"string":default:a=ae;break}a||(a=ae),t[i.prop]=[a,r,i.fallback]}return t}function nt(e){const t={};for(const r in e){const i=e[r];i&&i.effect&&(t[r]=i.effect)}return Object.keys(t).length?t:null}function rt(e){if(e.onAttrChange&&!e.declared)return null;const t=new Set;if(e.effects)for(const r in e.effects)t.add(r);if(e.onAttrChange&&e.declared)for(const r of e.declared)t.add(r);return t}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.defineAttrs=Ee,window.lnCore.attrSpec=Ie,window.lnCore.attrStr=ae,window.lnCore.attrInt=Y,window.lnCore.attrBool=se,window.lnCore.attrList=le,window.lnCore.attrEnum=ve,window.lnCore.attrFloat=xe,window.lnCore.attrJson=ke);function W(e,t){if(!e[t.attribute]){window.lnCore._persistSink&&e.hasAttribute&&e.hasAttribute("data-ln-persist")&&window.lnCore._persistSink(e,t.selector);try{e[t.attribute]=new t.ComponentFn(e)}catch(r){console.error("["+t.attribute+"] init failed",e,r)}}}function Le(e,t,r,i){if(e.nodeType!==1)return;const l=t.indexOf("[")!==-1||t.indexOf(".")!==-1||t.indexOf("#")!==-1?t:"["+t+"]",c={selector:t,attribute:r,ComponentFn:i};if(e.matches&&e.matches(l)&&W(e,c),e.querySelectorAll){const d=e.querySelectorAll(l);for(let s=0;s<d.length;s++)W(d[s],c)}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore._bootHolds=window.lnCore._bootHolds||0,window.lnCore._bootQueue=window.lnCore._bootQueue||[]);function ot(){return typeof window<"u"&&window.lnCore&&window.lnCore._bootHolds||0}function it(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 De(){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 at(e){const t=De(),r=e.observed||[];for(let i=0;i<r.length;i++){const a=r[i];t.byAttr.has(a)||t.byAttr.set(a,[]),t.byAttr.get(a).push(e)}if(t.byDeclaredAttr=t.byDeclaredAttr||new Map,e.attributes)for(const i in e.attributes){t.byDeclaredAttr.has(i)||t.byDeclaredAttr.set(i,[]);const a=t.byDeclaredAttr.get(i);a.some(l=>l.componentTag===e.componentTag)||a.push({spec:e.attributes[i],componentTag:e.componentTag})}if(e.onAttrChange||e.effects){t.reactive.push(e);const i=rt(e);if(i===null)t.reactiveWildcard.push(e);else for(const a of i)t.byReactive.has(a)||t.byReactive.set(a,[]),t.byReactive.get(a).push(e)}e.persist&&t.persist.push(e)}function Re(e,t,r,i){for(let a=0;a<e.length;a++){const l=e[a];if(!t[l.attribute])continue;const c=l.effects&&l.effects[r];c?c(t,r,i):l.onAttrChange&&(!l.declared||l.declared.has(r))&&l.onAttrChange(t,r,i)}}function st(e){const t=e.attributeName,r=t.indexOf("data-ln-")===0,i=De(),a=i.byAttr.get(t),l=be()&&i.byDeclaredAttr&&i.byDeclaredAttr.has(t);if(!r&&!a&&!l)return;const c=e.target;if(e.oldValue!==c.getAttribute(t)){if(l&&oe(c)){const d=i.byDeclaredAttr.get(t),s=c.getAttribute(t);for(let w=0;w<d.length;w++)qe(d[w].spec,s,t,d[w].componentTag,c)}if(window.lnCore._debugSink&&(r||a)&&window.lnCore._debugSink("attr",t,c,{oldValue:e.oldValue,newValue:c.getAttribute(t)}),r){const d=i.byReactive.get(t);d&&Re(d,c,t,e.oldValue),i.reactiveWildcard.length&&Re(i.reactiveWildcard,c,t,e.oldValue)}if(a)for(let d=0;d<a.length;d++){const s=a[d];if(s.handler){s.handler(c,t,e.oldValue);continue}s.onAttributeChange&&c[s.attribute]?s.onAttributeChange(c,t):(Le(c,s.selector,s.attribute,s.ComponentFn),s.onInit&&s.onInit(c))}}}function lt(){window.lnCore=window.lnCore||{},!window.lnCore._attrObserverBound&&(window.lnCore._attrObserverBound=!0,X(function(){new MutationObserver(function(t){for(let r=0;r<t.length;r++)try{st(t[r])}catch(i){console.error("[ln-core] mutation handler failed",t[r].target,i)}}).observe(document.body,{attributes:!0,subtree:!0,attributeOldValue:!0})},"ln-core"))}function ue(){return window.lnCore=window.lnCore||{},window.lnCore._lifecycleRegistry=window.lnCore._lifecycleRegistry||[]}function de(){return window.lnCore=window.lnCore||{},window.lnCore._subtreeRegistry=window.lnCore._subtreeRegistry||[]}function fe(e,t){if(!document.contains(e))if(t.attribute){const r=e[t.attribute];if(r&&typeof r.destroy=="function")try{r.destroy()}catch(i){console.error("["+t.attribute+"] destroy failed",e,i)}delete e[t.attribute]}else t.onDestroy&&t.onDestroy(e)}function Ne(e){const t=ue();if(!t.length)return;const r=e.target;if(r){const a=r.nodeType===1?r:r.parentElement;if(a&&(a.isContentEditable||a.closest&&a.closest('[contenteditable]:not([contenteditable="false"])')))return}const i=de();if(e.target&&i.length)for(let a=0;a<i.length;a++){const l=i[a],c=l.query,d=e.target.nodeType===1?e.target.matches&&e.target.matches(c)?e.target:e.target.closest?e.target.closest(c):null:e.target.parentElement&&e.target.parentElement.closest?e.target.parentElement.closest(c):null;d&&l.onSubtreeChange(d,e)}for(let a=0;a<e.addedNodes.length;a++){const l=e.addedNodes[a];if(l.nodeType===1){const c=!!(l.firstElementChild||l.children&&l.children.length);for(let d=0;d<t.length;d++){const s=t[d];if(s.selector&&s.attribute&&s.ComponentFn){if(!c)l.matches&&l.matches(s.query)&&W(l,s);else if(l.matches&&l.matches(s.query)&&W(l,s),l.querySelectorAll){const w=l.querySelectorAll(s.query);for(let b=0;b<w.length;b++)W(w[b],s)}}s.onInit&&s.onInit(l)}}}for(let a=0;a<e.removedNodes.length;a++){const l=e.removedNodes[a];if(l.nodeType===1){if(document.contains(l))continue;const c=!!(l.firstElementChild||l.children&&l.children.length);for(let d=0;d<t.length;d++){const s=t[d],w=s.query;if(w){if(!c)l.matches&&l.matches(w)&&fe(l,s);else if(l.matches&&l.matches(w)&&fe(l,s),l.querySelectorAll){const b=l.querySelectorAll(w);for(let _=0;_<b.length;_++)fe(b[_],s)}}}}}}function Te(){window.lnCore=window.lnCore||{},!window.lnCore._lifecycleObserverBound&&(window.lnCore._lifecycleObserverBound=!0,X(function(){const e=new MutationObserver(function(t){for(let r=0;r<t.length;r++){const i=t[r];if(i.type==="childList")try{Ne(i)}catch(a){console.error("[ln-core] lifecycle handler failed",i.target,a)}}});window.lnCore._lifecycleObserver=e,e.observe(document.body,{childList:!0,subtree:!0})},"ln-core"))}function ct(e){if(typeof window>"u")return e();window.lnCore=window.lnCore||{};const t=window.lnCore._lifecycleObserver;if(!t)return e();const r=t.takeRecords();for(let i=0;i<r.length;i++){const a=r[i];if(a.type==="childList")try{Ne(a)}catch(l){console.error("[ln-core] lifecycle handler failed",a.target,l)}}t.disconnect();try{return e()}finally{t.observe(document.body,{childList:!0,subtree:!0})}}function ut(e){ue().push(e),e.onSubtreeChange&&e.query&&de().push(e),Te()}function ze(e,t,r,i,a={}){const l=a.extraAttributes||[],c=a.onAttributeChange||null,d=a.onSubtreeChange||null,s=a.onInit||null,w=a.onAttrChange||null,b=a.effects||null,_=a.attributes||null,x=_?nt(_):b,M=_?new Set(Object.keys(_)):null,$=a.persist||null;function m(L){const D=L||document.body;if(Le(D,e,t,r),_&&be())for(const B in _){const ye=_[B],K=Array.from(D.querySelectorAll("["+B+"]"));D.matches&&D.matches("["+B+"]")&&K.push(D);for(let j=0;j<K.length;j++){const Q=K[j];oe(Q)&&qe(ye,Q.getAttribute(B),B,i,Q)}}s&&s(D)}const A=[];if(e.indexOf("[")!==-1){const L=/\[([\w-]+)/g;let D;for(;(D=L.exec(e))!==null;)A.push(D[1])}else A.push(e);at({selector:e,attribute:t,componentTag:i,attributes:_,ComponentFn:r,onInit:s,observed:A.concat(l),onAttributeChange:c,onAttrChange:w,effects:x,declared:M,persist:$}),lt();const I=e.indexOf("[")!==-1||e.indexOf(".")!==-1||e.indexOf("#")!==-1,k=a.subtreeQuery||(I?e:"["+e+"]"),v={selector:e,attribute:t,ComponentFn:r,onInit:s,onSubtreeChange:d,query:k};ue().push(v),d&&k&&de().push(v),Te(),window[t]=m,typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerComponent=ze,window.lnCore.observeLifecycle=ut,window.lnCore.withoutLifecycle=ct);function q(){ot()>0?it(function(){m(document.body)}):m(document.body)}return document.readyState==="loading"?document.addEventListener("DOMContentLoaded",q):q(),m}function dt(e){let t=!1;for(let r=0;r<e.length;r++){const i=e[r];if(!(i===""||i==null)&&(t=!0,!Number.isFinite(Number(i))))return"string"}return t?"number":"string"}function ft(e,t,r,i){if(r==="number"){const c=parseFloat(e),d=parseFloat(t);return(isNaN(c)?0:c)-(isNaN(d)?0:d)}const a=e!=null?String(e):"",l=t!=null?String(t):"";return i?i.compare(a,l):a<l?-1:a>l?1:0}function Oe(e){return(e||"").replace(/^#/,"")}function he(e){const t=e===void 0?location.hash:e,r={},i=Oe(t);if(!i)return r;const a=i.split("&");for(let l=0;l<a.length;l++){const c=a[l];if(!c)continue;const d=c.indexOf(":"),s=d>-1?c.slice(0,d):c,w=d>-1?c.slice(d+1):"";if(s)try{r[s]=decodeURIComponent(w)}catch{r[s]=w}}return r}function ht(e){if(!e)return null;const t=he();return e in t?t[e]:null}function wt(e,t){if(!e)return;const r=he();t==null?delete r[e]:r[e]=String(t);const a=Object.keys(r).map(function(l){const c=r[l];return c===""?l:l+":"+encodeURIComponent(c)}).join("&");Oe(location.hash)!==a&&(location.hash=a)}function yt(e){return e.button===1||e.ctrlKey||e.metaKey||e.shiftKey?!1:(e.preventDefault(),!0)}function pt(e,t){if(!e||!e.hasAttribute("data-ln-hash"))return null;const r=e.getAttribute("data-ln-hash");if(r&&r.trim()!=="")return r.trim();const i=e.getAttribute("data-ln-sort")||e.getAttribute("data-ln-search-for")||e.getAttribute("data-ln-search")||e.getAttribute("data-ln-filter")||e.id;return i?t?i+"-"+t:i:t||null}function mt(e,t){return!t||t==="none"||e===null||e===void 0?null:String(e)+"."+t}function gt(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 bt(e,t){return!e||!Array.isArray(t)||t.length===0?null:e+":"+t.map(encodeURIComponent).join(",")}function _t(e){if(!e||typeof e!="string")return null;const t=e.indexOf(":");if(t===-1)return null;const r=e.slice(0,t),i=e.slice(t+1),a=i?i.split(",").map(function(l){try{return decodeURIComponent(l)}catch{return l}}).filter(Boolean):[];return{key:r,values:a}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.hashParse=he,window.lnCore.hashGet=ht,window.lnCore.hashSet=wt,window.lnCore.hashLinkClick=yt,window.lnCore.resolveHashNamespace=pt,window.lnCore.hashSortEncode=mt,window.lnCore.hashSortDecode=gt,window.lnCore.hashFilterEncode=bt,window.lnCore.hashFilterDecode=_t);function Ct(e){return(e||"").replace(/^\?/,"")}function St(e){const t=e===void 0?typeof window<"u"?window.location.search:"":e,r={},i=Ct(t);if(!i)return r;const a=new URLSearchParams(i);for(const[l,c]of a.entries())r[l]=c;return r}function At(e){if(!e||typeof window>"u")return null;const t=new URLSearchParams(window.location.search);return t.has(e)?t.get(e):null}function vt(e,t){if(!e||typeof window>"u")return;const r=new URL(window.location.href);if(t==null||t===""?r.searchParams.delete(e):r.searchParams.set(e,String(t)),r.search===window.location.search)return;const i=r.pathname+r.search+r.hash;window.history.replaceState(window.history.state,"",i)}function xt(e,t){if(!e||!e.hasAttribute("data-ln-query"))return null;const r=e.getAttribute("data-ln-query");if(r&&r.trim()!=="")return r.trim();const i=e.getAttribute("data-ln-sort")||e.getAttribute("data-ln-search-for")||e.getAttribute("data-ln-search")||e.getAttribute("data-ln-filter")||e.id;return i?t?i+"_"+t:i:t||null}function kt(e,t){return!t||t==="none"||e===null||e===void 0?null:String(e)+"."+t}function qt(e,t){if(e&&typeof e=="string"){if(e.endsWith(".asc"))return{fieldOrColumn:e.slice(0,-4),direction:"asc"};if(e.endsWith(".desc"))return{fieldOrColumn:e.slice(0,-5),direction:"desc"}}if(t&&typeof t=="object"){const r=t.sort_field||t.sort_by;if(r){const i=t.sort_dir&&String(t.sort_dir).toLowerCase()==="desc"?"desc":"asc";return{fieldOrColumn:r,direction:i}}}return null}function Et(e){return!Array.isArray(e)||e.length===0?null:e.map(encodeURIComponent).join(",")}function It(e){return!e||typeof e!="string"?[]:e.split(",").map(function(t){try{return decodeURIComponent(t.trim())}catch{return t.trim()}}).filter(Boolean)}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.queryParse=St,window.lnCore.queryGet=At,window.lnCore.querySet=vt,window.lnCore.resolveQueryParam=xt,window.lnCore.querySortEncode=kt,window.lnCore.querySortDecode=qt,window.lnCore.queryFilterEncode=Et,window.lnCore.queryFilterDecode=It);let H=null;const Lt="ln-ashlar:storage-salt:v1",Pe=32768;function Fe(e){let t="";const r=e.byteLength;for(let i=0;i<r;i+=Pe)t+=String.fromCharCode.apply(null,e.subarray(i,Math.min(i+Pe,r)));return btoa(t)}function Me(e){const t=atob(e),r=t.length,i=new Uint8Array(r);for(let a=0;a<r;a++)i[a]=t.charCodeAt(a);return i}function Be(e,t){let r=H,i={};return typeof CryptoKey<"u"&&e instanceof CryptoKey?r=e:e&&typeof e=="object"&&(i=e,typeof CryptoKey<"u"&&i.key instanceof CryptoKey&&(r=i.key)),{key:r,options:i}}async function Dt(e,t={}){if(!e)throw new Error("[ln-crypto] Key derivation failed: Secret string is required");const r=t.method||"pbkdf2",i=new TextEncoder;if(r==="sha256"){const s=await crypto.subtle.digest("SHA-256",i.encode(e));return crypto.subtle.importKey("raw",s,{name:"AES-GCM"},!1,["encrypt","decrypt"])}const a=t.salt||Lt,l=typeof a=="string"?i.encode(a):a,c=t.iterations||1e5,d=await crypto.subtle.importKey("raw",i.encode(e),"PBKDF2",!1,["deriveKey"]);return crypto.subtle.deriveKey({name:"PBKDF2",salt:l,iterations:c,hash:"SHA-256"},d,{name:"AES-GCM",length:256},!1,["encrypt","decrypt"])}async function je(e,t={}){if(!e){H=null;return}try{const r=t.method||"sha256";H=await Dt(e,{...t,method:r})}catch(r){throw console.error("[ln-core/crypto] Key derivation failed:",r),H=null,r}}function F(){return H}async function Rt(e,t,r){const{key:i}=Be(t);if(e==null)return e;if(!i)throw new Error("[ln-crypto] Encryption failed: No active cryptographic key provided");try{const a=new TextEncoder,l=crypto.getRandomValues(new Uint8Array(12)),c=typeof e=="string"?e:JSON.stringify(e),d=await crypto.subtle.encrypt({name:"AES-GCM",iv:l},i,a.encode(c));return{v:1,alg:"AES-GCM",encrypted:!0,iv:Fe(l),data:Fe(new Uint8Array(d))}}catch(a){throw console.error("[ln-core/crypto] Encryption failed:",a),new Error("[ln-crypto] Encryption failed: "+(a&&a.message?a.message:String(a)))}}async function Nt(e,t,r){const{key:i,options:a}=Be(t),l=a.silent===!0;if(!e||!e.encrypted)return e;if(!i){if(l)return{...e,decryptionError:!0};throw new Error("[ln-crypto] Decryption failed: No active cryptographic key provided")}if(!e.iv||!e.data){if(l)return{...e,decryptionError:!0};throw new Error("[ln-crypto] Decryption failed: Malformed envelope (missing iv or data)")}try{const c=new TextDecoder,d=Me(e.iv),s=Me(e.data),w=await crypto.subtle.decrypt({name:"AES-GCM",iv:d},i,s),b=c.decode(w);try{return JSON.parse(b)}catch{return b}}catch(c){if(l)return{...e,decryptionError:!0};throw console.error("[ln-core/crypto] Decryption failed. Key may be incorrect or payload tampered:",c),new Error("[ln-crypto] Decryption failed. Key may be incorrect or payload tampered: "+(c&&c.message?c.message:String(c)))}}function Tt(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{const t=Math.random()*16|0;return(e==="x"?t:t&3|8).toString(16)})}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.uuid=Tt);function zt(e){return String(e||"").trim().toLowerCase()}function Ot(e){const t=zt(e);return t?t.split(/\s+/).filter(Boolean):[]}function Pt(e,t){if(!t||t.length===0)return!0;if(!e)return!1;const r=String(e).toLowerCase();for(let i=0;i<t.length;i++)if(r.indexOf(t[i])===-1)return!1;return!0}function Ft(e,t){if(!t||t.length===0)return!0;if(e==null)return!1;const r=String(e).trim().toLowerCase();for(let i=0;i<t.length;i++)if(String(t[i]).trim().toLowerCase()===r)return!0;return!1}function Mt(e={}){let t=e.windowSize>0?e.windowSize:1e3,r=e.pageSize>0?e.pageSize:200,i=e.fetchDebounce!=null?e.fetchDebounce:120;const a=typeof e.requestPage=="function"?e.requestPage:()=>{},l=new Map,c=new Set;let d=0,s=0,w=0,b=!1,_=null;function x(m,A){l.delete(m),l.set(m,A)}function M(){if(l.size<=t)return[];const m=[];for(;l.size>t;){const I=l.keys().next().value;m.push(l.get(I)),l.delete(I)}const A=new Set(l.values());return m.filter(I=>!A.has(I))}function $(m,A){c.add(m),clearTimeout(_),_=setTimeout(()=>a(m,r,A),i)}return{get logicalTotal(){return d},set logicalTotal(m){d=m},get grandTotal(){return s},set grandTotal(m){s=m},get queryGen(){return w},set queryGen(m){w=m},get size(){return l.size},get hasLoaded(){return b},getId:m=>{if(!l.has(m))return;const A=l.get(m);return x(m,A),A},ensure:(m,A,I)=>{if(!b&&!c.has(0))return $(0,I);if(d<=0)return;const k=Math.max(0,m),v=Math.min(d,A);for(let q=k;q<v;q++)if(!l.has(q)){const L=Math.floor(q/r)*r;if(!c.has(L))return $(L,I)}},ingest:(m,A,I,k,v)=>{if(v!=null&&v!==w)return[];b=!0,I!=null&&(s=I),k!=null&&(d=k);for(let q=0;q<A.length;q++)x(m+q,A[q]);return c.delete(m),M()},reset:function(){w++,this.clear()},clear:()=>{b=!1,l.clear(),c.clear(),clearTimeout(_)},configure:(m={})=>{let A=[];return m.windowSize>0&&m.windowSize!==t&&(t=m.windowSize,A=M()),m.pageSize>0&&(r=m.pageSize),m.fetchDebounce>=0&&(i=m.fetchDebounce),A}}}function Bt(e,t,r){if(!Array.isArray(e)||!t||!t.field)return e;const{field:i,direction:a}=t,l=a==="desc",c=e.map(s=>s?s[i]:void 0),d=dt(c);return[...e].sort((s,w)=>{const b=s?s[i]:void 0,_=w?w[i]:void 0,x=ft(b,_,d,r);return l?-x:x})}function we(e,t){if(!Array.isArray(e)||!t||typeof t!="object")return e;const r=Object.keys(t).filter(i=>Array.isArray(t[i])&&t[i].length>0);return r.length?e.filter(i=>i?r.every(a=>Ft(i[a],t[a])):!1):e}function jt(e,t,r){if(!Array.isArray(e)||!t||!r||!r.length)return e;const i=Ot(t);return i.length?e.filter(a=>a?i.every(l=>r.some(c=>{const d=a[c];return d!=null&&Pt(String(d),[l])})):!1):e}function $t(e,t,r){if(!Array.isArray(e)||!e.length)return 0;if(r==="count")return e.length;const i=e.map(l=>l&&l[t]!=null?parseFloat(l[t]):NaN).filter(l=>Number.isFinite(l)),a=i.reduce((l,c)=>l+c,0);return r==="sum"?a:r==="avg"&&i.length?a/i.length:0}function Kt(e,t={},r=[],i){if(!Array.isArray(e))return{records:[],total:0,filtered:0};const a=e.length;let l=e;t.filters&&(l=we(l,t.filters)),t.search&&(l=jt(l,t.search,r));const c=l.length;if(t.sort&&(l=Bt(l,t.sort,i)),t.offset||t.limit){const d=t.offset||0,s=t.limit||l.length;l=l.slice(d,d+s)}return{records:l,total:a,filtered:c}}function Ut(e,t){return!Array.isArray(e)||!t||typeof t!="object"?e:e.map(r=>{if(!r)return null;const i={...r};for(const[a,l]of Object.entries(t))if(typeof l=="function")try{i[a]=l(r)}catch{i[a]=void 0}return i})}function Gt(e,t,r,i="_meta"){if(!Array.isArray(e)||!e.includes(i))return!0;for(const a of Object.keys(t||{})){if(!e.includes(a))return!0;const l=t[a]&&t[a].indexes||[],c=r&&r[a]||[];if(l.some(d=>!c.includes(d)))return!0}return!1}function Vt(e){return{ok:!1,error:e&&e.message?e.message:String(e)}}function Wt(e){if(!e||typeof e!="string")return null;const t=e.trim();if(!t)return null;try{const r=JSON.parse(t);return Array.isArray(r)?r:null}catch{return null}}(function(){const e="data-ln-data-store",t="lnDataStore";if(window[t]!==void 0)return;function r(n,o,u){const f=n.getAttribute(o);if(f==="never"||f==="-1")return-1;const h=parseInt(f,10);return isNaN(h)?u:h}const i={"data-ln-data-store":{type:"marker",effect:Ke,description:"Identifies the element as a data-store definition container"},"data-ln-data-store-indexes":{type:"list",effect:Ke,description:"Comma-separated index field names for the IndexedDB store"},"data-ln-data-store-seed":{type:"string",description:"Selector or element ID of an external seed script block"},"data-ln-data-store-stale":{prop:"_staleThreshold",type:"integer",read:r,fallback:300,description:"Cache staleness threshold in seconds, or -1/never"},"data-ln-data-store-search-fields":{prop:"_searchFields",type:"list",read:le,description:"Record fields to index for client-side search"},"data-ln-data-store-no-local-query":{prop:"noLocalQuery",type:"boolean",read:se,description:"Bypasses local IndexedDB query resolution, forcing remote fetching"},"data-ln-data-store-window":{prop:"_windowSize",type:"integer",read:Y,fallback:1e3,min:10,effect:yn,description:"Virtual scrolling cache window size in records"},"data-ln-data-store-window-page":{prop:"_windowPageSize",type:"integer",read:Y,fallback:200,min:5,effect:pn,description:"Virtual scrolling slice page size"},"data-ln-data-store-frozen":{type:"marker",description:"Applied at runtime to indicate store schema is locked in IndexedDB"}},a=Ie(i),l="ln_app_cache",c="_meta",d="1.0";let s=null,w=null;const b={};function _(n){n&&n.name==="QuotaExceededError"&&C(document,"ln-data-store:quota-exceeded",{error:n})}function x(){const n={};for(const o of document.querySelectorAll(`[${e}]`)){const u=o.id;if(u){const f=o.getAttribute("data-ln-data-store-indexes")||"";n[u]={indexes:f.split(",").map(h=>h.trim()).filter(Boolean)}}}return n}function M(){return w||(w=new Promise(n=>{if(typeof indexedDB>"u")return console.warn("[ln-data-store] IndexedDB is not available in this environment"),n(null);const o=x(),u=Object.keys(o),f=indexedDB.open(l);f.onerror=()=>{console.warn("[ln-data-store] IndexedDB open failed"),n(null)},f.onsuccess=h=>{const y=h.target.result,p=Array.from(y.objectStoreNames),g=u.filter(N=>p.includes(N));let S={};if(g.length>0){const N=y.transaction(g,"readonly");for(const T of g)S[T]=Array.from(N.objectStore(T).indexNames)}if(!Gt(p,o,S,c))return $(y),s=y,n(y);const U=y.version;y.close();const P=indexedDB.open(l,U+1);let z=!1,O=null;P.onblocked=()=>{console.warn("[ln-data-store] Database upgrade blocked — waiting for other tabs to close connection"),C(document,"ln-data-store:blocked",{db:l}),O||(O=setTimeout(()=>{z||(console.warn("[ln-data-store] Database upgrade timed out while blocked"),z=!0,w=null,n(null))},5e3))},P.onerror=()=>{z||(O&&clearTimeout(O),z=!0,w=null,console.warn("[ln-data-store] Database upgrade failed"),n(null))},P.onupgradeneeded=N=>{const T=N.target.result,mn=N.target.transaction;T.objectStoreNames.contains(c)||T.createObjectStore(c,{keyPath:"key"});for(const Z of u)if(T.objectStoreNames.contains(Z)){const re=mn.objectStore(Z);for(const V of o[Z].indexes)re.indexNames.contains(V)||re.createIndex(V,V,{unique:!1})}else{const re=T.createObjectStore(Z,{keyPath:"id"});for(const V of o[Z].indexes)re.createIndex(V,V,{unique:!1})}},P.onsuccess=N=>{if(z){N.target.result&&N.target.result.close();return}O&&clearTimeout(O),z=!0;const T=N.target.result;$(T),s=T,n(T)}}}),w)}function $(n){n.onversionchange=()=>{n.close(),s=null,w=null}}function m(){return s?Promise.resolve(s):(w=null,M())}async function A(n){if(!F()||!n)return n;const o={...n},u=o.id,f=await Rt(o);return!f||!f.encrypted?n:{...f,id:u}}async function I(n){return!n||!n.encrypted||!F()?n:Nt(n,{silent:!0})}const k=(n,o)=>m().then(u=>u?u.transaction(n,o).objectStore(n):null);function v(n){return new Promise((o,u)=>{n.onsuccess=()=>o(n.result),n.onerror=()=>{_(n.error),u(n.error)}})}const q=n=>k(n,"readonly").then(o=>o?v(o.getAll()):[]).then(o=>F()?Promise.all(o.map(u=>I(u))):o),L=(n,o)=>k(n,"readonly").then(u=>u?v(u.get(o)).then(f=>f!==void 0?f:typeof o=="string"&&o.trim()!==""&&!isNaN(Number(o))?v(u.get(Number(o))):typeof o=="number"?v(u.get(String(o))):null):null).then(u=>u?I(u):null),D=(n,o)=>m().then(u=>{if(!u)return[];const h=u.transaction(n,"readonly").objectStore(n),y=o.map(p=>v(h.get(p)).then(g=>g!==void 0?g:typeof p=="string"&&p.trim()!==""&&!isNaN(Number(p))?v(h.get(Number(p))):typeof p=="number"?v(h.get(String(p))):null));return Promise.all(y).then(p=>F()?Promise.all(p.map(g=>g?I(g):null)):p)}),B=(n,o)=>(F()?A(o):Promise.resolve(o)).then(f=>k(n,"readwrite").then(h=>h?v(h.put(f)):null)),ye=(n,o)=>k(n,"readwrite").then(u=>u?v(u.delete(o)).then(()=>{if(typeof o=="string"&&o.trim()!==""&&!isNaN(Number(o)))return v(u.delete(Number(o)));if(typeof o=="number")return v(u.delete(String(o)))}):null),K=n=>k(n,"readwrite").then(o=>o?v(o.clear()):null),j=n=>k(n,"readonly").then(o=>o?v(o.count()):0),Q=n=>k(c,"readonly").then(o=>o?v(o.get(n)):null),J=(n,o)=>k(c,"readwrite").then(u=>{if(u)return o.key=n,v(u.put(o))});function R(n){return this.dom=n,this._name=n.id,this._name||console.warn("[ln-data-store] missing id — the store cannot be addressed",n),Ee(this,n,a),this._handlers=null,this.isLoaded=!1,this.canServe=!1,this.isInitialized=!1,this.initializationError=null,this.hasCache=!1,this.isSyncing=!1,this.lastSyncedAt=null,this.query={filters:{},search:"",sort:null},n.hasAttribute("data-ln-data-store-window")?this._windowIndex=Mt({windowSize:this._windowSize,pageSize:this._windowPageSize,requestPage:(o,u,f)=>{C(this.dom,"ln-data-store:request-page",{store:this._name,offset:o,limit:u,query:f,queryGen:this._windowIndex.queryGen})}}):this._windowIndex=null,this.windowed=this._windowIndex!==null,this.totalCount=0,this.presenters=null,this._mutationChain=Promise.resolve(),b[this._name]=this,Ht(this),this.ready=tn(this),this}function Ht(n){n._handlers={create:o=>ee(n,"create",o.detail,()=>Qt(n,o.detail)),update:o=>ee(n,"update",o.detail,()=>Jt(n,o.detail)),delete:o=>ee(n,"delete",o.detail,()=>Zt(n,o.detail)),"bulk-delete":o=>ee(n,"bulk-delete",o.detail,()=>Xt(n,o.detail)),"sync-failed":o=>{n.isSyncing=!1,C(n.dom,"ln-data-store:sync-error",{store:n._name,error:o.detail&&o.detail.error,status:o.detail&&o.detail.status})}};for(const[o,u]of Object.entries(n._handlers))n.dom.addEventListener(`ln-data-store:request-${o}`,u);n._queryHandlers={"ln-search:change":o=>{o.preventDefault();const u=o.detail&&o.detail.term!=null?o.detail.term:"";u!==n.query.search&&(n.query.search=u,ge(n))},"ln-filter:change":o=>{o.preventDefault();const u=o.detail&&o.detail.key;if(!u)return;const f=(o.detail.values||[]).slice(),h=n.query.filters[u];(h?h.length===f.length&&h.every((p,g)=>p===f[g]):!f.length)||(f.length?n.query.filters[u]=f:delete n.query.filters[u],ge(n))},"ln-sort:change":o=>{o.preventDefault();const u=o.detail&&o.detail.field,f=o.detail&&o.detail.direction,h=f&&f!=="none"?{field:u,direction:f}:null,y=n.query.sort;!y&&!h||y&&h&&y.field===h.field&&y.direction===h.direction||(n.query.sort=h,ge(n))}};for(const[o,u]of Object.entries(n._queryHandlers))n.dom.addEventListener(o,u)}function ee(n,o,u,f){const h=u&&u.requestId;return n._mutationChain=n._mutationChain.then(()=>n.ready).then(()=>{if(n.initializationError)throw n.initializationError;return f()}).catch(y=>Yt(n,o,h,y)),n._mutationChain}function te(n,o=0){return j(n._name).then(u=>{if(n._windowIndex||n.windowed){const f=n.totalCount!=null?n.totalCount:u;n.totalCount=Math.max(0,f+o)}else n.totalCount=u;return n.hasCache=!0,n.isLoaded=!0,n.canServe=!0,J(n._name,{schema_version:d,last_synced_at:n.lastSyncedAt,has_cache:!0,record_count:n.totalCount})})}function Qt(n,{tempId:o,data:u={},requestId:f}={}){const h={...u,id:o};return B(n._name,h).then(()=>te(n,1)).then(()=>{C(n.dom,"ln-data-store:created",{store:n._name,record:h,tempId:o,requestId:f})})}function Jt(n,{id:o,data:u={},requestId:f}={}){return L(n._name,o).then(h=>{if(!h)throw new Error(`Record not found: ${o}`);const y=h.id,p={...h,...u,id:y},g=u.id,S=g!==void 0&&g!==y;return(S?nn(n._name,y,{...p,id:g}):B(n._name,p)).then(()=>te(n,0)).then(()=>{C(n.dom,"ln-data-store:updated",{store:n._name,record:S?{...p,id:g}:p,previous:h,requestId:f})})})}function Zt(n,{id:o,requestId:u}={}){return L(n._name,o).then(f=>{if(!f){C(n.dom,"ln-data-store:deleted",{store:n._name,id:o,requestId:u,missing:!0});return}const h=f.id;return ye(n._name,h).then(()=>te(n,-1)).then(()=>{C(n.dom,"ln-data-store:deleted",{store:n._name,id:h,requestId:u})})})}function Xt(n,{ids:o=[],requestId:u}={}){return o.length?Promise.all(o.map(f=>L(n._name,f))).then(f=>{const h=f.filter(Boolean).map(y=>y.id);return ne(n._name,h).then(()=>te(n,-h.length)).then(()=>{C(n.dom,"ln-data-store:deleted",{store:n._name,ids:h,requestId:u})})}):(C(n.dom,"ln-data-store:deleted",{store:n._name,ids:[],requestId:u}),Promise.resolve())}function Yt(n,o,u,f){console.error("[ln-data-store] "+o+" failed:",f),C(n.dom,"ln-data-store:mutation-error",{store:n._name,action:o,requestId:u,error:f})}function en(n){let o=null;const u=n.dom.getAttribute("data-ln-data-store-seed");if(u&&(o=document.getElementById(u),!o))try{o=document.querySelector(u)}catch{}return o||(o=n.dom.querySelector('script[type="application/json"]')||n.dom.querySelector("script")),o&&o.textContent?Wt(o.textContent):null}function tn(n){const o=en(n);return n._seedRecords=o,o?(n.lastSyncedAt=Math.floor(Date.now()/1e3),n.totalCount=o.length,n.hasCache=!0,n.isLoaded=!0,n.canServe=!0,n.isInitialized=!0,setTimeout(()=>{C(n.dom,"ln-data-store:ready",{store:n._name,count:n.totalCount,source:"seed"}),C(n.dom,"ln-data-store:initialized",{store:n._name,hasCache:!0,lastSyncedAt:n.lastSyncedAt,count:n.totalCount,source:"seed"})},0),M().then(u=>{if(u)return K(n._name).then(()=>pe(n._name,o)).then(()=>J(n._name,{schema_version:d,last_synced_at:n.lastSyncedAt,has_cache:!0,record_count:n.totalCount}))}).catch(()=>{}),Promise.resolve({ok:!0,source:"seed"})):M().then(u=>{if(!u)throw new Error("IndexedDB is unavailable");return Q(n._name)}).then(u=>{if(!o)if(n.initializationError=null,u&&u.schema_version===d)n.lastSyncedAt=u.last_synced_at||null,n.totalCount=u.record_count||0,n.hasCache=u.has_cache===!0||n.totalCount>0,n.hasCache&&(n.isLoaded=!0,n.canServe=!0,C(n.dom,"ln-data-store:ready",{store:n._name,count:n.totalCount,source:"cache"})),n.isInitialized=!0,C(n.dom,"ln-data-store:initialized",{store:n._name,hasCache:n.hasCache,lastSyncedAt:n.lastSyncedAt,count:n.totalCount});else{if(u&&u.schema_version!==d)return K(n._name).then(()=>J(n._name,{schema_version:d,last_synced_at:null,has_cache:!1,record_count:0})).then(()=>{n.isInitialized=!0,n.hasCache=!1,C(n.dom,"ln-data-store:initialized",{store:n._name,hasCache:!1,lastSyncedAt:null,count:0})});n.isInitialized=!0,n.hasCache=!1,C(n.dom,"ln-data-store:initialized",{store:n._name,hasCache:!1,lastSyncedAt:null,count:0})}}).catch(u=>o?(n.lastSyncedAt=Math.floor(Date.now()/1e3),n.totalCount=o.length,n.hasCache=!0,n.isLoaded=!0,n.canServe=!0,n.isInitialized=!0,C(n.dom,"ln-data-store:ready",{store:n._name,count:n.totalCount,source:"seed"}),C(n.dom,"ln-data-store:initialized",{store:n._name,hasCache:!0,lastSyncedAt:n.lastSyncedAt,count:n.totalCount,source:"seed"}),{ok:!0,source:"seed"}):(n.isInitialized=!0,n.isLoaded=!1,n.canServe=!1,n.hasCache=!1,n.isSyncing=!1,n.initializationError=u,C(n.dom,"ln-data-store:initialization-error",{store:n._name,error:u}),{ok:!1,error:u}))}function $e(n){n.isSyncing=!0,C(n.dom,"ln-data-store:request-remote-sync",{since:n.lastSyncedAt})}function pe(n,o){return m().then(u=>u?(F()?Promise.all(o.map(h=>A(h))):Promise.resolve(o)).then(h=>new Promise((y,p)=>{const g=u.transaction(n,"readwrite"),S=g.objectStore(n);h.forEach(E=>S.put(E)),g.oncomplete=()=>y(),g.onerror=()=>{_(g.error),p(g.error)}})):void 0)}function ne(n,o){return m().then(u=>{if(u)return new Promise((f,h)=>{const y=u.transaction(n,"readwrite"),p=y.objectStore(n);o.forEach(g=>{p.delete(g),typeof g=="string"&&g.trim()!==""&&!isNaN(Number(g))?p.delete(Number(g)):typeof g=="number"&&p.delete(String(g))}),y.oncomplete=()=>f(),y.onerror=()=>h(y.error)})})}function nn(n,o,u){return(F()?A(u):Promise.resolve(u)).then(h=>m().then(y=>{if(y)return new Promise((p,g)=>{const S=y.transaction(n,"readwrite"),E=S.objectStore(n);E.put(h),E.delete(o),S.oncomplete=()=>p(),S.onerror=()=>{_(S.error),g(S.error)}})}))}const rn=new Intl.Collator(void 0,{numeric:!0,sensitivity:"base"});function on(n){return n?Object.keys(n).filter(o=>Array.isArray(n[o])&&n[o].length>0):[]}function an(n,o,u){return o.every(f=>u[f].map(String).includes(String(n[f])))}function sn(n){return String(n||"").toLowerCase().split(/\s+/).filter(Boolean)}function ln(n,o,u){return o.every(f=>u.some(h=>{const y=n[h];return y!=null&&String(y).toLowerCase().includes(f)}))}function cn(n,o,u){return $t(n,o,u)}function G(n,o){return Ut(o,n.presenters&&n.presenters.computed)}function un(n){return!n.sort&&!F()}function dn(n,o,u){const f=on(o.filters),h=o.search?sn(o.search):[],y=n._searchFields,p=h.length>0&&y&&y.length>0;return k(n._name,"readonly").then(g=>g?new Promise((S,E)=>{const U=[],P=g.openCursor();P.onsuccess=()=>{const z=P.result;if(!z||U.length>=u){S(U);return}const O=z.value;(!f.length||an(O,f,o.filters))&&(!p||ln(O,h,y))&&U.push(O),z.continue()},P.onerror=()=>E(P.error)}):[])}function me(n,o,u){return Kt(o,u,n._searchFields,rn)}function fn(n,o,u){const f=[];for(let y=o;y<o+u;y++){const p=n._windowIndex.getId(y);f.push(p)}const h=Array.from(new Set(f.filter(y=>y!==void 0)));return D(n._name,h).then(y=>{const p=new Map;for(let S=0;S<y.length;S++){const E=y[S];E&&p.set(String(E.id),E)}const g=[];for(let S=0;S<f.length;S++){const E=f[S];if(E===void 0)g.push(null);else{const U=p.get(String(E));g.push(U||null)}}return{data:G(n,g),total:n._windowIndex.grandTotal,filtered:n._windowIndex.logicalTotal,offset:o,queryGen:n._windowIndex.queryGen}})}R.prototype.getAll=function(n={}){const o=this;if(o._seedRecords){const u=me(o,o._seedRecords,n);return Promise.resolve({data:G(o,u.records),total:u.total,filtered:u.filtered})}if(o._windowIndex){const u=n.offset||0,f=n.limit||200;if(o._windowIndex.ensure(u,u+f,n),!o._windowIndex.hasLoaded&&!o.noLocalQuery){const h=u+f,y=p=>({data:G(o,p),offset:u,queryGen:o._windowIndex.queryGen,provisional:!0});return un(n)?dn(o,n,h).then(p=>y(p.slice(u,h))):q(o._name).then(p=>y(me(o,p,n).records))}return fn(o,u,f)}return q(o._name).then(u=>{const f=me(o,u,n);return{data:G(o,f.records),total:f.total,filtered:f.filtered}})},R.prototype.getById=function(n){return L(this._name,n).then(o=>o?G(this,[o])[0]:null)},R.prototype.count=function(n){if(this._seedRecords){const u=n&&Object.keys(n).length>0;return Promise.resolve(u?we(this._seedRecords,n).length:this._seedRecords.length)}return n&&Object.keys(n).length>0?q(this._name).then(u=>we(u,n).length):this.windowed&&this.totalCount!=null?Promise.resolve(this.totalCount):j(this._name)},R.prototype.aggregate=function(n,o){return q(this._name).then(u=>cn(u,n,o))},R.prototype.setPresenters=function(n){this.presenters=n},R.prototype.applySync=function(n,o,u,f){f=f||{};const h=this;if(h._windowIndex&&f.queryGen!=null&&f.queryGen!==h._windowIndex.queryGen)return Promise.resolve({ok:!0,stale:!0});let y=m().then(p=>{if(!p)throw new Error("IndexedDB unavailable")});return n.length>0&&(y=y.then(()=>pe(h._name,n))),o.length>0&&(y=y.then(()=>ne(h._name,o))),y.then(()=>{if(h._windowIndex&&(f.offset!=null||f.total!=null)){const p=f.offset!=null?f.offset:0,g=n.map(E=>E.id),S=h._windowIndex.ingest(p,g,f.total,f.filtered,f.queryGen);if(S&&S.length)return ne(h._name,S)}}).then(()=>j(h._name)).then(p=>(h.totalCount=f.total!==void 0?f.total:p,h.hasCache=!0,J(h._name,{schema_version:d,last_synced_at:u,has_cache:!0,record_count:h.totalCount}))).then(()=>{const p=!h.isLoaded;return h.isLoaded=!0,h.canServe=!0,h.isSyncing=!1,h.lastSyncedAt=u,p?(C(h.dom,"ln-data-store:loaded",{store:h._name,count:h.totalCount,meta:f}),C(h.dom,"ln-data-store:ready",{store:h._name,count:h.totalCount,source:"server",meta:f})):C(h.dom,"ln-data-store:synced",{store:h._name,added:n.length,deleted:o.length,changed:!0,meta:f}),{ok:!0}}).catch(p=>{h.isSyncing=!1;const g=p&&p.message?p.message:String(p);return console.error("[ln-data-store] applySync failed:",p),C(h.dom,"ln-data-store:sync-error",{store:h._name,error:g}),Vt(p)})},R.prototype.applyQuery=function(n,o){o=o||{};const u=this;let f=Promise.resolve();return n.length>0&&(f=f.then(()=>pe(u._name,n))),f.then(()=>j(u._name)).then(h=>(u.totalCount=o.total!==void 0?o.total:h,n.length>0&&(u.canServe=!0),G(u,n))).catch(h=>(console.error("[ln-data-store] applyQuery failed:",h),[]))},R.prototype.forceSync=function(){this.isSyncing||$e(this)},R.prototype.fullReload=function(){const n=this;return K(n._name).then(()=>J(n._name,{schema_version:d,last_synced_at:null,has_cache:!1,record_count:0})).then(()=>{n.isLoaded=!1,n.hasCache=!1,n.lastSyncedAt=null,n.totalCount=0,$e(n)})},R.prototype.destroy=function(){if(this._windowIndex&&(this._windowIndex.clear(),this._windowIndex=null,this.windowed=!1),this._handlers){for(const[n,o]of Object.entries(this._handlers))this.dom.removeEventListener(`ln-data-store:request-${n}`,o);this._handlers=null}if(this._queryHandlers){for(const[n,o]of Object.entries(this._queryHandlers))this.dom.removeEventListener(n,o);this._queryHandlers=null}delete b[this._name],delete this.dom[t]};function hn(){return m().then(n=>{if(!n)return;const o=Array.from(n.objectStoreNames);return new Promise((u,f)=>{const h=n.transaction(o,"readwrite");o.forEach(y=>h.objectStore(y).clear()),h.oncomplete=()=>u(),h.onerror=()=>f(h.error)})}).then(()=>{Object.values(b).forEach(n=>{n.isLoaded=!1,n.canServe=!1,n.isInitialized=!1,n.initializationError=null,n.hasCache=!1,n.isSyncing=!1,n.lastSyncedAt=null,n.totalCount=0})})}function ge(n){n._windowIndex&&n._windowIndex.reset(),C(n.dom,"ln-data-store:query-changed",{store:n._name,query:{filters:Object.assign({},n.query.filters),search:n.query.search,sort:n.query.sort?Object.assign({},n.query.sort):null}})}const wn="data-ln-data-store-frozen";function Ke(n,o){n.setAttribute(wn,o)}function yn(n){const o=n[t];if(!o._windowIndex)return;const u=o._windowIndex.configure({windowSize:o._windowSize});u.length&&ne(o._name,u).catch(f=>{console.error("[ln-data-store] window shrink eviction failed:",f)})}function pn(n){const o=n[t];o._windowIndex&&o._windowIndex.configure({pageSize:o._windowPageSize})}ze(e,t,R,"ln-data-store",{attributes:i}),window[t].clearAll=hn,window[t].init=window[t],window[t].setStorageKey=je,typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.setStorageKey=je)})()})();
|
|
@@ -1,84 +1,92 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$comment": "This file is partly generated. The $comment, component, generator, and each attribute's direction, sources, type, values, fallback, and description keys are owned by the generator and synchronized from JS source code. All other keys are preserved and safe to hand-author. Regenerate with `npm run sync:ln-schemas`.",
|
|
3
|
-
"component": "ln-data-store",
|
|
4
|
-
"generator": "scripts/sync-ln-schemas.mjs",
|
|
5
|
-
"attributes": {
|
|
6
|
-
"data-ln-data-store": {
|
|
7
|
-
"direction": "author",
|
|
8
|
-
"sources": [
|
|
9
|
-
"ln-data-store-dev.scss",
|
|
10
|
-
"src/ln-data-store.js"
|
|
11
|
-
],
|
|
12
|
-
"type": "marker",
|
|
13
|
-
"description": "Identifies the element as a data-store definition container"
|
|
14
|
-
},
|
|
15
|
-
"data-ln-data-store-frozen": {
|
|
16
|
-
"direction": "runtime",
|
|
17
|
-
"sources": [
|
|
18
|
-
"ln-data-store-dev.scss",
|
|
19
|
-
"src/ln-data-store.js"
|
|
20
|
-
],
|
|
21
|
-
"type": "marker",
|
|
22
|
-
"description": "Applied at runtime to indicate store schema is locked in IndexedDB"
|
|
23
|
-
},
|
|
24
|
-
"data-ln-data-store-indexes": {
|
|
25
|
-
"direction": "author",
|
|
26
|
-
"sources": [
|
|
27
|
-
"src/ln-data-store.js"
|
|
28
|
-
],
|
|
29
|
-
"type": "list",
|
|
30
|
-
"description": "Comma-separated index field names for the IndexedDB store"
|
|
31
|
-
},
|
|
32
|
-
"data-ln-data-store-no-local-query": {
|
|
33
|
-
"direction": null,
|
|
34
|
-
"sources": [
|
|
35
|
-
"src/ln-data-store.js"
|
|
36
|
-
],
|
|
37
|
-
"type": "boolean",
|
|
38
|
-
"description": "Bypasses local IndexedDB query resolution, forcing remote fetching"
|
|
39
|
-
},
|
|
40
|
-
"data-ln-data-store-search-fields": {
|
|
41
|
-
"direction": null,
|
|
42
|
-
"sources": [
|
|
43
|
-
"src/ln-data-store.js"
|
|
44
|
-
],
|
|
45
|
-
"type": "list",
|
|
46
|
-
"description": "Record fields to index for client-side search"
|
|
47
|
-
},
|
|
48
|
-
"data-ln-data-store-
|
|
49
|
-
"direction":
|
|
50
|
-
"sources": [
|
|
51
|
-
"src/ln-data-store.js"
|
|
52
|
-
],
|
|
53
|
-
"type": "
|
|
54
|
-
"
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
"
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
"
|
|
63
|
-
"
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
"
|
|
73
|
-
"
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"$comment": "This file is partly generated. The $comment, component, generator, and each attribute's direction, sources, type, values, fallback, and description keys are owned by the generator and synchronized from JS source code. All other keys are preserved and safe to hand-author. Regenerate with `npm run sync:ln-schemas`.",
|
|
3
|
+
"component": "ln-data-store",
|
|
4
|
+
"generator": "scripts/sync-ln-schemas.mjs",
|
|
5
|
+
"attributes": {
|
|
6
|
+
"data-ln-data-store": {
|
|
7
|
+
"direction": "author",
|
|
8
|
+
"sources": [
|
|
9
|
+
"ln-data-store-dev.scss",
|
|
10
|
+
"src/ln-data-store.js"
|
|
11
|
+
],
|
|
12
|
+
"type": "marker",
|
|
13
|
+
"description": "Identifies the element as a data-store definition container"
|
|
14
|
+
},
|
|
15
|
+
"data-ln-data-store-frozen": {
|
|
16
|
+
"direction": "runtime",
|
|
17
|
+
"sources": [
|
|
18
|
+
"ln-data-store-dev.scss",
|
|
19
|
+
"src/ln-data-store.js"
|
|
20
|
+
],
|
|
21
|
+
"type": "marker",
|
|
22
|
+
"description": "Applied at runtime to indicate store schema is locked in IndexedDB"
|
|
23
|
+
},
|
|
24
|
+
"data-ln-data-store-indexes": {
|
|
25
|
+
"direction": "author",
|
|
26
|
+
"sources": [
|
|
27
|
+
"src/ln-data-store.js"
|
|
28
|
+
],
|
|
29
|
+
"type": "list",
|
|
30
|
+
"description": "Comma-separated index field names for the IndexedDB store"
|
|
31
|
+
},
|
|
32
|
+
"data-ln-data-store-no-local-query": {
|
|
33
|
+
"direction": null,
|
|
34
|
+
"sources": [
|
|
35
|
+
"src/ln-data-store.js"
|
|
36
|
+
],
|
|
37
|
+
"type": "boolean",
|
|
38
|
+
"description": "Bypasses local IndexedDB query resolution, forcing remote fetching"
|
|
39
|
+
},
|
|
40
|
+
"data-ln-data-store-search-fields": {
|
|
41
|
+
"direction": null,
|
|
42
|
+
"sources": [
|
|
43
|
+
"src/ln-data-store.js"
|
|
44
|
+
],
|
|
45
|
+
"type": "list",
|
|
46
|
+
"description": "Record fields to index for client-side search"
|
|
47
|
+
},
|
|
48
|
+
"data-ln-data-store-seed": {
|
|
49
|
+
"direction": "author",
|
|
50
|
+
"sources": [
|
|
51
|
+
"src/ln-data-store.js"
|
|
52
|
+
],
|
|
53
|
+
"type": "string",
|
|
54
|
+
"description": "Selector or element ID of an external seed script block"
|
|
55
|
+
},
|
|
56
|
+
"data-ln-data-store-stale": {
|
|
57
|
+
"direction": null,
|
|
58
|
+
"sources": [
|
|
59
|
+
"src/ln-data-store.js"
|
|
60
|
+
],
|
|
61
|
+
"type": "integer",
|
|
62
|
+
"fallback": 300,
|
|
63
|
+
"description": "Cache staleness threshold in seconds, or -1/never"
|
|
64
|
+
},
|
|
65
|
+
"data-ln-data-store-window": {
|
|
66
|
+
"direction": "author",
|
|
67
|
+
"sources": [
|
|
68
|
+
"src/ln-data-store.js"
|
|
69
|
+
],
|
|
70
|
+
"type": "integer",
|
|
71
|
+
"fallback": 1000,
|
|
72
|
+
"min": 10,
|
|
73
|
+
"description": "Virtual scrolling cache window size in records"
|
|
74
|
+
},
|
|
75
|
+
"data-ln-data-store-window-page": {
|
|
76
|
+
"direction": null,
|
|
77
|
+
"sources": [
|
|
78
|
+
"src/ln-data-store.js"
|
|
79
|
+
],
|
|
80
|
+
"type": "integer",
|
|
81
|
+
"fallback": 200,
|
|
82
|
+
"min": 5,
|
|
83
|
+
"description": "Virtual scrolling slice page size"
|
|
84
|
+
},
|
|
85
|
+
"data-ln-debug": {
|
|
86
|
+
"direction": null,
|
|
87
|
+
"sources": [
|
|
88
|
+
"ln-data-store-dev.scss"
|
|
89
|
+
]
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -182,3 +182,20 @@ export function normalizeSyncError(err) {
|
|
|
182
182
|
const errorMsg = (err && err.message) ? err.message : String(err);
|
|
183
183
|
return { ok: false, error: errorMsg };
|
|
184
184
|
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Parses raw JSON seed string into an array of record objects.
|
|
188
|
+
* @param {string} raw
|
|
189
|
+
* @returns {Array<Record<string, any>> | null}
|
|
190
|
+
*/
|
|
191
|
+
export function parseSeedRecords(raw) {
|
|
192
|
+
if (!raw || typeof raw !== 'string') return null;
|
|
193
|
+
const trimmed = raw.trim();
|
|
194
|
+
if (!trimmed) return null;
|
|
195
|
+
try {
|
|
196
|
+
const parsed = JSON.parse(trimmed);
|
|
197
|
+
return Array.isArray(parsed) ? parsed : null;
|
|
198
|
+
} catch (_) {
|
|
199
|
+
return null;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { registerComponent, dispatch, setCryptoKey, getCryptoKey, encryptData, decryptData, defineAttrs, attrSpec, attrInt, attrBool, attrList } from '../../ln-core';
|
|
2
2
|
import { createWindowIndex } from './window-index.js';
|
|
3
|
-
import { aggregateRecords, decorateRecords, filterRecords, queryRecords, checkNeedsUpgrade, normalizeSyncError } from './data-store-model.js';
|
|
3
|
+
import { aggregateRecords, decorateRecords, filterRecords, queryRecords, checkNeedsUpgrade, normalizeSyncError, parseSeedRecords } from './data-store-model.js';
|
|
4
4
|
|
|
5
5
|
(function () {
|
|
6
6
|
const DOM_SELECTOR = 'data-ln-data-store';
|
|
@@ -21,6 +21,7 @@ import { aggregateRecords, decorateRecords, filterRecords, queryRecords, checkNe
|
|
|
21
21
|
const ATTRIBUTES = {
|
|
22
22
|
'data-ln-data-store': { type: 'marker', effect: _markFrozen, description: 'Identifies the element as a data-store definition container' },
|
|
23
23
|
'data-ln-data-store-indexes': { type: 'list', effect: _markFrozen, description: 'Comma-separated index field names for the IndexedDB store' },
|
|
24
|
+
'data-ln-data-store-seed': { type: 'string', description: 'Selector or element ID of an external seed script block' },
|
|
24
25
|
'data-ln-data-store-stale': { prop: '_staleThreshold', type: 'integer', read: _readStale, fallback: 300, description: 'Cache staleness threshold in seconds, or -1/never' },
|
|
25
26
|
'data-ln-data-store-search-fields': { prop: '_searchFields', type: 'list', read: attrList, description: 'Record fields to index for client-side search' },
|
|
26
27
|
'data-ln-data-store-no-local-query': { prop: 'noLocalQuery', type: 'boolean', read: attrBool, description: 'Bypasses local IndexedDB query resolution, forcing remote fetching' },
|
|
@@ -515,11 +516,63 @@ import { aggregateRecords, decorateRecords, filterRecords, queryRecords, checkNe
|
|
|
515
516
|
|
|
516
517
|
// ─── Initialization ────────────────────────────────────
|
|
517
518
|
|
|
519
|
+
function _readSeedRecords(self) {
|
|
520
|
+
let scriptEl = null;
|
|
521
|
+
const seedSelector = self.dom.getAttribute('data-ln-data-store-seed');
|
|
522
|
+
if (seedSelector) {
|
|
523
|
+
scriptEl = document.getElementById(seedSelector);
|
|
524
|
+
if (!scriptEl) {
|
|
525
|
+
try {
|
|
526
|
+
scriptEl = document.querySelector(seedSelector);
|
|
527
|
+
} catch (_) {}
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
if (!scriptEl) {
|
|
531
|
+
scriptEl = self.dom.querySelector('script[type="application/json"]') || self.dom.querySelector('script');
|
|
532
|
+
}
|
|
533
|
+
if (scriptEl && scriptEl.textContent) {
|
|
534
|
+
return parseSeedRecords(scriptEl.textContent);
|
|
535
|
+
}
|
|
536
|
+
return null;
|
|
537
|
+
}
|
|
538
|
+
|
|
518
539
|
function _initStore(self) {
|
|
540
|
+
const seedRecords = _readSeedRecords(self);
|
|
541
|
+
self._seedRecords = seedRecords;
|
|
542
|
+
|
|
543
|
+
if (seedRecords) {
|
|
544
|
+
self.lastSyncedAt = Math.floor(Date.now() / 1000);
|
|
545
|
+
self.totalCount = seedRecords.length;
|
|
546
|
+
self.hasCache = true;
|
|
547
|
+
self.isLoaded = true;
|
|
548
|
+
self.canServe = true;
|
|
549
|
+
self.isInitialized = true;
|
|
550
|
+
setTimeout(() => {
|
|
551
|
+
dispatch(self.dom, 'ln-data-store:ready', { store: self._name, count: self.totalCount, source: 'seed' });
|
|
552
|
+
dispatch(self.dom, 'ln-data-store:initialized', { store: self._name, hasCache: true, lastSyncedAt: self.lastSyncedAt, count: self.totalCount, source: 'seed' });
|
|
553
|
+
}, 0);
|
|
554
|
+
|
|
555
|
+
// Persist seed asynchronously to IndexedDB in background without blocking immediate queries
|
|
556
|
+
_openDatabase().then(db => {
|
|
557
|
+
if (!db) return;
|
|
558
|
+
return _clearStore(self._name)
|
|
559
|
+
.then(() => _putBulk(self._name, seedRecords))
|
|
560
|
+
.then(() => _setMeta(self._name, {
|
|
561
|
+
schema_version: SCHEMA_VERSION,
|
|
562
|
+
last_synced_at: self.lastSyncedAt,
|
|
563
|
+
has_cache: true,
|
|
564
|
+
record_count: self.totalCount
|
|
565
|
+
}));
|
|
566
|
+
}).catch(() => {});
|
|
567
|
+
|
|
568
|
+
return Promise.resolve({ ok: true, source: 'seed' });
|
|
569
|
+
}
|
|
570
|
+
|
|
519
571
|
return _openDatabase().then(db => {
|
|
520
572
|
if (!db) throw new Error('IndexedDB is unavailable');
|
|
521
573
|
return _getMeta(self._name);
|
|
522
574
|
}).then(meta => {
|
|
575
|
+
if (seedRecords) return;
|
|
523
576
|
self.initializationError = null;
|
|
524
577
|
if (meta && meta.schema_version === SCHEMA_VERSION) {
|
|
525
578
|
self.lastSyncedAt = meta.last_synced_at || null;
|
|
@@ -548,6 +601,17 @@ import { aggregateRecords, decorateRecords, filterRecords, queryRecords, checkNe
|
|
|
548
601
|
dispatch(self.dom, 'ln-data-store:initialized', { store: self._name, hasCache: false, lastSyncedAt: null, count: 0 });
|
|
549
602
|
}
|
|
550
603
|
}).catch(error => {
|
|
604
|
+
if (seedRecords) {
|
|
605
|
+
self.lastSyncedAt = Math.floor(Date.now() / 1000);
|
|
606
|
+
self.totalCount = seedRecords.length;
|
|
607
|
+
self.hasCache = true;
|
|
608
|
+
self.isLoaded = true;
|
|
609
|
+
self.canServe = true;
|
|
610
|
+
self.isInitialized = true;
|
|
611
|
+
dispatch(self.dom, 'ln-data-store:ready', { store: self._name, count: self.totalCount, source: 'seed' });
|
|
612
|
+
dispatch(self.dom, 'ln-data-store:initialized', { store: self._name, hasCache: true, lastSyncedAt: self.lastSyncedAt, count: self.totalCount, source: 'seed' });
|
|
613
|
+
return { ok: true, source: 'seed' };
|
|
614
|
+
}
|
|
551
615
|
self.isInitialized = true;
|
|
552
616
|
self.isLoaded = false;
|
|
553
617
|
self.canServe = false;
|
|
@@ -752,6 +816,14 @@ import { aggregateRecords, decorateRecords, filterRecords, queryRecords, checkNe
|
|
|
752
816
|
|
|
753
817
|
_component.prototype.getAll = function (options = {}) {
|
|
754
818
|
const self = this;
|
|
819
|
+
if (self._seedRecords) {
|
|
820
|
+
const r = _queryLocal(self, self._seedRecords, options);
|
|
821
|
+
return Promise.resolve({
|
|
822
|
+
data: _decorate(self, r.records),
|
|
823
|
+
total: r.total,
|
|
824
|
+
filtered: r.filtered
|
|
825
|
+
});
|
|
826
|
+
}
|
|
755
827
|
if (self._windowIndex) {
|
|
756
828
|
const offset = options.offset || 0;
|
|
757
829
|
const limit = options.limit || 200;
|
|
@@ -807,6 +879,10 @@ import { aggregateRecords, decorateRecords, filterRecords, queryRecords, checkNe
|
|
|
807
879
|
};
|
|
808
880
|
|
|
809
881
|
_component.prototype.count = function (filters) {
|
|
882
|
+
if (this._seedRecords) {
|
|
883
|
+
const hasFilters = filters && Object.keys(filters).length > 0;
|
|
884
|
+
return Promise.resolve(hasFilters ? filterRecords(this._seedRecords, filters).length : this._seedRecords.length);
|
|
885
|
+
}
|
|
810
886
|
const hasFilters = filters && Object.keys(filters).length > 0;
|
|
811
887
|
if (!hasFilters) {
|
|
812
888
|
if (this.windowed && this.totalCount != null) return Promise.resolve(this.totalCount);
|