The web UI showed the wrong up/down state for frontends whose pool
composition had been touched by a mix of runtime disable/enable and
weight changes: a frontend with every backend at effective_weight=0
would still display "up", while a sibling frontend with a serving
fallback backend would display "down". Two independent bugs, each
fixed on its own layer.
On the fast path (healthCheckEqual returns true), Reload did
`w.entry = b`, blindly replacing the runtime worker entry with the
fresh YAML record. YAML's default for Enabled is true, so any
backend the operator had runtime-disabled would have its Enabled
flag silently reset while the worker's backend.State stayed at
StateDisabled. Subsequent EnableBackend calls then early-returned
on `if w.entry.Enabled` and never transitioned the state machine
— the CLI reported "enabled, state is 'disabled'" and the backend
was permanently stuck.
Fix: preserve w.entry.Enabled across the fast-path replacement.
runtimeEnabled := w.entry.Enabled
w.entry = b
w.entry.Enabled = runtimeEnabled
Runtime operator state now outlives config reloads. On the worker-
restart path (different health check) the new worker is
structurally fresh and the YAML's Enabled is still authoritative.
Both methods used `w.entry.Enabled` as their idempotency check,
which meant a stuck `Enabled=true, State=disabled` combo couldn't
be repaired even after the Reload fix (existing bad state had to
survive the upgrade). Switched both methods to key on
`w.backend.State`:
- DisableBackend: if state == StateDisabled, sync the flag but
don't emit a redundant transition; otherwise do the full
state transition + flag flip + worker cancel.
- EnableBackend: if state != StateDisabled, sync the flag but
don't emit a redundant transition; otherwise do the full
transition + flag flip + probe-goroutine restart.
Either method will now unstick any inconsistency between the
flag and the state machine — future drift from a panic, a new
code path we haven't thought of, or existing already-stuck
backends from before this commit are all repaired on the next
enable/disable call.
Changing a backend's weight can flip a frontend between up and
down (e.g. zeroing the last non-zero-weighted backend in the
active pool), but SetFrontendPoolBackendWeight never called
updateFrontendState, so the checker's cached frontend state
would drift from reality until the next genuine backend
transition happened to trigger a recompute. The symptom was
"show frontends nginx-ip4-http" reporting up even with every
effective_weight=0.
Fix: call c.updateFrontendState(frontendName, fe) after the
weight mutation, under the same lock. The recompute emits a
FrontendEvent transition if the aggregate flipped, so any
WatchEvents consumer picks up the change live.
stores/state.ts recomputeEffectiveWeights is renamed and
extended to recomputeDerivedState, which now also writes
fe.state using the same rule as health.ComputeFrontendState:
unknown if no backends or all unknown, up if any effective
weight > 0, down otherwise. Called from every mutation path
(replaceAll, replaceSnapshot, applyBackendTransition,
applyConfiguredWeight) so the SPA is authoritative for *display*
state and doesn't inherit any staleness the server's cached
frontendStates map might have.
applyFrontendTransition is now a no-op for the state field —
the server's `to` value is no longer trusted because
recomputeDerivedState walks the local backends array on every
update and produces a fresh, correct answer. The reducer is kept
as a named function so sse.ts's dispatch table still has a
landing spot for "frontend" events (they still feed the
DebugPanel via pushEvent); the empty body is deliberate, not a
bug — a comment at the top spells it out.
2 lines
35 KiB
JavaScript
2 lines
35 KiB
JavaScript
(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const s of document.querySelectorAll('link[rel="modulepreload"]'))r(s);new MutationObserver(s=>{for(const l of s)if(l.type==="childList")for(const i of l.addedNodes)i.tagName==="LINK"&&i.rel==="modulepreload"&&r(i)}).observe(document,{childList:!0,subtree:!0});function n(s){const l={};return s.integrity&&(l.integrity=s.integrity),s.referrerPolicy&&(l.referrerPolicy=s.referrerPolicy),s.crossOrigin==="use-credentials"?l.credentials="include":s.crossOrigin==="anonymous"?l.credentials="omit":l.credentials="same-origin",l}function r(s){if(s.ep)return;s.ep=!0;const l=n(s);fetch(s.href,l)}})();const at=!1,ct=(e,t)=>e===t,W=Symbol("solid-proxy"),xe=Symbol("solid-track"),ce={equals:ct};let Fe=Ke;const U=1,ue=2,We={owned:null,cleanups:null,context:null,owner:null};var v=null;let Se=null,ut=null,p=null,E=null,D=null,pe=0;function te(e,t){const n=p,r=v,s=e.length===0,l=t===void 0?r:t,i=s?We:{owned:null,cleanups:null,context:l?l.context:null,owner:l},o=s?e:()=>e(()=>M(()=>re(i)));v=i,p=null;try{return G(o,!0)}finally{p=n,v=r}}function x(e,t){t=t?Object.assign({},ce,t):ce;const n={value:e,observers:null,observerSlots:null,comparator:t.equals||void 0},r=s=>(typeof s=="function"&&(s=s(n.value)),Ge(n,s));return[He.bind(n),r]}function C(e,t,n){const r=Pe(e,t,!1,U);le(r)}function H(e,t,n){Fe=pt;const r=Pe(e,t,!1,U);(!n||!n.render)&&(r.user=!0),D?D.push(r):le(r)}function F(e,t,n){n=n?Object.assign({},ce,n):ce;const r=Pe(e,t,!0,0);return r.observers=null,r.observerSlots=null,r.comparator=n.equals||void 0,le(r),He.bind(r)}function ft(e){return G(e,!1)}function M(e){if(p===null)return e();const t=p;p=null;try{return e()}finally{p=t}}function dt(e,t,n){const r=Array.isArray(e);let s,l=n&&n.defer;return i=>{let o;if(r){o=Array(e.length);for(let u=0;u<e.length;u++)o[u]=e[u]()}else o=e();if(l)return l=!1,i;const a=M(()=>t(o,s,i));return s=o,a}}function gt(e){H(()=>M(e))}function Y(e){return v===null||(v.cleanups===null?v.cleanups=[e]:v.cleanups.push(e)),e}function Ae(){return p}function ht(){return v}function bt(e,t){const n=v,r=p;v=e,p=null;try{return G(t,!0)}catch(s){Oe(s)}finally{v=n,p=r}}function He(){if(this.sources&&this.state)if(this.state===U)le(this);else{const e=E;E=null,G(()=>de(this),!1),E=e}if(p){const e=this.observers?this.observers.length:0;p.sources?(p.sources.push(this),p.sourceSlots.push(e)):(p.sources=[this],p.sourceSlots=[e]),this.observers?(this.observers.push(p),this.observerSlots.push(p.sources.length-1)):(this.observers=[p],this.observerSlots=[p.sources.length-1])}return this.value}function Ge(e,t,n){let r=e.value;return(!e.comparator||!e.comparator(r,t))&&(e.value=t,e.observers&&e.observers.length&&G(()=>{for(let s=0;s<e.observers.length;s+=1){const l=e.observers[s],i=Se&&Se.running;i&&Se.disposed.has(l),(i?!l.tState:!l.state)&&(l.pure?E.push(l):D.push(l),l.observers&&qe(l)),i||(l.state=U)}if(E.length>1e6)throw E=[],new Error},!1)),t}function le(e){if(!e.fn)return;re(e);const t=pe;mt(e,e.value,t)}function mt(e,t,n){let r;const s=v,l=p;p=v=e;try{r=e.fn(t)}catch(i){return e.pure&&(e.state=U,e.owned&&e.owned.forEach(re),e.owned=null),e.updatedAt=n+1,Oe(i)}finally{p=l,v=s}(!e.updatedAt||e.updatedAt<=n)&&(e.updatedAt!=null&&"observers"in e?Ge(e,r):e.value=r,e.updatedAt=n)}function Pe(e,t,n,r=U,s){const l={fn:e,state:r,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:t,owner:v,context:v?v.context:null,pure:n};return v===null||v!==We&&(v.owned?v.owned.push(l):v.owned=[l]),l}function fe(e){if(e.state===0)return;if(e.state===ue)return de(e);if(e.suspense&&M(e.suspense.inFallback))return e.suspense.effects.push(e);const t=[e];for(;(e=e.owner)&&(!e.updatedAt||e.updatedAt<pe);)e.state&&t.push(e);for(let n=t.length-1;n>=0;n--)if(e=t[n],e.state===U)le(e);else if(e.state===ue){const r=E;E=null,G(()=>de(e,t[0]),!1),E=r}}function G(e,t){if(E)return e();let n=!1;t||(E=[]),D?n=!0:D=[],pe++;try{const r=e();return $t(n),r}catch(r){n||(D=null),E=null,Oe(r)}}function $t(e){if(E&&(Ke(E),E=null),e)return;const t=D;D=null,t.length&&G(()=>Fe(t),!1)}function Ke(e){for(let t=0;t<e.length;t++)fe(e[t])}function pt(e){let t,n=0;for(t=0;t<e.length;t++){const r=e[t];r.user?e[n++]=r:fe(r)}for(t=0;t<n;t++)fe(e[t])}function de(e,t){e.state=0;for(let n=0;n<e.sources.length;n+=1){const r=e.sources[n];if(r.sources){const s=r.state;s===U?r!==t&&(!r.updatedAt||r.updatedAt<pe)&&fe(r):s===ue&&de(r,t)}}}function qe(e){for(let t=0;t<e.observers.length;t+=1){const n=e.observers[t];n.state||(n.state=ue,n.pure?E.push(n):D.push(n),n.observers&&qe(n))}}function re(e){let t;if(e.sources)for(;e.sources.length;){const n=e.sources.pop(),r=e.sourceSlots.pop(),s=n.observers;if(s&&s.length){const l=s.pop(),i=n.observerSlots.pop();r<s.length&&(l.sourceSlots[i]=r,s[r]=l,n.observerSlots[r]=i)}}if(e.tOwned){for(t=e.tOwned.length-1;t>=0;t--)re(e.tOwned[t]);delete e.tOwned}if(e.owned){for(t=e.owned.length-1;t>=0;t--)re(e.owned[t]);e.owned=null}if(e.cleanups){for(t=e.cleanups.length-1;t>=0;t--)e.cleanups[t]();e.cleanups=null}e.state=0}function wt(e){return e instanceof Error?e:new Error(typeof e=="string"?e:"Unknown error",{cause:e})}function Oe(e,t=v){throw wt(e)}const vt=Symbol("fallback");function Me(e){for(let t=0;t<e.length;t++)e[t]()}function yt(e,t,n={}){let r=[],s=[],l=[],i=0,o=t.length>1?[]:null;return Y(()=>Me(l)),()=>{let a=e()||[],u=a.length,f,c;return a[xe],M(()=>{let b,y,S,P,B,m,w,_,A;if(u===0)i!==0&&(Me(l),l=[],r=[],s=[],i=0,o&&(o=[])),n.fallback&&(r=[vt],s[0]=te(k=>(l[0]=k,n.fallback())),i=1);else if(i===0){for(s=new Array(u),c=0;c<u;c++)r[c]=a[c],s[c]=te($);i=u}else{for(S=new Array(u),P=new Array(u),o&&(B=new Array(u)),m=0,w=Math.min(i,u);m<w&&r[m]===a[m];m++);for(w=i-1,_=u-1;w>=m&&_>=m&&r[w]===a[_];w--,_--)S[_]=s[w],P[_]=l[w],o&&(B[_]=o[w]);for(b=new Map,y=new Array(_+1),c=_;c>=m;c--)A=a[c],f=b.get(A),y[c]=f===void 0?-1:f,b.set(A,c);for(f=m;f<=w;f++)A=r[f],c=b.get(A),c!==void 0&&c!==-1?(S[c]=s[f],P[c]=l[f],o&&(B[c]=o[f]),c=y[c],b.set(A,c)):l[f]();for(c=m;c<u;c++)c in S?(s[c]=S[c],l[c]=P[c],o&&(o[c]=B[c],o[c](c))):s[c]=te($);s=s.slice(0,i=u),r=a.slice(0)}return s});function $(b){if(l[c]=b,o){const[y,S]=x(c);return o[c]=S,t(a[c],y)}return t(a[c])}}}function g(e,t){return M(()=>e(t||{}))}const _t=e=>`Stale read from <${e}>.`;function J(e){const t="fallback"in e&&{fallback:()=>e.fallback};return F(yt(()=>e.each,e.children,t||void 0))}function O(e){const t=e.keyed,n=F(()=>e.when,void 0,void 0),r=t?n:F(n,void 0,{equals:(s,l)=>!s==!l});return F(()=>{const s=r();if(s){const l=e.children;return typeof l=="function"&&l.length>0?M(()=>l(t?s:()=>{if(!M(r))throw _t("Show");return n()})):l}return e.fallback},void 0,void 0)}const L=e=>F(()=>e());function kt(e,t,n){let r=n.length,s=t.length,l=r,i=0,o=0,a=t[s-1].nextSibling,u=null;for(;i<s||o<l;){if(t[i]===n[o]){i++,o++;continue}for(;t[s-1]===n[l-1];)s--,l--;if(s===i){const f=l<r?o?n[o-1].nextSibling:n[l-o]:a;for(;o<l;)e.insertBefore(n[o++],f)}else if(l===o)for(;i<s;)(!u||!u.has(t[i]))&&t[i].remove(),i++;else if(t[i]===n[l-1]&&n[o]===t[s-1]){const f=t[--s].nextSibling;e.insertBefore(n[o++],t[i++].nextSibling),e.insertBefore(n[--l],f),t[s]=n[l]}else{if(!u){u=new Map;let c=o;for(;c<l;)u.set(n[c],c++)}const f=u.get(t[i]);if(f!=null)if(o<f&&f<l){let c=i,$=1,b;for(;++c<s&&c<l&&!((b=u.get(t[c]))==null||b!==f+$);)$++;if($>f-o){const y=t[i];for(;o<f;)e.insertBefore(n[o++],y)}else e.replaceChild(n[o++],t[i++])}else i++;else t[i++].remove()}}}const Be="_$DX_DELEGATE";function St(e,t,n,r={}){let s;return te(l=>{s=l,t===document?e():d(t,e(),t.firstChild?null:void 0,n)},r.owner),()=>{s(),t.textContent=""}}function h(e,t,n,r){let s;const l=()=>{const o=document.createElement("template");return o.innerHTML=e,o.content.firstChild},i=()=>(s||(s=l())).cloneNode(!0);return i.cloneNode=i,i}function we(e,t=window.document){const n=t[Be]||(t[Be]=new Set);for(let r=0,s=e.length;r<s;r++){const l=e[r];n.has(l)||(n.add(l),t.addEventListener(l,Ct))}}function N(e,t,n){n==null?e.removeAttribute(t):e.setAttribute(t,n)}function xt(e,t){t==null?e.removeAttribute("class"):e.className=t}function At(e,t,n,r){Array.isArray(n)?(e[`$$${t}`]=n[0],e[`$$${t}Data`]=n[1]):e[`$$${t}`]=n}function ve(e,t,n){return M(()=>e(t,n))}function d(e,t,n,r){if(n!==void 0&&!r&&(r=[]),typeof t!="function")return ge(e,t,r,n);C(s=>ge(e,t(),s,n),r)}function Ct(e){let t=e.target;const n=`$$${e.type}`,r=e.target,s=e.currentTarget,l=a=>Object.defineProperty(e,"target",{configurable:!0,value:a}),i=()=>{const a=t[n];if(a&&!t.disabled){const u=t[`${n}Data`];if(u!==void 0?a.call(t,u,e):a.call(t,e),e.cancelBubble)return}return t.host&&typeof t.host!="string"&&!t.host._$host&&t.contains(e.target)&&l(t.host),!0},o=()=>{for(;i()&&(t=t._$host||t.parentNode||t.host););};if(Object.defineProperty(e,"currentTarget",{configurable:!0,get(){return t||document}}),e.composedPath){const a=e.composedPath();l(a[0]);for(let u=0;u<a.length-2&&(t=a[u],!!i());u++){if(t._$host){t=t._$host,o();break}if(t.parentNode===s)break}}else o();l(r)}function ge(e,t,n,r,s){for(;typeof n=="function";)n=n();if(t===n)return n;const l=typeof t,i=r!==void 0;if(e=i&&n[0]&&n[0].parentNode||e,l==="string"||l==="number"){if(l==="number"&&(t=t.toString(),t===n))return n;if(i){let o=n[0];o&&o.nodeType===3?o.data!==t&&(o.data=t):o=document.createTextNode(t),n=K(e,n,r,o)}else n!==""&&typeof n=="string"?n=e.firstChild.data=t:n=e.textContent=t}else if(t==null||l==="boolean")n=K(e,n,r);else{if(l==="function")return C(()=>{let o=t();for(;typeof o=="function";)o=o();n=ge(e,o,n,r)}),()=>n;if(Array.isArray(t)){const o=[],a=n&&Array.isArray(n);if(Ce(o,t,n,s))return C(()=>n=ge(e,o,n,r,!0)),()=>n;if(o.length===0){if(n=K(e,n,r),i)return n}else a?n.length===0?Re(e,o,r):kt(e,n,o):(n&&K(e),Re(e,o));n=o}else if(t.nodeType){if(Array.isArray(n)){if(i)return n=K(e,n,r,t);K(e,n,null,t)}else n==null||n===""||!e.firstChild?e.appendChild(t):e.replaceChild(t,e.firstChild);n=t}}return n}function Ce(e,t,n,r){let s=!1;for(let l=0,i=t.length;l<i;l++){let o=t[l],a=n&&n[e.length],u;if(!(o==null||o===!0||o===!1))if((u=typeof o)=="object"&&o.nodeType)e.push(o);else if(Array.isArray(o))s=Ce(e,o,a)||s;else if(u==="function")if(r){for(;typeof o=="function";)o=o();s=Ce(e,Array.isArray(o)?o:[o],Array.isArray(a)?a:[a])||s}else e.push(o),s=!0;else{const f=String(o);a&&a.nodeType===3&&a.data===f?e.push(a):e.push(document.createTextNode(f))}}return s}function Re(e,t,n=null){for(let r=0,s=t.length;r<s;r++)e.insertBefore(t[r],n)}function K(e,t,n,r){if(n===void 0)return e.textContent="";const s=r||document.createTextNode("");if(t.length){let l=!1;for(let i=t.length-1;i>=0;i--){const o=t[i];if(s!==o){const a=o.parentNode===e;!l&&!i?a?e.replaceChild(s,o):e.insertBefore(s,n):a&&o.remove()}else l=!0}}else e.insertBefore(s,n);return[s]}const Et="http://www.w3.org/2000/svg";function Pt(e,t=!1,n=void 0){return t?document.createElementNS(Et,e):document.createElement(e,{is:n})}function Ot(e){const{useShadow:t}=e,n=document.createTextNode(""),r=()=>e.mount||document.body,s=ht();let l;return H(()=>{l||(l=bt(s,()=>F(()=>e.children)));const i=r();if(i instanceof HTMLHeadElement){const[o,a]=x(!1),u=()=>a(!0);te(f=>d(i,()=>o()?f():l(),null)),Y(u)}else{const o=Pt(e.isSVG?"g":"div",e.isSVG),a=t&&o.attachShadow?o.attachShadow({mode:"open"}):o;Object.defineProperty(o,"_$host",{get(){return n.parentNode},configurable:!0}),d(a,l),i.appendChild(o),e.ref&&e.ref(o),Y(()=>i.removeChild(o))}},void 0,{render:!0}),n}async function Ye(e){const t=await fetch(e,{credentials:"same-origin"});if(!t.ok)throw new Error(`${e}: ${t.status} ${t.statusText}`);return await t.json()}function Je(){return Ye("/view/api/state")}function Tt(){return Ye("/view/api/version")}const he=Symbol("store-raw"),q=Symbol("store-node"),j=Symbol("store-has"),Xe=Symbol("store-self");function ze(e){let t=e[W];if(!t&&(Object.defineProperty(e,W,{value:t=new Proxy(e,It)}),!Array.isArray(e))){const n=Object.keys(e),r=Object.getOwnPropertyDescriptors(e);for(let s=0,l=n.length;s<l;s++){const i=n[s];r[i].get&&Object.defineProperty(e,i,{enumerable:r[i].enumerable,get:r[i].get.bind(t)})}}return t}function X(e){let t;return e!=null&&typeof e=="object"&&(e[W]||!(t=Object.getPrototypeOf(e))||t===Object.prototype||Array.isArray(e))}function z(e,t=new Set){let n,r,s,l;if(n=e!=null&&e[he])return n;if(!X(e)||t.has(e))return e;if(Array.isArray(e)){Object.isFrozen(e)?e=e.slice(0):t.add(e);for(let i=0,o=e.length;i<o;i++)s=e[i],(r=z(s,t))!==s&&(e[i]=r)}else{Object.isFrozen(e)?e=Object.assign({},e):t.add(e);const i=Object.keys(e),o=Object.getOwnPropertyDescriptors(e);for(let a=0,u=i.length;a<u;a++)l=i[a],!o[l].get&&(s=e[l],(r=z(s,t))!==s&&(e[l]=r))}return e}function be(e,t){let n=e[t];return n||Object.defineProperty(e,t,{value:n=Object.create(null)}),n}function se(e,t,n){if(e[t])return e[t];const[r,s]=x(n,{equals:!1,internal:!0});return r.$=s,e[t]=r}function Nt(e,t){const n=Reflect.getOwnPropertyDescriptor(e,t);return!n||n.get||!n.configurable||t===W||t===q||(delete n.value,delete n.writable,n.get=()=>e[W][t]),n}function Qe(e){Ae()&&se(be(e,q),Xe)()}function Lt(e){return Qe(e),Reflect.ownKeys(e)}const It={get(e,t,n){if(t===he)return e;if(t===W)return n;if(t===xe)return Qe(e),n;const r=be(e,q),s=r[t];let l=s?s():e[t];if(t===q||t===j||t==="__proto__")return l;if(!s){const i=Object.getOwnPropertyDescriptor(e,t);Ae()&&(typeof l!="function"||e.hasOwnProperty(t))&&!(i&&i.get)&&(l=se(r,t,l)())}return X(l)?ze(l):l},has(e,t){return t===he||t===W||t===xe||t===q||t===j||t==="__proto__"?!0:(Ae()&&se(be(e,j),t)(),t in e)},set(){return!0},deleteProperty(){return!0},ownKeys:Lt,getOwnPropertyDescriptor:Nt};function Q(e,t,n,r=!1){if(!r&&e[t]===n)return;const s=e[t],l=e.length;n===void 0?(delete e[t],e[j]&&e[j][t]&&s!==void 0&&e[j][t].$()):(e[t]=n,e[j]&&e[j][t]&&s===void 0&&e[j][t].$());let i=be(e,q),o;if((o=se(i,t,s))&&o.$(()=>n),Array.isArray(e)&&e.length!==l){for(let a=e.length;a<l;a++)(o=i[a])&&o.$();(o=se(i,"length",l))&&o.$(e.length)}(o=i[Xe])&&o.$()}function Ze(e,t){const n=Object.keys(t);for(let r=0;r<n.length;r+=1){const s=n[r];Q(e,s,t[s])}}function jt(e,t){if(typeof t=="function"&&(t=t(e)),t=z(t),Array.isArray(t)){if(e===t)return;let n=0,r=t.length;for(;n<r;n++){const s=t[n];e[n]!==s&&Q(e,n,s)}Q(e,"length",r)}else Ze(e,t)}function ee(e,t,n=[]){let r,s=e;if(t.length>1){r=t.shift();const i=typeof r,o=Array.isArray(e);if(Array.isArray(r)){for(let a=0;a<r.length;a++)ee(e,[r[a]].concat(t),n);return}else if(o&&i==="function"){for(let a=0;a<e.length;a++)r(e[a],a)&&ee(e,[a].concat(t),n);return}else if(o&&i==="object"){const{from:a=0,to:u=e.length-1,by:f=1}=r;for(let c=a;c<=u;c+=f)ee(e,[c].concat(t),n);return}else if(t.length>1){ee(e[r],t,[r].concat(n));return}s=e[r],n=[r].concat(n)}let l=t[0];typeof l=="function"&&(l=l(s,n),l===s)||r===void 0&&l==null||(l=z(l),r===void 0||X(s)&&X(l)&&!Array.isArray(l)?Ze(s,l):Q(e,r,l))}function Dt(...[e,t]){const n=z(e||{}),r=Array.isArray(n),s=ze(n);function l(...i){ft(()=>{r&&i.length===1?jt(n,i[0]):ee(n,i)})}return[s,l]}const me=new WeakMap,et={get(e,t){if(t===he)return e;const n=e[t];let r;return X(n)?me.get(n)||(me.set(n,r=new Proxy(n,et)),r):n},set(e,t,n){return Q(e,t,z(n)),!0},deleteProperty(e,t){return Q(e,t,void 0,!0),!0}};function ye(e){return t=>{if(X(t)){let n;(n=me.get(t))||me.set(t,n=new Proxy(t,et)),e(n)}return t}}const[Mt,Bt]=x(0);setInterval(()=>Bt(e=>e+1),5e3);function Te(e){const t={};for(const n of e.backends)t[n.name]=n.state;for(const n of e.frontends){let r=0;for(let a=0;a<n.pools.length;a++){let u=!1;for(const f of n.pools[a].backends)if(t[f.name]==="up"&&f.weight>0){u=!0;break}if(u){r=a;break}}let s=!1,l=!1,i=!0;const o=new Set;for(let a=0;a<n.pools.length;a++)for(const u of n.pools[a].backends){const f=t[u.name];u.effective_weight=f==="up"&&a===r?u.weight:0,u.effective_weight>0&&(s=!0),o.has(u.name)||(o.add(u.name),l=!0,f!=="unknown"&&(i=!1))}!l||i?n.state="unknown":s?n.state="up":n.state="down"}}const[$e,ie]=Dt({byName:{}});function tt(e){const t={};for(const n of e)Te(n),t[n.maglevd.name]=n;ie({byName:t})}function Rt(e,t){ie(ye(n=>{const r=n.byName[e];if(!r)return;const s=r.backends.find(l=>l.name===t.backend);s&&(s.state=t.transition.to,s.enabled=t.transition.to!=="disabled",s.last_transition=t.transition,s.transitions||(s.transitions=[]),s.transitions.push(t.transition),s.transitions.length>20&&(s.transitions=s.transitions.slice(s.transitions.length-20)),Te(r))}))}function Ut(e,t){ie(ye(n=>{const r=n.byName[e];r&&(r.vpp_state=t)}))}function Vt(e,t){ie(ye(n=>{const r=n.byName[e];r&&(r.maglevd.connected=t.connected,r.maglevd.last_error=t.last_error)}))}function Ft(e,t,n,r,s){ie(ye(l=>{const i=l.byName[e];if(!i)return;const o=i.frontends.find(f=>f.name===t);if(!o)return;const a=o.pools.find(f=>f.name===n);if(!a)return;const u=a.backends.find(f=>f.name===r);u&&(u.weight=s,Te(i))}))}function Wt(e,t){return e.includes(":")?`[${e}]:${t}`:`${e}:${t}`}function Ht(e){if(Mt(),!e||!e.at_unix_ns||e.at_unix_ns<=0)return"";const t=Date.now()-e.at_unix_ns/1e6,n=Math.floor(t/1e3);if(n<=1)return"now";const r=n%60,s=Math.floor(n/60);if(s<1)return`${n}s ago`;const l=s%60,i=Math.floor(s/60);if(i<1)return`${l}m${r}s ago`;const o=i%24,a=Math.floor(i/24);return a<1?`${i}h${l}m ago`:`${a}d${o}h ago`}const Ue=500,[Ee,Gt]=x([]);function Kt(e){Gt(t=>{const n=[...t,e];return n.length>Ue?n.slice(n.length-Ue):n})}function qt(){const e=new EventSource("/view/api/events");return e.onmessage=t=>{try{const n=JSON.parse(t.data);Yt(n)}catch(n){console.error("sse parse error",n,t.data)}},e.addEventListener("resync",async()=>{try{const t=await Je();tt(t)}catch(t){console.error("resync refetch failed",t)}}),e.onerror=t=>{console.debug("sse error, browser will reconnect",t)},e}function Yt(e){switch(Kt(e),e.type){case"backend":Rt(e.maglevd,e.payload);break;case"frontend":e.maglevd,e.payload;break;case"maglevd-status":Vt(e.maglevd,e.payload);break;case"vpp-status":Ut(e.maglevd,e.payload.state);break}}const[_e,nt]=x(void 0);var Jt=h("<nav class=scope-selector>"),Xt=h("<button class=scope-tab><span class=dot>");const zt=()=>{const e=()=>Object.keys($e.byName).sort();return(()=>{var t=Jt();return d(t,g(J,{get each(){return e()},children:n=>{const r=()=>$e.byName[n],s=()=>r()?.maglevd.connected??!1;return(()=>{var l=Xt();return l.firstChild,l.$$click=()=>nt(n),d(l,n,null),C(i=>{var o=_e()===n,a=!!s(),u=!s(),f=r()?.maglevd.address??"";return o!==i.e&&l.classList.toggle("active",i.e=o),a!==i.t&&l.classList.toggle("connected",i.t=a),u!==i.a&&l.classList.toggle("disconnected",i.a=u),f!==i.o&&N(l,"title",i.o=f),i},{e:void 0,t:void 0,a:void 0,o:void 0}),l})()}})),t})()};we(["click"]);var Qt=h("<span class=status-badge>");const rt=e=>(()=>{var t=Qt();return d(t,()=>e.label??e.state),C(()=>N(t,"data-state",e.state)),t})();var Zt=h("<span class=probe-heartbeat>");const en="▶",tn="⏸",nn="⏹",rn="❤️",Ve=400;function sn(e){switch(e){case"paused":return tn;case"disabled":case"removed":return nn;default:return en}}const ln=e=>{const[t,n]=x(!1);let r,s;return H(()=>{const l=Ee();if(l.length===0)return;const i=l[l.length-1];if(i.type!=="log"||i.maglevd!==e.maglevd)return;const o=i.payload;o.attrs?.backend===e.backend&&o.msg==="probe-start"&&(n(!0),r?.animate([{transform:"scale(1)"},{transform:"scale(1.6)",offset:.25},{transform:"scale(1)"}],{duration:Ve,easing:"ease-out"}),s!==void 0&&clearTimeout(s),s=window.setTimeout(()=>{n(!1),s=void 0},Ve))}),Y(()=>{s!==void 0&&clearTimeout(s)}),(()=>{var l=Zt(),i=r;return typeof i=="function"?ve(i,l):r=l,d(l,(()=>{var o=L(()=>!!t());return()=>o()?rn:sn(e.state)})()),C(()=>l.classList.toggle("in-flight",!!t())),l})()};var on=h("<span class=flash-target>");const ne=e=>{let t;return H(dt(()=>e.value,()=>{t?.animate([{transform:"scale(1)",backgroundColor:"#facc15",boxShadow:"0 0 0 2px #facc15",offset:0},{transform:"scale(1.35)",backgroundColor:"#facc15",boxShadow:"0 0 0 4px #facc15",offset:.18},{transform:"scale(1)",backgroundColor:"#facc15",boxShadow:"0 0 0 2px #facc15",offset:.5},{transform:"scale(1)",backgroundColor:"transparent",boxShadow:"0 0 0 0 transparent",offset:1}],{duration:1500,easing:"ease-out"})},{defer:!0})),(()=>{var n=on(),r=t;return typeof r=="function"?ve(r,n):t=n,d(n,()=>e.children??e.value),n})()};async function an(e,t,n){const r=`/admin/api/${encodeURIComponent(e)}/backend/${encodeURIComponent(t)}/${n}`,s=await fetch(r,{method:"POST",credentials:"same-origin"});if(!s.ok){const l=(await s.text()).trim();throw new Error(l||`${s.status} ${s.statusText}`)}return await s.json()}async function cn(e,t,n,r,s,l){const i=`/admin/api/${encodeURIComponent(e)}/frontend/${encodeURIComponent(t)}/pool/${encodeURIComponent(n)}/backend/${encodeURIComponent(r)}/weight`,o=await fetch(i,{method:"POST",credentials:"same-origin",headers:{"Content-Type":"application/json"},body:JSON.stringify({weight:s,flush:l})});if(!o.ok){const a=(await o.text()).trim();throw new Error(a||`${o.status} ${o.statusText}`)}return await o.json()}var un=h("<div class=modal-backdrop><div class=modal-card role=dialog aria-modal=true><header class=modal-header><h3></h3><button type=button class=modal-close aria-label=close>×</button></header><div class=modal-body>");const fn=e=>(H(()=>{const t=n=>{n.key==="Escape"&&e.onClose()};document.addEventListener("keydown",t),Y(()=>document.removeEventListener("keydown",t))}),g(Ot,{get mount(){return document.body},get children(){var t=un(),n=t.firstChild,r=n.firstChild,s=r.firstChild,l=s.nextSibling,i=r.nextSibling;return t.$$mousedown=o=>{o.target===o.currentTarget&&e.onClose()},d(s,()=>e.title),At(l,"click",e.onClose),d(i,()=>e.children),C(()=>N(n,"aria-label",e.title)),t}}));we(["mousedown","click"]);var dn=h("<div class=kebab-menu role=menu>"),gn=h('<div class=kebab-wrap><button type=button class=kebab-btn aria-haspopup=menu title="backend actions">⋮'),hn=h("<button type=button class=kebab-item role=menuitem>"),bn=h("<p class=dialog-error>"),mn=h("<footer class=dialog-footer><button type=button class=btn-secondary>cancel</button><button type=button class=btn-primary>"),$n=h("<p class=dialog-warn>VPP's flow table will be cleared for this backend. Active sessions will be dropped immediately."),pn=h('<div class=dialog-body><p class=dialog-target><code></code> in pool <code></code> of frontend <code></code></p><label class=dialog-field><span class=weight-slider-label>weight<output class=weight-slider-value></output></span><input type=range class=weight-slider min=0 max=100 step=1><small>0–100; 0 keeps the backend in the pool but assigns it no traffic</small></label><label class="dialog-field checkbox"><input type=checkbox><span>flush existing flows'),wn=h("<p class=dialog-note>VPP's flow table is left alone. Existing sessions keep reaching this backend until they finish."),vn=h("<div class=dialog-body><p class=dialog-consequence>");function yn(e){const t={label:"set weight…",action:"weight"};switch(e){case"up":case"down":case"unknown":return[t,{label:"pause",action:"pause"},{label:"disable",action:"disable"}];case"paused":return[t,{label:"resume",action:"resume"},{label:"disable",action:"disable"}];case"disabled":return[t,{label:"enable",action:"enable"}];default:return[]}}function _n(e){switch(e){case"pause":return"This will stop health checks and set the weight to 0, but existing flows to this backend are kept. New traffic will be rerouted to other backends.";case"resume":return"This will restart health checks. The backend re-enters the 'unknown' state and will start receiving traffic once it probes up.";case"disable":return"This will stop health checks, set the weight to 0, AND flush VPP's flow table for this backend. Active sessions will be dropped immediately.";case"enable":return"This will restart health checks on a previously disabled backend. It re-enters the 'unknown' state and will start receiving traffic once it probes up."}}const kn=e=>{const[t,n]=x(!1),[r,s]=x(),[l,i]=x(!1),[o,a]=x(),[u,f]=x(e.configuredWeight),[c,$]=x(!1);let b;const y=()=>yn(e.state);H(()=>{if(!t())return;const m=_=>{b&&(b.contains(_.target)||n(!1))},w=_=>{_.key==="Escape"&&n(!1)};document.addEventListener("mousedown",m),document.addEventListener("keydown",w),Y(()=>{document.removeEventListener("mousedown",m),document.removeEventListener("keydown",w)})});const S=m=>{n(!1),a(void 0),m==="weight"&&(f(e.configuredWeight),$(!1)),s(m)},P=()=>{l()||(s(void 0),a(void 0))},B=async()=>{const m=r();if(m){i(!0),a(void 0);try{if(m==="weight"){const w=u();if(!Number.isFinite(w)||w<0||w>100)throw new Error("weight must be an integer in [0, 100]");const _=Math.floor(w);await cn(e.maglevd,e.frontend,e.pool,e.backend,_,c()),Ft(e.maglevd,e.frontend,e.pool,e.backend,_)}else await an(e.maglevd,e.backend,m);s(void 0)}catch(w){a(`${w}`)}finally{i(!1)}}};return g(O,{get when(){return y().length>0},get children(){var m=gn(),w=m.firstChild,_=b;return typeof _=="function"?ve(_,m):b=m,w.$$click=A=>{A.stopPropagation(),n(k=>!k)},d(m,g(O,{get when(){return t()},get children(){var A=dn();return d(A,g(J,{get each(){return y()},children:k=>(()=>{var T=hn();return T.$$click=()=>S(k.action),d(T,()=>k.label),T})()})),A}}),null),d(m,g(O,{get when(){return r()},children:A=>g(fn,{get title(){return Sn(A(),e.backend)},onClose:P,get children(){return[L(()=>L(()=>A()==="weight")()?(()=>{var k=pn(),T=k.firstChild,V=T.firstChild,I=V.nextSibling,Z=I.nextSibling,oe=Z.nextSibling,ae=oe.nextSibling,Le=T.nextSibling,Ie=Le.firstChild,lt=Ie.firstChild,it=lt.nextSibling,je=Ie.nextSibling,ot=Le.nextSibling,De=ot.firstChild;return d(V,()=>e.backend),d(Z,()=>e.pool),d(ae,()=>e.frontend),d(it,u),je.$$input=ke=>f(Number(ke.currentTarget.value)),De.addEventListener("change",ke=>$(ke.currentTarget.checked)),d(k,g(O,{get when(){return c()},get fallback(){return wn()},get children(){return $n()}}),null),C(()=>je.value=u()),C(()=>De.checked=c()),k})():(()=>{var k=vn(),T=k.firstChild;return d(T,()=>_n(A())),k})()),g(O,{get when(){return o()},get children(){var k=bn();return d(k,o),k}}),(()=>{var k=mn(),T=k.firstChild,V=T.nextSibling;return T.$$click=P,V.$$click=B,d(V,()=>l()?"committing…":"commit"),C(I=>{var Z=l(),oe=!!(A()==="disable"||A()==="weight"&&c()),ae=l();return Z!==I.e&&(T.disabled=I.e=Z),oe!==I.t&&V.classList.toggle("btn-danger",I.t=oe),ae!==I.a&&(V.disabled=I.a=ae),I},{e:void 0,t:void 0,a:void 0}),k})()]}})}),null),C(()=>N(w,"aria-expanded",t())),m}})};function Sn(e,t){switch(e){case"weight":return`Set weight — ${t}`;case"pause":return`Pause ${t}?`;case"resume":return`Resume ${t}?`;case"disable":return`Disable ${t}?`;case"enable":return`Enable ${t}?`}}we(["click","input"]);const R=window.location.pathname.startsWith("/admin");var xn=h("<td class=actions>"),An=h("<tr class=backend-row><td class=col-pool></td><td class=backend-name><span class=backend-name-text></span></td><td class=backend-address></td><td></td><td class=numeric></td><td class=numeric></td><td class=age>");const Cn=e=>{const t=()=>e.backend;return(()=>{var n=An(),r=n.firstChild,s=r.nextSibling,l=s.firstChild,i=s.nextSibling,o=i.nextSibling,a=o.nextSibling,u=a.nextSibling,f=u.nextSibling;return d(r,(()=>{var c=L(()=>!!e.showPool);return()=>c()?e.pool:""})()),d(s,g(ln,{get maglevd(){return e.maglevd},get backend(){return t().name},get state(){return t().state}}),l),d(l,()=>t().name),d(i,()=>t().address),d(o,g(ne,{get value(){return t().state},get children(){return g(rt,{get state(){return t().state}})}})),d(a,g(ne,{get value(){return e.poolBackend.weight}})),d(u,g(ne,{get value(){return e.poolBackend.effective_weight}})),d(f,()=>Ht(t().last_transition)),d(n,g(O,{when:R,get children(){var c=xn();return d(c,g(kn,{get maglevd(){return e.maglevd},get frontend(){return e.frontend},get pool(){return e.pool},get backend(){return t().name},get state(){return t().state},get configuredWeight(){return e.poolBackend.weight}})),c}}),null),C(c=>{var $=!e.poolActive,b=t().state;return $!==c.e&&n.classList.toggle("pool-standby",c.e=$),b!==c.t&&N(n,"data-state",c.t=b),c},{e:void 0,t:void 0}),n})()};var En=h("<details class=zippy><summary></summary><div class=zippy-body>");const Ne=e=>(()=>{var t=En(),n=t.firstChild,r=n.nextSibling;return d(n,()=>e.title),d(r,()=>e.children),C(()=>t.open=e.open),t})();var Pn=h("<span class=frontend-title><span class=frontend-title-name></span><span class=frontend-title-addr></span><span class=frontend-title-proto>"),On=h("<span class=tag>sticky"),Tn=h("<span class=frontend-title-desc>"),Nn=h('<th class="col-actions actions">'),Ln=h('<table class=backend-table><thead><tr><th class=col-pool>pool</th><th class=col-name>backend</th><th class=col-address>address</th><th class=col-state>state</th><th class="col-weight numeric">weight</th><th class="col-effective numeric">effective</th><th class=col-age>last transition</th></tr></thead><tbody>');const In=e=>{const t=()=>Object.fromEntries(e.snap.backends.map(s=>[s.name,s])),n=()=>e.frontend,r=(()=>{var s=Pn(),l=s.firstChild,i=l.nextSibling,o=i.nextSibling;return d(l,()=>n().name),d(s,g(ne,{get value(){return n().state??"unknown"},get children(){return g(rt,{get state(){return n().state??"unknown"}})}}),i),d(i,()=>Wt(n().address,n().port)),d(o,()=>n().protocol.toUpperCase()),d(s,(()=>{var a=L(()=>!!n().src_ip_sticky);return()=>a()&&On()})(),null),d(s,(()=>{var a=L(()=>!!n().description);return()=>a()&&(()=>{var u=Tn();return d(u,()=>n().description),u})()})(),null),s})();return g(Ne,{title:r,open:!0,get children(){var s=Ln(),l=s.firstChild,i=l.firstChild,o=i.firstChild,a=o.nextSibling,u=a.nextSibling,f=u.nextSibling,c=f.nextSibling,$=c.nextSibling;$.nextSibling;var b=l.nextSibling;return d(i,g(O,{when:R,get children(){return Nn()}}),null),d(b,g(J,{get each(){return n().pools},children:y=>{const S=()=>y.backends.some(P=>P.effective_weight>0);return g(J,{get each(){return y.backends},children:(P,B)=>{const m=t()[P.name];return m?g(Cn,{get maglevd(){return e.snap.maglevd.name},get frontend(){return n().name},get pool(){return y.name},get showPool(){return B()===0},get poolActive(){return S()},backend:m,poolBackend:P}):null}})}})),s}})};var jn=h("<span class=vpp-badge>"),Dn=h("<span class=zippy-title>VPP"),Mn=h("<p class=empty>No VPP information available."),Bn=h("<dl class=kv><dt>version</dt><dd></dd><dt>build date</dt><dd></dd><dt>pid</dt><dd></dd><dt>booted</dt><dd></dd><dt>connected</dt><dd>");const Rn=e=>{const t=()=>e.info?.boottime_ns?new Date(e.info.boottime_ns/1e6).toISOString():"",n=()=>e.info?.connecttime_ns?new Date(e.info.connecttime_ns/1e6).toISOString():"",r=()=>e.state==="connected"?"connected":"disconnected",s=(()=>{var l=Dn();return l.firstChild,d(l,g(ne,{get value(){return r()},get children(){var i=jn();return d(i,r),C(()=>N(i,"data-state",r())),i}}),null),l})();return g(Ne,{title:s,get children(){return g(O,{get when(){return e.info},get fallback(){return Mn()},children:l=>(()=>{var i=Bn(),o=i.firstChild,a=o.nextSibling,u=a.nextSibling,f=u.nextSibling,c=f.nextSibling,$=c.nextSibling,b=$.nextSibling,y=b.nextSibling,S=y.nextSibling,P=S.nextSibling;return d(a,()=>l().version),d(f,()=>l().build_date),d($,()=>l().pid),d(y,t),d(P,n),i})()})}})};var Un=h("<main class=overview>"),Vn=h("<p class=empty>No maglevd selected."),Fn=h('<div class="banner warn"> disconnected'),Wn=h("<div class=frontend-list>");const Hn=()=>{const e=()=>{const t=_e();return t?$e.byName[t]:void 0};return(()=>{var t=Un();return d(t,g(O,{get when(){return e()},get fallback(){return Vn()},children:n=>[g(O,{get when(){return!n().maglevd.connected},get children(){var r=Fn(),s=r.firstChild;return d(r,()=>n().maglevd.name,s),d(r,(()=>{var l=L(()=>!!n().maglevd.last_error);return()=>l()&&`: ${n().maglevd.last_error}`})(),null),r}}),(()=>{var r=Wn();return d(r,g(J,{get each(){return n().frontends},children:s=>g(In,{get snap(){return n()},frontend:s})})),r})(),g(Rn,{get info(){return n().vpp_info},get state(){return n().vpp_state}})]})),t})()};var Gn=h("<ol class=event-tail>"),Kn=h("<div class=debug-toolbar><label><input type=checkbox>all maglevds</label><button></button><span class=count> events"),qn=h("<li>");const Yn=()=>{const[e,t]=x(!1),[n,r]=x(!1),[s,l]=x([]),i=F(()=>{const u=n()?s():Ee();if(e())return u;const f=_e();return f?u.filter(c=>c.maglevd===f):u}),o=()=>{n()?r(!1):(l([...Ee()]),r(!0))};let a;return H(()=>{i(),!n()&&a&&(a.scrollTop=a.scrollHeight)}),g(Ne,{title:"Event stream",get children(){return[(()=>{var u=Gn(),f=a;return typeof f=="function"?ve(f,u):a=u,d(u,g(J,{get each(){return i()},children:c=>(()=>{var $=qn();return d($,()=>zn(c)),C(b=>{var y=`event-row event-${c.type}`,S=!!Jn(c);return y!==b.e&&xt($,b.e=y),S!==b.t&&$.classList.toggle("event-sync",b.t=S),b},{e:void 0,t:void 0}),$})()})),u})(),(()=>{var u=Kn(),f=u.firstChild,c=f.firstChild,$=f.nextSibling,b=$.nextSibling,y=b.firstChild;return c.addEventListener("change",S=>t(S.currentTarget.checked)),$.$$click=o,d($,()=>n()?"resume":"pause"),d(b,()=>i().length,y),C(()=>c.checked=e()),u})()]}})};function Jn(e){return e.type!=="log"?!1:e.payload.msg.startsWith("vpp-lb-sync-")}function Xn(e){if(!e)return"";const t=["vip","protocol","port","address","weight","from","to","encap","src-ip-sticky","flush"],n=[],r=new Set;for(const s of t)s in e&&(n.push(`${s}=${e[s]}`),r.add(s));for(const[s,l]of Object.entries(e))r.has(s)||n.push(`${s}=${l}`);return n.join(" ")}function zn(e){const t=new Date(e.at_unix_ns/1e6).toISOString().substring(11,23),n=`[${e.maglevd}]`;switch(e.type){case"backend":{const r=e.payload;return`${t} ${n} backend ${r.backend}: ${r.transition.from} → ${r.transition.to}`}case"frontend":{const r=e.payload;return`${t} ${n} frontend ${r.frontend}: ${r.transition.from} → ${r.transition.to}`}case"log":{const r=e.payload;if(r.msg.startsWith("vpp-lb-sync-"))return`${t} ${n} ${r.msg} ${Xn(r.attrs)}`.trimEnd();const s=r.attrs?Object.entries(r.attrs).map(([l,i])=>`${l}=${i}`).join(" "):"";return`${t} ${n} ${r.level} ${r.msg} ${s}`.trimEnd()}case"maglevd-status":return`${t} ${n} maglevd status: ${JSON.stringify(e.payload)}`;default:return`${t} ${n} ${e.type}`}}we(["click"]);const Qn="/view/assets/logo-bimi-Bguc6E_L.svg";var Zn=h("<span class=mode-tag>"),er=h("<a class=admin-toggle>"),tr=h('<div class=app><header class=app-header><div class=brand><a class=brand-logo href=https://ipng.ch/ target=_blank rel=noopener title="IPng Networks"><img alt=IPng></a><a class=brand-name href=https://git.ipng.ch/ipng/vpp-maglev target=_blank rel=noopener title="vpp-maglev on git.ipng.ch"><strong>vpp-maglev'),nr=h("<span class=version> (<!>)"),rr=h('<div class="banner err">'),sr=h("<p class=loading>Loading…");const lr=()=>{const[e,t]=x(),[n,r]=x();gt(async()=>{try{const[l,i]=await Promise.all([Je(),Tt()]);tt(l),r(i),!_e()&&l.length>0&&nt(l[0].maglevd.name),qt()}catch(l){t(`${l}`)}});const s=()=>n()?.admin_enabled===!0;return(()=>{var l=tr(),i=l.firstChild,o=i.firstChild,a=o.firstChild,u=a.firstChild;return a.nextSibling,N(u,"src",Qn),d(o,(()=>{var f=L(()=>!!n());return()=>f()&&(()=>{var c=nr(),$=c.firstChild,b=$.nextSibling;return b.nextSibling,d(c,()=>n().version,$),d(c,()=>n().commit,b),C(()=>N(c,"title",`commit ${n().commit} · built ${n().date}`)),c})()})(),null),d(i,g(zt,{}),null),d(i,g(O,{get when(){return R||s()},get children(){var f=Zn();return d(f,R?"admin":"view"),f}}),null),d(i,g(O,{get when(){return s()},get children(){var f=er();return N(f,"href",R?"/view/":"/admin/"),N(f,"title",R?"exit admin mode":"enter admin mode"),d(f,R?"exit admin":"admin…"),f}}),null),d(l,(()=>{var f=L(()=>!!e());return()=>f()&&(()=>{var c=rr();return d(c,e),c})()})(),null),d(l,(()=>{var f=L(()=>!e()&&Object.keys($e.byName).length===0);return()=>f()&&sr()})(),null),d(l,g(Hn,{}),null),d(l,g(O,{when:R,get children(){return g(Yn,{})}}),null),l})()},st=document.getElementById("root");if(!st)throw new Error("no #root element");St(()=>g(lr,{}),st);
|