Checker / reload:
- Reload's update-in-place branch now mirrors b.Address onto the
runtime health.Backend. Without this, GetBackend kept returning
the pre-reload address indefinitely after a config edit that
touched addresses but not healthcheck settings — the VPP sync
path reads cfg.Backends directly so the dataplane moved on
while the gRPC and SPA view stayed wedged on the old IPv4/IPv6.
Sync (internal/vpp/lbsync.go):
- reconcileVIP now detects encap mismatch in addition to
src-ip-sticky mismatch and takes the full tear-down / re-add
path via a new shared recreateVIP helper. Triggered when every
backend flips address family (gre4 <-> gre6) and the existing
VIP can no longer accept new ASes — previously the sync wedged
with 'Invalid address family' until a full maglevd restart.
- setASWeight is issued whenever the state machine requests
flush (a.Flush=true), not only on the weight-value transition
edge. Fixes the case where a backend reached StateDisabled
after its effective weight had already been drained to 0 by
pool failover — the sticky-cache entries pointing at it were
previously never cleared.
maglev-frontend:
- signal.Ignore(SIGHUP) so a controlling-terminal disconnect
doesn't kill the daemon.
- debian/vpp-maglev.service grants CAP_SYS_ADMIN in addition to
CAP_NET_RAW so setns(CLONE_NEWNET) can join the healthcheck
netns. Comment documents the 'operation not permitted' symptom
and notes the knob can be dropped if the deployment doesn't use
the 'netns:' healthcheck option.
LB plugin counters (internal/vpp/lbstats.go + friends):
- Fix the VIP counter regex: the LB plugin registers
vlib_simple_counter_main_t names without a leading '/'
(vlib_validate_simple_counter in counter.c:50 uses cm->name
verbatim; only entries that set cm->stat_segment_name get a
slash). first/next/untracked/no-server now read through as
live values instead of zero.
- Drop the per-backend FIB counter block end-to-end (proto,
grpcapi, metrics, vpp.Client, lbstats, maglevc). Traced from
lb/node.c:558 into ip{4,6}_forward.h:141 — the LB plugin
forwards by writing adj_index[VLIB_TX] directly and bypassing
ip{4,6}_lookup_inline, which is the only path that increments
lbm_to_counters. The backend's FIB load_balance stats_index
literally never ticks for LB-forwarded traffic, so the column
was always zero and misleading. docs/implementation/TODO
records the full investigation and the recommended upstream
path (new lb_as_stats_dump API message) for when we're ready
to carry that VPP patch.
- maglevc show vpp lb counters: plain-text tabular headers.
label() wraps strings in ANSI escapes (~11 bytes of overhead),
but tabwriter counts bytes, not rendered width — so a header
row with label()'d cells and data rows with plain cells drifts
column alignment on every row. color.go comment now spells
out the constraint: label() only works when column N is
wrapped identically in every row (key-value layouts are fine,
multi-column tables with header-only labelling are not).
SPA:
- stores/scope.ts is cookie-backed (maglev_scope, 1 year,
SameSite=Lax). App.tsx hydrates from the cookie then validates
against the fetched snapshots: a cookie referencing a maglevd
that no longer exists falls through to snaps[0] instead of
leaving the user on a ghost selection.
- components/Flash.tsx wraps props.value in createMemo. Solid's
on() fires its callback on every dep notification, not on
value change — source is right in solid-js/dist/solid.js:460,
no equality check. Without the memo, flipping scope between
two 'connected' maglevds (or any other cross-store reactive
re-eval that doesn't actually change the concrete string)
replays the animation every time. createMemo's default ===
dedupe fixes it in one place for every Flash consumer,
superseding the local createMemo workaround we'd added in
BackendRow earlier.
2 lines
39 KiB
JavaScript
2 lines
39 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 i of s)if(i.type==="childList")for(const o of i.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&r(o)}).observe(document,{childList:!0,subtree:!0});function n(s){const i={};return s.integrity&&(i.integrity=s.integrity),s.referrerPolicy&&(i.referrerPolicy=s.referrerPolicy),s.crossOrigin==="use-credentials"?i.credentials="include":s.crossOrigin==="anonymous"?i.credentials="omit":i.credentials="same-origin",i}function r(s){if(s.ep)return;s.ep=!0;const i=n(s);fetch(s.href,i)}})();const gt=!1,ht=(e,t)=>e===t,G=Symbol("solid-proxy"),Ce=Symbol("solid-track"),de={equals:ht};let Ke=Ye;const V=1,ge=2,Ge={owned:null,cleanups:null,context:null,owner:null};var k=null;let Ee=null,bt=null,_=null,O=null,R=null,_e=0;function ie(e,t){const n=_,r=k,s=e.length===0,i=t===void 0?r:t,o=s?Ge:{owned:null,cleanups:null,context:i?i.context:null,owner:i},l=s?e:()=>e(()=>U(()=>oe(o)));k=o,_=null;try{return Y(l,!0)}finally{_=n,k=r}}function A(e,t){t=t?Object.assign({},de,t):de;const n={value:e,observers:null,observerSlots:null,comparator:t.equals||void 0},r=s=>(typeof s=="function"&&(s=s(n.value)),Xe(n,s));return[qe.bind(n),r]}function E(e,t,n){const r=Le(e,t,!1,V);ce(r)}function K(e,t,n){Ke=kt;const r=Le(e,t,!1,V);(!n||!n.render)&&(r.user=!0),R?R.push(r):ce(r)}function B(e,t,n){n=n?Object.assign({},de,n):de;const r=Le(e,t,!0,0);return r.observers=null,r.observerSlots=null,r.comparator=n.equals||void 0,ce(r),qe.bind(r)}function mt(e){return Y(e,!1)}function U(e){if(_===null)return e();const t=_;_=null;try{return e()}finally{_=t}}function pt(e,t,n){const r=Array.isArray(e);let s,i=n&&n.defer;return o=>{let l;if(r){l=Array(e.length);for(let c=0;c<e.length;c++)l[c]=e[c]()}else l=e();if(i)return i=!1,o;const a=U(()=>t(l,s,o));return s=l,a}}function $t(e){K(()=>U(e))}function q(e){return k===null||(k.cleanups===null?k.cleanups=[e]:k.cleanups.push(e)),e}function Oe(){return _}function vt(){return k}function wt(e,t){const n=k,r=_;k=e,_=null;try{return Y(t,!0)}catch(s){Ne(s)}finally{k=n,_=r}}function qe(){if(this.sources&&this.state)if(this.state===V)ce(this);else{const e=O;O=null,Y(()=>be(this),!1),O=e}if(_){const e=this.observers?this.observers.length:0;_.sources?(_.sources.push(this),_.sourceSlots.push(e)):(_.sources=[this],_.sourceSlots=[e]),this.observers?(this.observers.push(_),this.observerSlots.push(_.sources.length-1)):(this.observers=[_],this.observerSlots=[_.sources.length-1])}return this.value}function Xe(e,t,n){let r=e.value;return(!e.comparator||!e.comparator(r,t))&&(e.value=t,e.observers&&e.observers.length&&Y(()=>{for(let s=0;s<e.observers.length;s+=1){const i=e.observers[s],o=Ee&&Ee.running;o&&Ee.disposed.has(i),(o?!i.tState:!i.state)&&(i.pure?O.push(i):R.push(i),i.observers&&Je(i)),o||(i.state=V)}if(O.length>1e6)throw O=[],new Error},!1)),t}function ce(e){if(!e.fn)return;oe(e);const t=_e;yt(e,e.value,t)}function yt(e,t,n){let r;const s=k,i=_;_=k=e;try{r=e.fn(t)}catch(o){return e.pure&&(e.state=V,e.owned&&e.owned.forEach(oe),e.owned=null),e.updatedAt=n+1,Ne(o)}finally{_=i,k=s}(!e.updatedAt||e.updatedAt<=n)&&(e.updatedAt!=null&&"observers"in e?Xe(e,r):e.value=r,e.updatedAt=n)}function Le(e,t,n,r=V,s){const i={fn:e,state:r,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:t,owner:k,context:k?k.context:null,pure:n};return k===null||k!==Ge&&(k.owned?k.owned.push(i):k.owned=[i]),i}function he(e){if(e.state===0)return;if(e.state===ge)return be(e);if(e.suspense&&U(e.suspense.inFallback))return e.suspense.effects.push(e);const t=[e];for(;(e=e.owner)&&(!e.updatedAt||e.updatedAt<_e);)e.state&&t.push(e);for(let n=t.length-1;n>=0;n--)if(e=t[n],e.state===V)ce(e);else if(e.state===ge){const r=O;O=null,Y(()=>be(e,t[0]),!1),O=r}}function Y(e,t){if(O)return e();let n=!1;t||(O=[]),R?n=!0:R=[],_e++;try{const r=e();return _t(n),r}catch(r){n||(R=null),O=null,Ne(r)}}function _t(e){if(O&&(Ye(O),O=null),e)return;const t=R;R=null,t.length&&Y(()=>Ke(t),!1)}function Ye(e){for(let t=0;t<e.length;t++)he(e[t])}function kt(e){let t,n=0;for(t=0;t<e.length;t++){const r=e[t];r.user?e[n++]=r:he(r)}for(t=0;t<n;t++)he(e[t])}function be(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===V?r!==t&&(!r.updatedAt||r.updatedAt<_e)&&he(r):s===ge&&be(r,t)}}}function Je(e){for(let t=0;t<e.observers.length;t+=1){const n=e.observers[t];n.state||(n.state=ge,n.pure?O.push(n):R.push(n),n.observers&&Je(n))}}function oe(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 i=s.pop(),o=n.observerSlots.pop();r<s.length&&(i.sourceSlots[o]=r,s[r]=i,n.observerSlots[r]=o)}}if(e.tOwned){for(t=e.tOwned.length-1;t>=0;t--)oe(e.tOwned[t]);delete e.tOwned}if(e.owned){for(t=e.owned.length-1;t>=0;t--)oe(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 St(e){return e instanceof Error?e:new Error(typeof e=="string"?e:"Unknown error",{cause:e})}function Ne(e,t=k){throw St(e)}const xt=Symbol("fallback");function Ue(e){for(let t=0;t<e.length;t++)e[t]()}function At(e,t,n={}){let r=[],s=[],i=[],o=0,l=t.length>1?[]:null;return q(()=>Ue(i)),()=>{let a=e()||[],c=a.length,u,f;return a[Ce],U(()=>{let g,w,v,T,C,p,m,y,S;if(c===0)o!==0&&(Ue(i),i=[],r=[],s=[],o=0,l&&(l=[])),n.fallback&&(r=[xt],s[0]=ie(x=>(i[0]=x,n.fallback())),o=1);else if(o===0){for(s=new Array(c),f=0;f<c;f++)r[f]=a[f],s[f]=ie($);o=c}else{for(v=new Array(c),T=new Array(c),l&&(C=new Array(c)),p=0,m=Math.min(o,c);p<m&&r[p]===a[p];p++);for(m=o-1,y=c-1;m>=p&&y>=p&&r[m]===a[y];m--,y--)v[y]=s[m],T[y]=i[m],l&&(C[y]=l[m]);for(g=new Map,w=new Array(y+1),f=y;f>=p;f--)S=a[f],u=g.get(S),w[f]=u===void 0?-1:u,g.set(S,f);for(u=p;u<=m;u++)S=r[u],f=g.get(S),f!==void 0&&f!==-1?(v[f]=s[u],T[f]=i[u],l&&(C[f]=l[u]),f=w[f],g.set(S,f)):i[u]();for(f=p;f<c;f++)f in v?(s[f]=v[f],i[f]=T[f],l&&(l[f]=C[f],l[f](f))):s[f]=ie($);s=s.slice(0,o=c),r=a.slice(0)}return s});function $(g){if(i[f]=g,l){const[w,v]=A(f);return l[f]=v,t(a[f],w)}return t(a[f])}}}function h(e,t){return U(()=>e(t||{}))}const Et=e=>`Stale read from <${e}>.`;function Q(e){const t="fallback"in e&&{fallback:()=>e.fallback};return B(At(()=>e.each,e.children,t||void 0))}function L(e){const t=e.keyed,n=B(()=>e.when,void 0,void 0),r=t?n:B(n,void 0,{equals:(s,i)=>!s==!i});return B(()=>{const s=r();if(s){const i=e.children;return typeof i=="function"&&i.length>0?U(()=>i(t?s:()=>{if(!U(r))throw Et("Show");return n()})):i}return e.fallback},void 0,void 0)}const I=e=>B(()=>e());function Ct(e,t,n){let r=n.length,s=t.length,i=r,o=0,l=0,a=t[s-1].nextSibling,c=null;for(;o<s||l<i;){if(t[o]===n[l]){o++,l++;continue}for(;t[s-1]===n[i-1];)s--,i--;if(s===o){const u=i<r?l?n[l-1].nextSibling:n[i-l]:a;for(;l<i;)e.insertBefore(n[l++],u)}else if(i===l)for(;o<s;)(!c||!c.has(t[o]))&&t[o].remove(),o++;else if(t[o]===n[i-1]&&n[l]===t[s-1]){const u=t[--s].nextSibling;e.insertBefore(n[l++],t[o++].nextSibling),e.insertBefore(n[--i],u),t[s]=n[i]}else{if(!c){c=new Map;let f=l;for(;f<i;)c.set(n[f],f++)}const u=c.get(t[o]);if(u!=null)if(l<u&&u<i){let f=o,$=1,g;for(;++f<s&&f<i&&!((g=c.get(t[f]))==null||g!==u+$);)$++;if($>u-l){const w=t[o];for(;l<u;)e.insertBefore(n[l++],w)}else e.replaceChild(n[l++],t[o++])}else o++;else t[o++].remove()}}}const We="_$DX_DELEGATE";function Ot(e,t,n,r={}){let s;return ie(i=>{s=i,t===document?e():d(t,e(),t.firstChild?null:void 0,n)},r.owner),()=>{s(),t.textContent=""}}function b(e,t,n,r){let s;const i=()=>{const l=document.createElement("template");return l.innerHTML=e,l.content.firstChild},o=()=>(s||(s=i())).cloneNode(!0);return o.cloneNode=o,o}function ke(e,t=window.document){const n=t[We]||(t[We]=new Set);for(let r=0,s=e.length;r<s;r++){const i=e[r];n.has(i)||(n.add(i),t.addEventListener(i,Lt))}}function N(e,t,n){n==null?e.removeAttribute(t):e.setAttribute(t,n)}function Tt(e,t){t==null?e.removeAttribute("class"):e.className=t}function Pt(e,t,n,r){Array.isArray(n)?(e[`$$${t}`]=n[0],e[`$$${t}Data`]=n[1]):e[`$$${t}`]=n}function Se(e,t,n){return U(()=>e(t,n))}function d(e,t,n,r){if(n!==void 0&&!r&&(r=[]),typeof t!="function")return me(e,t,r,n);E(s=>me(e,t(),s,n),r)}function Lt(e){let t=e.target;const n=`$$${e.type}`,r=e.target,s=e.currentTarget,i=a=>Object.defineProperty(e,"target",{configurable:!0,value:a}),o=()=>{const a=t[n];if(a&&!t.disabled){const c=t[`${n}Data`];if(c!==void 0?a.call(t,c,e):a.call(t,e),e.cancelBubble)return}return t.host&&typeof t.host!="string"&&!t.host._$host&&t.contains(e.target)&&i(t.host),!0},l=()=>{for(;o()&&(t=t._$host||t.parentNode||t.host););};if(Object.defineProperty(e,"currentTarget",{configurable:!0,get(){return t||document}}),e.composedPath){const a=e.composedPath();i(a[0]);for(let c=0;c<a.length-2&&(t=a[c],!!o());c++){if(t._$host){t=t._$host,l();break}if(t.parentNode===s)break}}else l();i(r)}function me(e,t,n,r,s){for(;typeof n=="function";)n=n();if(t===n)return n;const i=typeof t,o=r!==void 0;if(e=o&&n[0]&&n[0].parentNode||e,i==="string"||i==="number"){if(i==="number"&&(t=t.toString(),t===n))return n;if(o){let l=n[0];l&&l.nodeType===3?l.data!==t&&(l.data=t):l=document.createTextNode(t),n=J(e,n,r,l)}else n!==""&&typeof n=="string"?n=e.firstChild.data=t:n=e.textContent=t}else if(t==null||i==="boolean")n=J(e,n,r);else{if(i==="function")return E(()=>{let l=t();for(;typeof l=="function";)l=l();n=me(e,l,n,r)}),()=>n;if(Array.isArray(t)){const l=[],a=n&&Array.isArray(n);if(Te(l,t,n,s))return E(()=>n=me(e,l,n,r,!0)),()=>n;if(l.length===0){if(n=J(e,n,r),o)return n}else a?n.length===0?He(e,l,r):Ct(e,n,l):(n&&J(e),He(e,l));n=l}else if(t.nodeType){if(Array.isArray(n)){if(o)return n=J(e,n,r,t);J(e,n,null,t)}else n==null||n===""||!e.firstChild?e.appendChild(t):e.replaceChild(t,e.firstChild);n=t}}return n}function Te(e,t,n,r){let s=!1;for(let i=0,o=t.length;i<o;i++){let l=t[i],a=n&&n[e.length],c;if(!(l==null||l===!0||l===!1))if((c=typeof l)=="object"&&l.nodeType)e.push(l);else if(Array.isArray(l))s=Te(e,l,a)||s;else if(c==="function")if(r){for(;typeof l=="function";)l=l();s=Te(e,Array.isArray(l)?l:[l],Array.isArray(a)?a:[a])||s}else e.push(l),s=!0;else{const u=String(l);a&&a.nodeType===3&&a.data===u?e.push(a):e.push(document.createTextNode(u))}}return s}function He(e,t,n=null){for(let r=0,s=t.length;r<s;r++)e.insertBefore(t[r],n)}function J(e,t,n,r){if(n===void 0)return e.textContent="";const s=r||document.createTextNode("");if(t.length){let i=!1;for(let o=t.length-1;o>=0;o--){const l=t[o];if(s!==l){const a=l.parentNode===e;!i&&!o?a?e.replaceChild(s,l):e.insertBefore(s,n):a&&l.remove()}else i=!0}}else e.insertBefore(s,n);return[s]}const Nt="http://www.w3.org/2000/svg";function It(e,t=!1,n=void 0){return t?document.createElementNS(Nt,e):document.createElement(e,{is:n})}function Mt(e){const{useShadow:t}=e,n=document.createTextNode(""),r=()=>e.mount||document.body,s=vt();let i;return K(()=>{i||(i=wt(s,()=>B(()=>e.children)));const o=r();if(o instanceof HTMLHeadElement){const[l,a]=A(!1),c=()=>a(!0);ie(u=>d(o,()=>l()?u():i(),null)),q(c)}else{const l=It(e.isSVG?"g":"div",e.isSVG),a=t&&l.attachShadow?l.attachShadow({mode:"open"}):l;Object.defineProperty(l,"_$host",{get(){return n.parentNode},configurable:!0}),d(a,i),o.appendChild(l),e.ref&&e.ref(l),q(()=>o.removeChild(l))}},void 0,{render:!0}),n}async function Ze(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 ze(){return Ze("/view/api/state")}function jt(){return Ze("/view/api/version")}const pe=Symbol("store-raw"),z=Symbol("store-node"),D=Symbol("store-has"),Qe=Symbol("store-self");function et(e){let t=e[G];if(!t&&(Object.defineProperty(e,G,{value:t=new Proxy(e,Bt)}),!Array.isArray(e))){const n=Object.keys(e),r=Object.getOwnPropertyDescriptors(e);for(let s=0,i=n.length;s<i;s++){const o=n[s];r[o].get&&Object.defineProperty(e,o,{enumerable:r[o].enumerable,get:r[o].get.bind(t)})}}return t}function ee(e){let t;return e!=null&&typeof e=="object"&&(e[G]||!(t=Object.getPrototypeOf(e))||t===Object.prototype||Array.isArray(e))}function te(e,t=new Set){let n,r,s,i;if(n=e!=null&&e[pe])return n;if(!ee(e)||t.has(e))return e;if(Array.isArray(e)){Object.isFrozen(e)?e=e.slice(0):t.add(e);for(let o=0,l=e.length;o<l;o++)s=e[o],(r=te(s,t))!==s&&(e[o]=r)}else{Object.isFrozen(e)?e=Object.assign({},e):t.add(e);const o=Object.keys(e),l=Object.getOwnPropertyDescriptors(e);for(let a=0,c=o.length;a<c;a++)i=o[a],!l[i].get&&(s=e[i],(r=te(s,t))!==s&&(e[i]=r))}return e}function $e(e,t){let n=e[t];return n||Object.defineProperty(e,t,{value:n=Object.create(null)}),n}function ae(e,t,n){if(e[t])return e[t];const[r,s]=A(n,{equals:!1,internal:!0});return r.$=s,e[t]=r}function Dt(e,t){const n=Reflect.getOwnPropertyDescriptor(e,t);return!n||n.get||!n.configurable||t===G||t===z||(delete n.value,delete n.writable,n.get=()=>e[G][t]),n}function tt(e){Oe()&&ae($e(e,z),Qe)()}function Rt(e){return tt(e),Reflect.ownKeys(e)}const Bt={get(e,t,n){if(t===pe)return e;if(t===G)return n;if(t===Ce)return tt(e),n;const r=$e(e,z),s=r[t];let i=s?s():e[t];if(t===z||t===D||t==="__proto__")return i;if(!s){const o=Object.getOwnPropertyDescriptor(e,t);Oe()&&(typeof i!="function"||e.hasOwnProperty(t))&&!(o&&o.get)&&(i=ae(r,t,i)())}return ee(i)?et(i):i},has(e,t){return t===pe||t===G||t===Ce||t===z||t===D||t==="__proto__"?!0:(Oe()&&ae($e(e,D),t)(),t in e)},set(){return!0},deleteProperty(){return!0},ownKeys:Rt,getOwnPropertyDescriptor:Dt};function ne(e,t,n,r=!1){if(!r&&e[t]===n)return;const s=e[t],i=e.length;n===void 0?(delete e[t],e[D]&&e[D][t]&&s!==void 0&&e[D][t].$()):(e[t]=n,e[D]&&e[D][t]&&s===void 0&&e[D][t].$());let o=$e(e,z),l;if((l=ae(o,t,s))&&l.$(()=>n),Array.isArray(e)&&e.length!==i){for(let a=e.length;a<i;a++)(l=o[a])&&l.$();(l=ae(o,"length",i))&&l.$(e.length)}(l=o[Qe])&&l.$()}function nt(e,t){const n=Object.keys(t);for(let r=0;r<n.length;r+=1){const s=n[r];ne(e,s,t[s])}}function Ut(e,t){if(typeof t=="function"&&(t=t(e)),t=te(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&&ne(e,n,s)}ne(e,"length",r)}else nt(e,t)}function se(e,t,n=[]){let r,s=e;if(t.length>1){r=t.shift();const o=typeof r,l=Array.isArray(e);if(Array.isArray(r)){for(let a=0;a<r.length;a++)se(e,[r[a]].concat(t),n);return}else if(l&&o==="function"){for(let a=0;a<e.length;a++)r(e[a],a)&&se(e,[a].concat(t),n);return}else if(l&&o==="object"){const{from:a=0,to:c=e.length-1,by:u=1}=r;for(let f=a;f<=c;f+=u)se(e,[f].concat(t),n);return}else if(t.length>1){se(e[r],t,[r].concat(n));return}s=e[r],n=[r].concat(n)}let i=t[0];typeof i=="function"&&(i=i(s,n),i===s)||r===void 0&&i==null||(i=te(i),r===void 0||ee(s)&&ee(i)&&!Array.isArray(i)?nt(s,i):ne(e,r,i))}function Wt(...[e,t]){const n=te(e||{}),r=Array.isArray(n),s=et(n);function i(...o){mt(()=>{r&&o.length===1?Ut(n,o[0]):se(n,o)})}return[s,i]}const ve=new WeakMap,rt={get(e,t){if(t===pe)return e;const n=e[t];let r;return ee(n)?ve.get(n)||(ve.set(n,r=new Proxy(n,rt)),r):n},set(e,t,n){return ne(e,t,te(n)),!0},deleteProperty(e,t){return ne(e,t,void 0,!0),!0}};function F(e){return t=>{if(ee(t)){let n;(n=ve.get(t))||ve.set(t,n=new Proxy(t,rt)),e(n)}return t}}const[Ht,Ft]=A(0);setInterval(()=>Ft(e=>e+1),5e3);function Ie(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 c=!1;for(const u of n.pools[a].backends)if(t[u.name]==="up"&&u.weight>0){c=!0;break}if(c){r=a;break}}let s=!1,i=!1,o=!0;const l=new Set;for(let a=0;a<n.pools.length;a++)for(const c of n.pools[a].backends){const u=t[c.name];c.effective_weight=u==="up"&&a===r?c.weight:0,c.effective_weight>0&&(s=!0),l.has(c.name)||(l.add(c.name),i=!0,u!=="unknown"&&(o=!1))}!i||o?n.state="unknown":s?n.state="up":n.state="down"}}const[X,W]=Wt({byName:{},settling:{}}),Vt=2e3,le=new Map;function Kt(e,t){return`${e}\0${t}`}function st(e,t){W(F(s=>{s.settling[e]||(s.settling[e]={}),s.settling[e][t]=!0}));const n=Kt(e,t),r=le.get(n);r&&clearTimeout(r),le.set(n,setTimeout(()=>{le.delete(n),W(F(s=>{s.settling[e]&&delete s.settling[e][t]}))},Vt))}function Gt(e){for(const[t,n]of le)t.startsWith(e+"\0")&&(clearTimeout(n),le.delete(t));W(F(t=>{t.settling[e]&&(t.settling[e]={})}))}function it(e){const t={};for(const n of e)Ie(n),t[n.maglevd.name]=n;W({byName:t})}function qt(e,t){W(F(r=>{const s=r.byName[e];if(!s)return;const i=s.backends.find(o=>o.name===t.backend);i&&(i.state=t.transition.to,i.enabled=t.transition.to!=="disabled",i.last_transition=t.transition,i.transitions||(i.transitions=[]),i.transitions.push(t.transition),i.transitions.length>20&&(i.transitions=i.transitions.slice(i.transitions.length-20)),Ie(s))}));const n=X.byName[e];if(n)for(const r of n.frontends)r.pools.some(s=>s.backends.some(i=>i.name===t.backend))&&st(e,r.name)}function Xt(e,t){W(F(n=>{const r=n.byName[e];if(!r)return;const s=t.per_frontend;if(!s||Object.keys(s).length===0){r.lb_state!==void 0&&(r.lb_state=void 0);return}r.lb_state||(r.lb_state={per_frontend:{}});const o=r.lb_state.per_frontend;for(const l of Object.keys(s)){o[l]||(o[l]={});const a=o[l],c=s[l];for(const u of Object.keys(c))a[u]!==c[u]&&(a[u]=c[u]);for(const u of Object.keys(a))u in c||delete a[u]}for(const l of Object.keys(o))l in s||delete o[l]})),Gt(e)}function Yt(e,t,n){return e?.lb_state?.per_frontend?.[t]?.[n]}function Jt(e,t){W(F(n=>{const r=n.byName[e];r&&(r.vpp_state=t)}))}function Zt(e,t){W(F(n=>{const r=n.byName[e];r&&(r.maglevd.connected=t.connected,r.maglevd.last_error=t.last_error)}))}function zt(e,t,n,r,s){W(F(i=>{const o=i.byName[e];if(!o)return;const l=o.frontends.find(u=>u.name===t);if(!l)return;const a=l.pools.find(u=>u.name===n);if(!a)return;const c=a.backends.find(u=>u.name===r);c&&(c.weight=s,Ie(o))})),st(e,t)}function Qt(e,t){const n={};for(const f of e.backends)n[f.name]=f.state;const r=!!e.lb_state,s=e.lb_state?.per_frontend?.[t.name],i=!!X.settling[e.maglevd.name]?.[t.name];let o=!1,l=!1;for(const f of t.pools)for(const $ of f.backends)if(n[$.name]!=="up"&&(o=!0),!i&&r&&$.effective_weight>0){const g=s?.[$.name];(g===void 0||g===0)&&(l=!0)}const a=t.pools[0],c=!!a&&a.backends.some(f=>f.weight>0),u=!a||a.backends.every(f=>f.effective_weight===0);return!o&&c&&!l?"ok":l?"bug-buckets":u?"primary-drained":o?"degraded":"unknown"}function en(e,t){switch(Qt(e,t)){case"ok":return"✅";case"bug-buckets":return"‼️";case"primary-drained":return"❗";case"degraded":return"⚠️";case"unknown":return"❓"}}function tn(e,t){return e.includes(":")?`[${e}]:${t}`:`${e}:${t}`}function nn(e){if(Ht(),!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 i=s%60,o=Math.floor(s/60);if(o<1)return`${i}m${r}s ago`;const l=o%24,a=Math.floor(o/24);return a<1?`${o}h${i}m ago`:`${a}d${l}h ago`}const Fe=500,[we,rn]=A([]);function sn(e){rn(t=>{const n=[...t,e];return n.length>Fe?n.slice(n.length-Fe):n})}const ln=1e4,on=3e4;function an(){let e,t=!1;const n=l=>{try{const a=JSON.parse(l.data);cn(a)}catch(a){console.error("sse parse error",a,l.data)}},r=async()=>{try{const l=await ze();it(l)}catch(l){console.error("resync refetch failed",l)}},s=()=>{e&&(e.close(),e=void 0),e=new EventSource("/view/api/events"),e.onmessage=n,e.addEventListener("resync",r),e.onerror=l=>{console.debug("sse error, browser will reconnect",l)}},i=l=>{t||(t=!0,console.info("sse reconnecting:",l),s(),setTimeout(()=>{t=!1},1e3))};let o=Date.now();setInterval(()=>{const l=Date.now(),a=l-o;o=l,a>on&&i(`wake detected (${Math.round(a/1e3)}s gap)`)},ln),s()}function cn(e){switch(sn(e),e.type){case"backend":qt(e.maglevd,e.payload);break;case"frontend":e.maglevd,e.payload;break;case"maglevd-status":Zt(e.maglevd,e.payload);break;case"vpp-status":Jt(e.maglevd,e.payload.state);break;case"lb-state":Xt(e.maglevd,e.payload);break}}const ye="maglev_scope",un=60*60*24*365;function fn(){try{const e=document.cookie.split("; ").find(n=>n.startsWith(ye+"="));return e&&decodeURIComponent(e.slice(ye.length+1))||void 0}catch{return}}function dn(e){try{if(!e){document.cookie=`${ye}=; Path=/; Max-Age=0; SameSite=Lax`;return}const t=encodeURIComponent(e);document.cookie=`${ye}=${t}; Path=/; Max-Age=${un}; SameSite=Lax`}catch{}}const[xe,gn]=A(fn());function lt(e){gn(e),dn(e)}var hn=b("<nav class=scope-selector>"),bn=b("<button class=scope-tab><span class=dot>");const mn=()=>{const e=()=>Object.keys(X.byName).sort();return(()=>{var t=hn();return d(t,h(Q,{get each(){return e()},children:n=>{const r=()=>X.byName[n],s=()=>r()?.maglevd.connected??!1;return(()=>{var i=bn();return i.firstChild,i.$$click=()=>lt(n),d(i,n,null),E(o=>{var l=xe()===n,a=!!s(),c=!s(),u=r()?.maglevd.address??"";return l!==o.e&&i.classList.toggle("active",o.e=l),a!==o.t&&i.classList.toggle("connected",o.t=a),c!==o.a&&i.classList.toggle("disconnected",o.a=c),u!==o.o&&N(i,"title",o.o=u),o},{e:void 0,t:void 0,a:void 0,o:void 0}),i})()}})),t})()};ke(["click"]);var pn=b("<span class=status-badge>");const ot=e=>(()=>{var t=pn();return d(t,()=>e.label??e.state),E(()=>N(t,"data-state",e.state)),t})();var $n=b("<span class=probe-heartbeat>");const vn="▶",wn="⏸",yn="⏹",_n="❤️",Ve=400;function kn(e){switch(e){case"paused":return wn;case"disabled":case"removed":return yn;default:return vn}}const Sn=e=>{const[t,n]=A(!1);let r,s;return K(()=>{const i=we();if(i.length===0)return;const o=i[i.length-1];if(o.type!=="log"||o.maglevd!==e.maglevd)return;const l=o.payload;l.attrs?.backend===e.backend&&l.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))}),q(()=>{s!==void 0&&clearTimeout(s)}),(()=>{var i=$n(),o=r;return typeof o=="function"?Se(o,i):r=i,d(i,(()=>{var l=I(()=>!!t());return()=>l()?_n:kn(e.state)})()),E(()=>i.classList.toggle("in-flight",!!t())),i})()};var xn=b("<span class=flash-target>");const Z=e=>{let t;const n=B(()=>e.value);return K(pt(n,()=>{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 r=xn(),s=t;return typeof s=="function"?Se(s,r):t=r,d(r,()=>e.children??e.value),r})()};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 i=(await s.text()).trim();throw new Error(i||`${s.status} ${s.statusText}`)}return await s.json()}async function En(e,t,n,r,s,i){const o=`/admin/api/${encodeURIComponent(e)}/frontend/${encodeURIComponent(t)}/pool/${encodeURIComponent(n)}/backend/${encodeURIComponent(r)}/weight`,l=await fetch(o,{method:"POST",credentials:"same-origin",headers:{"Content-Type":"application/json"},body:JSON.stringify({weight:s,flush:i})});if(!l.ok){const a=(await l.text()).trim();throw new Error(a||`${l.status} ${l.statusText}`)}return await l.json()}var Cn=b("<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 On=e=>(K(()=>{const t=n=>{n.key==="Escape"&&e.onClose()};document.addEventListener("keydown",t),q(()=>document.removeEventListener("keydown",t))}),h(Mt,{get mount(){return document.body},get children(){var t=Cn(),n=t.firstChild,r=n.firstChild,s=r.firstChild,i=s.nextSibling,o=r.nextSibling;return t.$$mousedown=l=>{l.target===l.currentTarget&&e.onClose()},d(s,()=>e.title),Pt(i,"click",e.onClose),d(o,()=>e.children),E(()=>N(n,"aria-label",e.title)),t}}));ke(["mousedown","click"]);var Tn=b("<div class=kebab-menu role=menu>"),Pn=b('<div class=kebab-wrap><button type=button class=kebab-btn aria-haspopup=menu title="backend actions">⋮'),Ln=b("<button type=button class=kebab-item role=menuitem>"),Nn=b("<p class=dialog-error>"),In=b("<footer class=dialog-footer><button type=button class=btn-secondary>cancel</button><button type=button class=btn-primary>"),Mn=b("<p class=dialog-warn>VPP's flow table will be cleared for this backend. Active sessions will be dropped immediately."),jn=b('<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'),Dn=b("<p class=dialog-note>VPP's flow table is left alone. Existing sessions keep reaching this backend until they finish."),Rn=b("<div class=dialog-body><p class=dialog-consequence>");function Bn(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 Un(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 Wn=e=>{const[t,n]=A(!1),[r,s]=A(),[i,o]=A(!1),[l,a]=A(),[c,u]=A(e.configuredWeight),[f,$]=A(!1);let g;const w=()=>Bn(e.state);K(()=>{if(!t())return;const p=y=>{g&&(g.contains(y.target)||n(!1))},m=y=>{y.key==="Escape"&&n(!1)};document.addEventListener("mousedown",p),document.addEventListener("keydown",m),q(()=>{document.removeEventListener("mousedown",p),document.removeEventListener("keydown",m)})});const v=p=>{n(!1),a(void 0),p==="weight"&&(u(e.configuredWeight),$(!1)),s(p)},T=()=>{i()||(s(void 0),a(void 0))},C=async()=>{const p=r();if(p){o(!0),a(void 0);try{if(p==="weight"){const m=c();if(!Number.isFinite(m)||m<0||m>100)throw new Error("weight must be an integer in [0, 100]");const y=Math.floor(m);await En(e.maglevd,e.frontend,e.pool,e.backend,y,f()),zt(e.maglevd,e.frontend,e.pool,e.backend,y)}else await An(e.maglevd,e.backend,p);s(void 0)}catch(m){a(`${m}`)}finally{o(!1)}}};return h(L,{get when(){return w().length>0},get children(){var p=Pn(),m=p.firstChild,y=g;return typeof y=="function"?Se(y,p):g=p,m.$$click=S=>{S.stopPropagation(),n(x=>!x)},d(p,h(L,{get when(){return t()},get children(){var S=Tn();return d(S,h(Q,{get each(){return w()},children:x=>(()=>{var P=Ln();return P.$$click=()=>v(x.action),d(P,()=>x.label),P})()})),S}}),null),d(p,h(L,{get when(){return r()},children:S=>h(On,{get title(){return Hn(S(),e.backend)},onClose:T,get children(){return[I(()=>I(()=>S()==="weight")()?(()=>{var x=jn(),P=x.firstChild,M=P.firstChild,j=M.nextSibling,re=j.nextSibling,ue=re.nextSibling,fe=ue.nextSibling,je=P.nextSibling,De=je.firstChild,ut=De.firstChild,ft=ut.nextSibling,Re=De.nextSibling,dt=je.nextSibling,Be=dt.firstChild;return d(M,()=>e.backend),d(re,()=>e.pool),d(fe,()=>e.frontend),d(ft,c),Re.$$input=Ae=>u(Number(Ae.currentTarget.value)),Be.addEventListener("change",Ae=>$(Ae.currentTarget.checked)),d(x,h(L,{get when(){return f()},get fallback(){return Dn()},get children(){return Mn()}}),null),E(()=>Re.value=c()),E(()=>Be.checked=f()),x})():(()=>{var x=Rn(),P=x.firstChild;return d(P,()=>Un(S())),x})()),h(L,{get when(){return l()},get children(){var x=Nn();return d(x,l),x}}),(()=>{var x=In(),P=x.firstChild,M=P.nextSibling;return P.$$click=T,M.$$click=C,d(M,()=>i()?"committing…":"commit"),E(j=>{var re=i(),ue=!!(S()==="disable"||S()==="weight"&&f()),fe=i();return re!==j.e&&(P.disabled=j.e=re),ue!==j.t&&M.classList.toggle("btn-danger",j.t=ue),fe!==j.a&&(M.disabled=j.a=fe),j},{e:void 0,t:void 0,a:void 0}),x})()]}})}),null),E(()=>N(m,"aria-expanded",t())),p}})};function Hn(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}?`}}ke(["click","input"]);const H=window.location.pathname.startsWith("/admin");var Fn=b("<td class=actions>"),Vn=b("<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=numeric></td><td class=age>");const Kn=e=>{const t=()=>e.backend,n=B(()=>{const r=Yt(X.byName[e.maglevd],e.frontend,t().name);return r===void 0?"—":r});return(()=>{var r=Vn(),s=r.firstChild,i=s.nextSibling,o=i.firstChild,l=i.nextSibling,a=l.nextSibling,c=a.nextSibling,u=c.nextSibling,f=u.nextSibling,$=f.nextSibling;return d(s,(()=>{var g=I(()=>!!e.showPool);return()=>g()?e.pool:""})()),d(i,h(Sn,{get maglevd(){return e.maglevd},get backend(){return t().name},get state(){return t().state}}),o),d(o,()=>t().name),d(l,()=>t().address),d(a,h(Z,{get value(){return t().state},get children(){return h(ot,{get state(){return t().state}})}})),d(c,h(Z,{get value(){return e.poolBackend.weight}})),d(u,h(Z,{get value(){return e.poolBackend.effective_weight}})),d(f,h(Z,{get value(){return n()}})),d($,()=>nn(t().last_transition)),d(r,h(L,{when:H,get children(){var g=Fn();return d(g,h(Wn,{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}})),g}}),null),E(g=>{var w=!e.poolActive,v=t().state;return w!==g.e&&r.classList.toggle("pool-standby",g.e=w),v!==g.t&&N(r,"data-state",g.t=v),g},{e:void 0,t:void 0}),r})()},Pe="maglev_zippy_open",Gn=60*60*24*365;function qn(){try{const e=document.cookie.split("; ").find(n=>n.startsWith(Pe+"="));if(!e)return new Set;const t=decodeURIComponent(e.slice(Pe.length+1));return t?new Set(t.split(",")):new Set}catch{return new Set}}function Xn(e){try{const t=encodeURIComponent([...e].join(","));document.cookie=`${Pe}=${t}; Path=/; Max-Age=${Gn}; SameSite=Lax`}catch{}}const[at,Yn]=A(qn());function Jn(e){return at().has(e)}function Zn(e,t){const n=at();if(t===n.has(e))return;const r=new Set(n);t?r.add(e):r.delete(e),Yn(r),Xn(r)}var zn=b("<details class=zippy><summary></summary><div class=zippy-body>");const Me=e=>(()=>{var t=zn(),n=t.firstChild,r=n.nextSibling;return t.addEventListener("toggle",s=>Zn(e.id,s.currentTarget.open)),d(n,()=>e.title),d(r,()=>e.children),E(()=>t.open=Jn(e.id)),t})();var Qn=b("<span class=frontend-title><span class=frontend-title-icon aria-label=health role=img></span><span class=frontend-title-name></span><span class=frontend-title-addr></span><span class=frontend-title-proto>"),er=b("<span class=tag>sticky"),tr=b("<span class=frontend-title-desc>"),nr=b('<th class="col-actions actions">'),rr=b('<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-buckets numeric">lb buckets</th><th class=col-age>last transition</th></tr></thead><tbody>');const sr=e=>{const t=()=>Object.fromEntries(e.snap.backends.map(s=>[s.name,s])),n=()=>e.frontend,r=(()=>{var s=Qn(),i=s.firstChild,o=i.nextSibling,l=o.nextSibling,a=l.nextSibling;return d(i,()=>en(e.snap,n())),d(o,()=>n().name),d(s,h(Z,{get value(){return n().state??"unknown"},get children(){return h(ot,{get state(){return n().state??"unknown"}})}}),l),d(l,()=>tn(n().address,n().port)),d(a,()=>n().protocol.toUpperCase()),d(s,(()=>{var c=I(()=>!!n().src_ip_sticky);return()=>c()&&er()})(),null),d(s,(()=>{var c=I(()=>!!n().description);return()=>c()&&(()=>{var u=tr();return d(u,()=>n().description),u})()})(),null),s})();return h(Me,{get id(){return`frontend-${e.snap.maglevd.name}-${n().name}`},title:r,get children(){var s=rr(),i=s.firstChild,o=i.firstChild,l=o.firstChild,a=l.nextSibling,c=a.nextSibling,u=c.nextSibling,f=u.nextSibling,$=f.nextSibling,g=$.nextSibling;g.nextSibling;var w=i.nextSibling;return d(o,h(L,{when:H,get children(){return nr()}}),null),d(w,h(Q,{get each(){return n().pools},children:v=>{const T=()=>v.backends.some(C=>C.effective_weight>0);return h(Q,{get each(){return v.backends},children:(C,p)=>{const m=t()[C.name];return m?h(Kn,{get maglevd(){return e.snap.maglevd.name},get frontend(){return n().name},get pool(){return v.name},get showPool(){return p()===0},get poolActive(){return T()},backend:m,poolBackend:C}):null}})}})),s}})};var ir=b("<span class=vpp-badge>"),lr=b("<span class=zippy-title>VPP<span class=vpp-io aria-hidden=true><span class=vpp-io-label>API:</span><span class=vpp-tx>↑</span><span class=vpp-rx>↓"),or=b("<p class=empty>No VPP information available."),ar=b("<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 cr=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,i]=A(!1),[o,l]=A(!1);let a,c;const u=()=>{i(!0),a&&clearTimeout(a),a=window.setTimeout(()=>{i(!1),a=void 0},250)},f=()=>{l(!0),c&&clearTimeout(c),c=window.setTimeout(()=>{l(!1),c=void 0},250)};K(()=>{const g=we();if(!g.length)return;const w=g[g.length-1];if(w.maglevd!==e.name||w.type!=="log")return;const v=w.payload?.msg;v&&(v.startsWith("vpp-api-send")?u():v.startsWith("vpp-api-recv")&&f())}),q(()=>{a&&clearTimeout(a),c&&clearTimeout(c)});const $=(()=>{var g=lr(),w=g.firstChild,v=w.nextSibling,T=v.firstChild,C=T.nextSibling,p=C.nextSibling;return d(g,h(Z,{get value(){return r()},get children(){var m=ir();return d(m,r),E(()=>N(m,"data-state",r())),m}}),v),E(m=>{var y=!!s(),S=!!o();return y!==m.e&&C.classList.toggle("lit",m.e=y),S!==m.t&&p.classList.toggle("lit",m.t=S),m},{e:void 0,t:void 0}),g})();return h(Me,{get id(){return`vpp-${e.name}`},title:$,get children(){return h(L,{get when(){return e.info},get fallback(){return or()},children:g=>(()=>{var w=ar(),v=w.firstChild,T=v.nextSibling,C=T.nextSibling,p=C.nextSibling,m=p.nextSibling,y=m.nextSibling,S=y.nextSibling,x=S.nextSibling,P=x.nextSibling,M=P.nextSibling;return d(T,()=>g().version),d(p,()=>g().build_date),d(y,()=>g().pid),d(x,t),d(M,n),w})()})}})};var ur=b("<main class=overview>"),fr=b("<p class=empty>No maglevd selected."),dr=b('<div class="banner warn"> disconnected'),gr=b("<div class=frontend-list>");const hr=()=>{const e=()=>{const t=xe();return t?X.byName[t]:void 0};return(()=>{var t=ur();return d(t,h(L,{get when(){return e()},get fallback(){return fr()},children:n=>[h(L,{get when(){return!n().maglevd.connected},get children(){var r=dr(),s=r.firstChild;return d(r,()=>n().maglevd.name,s),d(r,(()=>{var i=I(()=>!!n().maglevd.last_error);return()=>i()&&`: ${n().maglevd.last_error}`})(),null),r}}),(()=>{var r=gr();return d(r,h(Q,{get each(){return n().frontends},children:s=>h(sr,{get snap(){return n()},frontend:s})})),r})(),h(cr,{get name(){return n().maglevd.name},get info(){return n().vpp_info},get state(){return n().vpp_state}})]})),t})()};var br=b("<ol class=event-tail>"),mr=b("<div class=debug-toolbar><label><input type=checkbox>all maglevds</label><button></button><span class=count> events"),pr=b("<li>");const $r=()=>{const[e,t]=A(!1),[n,r]=A(!1),[s,i]=A([]),o=B(()=>{const c=n()?s():we();if(e())return c;const u=xe();return u?c.filter(f=>f.maglevd===u):c}),l=()=>{n()?r(!1):(i([...we()]),r(!0))};let a;return K(()=>{o(),!n()&&a&&(a.scrollTop=a.scrollHeight)}),h(Me,{id:"debug-events",title:"Event stream",get children(){return[(()=>{var c=br(),u=a;return typeof u=="function"?Se(u,c):a=c,d(c,h(Q,{get each(){return o()},children:f=>(()=>{var $=pr();return d($,()=>yr(f)),E(g=>{var w=`event-row event-${f.type}`,v=!!vr(f);return w!==g.e&&Tt($,g.e=w),v!==g.t&&$.classList.toggle("event-sync",g.t=v),g},{e:void 0,t:void 0}),$})()})),c})(),(()=>{var c=mr(),u=c.firstChild,f=u.firstChild,$=u.nextSibling,g=$.nextSibling,w=g.firstChild;return f.addEventListener("change",v=>t(v.currentTarget.checked)),$.$$click=l,d($,()=>n()?"resume":"pause"),d(g,()=>o().length,w),E(()=>f.checked=e()),c})()]}})};function vr(e){return e.type!=="log"?!1:e.payload.msg.startsWith("vpp-lb-sync-")}function wr(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,i]of Object.entries(e))r.has(s)||n.push(`${s}=${i}`);return n.join(" ")}function yr(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} ${wr(r.attrs)}`.trimEnd();const s=r.attrs?Object.entries(r.attrs).map(([i,o])=>`${i}=${o}`).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}`}}ke(["click"]);const _r="/view/assets/logo-bimi-Bguc6E_L.svg";var kr=b("<span class=mode-tag>"),Sr=b("<a class=admin-toggle>"),xr=b('<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'),Ar=b("<span class=version> (<!>)"),Er=b('<div class="banner err">'),Cr=b("<p class=loading>Loading…");const Or=()=>{const[e,t]=A(),[n,r]=A();$t(async()=>{try{const[i,o]=await Promise.all([ze(),jt()]);it(i),r(o);const l=xe();!(l&&i.some(c=>c.maglevd.name===l))&&i.length>0&<(i[0].maglevd.name),an()}catch(i){t(`${i}`)}});const s=()=>n()?.admin_enabled===!0;return(()=>{var i=xr(),o=i.firstChild,l=o.firstChild,a=l.firstChild,c=a.firstChild;return a.nextSibling,N(c,"src",_r),d(l,(()=>{var u=I(()=>!!n());return()=>u()&&(()=>{var f=Ar(),$=f.firstChild,g=$.nextSibling;return g.nextSibling,d(f,()=>n().version,$),d(f,()=>n().commit,g),E(()=>N(f,"title",`commit ${n().commit} · built ${n().date}`)),f})()})(),null),d(o,h(mn,{}),null),d(o,h(L,{get when(){return H||s()},get children(){var u=kr();return d(u,H?"admin":"view"),u}}),null),d(o,h(L,{get when(){return s()},get children(){var u=Sr();return N(u,"href",H?"/view/":"/admin/"),N(u,"title",H?"exit admin mode":"enter admin mode"),d(u,H?"exit admin":"admin…"),u}}),null),d(i,(()=>{var u=I(()=>!!e());return()=>u()&&(()=>{var f=Er();return d(f,e),f})()})(),null),d(i,(()=>{var u=I(()=>!e()&&Object.keys(X.byName).length===0);return()=>u()&&Cr()})(),null),d(i,h(hr,{}),null),d(i,h(L,{when:H,get children(){return h($r,{})}}),null),i})()},ct=document.getElementById("root");if(!ct)throw new Error("no #root element");Ot(()=>h(Or,{}),ct);
|