@enigmax/dashboard 0.1.110 → 0.1.111

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/assets/index.html CHANGED
@@ -651,12 +651,15 @@
651
651
  .modal-back[hidden] { display: none; }
652
652
  .modal-back.pal-back { align-items: flex-start; padding-top: 12vh; }
653
653
  .modal.pal { max-width: 520px; padding: 12px; }
654
+ /* WebKit's own clear cross, on every search field. Where we want one we draw it
655
+ ourselves, so the platform's is a second cross for WebKit users only. */
656
+ input[type="search"]::-webkit-search-cancel-button,
657
+ input[type="search"]::-webkit-search-decoration { -webkit-appearance: none; appearance: none; }
654
658
  .pal-input {
655
659
  width: 100%; background: transparent; color: var(--text); border: none; border-bottom: 1px solid var(--border);
656
660
  padding: 8px 6px 12px; font-size: 14px; font-family: var(--mono);
657
661
  }
658
662
  .pal-input:focus { outline: none; }
659
- .pal-input::-webkit-search-cancel-button { display: none; }
660
663
  .pal-list { max-height: 46vh; overflow-y: auto; overscroll-behavior: contain; margin-top: 8px; }
661
664
  .pal-gt {
662
665
  font-family: var(--mono); font-size: 9.5px; font-weight: 600; text-transform: uppercase; letter-spacing: 1.4px;
@@ -671,7 +674,7 @@
671
674
  .pal-row .pal-hint { margin-left: auto; font-family: var(--mono); font-size: 11px; opacity: .6; }
672
675
  .pal-row.sel { background: var(--surface2); color: var(--text); }
673
676
  .pal-row.sel .tab-ic { opacity: 1; color: var(--accent); }
674
- .pal-empty { padding: 18px 8px; color: var(--muted); font-size: 13px; }
677
+ .pal-empty { padding: 18px 8px; color: var(--muted); font-size: 13px; overflow-wrap: anywhere; }
675
678
  .pal-foot {
676
679
  display: flex; gap: 14px; padding: 10px 8px 2px; border-top: 1px solid var(--border-soft);
677
680
  font-family: var(--mono); font-size: 10.5px; color: var(--muted); opacity: .7;
@@ -2469,6 +2472,11 @@ export {
2469
2472
  };
2470
2473
  </script>
2471
2474
  <script src="/lib/chart.min.js"></script>
2475
+ <!-- The framework-agnostic half of @enigmax/primitives, vendored beside Chart.js by
2476
+ scripts/sync-primitives.mjs. The dashboard writes its own DOM; what it takes from
2477
+ the package is the search engine, the keyboard arithmetic, the grouping and the
2478
+ history - all of which it used to hand-roll. -->
2479
+ <script src="/lib/enigma-primitives.js"></script>
2472
2480
  <script>
2473
2481
  const POLL_MS = 5000;
2474
2482
  const DAY = 86400000;
@@ -4620,7 +4628,7 @@ export {
4620
4628
  : "";
4621
4629
  return '<div class="gate-run"><div class="gate-run-h">'
4622
4630
  + '<span class="gate-run-b">' + esc(r.branch) + "</span>"
4623
- + '<span class="cstatus ' + (r.status === "completed" ? "ok" : r.status === "running" ? "orange" : r.status === "failed" ? "bad" : "") + '"><span class="cdot"></span>' + esc(r.status) + (r.awaitingAgent ? " · parked" : "") + "</span>"
4631
+ + '<span class="cstatus ' + (r.status === "completed" ? "ok" : r.status === "running" ? "orange" : r.status === "failed" ? "bad" : "") + '"><span class="cdot"></span>' + esc(r.status) + (r.blockedReason ? " · needs you: " + esc(r.blockedReason) : r.awaitingAgent ? " · parked" : "") + "</span>"
4624
4632
  + '<span class="gate-run-meta">' + esc(r.headSha) + pr + "</span>"
4625
4633
  + '<span style="flex:1"></span>' + stop
4626
4634
  + "</div>" + '<div class="gate-steps">' + steps + "</div>"
@@ -5052,30 +5060,41 @@ export {
5052
5060
  // Palette"). enigma: the dashboard is a single dependency-free HTML file served over
5053
5061
  // loopback, so the ~20-line matcher below stands in for fuse.js - upgrade to fuse.js
5054
5062
  // if this page ever gains a build step.
5063
+ // Guarded rather than destructured outright: this page is ONE script, so a missing
5064
+ // vendored file would throw here and take every panel below it with it - which is
5065
+ // exactly how the README's preview render came out with "-" in every card. Only the
5066
+ // four things called at MODULE scope need a stand-in; the rest are called from
5067
+ // handlers, where a failure is contained to the palette that is already degraded.
5068
+ const primitives = window.EnigmaPrimitives || {};
5069
+ const { moveActive, groupRows, isPaletteShortcut } = primitives;
5070
+ const subsequenceMatcher = primitives.subsequenceMatcher || (() => undefined);
5071
+ // The empty state quotes what was typed, and what was typed is arbitrary: a pasted
5072
+ // string with no spaces in it has no break opportunity, so it runs out of the panel.
5073
+ const shortenQuery = primitives.shortenQuery || ((value) => value);
5074
+ const createSearch = primitives.createSearch || (() => ({ setItems() {}, search() {}, searchNow() {}, update() {}, destroy() {} }));
5075
+ const createRecentStore = primitives.createRecentStore || (() => ({ list: () => [], remember: () => [], forget: () => [], clear() {} }));
5076
+ const shortcutLabel = primitives.shortcutLabel || ((key) => "Ctrl " + key);
5055
5077
  const palBack = $("palBack"), palInput = $("palInput"), palList = $("palList");
5056
- const IS_MAC = /Mac|iPhone|iPad/.test(navigator.platform || navigator.userAgent);
5057
5078
  let palItems = [], palSel = 0, palReturnFocus = null;
5058
- $("palHint").textContent = IS_MAC ? "Cmd K" : "Ctrl K";
5079
+ $("palHint").textContent = shortcutLabel("K");
5059
5080
 
5060
5081
  /**
5061
- * Fuzzy rank of `query` inside `text`: -1 when the query is not a subsequence, otherwise
5062
- * a score that rewards consecutive runs and word starts. Beats a substring filter because
5063
- * "qgate" finds "Quality gate" and "plyg" finds "Playground", which .includes() cannot.
5082
+ * The palette's engine, from @enigmax/primitives: subsequence ranking (so "qgate"
5083
+ * finds "Quality gate" and "plyg" finds "Playground"), the debounce and the
5084
+ * cancellation. The scorer this replaced is the one the package now ships, so the
5085
+ * dashboard and every other consumer rank the same way.
5064
5086
  */
5065
- function palScore(query, text) {
5066
- const q = query.toLowerCase(), t = text.toLowerCase();
5067
- if (!q) return 0;
5068
- let at = 0, from = 0, score = 0, run = 0;
5069
- for (let i = 0; i < q.length; i++) {
5070
- at = t.indexOf(q[i], from);
5071
- if (at === -1) return -1;
5072
- run = (i > 0 && at === from) ? run + 1 : 0;
5073
- const wordStart = at === 0 || /[^a-z0-9]/.test(t[at - 1]);
5074
- score += 10 + run * 6 + (wordStart ? 8 : 0) - Math.min(at - from, 6);
5075
- from = at + 1;
5087
+ const palRecents = createRecentStore({ key: "enigma:dashboard:palette", limit: 5 });
5088
+ const palSearch = createSearch({
5089
+ keys: ["name", "kind"],
5090
+ matcher: subsequenceMatcher(["name", "kind"]),
5091
+ debounce: 0,
5092
+ onResults: (matches) => {
5093
+ palItems = matches.map((match) => match.item);
5094
+ palSel = 0;
5095
+ palPaint();
5076
5096
  }
5077
- return score;
5078
- }
5097
+ });
5079
5098
 
5080
5099
  /** Built from the live DOM on every open, so it can never drift from the rail or the scopes. */
5081
5100
  function palIndex() {
@@ -5105,36 +5124,59 @@ export {
5105
5124
 
5106
5125
  function palRender(query) {
5107
5126
  const q = query.trim();
5108
- const all = palIndex();
5109
- palItems = (!q ? all : all
5110
- .map((it) => ({ it, s: Math.max(palScore(q, it.name), palScore(q, it.kind + " " + it.name) - 4) }))
5111
- .filter((r) => r.s >= 0)
5112
- .sort((a, b) => b.s - a.s)
5113
- .map((r) => r.it));
5114
- palSel = 0;
5127
+ const index = palIndex();
5128
+ palSearch.setItems(index);
5129
+ if (!q) {
5130
+ // An empty query opens on what was run before, which is the shortcut on the
5131
+ // second visit. Anything no longer in the index is dropped rather than shown
5132
+ // as a row that goes nowhere.
5133
+ const remembered = palRecents.list()
5134
+ .map((entry) => index.find((item) => item.kind + "::" + item.name === entry.term))
5135
+ .filter(Boolean)
5136
+ .map((item) => ({ ...item, kind: "Recent" }));
5137
+ palItems = remembered.concat(index);
5138
+ palSel = 0;
5139
+ palPaint();
5140
+ return;
5141
+ }
5142
+ palSearch.searchNow(q);
5143
+ }
5144
+
5145
+ /** Draws whatever is in `palItems`, grouped. The selection is applied by palMove. */
5146
+ function palPaint() {
5115
5147
  if (!palItems.length) {
5116
- palList.innerHTML = '<div class="pal-empty">No view or project matches "' + esc(q) + '".</div>';
5148
+ palList.innerHTML = '<div class="pal-empty">No view or project matches "' + esc(shortenQuery(palInput.value)) + '".</div>';
5117
5149
  palInput.removeAttribute("aria-activedescendant");
5118
5150
  return;
5119
5151
  }
5120
- let html = "", kind = null;
5121
- palItems.forEach((it, i) => {
5122
- if (it.kind !== kind) { kind = it.kind; html += '<div class="pal-gt">' + esc(kind === "View" ? "Views" : "Switch scope") + "</div>"; }
5123
- html += '<div class="pal-row' + (i === 0 ? " sel" : "") + '" role="option" id="pal-o' + i + '"'
5124
- + ' aria-selected="' + (i === 0 ? "true" : "false") + '" data-i="' + i + '">'
5125
- + it.icon
5126
- + '<span class="pal-name">' + esc(it.name) + "</span>"
5127
- + (it.group ? '<span class="pal-hint">' + esc(it.group) + "</span>" : (it.hint ? '<span class="pal-hint">' + esc(it.hint) + "</span>" : ""))
5128
- + "</div>";
5129
- });
5130
- palList.innerHTML = html;
5152
+ // Grouped for the headings, but each row carries its FLAT index, so the arrows
5153
+ // run straight through a group boundary.
5154
+ const heading = (kind) => (kind === "View" ? "Views" : kind === "Recent" ? "Recent" : "Switch scope");
5155
+ palList.innerHTML = groupRows(palItems, (item) => item.kind).map((group) => (
5156
+ '<div class="pal-gt">' + esc(heading(group.label)) + "</div>"
5157
+ + group.rows.map(({ row, position }) =>
5158
+ '<div class="pal-row" role="option" id="pal-o' + position + '"'
5159
+ + ' aria-selected="false" data-i="' + position + '">'
5160
+ + row.icon
5161
+ + '<span class="pal-name">' + esc(row.name) + "</span>"
5162
+ + (row.group ? '<span class="pal-hint">' + esc(row.group) + "</span>"
5163
+ : (row.hint ? '<span class="pal-hint">' + esc(row.hint) + "</span>" : ""))
5164
+ + "</div>").join("")
5165
+ )).join("");
5131
5166
  palMove(0);
5132
5167
  }
5133
5168
 
5169
+ /**
5170
+ * Where the highlight lands. A key name goes through the package's own arithmetic -
5171
+ * it wraps, which in a short list is what the arrow keys are expected to do - and a
5172
+ * number is the pointer landing on a row directly.
5173
+ */
5134
5174
  function palMove(next) {
5135
5175
  if (!palItems.length) return;
5136
5176
  const rows = palList.querySelectorAll(".pal-row");
5137
- palSel = (next + palItems.length) % palItems.length;
5177
+ palSel = typeof next === "string"
5178
+ ? moveActive(palSel, palItems.length, next)
5179
+ : (next + palItems.length) % palItems.length;
5138
5180
  rows.forEach((r, i) => {
5139
5181
  const on = i === palSel;
5140
5182
  r.classList.toggle("sel", on);
@@ -5163,6 +5205,7 @@ export {
5163
5205
  function palRun() {
5164
5206
  const it = palItems[palSel];
5165
5207
  if (!it) return;
5208
+ palRecents.remember({ term: it.kind + "::" + it.name, label: it.name });
5166
5209
  palClose();
5167
5210
  setNav(false);
5168
5211
  it.run();
@@ -5175,8 +5218,7 @@ export {
5175
5218
  palBack.addEventListener("mousedown", (e) => { if (e.target === palBack) palClose(); });
5176
5219
  // Focus stays inside: the dialog holds one input and a list driven from it.
5177
5220
  palBack.addEventListener("keydown", (e) => {
5178
- if (e.key === "ArrowDown") { e.preventDefault(); palMove(palSel + 1); }
5179
- else if (e.key === "ArrowUp") { e.preventDefault(); palMove(palSel - 1); }
5221
+ if (e.key === "ArrowDown" || e.key === "ArrowUp" || e.key === "Home" || e.key === "End") { e.preventDefault(); palMove(e.key); }
5180
5222
  else if (e.key === "Enter") { e.preventDefault(); palRun(); }
5181
5223
  // Escape closes the topmost surface only: the drawer behind it stays open.
5182
5224
  else if (e.key === "Escape") { e.preventDefault(); e.stopPropagation(); palClose(); }
@@ -5184,7 +5226,7 @@ export {
5184
5226
  });
5185
5227
  document.addEventListener("keydown", (e) => {
5186
5228
  // Ctrl+K is the browser's own search-bar shortcut, so it has to be taken explicitly.
5187
- if (e.key.toLowerCase() !== "k" || !(IS_MAC ? e.metaKey : e.ctrlKey) || e.altKey) return;
5229
+ if (!isPaletteShortcut(e) || e.altKey) return;
5188
5230
  e.preventDefault();
5189
5231
  if (palBack.hidden) palOpen(); else palClose();
5190
5232
  });
@@ -0,0 +1,2 @@
1
+ /* @enigmax/primitives core, vendored by scripts/sync-primitives.mjs. Do not edit. */
2
+ "use strict";var EnigmaPrimitives=(()=>{var W=Object.defineProperty;var at=Object.getOwnPropertyDescriptor;var lt=Object.getOwnPropertyNames;var ct=Object.prototype.hasOwnProperty;var ut=(e,t)=>{for(var n in t)W(e,n,{get:t[n],enumerable:!0})},dt=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of lt(t))!ct.call(e,a)&&a!==n&&W(e,a,{get:()=>t[a],enumerable:!(o=at(t,a))||o.enumerable});return e};var ft=e=>dt(W({},"__esModule",{value:!0}),e);var Zt={};ut(Zt,{FLAG_CDN:()=>oe,FLAG_RATIO:()=>re,INPUT_ICON_PATHS:()=>_,SELECT_SEARCH_KEYS:()=>G,SERVER_NETWORK_STATE:()=>J,configureFlags:()=>qe,createButton:()=>Oe,createInput:()=>we,createMarquee:()=>ve,createNetworkMonitor:()=>Re,createNotifications:()=>ke,createRecentStore:()=>Ye,createSearch:()=>$,createSelect:()=>ot,ensureZone:()=>ee,estimatePasswordStrength:()=>Ae,flagAttributes:()=>Ze,flagConfig:()=>Ue,flagName:()=>ie,flagSrc:()=>se,flagView:()=>ae,generatePassword:()=>Ce,groupRows:()=>je,iconMarkup:()=>H,isPaletteShortcut:()=>Xe,moveActive:()=>We,normalizeDate:()=>te,normalizeFlagCode:()=>B,parseDuration:()=>ne,recentKey:()=>U,relativeTimeAttributes:()=>Fe,relativeTimeView:()=>De,resetFlagConfig:()=>Be,shortcutLabel:()=>Qe,shortenQuery:()=>Ee,subsequenceMatcher:()=>Te});var pt={speed:60,reverse:!1,vertical:!1,draggable:!0,hover:"off",decay:.12,manageStyles:!0,copies:"clone"},mt=24;function ve(e,t,n={}){let o={...pt,...n},a=0,i=Math.max(2,t.children.length),s=0,r=0,c=!1,g=!1,f=!1,h=0,T=0,v=!1,E=null,x=0,M=0,p=0,w=0,L=!1,m=0,b=typeof window.matchMedia=="function"?window.matchMedia("(prefers-reduced-motion: reduce)"):null,d=b?.matches??!1;function l(u){let S=o.hover??"off";return S==="off"?u:S==="pause"?0:typeof S=="number"?u*S:(u<0?-1:1)*Math.abs(S.speed)}function y(){if(d||g)return 0;let u=o.reverse?-o.speed:o.speed;return L?l(u):u}function I(u){return o.vertical?u.offsetHeight:u.offsetWidth}function O(u){return o.vertical?u.offsetTop:u.offsetLeft}function k(){o.manageStyles&&(e.style.overflow="hidden",e.style.touchAction=o.vertical?"pan-x":"pan-y",e.style.userSelect="none",e.style.webkitUserSelect="none",t.style.willChange="transform")}function C(){let u=o.vertical?0:-s,S=o.vertical?-s:0;t.style.transform=`translate3d(${u}px, ${S}px, 0)`}function N(){let u=t.children[0],S=t.children[1];if(!u)return 0;if(S){let A=O(S)-O(u);if(A>0)return A}return I(u)}function le(u){return u<=0?2:Math.min(mt,Math.max(2,Math.ceil(I(e)/u)+1))}function ce(u){let S=t.children[0];if(S){for(;t.children.length>u;)t.removeChild(t.lastElementChild);for(;t.children.length<u;){let A=S.cloneNode(!0);A.setAttribute("aria-hidden","true"),A.dataset.enigmaMarqueeCopy=String(t.children.length),t.appendChild(A)}}}function D(){if(f)return;let u=o.copies==="clone";u&&t.children.length<2&&ce(2);let S=N(),A=le(S);u&&t.children.length!==A&&(ce(A),S=N(),A=le(S));let j=S!==a||A!==i;a=S,A!==i&&(i=A,o.onCopyCountChange?.(A)),a>0&&(s=V(s)),C(),j&&o.onMeasure?.(a,i),R()}function V(u){return a<=0?u:(u%a+a)%a}function ue(u){if(h=0,f)return;let S=Math.min((u-T)/1e3,.05);if(T=u,v||(r+=(y()-r)*(1-Math.pow(o.decay,S)),s=V(s+r*S)),C(),!v&&Math.abs(r)<.01&&Math.abs(y())<.01){r=0,c=!1;return}h=requestAnimationFrame(ue)}function R(){f||c||(c=!0,T=performance.now(),h=requestAnimationFrame(ue))}function de(u){return o.vertical?u.clientY:u.clientX}function fe(u){u.pointerType!=="mouse"&&z(),!(!o.draggable||u.button>0||E!==null)&&(E=u.pointerId,v=!0,x=de(u),M=x,p=u.timeStamp,w=0,e.dataset.dragging="true",window.addEventListener("pointermove",Z),window.addEventListener("pointerup",F),window.addEventListener("pointercancel",F),R())}function Z(u){if(u.pointerId!==E)return;let S=de(u),A=S-x;x=S;let j=Math.max((u.timeStamp-p)/1e3,.001);p=u.timeStamp,w=Math.max(w,Math.abs(S-M)),s=V(s-A);let st=-A/j;r=r*.6+st*(1-.6)}function F(u){u.pointerId===E&&(E=null,v=!1,delete e.dataset.dragging,window.removeEventListener("pointermove",Z),window.removeEventListener("pointerup",F),window.removeEventListener("pointercancel",F),u.timeStamp-p>90&&(r=0),R())}function pe(u){w<=6||(u.preventDefault(),u.stopPropagation())}function me(u){w>6||o.onItemClick?.(u)}function ge(u){if(u.pointerType!=="mouse"){z();return}Date.now()-m<1e3||(L=!0,e.dataset.hovering="true",R())}function ye(){L=!1,delete e.dataset.hovering,R()}function z(){m=Date.now(),L&&(L=!1,delete e.dataset.hovering,R())}function he(u){d=u.matches,e.dataset.reducedMotion=String(d),R()}let Y=typeof ResizeObserver=="function"?new ResizeObserver(()=>D()):null;function rt(){var S;k(),e.dataset.enigmaMarquee="",e.dataset.reducedMotion=String(d),t.dataset.enigmaMarqueeTrack="";for(let A of Array.from(t.children))(S=A.dataset).enigmaMarqueeCopy??(S.enigmaMarqueeCopy="0");e.addEventListener("pointerdown",fe),e.addEventListener("pointerenter",ge),e.addEventListener("pointerleave",ye),e.addEventListener("touchstart",z,{passive:!0}),e.addEventListener("click",pe,!0),e.addEventListener("click",me),b?.addEventListener("change",he),Y?.observe(e);let u=t.children[0];u&&Y?.observe(u),D(),document.fonts?.ready.then(()=>D()),it()}function it(){for(let u of t.querySelectorAll("img")){if(u.complete)continue;let S=()=>{u.removeEventListener("load",S),u.removeEventListener("error",S),f||D()};u.addEventListener("load",S),u.addEventListener("error",S)}}return rt(),{get offset(){return s},get period(){return a},get copyCount(){return i},get dragging(){return v},get reducedMotion(){return d},update(u){let S=u.vertical!==void 0||u.manageStyles!==void 0;o={...o,...u},S&&k(),D()},measure:D,pause(){g=!0,R()},resume(){g=!1,R()},destroy(){f=!0,h&&cancelAnimationFrame(h),Y?.disconnect(),b?.removeEventListener("change",he),e.removeEventListener("pointerdown",fe),e.removeEventListener("pointerenter",ge),e.removeEventListener("pointerleave",ye),e.removeEventListener("touchstart",z),e.removeEventListener("click",pe,!0),e.removeEventListener("click",me),window.removeEventListener("pointermove",Z),window.removeEventListener("pointerup",F),window.removeEventListener("pointercancel",F)}}}var _={eye:["M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7-10-7-10-7Z","M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z"],eyeOff:["M10.6 5.2A9.8 9.8 0 0 1 12 5c6.5 0 10 7 10 7a17.6 17.6 0 0 1-3.2 4.2M6.2 6.2A17.7 17.7 0 0 0 2 12s3.5 7 10 7a9.6 9.6 0 0 0 4.2-.9","m2 2 20 20","M9.9 9.9a3 3 0 0 0 4.2 4.2"],generate:["m12 3 1.9 4.6L18.5 9.5 13.9 11.4 12 16l-1.9-4.6L5.5 9.5l4.6-1.9Z","M19 15l.8 2.2 2.2.8-2.2.8-.8 2.2-.8-2.2-2.2-.8 2.2-.8Z"],clear:["m6 6 12 12","m18 6-12 12"],search:["M11 4a7 7 0 1 0 0 14 7 7 0 0 0 0-14Z","m20 20-4.2-4.2"]};function H(e){return`<svg viewBox="0 0 24 24" width="1em" height="1em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${e.map(n=>`<path d="${n}"/>`).join("")}</svg>`}var gt=H(_.eye),yt=H(_.eyeOff);function be(e,t){return typeof e=="function"?e(t):e}function ht(e,t){typeof t=="string"?e.innerHTML=t:e.replaceChildren(t)}function we(e,t={}){let n={...t},o=!1,a=!1,i=null,s=!n.container,r=n.container??document.createElement("span"),c=new Map;function g(){return{input:e,revealed:o,locked:e.disabled||e.readOnly}}function f(){return typeof n.reveal=="object"?n.reveal:{}}function h(){let d=f();return{name:"reveal",label:l=>l.revealed?d.hideLabel??"Hide password":d.showLabel??"Show password",icon:l=>l.revealed?d.hideIcon??yt:d.showIcon??gt,pressed:l=>l.revealed,onSelect:()=>E(!o)}}function T(){return e.type==="password"||o&&e.dataset.enigmaInputReveal==="on"}function v(){let d=n.actions??[];return[...n.reveal!==!1&&T()&&!d.some(I=>I.name==="reveal")?[h()]:[],...d]}function E(d){if(!T()&&d)return;let l=x();o=d,e.type=d?"text":"password",e.dataset.enigmaInputReveal=d?"on":"off",p(),l&&(M(l),i!==null&&clearTimeout(i),i=setTimeout(()=>{i=null,!a&&document.activeElement===e&&M(l)},0)),n.onRevealChange?.(d)}function x(){if(document.activeElement!==e)return null;try{let{selectionStart:d,selectionEnd:l}=e;return d===null||l===null?null:[d,l]}catch{return null}}function M(d){try{e.setSelectionRange(d[0],d[1])}catch{}}function p(){if(a)return;let d=x(),l=g(),y=v(),I=new Set;for(let O of y){I.add(O.name);let k=O.visible?O.visible(l):!0,C=c.get(O.name);if(C||(C=document.createElement("button"),C.type="button",C.dataset.enigmaInputAction=O.name,c.set(O.name,C),r.append(C)),!k){C.remove(),c.delete(O.name);continue}C.isConnected||r.append(C);let N=be(O.label,l);C.setAttribute("aria-label",N),C.title=N,C.disabled=l.locked,O.pressed?C.setAttribute("aria-pressed",String(O.pressed(l))):C.removeAttribute("aria-pressed"),ht(C,be(O.icon,l))}for(let[O,k]of[...c])I.has(O)||(k.remove(),c.delete(O));if(r.hidden=c.size===0,d)try{e.setSelectionRange(d[0],d[1])}catch{}}function w(d){d.target?.closest("[data-enigma-input-action]")&&d.preventDefault()}function L(d){let l=d.target?.closest("[data-enigma-input-action]");if(!l)return;let y=v().find(I=>I.name===l.dataset.enigmaInputAction);y&&(d.preventDefault(),y.onSelect(g()))}let m=typeof MutationObserver=="function"?new MutationObserver(()=>{!T()&&o&&(o=!1),p()}):null;function b(){e.dataset.enigmaInput="",r.dataset.enigmaInputActions="",r.dataset.position=n.position??"end",s&&!r.isConnected&&((n.position??"end")==="start"?e.before(r):e.after(r)),r.addEventListener("mousedown",w),r.addEventListener("click",L),m?.observe(e,{attributes:!0,attributeFilter:["type","disabled","readonly"]}),p()}return b(),{get revealed(){return o},reveal(d){E(d??!o)},refresh:p,update(d){let l=d.position!==void 0&&d.position!==n.position;n={...n,...d},l&&s&&(r.dataset.position=n.position??"end",n.position==="start"?e.before(r):e.after(r)),p()},destroy(){a=!0,i!==null&&clearTimeout(i),m?.disconnect(),r.removeEventListener("mousedown",w),r.removeEventListener("click",L);for(let d of c.values())d.remove();c.clear(),s&&r.remove(),delete e.dataset.enigmaInput,delete e.dataset.enigmaInputReveal,o&&(e.type="password")}}}function K(e){return e.normalize("NFD").replace(/\p{Diacritic}/gu,"").toLowerCase()}function Se(e,t){let n=e;for(let o of t.split(".")){if(n==null||typeof n!="object")return"";n=n[o]}return n==null?"":String(n)}function vt(e,t,n){let o=K(e),a=[];for(let i of t){let s=n.length?n:[""],r=null;for(let c=0;c<s.length;c++){let g=s[c],f=K(g?Se(i,g):String(i)),h=f.indexOf(o);if(h<0)continue;let T=f===o?0:(h+1)/(f.length+1)+c*.01;(!r||T<r.score)&&(r={item:i,score:T,key:g||void 0})}r&&a.push(r)}return a.sort((i,s)=>i.score-s.score)}function Te(e=[]){return(t,n)=>{let o=K(t),a=[];for(let i of n){let s=e.length?e:[""],r=null;for(let c of s){let g=K(c?Se(i,c):String(i)),f=bt(o,g);if(f<0)continue;let h=-f;(!r||h<r.score)&&(r={item:i,score:h,key:c||void 0})}r&&a.push(r)}return a.sort((i,s)=>i.score-s.score)}}function bt(e,t){if(!e)return 0;let n=0,o=0,a=0;for(let i=0;i<e.length;i++){let s=t.indexOf(e[i],n);if(s===-1)return-1;a=i>0&&s===n?a+1:0;let r=s===0||/[^a-z0-9]/.test(t[s-1]);o+=10+a*6+(r?8:0)-Math.min(s-n,6),n=s+1}return o}function Ee(e,t=32){let n=e.trim();return n.length<=t?n:`${n.slice(0,t-1).trimEnd()}\u2026`}function $(e={}){let t={...e},n=t.items??[],o="",a=[],i=null,s=null,r=!1,c=new Set;function g(){s=null,!(t.matcher||!t.fuse)&&(s=new t.fuse(n,{keys:t.keys??[],includeScore:!0,includeMatches:!0,threshold:.4,...t.fuseOptions}))}function f(v){let E=v.trim(),x=t.minLength??1,M;return E.length<x?M=(t.empty??"none")==="all"?n.map(p=>({item:p,score:0})):[]:t.matcher?M=t.matcher(E,n):s?M=s.search(E).map(p=>({item:p.item,score:p.score??0,key:p.matches?.[0]?.key})):M=vt(E,n,t.keys??[]),t.limit!=null?M.slice(0,t.limit):M}function h(v){o=v,a=f(v),t.onResults?.(a,o);for(let E of c)E(a,o);return a}function T(){i!==null&&(clearTimeout(i),i=null)}return g(),{get query(){return o},get results(){return a},search(v){if(r)return;T();let E=t.debounce??120;if(E<=0){h(v);return}i=setTimeout(()=>{i=null,h(v)},E)},searchNow(v){return T(),h(v)},setItems(v){n=v,g(),o&&h(o)},update(v){t={...t,...v},v.items&&(n=v.items),g(),o&&h(o)},attach(v){let E=()=>this.search(v.value),x=M=>{M.key!=="Escape"||!v.value||(M.stopPropagation(),v.value="",this.searchNow(""))};return v.addEventListener("input",E),v.addEventListener("keydown",x),v.dataset.enigmaSearch="",v.value&&this.searchNow(v.value),()=>{v.removeEventListener("input",E),v.removeEventListener("keydown",x),delete v.dataset.enigmaSearch}},subscribe(v){return c.add(v),()=>{c.delete(v)}},destroy(){r=!0,T(),c.clear(),s=null}}}function Q(e){if(!e.key||typeof window>"u")return null;try{let t=e.storage==="local"?window.localStorage:window.sessionStorage,n="__enigma_probe__";return t.setItem(n,"1"),t.removeItem(n),t}catch{return null}}function q(e){return e==null?null:typeof e=="number"?{ms:e}:e}function wt(e){let t=e;if(!t)return!1;let n=t.tagName;return n==="INPUT"||n==="TEXTAREA"||n==="SELECT"||t.isContentEditable===!0}function Oe(e={}){let t={...e},n=!!t.loading,o=0,a=null,i=!1,s=new Set,r=()=>{let p=q(t.cooldown);return p?.key?`enigma:cooldown:${p.key}`:null};function c(){let p=q(t.cooldown);if(!p)return;let w=Q(p),L=r();if(!w||!L)return;let m=Number(w.getItem(L));Number.isFinite(m)&&m>Date.now()&&(o=m)}function g(){return Math.max(0,o-Date.now())}function f(){let p=!!t.disabled,w=g();return{element:t.href?"a":"button",available:!p&&!n&&w===0,loading:n,disabled:p,cooldown:w,shortcut:t.shortcut??null}}function h(){let p=f();t.onChange?.(p);for(let w of s)w(p)}function T(){a!==null&&(clearInterval(a),a=null)}function v(){a!==null||g()===0||(a=setInterval(()=>{if(g()>0){h();return}T(),h()},100))}function E(){let p=q(t.cooldown);if(!p||p.ms<=0)return;o=Date.now()+p.ms;let w=Q(p),L=r();if(w&&L)try{w.setItem(L,String(o))}catch{}v()}async function x(p){if(i||!f().available)return;let w=t.onPress?.(p);if(w instanceof Promise){n=!0,h();try{await w}finally{n=!1,E(),h()}return}E(),h()}function M(p){!t.shortcut||wt(p.target)||p.ctrlKey||p.metaKey||p.altKey||p.shiftKey||p.key.toLowerCase()===t.shortcut.toLowerCase()&&f().available&&(p.preventDefault(),x(p))}return typeof window<"u"&&(c(),v(),window.addEventListener("keydown",M)),{get state(){return f()},press:x,update(p){let w=JSON.stringify(q(t.cooldown));t={...t,...p},p.loading!==void 0&&(n=!!p.loading),JSON.stringify(q(t.cooldown))!==w&&c(),h()},reset(){o=0,T();let p=q(t.cooldown),w=r();p&&w&&Q(p)?.removeItem(w),h()},subscribe(p){return s.add(p),()=>{s.delete(p)}},destroy(){i=!0,T(),s.clear(),typeof window<"u"&&window.removeEventListener("keydown",M)}}}var St="abcdefghijklmnopqrstuvwxyz",Tt="ABCDEFGHIJKLMNOPQRSTUVWXYZ",Et="0123456789",Le="!@#$%^&*()-_=+[]{};:,.?",Ot="Il1O0";function xe(e){let t=globalThis.crypto?.getRandomValues?.bind(globalThis.crypto);if(!t)throw new Error("Generating a password needs crypto.getRandomValues, which browsers only expose over HTTPS (or on localhost).");let n=Math.floor(2**32/e)*e,o=new Uint32Array(1),a;do t(o),a=o[0];while(a>=n);return a%e}function Me(e){return e[xe(e.length)]}function Mt(e){let{lowercase:t=!0,uppercase:n=!0,digits:o=!0,symbols:a=!0,excludeAmbiguous:i=!1,exclude:s=""}=e,r=new Set([...i?Ot:"",...s]),c=g=>[...g].filter(f=>!r.has(f)).join("");return[t?c(St):"",n?c(Tt):"",o?c(Et):"",a?c(Le):""].filter(Boolean)}function It(e){for(let t=e.length-1;t>0;t--){let n=xe(t+1);[e[t],e[n]]=[e[n],e[t]]}return e}function Ce(e={}){let{length:t=20,requireEachClass:n=!0}=e,o=Mt(e);if(!o.length)throw new Error("generatePassword: every character class was excluded.");if(t<1)throw new Error("generatePassword: length must be at least 1.");if(n&&t<o.length)throw new Error(`generatePassword: length ${t} cannot hold one character from each of the ${o.length} classes requested.`);let a=o.join(""),i=n?o.map(Me):[],s=Array.from({length:t-i.length},()=>Me(a));return It([...i,...s]).join("")}var Ie=new Set(["password","passwd","123456","12345678","123456789","1234567890","qwerty","qwertyuiop","abc123","111111","123123","admin","letmein","welcome","monkey","dragon","sunshine","iloveyou","princess","football","baseball","master","shadow","superman","batman","trustno1","hello","freedom","whatever","starwars","changeme","secret","login","root","toor","test","guest","azerty","1q2w3e4r","zaq12wsx"]),Lt=["abcdefghijklmnopqrstuvwxyz","0123456789","qwertyuiop","asdfghjkl","zxcvbnm"];function X(e){let t=0;return/[a-z]/.test(e)&&(t+=26),/[A-Z]/.test(e)&&(t+=26),/\d/.test(e)&&(t+=10),/[^\w\s]|_/.test(e)&&(t+=Le.length),/\s/.test(e)&&(t+=1),t||1}function xt(e){let t=1,n=1;for(let o=1;o<e.length;o++)n=e[o]===e[o-1]?n+1:1,t=Math.max(t,n);return t}function Ct(e){let t=e.toLowerCase(),n=0;for(let o of Lt){let a=[...o].reverse().join("");for(let i of[o,a])for(let s=0;s<i.length;s++)for(let r=i.length;r>s+n;r--)if(t.includes(i.slice(s,r))){n=Math.max(n,r-s);break}}return n}function At(e){return e.toLowerCase().replace(/^[^a-z]+/,"").replace(/[^a-z]+$/,"").replace(/[0!@$]/g,t=>({0:"o","!":"i","@":"a",$:"s"})[t]??t)}function Ae(e,t={}){if(!e)return{score:0,bits:0,warnings:[],empty:!0};let n=[],o=e.length*Math.log2(X(e)),a=At(e);(Ie.has(e.toLowerCase())||Ie.has(a))&&(o=Math.min(o,8),n.push("This is one of the most common passwords there is."));for(let c of t.userInputs??[]){let g=c.trim().toLowerCase();if(!(g.length<4||!e.toLowerCase().includes(g))){o=Math.min(o,16),n.push("It contains something you already typed on this form.");break}}let i=xt(e);i>=3&&(o-=(i-2)*Math.log2(X(e)),n.push("A character repeats several times in a row."));let s=Ct(e);return s>=4&&(o-=s*Math.log2(X(e))*.75,n.push("Part of it runs straight along the keyboard or the alphabet.")),e.length<8&&n.push("Short passwords fall to a brute force whatever they contain."),o=Math.max(0,Math.round(o)),{score:o<28?0:o<40?1:o<60?2:o<80?3:4,bits:o,warnings:n,empty:!1}}function ke(e={}){let t=typeof document>"u"?null:document,n=e.max??4,o=e.duration??5e3,a=new Set([...e.stickyTones??["error"],"loading"]),i=[],s=!1,r=0,c=new Set,g=new Map;function f(){let m=Object.freeze([...i]);for(let b of c)b(m)}function h(m){let b=g.get(m);b?.handle&&clearTimeout(b.handle),g.delete(m)}function T(m,b){if(!Number.isFinite(b)||b<=0)return;let d=s?null:setTimeout(()=>v(m),b);g.set(m,{handle:d,remaining:b,startedAt:Date.now()})}function v(m){let b=i.filter(d=>d.id!==m);b.length!==i.length&&(i=b,h(m),f())}function E(m){let b=m.tone??"info",d=m.duration??(a.has(b)?1/0:o),l=m.key?i.find(O=>O.key===m.key):void 0,y=l?.id??`n${++r}`,I={id:y,key:m.key,title:m.title,body:m.body,tone:b,duration:d,action:m.action,data:m.data,createdAt:Date.now()};if(i=l?i.map(O=>O.id===y?I:O):[...i,I],i.length>n){let O=i.find(k=>Number.isFinite(k.duration)&&k.id!==y);O?(i=i.filter(k=>k.id!==O.id),h(O.id)):i=i.slice(i.length-n)}return h(y),T(y,d),f(),y}let x=()=>{t&&(t.hidden?L.pause():L.resume())};function M(m,b){let d=i.find(I=>I.id===m);if(!d)return;let l=b.tone??d.tone,y=b.duration??(b.tone?a.has(l)?1/0:o:d.duration);i=i.map(I=>I.id===m?{...d,...b,tone:l,duration:y}:I),h(m),T(m,y),f()}function p(m,b){let d=typeof m=="function"?m(b):m;return typeof d=="string"?{title:d}:d}async function w(m,b){let d=typeof b.loading=="string"?{title:b.loading}:b.loading,l=d.key??`p${++r}`;E({...d,key:l,tone:"loading"});try{let y=await m;return E({...p(b.success,y),key:l,tone:"success"}),y}catch(y){throw E({...p(b.error,y),key:l,tone:"error"}),y}}let L={get items(){return Object.freeze([...i])},notify:E,update:M,promise:w,dismiss:v,dismissAll(){for(let m of i)h(m.id);i=[],f()},pause(){if(!s){s=!0;for(let[m,b]of g)b.handle&&(clearTimeout(b.handle),g.set(m,{handle:null,remaining:Math.max(b.remaining-(Date.now()-b.startedAt),0),startedAt:Date.now()}))}},resume(){if(s){s=!1;for(let[m,b]of[...g])h(m),T(m,b.remaining)}},subscribe(m){return c.add(m),()=>{c.delete(m)}},destroy(){for(let m of i)h(m.id);i=[],c.clear(),t?.removeEventListener("visibilitychange",x)}};return t?.addEventListener("visibilitychange",x),L}var J={online:!0,downlink:null,downlinkMax:null,effectiveType:null,rtt:null,saveData:null,type:null,recovered:!1,slow:!1};function Ne(){if(typeof navigator>"u")return null;let e=navigator;return e.connection??e.mozConnection??e.webkitConnection??null}function kt(e,t){for(let n of Object.keys(e))if(e[n]!==t[n])return!1;return!0}function Re(){if(typeof window>"u")return{get state(){return J},subscribe(){return()=>{}},destroy(){}};let e=new Set,t=!1,n=o();function o(){let s=Ne(),r=navigator.onLine,c=s?.effectiveType??null,g=s?.saveData??null;return{online:r,downlink:s?.downlink??null,downlinkMax:s?.downlinkMax??null,effectiveType:c,rtt:s?.rtt??null,saveData:g,type:s?.type??null,recovered:r&&t,slow:g===!0||c==="2g"||c==="slow-2g"}}function a(){navigator.onLine||(t=!0);let s=o();if(!kt(n,s)){n=s;for(let r of e)r(n)}}let i=Ne();return window.addEventListener("online",a,{passive:!0}),window.addEventListener("offline",a,{passive:!0}),i?.addEventListener("change",a,{passive:!0}),{get state(){return n},subscribe(s){return e.add(s),()=>{e.delete(s)}},destroy(){e.clear(),window.removeEventListener("online",a),window.removeEventListener("offline",a),i?.removeEventListener("change",a)}}}var Nt=/([zZ]|[+-]\d{2}:?\d{2})$/,Rt=/^\d{4}-\d{2}-\d{2}$/,Pt=/\d{2}:\d{2}/,Dt=/^([+-])?P(?:(\d+(?:\.\d+)?)Y)?(?:(\d+(?:\.\d+)?)M)?(?:(\d+(?:\.\d+)?)W)?(?:(\d+(?:\.\d+)?)D)?(?:T(?:(\d+(?:\.\d+)?)H)?(?:(\d+(?:\.\d+)?)M)?(?:(\d+(?:\.\d+)?)S)?)?$/;function ee(e){let t=e.trim();if(!t||Rt.test(t)||Nt.test(t))return t;let n=t.replace(" ","T");return Pt.test(n)?`${n}Z`:n}function te(e){if(e==null)return null;if(e instanceof Date)return Number.isNaN(e.getTime())?null:e;if(typeof e=="number")return Number.isFinite(e)?new Date(e):null;let t=new Date(ee(e));return Number.isNaN(t.getTime())?null:t}function ne(e){let t=Dt.exec(e.trim());if(!t)return 0;let[,n,o,a,i,s,r,c,g]=t,f=T=>T?Number(T):0,h=f(o)*31536e6+f(a)*2592e6+f(i)*6048e5+f(s)*864e5+f(r)*36e5+f(c)*6e4+f(g)*1e3;return n==="-"?-h:h}function Ft(e){let{second:t,minute:n,hour:o,weekday:a,day:i,month:s,year:r,timeZone:c,timeZoneName:g}=e,f={timeZone:c,timeZoneName:g,second:t,minute:n,hour:o,weekday:a,day:i,month:s,year:r};for(let h of Object.keys(f))f[h]===void 0&&delete f[h];return f}function Pe(e,t,n){try{return new Intl.DateTimeFormat(t,n).format(e)}catch{return e.toISOString()}}function De(e,t={},n=new Date){let o=te(e);if(!o)return{date:null,iso:"",label:"",exact:"",beyondThreshold:!1,absoluteOnly:!1};let{locale:a,threshold:i="P30D",prefix:s="on",numericBeyondThreshold:r=!1}=t,g=Math.abs(o.getTime()-n.getTime())>ne(i),f=r&&g,h=f?{day:"numeric",month:"numeric",year:"numeric",timeZone:t.timeZone}:{day:"numeric",month:"short",year:"numeric",...Ft(t)},T=Pe(o,a,h);return{date:o,iso:o.toISOString(),label:!f&&s?`${s} ${T}`:T,exact:Pe(o,a,{dateStyle:"full",timeStyle:"long",timeZone:t.timeZone}),beyondThreshold:g,absoluteOnly:f}}function Fe(e,t={}){let n={datetime:e.iso,format:t.format,tense:t.tense,precision:t.precision,threshold:t.threshold,prefix:t.prefix,"format-style":t.formatStyle,second:t.second,minute:t.minute,hour:t.hour,weekday:t.weekday,day:t.day,month:t.month,year:t.year,lang:t.locale,"time-zone":t.timeZone,"time-zone-name":t.timeZoneName,"no-title":t.noTitle?"":void 0},o={};for(let[a,i]of Object.entries(n))i!==void 0&&(o[a]=i);return o}var oe="https://cdn.jsdelivr.net/gh/FJRG2007/enigma@main/assets/flags",He={shape:"rect",format:"svg",source:"cdn",basePath:"/flags",size:16},P={...He};function qe(e){return P={...P,...e},P}function Ue(){return P}function Be(){return P={...He},P}var re={rect:4/3,square:1,circle:1},_t=/^[\u{1F1E6}-\u{1F1FF}]{2}$/u,Ht=/^([A-Za-z]{2,3})[-_]([A-Z]{2})$/,qt=/^[a-z]{2,}[-_][a-z0-9_-]+$/,ze=/^[a-z]{2}$/;function Ke(e){return e.normalize("NFD").replace(/\p{Diacritic}/gu,"").replace(/['‘’ʼ`´]/g,"").toLowerCase().replace(/&/g," and ").replace(/\bst\.?\s/g,"saint ").replace(/^the\s+/,"").replace(/[.,]/g,"").replace(/\s+/g," ").trim()}var _e=new Map;function $e(e){try{return new Intl.Locale(`und-${e}`).region?.toLowerCase()??e.toLowerCase()}catch{return e.toLowerCase()}}function Ge(e){return e.of("ZZ")}function Ut(e){let t=_e.get(e);if(t!==void 0)return t;let n=null;try{let o=new Intl.DisplayNames([e],{type:"region"}),a=Ge(o);n=new Map;for(let i=65;i<=90;i++)for(let s=65;s<=90;s++){let r=String.fromCharCode(i,s),c=o.of(r);if(!c||c===r||c===a)continue;let g=Ke(c);n.has(g)||n.set(g,$e(r))}}catch{n=null}return _e.set(e,n),n}function Bt(e){try{let t=new Intl.DisplayNames(["en"],{type:"region"}),n=e.toUpperCase(),o=t.of(n);return!!o&&o!==n&&o!==Ge(t)}catch{return!0}}function B(e,t){if(!e)return null;let n=e.trim();if(!n)return null;if(_t.test(n))return[...n].map(r=>String.fromCharCode((r.codePointAt(0)??0)-127462+97)).join("");let o=Ht.exec(n);if(o)return o[2].toLowerCase();let a=n.toLowerCase();if(ze.test(a))return Bt(a)?$e(a):null;if(qt.test(a))return a;let i=Ke(n);for(let s of[t,Ve(),"en",zt()]){if(!s)continue;let r=Ut(s)?.get(i);if(r)return r}return null}function ie(e,t){let n=B(e);if(!n||!ze.test(n))return null;let o=n.toUpperCase();try{let i=new Intl.DisplayNames([t??Ve()??"en"],{type:"region"}).of(o);return!i||i===o?null:i}catch{return null}}function zt(){try{return Intl.DateTimeFormat().resolvedOptions().locale}catch{return}}function Ve(){if(!(typeof document>"u"))return document.documentElement.lang||void 0}var Kt=!1;function se(e,t={}){let n={...P,...t},o=B(e);if(!o)return null;let a=n.source==="cdn",i=n.format;return a&&i!=="svg"&&(!Kt&&typeof process<"u",i="svg"),`${a?oe:(n.source==="local"?n.basePath:n.source).replace(/\/+$/,"")}/${n.shape}/${o}.${i}`}function ae(e,t={}){let n={...P,...t},o=B(e),a=se(o,t);if(!o||!a)return null;let i=Math.max(1,Math.round(n.size));return{code:o,src:a,shape:n.shape,format:n.source==="cdn"?"svg":n.format,width:Math.round(i*re[n.shape]),height:i,name:ie(o,n.locale)}}function Ze(e,t={}){let n=ae(e,t);if(!n)return null;let o=t.decorative?"":t.label?.trim()||n.name||"";return{src:n.src,alt:o,width:n.width,height:n.height,loading:"lazy",decoding:"async","data-enigma-flag":"","data-flag-code":n.code,"data-flag-shape":n.shape,...o?{title:o}:{"aria-hidden":"true"}}}function U(e){return`${e.scope??""}\0${e.href??""}\0${e.href?"":e.term.trim().toLowerCase()}`}function Ye(e={}){let{key:t="enigma:palette:recent",limit:n=8,storage:o="local"}=e;function a(){if(typeof window>"u")return null;try{return o==="session"?window.sessionStorage:window.localStorage}catch{return null}}function i(){let r=a();if(!r)return[];try{let c=r.getItem(t);if(!c)return[];let g=JSON.parse(c);return Array.isArray(g)?g.filter(f=>!!f&&typeof f.term=="string").sort((f,h)=>h.at-f.at).slice(0,n):[]}catch{return[]}}function s(r){let c=a(),g=r.slice(0,n);try{c?.setItem(t,JSON.stringify(g))}catch{}return g}return{list:i,remember(r){let c={...r,at:r.at??Date.now()};if(!c.term.trim()&&!c.href)return i();let g=U(c);return s([c,...i().filter(f=>U(f)!==g)])},forget(r){let c=U(r);return s(i().filter(g=>U(g)!==c))},clear(){let r=a();try{r?.removeItem(t)}catch{}}}}function je(e,t){let n=[],o=new Map;return e.forEach((a,i)=>{let s=t(a),r=o.get(s);r||(r={label:s,rows:[]},o.set(s,r),n.push(r)),r.rows.push({row:a,position:i})}),n}function We(e,t,n,o=5){if(t<=0)return 0;switch(n){case"ArrowDown":return(e+1)%t;case"ArrowUp":return(e-1+t)%t;case"Home":return 0;case"End":return t-1;case"PageDown":return Math.min(t-1,e+o);case"PageUp":return Math.max(0,e-o)}}function Qe(e="K"){return`${typeof navigator<"u"&&/mac|iphone|ipad|ipod/i.test(navigator.platform||navigator.userAgent||"")?"\u2318":"Ctrl"} ${e.toUpperCase()}`}function Xe(e,t="k"){return e.key.toLowerCase()!==t.toLowerCase()?!1:e.metaKey||e.ctrlKey}var G=["label","description","group","keywords"],$t=600,Je=5;function et(e){return e.normalize("NFD").replace(/\p{Diacritic}/gu,"").toLowerCase()}function tt(e){return e==null?[]:(Array.isArray(e)?[...e]:[e]).filter(n=>n!=="")}function Gt(e,t){return e.length===t.length&&e.every((n,o)=>n===t[o])}function nt(e,t){return e.length===t.length&&e.every((n,o)=>n===t[o])}function Vt(e,t){return e.open===t.open&&e.query===t.query&&e.active===t.active&&e.multiple===t.multiple&&e.empty===t.empty&&Gt(e.value,t.value)&&nt(e.visible,t.visible)&&nt(e.selected,t.selected)}function ot(e={}){let t={...e},n=t.options??[],o=tt(t.value),a=!1,i="",s=-1,r=[...n],c="",g=0,f=!1,h=new Set,T=$({items:n,keys:t.searchKeys??G,fuse:t.fuse,fuseOptions:t.fuseOptions,matcher:t.matcher,debounce:0,empty:"all"});function v(l){return n.find(y=>y.value===l)}function E(){return o.map(v).filter(l=>!!l)}function x(){return{open:a,query:i,active:s,visible:r,selected:E(),value:[...o],multiple:!!t.multiple,empty:r.length===0}}function M(){let l=x();t.onChange?.(l);for(let y of h)y(l)}function p(l){let y=r.length;return(l%y+y)%y}function w(l,y){if(r.length===0)return-1;for(let I=0;I<r.length;I++){let O=p(l+y*I);if(!r[O]?.disabled)return O}return-1}let L;function m(){r=t.searchable&&i.trim()?T.searchNow(i).map(y=>y.item):[...n];let l=s>=0?r.findIndex(y=>y===L):-1;s=l>=0&&!r[l]?.disabled?l:w(0,1),L=r[s]}function b(){let l=E();t.onValueChange?.(t.multiple?[...o]:o[0]??"",l)}function d(){return t.closeOnSelect??!t.multiple}return m(),{get state(){return x()},setOpen(l){if(!(f||a===l)){if(a=l,a){i="",m();let y=o[0]?r.findIndex(I=>I.value===o[0]):-1;s=y>=0&&!r[y]?.disabled?y:w(0,1),L=r[s]}else i="",c="",m();M()}},toggleOpen(){this.setOpen(!a)},setQuery(l){f||(i=l,m(),M())},move(l){if(f||r.length===0)return;let y=s<0?-1:s;switch(l){case"ArrowDown":s=w(y+1,1);break;case"ArrowUp":s=w(y-1+r.length,-1);break;case"Home":s=w(0,1);break;case"End":s=w(r.length-1,-1);break;case"PageDown":s=w(Math.min(r.length-1,y+Je),1);break;case"PageUp":s=w(Math.max(0,y-Je),-1);break}L=r[s],M()},setActive(l){f||l===s||l<0||l>=r.length||r[l]?.disabled||(s=l,L=r[s],M())},select(l){if(f)return;let y=v(l);!y||y.disabled||(t.multiple?o=o.includes(l)?o.filter(I=>I!==l):[...o,l]:o=[l],b(),d()&&(a=!1,i="",m()),M())},selectActive(){let l=r[s];l&&this.select(l.value)},remove(l){f||!o.includes(l)||(o=o.filter(y=>y!==l),b(),M())},clear(){f||o.length===0||(o=[],b(),M())},typeahead(l){if(f||l.length!==1)return;let y=Date.now();c=y-g>$t?l:c+l,g=y;let I=et(c),O=c.length===1?1:0;for(let k=O;k<r.length+O;k++){let C=p(Math.max(s,0)+k),N=r[C];if(!(!N||N.disabled)&&et(N.label).startsWith(I)){s=C,L=N,M();return}}},update(l){if(f)return;let y=x(),I=l.options!==void 0;t={...t,...l},I&&(n=l.options??[]),l.value!==void 0&&(o=tt(l.value)),(I||l.searchKeys||l.fuse||l.fuseOptions||l.matcher)&&T.update({items:n,keys:t.searchKeys??G,fuse:t.fuse,fuseOptions:t.fuseOptions,matcher:t.matcher}),m(),Vt(y,x())||M()},subscribe(l){return h.add(l),()=>{h.delete(l)}},destroy(){f=!0,h.clear(),T.destroy()}}}return ft(Zt);})();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@enigmax/dashboard",
3
- "version": "0.1.110",
3
+ "version": "0.1.111",
4
4
  "description": "Local browser dashboard UI for enigma: the static page and chart assets enigma serves on its loopback dashboard (savings, real tool usage, in-browser settings). Installed on demand by enigma-cli; not a runtime dependency.",
5
5
  "type": "module",
6
6
  "files": [