var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports),s=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;li[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},c=(n,r,a)=>(a=n==null?{}:e(i(n)),s(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));(function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),e.crossOrigin===`use-credentials`?t.credentials=`include`:e.crossOrigin===`anonymous`?t.credentials=`omit`:t.credentials=`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var l=o((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.portal`),r=Symbol.for(`react.fragment`),i=Symbol.for(`react.strict_mode`),a=Symbol.for(`react.profiler`),o=Symbol.for(`react.consumer`),s=Symbol.for(`react.context`),c=Symbol.for(`react.forward_ref`),l=Symbol.for(`react.suspense`),u=Symbol.for(`react.memo`),d=Symbol.for(`react.lazy`),f=Symbol.for(`react.activity`),p=Symbol.iterator;function m(e){return typeof e!=`object`||!e?null:(e=p&&e[p]||e[`@@iterator`],typeof e==`function`?e:null)}var h={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},g=Object.assign,_={};function v(e,t,n){this.props=e,this.context=t,this.refs=_,this.updater=n||h}v.prototype.isReactComponent={},v.prototype.setState=function(e,t){if(typeof e!=`object`&&typeof e!=`function`&&e!=null)throw Error(`takes an object of state variables to update or a function which returns an object of state variables.`);this.updater.enqueueSetState(this,e,t,`setState`)},v.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,`forceUpdate`)};function y(){}y.prototype=v.prototype;function b(e,t,n){this.props=e,this.context=t,this.refs=_,this.updater=n||h}var x=b.prototype=new y;x.constructor=b,g(x,v.prototype),x.isPureReactComponent=!0;var S=Array.isArray;function C(){}var w={H:null,A:null,T:null,S:null},T=Object.prototype.hasOwnProperty;function ee(e,n,r){var i=r.ref;return{$$typeof:t,type:e,key:n,ref:i===void 0?null:i,props:r}}function te(e,t){return ee(e.type,t,e.props)}function E(e){return typeof e==`object`&&!!e&&e.$$typeof===t}function D(e){var t={"=":`=0`,":":`=2`};return`$`+e.replace(/[=:]/g,function(e){return t[e]})}var ne=/\/+/g;function re(e,t){return typeof e==`object`&&e&&e.key!=null?D(``+e.key):t.toString(36)}function ie(e){switch(e.status){case`fulfilled`:return e.value;case`rejected`:throw e.reason;default:switch(typeof e.status==`string`?e.then(C,C):(e.status=`pending`,e.then(function(t){e.status===`pending`&&(e.status=`fulfilled`,e.value=t)},function(t){e.status===`pending`&&(e.status=`rejected`,e.reason=t)})),e.status){case`fulfilled`:return e.value;case`rejected`:throw e.reason}}throw e}function ae(e,r,i,a,o){var s=typeof e;(s===`undefined`||s===`boolean`)&&(e=null);var c=!1;if(e===null)c=!0;else switch(s){case`bigint`:case`string`:case`number`:c=!0;break;case`object`:switch(e.$$typeof){case t:case n:c=!0;break;case d:return c=e._init,ae(c(e._payload),r,i,a,o)}}if(c)return o=o(e),c=a===``?`.`+re(e,0):a,S(o)?(i=``,c!=null&&(i=c.replace(ne,`$&/`)+`/`),ae(o,r,i,``,function(e){return e})):o!=null&&(E(o)&&(o=te(o,i+(o.key==null||e&&e.key===o.key?``:(``+o.key).replace(ne,`$&/`)+`/`)+c)),r.push(o)),1;c=0;var l=a===``?`.`:a+`:`;if(S(e))for(var u=0;u{t.exports=l()})),d=o((e=>{function t(e,t){var n=e.length;e.push(t);a:for(;0>>1,a=e[r];if(0>>1;ri(c,n))li(u,c)?(e[r]=u,e[l]=n,r=l):(e[r]=c,e[s]=n,r=s);else if(li(u,n))e[r]=u,e[l]=n,r=l;else break a}}return t}function i(e,t){var n=e.sortIndex-t.sortIndex;return n===0?e.id-t.id:n}if(e.unstable_now=void 0,typeof performance==`object`&&typeof performance.now==`function`){var a=performance;e.unstable_now=function(){return a.now()}}else{var o=Date,s=o.now();e.unstable_now=function(){return o.now()-s}}var c=[],l=[],u=1,d=null,f=3,p=!1,m=!1,h=!1,g=!1,_=typeof setTimeout==`function`?setTimeout:null,v=typeof clearTimeout==`function`?clearTimeout:null,y=typeof setImmediate<`u`?setImmediate:null;function b(e){for(var i=n(l);i!==null;){if(i.callback===null)r(l);else if(i.startTime<=e)r(l),i.sortIndex=i.expirationTime,t(c,i);else break;i=n(l)}}function x(e){if(h=!1,b(e),!m)if(n(c)!==null)m=!0,S||(S=!0,E());else{var t=n(l);t!==null&&re(x,t.startTime-e)}}var S=!1,C=-1,w=5,T=-1;function ee(){return g?!0:!(e.unstable_now()-Tt&&ee());){var o=d.callback;if(typeof o==`function`){d.callback=null,f=d.priorityLevel;var s=o(d.expirationTime<=t);if(t=e.unstable_now(),typeof s==`function`){d.callback=s,b(t),i=!0;break b}d===n(c)&&r(c),b(t)}else r(c);d=n(c)}if(d!==null)i=!0;else{var u=n(l);u!==null&&re(x,u.startTime-t),i=!1}}break a}finally{d=null,f=a,p=!1}i=void 0}}finally{i?E():S=!1}}}var E;if(typeof y==`function`)E=function(){y(te)};else if(typeof MessageChannel<`u`){var D=new MessageChannel,ne=D.port2;D.port1.onmessage=te,E=function(){ne.postMessage(null)}}else E=function(){_(te,0)};function re(t,n){C=_(function(){t(e.unstable_now())},n)}e.unstable_IdlePriority=5,e.unstable_ImmediatePriority=1,e.unstable_LowPriority=4,e.unstable_NormalPriority=3,e.unstable_Profiling=null,e.unstable_UserBlockingPriority=2,e.unstable_cancelCallback=function(e){e.callback=null},e.unstable_forceFrameRate=function(e){0>e||125o?(r.sortIndex=a,t(l,r),n(c)===null&&r===n(l)&&(h?(v(C),C=-1):h=!0,re(x,a-o))):(r.sortIndex=s,t(c,r),m||p||(m=!0,S||(S=!0,E()))),r},e.unstable_shouldYield=ee,e.unstable_wrapCallback=function(e){var t=f;return function(){var n=f;f=t;try{return e.apply(this,arguments)}finally{f=n}}}})),f=o(((e,t)=>{t.exports=d()})),p=o((e=>{var t=u();function n(e){var t=`https://react.dev/errors/`+e;if(1{function n(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>`u`||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=`function`))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=p()})),h=o((e=>{var t=f(),n=u(),r=m();function i(e){var t=`https://react.dev/errors/`+e;if(1ue||(e.current=le[ue],le[ue]=null,ue--)}function pe(e,t){ue++,le[ue]=e.current,e.current=t}var me=de(null),he=de(null),ge=de(null),_e=de(null);function ve(e,t){switch(pe(ge,t),pe(he,e),pe(me,null),t.nodeType){case 9:case 11:e=(e=t.documentElement)&&(e=e.namespaceURI)?Vd(e):0;break;default:if(e=t.tagName,t=t.namespaceURI)t=Vd(t),e=Hd(t,e);else switch(e){case`svg`:e=1;break;case`math`:e=2;break;default:e=0}}fe(me),pe(me,e)}function A(){fe(me),fe(he),fe(ge)}function ye(e){e.memoizedState!==null&&pe(_e,e);var t=me.current,n=Hd(t,e.type);t!==n&&(pe(he,e),pe(me,n))}function be(e){he.current===e&&(fe(me),fe(he)),_e.current===e&&(fe(_e),Qf._currentValue=ce)}var xe,Se;function Ce(e){if(xe===void 0)try{throw Error()}catch(e){var t=e.stack.trim().match(/\n( *(at )?)/);xe=t&&t[1]||``,Se=-1)`:-1i||c[r]!==l[i]){var u=` `+c[r].replace(` at new `,` at `);return e.displayName&&u.includes(``)&&(u=u.replace(``,e.displayName)),u}while(1<=r&&0<=i);break}}}finally{we=!1,Error.prepareStackTrace=n}return(n=e?e.displayName||e.name:``)?Ce(n):``}function Ee(e,t){switch(e.tag){case 26:case 27:case 5:return Ce(e.type);case 16:return Ce(`Lazy`);case 13:return e.child!==t&&t!==null?Ce(`Suspense Fallback`):Ce(`Suspense`);case 19:return Ce(`SuspenseList`);case 0:case 15:return Te(e.type,!1);case 11:return Te(e.type.render,!1);case 1:return Te(e.type,!0);case 31:return Ce(`Activity`);default:return``}}function j(e){try{var t=``,n=null;do t+=Ee(e,n),n=e,e=e.return;while(e);return t}catch(e){return` Error generating stack: `+e.message+` `+e.stack}}var De=Object.prototype.hasOwnProperty,Oe=t.unstable_scheduleCallback,ke=t.unstable_cancelCallback,Ae=t.unstable_shouldYield,je=t.unstable_requestPaint,Me=t.unstable_now,Ne=t.unstable_getCurrentPriorityLevel,Pe=t.unstable_ImmediatePriority,Fe=t.unstable_UserBlockingPriority,Ie=t.unstable_NormalPriority,Le=t.unstable_LowPriority,M=t.unstable_IdlePriority,Re=t.log,ze=t.unstable_setDisableYieldValue,Be=null,Ve=null;function He(e){if(typeof Re==`function`&&ze(e),Ve&&typeof Ve.setStrictMode==`function`)try{Ve.setStrictMode(Be,e)}catch{}}var Ue=Math.clz32?Math.clz32:Ke,We=Math.log,Ge=Math.LN2;function Ke(e){return e>>>=0,e===0?32:31-(We(e)/Ge|0)|0}var qe=256,Je=262144,Ye=4194304;function Xe(e){var t=e&42;if(t!==0)return t;switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return e&261888;case 262144:case 524288:case 1048576:case 2097152:return e&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return e&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return e}}function Ze(e,t,n){var r=e.pendingLanes;if(r===0)return 0;var i=0,a=e.suspendedLanes,o=e.pingedLanes;e=e.warmLanes;var s=r&134217727;return s===0?(s=r&~a,s===0?o===0?n||(n=r&~e,n!==0&&(i=Xe(n))):i=Xe(o):i=Xe(s)):(r=s&~a,r===0?(o&=s,o===0?n||(n=s&~e,n!==0&&(i=Xe(n))):i=Xe(o)):i=Xe(r)),i===0?0:t!==0&&t!==i&&(t&a)===0&&(a=i&-i,n=t&-t,a>=n||a===32&&n&4194048)?t:i}function Qe(e,t){return(e.pendingLanes&~(e.suspendedLanes&~e.pingedLanes)&t)===0}function N(e,t){switch(e){case 1:case 2:case 4:case 8:case 64:return t+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return t+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function $e(){var e=Ye;return Ye<<=1,!(Ye&62914560)&&(Ye=4194304),e}function et(e){for(var t=[],n=0;31>n;n++)t.push(e);return t}function tt(e,t){e.pendingLanes|=t,t!==268435456&&(e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0)}function nt(e,t,n,r,i,a){var o=e.pendingLanes;e.pendingLanes=n,e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0,e.expiredLanes&=n,e.entangledLanes&=n,e.errorRecoveryDisabledLanes&=n,e.shellSuspendCounter=0;var s=e.entanglements,c=e.expirationTimes,l=e.hiddenUpdates;for(n=o&~n;0`u`||window.document===void 0||window.document.createElement===void 0),dn=!1;if(un)try{var fn={};Object.defineProperty(fn,`passive`,{get:function(){dn=!0}}),window.addEventListener(`test`,fn,fn),window.removeEventListener(`test`,fn,fn)}catch{dn=!1}var pn=null,mn=null,hn=null;function gn(){if(hn)return hn;var e,t=mn,n=t.length,r,i=`value`in pn?pn.value:pn.textContent,a=i.length;for(e=0;e=Kn),Yn=` `,B=!1;function V(e,t){switch(e){case`keyup`:return Wn.indexOf(t.keyCode)!==-1;case`keydown`:return t.keyCode!==229;case`keypress`:case`mousedown`:case`focusout`:return!0;default:return!1}}function Xn(e){return e=e.detail,typeof e==`object`&&`data`in e?e.data:null}var Zn=!1;function Qn(e,t){switch(e){case`compositionend`:return Xn(t);case`keypress`:return t.which===32?(B=!0,Yn):null;case`textInput`:return e=t.data,e===Yn&&B?null:e;default:return null}}function $n(e,t){if(Zn)return e===`compositionend`||!Gn&&V(e,t)?(e=gn(),hn=mn=pn=null,Zn=!1,e):null;switch(e){case`paste`:return null;case`keypress`:if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1=t)return{node:n,offset:t-e};e=r}a:{for(;n;){if(n.nextSibling){n=n.nextSibling;break a}n=n.parentNode}n=void 0}n=br(n)}}function Sr(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?Sr(e,t.parentNode):`contains`in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function Cr(e){e=e!=null&&e.ownerDocument!=null&&e.ownerDocument.defaultView!=null?e.ownerDocument.defaultView:window;for(var t=Rt(e.document);t instanceof e.HTMLIFrameElement;){try{var n=typeof t.contentWindow.location.href==`string`}catch{n=!1}if(n)e=t.contentWindow;else break;t=Rt(e.document)}return t}function wr(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&(t===`input`&&(e.type===`text`||e.type===`search`||e.type===`tel`||e.type===`url`||e.type===`password`)||t===`textarea`||e.contentEditable===`true`)}var Tr=un&&`documentMode`in document&&11>=document.documentMode,Er=null,Dr=null,Or=null,kr=!1;function Ar(e,t,n){var r=n.window===n?n.document:n.nodeType===9?n:n.ownerDocument;kr||Er==null||Er!==Rt(r)||(r=Er,`selectionStart`in r&&wr(r)?r={start:r.selectionStart,end:r.selectionEnd}:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection(),r={anchorNode:r.anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset}),Or&&yr(Or,r)||(Or=r,r=Td(Dr,`onSelect`),0>=o,i-=o,bi=1<<32-Ue(t)+i|n<h?(g=d,d=null):g=d.sibling;var _=p(i,d,s[h],c);if(_===null){d===null&&(d=g);break}e&&d&&_.alternate===null&&t(i,d),a=o(_,a,h),u===null?l=_:u.sibling=_,u=_,d=g}if(h===s.length)return n(i,d),ki&&Si(i,h),l;if(d===null){for(;hg?(_=h,h=null):_=h.sibling;var y=p(a,h,v.value,l);if(y===null){h===null&&(h=_);break}e&&h&&y.alternate===null&&t(a,h),s=o(y,s,g),d===null?u=y:d.sibling=y,d=y,h=_}if(v.done)return n(a,h),ki&&Si(a,g),u;if(h===null){for(;!v.done;g++,v=c.next())v=f(a,v.value,l),v!==null&&(s=o(v,s,g),d===null?u=v:d.sibling=v,d=v);return ki&&Si(a,g),u}for(h=r(h);!v.done;g++,v=c.next())v=m(h,a,g,v.value,l),v!==null&&(e&&v.alternate!==null&&h.delete(v.key===null?g:v.key),s=o(v,s,g),d===null?u=v:d.sibling=v,d=v);return e&&h.forEach(function(e){return t(a,e)}),ki&&Si(a,g),u}function b(e,r,o,c){if(typeof o==`object`&&o&&o.type===y&&o.key===null&&(o=o.props.children),typeof o==`object`&&o){switch(o.$$typeof){case _:a:{for(var l=o.key;r!==null;){if(r.key===l){if(l=o.type,l===y){if(r.tag===7){n(e,r.sibling),c=a(r,o.props.children),c.return=e,e=c;break a}}else if(r.elementType===l||typeof l==`object`&&l&&l.$$typeof===E&&ya(l)===r.type){n(e,r.sibling),c=a(r,o.props),Ea(c,o),c.return=e,e=c;break a}n(e,r);break}else t(e,r);r=r.sibling}o.type===y?(c=si(o.props.children,e.mode,c,o.key),c.return=e,e=c):(c=oi(o.type,o.key,o.props,null,e.mode,c),Ea(c,o),c.return=e,e=c)}return s(e);case v:a:{for(l=o.key;r!==null;){if(r.key===l)if(r.tag===4&&r.stateNode.containerInfo===o.containerInfo&&r.stateNode.implementation===o.implementation){n(e,r.sibling),c=a(r,o.children||[]),c.return=e,e=c;break a}else{n(e,r);break}else t(e,r);r=r.sibling}c=ui(o,e.mode,c),c.return=e,e=c}return s(e);case E:return o=ya(o),b(e,r,o,c)}if(se(o))return h(e,r,o,c);if(ie(o)){if(l=ie(o),typeof l!=`function`)throw Error(i(150));return o=l.call(o),g(e,r,o,c)}if(typeof o.then==`function`)return b(e,r,Ta(o),c);if(o.$$typeof===C)return b(e,r,Xi(e,o),c);Da(e,o)}return typeof o==`string`&&o!==``||typeof o==`number`||typeof o==`bigint`?(o=``+o,r!==null&&r.tag===6?(n(e,r.sibling),c=a(r,o),c.return=e,e=c):(n(e,r),c=ci(o,e.mode,c),c.return=e,e=c),s(e)):n(e,r)}return function(e,t,n,r){try{wa=0;var i=b(e,t,n,r);return Ca=null,i}catch(t){if(t===ma||t===ha)throw t;var a=W(29,t,null,e.mode);return a.lanes=r,a.return=e,a}}}var ka=Oa(!0),Aa=Oa(!1),ja=!1;function Ma(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function Na(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,callbacks:null})}function Pa(e){return{lane:e,tag:0,payload:null,callback:null,next:null}}function Fa(e,t,n){var r=e.updateQueue;if(r===null)return null;if(r=r.shared,Pl&2){var i=r.pending;return i===null?t.next=t:(t.next=i.next,i.next=t),r.pending=t,t=ti(e),ei(e,null,n),t}return Zr(e,r,t,n),ti(e)}function Ia(e,t,n){if(t=t.updateQueue,t!==null&&(t=t.shared,n&4194048)){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,it(e,n)}}function La(e,t){var n=e.updateQueue,r=e.alternate;if(r!==null&&(r=r.updateQueue,n===r)){var i=null,a=null;if(n=n.firstBaseUpdate,n!==null){do{var o={lane:n.lane,tag:n.tag,payload:n.payload,callback:null,next:null};a===null?i=a=o:a=a.next=o,n=n.next}while(n!==null);a===null?i=a=t:a=a.next=t}else i=a=t;n={baseState:r.baseState,firstBaseUpdate:i,lastBaseUpdate:a,shared:r.shared,callbacks:r.callbacks},e.updateQueue=n;return}e=n.lastBaseUpdate,e===null?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}var Ra=!1;function za(){if(Ra){var e=oa;if(e!==null)throw e}}function Ba(e,t,n,r){Ra=!1;var i=e.updateQueue;ja=!1;var a=i.firstBaseUpdate,o=i.lastBaseUpdate,s=i.shared.pending;if(s!==null){i.shared.pending=null;var c=s,l=c.next;c.next=null,o===null?a=l:o.next=l,o=c;var u=e.alternate;u!==null&&(u=u.updateQueue,s=u.lastBaseUpdate,s!==o&&(s===null?u.firstBaseUpdate=l:s.next=l,u.lastBaseUpdate=c))}if(a!==null){var d=i.baseState;o=0,u=l=c=null,s=a;do{var f=s.lane&-536870913,p=f!==s.lane;if(p?(Q&f)===f:(r&f)===f){f!==0&&f===aa&&(Ra=!0),u!==null&&(u=u.next={lane:0,tag:s.tag,payload:s.payload,callback:null,next:null});a:{var m=e,g=s;f=t;var _=n;switch(g.tag){case 1:if(m=g.payload,typeof m==`function`){d=m.call(_,d,f);break a}d=m;break a;case 3:m.flags=m.flags&-65537|128;case 0:if(m=g.payload,f=typeof m==`function`?m.call(_,d,f):m,f==null)break a;d=h({},d,f);break a;case 2:ja=!0}}f=s.callback,f!==null&&(e.flags|=64,p&&(e.flags|=8192),p=i.callbacks,p===null?i.callbacks=[f]:p.push(f))}else p={lane:f,tag:s.tag,payload:s.payload,callback:s.callback,next:null},u===null?(l=u=p,c=d):u=u.next=p,o|=f;if(s=s.next,s===null){if(s=i.shared.pending,s===null)break;p=s,s=p.next,p.next=null,i.lastBaseUpdate=p,i.shared.pending=null}}while(1);u===null&&(c=d),i.baseState=c,i.firstBaseUpdate=l,i.lastBaseUpdate=u,a===null&&(i.shared.lanes=0),Ul|=o,e.lanes=o,e.memoizedState=d}}function Va(e,t){if(typeof e!=`function`)throw Error(i(191,e));e.call(t)}function Ha(e,t){var n=e.callbacks;if(n!==null)for(e.callbacks=null,e=0;ea?a:8;var o=O.T,s={};O.T=s,Ds(e,!1,t,n);try{var c=i(),l=O.S;l!==null&&l(s,c),typeof c==`object`&&c&&typeof c.then==`function`?Es(e,t,la(c,r),du(e)):Es(e,t,r,du(e))}catch(n){Es(e,t,{then:function(){},status:`rejected`,reason:n},du())}finally{k.p=a,o!==null&&s.types!==null&&(o.types=s.types),O.T=o}}function gs(){}function _s(e,t,n,r){if(e.tag!==5)throw Error(i(476));var a=vs(e).queue;hs(e,a,t,ce,n===null?gs:function(){return ys(e),n(r)})}function vs(e){var t=e.memoizedState;if(t!==null)return t;t={memoizedState:ce,baseState:ce,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Oo,lastRenderedState:ce},next:null};var n={};return t.next={memoizedState:n,baseState:n,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Oo,lastRenderedState:n},next:null},e.memoizedState=t,e=e.alternate,e!==null&&(e.memoizedState=t),t}function ys(e){var t=vs(e);t.next===null&&(t=e.alternate.memoizedState),Es(e,t.next.queue,{},du())}function bs(){return Yi(Qf)}function xs(){return Co().memoizedState}function Ss(){return Co().memoizedState}function Cs(e){for(var t=e.return;t!==null;){switch(t.tag){case 24:case 3:var n=du();e=Pa(n);var r=Fa(t,e,n);r!==null&&(pu(r,t,n),Ia(r,t,n)),t={cache:K()},e.payload=t;return}t=t.return}}function ws(e,t,n){var r=du();n={lane:r,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null},Os(e)?ks(t,n):(n=Qr(e,t,n,r),n!==null&&(pu(n,e,r),As(n,t,r)))}function Ts(e,t,n){Es(e,t,n,du())}function Es(e,t,n,r){var i={lane:r,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null};if(Os(e))ks(t,i);else{var a=e.alternate;if(e.lanes===0&&(a===null||a.lanes===0)&&(a=t.lastRenderedReducer,a!==null))try{var o=t.lastRenderedState,s=a(o,n);if(i.hasEagerState=!0,i.eagerState=s,vr(s,o))return Zr(e,t,i,0),Fl===null&&Xr(),!1}catch{}if(n=Qr(e,t,i,r),n!==null)return pu(n,e,r),As(n,t,r),!0}return!1}function Ds(e,t,n,r){if(r={lane:2,revertLane:ud(),gesture:null,action:r,hasEagerState:!1,eagerState:null,next:null},Os(e)){if(t)throw Error(i(479))}else t=Qr(e,n,r,2),t!==null&&pu(t,e,2)}function Os(e){var t=e.alternate;return e===X||t!==null&&t===X}function ks(e,t){oo=ao=!0;var n=e.pending;n===null?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function As(e,t,n){if(n&4194048){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,it(e,n)}}var js={readContext:Yi,use:Eo,useCallback:po,useContext:po,useEffect:po,useImperativeHandle:po,useLayoutEffect:po,useInsertionEffect:po,useMemo:po,useReducer:po,useRef:po,useState:po,useDebugValue:po,useDeferredValue:po,useTransition:po,useSyncExternalStore:po,useId:po,useHostTransitionStatus:po,useFormState:po,useActionState:po,useOptimistic:po,useMemoCache:po,useCacheRefresh:po};js.useEffectEvent=po;var Ms={readContext:Yi,use:Eo,useCallback:function(e,t){return So().memoizedState=[e,t===void 0?null:t],e},useContext:Yi,useEffect:ns,useImperativeHandle:function(e,t,n){n=n==null?null:n.concat([e]),es(4194308,4,cs.bind(null,t,e),n)},useLayoutEffect:function(e,t){return es(4194308,4,e,t)},useInsertionEffect:function(e,t){es(4,2,e,t)},useMemo:function(e,t){var n=So();t=t===void 0?null:t;var r=e();if(so){He(!0);try{e()}finally{He(!1)}}return n.memoizedState=[r,t],r},useReducer:function(e,t,n){var r=So();if(n!==void 0){var i=n(t);if(so){He(!0);try{n(t)}finally{He(!1)}}}else i=t;return r.memoizedState=r.baseState=i,e={pending:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:i},r.queue=e,e=e.dispatch=ws.bind(null,X,e),[r.memoizedState,e]},useRef:function(e){var t=So();return e={current:e},t.memoizedState=e},useState:function(e){e=Ro(e);var t=e.queue,n=Ts.bind(null,X,t);return t.dispatch=n,[e.memoizedState,n]},useDebugValue:us,useDeferredValue:function(e,t){return ps(So(),e,t)},useTransition:function(){var e=Ro(!1);return e=hs.bind(null,X,e.queue,!0,!1),So().memoizedState=e,[!1,e]},useSyncExternalStore:function(e,t,n){var r=X,a=So();if(ki){if(n===void 0)throw Error(i(407));n=n()}else{if(n=t(),Fl===null)throw Error(i(349));Q&127||No(r,t,n)}a.memoizedState=n;var o={value:n,getSnapshot:t};return a.queue=o,ns(Fo.bind(null,r,o,e),[e]),r.flags|=2048,Qo(9,{destroy:void 0},Po.bind(null,r,o,n,t),null),n},useId:function(){var e=So(),t=Fl.identifierPrefix;if(ki){var n=xi,r=bi;n=(r&~(1<<32-Ue(r)-1)).toString(32)+n,t=`_`+t+`R_`+n,n=co++,0<\/script>`,o=o.removeChild(o.firstChild);break;case`select`:o=typeof r.is==`string`?s.createElement(`select`,{is:r.is}):s.createElement(`select`),r.multiple?o.multiple=!0:r.size&&(o.size=r.size);break;default:o=typeof r.is==`string`?s.createElement(a,{is:r.is}):s.createElement(a)}}o[dt]=t,o[ft]=r;a:for(s=t.child;s!==null;){if(s.tag===5||s.tag===6)o.appendChild(s.stateNode);else if(s.tag!==4&&s.tag!==27&&s.child!==null){s.child.return=s,s=s.child;continue}if(s===t)break a;for(;s.sibling===null;){if(s.return===null||s.return===t)break a;s=s.return}s.sibling.return=s.return,s=s.sibling}t.stateNode=o;a:switch(Pd(o,a,r),a){case`button`:case`input`:case`select`:case`textarea`:r=!!r.autoFocus;break a;case`img`:r=!0;break a;default:r=!1}r&&Ec(t)}}return jc(t),Dc(t,t.type,e===null?null:e.memoizedProps,t.pendingProps,n),null;case 6:if(e&&t.stateNode!=null)e.memoizedProps!==r&&Ec(t);else{if(typeof r!=`string`&&t.stateNode===null)throw Error(i(166));if(e=ge.current,Ii(t)){if(e=t.stateNode,n=t.memoizedProps,r=null,a=Di,a!==null)switch(a.tag){case 27:case 5:r=a.memoizedProps}e[dt]=t,e=!!(e.nodeValue===n||r!==null&&!0===r.suppressHydrationWarning||jd(e.nodeValue,n)),e||Ni(t,!0)}else e=Bd(e).createTextNode(r),e[dt]=t,t.stateNode=e}return jc(t),null;case 31:if(n=t.memoizedState,e===null||e.memoizedState!==null){if(r=Ii(t),n!==null){if(e===null){if(!r)throw Error(i(318));if(e=t.memoizedState,e=e===null?null:e.dehydrated,!e)throw Error(i(557));e[dt]=t}else Li(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;jc(t),e=!1}else n=Ri(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=n),e=!0;if(!e)return t.flags&256?($a(t),t):($a(t),null);if(t.flags&128)throw Error(i(558))}return jc(t),null;case 13:if(r=t.memoizedState,e===null||e.memoizedState!==null&&e.memoizedState.dehydrated!==null){if(a=Ii(t),r!==null&&r.dehydrated!==null){if(e===null){if(!a)throw Error(i(318));if(a=t.memoizedState,a=a===null?null:a.dehydrated,!a)throw Error(i(317));a[dt]=t}else Li(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;jc(t),a=!1}else a=Ri(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=a),a=!0;if(!a)return t.flags&256?($a(t),t):($a(t),null)}return $a(t),t.flags&128?(t.lanes=n,t):(n=r!==null,e=e!==null&&e.memoizedState!==null,n&&(r=t.child,a=null,r.alternate!==null&&r.alternate.memoizedState!==null&&r.alternate.memoizedState.cachePool!==null&&(a=r.alternate.memoizedState.cachePool.pool),o=null,r.memoizedState!==null&&r.memoizedState.cachePool!==null&&(o=r.memoizedState.cachePool.pool),o!==a&&(r.flags|=2048)),n!==e&&n&&(t.child.flags|=8192),kc(t,t.updateQueue),jc(t),null);case 4:return A(),e===null&&xd(t.stateNode.containerInfo),jc(t),null;case 10:return Ui(t.type),jc(t),null;case 19:if(fe(eo),r=t.memoizedState,r===null)return jc(t),null;if(a=(t.flags&128)!=0,o=r.rendering,o===null)if(a)Ac(r,!1);else{if(Hl!==0||e!==null&&e.flags&128)for(e=t.child;e!==null;){if(o=to(e),o!==null){for(t.flags|=128,Ac(r,!1),e=o.updateQueue,t.updateQueue=e,kc(t,e),t.subtreeFlags=0,e=n,n=t.child;n!==null;)ai(n,e),n=n.sibling;return pe(eo,eo.current&1|2),ki&&Si(t,r.treeForkCount),t.child}e=e.sibling}r.tail!==null&&Me()>$l&&(t.flags|=128,a=!0,Ac(r,!1),t.lanes=4194304)}else{if(!a)if(e=to(o),e!==null){if(t.flags|=128,a=!0,e=e.updateQueue,t.updateQueue=e,kc(t,e),Ac(r,!0),r.tail===null&&r.tailMode===`hidden`&&!o.alternate&&!ki)return jc(t),null}else 2*Me()-r.renderingStartTime>$l&&n!==536870912&&(t.flags|=128,a=!0,Ac(r,!1),t.lanes=4194304);r.isBackwards?(o.sibling=t.child,t.child=o):(e=r.last,e===null?t.child=o:e.sibling=o,r.last=o)}return r.tail===null?(jc(t),null):(e=r.tail,r.rendering=e,r.tail=e.sibling,r.renderingStartTime=Me(),e.sibling=null,n=eo.current,pe(eo,a?n&1|2:n&1),ki&&Si(t,r.treeForkCount),e);case 22:case 23:return $a(t),qa(),r=t.memoizedState!==null,e===null?r&&(t.flags|=8192):e.memoizedState!==null!==r&&(t.flags|=8192),r?n&536870912&&!(t.flags&128)&&(jc(t),t.subtreeFlags&6&&(t.flags|=8192)):jc(t),n=t.updateQueue,n!==null&&kc(t,n.retryQueue),n=null,e!==null&&e.memoizedState!==null&&e.memoizedState.cachePool!==null&&(n=e.memoizedState.cachePool.pool),r=null,t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(r=t.memoizedState.cachePool.pool),r!==n&&(t.flags|=2048),e!==null&&fe(da),null;case 24:return n=null,e!==null&&(n=e.memoizedState.cache),t.memoizedState.cache!==n&&(t.flags|=2048),Ui(ta),jc(t),null;case 25:return null;case 30:return null}throw Error(i(156,t.tag))}function Nc(e,t){switch(Ti(t),t.tag){case 1:return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return Ui(ta),A(),e=t.flags,e&65536&&!(e&128)?(t.flags=e&-65537|128,t):null;case 26:case 27:case 5:return be(t),null;case 31:if(t.memoizedState!==null){if($a(t),t.alternate===null)throw Error(i(340));Li()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 13:if($a(t),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(i(340));Li()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return fe(eo),null;case 4:return A(),null;case 10:return Ui(t.type),null;case 22:case 23:return $a(t),qa(),e!==null&&fe(da),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 24:return Ui(ta),null;case 25:return null;default:return null}}function Pc(e,t){switch(Ti(t),t.tag){case 3:Ui(ta),A();break;case 26:case 27:case 5:be(t);break;case 4:A();break;case 31:t.memoizedState!==null&&$a(t);break;case 13:$a(t);break;case 19:fe(eo);break;case 10:Ui(t.type);break;case 22:case 23:$a(t),qa(),e!==null&&fe(da);break;case 24:Ui(ta)}}function Fc(e,t){try{var n=t.updateQueue,r=n===null?null:n.lastEffect;if(r!==null){var i=r.next;n=i;do{if((n.tag&e)===e){r=void 0;var a=n.create,o=n.inst;r=a(),o.destroy=r}n=n.next}while(n!==i)}}catch(e){Uu(t,t.return,e)}}function Ic(e,t,n){try{var r=t.updateQueue,i=r===null?null:r.lastEffect;if(i!==null){var a=i.next;r=a;do{if((r.tag&e)===e){var o=r.inst,s=o.destroy;if(s!==void 0){o.destroy=void 0,i=t;var c=n,l=s;try{l()}catch(e){Uu(i,c,e)}}}r=r.next}while(r!==a)}}catch(e){Uu(t,t.return,e)}}function Lc(e){var t=e.updateQueue;if(t!==null){var n=e.stateNode;try{Ha(t,n)}catch(t){Uu(e,e.return,t)}}}function Rc(e,t,n){n.props=zs(e.type,e.memoizedProps),n.state=e.memoizedState;try{n.componentWillUnmount()}catch(n){Uu(e,t,n)}}function zc(e,t){try{var n=e.ref;if(n!==null){switch(e.tag){case 26:case 27:case 5:var r=e.stateNode;break;case 30:r=e.stateNode;break;default:r=e.stateNode}typeof n==`function`?e.refCleanup=n(r):n.current=r}}catch(n){Uu(e,t,n)}}function Bc(e,t){var n=e.ref,r=e.refCleanup;if(n!==null)if(typeof r==`function`)try{r()}catch(n){Uu(e,t,n)}finally{e.refCleanup=null,e=e.alternate,e!=null&&(e.refCleanup=null)}else if(typeof n==`function`)try{n(null)}catch(n){Uu(e,t,n)}else n.current=null}function Vc(e){var t=e.type,n=e.memoizedProps,r=e.stateNode;try{a:switch(t){case`button`:case`input`:case`select`:case`textarea`:n.autoFocus&&r.focus();break a;case`img`:n.src?r.src=n.src:n.srcSet&&(r.srcset=n.srcSet)}}catch(t){Uu(e,e.return,t)}}function Hc(e,t,n){try{var r=e.stateNode;Fd(r,e.type,n,t),r[ft]=t}catch(t){Uu(e,e.return,t)}}function Uc(e){return e.tag===5||e.tag===3||e.tag===26||e.tag===27&&Zd(e.type)||e.tag===4}function Wc(e){a:for(;;){for(;e.sibling===null;){if(e.return===null||Uc(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.tag===27&&Zd(e.type)||e.flags&2||e.child===null||e.tag===4)continue a;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function Gc(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?(n.nodeType===9?n.body:n.nodeName===`HTML`?n.ownerDocument.body:n).insertBefore(e,t):(t=n.nodeType===9?n.body:n.nodeName===`HTML`?n.ownerDocument.body:n,t.appendChild(e),n=n._reactRootContainer,n!=null||t.onclick!==null||(t.onclick=en));else if(r!==4&&(r===27&&Zd(e.type)&&(n=e.stateNode,t=null),e=e.child,e!==null))for(Gc(e,t,n),e=e.sibling;e!==null;)Gc(e,t,n),e=e.sibling}function Kc(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?n.insertBefore(e,t):n.appendChild(e);else if(r!==4&&(r===27&&Zd(e.type)&&(n=e.stateNode),e=e.child,e!==null))for(Kc(e,t,n),e=e.sibling;e!==null;)Kc(e,t,n),e=e.sibling}function qc(e){var t=e.stateNode,n=e.memoizedProps;try{for(var r=e.type,i=t.attributes;i.length;)t.removeAttributeNode(i[0]);Pd(t,r,n),t[dt]=e,t[ft]=n}catch(t){Uu(e,e.return,t)}}var Jc=!1,Yc=!1,Xc=!1,Zc=typeof WeakSet==`function`?WeakSet:Set,Qc=null;function $c(e,t){if(e=e.containerInfo,Rd=sp,e=Cr(e),wr(e)){if(`selectionStart`in e)var n={start:e.selectionStart,end:e.selectionEnd};else a:{n=(n=e.ownerDocument)&&n.defaultView||window;var r=n.getSelection&&n.getSelection();if(r&&r.rangeCount!==0){n=r.anchorNode;var a=r.anchorOffset,o=r.focusNode;r=r.focusOffset;try{n.nodeType,o.nodeType}catch{n=null;break a}var s=0,c=-1,l=-1,u=0,d=0,f=e,p=null;b:for(;;){for(var m;f!==n||a!==0&&f.nodeType!==3||(c=s+a),f!==o||r!==0&&f.nodeType!==3||(l=s+r),f.nodeType===3&&(s+=f.nodeValue.length),(m=f.firstChild)!==null;)p=f,f=m;for(;;){if(f===e)break b;if(p===n&&++u===a&&(c=s),p===o&&++d===r&&(l=s),(m=f.nextSibling)!==null)break;f=p,p=f.parentNode}f=m}n=c===-1||l===-1?null:{start:c,end:l}}else n=null}n||={start:0,end:0}}else n=null;for(zd={focusedElem:e,selectionRange:n},sp=!1,Qc=t;Qc!==null;)if(t=Qc,e=t.child,t.subtreeFlags&1028&&e!==null)e.return=t,Qc=e;else for(;Qc!==null;){switch(t=Qc,o=t.alternate,e=t.flags,t.tag){case 0:if(e&4&&(e=t.updateQueue,e=e===null?null:e.events,e!==null))for(n=0;n title`))),Pd(o,r,n),o[dt]=e,P(o),r=o;break a;case`link`:var s=Vf(`link`,`href`,a).get(r+(n.href||``));if(s){for(var c=0;cg&&(o=g,g=h,h=o);var _=xr(s,h),v=xr(s,g);if(_&&v&&(p.rangeCount!==1||p.anchorNode!==_.node||p.anchorOffset!==_.offset||p.focusNode!==v.node||p.focusOffset!==v.offset)){var y=d.createRange();y.setStart(_.node,_.offset),p.removeAllRanges(),h>g?(p.addRange(y),p.extend(v.node,v.offset)):(y.setEnd(v.node,v.offset),p.addRange(y))}}}}for(d=[],p=s;p=p.parentNode;)p.nodeType===1&&d.push({element:p,left:p.scrollLeft,top:p.scrollTop});for(typeof s.focus==`function`&&s.focus(),s=0;sn?32:n,O.T=null,n=su,su=null;var o=ru,s=au;if(nu=0,iu=ru=null,au=0,Pl&6)throw Error(i(331));var c=Pl;if(Pl|=4,kl(o.current),xl(o,o.current,s,n),Pl=c,rd(0,!1),Ve&&typeof Ve.onPostCommitFiberRoot==`function`)try{Ve.onPostCommitFiberRoot(Be,o)}catch{}return!0}finally{k.p=a,O.T=r,zu(e,t)}}function Hu(e,t,n){t=fi(n,t),t=Gs(e.stateNode,t,2),e=Fa(e,t,2),e!==null&&(tt(e,2),nd(e))}function Uu(e,t,n){if(e.tag===3)Hu(e,e,n);else for(;t!==null;){if(t.tag===3){Hu(t,e,n);break}else if(t.tag===1){var r=t.stateNode;if(typeof t.type.getDerivedStateFromError==`function`||typeof r.componentDidCatch==`function`&&(tu===null||!tu.has(r))){e=fi(n,e),n=Ks(2),r=Fa(t,n,2),r!==null&&(qs(n,r,t,e),tt(r,2),nd(r));break}}t=t.return}}function Wu(e,t,n){var r=e.pingCache;if(r===null){r=e.pingCache=new Nl;var i=new Set;r.set(t,i)}else i=r.get(t),i===void 0&&(i=new Set,r.set(t,i));i.has(n)||(Bl=!0,i.add(n),e=Gu.bind(null,e,t,n),t.then(e,e))}function Gu(e,t,n){var r=e.pingCache;r!==null&&r.delete(t),e.pingedLanes|=e.suspendedLanes&n,e.warmLanes&=~n,Fl===e&&(Q&n)===n&&(Hl===4||Hl===3&&(Q&62914560)===Q&&300>Me()-Zl?!(Pl&2)&&bu(e,0):Gl|=n,ql===Q&&(ql=0)),nd(e)}function Ku(e,t){t===0&&(t=$e()),e=$r(e,t),e!==null&&(tt(e,t),nd(e))}function qu(e){var t=e.memoizedState,n=0;t!==null&&(n=t.retryLane),Ku(e,n)}function Ju(e,t){var n=0;switch(e.tag){case 31:case 13:var r=e.stateNode,a=e.memoizedState;a!==null&&(n=a.retryLane);break;case 19:r=e.stateNode;break;case 22:r=e.stateNode._retryCache;break;default:throw Error(i(314))}r!==null&&r.delete(t),Ku(e,n)}function Yu(e,t){return Oe(e,t)}var Xu=null,Zu=null,Qu=!1,$u=!1,ed=!1,td=0;function nd(e){e!==Zu&&e.next===null&&(Zu===null?Xu=Zu=e:Zu=Zu.next=e),$u=!0,Qu||(Qu=!0,ld())}function rd(e,t){if(!ed&&$u){ed=!0;do for(var n=!1,r=Xu;r!==null;){if(!t)if(e!==0){var i=r.pendingLanes;if(i===0)var a=0;else{var o=r.suspendedLanes,s=r.pingedLanes;a=(1<<31-Ue(42|e)+1)-1,a&=i&~(o&~s),a=a&201326741?a&201326741|1:a?a|2:0}a!==0&&(n=!0,cd(r,a))}else a=Q,a=Ze(r,r===Fl?a:0,r.cancelPendingCommit!==null||r.timeoutHandle!==-1),!(a&3)||Qe(r,a)||(n=!0,cd(r,a));r=r.next}while(n);ed=!1}}function id(){ad()}function ad(){$u=Qu=!1;var e=0;td!==0&&Gd()&&(e=td);for(var t=Me(),n=null,r=Xu;r!==null;){var i=r.next,a=od(r,t);a===0?(r.next=null,n===null?Xu=i:n.next=i,i===null&&(Zu=n)):(n=r,(e!==0||a&3)&&($u=!0)),r=i}nu!==0&&nu!==5||rd(e,!1),td!==0&&(td=0)}function od(e,t){for(var n=e.suspendedLanes,r=e.pingedLanes,i=e.expirationTimes,a=e.pendingLanes&-62914561;0s)break;var u=c.transferSize,d=c.initiatorType;u&&Id(d)&&(c=c.responseEnd,o+=u*(c`u`?null:document;function xf(e,t,n){var r=bf;if(r&&typeof t==`string`&&t){var i=L(t);i=`link[rel="`+e+`"][href="`+i+`"]`,typeof n==`string`&&(i+=`[crossorigin="`+n+`"]`),hf.has(i)||(hf.add(i),e={rel:e,crossOrigin:n,href:t},r.querySelector(i)===null&&(t=r.createElement(`link`),Pd(t,`link`,e),P(t),r.head.appendChild(t)))}}function Sf(e){_f.D(e),xf(`dns-prefetch`,e,null)}function Cf(e,t){_f.C(e,t),xf(`preconnect`,e,t)}function wf(e,t,n){_f.L(e,t,n);var r=bf;if(r&&e&&t){var i=`link[rel="preload"][as="`+L(t)+`"]`;t===`image`&&n&&n.imageSrcSet?(i+=`[imagesrcset="`+L(n.imageSrcSet)+`"]`,typeof n.imageSizes==`string`&&(i+=`[imagesizes="`+L(n.imageSizes)+`"]`)):i+=`[href="`+L(e)+`"]`;var a=i;switch(t){case`style`:a=Af(e);break;case`script`:a=Pf(e)}mf.has(a)||(e=h({rel:`preload`,href:t===`image`&&n&&n.imageSrcSet?void 0:e,as:t},n),mf.set(a,e),r.querySelector(i)!==null||t===`style`&&r.querySelector(jf(a))||t===`script`&&r.querySelector(Ff(a))||(t=r.createElement(`link`),Pd(t,`link`,e),P(t),r.head.appendChild(t)))}}function Tf(e,t){_f.m(e,t);var n=bf;if(n&&e){var r=t&&typeof t.as==`string`?t.as:`script`,i=`link[rel="modulepreload"][as="`+L(r)+`"][href="`+L(e)+`"]`,a=i;switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:a=Pf(e)}if(!mf.has(a)&&(e=h({rel:`modulepreload`,href:e},t),mf.set(a,e),n.querySelector(i)===null)){switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:if(n.querySelector(Ff(a)))return}r=n.createElement(`link`),Pd(r,`link`,e),P(r),n.head.appendChild(r)}}}function Ef(e,t,n){_f.S(e,t,n);var r=bf;if(r&&e){var i=Ct(r).hoistableStyles,a=Af(e);t||=`default`;var o=i.get(a);if(!o){var s={loading:0,preload:null};if(o=r.querySelector(jf(a)))s.loading=5;else{e=h({rel:`stylesheet`,href:e,"data-precedence":t},n),(n=mf.get(a))&&Rf(e,n);var c=o=r.createElement(`link`);P(c),Pd(c,`link`,e),c._p=new Promise(function(e,t){c.onload=e,c.onerror=t}),c.addEventListener(`load`,function(){s.loading|=1}),c.addEventListener(`error`,function(){s.loading|=2}),s.loading|=4,Lf(o,t,r)}o={type:`stylesheet`,instance:o,count:1,state:s},i.set(a,o)}}}function Df(e,t){_f.X(e,t);var n=bf;if(n&&e){var r=Ct(n).hoistableScripts,i=Pf(e),a=r.get(i);a||(a=n.querySelector(Ff(i)),a||(e=h({src:e,async:!0},t),(t=mf.get(i))&&zf(e,t),a=n.createElement(`script`),P(a),Pd(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function Of(e,t){_f.M(e,t);var n=bf;if(n&&e){var r=Ct(n).hoistableScripts,i=Pf(e),a=r.get(i);a||(a=n.querySelector(Ff(i)),a||(e=h({src:e,async:!0,type:`module`},t),(t=mf.get(i))&&zf(e,t),a=n.createElement(`script`),P(a),Pd(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function kf(e,t,n,r){var a=(a=ge.current)?gf(a):null;if(!a)throw Error(i(446));switch(e){case`meta`:case`title`:return null;case`style`:return typeof n.precedence==`string`&&typeof n.href==`string`?(t=Af(n.href),n=Ct(a).hoistableStyles,r=n.get(t),r||(r={type:`style`,instance:null,count:0,state:null},n.set(t,r)),r):{type:`void`,instance:null,count:0,state:null};case`link`:if(n.rel===`stylesheet`&&typeof n.href==`string`&&typeof n.precedence==`string`){e=Af(n.href);var o=Ct(a).hoistableStyles,s=o.get(e);if(s||(a=a.ownerDocument||a,s={type:`stylesheet`,instance:null,count:0,state:{loading:0,preload:null}},o.set(e,s),(o=a.querySelector(jf(e)))&&!o._p&&(s.instance=o,s.state.loading=5),mf.has(e)||(n={rel:`preload`,as:`style`,href:n.href,crossOrigin:n.crossOrigin,integrity:n.integrity,media:n.media,hrefLang:n.hrefLang,referrerPolicy:n.referrerPolicy},mf.set(e,n),o||Nf(a,e,n,s.state))),t&&r===null)throw Error(i(528,``));return s}if(t&&r!==null)throw Error(i(529,``));return null;case`script`:return t=n.async,n=n.src,typeof n==`string`&&t&&typeof t!=`function`&&typeof t!=`symbol`?(t=Pf(n),n=Ct(a).hoistableScripts,r=n.get(t),r||(r={type:`script`,instance:null,count:0,state:null},n.set(t,r)),r):{type:`void`,instance:null,count:0,state:null};default:throw Error(i(444,e))}}function Af(e){return`href="`+L(e)+`"`}function jf(e){return`link[rel="stylesheet"][`+e+`]`}function Mf(e){return h({},e,{"data-precedence":e.precedence,precedence:null})}function Nf(e,t,n,r){e.querySelector(`link[rel="preload"][as="style"][`+t+`]`)?r.loading=1:(t=e.createElement(`link`),r.preload=t,t.addEventListener(`load`,function(){return r.loading|=1}),t.addEventListener(`error`,function(){return r.loading|=2}),Pd(t,`link`,n),P(t),e.head.appendChild(t))}function Pf(e){return`[src="`+L(e)+`"]`}function Ff(e){return`script[async]`+e}function If(e,t,n){if(t.count++,t.instance===null)switch(t.type){case`style`:var r=e.querySelector(`style[data-href~="`+L(n.href)+`"]`);if(r)return t.instance=r,P(r),r;var a=h({},n,{"data-href":n.href,"data-precedence":n.precedence,href:null,precedence:null});return r=(e.ownerDocument||e).createElement(`style`),P(r),Pd(r,`style`,a),Lf(r,n.precedence,e),t.instance=r;case`stylesheet`:a=Af(n.href);var o=e.querySelector(jf(a));if(o)return t.state.loading|=4,t.instance=o,P(o),o;r=Mf(n),(a=mf.get(a))&&Rf(r,a),o=(e.ownerDocument||e).createElement(`link`),P(o);var s=o;return s._p=new Promise(function(e,t){s.onload=e,s.onerror=t}),Pd(o,`link`,r),t.state.loading|=4,Lf(o,n.precedence,e),t.instance=o;case`script`:return o=Pf(n.src),(a=e.querySelector(Ff(o)))?(t.instance=a,P(a),a):(r=n,(a=mf.get(o))&&(r=h({},n),zf(r,a)),e=e.ownerDocument||e,a=e.createElement(`script`),P(a),Pd(a,`link`,r),e.head.appendChild(a),t.instance=a);case`void`:return null;default:throw Error(i(443,t.type))}else t.type===`stylesheet`&&!(t.state.loading&4)&&(r=t.instance,t.state.loading|=4,Lf(r,n.precedence,e));return t.instance}function Lf(e,t,n){for(var r=n.querySelectorAll(`link[rel="stylesheet"][data-precedence],style[data-precedence]`),i=r.length?r[r.length-1]:null,a=i,o=0;o title`):null)}function Uf(e,t,n){if(n===1||t.itemProp!=null)return!1;switch(e){case`meta`:case`title`:return!0;case`style`:if(typeof t.precedence!=`string`||typeof t.href!=`string`||t.href===``)break;return!0;case`link`:if(typeof t.rel!=`string`||typeof t.href!=`string`||t.href===``||t.onLoad||t.onError)break;switch(t.rel){case`stylesheet`:return e=t.disabled,typeof t.precedence==`string`&&e==null;default:return!0}case`script`:if(t.async&&typeof t.async!=`function`&&typeof t.async!=`symbol`&&!t.onLoad&&!t.onError&&t.src&&typeof t.src==`string`)return!0}return!1}function Wf(e){return!(e.type===`stylesheet`&&!(e.state.loading&3))}function Gf(e,t,n,r){if(n.type===`stylesheet`&&(typeof r.media!=`string`||!1!==matchMedia(r.media).matches)&&!(n.state.loading&4)){if(n.instance===null){var i=Af(r.href),a=t.querySelector(jf(i));if(a){t=a._p,typeof t==`object`&&t&&typeof t.then==`function`&&(e.count++,e=Jf.bind(e),t.then(e,e)),n.state.loading|=4,n.instance=a,P(a);return}a=t.ownerDocument||t,r=Mf(r),(i=mf.get(i))&&Rf(r,i),a=a.createElement(`link`),P(a);var o=a;o._p=new Promise(function(e,t){o.onload=e,o.onerror=t}),Pd(a,`link`,r),n.instance=a}e.stylesheets===null&&(e.stylesheets=new Map),e.stylesheets.set(n,t),(t=n.state.preload)&&!(n.state.loading&3)&&(e.count++,n=Jf.bind(e),t.addEventListener(`load`,n),t.addEventListener(`error`,n))}}var Kf=0;function qf(e,t){return e.stylesheets&&e.count===0&&Xf(e,e.stylesheets),0Kf?50:800)+t);return e.unsuspend=n,function(){e.unsuspend=null,clearTimeout(r),clearTimeout(i)}}:null}function Jf(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)Xf(this,this.stylesheets);else if(this.unsuspend){var e=this.unsuspend;this.unsuspend=null,e()}}}var Yf=null;function Xf(e,t){e.stylesheets=null,e.unsuspend!==null&&(e.count++,Yf=new Map,t.forEach(Zf,e),Yf=null,Jf.call(e))}function Zf(e,t){if(!(t.state.loading&4)){var n=Yf.get(e);if(n)var r=n.get(null);else{n=new Map,Yf.set(e,n);for(var i=e.querySelectorAll(`link[data-precedence],style[data-precedence]`),a=0;a{function n(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>`u`||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=`function`))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=h()})),_=c(u(),1),v=g(),y=class{baseUrl;actorUserId;constructor(e){this.baseUrl=e.baseUrl.replace(/\/$/,``),this.actorUserId=e.actorUserId.trim()}async login(e){return this.post(`/auth/login`,{email:e.email,password:e.password,device_fingerprint:T(),device_label:e.deviceLabel,trust_device:e.trustDevice})}async refresh(e){return this.post(`/auth/refresh`,{refresh_token:e.refreshToken})}async getInstallationStatus(){return(await this.request(`/installation/status`,{method:`GET`})).installation}async bootstrapOwner(e){return this.post(`/installation/bootstrap-owner`,{email:e.email,password:e.password,activation_payload:e.activationPayload,activation_signature:e.activationSignature||``})}async revokeAuthSession(e){await this.post(`/auth/sessions/revoke`,{user_id:e.userId,auth_session_id:e.authSessionId,reason:e.reason})}async listClusters(){return(await this.get(`/clusters`)).clusters??[]}async createCluster(e){return(await this.post(`/clusters/`,{actor_user_id:this.actorUserId,slug:e.slug,name:e.name,region:e.region||null,metadata:{}})).cluster}async updateCluster(e,t){return(await this.put(`/clusters/${e}`,{actor_user_id:this.actorUserId,name:t.name,status:t.status,region:t.region||null,metadata:t.metadata||{}})).cluster}async listClusterSummaries(){return(await this.get(`/cluster-admin-summaries`)).cluster_summaries??[]}async getClusterAuthority(e){return(await this.get(`/clusters/${e}/authority`)).authority_state}async updateClusterAuthority(e,t){return(await this.put(`/clusters/${e}/authority`,{actor_user_id:this.actorUserId,authority_state:t.authorityState,mutation_mode:t.mutationMode,notes:t.notes||null})).authority_state}async listNodes(e){return(await this.get(`/clusters/${e}/nodes`)).nodes??[]}async listNodeGroups(e){return(await this.get(`/clusters/${e}/node-groups`)).node_groups??[]}async createNodeGroup(e,t){return(await this.post(`/clusters/${e}/node-groups`,{actor_user_id:this.actorUserId,parent_group_id:t.parentGroupId||null,name:t.name,description:t.description||null,sort_order:t.sortOrder||0,metadata:{}})).node_group}async assignNodeGroup(e,t,n){return(await this.put(`/clusters/${e}/nodes/${t}/group`,{actor_user_id:this.actorUserId,group_id:n||null})).node}async disableMembership(e,t,n){await this.post(`/clusters/${e}/nodes/${t}/membership/disable`,{actor_user_id:this.actorUserId,reason:n})}async attachExistingNode(e,t,n){return(await this.post(`/clusters/${e}/nodes/${t}/membership/attach`,{actor_user_id:this.actorUserId,roles:n})).node}async revokeNodeIdentity(e,t,n){await this.post(`/clusters/${e}/nodes/${t}/identity/revoke`,{actor_user_id:this.actorUserId,reason:n})}async deleteClusterNode(e,t,n){await this.delete(`/clusters/${e}/nodes/${t}`,{actor_user_id:this.actorUserId,reason:n})}async listJoinRequests(e){return(await this.get(`/clusters/${e}/join-requests`)).join_requests??[]}async createJoinToken(e,t){let n=new Date(Date.now()+Math.max(t.ttlHours,1)*60*60*1e3).toISOString();return(await this.post(`/clusters/${e}/join-tokens`,{actor_user_id:this.actorUserId,scope:t.scope,expires_at:n,max_uses:Math.max(t.maxUses,1)})).join_token}async listJoinTokens(e){return(await this.get(`/clusters/${e}/join-tokens`)).join_tokens??[]}async revokeJoinToken(e,t){return(await this.post(`/clusters/${e}/join-tokens/${t}/revoke`,{actor_user_id:this.actorUserId})).join_token}async approveJoinRequest(e,t){await this.post(`/clusters/${e}/join-requests/${t}/approve`,{actor_user_id:this.actorUserId,ownership_type:`platform_managed`})}async rejectJoinRequest(e,t,n){await this.post(`/clusters/${e}/join-requests/${t}/reject`,{actor_user_id:this.actorUserId,reason:n})}async listNodeRoles(e,t){return(await this.get(`/clusters/${e}/nodes/${t}/roles`)).role_assignments??[]}async assignRole(e,t,n,r){await this.setRoleStatus(e,t,n,`active`,r)}async setRoleStatus(e,t,n,r,i){await this.post(`/clusters/${e}/nodes/${t}/roles`,{actor_user_id:this.actorUserId,organization_id:i||null,role:n,status:r,policy:{}})}async listWorkloadStatuses(e,t){return(await this.get(`/clusters/${e}/nodes/${t}/workloads/status`)).workload_statuses??[]}async listDesiredWorkloads(e,t){return(await this.get(`/clusters/${e}/nodes/${t}/workloads/desired`)).desired_workloads??[]}async listNodeHeartbeats(e,t,n=100){return(await this.get(`/clusters/${e}/nodes/${t}/heartbeats?limit=${n}`)).heartbeats??[]}async listNodeTelemetry(e,t,n=120){return(await this.get(`/clusters/${e}/nodes/${t}/telemetry?limit=${n}`)).telemetry??[]}async listReleaseVersions(e,t=`rap-node-agent`,n=`dev`){let r=new URLSearchParams({product:t,channel:n});return(await this.get(`/clusters/${e}/updates/releases?${r.toString()}`)).release_versions??[]}async createReleaseVersion(e,t){return(await this.post(`/clusters/${e}/updates/releases`,{actor_user_id:this.actorUserId,product:t.product,version:t.version,channel:t.channel||`stable`,status:t.status||`active`,compatibility:t.compatibility||{},changelog:t.changelog||``,artifacts:t.artifacts.map(e=>({os:e.os,arch:e.arch,install_type:e.installType,kind:e.kind,url:e.url,sha256:e.sha256,size_bytes:e.sizeBytes||0,metadata:e.metadata||{}}))})).release_version}async getStaleNodeRiskReport(e){let t=new URLSearchParams({actor_user_id:this.actorUserId});return(await this.get(`/clusters/${e}/updates/stale-node-risk-report?${t.toString()}`)).stale_node_risk_report}async getNodeUpdatePlan(e,t,n){let r=new URLSearchParams({product:n.product||`rap-node-agent`,current_version:n.currentVersion||``,os:n.os||`linux`,arch:n.arch||`amd64`,install_type:n.installType||`docker`,channel:n.channel||`dev`});return(await this.get(`/clusters/${e}/nodes/${t}/updates/plan?${r.toString()}`)).node_update_plan}async getNodeBridgeReplayPlan(e,t){let n=new URLSearchParams({actor_user_id:this.actorUserId});return(await this.get(`/clusters/${e}/nodes/${t}/updates/bridge-replay-plan?${n.toString()}`)).node_bridge_replay_plan}async upsertNodeUpdatePolicy(e,t,n){return(await this.put(`/clusters/${e}/nodes/${t}/updates/policy`,{actor_user_id:this.actorUserId,product:n.product,channel:n.channel||`dev`,target_version:n.targetVersion??null,strategy:n.strategy||`rolling`,enabled:n.enabled??!0,rollback_allowed:n.rollbackAllowed??!0,health_window_seconds:n.healthWindowSeconds||180})).node_update_policy}async listNodeUpdateStatuses(e,t,n=80){let r=new URLSearchParams({actor_user_id:this.actorUserId,limit:String(n)});return(await this.get(`/clusters/${e}/nodes/${t}/updates/statuses?${r.toString()}`)).node_update_statuses??[]}async listFabricTestingFlags(){return(await this.get(`/fabric/testing-flags`)).testing_flags??[]}async updateFabricTestingFlag(e){return(await this.put(`/fabric/testing-flags`,{actor_user_id:this.actorUserId,scope_type:e.scopeType,scope_id:e.scopeId||null,cluster_id:e.clusterId||null,enabled:e.enabled,telemetry_enabled:e.telemetryEnabled,synthetic_links_enabled:e.syntheticLinksEnabled,history_retention_hours:e.historyRetentionHours,metadata:e.metadata||{}})).testing_flag}async setDesiredWorkload(e,t,n,r){await this.put(`/clusters/${e}/nodes/${t}/workloads/${n}/desired`,{actor_user_id:this.actorUserId,desired_state:r.desiredState,version:r.version||null,runtime_mode:r.runtimeMode,artifact_ref:null,config:r.config,environment:r.environment})}async listMeshLinks(e){return(await this.get(`/clusters/${e}/mesh/links`)).mesh_links??[]}async listRouteIntents(e){let t=new URLSearchParams({actor_user_id:this.actorUserId});return(await this.get(`/clusters/${e}/mesh/route-intents?${t.toString()}`)).route_intents??[]}async expireRouteIntent(e,t,n){return(await this.post(`/clusters/${e}/mesh/route-intents/${t}/expire`,{actor_user_id:this.actorUserId,reason:n})).route_intent}async disableRouteIntent(e,t,n){return(await this.post(`/clusters/${e}/mesh/route-intents/${t}/disable`,{actor_user_id:this.actorUserId,reason:n})).route_intent}async getNodeSyntheticMeshConfig(e,t){return(await this.get(`/clusters/${e}/nodes/${t}/mesh/synthetic-config`)).synthetic_mesh_config}async listFabricServiceChannelRouteFeedback(e,t={}){let n=new URLSearchParams({actor_user_id:this.actorUserId});return t.reporterNodeId&&n.set(`reporter_node_id`,t.reporterNodeId),t.routeId&&n.set(`route_id`,t.routeId),t.serviceClass&&n.set(`service_class`,t.serviceClass),t.feedbackStatus&&n.set(`feedback_status`,t.feedbackStatus),t.includeExpired&&n.set(`include_expired`,`true`),(await this.get(`/clusters/${e}/fabric/service-channels/route-feedback?${n.toString()}`)).route_feedback??[]}async expireFabricServiceChannelRouteFeedback(e,t){return(await this.post(`/clusters/${e}/fabric/service-channels/route-feedback/expire`,{actor_user_id:this.actorUserId,route_id:t.routeId,reporter_node_id:t.reporterNodeId||``,service_class:t.serviceClass||``,reason:t.reason||`expired from admin fabric diagnostics`})).route_feedback_expire}async listFabricServiceChannelRouteRebuildAttempts(e,t={}){let n=new URLSearchParams({actor_user_id:this.actorUserId});return t.reporterNodeId&&n.set(`reporter_node_id`,t.reporterNodeId),t.routeId&&n.set(`route_id`,t.routeId),t.replacementRouteId&&n.set(`replacement_route_id`,t.replacementRouteId),t.serviceClass&&n.set(`service_class`,t.serviceClass),t.rebuildStatus&&n.set(`rebuild_status`,t.rebuildStatus),t.rebuildRequestId&&n.set(`rebuild_request_id`,t.rebuildRequestId),t.generation&&n.set(`generation`,t.generation),t.feedbackSource&&n.set(`feedback_source`,t.feedbackSource),t.feedbackChannelId&&n.set(`feedback_channel_id`,t.feedbackChannelId),t.feedbackViolationStatus&&n.set(`feedback_violation_status`,t.feedbackViolationStatus),t.enrichment&&n.set(`enrichment`,t.enrichment),t.limit&&n.set(`limit`,String(t.limit)),t.offset&&n.set(`offset`,String(t.offset)),(await this.get(`/clusters/${e}/fabric/service-channels/rebuild-attempts?${n.toString()}`)).rebuild_attempts??[]}async getFabricServiceChannelRouteRebuildHealthSummary(e,t={}){let n=new URLSearchParams({actor_user_id:this.actorUserId});return t.limit&&n.set(`limit`,String(t.limit)),(await this.get(`/clusters/${e}/fabric/service-channels/rebuild-health?${n.toString()}`)).rebuild_health}async getFabricServiceChannelReadiness(e,t={}){let n=new URLSearchParams({actor_user_id:this.actorUserId});return t.limit&&n.set(`limit`,String(t.limit)),(await this.get(`/clusters/${e}/fabric/service-channels/readiness?${n.toString()}`)).fabric_service_channel_readiness}async getFabricServiceChannelSchemaStatus(e){let t=new URLSearchParams({actor_user_id:this.actorUserId});return(await this.get(`/clusters/${e}/fabric/service-channels/schema-status?${t.toString()}`)).fabric_service_channel_schema_status}async getFabricServiceChannelRebuildSnapshotMaintenanceHealth(e,t={}){let n=new URLSearchParams({actor_user_id:this.actorUserId});return t.limit&&n.set(`limit`,String(t.limit)),t.minAgeSeconds&&n.set(`min_age_seconds`,String(t.minAgeSeconds)),t.heartbeatThreshold&&n.set(`heartbeat_threshold`,String(t.heartbeatThreshold)),(await this.get(`/clusters/${e}/fabric/service-channels/rebuild-snapshots/health?${n.toString()}`)).rebuild_snapshot_health}async warmupFabricServiceChannelRebuildSnapshots(e,t={}){return(await this.post(`/clusters/${e}/fabric/service-channels/rebuild-snapshots/warmup`,{actor_user_id:this.actorUserId,limit:t.limit||10,stale_after_seconds:t.staleAfterSeconds||60})).rebuild_snapshot_warmup}async getFabricServiceChannelLeaseMaintenance(e,t={}){let n=new URLSearchParams({actor_user_id:this.actorUserId});return t.limit&&n.set(`limit`,String(t.limit)),t.includeExpired&&n.set(`include_expired`,`true`),(await this.get(`/clusters/${e}/fabric/service-channels/leases?${n.toString()}`)).fabric_service_channel_lease_maintenance}async cleanupFabricServiceChannelLeases(e,t={}){return(await this.post(`/clusters/${e}/fabric/service-channels/leases/cleanup`,{actor_user_id:this.actorUserId,limit:t.limit||100})).fabric_service_channel_lease_maintenance}async getFabricServiceChannelAccessTelemetry(e,t={}){let n=new URLSearchParams({actor_user_id:this.actorUserId});return t.limit&&n.set(`limit`,String(t.limit)),(await this.get(`/clusters/${e}/fabric/service-channels/access-telemetry?${n.toString()}`)).fabric_service_channel_access_telemetry}async listFabricServiceChannelRouteRebuildIncidents(e,t={}){let n=new URLSearchParams({actor_user_id:this.actorUserId});return t.limit&&n.set(`limit`,String(t.limit)),(await this.get(`/clusters/${e}/fabric/service-channels/rebuild-incidents?${n.toString()}`)).rebuild_incidents??[]}async getFabricServiceChannelRebuildInvestigationBreadcrumbs(e,t={}){let n=new URLSearchParams({actor_user_id:this.actorUserId});return t.limit&&n.set(`limit`,String(t.limit)),t.currentWindowSeconds&&n.set(`current_window_seconds`,String(t.currentWindowSeconds)),t.historyWindowSeconds&&n.set(`history_window_seconds`,String(t.historyWindowSeconds)),(await this.get(`/clusters/${e}/fabric/service-channels/rebuild-investigations/breadcrumbs?${n.toString()}`)).rebuild_investigation_breadcrumbs}async recordFabricServiceChannelRouteRebuildInvestigation(e,t){await this.post(`/clusters/${e}/fabric/service-channels/rebuild-incidents/investigations`,{actor_user_id:this.actorUserId,reporter_node_id:t.reporterNodeId,route_id:t.routeId,service_class:t.serviceClass||``,generation:t.generation||``,guard_status:t.guardStatus||``,incident_id:t.incidentId||``,feedback_source:t.feedbackSource||``,feedback_channel_id:t.feedbackChannelId||``,feedback_violation_status:t.feedbackViolationStatus||``,drilldown_source:t.drilldownSource||``,reason:t.reason||`operator opened deep rebuild ledger`})}async silenceFabricServiceChannelRouteRebuildAlert(e,t){return(await this.post(`/clusters/${e}/fabric/service-channels/rebuild-health/silences`,{actor_user_id:this.actorUserId,incident_source:t.incidentSource||``,channel_id:t.channelId||``,reporter_node_id:t.reporterNodeId,route_id:t.routeId,guard_status:t.guardStatus,generation:t.generation||``,reason:t.reason||`operator acknowledged rebuild alert`,ttl_seconds:t.ttlSeconds||21600})).rebuild_alert_silence}async listFabricServiceChannelRouteRebuildAlertSilences(e){let t=new URLSearchParams({actor_user_id:this.actorUserId});return(await this.get(`/clusters/${e}/fabric/service-channels/rebuild-health/silences?${t.toString()}`)).rebuild_alert_silences??[]}async unsilenceFabricServiceChannelRouteRebuildAlert(e,t,n){return(await this.delete(`/clusters/${e}/fabric/service-channels/rebuild-health/silences/${encodeURIComponent(t)}`,{actor_user_id:this.actorUserId,reason:n||`operator removed rebuild alert silence`})).rebuild_alert_silence}async getFabricServiceChannelRecoveryPolicy(e){let t=new URLSearchParams({actor_user_id:this.actorUserId});return(await this.get(`/clusters/${e}/fabric/service-channels/recovery-policy?${t.toString()}`)).fabric_service_channel_recovery_policy}async updateFabricServiceChannelRecoveryPolicy(e,t){return(await this.put(`/clusters/${e}/fabric/service-channels/recovery-policy`,{actor_user_id:this.actorUserId,hysteresis_penalty:t.hysteresisPenalty,promotion_min_samples:t.promotionMinSamples,demotion_failure_threshold:t.demotionFailureThreshold,demotion_drop_threshold:t.demotionDropThreshold,demotion_slow_threshold:t.demotionSlowThreshold,demotion_rebuild_enabled:t.demotionRebuildEnabled,demotion_fenced_enabled:t.demotionFencedEnabled})).fabric_service_channel_recovery_policy}async getFabricServiceChannelAdaptivePolicy(e){let t=new URLSearchParams({actor_user_id:this.actorUserId});return(await this.get(`/clusters/${e}/fabric/service-channels/adaptive-policy?${t.toString()}`)).fabric_service_channel_adaptive_policy}async updateFabricServiceChannelAdaptivePolicy(e,t){return(await this.put(`/clusters/${e}/fabric/service-channels/adaptive-policy`,{actor_user_id:this.actorUserId,max_parallel_window:t.maxParallelWindow,bulk_pressure_channel_threshold:t.bulkPressureChannelThreshold,queue_pressure_high_watermark:t.queuePressureHighWatermark,queue_pressure_max_in_flight:t.queuePressureMaxInFlight,class_windows:t.classWindows})).fabric_service_channel_adaptive_policy}async getFabricServiceChannelPoolPolicy(e){let t=new URLSearchParams({actor_user_id:this.actorUserId});return(await this.get(`/clusters/${e}/fabric/service-channels/pool-policy?${t.toString()}`)).fabric_service_channel_pool_policy}async updateFabricServiceChannelPoolPolicy(e,t){return(await this.put(`/clusters/${e}/fabric/service-channels/pool-policy`,{actor_user_id:this.actorUserId,entry_pool_node_ids:t.entryPoolNodeIds,exit_pool_node_ids:t.exitPoolNodeIds,preferred_entry_node_id:t.preferredEntryNodeId,preferred_exit_node_id:t.preferredExitNodeId,selection_strategy:t.selectionStrategy,route_rebuild:t.routeRebuild,entry_failover:t.entryFailover,exit_failover:t.exitFailover,backend_fallback_allowed:t.backendFallbackAllowed,sticky_session:t.stickySession})).fabric_service_channel_pool_policy}async getFabricServiceChannelBreadcrumbWindowPolicy(e){let t=new URLSearchParams({actor_user_id:this.actorUserId});return(await this.get(`/clusters/${e}/fabric/service-channels/breadcrumb-window-policy?${t.toString()}`)).fabric_service_channel_breadcrumb_window_policy}async updateFabricServiceChannelBreadcrumbWindowPolicy(e,t){return(await this.put(`/clusters/${e}/fabric/service-channels/breadcrumb-window-policy`,{actor_user_id:this.actorUserId,current_window_seconds:t.currentWindowSeconds,history_window_seconds:t.historyWindowSeconds})).fabric_service_channel_breadcrumb_window_policy}async listQoSPolicies(e){return(await this.get(`/clusters/${e}/mesh/qos-policies`)).qos_policies??[]}async listVPNConnections(e){return(await this.get(`/clusters/${e}/vpn-connections`)).vpn_connections??[]}async createVPNConnection(e,t){return(await this.post(`/clusters/${e}/vpn-connections`,{actor_user_id:this.actorUserId,organization_id:t.organizationId,name:t.name,target_endpoint:t.targetEndpoint,protocol_family:t.protocolFamily,credential_ref:t.credentialRef||null,mode:`single_active`,desired_state:t.desiredState,allowed_node_policy:t.allowedNodePolicy,routing_usage:t.routingUsage,route_policy:t.routePolicy,qos_policy:t.qosPolicy,placement_policy:t.placementPolicy,metadata:{}})).vpn_connection}async updateVPNConnectionDesiredState(e,t,n){return(await this.put(`/clusters/${e}/vpn-connections/${t}/desired-state`,{actor_user_id:this.actorUserId,desired_state:n})).vpn_connection}async getActiveVPNLease(e,t){try{return(await this.get(`/clusters/${e}/vpn-connections/${t}/leases/active`)).lease}catch{return null}}async getVPNPacketStats(e,t){return(await this.get(`/clusters/${e}/vpn-connections/${t}/tunnel/stats`)).vpn_packet_stats??{}}async getVPNClientDiagnosticStatus(e,t){if(!t.trim())return null;try{return(await this.get(`/clusters/${e}/vpn/client-diagnostics/${encodeURIComponent(t.trim())}/status`)).vpn_client_diagnostic_status??null}catch{return null}}async listVPNClientDiagnosticStatuses(e){return(await this.get(`/clusters/${e}/vpn/client-diagnostics`)).vpn_client_diagnostic_statuses??[]}async enqueueVPNClientDiagnosticCommand(e,t,n){return(await this.post(`/clusters/${e}/vpn/client-diagnostics/${encodeURIComponent(t.trim())}/commands`,n)).vpn_client_diagnostic_command}async expireStaleVPNLeases(e){return(await this.post(`/clusters/${e}/vpn-connection-leases/expire-stale`,{actor_user_id:this.actorUserId})).expired_leases??[]}async listAudit(e,t={}){return(await this.listAuditDetailed(e,t)).events}async listAuditDetailed(e,t={}){let n=new URLSearchParams({limit:String(t.limit||100)});for(let e of t.eventTypes||[])e&&n.append(`event_type`,e);for(let e of t.targetTypes||[])e&&n.append(`target_type`,e);t.correlation&&n.set(`correlation`,t.correlation);let r=await this.get(`/clusters/${e}/audit?${n.toString()}`);return{events:r.audit_events??[],summary:r.audit_summary}}clusterEventsURL(e){return`${this.baseUrl}/clusters/${encodeURIComponent(e)}/events?actor_user_id=${encodeURIComponent(this.actorUserId)}`}async getOrganizationAdminSummary(e){return(await this.get(`/organizations/${e}/admin-summary`)).admin_summary}async listOrganizations(){return(await this.request(`/organizations?user_id=${encodeURIComponent(this.actorUserId)}`,{method:`GET`})).organizations??[]}async createOrganization(e){return(await this.post(`/organizations/`,{actor_user_id:this.actorUserId,slug:e.slug,name:e.name,metadata:e.metadata||{}})).organization}async listUsers(){return(await this.get(`/users/`)).users??[]}async createUser(e){return(await this.post(`/users/`,{actor_user_id:this.actorUserId,email:e.email,password:e.password,platform_role:e.platformRole||`user`})).user}async listOrganizationMemberships(e){return(await this.request(`/organizations/${e}/memberships?user_id=${encodeURIComponent(this.actorUserId)}`,{method:`GET`})).memberships??[]}async addOrganizationMembership(e,t){return(await this.post(`/organizations/${e}/memberships`,{actor_user_id:this.actorUserId,user_id:t.userId,role_id:t.roleId})).membership}async listResources(e){let t=new URLSearchParams({user_id:this.actorUserId});return e&&t.set(`organization_id`,e),(await this.request(`/resources?${t.toString()}`,{method:`GET`})).resources??[]}async createResource(e){return(await this.post(`/resources/`,{actor_user_id:this.actorUserId,organization_id:e.organizationId,name:e.name,address:e.address,protocol:e.protocol||`rdp`,secret_ref:e.secretRef||null,certificate_verification_mode:e.certificateVerificationMode||`strict`,render_quality_profile:e.renderQualityProfile||`balanced`,clipboard_mode:e.clipboardMode||`disabled`,file_transfer_mode:e.fileTransferMode||`disabled`,metadata:e.metadata||{}})).resource}async upsertResourceSecret(e,t){await this.put(`/resources/${e}/secret`,{actor_user_id:this.actorUserId,payload:{username:t.username||``,password:t.password||``,domain:t.domain||``},metadata:{source:`web-admin`}})}async get(e){let t=e.includes(`?`)?`&`:`?`;return this.request(`${e}${t}actor_user_id=${encodeURIComponent(this.actorUserId)}`,{method:`GET`})}async post(e,t){return this.request(e,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t)})}async put(e,t){return this.request(e,{method:`PUT`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t)})}async delete(e,t){return this.request(e,{method:`DELETE`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t)})}async request(e,t){let n=await fetch(`${this.baseUrl}${e}`,t);if(!n.ok){let e=`Запрос завершился ошибкой HTTP ${n.status}`;try{let t=await n.json();e=b(t,n.status)||t.error?.fallback_message||t.error?.code||e}catch{}throw Error(e)}return await n.json()}};function b(e,t){let n=e.error;if(!n)return``;if(t===409&&n.code===`conflict.legacy_compatibility_removal_is_blocked_while_stale_recovery_risk_nodes_remain`){let e=n.details||{},t=[`Compatibility cleanup заблокирован.`],r=x(e,`blocked_operation`);r&&t.push(`Операция: ${r}.`);let i=[S(e,`blocked_nodes`)?`blockers ${S(e,`blocked_nodes`)}`:``,S(e,`stale_nodes`)?`stale ${S(e,`stale_nodes`)}`:``,S(e,`artifact_gap_nodes`)?`artifact gap ${S(e,`artifact_gap_nodes`)}`:``,S(e,`unknown_profile_nodes`)?`profile unknown ${S(e,`unknown_profile_nodes`)}`:``,S(e,`waiting_update_status_nodes`)?`waiting status ${S(e,`waiting_update_status_nodes`)}`:``,S(e,`unknown_version_nodes`)?`version unknown ${S(e,`unknown_version_nodes`)}`:``,S(e,`legacy_recovery_contract_nodes`)?`legacy contract ${S(e,`legacy_recovery_contract_nodes`)}`:``,S(e,`recovery_bridge_required_nodes`)?`recovery bridge ${S(e,`recovery_bridge_required_nodes`)}`:``,S(e,`recovery_bridge_replay_ready_nodes`)?`bridge replay ready ${S(e,`recovery_bridge_replay_ready_nodes`)}`:``,S(e,`waiting_recovery_heartbeat_nodes`)?`waiting heartbeat ${S(e,`waiting_recovery_heartbeat_nodes`)}`:``].filter(Boolean);i.length>0&&t.push(i.join(` / `)+`.`);let a=w(e,`blocked_node_ids`);if(a.length>0&&t.push(`Blocked nodes: ${a.join(`, `)}.`),C(e,`bridge_hold_required`)){let n=w(e,`bridge_hold_reasons`),r=w(e,`bridge_hold_node_ids`),i=[];n.length>0&&i.push(`reasons ${n.join(`, `)}`),r.length>0&&i.push(`nodes ${r.join(`, `)}`),t.push(`Recovery bridge hold active${i.length>0?`: ${i.join(` / `)}`:``}.`)}let o=n.trace_id?.trim();return o&&t.push(`Trace: ${o}.`),t.join(` `)}return``}function x(e,t){let n=e[t];return typeof n==`string`?n.trim():``}function S(e,t){let n=e[t];return typeof n==`number`&&Number.isFinite(n)?n:0}function C(e,t){return e[t]===!0}function w(e,t){let n=e[t];return Array.isArray(n)?n.filter(e=>typeof e==`string`&&e.trim().length>0):[]}function T(){let e=`rap.webAdmin.deviceFingerprint`,t=localStorage.getItem(e);if(t)return t;let n=`web-admin-${ee()}`;return localStorage.setItem(e,n),n}function ee(){if(typeof globalThis.crypto?.randomUUID==`function`)return globalThis.crypto.randomUUID();if(typeof globalThis.crypto?.getRandomValues==`function`){let e=new Uint8Array(16);globalThis.crypto.getRandomValues(e),e[6]=e[6]&15|64,e[8]=e[8]&63|128;let t=Array.from(e,e=>e.toString(16).padStart(2,`0`)).join(``);return`${t.slice(0,8)}-${t.slice(8,12)}-${t.slice(12,16)}-${t.slice(16,20)}-${t.slice(20)}`}return`${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`}var te=o((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.fragment`);function r(e,n,r){var i=null;if(r!==void 0&&(i=``+r),n.key!==void 0&&(i=``+n.key),`key`in n)for(var a in r={},n)a!==`key`&&(r[a]=n[a]);else r=n;return n=r.ref,{$$typeof:t,type:e,key:i,ref:n===void 0?null:n,props:r}}e.Fragment=n,e.jsx=r,e.jsxs=r})),E=o(((e,t)=>{t.exports=te()}))(),D={baseUrl:`rap.webAdmin.baseUrl`,actorUserId:`rap.webAdmin.actorUserId`,auth:`rap.webAdmin.auth`,language:`rap.webAdmin.language`,vpnDiagnosticDeviceId:`rap.webAdmin.vpnDiagnosticDeviceId`},ne=`/api/v1`,re=`http://192.168.200.61:8080/api/v1`,ie={reporterNodeId:``,routeId:``,serviceClass:``,generation:``,feedbackSource:``,feedbackChannelId:``,feedbackViolationStatus:``,offset:0},ae=[`public-ingress`,`admin-ingress`,`global-admin-runtime`,`cluster-admin-runtime`,`organization-portal-runtime`,`user-portal-runtime`,`identity-runtime`,`policy-authority`,`audit-sink`,`entry-node`,`relay-node`,`core-mesh`,`rdp-worker`,`vnc-worker`,`vpn-exit`,`vpn-connector`,`vpn-client`,`ipv4-egress`,`file-storage-cache`,`update-cache`,`video-relay`],oe={"public-ingress":`Public HTTPS ingress`,"admin-ingress":`Admin HTTPS ingress`,"global-admin-runtime":`Global admin runtime`,"cluster-admin-runtime":`Cluster admin runtime`,"organization-portal-runtime":`Organization portal runtime`,"user-portal-runtime":`User portal runtime`,"identity-runtime":`Identity runtime`,"policy-authority":`Policy authority`,"audit-sink":`Audit sink`,"entry-node":`Entry node`,"relay-node":`Relay node`,"core-mesh":`Mesh core`,"rdp-worker":`RDP worker`,"vnc-worker":`VNC worker`,"vpn-exit":`VPN exit`,"vpn-connector":`VPN connector`,"vpn-client":`VPN client node`,"ipv4-egress":`IPv4 egress`,"file-storage-cache":`File/cache storage`,"update-cache":`Update cache`,"video-relay":`Video relay`},se={"public-ingress":[`can_accept_client_ingress`,`fabric_service_channel_runtime`],"admin-ingress":[`can_accept_client_ingress`,`fabric_service_channel_runtime`],"global-admin-runtime":[`can_run_admin_runtime`,`platform_owner_trusted_node`],"cluster-admin-runtime":[`can_run_admin_runtime`],"organization-portal-runtime":[`can_run_admin_runtime`],"user-portal-runtime":[`can_run_admin_runtime`],"identity-runtime":[`can_run_identity_runtime`],"policy-authority":[`can_run_policy_authority`,`platform_owner_trusted_node`],"audit-sink":[`can_run_audit_sink`,`platform_owner_trusted_node`],"entry-node":[`can_accept_client_ingress`],"relay-node":[`mesh_rendezvous_relay_control_contract`,`mesh_peer_connection_manager`],"core-mesh":[`native_node_agent`,`mesh_peer_connection_manager`,`mesh_listener_diagnostics`],"rdp-worker":[`can_run_rdp_worker`],"vnc-worker":[`can_run_vnc_worker`],"vpn-exit":[`can_run_vpn_exit`],"vpn-connector":[`can_run_vpn_connector`],"vpn-client":[`can_run_vpn_client`,`fabric_service_channel_required`],"ipv4-egress":[`can_egress_internet`,`fabric_service_channel_required`],"file-storage-cache":[`can_run_file_cache`],"update-cache":[`can_run_update_cache`],"video-relay":[`can_run_video_relay`]},O=[{id:`command`,ru:`Обзор`,en:`Command`},{id:`clusters`,ru:`Кластеры`,en:`Clusters`},{id:`cluster-settings`,ru:`Настройки кластера`,en:`Cluster Settings`},{id:`nodes`,ru:`Узлы`,en:`Nodes`},{id:`enrollment`,ru:`Новый узел`,en:`New Node`},{id:`roles`,ru:`Роли`,en:`Roles`},{id:`workloads`,ru:`Сервисы`,en:`Workloads`},{id:`fabric`,ru:`Связи Fabric`,en:`Fabric Links`},{id:`vpn`,ru:`VPN Control`,en:`VPN Control`},{id:`servers`,ru:`Серверы`,en:`Servers`},{id:`org-safe`,ru:`Организации`,en:`Organizations`},{id:`audit`,ru:`Аудит`,en:`Audit`}];function k(e){if(!e||typeof e!=`object`)return null;let t=e;return typeof t.userId!=`string`||typeof t.email!=`string`||typeof t.authSessionId!=`string`||typeof t.accessToken!=`string`||typeof t.refreshToken!=`string`||typeof t.accessTokenExpiresAt!=`string`||typeof t.refreshTokenExpiresAt!=`string`||!t.userId||!t.refreshToken?null:{userId:t.userId,email:t.email,authSessionId:t.authSessionId,accessToken:t.accessToken,refreshToken:t.refreshToken,accessTokenExpiresAt:t.accessTokenExpiresAt,refreshTokenExpiresAt:t.refreshTokenExpiresAt}}function ce(e){let t=Date.parse(e);return!Number.isFinite(t)||t<=Date.now()}function le(){try{let e=localStorage.getItem(D.auth);if(!e)return null;let t=k(JSON.parse(e));return!t||ce(t.refreshTokenExpiresAt)?null:t}catch{return null}}var ue={ttlHours:24,maxUses:1,roles:[`core-mesh`],nodeName:``,nodeGroupId:``,ownershipType:`platform_managed`,purpose:``,installMode:`docker`,dockerImage:`rap-node-agent:dev-enrollment-bootstrap-smoke`,dockerContainerName:``,dockerNetwork:`host`,windowsStartupMode:`auto`,windowsInstallDir:``,windowsNodeAgentSHA256:``,linuxInstallDir:``,linuxNodeAgentSHA256:``,meshListenAddr:``,meshListenPortMode:`auto`,meshListenAutoPortStart:19131,meshListenAutoPortEnd:19231,meshAdvertiseEndpoint:``,meshAdvertiseEndpoints:``,meshAdvertiseTransport:`direct_quic`,meshConnectivityMode:`private_lan`,meshNATType:`none`,meshRegion:`docker-test`,controlPlaneEndpoint:``,artifactEndpoints:``,dockerImageArtifactSHA256:``,pullImage:!1,replace:!0,syntheticRuntime:!1},de={ru:{productOwner:`Владелец продукта`,controlPlane:`Панель управления`,sideText:`Главная панель владельца платформы для кластеров, узлов, доверия, ролей и безопасного desired state.`,signInTitle:`Вход`,signInText:`Введите учетные данные.`,bootstrapTitle:`Первый владелец`,bootstrapText:`Пустая установка принимает только подписанную активацию продукта.`,activationPayload:`Activation manifest JSON`,activationSignature:`Подпись manifest`,createOwner:`Создать владельца`,creatingOwner:`Создание...`,ownerCreated:`Владелец создан. Теперь можно войти.`,installationLocked:`Установка уже активирована`,insecureBootstrapDisabled:`Insecure bootstrap выключен. Нужна strict-активация с ключом продукта.`,email:`Логин`,password:`Пароль`,backendApi:`Backend API`,useLocalProxy:`Использовать локальный /api/v1 proxy`,language:`Язык`,deviceLabel:`Устройство`,rememberMe:`Запомнить меня`,trustDevice:`Доверять этому устройству`,signIn:`Войти`,signingIn:`Вход...`,logout:`Выйти`,profile:`Профиль`,refresh:`Обновить`,refreshing:`Обновление...`,autoRefresh:`Автообновление`,lastRefresh:`Данные обновлены`,activeCluster:`Активный кластер`,slugLabel:`Технический код`,slugHelp:`Slug — постоянный короткий технический идентификатор кластера для URL, скриптов, логов и интеграций. Его лучше не менять после создания.`,clusterCatalog:`Каталог кластеров`,clusterCatalogText:`Список реальных кластеров из Control/API слоя. Выберите активный кластер или раскройте карточку для подробностей.`,makeActive:`Сделать активным`,openSettings:`Открыть настройки`,selected:`Выбран`,createCluster:`Создать кластер`,clusterDetails:`Подробнее`,consoleTitle:`Панель владельца платформы`,boundary:`WEB является только представлением. HTTP Control API управляет политикой, релизами и аудитом; межузловой transport Fabric остается QUIC/UDP.`,noLoginError:`Войдите как владелец продукта или администратор платформы, чтобы загрузить панель.`,accessDenied:`Доступ к этой панели запрещен.`,sessionMode:`Режим сессии`,sessionModeAdmin:`Админ`,sessionModeUser:`Пользователь`,sessionRefreshedAt:`Сессия обновлена`,emptyLiveTitle:`Кластер пока пустой`,emptyLiveText:`Это реальные данные, не заглушка: в выбранном кластере ещё нет одобренных node-agent узлов. Создайте join token, запустите rap-node-agent и подтвердите join request.`,realDataNote:`Показываются только данные из PostgreSQL и Control/API слоя. Если значения нулевые, значит соответствующих узлов, ролей или сервисов пока нет.`,signedInAs:`Вход выполнен`,actorUser:`Actor user`,testMode:`Тестирование`,testModeText:`Включает тестовую телеметрию и синтетические наблюдения связей. Это не production mesh runtime.`,platformTestFlag:`Тестирование сервера`,nodeTelemetry:`Телеметрия узла`,heartbeatHistory:`История heartbeat`,noTelemetry:`Телеметрии пока нет`,enableTelemetry:`Включить телеметрию`,enableSyntheticLinks:`Включить тестовые связи`,saveTestFlag:`Сохранить флаг`,nodeManagement:`Управление узлом`,nodeScope:`Область просмотра`,currentClusterNodes:`Узлы активного кластера`,allNodes:`Все узлы платформы`,showAllPlatformNodes:`Показать все узлы платформы`,currentClusterMembership:`Участие в активном кластере`,clusterMemberships:`Участие по кластерам`,notMemberOfActiveCluster:`не состоит`,nodeIdentity:`Физическая идентичность узла`,activeClusterScope:`Область активного кластера`,activeClusterScopeText:`Один физический узел может состоять в нескольких кластерах. Роли и desired-сервисы ниже относятся только к выбранному активному кластеру.`,capabilityConfirmed:`способность подтверждена heartbeat`,capabilityMissing:`способность не заявлена узлом`,capabilityUnknown:`способность не подтверждена: нет heartbeat`,nodeGlobalInventoryText:`Один физический узел показан один раз. Участие и роли остаются кластерными: в разных кластерах этот же узел может иметь разные назначения.`,nodeSearch:`Поиск узлов`,groupNodesBy:`Группировать`,groupByMembership:`по участию`,groupByHealth:`по здоровью`,groupByOwnership:`по владению`,groupByClusterCount:`по числу кластеров`,nodeGroups:`Группы узлов`,nodeGroupTree:`Дерево групп`,nodeGroupFilter:`Фильтр по группе`,allNodeGroups:`Все группы`,nodeGroupCreatePanel:`Создание группы`,nodeGroupName:`Название группы`,parentNodeGroup:`Родительская группа`,rootNodeGroup:`Корень`,ungroupedNodes:`Без группы`,createNodeGroup:`Создать группу`,createSubgroup:`Создать подгруппу`,collapseGroup:`Свернуть`,expandGroup:`Развернуть`,assignNodeGroup:`Переместить в группу`,removeFromNodeGroup:`Убрать из группы`,connectExistingNode:`Подключить к активному кластеру`,connectExistingNodeTitle:`Подключить существующий узел`,connectExistingNodeText:`Будет создано или повторно включено участие конкретного физического узла в активном кластере. Роли ниже назначаются только в этом кластере.`,connectWithRoles:`Подключить с ролями`,nodeDetails:`Сведения`,manageNode:`Настроить`,nodeFunctions:`Функции узла`,nodeFunctionsText:`Одна строка управляет функцией целиком: роль задает разрешение в активном кластере, desired-сервис задает запуск, observed показывает факт от node-agent.`,rolePermission:`Разрешение`,permissionGranted:`разрешено`,permissionDenied:`нет разрешения`,organizationScopeForEnable:`Область организации для новых включений, опционально`,clusterWideRolePlaceholder:`пусто = роль на весь кластер`,desiredRuntime:`Желаемое состояние`,observedRuntime:`Фактически`,enableFunction:`Включить функцию`,disableFunction:`Выключить функцию`,close:`Закрыть`,nodeBriefList:`Краткий список узлов`,noActiveClusterMembership:`Узел не входит в активный кластер`,nodeBriefListHelp:`Список сгруппирован деревом активного кластера. Полные сведения, управление, роли, сервисы и статистика открываются из строки узла.`,nodeSearchPlaceholder:`имя, ключ, кластер, статус`,nodeGroupInventoryText:`Группы — это кластерная инвентарная структура. Перенос узла в группу меняет только его размещение внутри активного кластера, не роли и не членство.`,nodeGroupCreated:`Группа узлов создана.`,noNodesTitle:`Нет узлов`,noNodesByFilter:`По текущему фильтру узлы не найдены.`,cancel:`Отмена`,alreadyMember:`Уже в активном кластере`,revokedMembership:`Участие отозвано`,addNode:`Подключить узел`,addNodeText:`Подключение существующего физического узла к активному кластеру выполняется из списка узлов: включите общий режим и нажмите «Подключить к активному кластеру».`,joinTokenTitle:`Создать новый Docker-узел`,joinTokenText:`Сначала создается одноразовый install token и Docker install profile. Затем команда запускается на Docker-хосте, агент отправляет заявку, а владелец платформы подтверждает ее.`,ttlHours:`Срок действия, часов`,ttlHelp:`Через это время token станет недействительным, даже если им никто не воспользовался. Для ручного подключения обычно достаточно 1–24 часов.`,maxUses:`Максимум использований`,maxUsesHelp:`Сколько node-agent смогут использовать этот token. Самый безопасный вариант — 1 token на 1 новый узел.`,tokenPurpose:`Назначение token`,nodeOwnership:`Тип владения узлом`,suggestedRoles:`Разрешенные/ожидаемые роли`,generatedScope:`Сгенерированная область действия`,generatedScopeHelp:`JSON формируется автоматически из настроек выше. Оператор не должен писать его руками, чтобы не ошибиться синтаксисом или областью доступа.`,manualApprovalRequired:`Подтверждение заявки вручную обязательно`,nodeRoles:`Роли узла`,desiredServices:`Желаемые сервисы`,observedServices:`Наблюдаемые сервисы`,noRoles:`Ролей пока нет`,noServices:`Сервисов пока нет`,manageInCluster:`Управлять в кластере`,rolesAndServices:`Роли и сервисы`,links:`Связи`,fabricMap:`Карта трафика Fabric`,fabricNodeLayer:`Узлы кластера`,observedPeerLinks:`Наблюдаемые связи`,placementIntent:`управляющее назначение`,endpointName:`Название`,publicEndpoint:`Публичный адрес`,endpointType:`Тип входа`,description:`Описание`,routeScope:`Область маршрутов JSON`,endpointNodes:`Назначенные узлы`,assignEndpointNode:`Назначить узел`,selectNode:`Выберите узел`,assignedNodesEmpty:`Узлы пока не назначены`,addressNotSet:`адрес не задан`,descriptionNotSet:`описание не задано`,servicePlacement:`Размещение сервисов`,trafficFlow:`Потоки между узлами`,organizationTestFlag:`Тестирование организации`,organizationId:`ID организации`,saveOrganizationFlag:`Сохранить флаг организации`,noLinks:`Связей пока нет`,recentHeartbeats:`Последние heartbeat`,memory:`Память`,cpu:`Процессор`,processes:`Процессы`},en:{productOwner:`Product Owner`,controlPlane:`Control API`,sideText:`Full platform-owner panel for clusters, nodes, trust, placement, and safe service desired state.`,signInTitle:`Sign in`,signInText:`Enter your credentials.`,bootstrapTitle:`First owner`,bootstrapText:`An empty installation accepts only a signed product activation.`,activationPayload:`Activation manifest JSON`,activationSignature:`Manifest signature`,createOwner:`Create owner`,creatingOwner:`Creating...`,ownerCreated:`Owner created. You can sign in now.`,installationLocked:`Installation is already active`,insecureBootstrapDisabled:`Insecure bootstrap is disabled. Strict product-key activation is required.`,email:`Login`,password:`Password`,backendApi:`Backend API`,useLocalProxy:`Use local /api/v1 proxy`,language:`Language`,deviceLabel:`Device`,rememberMe:`Remember me`,trustDevice:`Trust this device`,signIn:`Sign in`,signingIn:`Signing in...`,logout:`Logout`,profile:`Profile`,refresh:`Refresh`,refreshing:`Refreshing...`,autoRefresh:`Auto refresh`,lastRefresh:`Data refreshed`,activeCluster:`Active cluster`,slugLabel:`Technical code`,slugHelp:`Slug is a stable short technical identifier for URLs, scripts, logs, and integrations. It should generally not change after creation.`,clusterCatalog:`Cluster catalog`,clusterCatalogText:`Real clusters from the Control/API layer. Select the active cluster or expand a card for details.`,makeActive:`Make active`,openSettings:`Open settings`,selected:`Selected`,createCluster:`Create cluster`,clusterDetails:`Details`,consoleTitle:`Platform Owner Console`,boundary:`WEB is presentation only. The HTTP Control API handles policy, releases, and audit; inter-node Fabric transport remains QUIC/UDP.`,noLoginError:`Sign in as a product owner or platform administrator to load the panel.`,accessDenied:`Access to this panel is denied.`,sessionMode:`Session mode`,sessionModeAdmin:`Admin`,sessionModeUser:`User`,sessionRefreshedAt:`Session refreshed`,emptyLiveTitle:`Cluster has no live nodes yet`,emptyLiveText:`These are real values, not placeholders: the selected cluster has no approved node-agent nodes yet. Create a join token, run rap-node-agent, and approve the join request.`,realDataNote:`Only PostgreSQL and Control/API data is shown. Zero values mean the corresponding nodes, roles, or services do not exist yet.`,signedInAs:`Signed in`,actorUser:`Actor user`,testMode:`Testing`,testModeText:`Enables test telemetry and synthetic link observations. This is not production mesh runtime.`,platformTestFlag:`Server testing`,nodeTelemetry:`Node telemetry`,heartbeatHistory:`Heartbeat history`,noTelemetry:`No telemetry yet`,enableTelemetry:`Enable telemetry`,enableSyntheticLinks:`Enable test links`,saveTestFlag:`Save flag`,nodeManagement:`Node management`,nodeScope:`View scope`,currentClusterNodes:`Active cluster nodes`,allNodes:`All platform nodes`,showAllPlatformNodes:`Show all platform nodes`,currentClusterMembership:`Active cluster membership`,clusterMemberships:`Cluster memberships`,notMemberOfActiveCluster:`not a member`,nodeIdentity:`Physical node identity`,activeClusterScope:`Active cluster scope`,activeClusterScopeText:`One physical node may belong to multiple clusters. Roles and desired services below belong only to the selected active cluster.`,capabilityConfirmed:`capability confirmed by heartbeat`,capabilityMissing:`capability not reported by node`,capabilityUnknown:`capability unconfirmed: no heartbeat`,nodeGlobalInventoryText:`Each physical node is shown once. Membership and roles remain cluster-scoped, so the same node may have different assignments in different clusters.`,nodeSearch:`Node search`,groupNodesBy:`Group by`,groupByMembership:`membership`,groupByHealth:`health`,groupByOwnership:`ownership`,groupByClusterCount:`cluster count`,nodeGroups:`Node groups`,nodeGroupTree:`Group tree`,nodeGroupFilter:`Group filter`,allNodeGroups:`All groups`,nodeGroupCreatePanel:`Create group`,nodeGroupName:`Group name`,parentNodeGroup:`Parent group`,rootNodeGroup:`Root`,ungroupedNodes:`Ungrouped`,createNodeGroup:`Create group`,createSubgroup:`Create subgroup`,collapseGroup:`Collapse`,expandGroup:`Expand`,assignNodeGroup:`Move to group`,removeFromNodeGroup:`Remove from group`,connectExistingNode:`Connect to active cluster`,connectExistingNodeTitle:`Connect existing node`,connectExistingNodeText:`This creates or re-enables membership for one concrete physical node in the active cluster. Roles below are assigned only in this cluster.`,connectWithRoles:`Connect with roles`,nodeDetails:`Details`,manageNode:`Configure`,nodeFunctions:`Node functions`,nodeFunctionsText:`One row controls the whole function: role grants permission in the active cluster, desired service requests runtime start, observed state reports node-agent facts.`,rolePermission:`Permission`,permissionGranted:`granted`,permissionDenied:`not allowed`,organizationScopeForEnable:`Organization scope for new enables, optional`,clusterWideRolePlaceholder:`empty = cluster-wide role`,desiredRuntime:`Desired state`,observedRuntime:`Observed`,enableFunction:`Enable function`,disableFunction:`Disable function`,close:`Close`,nodeBriefList:`Compact node list`,noActiveClusterMembership:`Node is not a member of the active cluster`,nodeBriefListHelp:`The list is grouped as the active cluster tree. Full details, management, roles, services, and statistics open from the node row.`,nodeSearchPlaceholder:`name, key, cluster, status`,nodeGroupInventoryText:`Groups are a cluster inventory structure. Moving a node to a group changes only its placement inside the active cluster, not roles or membership.`,nodeGroupCreated:`Node group created.`,noNodesTitle:`No nodes`,noNodesByFilter:`No nodes match the current filter.`,cancel:`Cancel`,alreadyMember:`Already in active cluster`,revokedMembership:`Membership revoked`,addNode:`Add node`,addNodeText:`Connect an existing physical node to the active cluster from the node list: enable platform-wide view and click “Connect to active cluster”.`,joinTokenTitle:`Create new Docker node`,joinTokenText:`First create a one-time install token and Docker install profile. Then run the generated command on the Docker host; the agent submits a request and the platform owner approves it.`,ttlHours:`Lifetime, hours`,ttlHelp:`After this time the token becomes invalid even if unused. For manual enrollment, 1–24 hours is usually enough.`,maxUses:`Maximum uses`,maxUsesHelp:`How many node-agents may use this token. The safest default is one token for one new node.`,tokenPurpose:`Token purpose`,nodeOwnership:`Node ownership type`,suggestedRoles:`Allowed/expected roles`,generatedScope:`Generated scope`,generatedScopeHelp:`JSON is generated automatically from the settings above. Operators should not hand-write it and risk syntax or access-scope mistakes.`,manualApprovalRequired:`Manual request approval is required`,nodeRoles:`Node roles`,desiredServices:`Desired services`,observedServices:`Observed services`,noRoles:`No roles yet`,noServices:`No services yet`,manageInCluster:`Manage in cluster`,rolesAndServices:`Roles and services`,links:`Links`,fabricMap:`Fabric traffic map`,fabricNodeLayer:`Cluster nodes`,observedPeerLinks:`Observed links`,placementIntent:`control/API placement`,endpointName:`Name`,publicEndpoint:`Public endpoint`,endpointType:`Entry type`,description:`Description`,routeScope:`Route scope JSON`,endpointNodes:`Assigned nodes`,assignEndpointNode:`Assign node`,selectNode:`Select node`,assignedNodesEmpty:`No nodes assigned yet`,addressNotSet:`address not set`,descriptionNotSet:`description not set`,servicePlacement:`Service placement`,trafficFlow:`Node traffic flows`,organizationTestFlag:`Organization testing`,organizationId:`Organization ID`,saveOrganizationFlag:`Save organization flag`,noLinks:`No links yet`,recentHeartbeats:`Recent heartbeats`,memory:`Memory`,cpu:`CPU`,processes:`Processes`}};function fe(e){return{userId:e.user.id||e.user.ID||``,email:e.user.email||e.user.Email||``,authSessionId:e.auth_session.id||e.auth_session.ID||``,accessToken:e.tokens.access_token,refreshToken:e.tokens.refresh_token,accessTokenExpiresAt:e.tokens.access_token_expires_at,refreshTokenExpiresAt:e.tokens.refresh_token_expires_at}}async function pe(e){try{return await e.listClusterSummaries(),`admin`}catch{try{return await Promise.all([e.listOrganizations(),e.listResources()]),`user`}catch{return null}}}function me(){let[e,t]=(0,_.useState)(!1),[n,r]=(0,_.useState)(()=>!!le()),[i]=(0,_.useState)(()=>{let e=localStorage.getItem(D.baseUrl)?.trim();return!e||e.startsWith(re)?ne:e}),[a,o]=(0,_.useState)(()=>le()),[s,c]=(0,_.useState)(null),[l,u]=(0,_.useState)(``),[d,f]=(0,_.useState)(()=>localStorage.getItem(D.language)===`en`?`en`:`ru`),[p,m]=(0,_.useState)(a?.userId??localStorage.getItem(D.actorUserId)??``),[h,g]=(0,_.useState)({email:``,password:``,deviceLabel:`Панель владельца платформы`,trustDevice:!0,rememberMe:!0,showPassword:!1}),[v,b]=(0,_.useState)(null),[x,S]=(0,_.useState)({email:``,password:``,activationPayload:``,activationSignature:``}),[C,w]=(0,_.useState)(`command`),[T,ee]=(0,_.useState)(``),[te,oe]=(0,_.useState)([]),[se,k]=(0,_.useState)([]),[me,xe]=(0,_.useState)(null),[j,De]=(0,_.useState)([]),[Oe,ke]=(0,_.useState)([]),[Ae,je]=(0,_.useState)({}),[Me,Ne]=(0,_.useState)([]),[Pe,Fe]=(0,_.useState)([]),[Ie,Le]=(0,_.useState)([]),[M,Re]=(0,_.useState)(null),[He,Ue]=(0,_.useState)({}),[We,Ge]=(0,_.useState)({}),[Ke,qe]=(0,_.useState)({}),[Je,Ye]=(0,_.useState)({}),[Xe,Ze]=(0,_.useState)({}),[nt,ot]=(0,_.useState)({}),[st,ct]=(0,_.useState)({}),[ut,_t]=(0,_.useState)({}),[bt,Ct]=(0,_.useState)([]),[P,wt]=(0,_.useState)([]),[Tt,Et]=(0,_.useState)({}),[Pt,Ft]=(0,_.useState)([]),[It,qt]=(0,_.useState)([]),[Jt,Xt]=(0,_.useState)(null),[$t,en]=(0,_.useState)([]),[dn,fn]=(0,_.useState)(null),[pn,mn]=(0,_.useState)(null),[hn,_n]=(0,_.useState)(null),[vn,yn]=(0,_.useState)(null),[bn,xn]=(0,_.useState)(null),[R,Sn]=(0,_.useState)(null),[Cn,wn]=(0,_.useState)([]),[Tn,z]=(0,_.useState)(!1),[En,Dn]=(0,_.useState)(ie),[jn,Mn]=(0,_.useState)(null),[Nn,Ln]=(0,_.useState)(null),[Rn,zn]=(0,_.useState)([]),[Bn,Vn]=(0,_.useState)([]),[Hn,Un]=(0,_.useState)([]),[Wn,Kn]=(0,_.useState)({}),[qn,$n]=(0,_.useState)({}),[ar,or]=(0,_.useState)(()=>localStorage.getItem(D.vpnDiagnosticDeviceId)||``),[sr,cr]=(0,_.useState)([]),[lr,ur]=(0,_.useState)(null),[dr,fr]=(0,_.useState)(`http://2ip.ru/`),[pr,mr]=(0,_.useState)(null),[hr,gr]=(0,_.useState)([]),[_r,vr]=(0,_.useState)([]),[yr,br]=(0,_.useState)([]),[xr,Sr]=(0,_.useState)({}),[Cr,wr]=(0,_.useState)([]),[Tr,Er]=(0,_.useState)(``),[Dr,Or]=(0,_.useState)(``),[kr,Ar]=(0,_.useState)([]),[jr,Mr]=(0,_.useState)(null),[Nr,Pr]=(0,_.useState)(``),[Fr,Ir]=(0,_.useState)(`poll`),[Lr,Rr]=(0,_.useState)(``),[zr,Br]=(0,_.useState)(null),[Vr,Hr]=(0,_.useState)(!1),[Ur,Wr]=(0,_.useState)(``),[Gr,Kr]=(0,_.useState)(``),[qr,Jr]=(0,_.useState)({slug:``,name:``,region:``}),[Yr,Xr]=(0,_.useState)({name:``,status:`active`,region:``,metadataJson:`{}`}),[Zr,Qr]=(0,_.useState)({name:``,parentGroupId:``}),[$r,ei]=(0,_.useState)({hysteresisPenalty:`150`,promotionMinSamples:`64`,demotionFailureThreshold:`1`,demotionDropThreshold:`1`,demotionSlowThreshold:`1`,demotionRebuildEnabled:!0,demotionFencedEnabled:!0}),[ti,ni]=(0,_.useState)({currentWindowSeconds:`1800`,historyWindowSeconds:`86400`}),[U,W]=(0,_.useState)(ue),[ri,ii]=(0,_.useState)(null),[ai,oi]=(0,_.useState)({authorityState:`authoritative`,mutationMode:`normal`,notes:``}),[si,ci]=(0,_.useState)(``),[li,ui]=(0,_.useState)(`cluster`),[di,fi]=(0,_.useState)(``),[pi,mi]=(0,_.useState)(``),[hi,gi]=(0,_.useState)([]),[_i,vi]=(0,_.useState)(`membership`),[yi,bi]=(0,_.useState)(null),[xi,Si]=(0,_.useState)([]),[Ci,wi]=(0,_.useState)(null),[Ti,Ei]=(0,_.useState)(`details`),[Di,Oi]=(0,_.useState)({}),[ki,Ai]=(0,_.useState)({}),[ji,Mi]=(0,_.useState)({}),[Ni,Pi]=(0,_.useState)({}),[Fi,Ii]=(0,_.useState)(``),[Li,Ri]=(0,_.useState)({telemetry:!0,links:!0}),[zi,Bi]=(0,_.useState)({nodeId:``,serviceType:`entry-node`,desiredState:`enabled`,runtimeMode:`container`,version:``,configJson:`{}`,environmentJson:`{}`}),[G,Vi]=(0,_.useState)({organizationId:``,name:``,protocolFamily:`generic`,desiredState:`disabled`,credentialRef:``,targetEndpointJson:`{}`,allowedNodePolicyJson:`{"mode":"explicit","node_ids":[]}`,routingUsageJson:`[]`,routePolicyJson:`{}`,qosPolicyJson:`{}`,placementPolicyJson:`{}`}),[Hi,Ui]=(0,_.useState)({slug:``,name:``}),[Wi,Gi]=(0,_.useState)({email:``,password:``,platformRole:`user`}),[Ki,qi]=(0,_.useState)({organizationId:``,userId:``,roleId:`org_member`}),[Ji,Yi]=(0,_.useState)(null),[Xi,Zi]=(0,_.useState)({username:``,password:``,domain:``}),[Qi,$i]=(0,_.useState)(``),[ea,ta]=(0,_.useState)(``),[K,na]=(0,_.useState)({organizationId:``,name:``,address:``,protocol:`rdp`,routeMode:`vpn_exit`,entryNode:``,exitNode:``,tags:``,username:``,password:``,domain:``}),[ra,ia]=(0,_.useState)(``),[aa,oa]=(0,_.useState)(``),[sa,ca]=(0,_.useState)(``),la=`rap-android-vpn-latest-release.apk`,[ua,da]=(0,_.useState)(la),q=(0,_.useMemo)(()=>new y({baseUrl:i,actorUserId:p}),[i,p]),fa=(0,_.useMemo)(()=>new y({baseUrl:i,actorUserId:``}),[i]),pa=(0,_.useRef)(0),ma=(0,_.useRef)(!1),J=de[d],ha=te.find(e=>e.id===T)||null,ga=se.find(e=>e.cluster_id===T)||null,_a=(0,_.useMemo)(()=>Yn(i),[i]),va=(0,_.useCallback)((e,t)=>{if(!e)return t;let n=e.trim();return n?/^https?:\/\//i.test(n)||n.startsWith(`/`)?n.startsWith(`/`)?n.substring(1):n:n.startsWith(`downloads/`)?n:`downloads/${n.replace(/^\.\/+/,``).replace(/^\/+/,``)}`:t},[]),ya=va(ua,la),ba=sa?va(sa,ya):ya,xa=sa?ba:ya,Sa=`${/^https?:\/\//i.test(xa)?xa:`${_a}/${xa}`}${aa?`?_v=${encodeURIComponent(aa)}`:``}`,Ca=(0,_.useMemo)(()=>Gt(U),[U]),wa=(0,_.useMemo)(()=>ri?Kt(ri.scope,U):U,[ri,U]),Ta=(0,_.useMemo)(()=>{let e=new Map;for(let t of te)for(let n of Ae[t.id]||[]){let r=e.get(n.id);r?(r.memberships.push({cluster:t,node:n}),(n.last_seen_at||``)>(r.node.last_seen_at||``)&&(r.node=n)):e.set(n.id,{node:n,memberships:[{cluster:t,node:n}]})}return Array.from(e.values()).sort((e,t)=>e.node.name.localeCompare(t.node.name))},[Ae,te]);(0,_.useMemo)(()=>kn(Ta,T,di,_i,d),[Ta,_i,di,d,T]);let Ea=(0,_.useMemo)(()=>Object.fromEntries(Ta.map(e=>[e.node.id,e])),[Ta]),Da=(0,_.useMemo)(()=>{let e=di.trim().toLowerCase(),t=pi?new Set([pi,...Ht(pi,Oe)]):null;return Ta.filter(n=>{let r=n.memberships.some(e=>e.cluster.id===T);if(li!==`all`&&!r)return!1;if(t){let e=n.memberships.find(e=>e.cluster.id===T);if(!e?.node.node_group_id||!t.has(e.node.node_group_id))return!1}return!e||An(n,e)})},[Ta,di,pi,Oe,li,T]),Oa=(0,_.useCallback)((e,t=!1)=>{if(e&&t){localStorage.setItem(D.auth,JSON.stringify(e)),localStorage.setItem(D.actorUserId,e.userId),r(!0);return}r(!1),localStorage.removeItem(D.auth),localStorage.removeItem(D.actorUserId)},[]),ka=(0,_.useCallback)(async()=>{try{let e=`${_a}/downloads/rap-android-vpn-build.json?_cb=${Date.now()}`,t=await fetch(e,{cache:`no-store`});if(!t.ok){ia(``),oa(new Date().toISOString()),ca(``),da(la);return}let n=await t.json();ia(n.version?.name||``),oa(n.published?.timestamp_utc||``),ca(n.release_paths?.versioned||``),da(n.published?.path||n.release_paths?.latest||la)}catch{ia(``),oa(new Date().toISOString()),ca(``),da(la)}},[_a]),Aa=(0,_.useMemo)(()=>Ut(Da,Oe,T,J,new Set(hi)),[hi,Oe,T,J,Da]),ja=(0,_.useMemo)(()=>Cr.filter(e=>e.event_type===`legacy_compatibility_removal.blocked`).slice(0,4),[Cr]),Ma=(0,_.useMemo)(()=>Tr?Cr.filter(e=>jt(e,Tr)):Cr,[Cr,Tr]),Na=(0,_.useCallback)((e,t)=>{let n=Ea[e];n&&(w(`nodes`),ui(`all`),mi(``),fi(n.node.name||n.node.node_key),wi(n),Ei(t))},[Ea]),Pa=(0,_.useCallback)(e=>{let t=Ea[e];Er(e),Or(t?.node.name||t?.node.node_key||e),w(`audit`)},[Ea]),Fa=(0,_.useMemo)(()=>kr.slice(0,8),[kr]);(0,_.useEffect)(()=>{if(e)return;t(!0);let n=le();if(n){if(ce(n.refreshTokenExpiresAt)){localStorage.removeItem(D.auth),localStorage.removeItem(D.actorUserId),r(!1);return}(async()=>{try{let e=fe(await fa.refresh({refreshToken:n.refreshToken}));if(!e.userId||!e.authSessionId)throw Error(`Не удалось восстановить сессию.`);let t=await pe(new y({baseUrl:i,actorUserId:e.userId}));if(!t)throw Error(`Доступ к этой панели запрещен.`);m(e.userId),Oa(e,!0),o(e),u(new Date().toISOString()),g(t=>({...t,email:e.email})),c(t)}catch{localStorage.removeItem(D.auth),localStorage.removeItem(D.actorUserId),r(!1),u(``),o(null),m(``),c(null)}})()}},[fa,e,i,Oa]),(0,_.useEffect)(()=>{let e=!1;return fa.getInstallationStatus().then(t=>{e||b(t)}).catch(t=>{e||Wr(t instanceof Error?t.message:`Не удалось загрузить статус установки.`)}),()=>{e=!0}},[fa]),(0,_.useEffect)(()=>{if(!ha){Xr({name:``,status:`active`,region:``,metadataJson:`{}`});return}Xr({name:ha.name,status:ha.status||`active`,region:ha.region||``,metadataJson:JSON.stringify(ha.metadata||{},null,2)})},[ha]),(0,_.useEffect)(()=>{mi(``),Qr({name:``,parentGroupId:``}),gi([])},[T]),(0,_.useEffect)(()=>{bi(null),Si([])},[T]),(0,_.useEffect)(()=>{localStorage.setItem(D.baseUrl,i),localStorage.setItem(D.language,d),a&&localStorage.setItem(`${D.language}.${a.userId}`,d),(!a||!n)&&(localStorage.removeItem(D.auth),localStorage.removeItem(D.actorUserId))},[i,d,n,a]),(0,_.useEffect)(()=>{if(!a)return;let e=localStorage.getItem(`${D.language}.${a.userId}`);(e===`ru`||e===`en`)&&f(e)},[a?.userId]),(0,_.useEffect)(()=>{a&&Ia()},[a?.userId]),(0,_.useEffect)(()=>{if(!a||s!==`admin`||!T)return;let e=!1,t=()=>{e||Vr||ma.current||document.visibilityState===`hidden`||(ma.current=!0,Ra(T).catch(t=>{e||Wr(t instanceof Error?t.message:`Не удалось автообновить данные панели.`)}).finally(()=>{ma.current=!1}))},n=null;typeof window.EventSource==`function`&&(n=new EventSource(q.clusterEventsURL(T)),n.onopen=()=>{e||Ir(`sse`)},n.onerror=()=>{e||Ir(`poll`)},n.addEventListener(`cluster.changed`,t));let r=window.setInterval(t,n?3e4:1e4);return()=>{e=!0,n?.close(),window.clearInterval(r)}},[q,s,Vr,T,a?.userId]);async function Ia(e=T){if(!p.trim()){Wr(J.noLoginError);return}if(s===`user`){await La();return}Hr(!0),Wr(``),Kr(``);try{let[t,n,r,i,a]=await Promise.all([q.listClusters(),q.listClusterSummaries(),q.listOrganizations(),q.listUsers(),q.listResources()]);oe(t),k(n),gr(r),vr(i),br(a),!Lr&&r[0]?.id&&Rr(r[0].id),qi(e=>({...e,organizationId:e.organizationId||r[0]?.id||``})),na(e=>({...e,organizationId:e.organizationId||r[0]?.id||``}));let o=await Promise.all(r.map(async e=>[e.id,await q.listOrganizationMemberships(e.id)]));Sr(Object.fromEntries(o));let s=await Promise.all(t.map(async e=>[e.id,await q.listNodes(e.id)]));je(Object.fromEntries(s));let c=e||t[0]?.id||``;ee(c),c&&await za(c),Pr(new Date().toISOString())}catch(e){Wr(e instanceof Error?e.message:`Неизвестная ошибка панели управления платформой.`)}finally{Hr(!1)}}async function La(){if(!p.trim()){Wr(`Войдите, чтобы загрузить личный кабинет.`);return}Hr(!0),Wr(``),Kr(``);try{await ka();let[e,t]=await Promise.all([q.listOrganizations(),q.listResources()]);gr(e),br(t),!Lr&&e[0]?.id&&Rr(e[0].id);let n=await Promise.all(e.map(async e=>[e.id,await q.listOrganizationMemberships(e.id)]));Sr(Object.fromEntries(n)),Pr(new Date().toISOString())}catch(e){Wr(e instanceof Error?e.message:`Не удалось загрузить личный кабинет.`)}finally{Hr(!1)}}async function Ra(e){if(!p.trim())return;let[t,n,r,i,a]=await Promise.all([q.listClusterSummaries(),q.listNodes(e),q.listOrganizations(),q.listUsers(),q.listResources()]);k(t),gr(r),vr(i),br(a),je(t=>({...t,[e]:n})),await za(e,{preserveEditableForms:!0}),Pr(new Date().toISOString())}async function za(e,t={}){let n=++pa.current,r=Tn?20:10,i=Tn?En.offset:0,a={reporterNodeId:En.reporterNodeId||void 0,routeId:En.routeId||void 0,serviceClass:En.serviceClass||void 0,generation:En.generation||void 0,feedbackSource:En.feedbackSource||void 0,feedbackChannelId:En.feedbackChannelId||void 0,feedbackViolationStatus:En.feedbackViolationStatus||void 0,limit:r,offset:i,enrichment:Tn?`deep`:`summary`},[o,s,c,l,u,d,f,p,m,h,g,_,v,y,b,x,S,C,w,T,ee,te,E,ne,re,ie]=await Promise.all([q.listNodes(e),q.listNodeGroups(e),q.listJoinRequests(e),q.listJoinTokens(e),q.listReleaseVersions(e,`rap-node-agent`,`dev`),q.getStaleNodeRiskReport(e),q.getClusterAuthority(e),q.listAudit(e),q.getFabricServiceChannelRebuildInvestigationBreadcrumbs(e,{limit:20}),q.listMeshLinks(e),q.listRouteIntents(e),q.listFabricServiceChannelRouteFeedback(e,{includeExpired:!0}),q.listFabricServiceChannelRouteRebuildAttempts(e,a),q.getFabricServiceChannelRouteRebuildHealthSummary(e,{limit:5}),q.listFabricServiceChannelRouteRebuildAlertSilences(e),q.getFabricServiceChannelReadiness(e,{limit:5}),q.getFabricServiceChannelSchemaStatus(e),q.getFabricServiceChannelRebuildSnapshotMaintenanceHealth(e,{limit:50,minAgeSeconds:60,heartbeatThreshold:2}),q.getFabricServiceChannelLeaseMaintenance(e,{limit:20,includeExpired:!0}),q.getFabricServiceChannelAccessTelemetry(e,{limit:20}),q.listFabricServiceChannelRouteRebuildIncidents(e,{limit:5}),q.getFabricServiceChannelRecoveryPolicy(e),q.getFabricServiceChannelBreadcrumbWindowPolicy(e),q.listQoSPolicies(e),q.listVPNConnections(e),q.listFabricTestingFlags()]);if(n!==pa.current)return;De(o),ke(s),Ne(c),Fe(l),Le(u),Re(d),xe(f),t.preserveEditableForms||oi({authorityState:f.authority_state,mutationMode:f.mutation_mode,notes:f.notes||``}),wr(p),Ar(m.events),Mr(m.summary||null),Ct(h),wt(g),Ft(_),qt(v),Xt(y),en(b),fn(x),mn(S),_n(C),xn(w),Sn(T),wn(ee),Mn(te),Ln(E),t.preserveEditableForms||ni({currentWindowSeconds:String(E.current_window_seconds||1800),historyWindowSeconds:String(E.history_window_seconds||86400)}),ei({hysteresisPenalty:String(te.hysteresis_penalty),promotionMinSamples:String(te.promotion_min_samples),demotionFailureThreshold:String(te.demotion_failure_threshold),demotionDropThreshold:String(te.demotion_drop_threshold),demotionSlowThreshold:String(te.demotion_slow_threshold),demotionRebuildEnabled:te.demotion_rebuild_enabled,demotionFencedEnabled:te.demotion_fenced_enabled}),zn(ne),Un(re),Vn(ie);let ae=await q.listVPNClientDiagnosticStatuses(e);if(n!==pa.current)return;cr(ae);let oe=ae.find(e=>e.device_id===ar.trim())||ae[0]||null;ur(oe),!ar.trim()&&oe&&(or(oe.device_id),localStorage.setItem(D.vpnDiagnosticDeviceId,oe.device_id));let se=await Promise.all(o.map(async t=>[t.id,await q.listNodeRoles(e,t.id)]));if(n!==pa.current)return;Ye(Object.fromEntries(se));let O=await Promise.all(o.map(async t=>[t.id,await q.listDesiredWorkloads(e,t.id)]));if(n!==pa.current)return;Ze(Object.fromEntries(O));let k=await Promise.all(o.map(async t=>[t.id,await q.listWorkloadStatuses(e,t.id)]));if(n!==pa.current)return;ot(Object.fromEntries(k));let ce=await Promise.all(o.map(async t=>[t.id,await q.listNodeHeartbeats(e,t.id,60)]));if(n!==pa.current)return;ct(Object.fromEntries(ce));let le=d.nodes.filter(e=>e.recovery_bridge_replay_ready).map(e=>e.node_id);if(le.length>0){let t=await Promise.all(le.map(async t=>[t,await q.getNodeBridgeReplayPlan(e,t)]));if(n!==pa.current)return;Ue(Object.fromEntries(t))}else Ue({});let ue=await Promise.all(o.map(async t=>[t.id,await q.getNodeUpdatePlan(e,t.id,{currentVersion:t.reported_version})]));if(n!==pa.current)return;Ge(Object.fromEntries(ue));let de=await Promise.all(o.map(async t=>[t.id,await q.listNodeUpdateStatuses(e,t.id,80)]));if(n!==pa.current)return;qe(Object.fromEntries(de));let fe=await Promise.all(o.map(async t=>[t.id,await q.listNodeTelemetry(e,t.id,120)]));if(n!==pa.current)return;_t(Object.fromEntries(fe));let pe=await Promise.all(o.map(async t=>[t.id,await q.getNodeSyntheticMeshConfig(e,t.id)]));if(n!==pa.current)return;Et(Object.fromEntries(pe));let me=await Promise.all(re.map(async t=>[t.id,await q.getActiveVPNLease(e,t.id)]));if(n!==pa.current)return;Kn(Object.fromEntries(me));let he=await Promise.all(re.map(async t=>[t.id,await q.getVPNPacketStats(e,t.id)]));n===pa.current&&$n(Object.fromEntries(he))}async function Ba(e=Tn,t=En){if(T){Hr(!0),Wr(``),Kr(``);try{let n=await q.listFabricServiceChannelRouteRebuildAttempts(T,{reporterNodeId:t.reporterNodeId||void 0,routeId:t.routeId||void 0,serviceClass:t.serviceClass||void 0,generation:t.generation||void 0,feedbackSource:t.feedbackSource||void 0,feedbackChannelId:t.feedbackChannelId||void 0,feedbackViolationStatus:t.feedbackViolationStatus||void 0,limit:e?20:10,offset:e?t.offset:0,enrichment:e?`deep`:`summary`});z(e),Dn(t),qt(n),Kr(e?`Deep rebuild ledger loaded.`:`Fast rebuild ledger loaded.`)}catch(e){Wr(e instanceof Error?e.message:`Не удалось загрузить rebuild ledger.`)}finally{Hr(!1)}}}async function Va(){if(!T)return;let[e,t,n,r,i,a,o,s,c,l]=await Promise.all([q.getFabricServiceChannelRouteRebuildHealthSummary(T,{limit:5}),q.listFabricServiceChannelRouteRebuildAlertSilences(T),q.getFabricServiceChannelReadiness(T,{limit:5}),q.getFabricServiceChannelSchemaStatus(T),q.getFabricServiceChannelRebuildSnapshotMaintenanceHealth(T,{limit:50,minAgeSeconds:60,heartbeatThreshold:2}),q.getFabricServiceChannelLeaseMaintenance(T,{limit:20,includeExpired:!0}),q.getFabricServiceChannelAccessTelemetry(T,{limit:20}),q.listFabricServiceChannelRouteRebuildIncidents(T,{limit:5}),q.getFabricServiceChannelRebuildInvestigationBreadcrumbs(T,{limit:20}),q.getFabricServiceChannelBreadcrumbWindowPolicy(T)]);Xt(e),en(t),fn(n),mn(r),_n(i),xn(a),Sn(o),wn(s),Ar(c.events),Mr(c.summary||null),Ln(l),ni({currentWindowSeconds:String(l.current_window_seconds||1800),historyWindowSeconds:String(l.history_window_seconds||86400)})}async function Ha(){if(T)try{Hr(!0);let e=await q.warmupFabricServiceChannelRebuildSnapshots(T,{limit:10,staleAfterSeconds:60});yn(e),await Va(),Kr(`Snapshot warmup: warmed ${e.warmed_count}, fresh ${e.already_fresh_count}, errors ${e.error_count}.`)}catch(e){Wr(e instanceof Error?e.message:`Не удалось прогреть rebuild snapshots.`)}finally{Hr(!1)}}async function Ua(){if(T)try{Hr(!0);let e=await q.cleanupFabricServiceChannelLeases(T,{limit:100});xn(e),Kr(`Service-channel lease cleanup: deleted ${e.deleted_expired_count||0}, active ${e.active_count}, expired ${e.expired_count}.`)}catch(e){Wr(e instanceof Error?e.message:`Не удалось очистить service-channel leases.`)}finally{Hr(!1)}}async function Wa(e){let t={reporterNodeId:e.reporter_node_id,routeId:e.route_id,serviceClass:e.service_class,generation:e.generation||``,feedbackSource:``,feedbackChannelId:e.channel_id||``,feedbackViolationStatus:``,offset:0};await q.recordFabricServiceChannelRouteRebuildInvestigation(T,{reporterNodeId:e.reporter_node_id,routeId:e.route_id,serviceClass:e.service_class,generation:e.generation||``,guardStatus:e.guard_status,incidentId:e.fingerprint});let n=await q.getFabricServiceChannelRebuildInvestigationBreadcrumbs(T,{limit:20});Ar(n.events),Mr(n.summary||null),Dn(t),await Ba(!0,t)}function Ga(e){let t=new Set(e.affected_reporter_node_ids||[]),n=new Set(e.affected_route_ids||[]);return Cn.filter(r=>{let i=!e.feedback_channel_id||r.channel_id===e.feedback_channel_id,a=t.size===0||t.has(r.reporter_node_id),o=n.size===0||n.has(r.route_id);return i&&a&&o})}function Ka(e){let t=F(e.payload)||{},n=I(t,`feedback_source`,``),r=I(t,`feedback_channel_id`,``),i=I(t,`feedback_violation_status`,``),a=I(t,`reporter_node_id`,``),o=I(t,`route_id`,``);return!n&&!r&&!i?null:(Jt?.feedback_breakdowns||[]).find(e=>!(n&&e.feedback_source!==n||r&&e.feedback_channel_id!==r||i&&e.feedback_violation_status!==i||a&&!(e.affected_reporter_node_ids||[]).includes(a)||o&&!(e.affected_route_ids||[]).includes(o)))||null}function qa(e){let t=F(e.payload)||{},n=I(t,`reporter_node_id`,``),r=I(t,`route_id`,e.target_type===`fabric_service_channel_route_rebuild_incident`&&e.target_id||``),i=I(t,`service_class`,``),a=I(t,`generation`,``),o=I(t,`guard_status`,``);return Cn.find(e=>n&&e.reporter_node_id!==n||r&&e.route_id!==r||i&&e.service_class!==i||a&&e.generation!==a||o&&e.guard_status!==o?!1:!!(n||r||i||a||o))||null}async function Ja(e){let t={...ie,feedbackSource:e.feedback_source||``,feedbackChannelId:e.feedback_channel_id||``,feedbackViolationStatus:e.feedback_violation_status||``,offset:0};await q.recordFabricServiceChannelRouteRebuildInvestigation(T,{reporterNodeId:(e.affected_reporter_node_ids||[])[0]||``,routeId:(e.affected_route_ids||[])[0]||``,feedbackSource:e.feedback_source||``,feedbackChannelId:e.feedback_channel_id||``,feedbackViolationStatus:e.feedback_violation_status||``,drilldownSource:`rebuild_health_feedback_breakdown`,reason:`operator opened rebuild-health feedback breakdown ledger`});let n=await q.getFabricServiceChannelRebuildInvestigationBreadcrumbs(T,{limit:20});Ar(n.events),Mr(n.summary||null),w(`fabric`),Dn(t),await Ba(!0,t)}async function Ya(e){await q.silenceFabricServiceChannelRouteRebuildAlert(T,{incidentSource:e.incident_source||``,channelId:e.channel_id||``,reporterNodeId:e.reporter_node_id,routeId:e.route_id,guardStatus:e.guard_status||`unknown`,generation:e.generation||``,reason:`operator acknowledged rebuild incident`,ttlSeconds:21600}),await Va()}async function Xa(e){await q.unsilenceFabricServiceChannelRouteRebuildAlert(T,e.id,`operator removed rebuild alert silence`),await Va()}function Za(){De([]),ke([]),Ne([]),Fe([]),Le([]),Re(null),Ue({}),Ge({}),xe(null),Ye({}),Ze({}),ot({}),ct({}),qe({}),_t({}),Ct([]),wt([]),Et({}),Ft([]),qt([]),Xt(null),en([]),fn(null),mn(null),yn(null),wn([]),z(!1),Dn(ie),zn([]),Vn([]),Un([]),Kn({}),$n({}),cr([]),ur(null),gr([]),vr([]),br([]),Sr({}),wr([]),Ar([]),Mr(null)}async function Y(e,t){Hr(!0),Wr(``),Kr(``);try{await e(),Kr(t),await Ia()}catch(e){Wr(e instanceof Error?e.message:`Действие не выполнено.`)}finally{Hr(!1)}}async function Qa(){if(!T||!M||M.summary.blocked_nodes<1){$i(`Guard smoke сейчас недоступен: в отчете нет blocker-узлов для controlled blocked-check.`),ta(new Date().toISOString());return}Hr(!0),Wr(``),Kr(``),$i(``);try{let e=`0.2.402-guard-smoke-${Date.now()}`;await q.createReleaseVersion(T,{product:`rap-node-agent`,version:e,channel:`stable`,status:`active`,compatibility:{legacy_removal:!0},changelog:`UI smoke check for legacy removal guard`,artifacts:[{os:`linux`,arch:`amd64`,installType:`docker`,kind:`image`,url:`https://example.test/rap-node-agent.tar`,sha256:`sha256-guard-smoke`,sizeBytes:123,metadata:{}}]}),$i(`Smoke unexpectedly succeeded. Guard should have blocked breaking release creation while stale recovery-risk nodes remain.`)}catch(e){$i(e instanceof Error?e.message:`Guard smoke failed with a non-Error response.`)}finally{ta(new Date().toISOString()),Hr(!1)}}async function $a(){if(!T){ur(null);return}let e=await q.listVPNClientDiagnosticStatuses(T);cr(e);let t=ar.trim()||e[0]?.device_id||``;t&&(localStorage.setItem(D.vpnDiagnosticDeviceId,t),or(t));let n=e.find(e=>e.device_id===t)||(t?await q.getVPNClientDiagnosticStatus(T,t):null);ur(n),Kr(n?`Диагностика VPN-клиента обновлена.`:`Диагностика VPN-клиента не найдена.`)}async function eo(e,t){if(!T){Wr(`Выбери кластер перед отправкой команды.`);return}let n=ar.trim();if(!n){Wr(`Укажи Android device id или выбери найденный клиент.`);return}Hr(!0),Wr(``),Kr(``);try{mr(await q.enqueueVPNClientDiagnosticCommand(T,n,e)),Kr(`${t}: команда поставлена в очередь. Клиент заберет ее через диагностический канал.`),window.setTimeout(()=>{$a()},3500)}catch(e){Wr(e instanceof Error?e.message:`Команда VPN-клиенту не отправлена.`)}finally{Hr(!1)}}async function to(){Hr(!0),Wr(``),Kr(``);try{let e=fe(await fa.login({email:h.email,password:h.password,deviceLabel:h.deviceLabel,trustDevice:h.trustDevice}));if(!e.userId||!e.authSessionId)throw Error(`Ответ входа не содержит пользователя или сессию.`);let t=new y({baseUrl:i,actorUserId:e.userId}),n=`admin`;try{await t.listClusterSummaries(),n=`admin`}catch{try{let[e,r]=await Promise.all([t.listOrganizations(),t.listResources()]);gr(e),br(r),e[0]?.id&&Rr(e[0].id);let i=await Promise.all(e.map(async e=>[e.id,await t.listOrganizationMemberships(e.id)]));Sr(Object.fromEntries(i)),n=`user`}catch{try{await fa.revokeAuthSession({userId:e.userId,authSessionId:e.authSessionId,reason:`user_portal_access_denied`})}catch{}throw Error(J.accessDenied)}}r(h.rememberMe),Oa(e,h.rememberMe),o(e),m(e.userId),g(t=>({...t,email:e.email,password:``})),u(new Date().toISOString()),c(n),Kr(`${J.signedInAs}: ${e.email}`)}catch(e){Wr(e instanceof Error?e.message:`Вход не выполнен.`)}finally{Hr(!1)}}async function no(){Hr(!0),Wr(``),Kr(``);try{let e;if(v?.strict_authority){if(!x.activationPayload.trim()||!x.activationSignature.trim())throw Error(J.bootstrapText);e=JSON.parse(x.activationPayload)}b((await fa.bootstrapOwner({email:x.email,password:x.password,activationPayload:e,activationSignature:x.activationSignature})).installation),g({...h,email:x.email,password:x.password}),Kr(J.ownerCreated)}catch(e){Wr(e instanceof Error?e.message:`Создание владельца не выполнено.`)}finally{Hr(!1)}}async function X(){let e=a;if(o(null),r(!1),u(``),Oa(null),c(null),m(``),oe([]),k([]),Za(),je({}),ee(``),e?.userId&&e.authSessionId)try{await fa.revokeAuthSession({userId:e.userId,authSessionId:e.authSessionId,reason:`platform_owner_console_logout`})}catch{}}async function ro(e){ee(e),Za(),Hr(!0),Wr(``),Kr(``);try{await za(e)}catch(e){Wr(e instanceof Error?e.message:`Не удалось загрузить кластер.`)}finally{Hr(!1)}}let io=Me.filter(e=>e.status===`pending`).length,ao=j.filter(e=>e.health_status===`healthy`).length,oo=j.filter(e=>e.health_status!==`healthy`||e.membership_status!==`active`).length,so=Object.values(Je).flat().filter(e=>e.status===`active`).length,co=Bn.find(e=>e.scope_type===`platform`&&!e.scope_id)||null;Bn.find(e=>e.scope_type===`organization`&&e.scope_id===Fi&&(!e.cluster_id||e.cluster_id===T));let lo=Object.values(Tt),uo=lo.filter(e=>e.enabled).length,fo=lo.reduce((e,t)=>e+t.routes.length,0),po=lo.reduce((e,t)=>e+Object.keys(t.peer_endpoints||{}).length,0),mo=lo.reduce((e,t)=>e+Lt(t),0);lo.reduce((e,t)=>e+(t.peer_directory?.length??0),0),lo.reduce((e,t)=>e+(t.recovery_seeds?.length??0),0);let ho=lo.filter(e=>e.production_forwarding).length,go=Be(j,st),_o=P.filter(e=>pt(e)===`active`),vo=P.filter(e=>pt(e)===`expired`),yo=P.filter(e=>pt(e)===`disabled`),bo=Pt.filter(e=>{let t=Date.parse(e.expires_at||``),n=Date.parse(e.retry_cooldown_until||``);return Number.isFinite(t)&&t>Date.now()||Number.isFinite(n)&&n>Date.now()}),xo=bo.filter(e=>e.feedback_status===`fenced`),So=bo.filter(e=>e.feedback_status===`degraded`),Co=bo.filter(e=>e.feedback_status===`healthy`),wo=bo.filter(e=>e.recovery_state===`recovered`||e.recovery_hysteresis_active),To=bo.filter(e=>e.recovery_promoted),Eo=bo.filter(e=>e.recovery_demoted),Do=bo.filter(e=>e.feedback_status===`operator_retry_cooldown`||e.retry_cooldown_until),Oo=lo.flatMap(e=>e.route_path_decisions?.decisions||[]),ko=Oo.filter(e=>e.decision_source===`service_channel_feedback_no_alternate`),Ao=Oo.filter(e=>e.decision_source===`service_channel_feedback_replacement`),jo=Oo.filter(e=>e.rebuild_status),Mo=jo.filter(e=>e.rebuild_status===`applied`),No=It.filter(e=>e.rebuild_status===`applied`),Po=It.filter(e=>e.rebuild_status&&e.rebuild_status!==`applied`),Fo=It.filter(e=>e.guard_severity===`bad`),Io=Oo.filter(e=>(e.score_reasons||[]).includes(`service_channel_recovery_hysteresis`)),Lo=Oo.filter(e=>(e.score_reasons||[]).includes(`service_channel_recovery_promoted`)),Ro=Oo.filter(e=>(e.score_reasons||[]).includes(`service_channel_recovery_demoted`)),zo=v?.bootstrapped===!1,Bo=zo&&!v?.strict_authority&&!v?.insecure_bootstrap_allowed,Vo=s===`admin`?J.sessionModeAdmin:J.sessionModeUser;if(!a)return(0,E.jsxs)(`main`,{className:`loginShell`,children:[v&&(0,E.jsxs)(`section`,{className:`loginCard`,children:[(0,E.jsx)(`h1`,{children:v.bootstrapped?J.installationLocked:J.bootstrapTitle}),(0,E.jsx)(A,{label:`Authority`,value:`${v.authority_mode}/${v.authority_state}`}),(0,E.jsx)(A,{label:`Strict`,value:v.strict_authority?`enabled`:`legacy`}),v.root_fingerprint&&(0,E.jsx)(A,{label:`Root key`,value:B(v.root_fingerprint)})]}),zo?(0,E.jsxs)(`section`,{className:`loginCard`,children:[(0,E.jsx)(`h1`,{children:J.bootstrapTitle}),(0,E.jsx)(`p`,{className:`loginHint`,children:Bo?J.insecureBootstrapDisabled:J.bootstrapText}),(0,E.jsxs)(`label`,{children:[J.email,(0,E.jsx)(`input`,{value:x.email,onChange:e=>S({...x,email:e.target.value}),autoComplete:`username`})]}),(0,E.jsxs)(`label`,{children:[J.password,(0,E.jsx)(`input`,{value:x.password,onChange:e=>S({...x,password:e.target.value}),type:`password`,autoComplete:`new-password`})]}),v?.strict_authority&&(0,E.jsxs)(E.Fragment,{children:[(0,E.jsxs)(`label`,{children:[J.activationPayload,(0,E.jsx)(`textarea`,{value:x.activationPayload,onChange:e=>S({...x,activationPayload:e.target.value}),spellCheck:!1})]}),(0,E.jsxs)(`label`,{children:[J.activationSignature,(0,E.jsx)(`input`,{value:x.activationSignature,onChange:e=>S({...x,activationSignature:e.target.value}),spellCheck:!1})]})]}),Ur&&(0,E.jsx)(`div`,{className:`errorPanel`,children:Ur}),Gr&&(0,E.jsx)(`div`,{className:`noticePanel`,children:Gr}),(0,E.jsx)(`button`,{className:`primary wide`,onClick:()=>void no(),disabled:Vr||Bo||!x.email||x.password.length<12||v?.strict_authority&&(!x.activationPayload||!x.activationSignature),children:Vr?J.creatingOwner:J.createOwner})]}):(0,E.jsxs)(`section`,{className:`loginCard`,children:[(0,E.jsx)(`h1`,{children:J.signInTitle}),(0,E.jsxs)(`label`,{children:[J.email,(0,E.jsx)(`input`,{value:h.email,onChange:e=>g({...h,email:e.target.value.trim()}),autoComplete:`username`,autoCapitalize:`none`,autoCorrect:`off`,spellCheck:!1})]}),(0,E.jsxs)(`label`,{children:[J.password,(0,E.jsx)(`input`,{value:h.password,onChange:e=>g({...h,password:e.target.value}),type:h.showPassword?`text`:`password`,autoComplete:`current-password`,autoCapitalize:`none`,autoCorrect:`off`,spellCheck:!1,onKeyDown:e=>{e.key===`Enter`&&to()}})]}),(0,E.jsxs)(`label`,{className:`checkLine`,children:[(0,E.jsx)(`input`,{type:`checkbox`,checked:h.showPassword,onChange:e=>g({...h,showPassword:e.target.checked})}),`Показать пароль`]}),(0,E.jsxs)(`label`,{className:`checkLine`,children:[(0,E.jsx)(`input`,{type:`checkbox`,checked:h.trustDevice,onChange:e=>g({...h,trustDevice:e.target.checked})}),J.trustDevice]}),(0,E.jsxs)(`label`,{className:`checkLine`,children:[(0,E.jsx)(`input`,{type:`checkbox`,checked:h.rememberMe,onChange:e=>g({...h,rememberMe:e.target.checked})}),J.rememberMe]}),Ur&&(0,E.jsx)(`div`,{className:`errorPanel`,children:Ur}),Gr&&(0,E.jsx)(`div`,{className:`noticePanel`,children:Gr}),(0,E.jsx)(`button`,{className:`primary wide`,onClick:()=>void to(),disabled:Vr||!h.email||!h.password,children:Vr?J.signingIn:J.signIn})]})]});if(a&&!s)return(0,E.jsx)(`main`,{className:`loginShell`,children:(0,E.jsx)(`section`,{className:`loginCard`,children:(0,E.jsx)(`p`,{children:Vr?J.lastRefresh:`Восстанавливаем сессию...`})})});if(s===`user`){let e=hr.find(e=>e.id===Lr)||hr[0]||null,t=e?yr.filter(t=>t.organization_id===e.id):yr,n=e?(xr[e.id]||[]).find(e=>e.user_id===a.userId):null,r=t.reduce((e,t)=>(e[t.protocol]=(e[t.protocol]||0)+1,e),{});return(0,E.jsxs)(`main`,{className:`portalShell`,children:[(0,E.jsxs)(`aside`,{className:`portalRail`,children:[(0,E.jsx)(`div`,{className:`brandMark`,children:`RAP`}),(0,E.jsx)(`p`,{className:`sideKicker`,children:`Личный кабинет`}),(0,E.jsx)(`h1`,{children:`Мой доступ`}),(0,E.jsx)(`p`,{className:`sideText`,children:`Установки, доступные серверы и состояние рабочей области пользователя.`}),(0,E.jsx)(A,{label:J.sessionMode,value:`${Vo} • ${l?Qn(l):`н/д`}`}),(0,E.jsx)(A,{label:J.actorUser,value:a.email}),(0,E.jsx)(`button`,{className:`ghost`,onClick:()=>void X(),disabled:Vr,children:J.logout})]}),(0,E.jsxs)(`section`,{className:`portalWorkspace`,children:[(0,E.jsxs)(`header`,{className:`portalTop`,children:[(0,E.jsxs)(`div`,{children:[(0,E.jsx)(`p`,{className:`eyebrow`,children:`Secure Access Fabric`}),(0,E.jsx)(`h2`,{children:e?.name||`Личный кабинет`}),(0,E.jsx)(`p`,{className:`muted`,children:a.email})]}),(0,E.jsxs)(`label`,{children:[`Организация`,(0,E.jsx)(`select`,{value:e?.id||``,onChange:e=>Rr(e.target.value),children:hr.map(e=>(0,E.jsx)(`option`,{value:e.id,children:e.name},e.id))})]}),(0,E.jsx)(`button`,{className:`primary`,onClick:()=>void La(),disabled:Vr,children:Vr?J.refreshing:J.refresh})]}),Ur&&(0,E.jsx)(`div`,{className:`errorPanel`,children:Ur}),Gr&&(0,E.jsx)(`div`,{className:`noticePanel`,children:Gr}),(0,E.jsxs)(`section`,{className:`grid three`,children:[(0,E.jsx)(he,{label:`Организации`,value:hr.length,tone:`steel`}),(0,E.jsx)(he,{label:`Серверы`,value:t.length,tone:`green`}),(0,E.jsx)(he,{label:`Установки`,value:2,tone:`amber`})]}),(0,E.jsxs)(`section`,{className:`grid two`,children:[(0,E.jsxs)(`article`,{className:`card`,children:[(0,E.jsxs)(`div`,{className:`cardHead`,children:[(0,E.jsxs)(`div`,{children:[(0,E.jsx)(`h3`,{children:`Установки`}),(0,E.jsx)(`p`,{className:`muted`,children:ra?`Актуальная версия Android: ${ra}`:`Скачивайте актуальные клиенты только отсюда, чтобы не ловить старую сборку.`})]}),(0,E.jsx)(`span`,{className:`status active`,children:`latest`})]}),(0,E.jsxs)(`div`,{className:`portalInstallList`,children:[(0,E.jsxs)(`a`,{className:`installTile primaryInstall`,href:Sa,children:[(0,E.jsx)(`strong`,{children:`Android VPN`}),(0,E.jsx)(`span`,{children:`Последняя сборка RAP HOME VPN для телефона`}),(0,E.jsx)(`small`,{children:sa||xa})]}),(0,E.jsxs)(`a`,{className:`installTile`,href:`${_a}/downloads/rap-windows-rdp-client-latest-win-x64.zip`,children:[(0,E.jsx)(`strong`,{children:`Windows RDP клиент`}),(0,E.jsx)(`span`,{children:`Клиент удаленного рабочего стола, когда нужен доступ к серверам`}),(0,E.jsx)(`small`,{children:`latest win-x64`})]})]})]}),(0,E.jsxs)(`article`,{className:`card`,children:[(0,E.jsx)(`h3`,{children:`Профиль`}),(0,E.jsx)(A,{label:`Пользователь`,value:a.email}),(0,E.jsx)(A,{label:`Роль в организации`,value:n?.role_id||`участник`}),(0,E.jsx)(A,{label:`Организация`,value:e?.name||`нет`}),(0,E.jsx)(A,{label:`Последнее обновление`,value:Nr?V(Nr):`нет`})]}),(0,E.jsxs)(`article`,{className:`card span2`,children:[(0,E.jsx)(`div`,{className:`cardHead`,children:(0,E.jsxs)(`div`,{children:[(0,E.jsx)(`h3`,{children:`Доступные серверы`}),(0,E.jsx)(`p`,{className:`muted`,children:`Список ресурсов, которые уже разрешены пользователю через организацию.`})]})}),(0,E.jsx)(N,{columns:[`имя`,`адрес`,`протокол`,`секрет`,`передача файлов`],rows:t.map(e=>[e.name,e.address,e.protocol,e.has_secret?`настроен`:`нет`,H(e.file_transfer_mode||`disabled`)])})]}),(0,E.jsxs)(`article`,{className:`card`,children:[(0,E.jsx)(`h3`,{children:`Сервисы`}),(0,E.jsx)(N,{columns:[`тип`,`количество`],rows:Object.entries(r).map(([e,t])=>[e,String(t)])})]}),(0,E.jsxs)(`article`,{className:`card`,children:[(0,E.jsx)(`h3`,{children:`Что здесь будет дальше`}),(0,E.jsxs)(`div`,{className:`portalRoadmap`,children:[(0,E.jsx)(`span`,{children:`Устройства и доверенные входы`}),(0,E.jsx)(`span`,{children:`Активные VPN-сессии`}),(0,E.jsx)(`span`,{children:`Обновление профиля VPN без ручных ключей`}),(0,E.jsx)(`span`,{children:`Самостоятельная смена пароля`})]})]})]})]})]})}return(0,E.jsxs)(`main`,{className:`consoleShell`,children:[(0,E.jsxs)(`aside`,{className:`sideRail`,children:[(0,E.jsx)(`div`,{className:`brandMark`,children:`SAF`}),(0,E.jsx)(`p`,{className:`sideKicker`,children:J.productOwner}),(0,E.jsx)(`h1`,{children:J.controlPlane}),(0,E.jsx)(`p`,{className:`sideText`,children:J.sideText}),(0,E.jsx)(`nav`,{className:`railNav`,children:O.filter(e=>e.id!==`roles`).map(e=>(0,E.jsx)(`button`,{className:C===e.id?`active`:``,onClick:()=>w(e.id),children:e[d]},e.id))})]}),(0,E.jsxs)(`section`,{className:`workspace`,children:[(0,E.jsxs)(`header`,{className:`topBar`,children:[(0,E.jsxs)(`div`,{children:[(0,E.jsx)(`p`,{className:`eyebrow`,children:`Secure Access Fabric`}),(0,E.jsx)(`h2`,{children:ha?ha.name:J.consoleTitle}),(0,E.jsx)(`p`,{className:`muted`,children:J.boundary})]}),(0,E.jsxs)(`div`,{className:`clusterPicker`,children:[(0,E.jsxs)(`label`,{children:[J.activeCluster,(0,E.jsx)(`select`,{value:T,onChange:e=>void ro(e.target.value),children:te.map(e=>(0,E.jsx)(`option`,{value:e.id,children:e.name},e.id))})]}),(0,E.jsxs)(`span`,{children:[J.slugLabel,`: `,ha?.slug||`н/д`]})]}),(0,E.jsx)(`button`,{className:`primary`,onClick:()=>void Ia(),disabled:Vr,children:Vr?J.refreshing:J.refresh}),(0,E.jsxs)(`div`,{className:`refreshStatus`,children:[(0,E.jsx)(`strong`,{children:J.autoRefresh}),(0,E.jsx)(`span`,{children:Nr?`${J.lastRefresh}: ${Qn(Nr)} / ${Fr.toUpperCase()}`:Fr.toUpperCase()})]}),(0,E.jsxs)(`div`,{className:`profilePanel`,children:[(0,E.jsx)(`strong`,{children:J.profile}),(0,E.jsx)(`span`,{children:a.email}),(0,E.jsxs)(`span`,{children:[J.sessionMode,`: `,Vo,` | `,J.sessionRefreshedAt,`: `,l?Qn(l):`н/д`]}),(0,E.jsxs)(`label`,{children:[J.language,(0,E.jsxs)(`select`,{value:d,onChange:e=>f(e.target.value),children:[(0,E.jsx)(`option`,{value:`ru`,children:`Русский`}),(0,E.jsx)(`option`,{value:`en`,children:d===`ru`?`Английский`:`English`})]})]}),(0,E.jsx)(`button`,{className:`ghost`,onClick:()=>void X(),disabled:Vr,children:J.logout})]})]}),Ur&&(0,E.jsx)(`div`,{className:`errorPanel`,children:Ur}),Gr&&(0,E.jsx)(`div`,{className:`noticePanel`,children:Gr}),ha&&j.length===0&&(0,E.jsxs)(`div`,{className:`noticePanel`,children:[(0,E.jsxs)(`strong`,{children:[J.emptyLiveTitle,`.`]}),` `,J.emptyLiveText]}),C===`command`&&(0,E.jsxs)(`section`,{className:`grid five`,children:[(0,E.jsx)(he,{label:`Кластеры`,value:te.length,tone:`steel`}),(0,E.jsx)(he,{label:`Узлы в области`,value:j.length,tone:`green`}),(0,E.jsx)(he,{label:`Здоровые узлы`,value:ao,tone:`green`}),(0,E.jsx)(he,{label:`Ожидают подключения`,value:io,tone:`amber`}),(0,E.jsx)(he,{label:`Рискованные состояния`,value:oo,tone:`red`}),(0,E.jsxs)(`article`,{className:`card span3`,children:[(0,E.jsx)(`h3`,{children:`Общее состояние кластеров`}),(0,E.jsx)(N,{columns:[`кластер`,`authority`,`ключ`,`режим изменений`,`узлы`,`заявки`,`роли`,`последний сигнал`],rows:se.map(e=>[e.name,e.authority_state,B(e.cluster_key_fingerprint),e.mutation_mode,`${e.healthy_node_count}/${e.node_count}`,String(e.pending_join_count),String(e.active_role_assignment_count),V(e.last_node_seen_at)])})]}),(0,E.jsxs)(`article`,{className:`card span2`,children:[(0,E.jsx)(`h3`,{children:`Authority выбранного кластера`}),me?(0,E.jsxs)(`div`,{className:`stateList`,children:[(0,E.jsx)(A,{label:`Authority`,value:me.authority_state}),(0,E.jsx)(A,{label:`Режим изменений`,value:me.mutation_mode}),(0,E.jsx)(A,{label:`Терм`,value:String(me.term)}),(0,E.jsx)(A,{label:`Cluster key`,value:B(ga?.cluster_key_fingerprint)}),(0,E.jsx)(A,{label:`Обновлено`,value:V(me.updated_at)})]}):(0,E.jsx)(ye,{title:`Нет состояния authority`,text:`Выберите кластер, чтобы загрузить состояние authority.`})]}),(0,E.jsxs)(`article`,{className:`card span2`,children:[(0,E.jsx)(`h3`,{children:`Граница платформы`}),(0,E.jsx)(`p`,{className:`muted`,children:`Эта панель предназначена для владельца продукта / владельца платформы. Панели организаций должны использовать безопасные проекции и не раскрывать mesh internals, peer cache, route cache, секреты или данные других tenants.`})]}),(0,E.jsxs)(`article`,{className:`card span3`,children:[(0,E.jsx)(`h3`,{children:`Текущие сигналы кластера`}),(0,E.jsxs)(`div`,{className:`signalStrip`,children:[(0,E.jsx)(ge,{label:`Активные роли`,value:String(so)}),(0,E.jsx)(ge,{label:`Отчеты сервисов`,value:String(Object.values(nt).filter(e=>e.length>0).length)}),(0,E.jsx)(ge,{label:`Наблюдения связей`,value:String(bt.length)}),(0,E.jsx)(ge,{label:`Synthetic configs`,value:`${uo}/${j.length}`})]})]})]}),C===`clusters`&&(0,E.jsxs)(`section`,{className:`grid two`,children:[(0,E.jsxs)(`article`,{className:`card span2`,children:[(0,E.jsxs)(`div`,{className:`cardHead`,children:[(0,E.jsxs)(`div`,{children:[(0,E.jsx)(`h3`,{children:J.clusterCatalog}),(0,E.jsx)(`p`,{className:`muted`,children:J.clusterCatalogText})]}),(0,E.jsx)(`span`,{className:`pill`,children:Gn(te.length,d)})]}),(0,E.jsxs)(`div`,{className:`clusterCatalog`,children:[te.map(e=>{let t=se.find(t=>t.cluster_id===e.id),n=e.id===T;return(0,E.jsxs)(`article`,{className:`clusterCard ${n?`selected`:``}`,children:[(0,E.jsxs)(`div`,{className:`clusterCardMain`,children:[(0,E.jsxs)(`div`,{children:[(0,E.jsx)(`p`,{className:`eyebrow`,children:e.region||`регион не задан`}),(0,E.jsx)(`h4`,{children:e.name}),(0,E.jsxs)(`p`,{className:`muted`,children:[J.slugLabel,`: `,(0,E.jsx)(`strong`,{children:e.slug})]})]}),(0,E.jsxs)(`div`,{className:`clusterCardActions`,children:[(0,E.jsx)(_e,{value:e.status}),n?(0,E.jsx)(`span`,{className:`pill good`,children:J.selected}):(0,E.jsx)(`button`,{onClick:()=>void ro(e.id),children:J.makeActive}),(0,E.jsx)(`button`,{className:`ghost`,onClick:()=>{ro(e.id),w(`cluster-settings`)},children:J.openSettings})]})]}),(0,E.jsxs)(`div`,{className:`signalStrip compact`,children:[(0,E.jsx)(ge,{label:`Узлы`,value:t?`${t.healthy_node_count}/${t.node_count}`:`н/д`}),(0,E.jsx)(ge,{label:`Заявки`,value:String(t?.pending_join_count??`н/д`)}),(0,E.jsx)(ge,{label:`Роли`,value:String(t?.active_role_assignment_count??`н/д`)}),(0,E.jsx)(ge,{label:`Последний сигнал`,value:V(t?.last_node_seen_at)})]}),(0,E.jsxs)(`details`,{children:[(0,E.jsx)(`summary`,{children:J.clusterDetails}),(0,E.jsxs)(`div`,{className:`stateList`,children:[(0,E.jsx)(A,{label:`ID`,value:e.id}),(0,E.jsx)(A,{label:J.slugLabel,value:e.slug}),(0,E.jsx)(A,{label:`Статус`,value:H(e.status)}),(0,E.jsx)(A,{label:`Authority`,value:t?`${t.authority_state}/${t.mutation_mode}`:`неизвестно`}),(0,E.jsx)(A,{label:`Создан`,value:V(e.created_at)}),(0,E.jsx)(A,{label:`Обновлен`,value:V(e.updated_at||e.created_at)})]})]})]},e.id)}),te.length===0&&(0,E.jsx)(ye,{title:`Кластеров нет`,text:`Создайте первый кластер, затем подключите стартовый node-agent.`})]})]}),(0,E.jsxs)(`article`,{className:`card`,children:[(0,E.jsx)(`h3`,{children:J.createCluster}),(0,E.jsxs)(Qe,{children:[(0,E.jsxs)(`label`,{children:[J.slugLabel,(0,E.jsx)(`input`,{value:qr.slug,onChange:e=>Jr({...qr,slug:e.target.value})})]}),(0,E.jsxs)(`label`,{children:[`Название`,(0,E.jsx)(`input`,{value:qr.name,onChange:e=>Jr({...qr,name:e.target.value})})]}),(0,E.jsxs)(`label`,{children:[`Регион`,(0,E.jsx)(`input`,{value:qr.region,onChange:e=>Jr({...qr,region:e.target.value})})]})]}),(0,E.jsx)(`p`,{className:`muted`,children:J.slugHelp}),(0,E.jsx)(`button`,{className:`primary`,disabled:!qr.slug||!qr.name,onClick:()=>void Y(async()=>{await q.createCluster({slug:qr.slug,name:qr.name,region:qr.region||null}),Jr({slug:``,name:``,region:``})},`Кластер создан.`),children:J.createCluster})]}),(0,E.jsxs)(`article`,{className:`card`,children:[(0,E.jsx)(`h3`,{children:`Что такое технический код?`}),(0,E.jsx)(`p`,{className:`muted`,children:J.slugHelp}),(0,E.jsx)(`p`,{className:`muted`,children:`Для человека основное поле — название. Для системы и операторов — технический код. Он нужен, чтобы сценарии, логи и будущие endpoint-адреса не зависели от переименования кластера.`})]})]}),C===`cluster-settings`&&(0,E.jsxs)(`section`,{className:`grid two`,children:[!ha&&(0,E.jsx)(ye,{title:`Кластер не выбран`,text:`Выберите активный кластер, чтобы открыть настройки.`}),ha&&(0,E.jsxs)(E.Fragment,{children:[(0,E.jsxs)(`article`,{className:`card`,children:[(0,E.jsx)(`h3`,{children:`Identity кластера`}),(0,E.jsx)(`p`,{className:`muted`,children:`Базовые параметры хранятся в PostgreSQL. Slug остается неизменяемым идентификатором для операторов и скриптов.`}),(0,E.jsxs)(Qe,{children:[(0,E.jsxs)(`label`,{children:[`ID`,(0,E.jsx)(`input`,{value:ha.id,readOnly:!0})]}),(0,E.jsxs)(`label`,{children:[`Slug`,(0,E.jsx)(`input`,{value:ha.slug,readOnly:!0})]}),(0,E.jsxs)(`label`,{children:[`Название`,(0,E.jsx)(`input`,{value:Yr.name,onChange:e=>Xr({...Yr,name:e.target.value})})]}),(0,E.jsxs)(`label`,{children:[`Статус`,(0,E.jsxs)(`select`,{value:Yr.status,onChange:e=>Xr({...Yr,status:e.target.value}),children:[(0,E.jsx)(`option`,{value:`active`,children:`active, работает`}),(0,E.jsx)(`option`,{value:`disabled`,children:`disabled, отключен`})]})]}),(0,E.jsxs)(`label`,{children:[`Регион`,(0,E.jsx)(`input`,{value:Yr.region,onChange:e=>Xr({...Yr,region:e.target.value}),placeholder:`например ru-msk-1`})]}),(0,E.jsxs)(`label`,{children:[`Обновлен`,(0,E.jsx)(`input`,{value:V(ha.updated_at||ha.created_at),readOnly:!0})]})]}),(0,E.jsxs)(`label`,{className:`wideLabel`,children:[`Metadata JSON`,(0,E.jsx)(`textarea`,{value:Yr.metadataJson,onChange:e=>Xr({...Yr,metadataJson:e.target.value}),rows:8,spellCheck:!1})]}),(0,E.jsx)(`button`,{className:`primary`,disabled:!Yr.name.trim(),onClick:()=>Jn(`Сохранить базовые настройки кластера`)&&void Y(async()=>{let e=$e(Yr.metadataJson||`{}`,`Metadata JSON`);await q.updateCluster(ha.id,{name:Yr.name,status:Yr.status,region:Yr.region||null,metadata:e})},`Настройки кластера сохранены.`),children:`Сохранить настройки кластера`})]}),(0,E.jsxs)(`article`,{className:`card`,children:[(0,E.jsx)(`h3`,{children:`Authority и режим изменений`}),(0,E.jsx)(`p`,{className:`muted`,children:`Эта секция защищает кластер от split-brain: minority/read-only сегменты не должны принимать изменения политик.`}),(0,E.jsxs)(`div`,{className:`stateGrid`,children:[(0,E.jsx)(A,{label:`Authority`,value:me?.authority_state||`неизвестно`}),(0,E.jsx)(A,{label:`Mutation mode`,value:me?.mutation_mode||`неизвестно`}),(0,E.jsx)(A,{label:`Term`,value:String(me?.term??`н/д`)}),(0,E.jsx)(A,{label:`Cluster key`,value:B(ga?.cluster_key_fingerprint)}),(0,E.jsx)(A,{label:`Последнее изменение`,value:V(me?.updated_at)})]}),(0,E.jsxs)(Qe,{children:[(0,E.jsxs)(`label`,{children:[`Состояние authority`,(0,E.jsxs)(`select`,{value:ai.authorityState,onChange:e=>oi({...ai,authorityState:e.target.value}),children:[(0,E.jsx)(`option`,{value:`authoritative`,children:`authoritative, основной`}),(0,E.jsx)(`option`,{value:`minority`,children:`minority, меньшинство`}),(0,E.jsx)(`option`,{value:`isolated`,children:`isolated, изолирован`}),(0,E.jsx)(`option`,{value:`recovery`,children:`recovery, восстановление`})]})]}),(0,E.jsxs)(`label`,{children:[`Режим изменений`,(0,E.jsxs)(`select`,{value:ai.mutationMode,onChange:e=>oi({...ai,mutationMode:e.target.value}),children:[(0,E.jsx)(`option`,{value:`normal`,children:`normal, обычный`}),(0,E.jsx)(`option`,{value:`read_only`,children:`read_only, только чтение`}),(0,E.jsx)(`option`,{value:`recovery_override`,children:`recovery_override, восстановление`})]})]}),(0,E.jsxs)(`label`,{children:[`Примечание`,(0,E.jsx)(`input`,{value:ai.notes,onChange:e=>oi({...ai,notes:e.target.value})})]})]}),(0,E.jsx)(`button`,{disabled:!T,onClick:()=>Jn(`Изменить authority state кластера`)&&void Y(()=>q.updateClusterAuthority(T,{authorityState:ai.authorityState,mutationMode:ai.mutationMode,notes:ai.notes}),`Authority кластера обновлен.`),children:`Обновить authority`})]}),(0,E.jsxs)(`article`,{className:`card`,children:[(0,E.jsx)(`h3`,{children:`Safety / quorum`}),(0,E.jsxs)(`div`,{className:`stateGrid`,children:[(0,E.jsx)(A,{label:`Узлы`,value:String(ga?.node_count??j.length)}),(0,E.jsx)(A,{label:`Healthy`,value:String(ga?.healthy_node_count??ao)}),(0,E.jsx)(A,{label:`Pending join`,value:String(ga?.pending_join_count??Me.filter(e=>e.status===`pending`).length)}),(0,E.jsx)(A,{label:`Последний узел`,value:V(ga?.last_node_seen_at)})]}),(0,E.jsx)(`p`,{className:`muted`,children:`Минимальный размер, quorum policy и split-brain rules пока не имеют отдельного runtime-переключателя. Сейчас защита выполняется через authority/mutation mode, explicit node approval и аудит.`})]}),(0,E.jsxs)(`article`,{className:`card`,children:[(0,E.jsx)(`h3`,{children:`Telemetry / testing`}),(0,E.jsxs)(`div`,{className:`stateGrid`,children:[(0,E.jsx)(A,{label:`Telemetry flag`,value:co?.telemetry_enabled?`включен`:`выключен`}),(0,E.jsx)(A,{label:`Synthetic links`,value:co?.synthetic_links_enabled?`включены`:`выключены`}),(0,E.jsx)(A,{label:`Хранение истории, часов`,value:String(co?.history_retention_hours??`н/д`)})]}),(0,E.jsx)(`p`,{className:`muted`,children:`Это тестовый контур наблюдаемости: heartbeat/telemetry реальные, а связи Fabric сейчас synthetic. Production mesh traffic здесь пока не отображается.`})]}),(0,E.jsxs)(`article`,{className:`card`,children:[(0,E.jsx)(`h3`,{children:`Storage / updates`}),(0,E.jsxs)(`div`,{className:`stateGrid`,children:[(0,E.jsx)(A,{label:`Version Storage`,value:`архитектура зафиксирована, runtime не реализован`}),(0,E.jsx)(A,{label:`Update cache`,value:`${Wt(`update-cache`,Je).length} узл.`}),(0,E.jsx)(A,{label:`File/config cache`,value:`${Wt(`file-storage-cache`,Je).length} узл.`}),(0,E.jsx)(A,{label:`Legacy removal`,value:M?.legacy_removal_allowed?`разрешено`:M?`заблокировано`:`н/д`}),(0,E.jsx)(A,{label:`Stale nodes`,value:M?`${M.summary.stale_nodes} stale / ${M.summary.blocked_nodes} blockers`:`н/д`})]}),(0,E.jsx)(`p`,{className:`muted`,children:`Version Storage и 409/HTTP ответы относятся к Control API. Межузловой runtime transport Fabric остается QUIC/UDP-only.`}),M&&(0,E.jsxs)(`div`,{className:`stack compact`,children:[(0,E.jsxs)(`div`,{className:`membershipList`,children:[(0,E.jsx)(`span`,{className:`pill ${M.legacy_removal_allowed?`good`:`bad`}`,children:M.legacy_removal_allowed?`legacy cleanup allowed`:`legacy cleanup blocked`}),(0,E.jsxs)(`span`,{className:`pill`,children:[`nodes `,M.summary.total_nodes]}),(0,E.jsxs)(`span`,{className:`pill ${M.summary.stale_nodes>0?`warn`:`good`}`,children:[`stale `,M.summary.stale_nodes]}),(0,E.jsxs)(`span`,{className:`pill ${M.summary.blocked_nodes>0?`bad`:`good`}`,children:[`blockers `,M.summary.blocked_nodes]}),M.bridge_hold_required&&(0,E.jsx)(`span`,{className:`pill bad`,children:`bridge hold active`}),(M.blocked_operations||[]).map(e=>(0,E.jsx)(`span`,{className:`pill bad`,children:e},e)),(M.summary.artifact_gap_nodes||0)>0&&(0,E.jsxs)(`span`,{className:`pill bad`,children:[`artifact gap `,M.summary.artifact_gap_nodes]}),(M.summary.unknown_profile_nodes||0)>0&&(0,E.jsxs)(`span`,{className:`pill warn`,children:[`profile unknown `,M.summary.unknown_profile_nodes]}),(M.summary.waiting_update_status_nodes||0)>0&&(0,E.jsxs)(`span`,{className:`pill warn`,children:[`waiting status `,M.summary.waiting_update_status_nodes]}),(M.summary.unknown_version_nodes||0)>0&&(0,E.jsxs)(`span`,{className:`pill warn`,children:[`version unknown `,M.summary.unknown_version_nodes]}),(M.summary.legacy_recovery_contract_nodes||0)>0&&(0,E.jsxs)(`span`,{className:`pill bad`,children:[`legacy recovery contract `,M.summary.legacy_recovery_contract_nodes]}),(M.summary.recovery_bridge_required_nodes||0)>0&&(0,E.jsxs)(`span`,{className:`pill bad`,children:[`recovery bridge `,M.summary.recovery_bridge_required_nodes]}),(M.summary.recovery_bridge_replay_ready_nodes||0)>0&&(0,E.jsxs)(`span`,{className:`pill warn`,children:[`bridge replay ready `,M.summary.recovery_bridge_replay_ready_nodes]}),(M.summary.waiting_recovery_heartbeat_nodes||0)>0&&(0,E.jsxs)(`span`,{className:`pill info`,children:[`waiting heartbeat `,M.summary.waiting_recovery_heartbeat_nodes]})]}),M.summary.blocked_nodes>0?(0,E.jsxs)(`div`,{className:`stack compact`,children:[M.bridge_hold_required&&(0,E.jsx)(`p`,{className:`muted`,children:(()=>{let e=(M.bridge_hold_node_ids||[]).length||M.summary.recovery_bridge_required_nodes||0,t=M.bridge_hold_reasons||[];return(0,E.jsxs)(E.Fragment,{children:[`Recovery bridge hold active: compatibility overlap must remain enabled for`,` `,e,` node(s)`,t.length>0?` until ${t.join(`, `)} is cleared.`:`.`]})})()}),M.nodes.filter(e=>e.blocked).slice(0,4).map(e=>{let t=He[e.node_id],n=e.products.map(e=>{let t=e.compatible_artifact_found?e.matching_release_version||`ok`:`missing`;return`${e.product}: ${t}`}).join(` | `);return(0,E.jsxs)(`div`,{className:`stateList`,children:[(0,E.jsx)(A,{label:`Blocker`,value:`${e.name} (${H(e.health_status)})`}),(0,E.jsx)(A,{label:`Last seen`,value:V(e.last_seen_at)}),(0,E.jsx)(A,{label:`Recovery readiness`,value:At(e)}),(0,E.jsx)(A,{label:`Recovery bridge`,value:e.recovery_bridge_required?`required`:`not required`}),(0,E.jsx)(A,{label:`Bridge replay`,value:e.recovery_bridge_replay_ready?`ready`:`not ready`}),(0,E.jsx)(A,{label:`Bridge hold`,value:e.recovery_bridge_required?`active: compatibility overlap must stay enabled`:`not active`}),(0,E.jsx)(A,{label:`Bridge actions`,value:(e.recovery_bridge_actions||[]).length>0?(e.recovery_bridge_actions||[]).join(`, `):`none`}),t&&t.products&&t.products.length>0&&(0,E.jsxs)(E.Fragment,{children:[(0,E.jsx)(A,{label:`Replay plan`,value:`${t.products.length} product(s), ${t.bridge_hold_required?`hold active`:`hold cleared`}`}),t.products.map(t=>(0,E.jsx)(A,{label:`Replay ${t.product}`,value:`${t.update_plan.action} -> ${t.update_plan.target_version||`none`} / ${t.recovery_bridge_mode||`default`} / ${t.last_status_reason||`no reason`}`},`${e.node_id}-${t.product}`)),(0,E.jsxs)(`div`,{className:`actions`,children:[(0,E.jsx)(`button`,{className:`ghost`,onClick:()=>{gn(JSON.stringify(t,null,2)),Kr(`Bridge replay plan copied: ${e.name}`)},children:`Copy replay plan`}),(0,E.jsx)(`button`,{className:`ghost`,onClick:()=>{let n=t.products?.map(e=>e.update_plan.artifact?.url||``).filter(e=>e.length>0)||[];gn(n.join(` `)),Kr(n.length>0?`Replay artifact URL copied: ${e.name}`:`Replay artifact URL is not available yet: ${e.name}`)},children:`Copy artifact URL`}),(0,E.jsx)(`button`,{className:`ghost`,onClick:()=>{gn((t.products||[]).map(e=>{let t=e.update_plan;return[`product=${e.product}`,`action=${t.action}`,`target=${t.target_version||`none`}`,`mode=${e.recovery_bridge_mode||`default`}`,`reason=${e.last_status_reason||t.reason||`unknown`}`,`artifact=${t.artifact?.url||`n/a`}`].join(` | `)}).join(` `)||`node=${e.name} | no replay products`),Kr(`Bridge replay summary copied: ${e.name}`)},children:`Copy replay summary`})]}),(0,E.jsx)(Ce,{title:`Raw bridge replay plan: ${e.name}`,value:t})]}),(0,E.jsx)(A,{label:`Risks`,value:e.risks.join(`, `)||`none`}),(0,E.jsx)(A,{label:`Recovery artifacts`,value:n||`н/д`}),(0,E.jsx)(A,{label:`Действие`,value:kt(e)}),(0,E.jsxs)(`div`,{className:`actions`,children:[(0,E.jsx)(`button`,{className:`ghost`,onClick:()=>Na(e.node_id,`details`),children:`Последние статусы`}),(0,E.jsx)(`button`,{className:`ghost`,onClick:()=>Na(e.node_id,`manage`),children:`Policy / listener`}),(0,E.jsx)(`button`,{className:`ghost`,onClick:()=>Pa(e.node_id),children:`Показать update trail`})]})]},e.node_id)})]}):(0,E.jsx)(`p`,{className:`muted`,children:`Сейчас старых узлов-блокеров нет: compatibility overlap можно снимать только после отдельного решения оператора.`}),ja.length>0&&(0,E.jsxs)(`div`,{className:`stack compact`,children:[(0,E.jsx)(`p`,{className:`muted`,children:`Последние заблокированные попытки rollout`}),ja.map(e=>{let t=F(e.payload)||{},n=I(t,`blocked_operation`,``),r=Ot(t,`stale_nodes`),i=Ot(t,`blocked_nodes`),a=`${H(e.target_type)}${e.target_id?`:${B(e.target_id)}`:``}`,o=[Number.isFinite(r)?`stale ${r}`:``,Number.isFinite(i)?`blockers ${i}`:``].filter(Boolean).join(` / `);return(0,E.jsxs)(`div`,{className:`stateList`,children:[(0,E.jsx)(A,{label:`Когда`,value:V(e.created_at)}),(0,E.jsx)(A,{label:`Операция`,value:n||e.event_type}),(0,E.jsx)(A,{label:`Цель`,value:a}),(0,E.jsx)(A,{label:`Причина`,value:o||`guard active`})]},e.id)})]}),(0,E.jsxs)(`div`,{className:`stack compact`,children:[(0,E.jsx)(`p`,{className:`muted`,children:"Operator smoke: этот action намеренно пытается создать breaking release через HTTP Control API и должен получить blocked `409`, пока stale recovery-risk узлы ещё есть. Это проверка guard и frontend error formatting, а не transport Fabric."}),(0,E.jsxs)(`div`,{className:`membershipList`,children:[(0,E.jsx)(`span`,{className:`pill`,children:`smoke`}),Qi?Qi.includes(`unexpectedly succeeded`)?(0,E.jsx)(`span`,{className:`pill bad`,children:`unexpected success`}):(0,E.jsxs)(`span`,{className:`pill good`,children:[`expected blocked 409`,ea?` · ${Zn(ea)}`:``]}):(0,E.jsx)(`span`,{className:`pill info`,children:`not checked`})]}),(0,E.jsx)(`div`,{className:`actions`,children:(0,E.jsx)(`button`,{className:`ghost`,disabled:!T||M.summary.blocked_nodes<1||Vr,onClick:()=>Jn(`Проверить legacy-removal guard через blocked release smoke`)&&void Qa(),children:`Проверить blocked 409`})}),Qi&&(0,E.jsxs)(`div`,{className:`noticePanel ${Qi.includes(`unexpectedly succeeded`)?`badPanel`:`warnPanel`}`,children:[(0,E.jsx)(`strong`,{children:`Guard smoke`}),(0,E.jsx)(`div`,{children:Qi}),ea&&(0,E.jsxs)(`div`,{className:`muted`,children:[`Проверено: `,V(ea)]})]})]})]})]}),(0,E.jsxs)(`article`,{className:`card`,children:[(0,E.jsx)(`h3`,{children:`Control/API access`}),(0,E.jsxs)(`div`,{className:`stateGrid`,children:[(0,E.jsx)(A,{label:`Entry nodes`,value:`${Wt(`entry-node`,Je).length} узл.`}),(0,E.jsx)(A,{label:`Relay nodes`,value:`${Wt(`relay-node`,Je).length} узл.`}),(0,E.jsx)(A,{label:`Core mesh`,value:`${Wt(`core-mesh`,Je).length} узл.`})]}),(0,E.jsx)(`p`,{className:`muted`,children:`Это слой входа в Control/API, а не transport fabric. Панель кластера не переезжает автоматически на storage-узел: admin/runtime access назначается отдельной ролью на ingress/admin-capable узле.`})]})]})]}),C===`nodes`&&(0,E.jsxs)(`section`,{className:`grid two`,children:[(0,E.jsxs)(`article`,{className:`card span2`,children:[(0,E.jsxs)(`div`,{className:`cardHead`,children:[(0,E.jsxs)(`div`,{children:[(0,E.jsx)(`h3`,{children:J.nodeManagement}),(0,E.jsx)(`p`,{className:`muted`,children:`Единый краткий список узлов. По умолчанию показан активный кластер; включите общий режим, чтобы увидеть весь инвентарь платформы.`})]}),(0,E.jsxs)(`div`,{className:`actions`,children:[(0,E.jsxs)(`label`,{className:`checkLine`,children:[(0,E.jsx)(`input`,{type:`checkbox`,checked:li===`all`,onChange:e=>ui(e.target.checked?`all`:`cluster`)}),J.showAllPlatformNodes]}),(0,E.jsx)(`button`,{className:`ghost`,onClick:()=>{ui(`all`),fi(``)},children:J.showAllPlatformNodes})]})]}),(0,E.jsxs)(`div`,{className:`signalStrip compact`,children:[(0,E.jsx)(ge,{label:`Узлы активного кластера`,value:String(j.length)}),(0,E.jsx)(ge,{label:`Все узлы`,value:String(Ta.length)}),(0,E.jsx)(ge,{label:`Заявки`,value:String(io)}),(0,E.jsx)(ge,{label:`Активные роли`,value:String(so)})]}),(0,E.jsx)(`p`,{className:`muted`,children:J.addNodeText})]}),(0,E.jsxs)(`article`,{className:`card span2`,children:[(0,E.jsxs)(`div`,{className:`cardHead`,children:[(0,E.jsxs)(`div`,{children:[(0,E.jsx)(`h3`,{children:J.nodeBriefList}),(0,E.jsx)(`p`,{className:`muted`,children:J.nodeBriefListHelp})]}),(0,E.jsx)(`span`,{className:`pill`,children:Da.length})]}),(0,E.jsxs)(Qe,{children:[(0,E.jsxs)(`label`,{children:[J.nodeSearch,(0,E.jsx)(`input`,{value:di,onChange:e=>fi(e.target.value),placeholder:J.nodeSearchPlaceholder})]}),(0,E.jsxs)(`label`,{children:[J.nodeGroupFilter,(0,E.jsxs)(`select`,{value:pi,onChange:e=>mi(e.target.value),children:[(0,E.jsx)(`option`,{value:``,children:J.allNodeGroups}),Oe.map(e=>(0,E.jsx)(`option`,{value:e.id,children:Bt(e,Oe)},e.id))]})]})]}),(0,E.jsx)(`p`,{className:`muted`,children:J.nodeGroupInventoryText}),(0,E.jsx)(`h4`,{children:J.nodeGroupCreatePanel}),(0,E.jsxs)(Qe,{children:[(0,E.jsxs)(`label`,{children:[J.nodeGroupName,(0,E.jsx)(`input`,{value:Zr.name,onChange:e=>Qr({...Zr,name:e.target.value})})]}),(0,E.jsxs)(`label`,{children:[J.parentNodeGroup,(0,E.jsxs)(`select`,{value:Zr.parentGroupId,onChange:e=>Qr({...Zr,parentGroupId:e.target.value}),children:[(0,E.jsx)(`option`,{value:``,children:J.rootNodeGroup}),Oe.map(e=>(0,E.jsx)(`option`,{value:e.id,children:Bt(e,Oe)},e.id))]})]}),(0,E.jsxs)(`label`,{children:[J.createNodeGroup,(0,E.jsx)(`button`,{className:`primary`,disabled:!Zr.name.trim(),onClick:()=>void Y(async()=>{await q.createNodeGroup(T,{name:Zr.name,parentGroupId:Zr.parentGroupId||null}),Qr({name:``,parentGroupId:``})},J.nodeGroupCreated),children:J.createNodeGroup})]})]}),(0,E.jsxs)(`div`,{className:`nodeList`,children:[Aa.map(e=>{if(e.kind===`group`){let t=hi.includes(e.key);return(0,E.jsxs)(`div`,{className:`nodeListGroup`,style:{paddingLeft:`${e.depth*18}px`},children:[(0,E.jsxs)(`div`,{className:`nodeListMain`,children:[(0,E.jsx)(`strong`,{children:e.label}),e.groupId&&(0,E.jsx)(`span`,{children:Vt(e.groupId,Oe)})]}),(0,E.jsxs)(`div`,{className:`actions`,children:[(0,E.jsx)(`span`,{className:`pill`,children:e.count}),(0,E.jsx)(`button`,{className:`ghost`,onClick:()=>gi(On(hi,e.key)),children:t?J.expandGroup:J.collapseGroup}),e.groupId&&(0,E.jsx)(`button`,{className:`ghost`,onClick:()=>Qr({name:``,parentGroupId:e.groupId||``}),children:J.createSubgroup})]})]},e.key)}let t=e.entry,n=t.memberships.find(e=>e.cluster.id===T),r=n?.node||t.node,i=Dt(r,st[r.id]||[],bt),a=at(r,We[r.id],Ie),o=gt(Ke[r.id]||[]),s=n?.node.membership_status===`active`,c=n?.node.membership_status===`revoked`;return(0,E.jsxs)(`div`,{className:`nodeListRow`,style:{marginLeft:`${e.depth*18}px`},children:[(0,E.jsxs)(`div`,{className:`nodeListMain`,children:[(0,E.jsx)(`strong`,{children:r.name}),(0,E.jsx)(`span`,{children:r.node_key}),(0,E.jsx)(`small`,{className:`muted`,children:i.address})]}),(0,E.jsx)(_e,{value:r.health_status}),(0,E.jsx)(we,{runtime:i}),(0,E.jsxs)(`div`,{className:`nodeEndpointCell`,children:[(0,E.jsx)(`strong`,{children:r.reported_version||`версия неизвестна`}),(0,E.jsx)(`small`,{children:a.targetLabel})]}),(0,E.jsx)(_e,{value:a.status}),(0,E.jsxs)(`div`,{className:`nodeEndpointCell`,children:[(0,E.jsx)(`strong`,{className:`pill ${o.tone}`,children:o.label}),(0,E.jsx)(`small`,{children:o.detail})]}),(0,E.jsx)(`span`,{className:`muted`,children:V(r.last_seen_at)}),n?(0,E.jsx)(_e,{value:n.node.membership_status}):(0,E.jsx)(`span`,{className:`muted`,children:J.notMemberOfActiveCluster}),(0,E.jsxs)(`div`,{className:`actions`,children:[(0,E.jsx)(`button`,{onClick:()=>{wi(t),Ei(`details`)},children:J.nodeDetails}),s?(0,E.jsxs)(E.Fragment,{children:[(0,E.jsx)(`button`,{className:`primary`,onClick:()=>{wi(t),Ei(`manage`)},children:J.manageNode}),(0,E.jsx)(`button`,{className:`danger`,onClick:()=>Jn(`Удалить узел ${r.name} из кластера`)&&void Y(()=>q.deleteClusterNode(T,r.id,`Удалено из списка узлов панели владельца платформы.`),`Узел удален из кластера.`),children:`Удалить`})]}):c?(0,E.jsx)(`span`,{className:`muted`,children:J.revokedMembership}):(0,E.jsx)(`button`,{className:`primary`,onClick:()=>{bi(t),Si([])},children:J.connectExistingNode})]})]},e.key)}),Aa.length===0&&(0,E.jsx)(ye,{title:J.noNodesTitle,text:J.noNodesByFilter})]})]}),yi&&(0,E.jsx)(`div`,{className:`modalBackdrop`,role:`presentation`,children:(0,E.jsxs)(`div`,{className:`modalCard`,role:`dialog`,"aria-modal":`true`,"aria-labelledby":`attach-node-title`,children:[(0,E.jsxs)(`div`,{className:`cardHead`,children:[(0,E.jsxs)(`div`,{children:[(0,E.jsx)(`h3`,{id:`attach-node-title`,children:J.connectExistingNodeTitle}),(0,E.jsx)(`p`,{className:`muted`,children:J.connectExistingNodeText})]}),(0,E.jsx)(`button`,{className:`ghost`,onClick:()=>bi(null),children:J.cancel})]}),(0,E.jsxs)(`div`,{className:`stateList`,children:[(0,E.jsx)(A,{label:`Узел`,value:yi.node.name}),(0,E.jsx)(A,{label:`Node key`,value:yi.node.node_key}),(0,E.jsx)(A,{label:J.activeCluster,value:ha?.name||T})]}),(0,E.jsx)(`div`,{className:`checkGrid`,children:ae.map(e=>(0,E.jsxs)(`label`,{className:`checkLine`,children:[(0,E.jsx)(`input`,{type:`checkbox`,checked:xi.includes(e),onChange:()=>Si(On(xi,e))}),rt(e)]},e))}),(0,E.jsxs)(`div`,{className:`actions`,children:[(0,E.jsx)(`button`,{className:`primary`,onClick:()=>void Y(async()=>{await q.attachExistingNode(T,yi.node.id,xi),bi(null),Si([]),ui(`cluster`)},`Узел подключен к активному кластеру.`),children:J.connectWithRoles}),(0,E.jsx)(`button`,{onClick:()=>bi(null),children:J.cancel})]})]})}),Ci&&(()=>{let e=Ci.memberships.find(e=>e.cluster.id===T),t=e?.node||Ci.node,n=e?(st[t.id]||[])[0]:void 0,r=e?(Je[t.id]||[]).filter(e=>e.status===`active`):[],i=e&&Xe[t.id]||[],a=e&&nt[t.id]||[];return(0,E.jsx)(`div`,{className:`modalBackdrop`,role:`presentation`,children:(0,E.jsxs)(`div`,{className:`modalCard wide`,role:`dialog`,"aria-modal":`true`,"aria-labelledby":`node-info-title`,children:[(0,E.jsxs)(`div`,{className:`cardHead`,children:[(0,E.jsxs)(`div`,{children:[(0,E.jsxs)(`h3`,{id:`node-info-title`,children:[Ti===`manage`?J.manageNode:J.nodeDetails,`: `,t.name]}),(0,E.jsx)(`p`,{className:`muted`,children:t.node_key})]}),(0,E.jsx)(`button`,{className:`ghost`,onClick:()=>{wi(null),Ei(`details`)},children:J.close})]}),(0,E.jsxs)(`section`,{className:`nodePanel`,children:[(0,E.jsx)(`h4`,{children:J.nodeIdentity}),(0,E.jsxs)(`div`,{className:`stateList`,children:[(0,E.jsx)(A,{label:`Node ID`,value:B(t.id)}),(0,E.jsx)(A,{label:`Ключ узла`,value:t.node_key}),(0,E.jsx)(A,{label:`Тип владения`,value:H(t.ownership_type)}),(0,E.jsx)(A,{label:`Owner org`,value:B(t.owner_organization_id)}),(0,E.jsx)(A,{label:`Регистрация`,value:H(t.registration_status)}),(0,E.jsx)(A,{label:`Здоровье`,value:H(t.health_status)}),(0,E.jsx)(A,{label:`Версия`,value:t.reported_version||`неизвестно`}),(0,E.jsx)(A,{label:`Последний сигнал`,value:V(t.last_seen_at)})]})]}),(0,E.jsxs)(`section`,{className:`nodePanel`,children:[(0,E.jsx)(`h4`,{children:J.clusterMemberships}),(0,E.jsx)(`div`,{className:`membershipList`,children:Ci.memberships.map(e=>(0,E.jsxs)(`span`,{className:e.cluster.id===T?`pill good`:`pill`,children:[e.cluster.name,`: `,H(e.node.membership_status)]},e.cluster.id))})]}),e?(0,E.jsxs)(E.Fragment,{children:[(0,E.jsxs)(`section`,{className:`nodePanel`,children:[(0,E.jsx)(`h4`,{children:J.activeClusterScope}),(0,E.jsxs)(`div`,{className:`stateList`,children:[(0,E.jsx)(A,{label:`Участие`,value:H(t.membership_status)}),(0,E.jsx)(A,{label:`Сегмент`,value:H(t.partition_state)}),(0,E.jsx)(A,{label:`Группа`,value:t.node_group_name||J.ungroupedNodes}),(0,E.jsx)(A,{label:`Ролей`,value:String(r.length)}),(0,E.jsx)(A,{label:`Desired-сервисов`,value:String(i.length)}),(0,E.jsx)(A,{label:`Observed-сервисов`,value:String(a.length)})]})]}),Ti===`details`&&(0,E.jsx)(Se,{node:t,memberships:Ci.memberships,activeRoles:r,desiredWorkloads:i,observedWorkloads:a,heartbeats:st[t.id]||[],telemetry:ut[t.id]||[],updatePlan:We[t.id],updateStatuses:Ke[t.id]||[],meshLinks:bt.filter(e=>e.source_node_id===t.id||e.target_node_id===t.id),syntheticConfig:Tt[t.id],allNodes:j,onSetUpdatePolicy:(e,t,n)=>void Y(async()=>{await q.upsertNodeUpdatePolicy(T,e.id,{product:t,channel:`dev`,targetVersion:n,strategy:`rolling`,enabled:!0,rollbackAllowed:!0,healthWindowSeconds:180})},n?`${t} поставлен в target ${n}.`:`${t} будет следовать latest dev.`),labels:J}),Ti===`manage`&&(0,E.jsxs)(`section`,{className:`nodePanel`,children:[(0,E.jsx)(`h4`,{children:J.nodeFunctions}),(0,E.jsx)(`p`,{className:`muted`,children:J.nodeFunctionsText}),(0,E.jsxs)(`label`,{className:`wideLabel`,children:[J.organizationScopeForEnable,(0,E.jsx)(`input`,{value:si,onChange:e=>ci(e.target.value),placeholder:J.clusterWideRolePlaceholder})]}),(0,E.jsx)(`div`,{className:`functionList`,children:ae.map(e=>{let o=r.find(t=>t.role===e),s=i.find(t=>t.service_type===e),c=a.find(t=>t.service_type===e),l=Pn(e,n),u=s?.desired_state||`not_configured`,f=c?.reported_state||`missing`,p=!!o&&u===`enabled`;return(0,E.jsxs)(`div`,{className:`functionRow`,children:[(0,E.jsxs)(`div`,{className:`nodeListMain`,children:[(0,E.jsx)(`strong`,{children:rt(e)}),(0,E.jsx)(`span`,{children:In(e,n,d)})]}),(0,E.jsx)(ve,{label:J.rolePermission,value:o?J.permissionGranted:J.permissionDenied,tone:o?`info`:``}),(0,E.jsx)(ve,{label:J.desiredRuntime,value:H(u),tone:u===`enabled`?`good`:``}),(0,E.jsx)(ve,{label:J.observedRuntime,value:H(f),tone:f===`running`?`good`:f===`missing`?`warn`:``}),(0,E.jsx)(`span`,{className:`pill ${l}`,children:Fn(e,n,J)}),(0,E.jsxs)(`div`,{className:`actions`,children:[(0,E.jsx)(`button`,{className:p?``:`primary`,disabled:p,onClick:()=>void Y(async()=>{o||await q.setRoleStatus(T,t.id,e,`active`,si||void 0),await q.setDesiredWorkload(T,t.id,e,{desiredState:`enabled`,runtimeMode:`container`,config:{},environment:{}})},`${e}: функция включена.`),children:J.enableFunction}),(0,E.jsx)(`button`,{disabled:!o&&u!==`enabled`,onClick:()=>void Y(async()=>{await q.setDesiredWorkload(T,t.id,e,{desiredState:`disabled`,runtimeMode:s?.runtime_mode||`container`,config:s?.config||{},environment:s?.environment||{}}),o&&await q.setRoleStatus(T,t.id,e,`disabled`,o.organization_id||void 0)},`${e}: функция выключена.`),children:J.disableFunction})]})]},e)})}),(()=>{let e=i.find(e=>e.service_type===`mesh-listener`)?.config||{},n=ji[t.id]||{listenAddr:String(e.listen_addr||``),mode:String(e.listen_port_mode||`auto`),autoRange:`${Number(e.auto_port_start||19131)}-${Number(e.auto_port_end||19231)}`,advertiseEndpoint:String(e.advertise_endpoint||``),endpointCandidates:Mt(e),advertiseTransport:String(e.advertise_transport||`direct_quic`),connectivity:String(e.connectivity_mode||`private_lan`),nat:String(e.nat_type||`none`),region:String(e.region||``)},r=e=>Mi({...ji,[t.id]:{...n,...e}});return(0,E.jsxs)(`section`,{className:`nodePanel nestedPanel`,children:[(0,E.jsx)(`h4`,{children:`Mesh listener`}),(0,E.jsxs)(Qe,{children:[(0,E.jsxs)(`label`,{children:[`Listen addr`,(0,E.jsx)(`input`,{value:n.listenAddr,onChange:e=>r({listenAddr:e.target.value}),placeholder:`0.0.0.0:19131 или :19131`})]}),(0,E.jsxs)(`label`,{children:[`Port mode`,(0,E.jsxs)(`select`,{value:n.mode,onChange:e=>r({mode:e.target.value}),children:[(0,E.jsx)(`option`,{value:`auto`,children:`auto`}),(0,E.jsx)(`option`,{value:`manual`,children:`manual`}),(0,E.jsx)(`option`,{value:`disabled`,children:`disabled`})]})]}),(0,E.jsxs)(`label`,{children:[`Auto ports`,(0,E.jsx)(`input`,{value:n.autoRange,onChange:e=>r({autoRange:e.target.value}),placeholder:`19131-19231`})]}),(0,E.jsxs)(`label`,{children:[`Advertise endpoint`,(0,E.jsx)(`input`,{value:n.advertiseEndpoint,onChange:e=>r({advertiseEndpoint:e.target.value}),placeholder:`quic://192.168.200.85:18080`})]}),(0,E.jsxs)(`label`,{className:`wideLabel`,children:[`Endpoint candidates`,(0,E.jsx)(`textarea`,{value:n.endpointCandidates,onChange:e=>r({endpointCandidates:e.target.value}),rows:5,placeholder:`quic://192.168.200.85:18080 reachability=private connectivity=private_lan interface=lan quic://94.141.118.222:19199 reachability=public connectivity=direct provider=isp1 maps_to=192.168.200.85:18080`}),(0,E.jsx)(`small`,{children:`Одна строка = один адрес узла. Можно указать provider, interface, maps_to, priority, reachability, connectivity, nat.`})]}),(0,E.jsxs)(`label`,{children:[`Advertise transport`,(0,E.jsxs)(`select`,{value:n.advertiseTransport,onChange:e=>r({advertiseTransport:e.target.value}),children:[(0,E.jsx)(`option`,{value:`direct_quic`,children:`direct_quic`}),(0,E.jsx)(`option`,{value:`relay_quic`,children:`relay_quic`}),(0,E.jsx)(`option`,{value:`outbound_reverse`,children:`outbound_reverse`})]})]}),(0,E.jsxs)(`label`,{children:[`Connectivity`,(0,E.jsxs)(`select`,{value:n.connectivity,onChange:e=>r({connectivity:e.target.value}),children:[(0,E.jsx)(`option`,{value:`private_lan`,children:`private_lan`}),(0,E.jsx)(`option`,{value:`direct`,children:`direct`}),(0,E.jsx)(`option`,{value:`outbound_only`,children:`outbound_only`}),(0,E.jsx)(`option`,{value:`relay_required`,children:`relay_required`})]})]}),(0,E.jsxs)(`label`,{children:[`NAT`,(0,E.jsxs)(`select`,{value:n.nat,onChange:e=>r({nat:e.target.value}),children:[(0,E.jsx)(`option`,{value:`none`,children:`none`}),(0,E.jsx)(`option`,{value:`unknown`,children:`unknown`}),(0,E.jsx)(`option`,{value:`port_restricted`,children:`port_restricted`}),(0,E.jsx)(`option`,{value:`symmetric`,children:`symmetric`})]})]}),(0,E.jsxs)(`label`,{children:[`Region/site`,(0,E.jsx)(`input`,{value:n.region,onChange:e=>r({region:e.target.value}),placeholder:`dc1, office, docker-test`})]})]}),(0,E.jsx)(`div`,{className:`actions`,children:(0,E.jsx)(`button`,{className:`primary`,onClick:()=>void Y(async()=>{let[e,r]=n.autoRange.split(`-`).map(e=>Number(e.trim())),i=Number.isFinite(e)?e:19131,a=Number.isFinite(r)?r:i,o=Nt(n,t.id),s=o.map(e=>String(e.address||``)).filter(Boolean),c=n.advertiseEndpoint.trim().replace(/\/$/,``)||s[0]||null;await q.setDesiredWorkload(T,t.id,`mesh-listener`,{desiredState:n.mode===`disabled`?`disabled`:`enabled`,version:`listener-${Date.now()}`,runtimeMode:`container`,config:{listen_addr:n.listenAddr,listen_port_mode:n.mode,auto_port_start:i,auto_port_end:a,advertise_endpoint:c,advertise_endpoints:s,endpoint_candidates:o,advertise_transport:n.advertiseTransport||`direct_quic`,connectivity_mode:n.connectivity,nat_type:n.nat,region:n.region||null},environment:{}})},`Mesh listener config обновлен.`),children:`Применить listener`})})]})})(),(0,E.jsx)(`div`,{className:`actions`,children:(0,E.jsxs)(`select`,{value:t.node_group_id||``,onChange:e=>void Y(()=>q.assignNodeGroup(T,t.id,e.target.value||null),e.target.value?`Узел перемещен в группу.`:`Узел убран из группы.`),children:[(0,E.jsx)(`option`,{value:``,children:J.ungroupedNodes}),Oe.map(e=>(0,E.jsx)(`option`,{value:e.id,children:Bt(e,Oe)},e.id))]})}),(0,E.jsxs)(`div`,{className:`actions`,children:[(0,E.jsx)(`button`,{onClick:()=>Jn(`Отключить участие узла ${t.name}`)&&void Y(()=>q.disableMembership(T,t.id,`Отключено из панели владельца платформы.`),`Участие узла отключено.`),children:`Отключить участие`}),(0,E.jsx)(`button`,{className:`danger`,onClick:()=>Jn(`Отозвать identity узла ${t.name}`)&&void Y(()=>q.revokeNodeIdentity(T,t.id,`Отозвано из панели владельца платформы.`),`Identity узла отозван.`),children:`Отозвать identity`})]})]})]}):(0,E.jsxs)(`section`,{className:`nodePanel`,children:[(0,E.jsx)(`h4`,{children:J.noActiveClusterMembership}),(0,E.jsx)(`div`,{className:`actions`,children:(0,E.jsx)(`button`,{className:`primary`,onClick:()=>{bi(Ci),Si([]),wi(null)},children:J.connectExistingNode})})]})]})})})(),!1]}),C===`enrollment`&&(0,E.jsxs)(`section`,{className:`grid two`,children:[(0,E.jsxs)(`article`,{className:`card`,children:[(0,E.jsx)(`h3`,{children:J.joinTokenTitle}),(0,E.jsx)(`p`,{className:`muted`,children:J.joinTokenText}),(0,E.jsxs)(Qe,{children:[(0,E.jsxs)(`label`,{children:[J.ttlHours,(0,E.jsx)(`input`,{type:`number`,min:1,max:720,value:U.ttlHours,onChange:e=>W({...U,ttlHours:Number(e.target.value)})}),(0,E.jsx)(`small`,{children:J.ttlHelp})]}),(0,E.jsxs)(`label`,{children:[J.maxUses,(0,E.jsx)(`input`,{type:`number`,min:1,max:100,value:U.maxUses,onChange:e=>W({...U,maxUses:Number(e.target.value)})}),(0,E.jsx)(`small`,{children:J.maxUsesHelp})]}),(0,E.jsxs)(`label`,{children:[J.nodeOwnership,(0,E.jsxs)(`select`,{value:U.ownershipType,onChange:e=>W({...U,ownershipType:e.target.value}),children:[(0,E.jsx)(`option`,{value:`platform_managed`,children:`platform_managed, управляется платформой`}),(0,E.jsx)(`option`,{value:`customer_managed`,children:`customer_managed, управляется клиентом`})]})]}),(0,E.jsxs)(`label`,{children:[J.tokenPurpose,(0,E.jsx)(`input`,{value:U.purpose,onChange:e=>W({...U,purpose:e.target.value}),placeholder:`например: стартовый entry-node в ru-msk-1`})]}),(0,E.jsxs)(`label`,{children:[`Имя нового узла`,(0,E.jsx)(`input`,{value:U.nodeName,onChange:e=>W({...U,nodeName:e.target.value}),placeholder:rn(U,ha)}),(0,E.jsx)(`small`,{children:`Если оставить пустым, панель подставит имя автоматически.`})]}),(0,E.jsxs)(`label`,{children:[`Группа узла`,(0,E.jsxs)(`select`,{value:U.nodeGroupId,onChange:e=>W({...U,nodeGroupId:e.target.value}),children:[(0,E.jsx)(`option`,{value:``,children:`Без группы`}),Oe.map(e=>(0,E.jsx)(`option`,{value:e.id,children:Bt(e,Oe)},e.id))]})]})]}),(0,E.jsxs)(`section`,{className:`nodePanel`,children:[(0,E.jsx)(`h4`,{children:`Install profile`}),(0,E.jsx)(`p`,{className:`muted`,children:`Эти поля попадут в install profile. Для Windows без админ-прав будет создан user startup task, с админ-правами - system startup task.`}),(0,E.jsx)(`div`,{className:`segmented`,children:[[`docker`,`Docker Linux`],[`linux_binary`,`Ubuntu service`],[`windows_service`,`Windows`]].map(([e,t])=>(0,E.jsx)(`button`,{type:`button`,className:U.installMode===e?`active`:``,onClick:()=>W({...U,installMode:e}),children:t},e))}),(0,E.jsx)(`div`,{className:`segmented`,children:[[`private_lan`,`LAN`],[`direct`,`Public`],[`nat_forward`,`NAT`],[`outbound_only`,`Outbound`]].map(([e,t])=>(0,E.jsx)(`button`,{type:`button`,className:tn(U)===e?`active`:``,onClick:()=>W(nn(U,e)),children:t},e))}),(0,E.jsxs)(Qe,{children:[(0,E.jsxs)(`label`,{children:[`Control-plane endpoint`,(0,E.jsx)(`input`,{value:U.controlPlaneEndpoint,onChange:e=>W({...U,controlPlaneEndpoint:e.target.value}),placeholder:Zt()})]}),(0,E.jsxs)(`label`,{children:[U.installMode===`windows_service`?`Windows node-agent artifact`:U.installMode===`linux_binary`?`Linux node-agent artifact`:`Docker image`,(0,E.jsx)(`input`,{value:U.dockerImage,onChange:e=>W({...U,dockerImage:e.target.value})})]}),U.installMode===`windows_service`&&(0,E.jsxs)(E.Fragment,{children:[(0,E.jsxs)(`label`,{children:[`Windows startup`,(0,E.jsxs)(`select`,{value:U.windowsStartupMode,onChange:e=>W({...U,windowsStartupMode:e.target.value}),children:[(0,E.jsx)(`option`,{value:`auto`,children:`auto: system task, fallback user task`}),(0,E.jsx)(`option`,{value:`system-task`,children:`system task, admin required`}),(0,E.jsx)(`option`,{value:`user-task`,children:`user task, no admin`}),(0,E.jsx)(`option`,{value:`none`,children:`none`})]})]}),(0,E.jsxs)(`label`,{children:[`Install dir`,(0,E.jsx)(`input`,{value:U.windowsInstallDir,onChange:e=>W({...U,windowsInstallDir:e.target.value}),placeholder:`C:\\\\Program Files\\\\RAP\\\\node-name`})]}),(0,E.jsxs)(`label`,{children:[`Windows node-agent SHA256`,(0,E.jsx)(`input`,{value:U.windowsNodeAgentSHA256,onChange:e=>W({...U,windowsNodeAgentSHA256:e.target.value}),placeholder:`опционально, но желательно для production`})]})]}),U.installMode===`linux_binary`&&(0,E.jsxs)(E.Fragment,{children:[(0,E.jsxs)(`label`,{children:[`Linux install dir`,(0,E.jsx)(`input`,{value:U.linuxInstallDir,onChange:e=>W({...U,linuxInstallDir:e.target.value}),placeholder:`/opt/rap/node-name`})]}),(0,E.jsxs)(`label`,{children:[`Linux node-agent SHA256`,(0,E.jsx)(`input`,{value:U.linuxNodeAgentSHA256,onChange:e=>W({...U,linuxNodeAgentSHA256:e.target.value}),placeholder:`опционально, но желательно для production`})]})]}),U.installMode===`docker`&&(0,E.jsxs)(`label`,{children:[`Container name`,(0,E.jsx)(`input`,{value:U.dockerContainerName,onChange:e=>W({...U,dockerContainerName:e.target.value}),placeholder:an(U,ha)})]}),(0,E.jsxs)(`label`,{children:[`Artifact endpoints`,(0,E.jsx)(`input`,{value:U.artifactEndpoints,onChange:e=>W({...U,artifactEndpoints:e.target.value}),placeholder:Qt()}),(0,E.jsx)(`small`,{children:`Через запятую: public/LAN/cache узлы, где host-agent сможет скачать image tar до входа в mesh.`})]}),U.installMode===`docker`&&(0,E.jsxs)(`label`,{children:[`Docker image tar SHA256`,(0,E.jsx)(`input`,{value:U.dockerImageArtifactSHA256,onChange:e=>W({...U,dockerImageArtifactSHA256:e.target.value}),placeholder:`опционально, но желательно для production`})]}),U.installMode===`docker`&&(0,E.jsxs)(`label`,{children:[`Docker network`,(0,E.jsxs)(`select`,{value:U.dockerNetwork,onChange:e=>W({...U,dockerNetwork:e.target.value}),children:[(0,E.jsx)(`option`,{value:`host`,children:`host`}),(0,E.jsx)(`option`,{value:`bridge`,children:`bridge`})]})]}),(0,E.jsxs)(`label`,{children:[`Listen addr`,(0,E.jsx)(`input`,{value:U.meshListenAddr,onChange:e=>W({...U,meshListenAddr:e.target.value})})]}),(0,E.jsxs)(`label`,{children:[`Listen mode`,(0,E.jsxs)(`select`,{value:U.meshListenPortMode,onChange:e=>W({...U,meshListenPortMode:e.target.value}),children:[(0,E.jsx)(`option`,{value:`auto`,children:`auto`}),(0,E.jsx)(`option`,{value:`manual`,children:`manual`}),(0,E.jsx)(`option`,{value:`disabled`,children:`disabled`})]})]}),(0,E.jsxs)(`label`,{children:[`Auto ports`,(0,E.jsx)(`input`,{value:`${U.meshListenAutoPortStart}-${U.meshListenAutoPortEnd}`,onChange:e=>{let[t,n]=e.target.value.split(`-`).map(e=>Number(e.trim()));W({...U,meshListenAutoPortStart:Number.isFinite(t)?t:U.meshListenAutoPortStart,meshListenAutoPortEnd:Number.isFinite(n)?n:U.meshListenAutoPortEnd})}})]}),(0,E.jsxs)(`label`,{children:[`Advertise endpoint`,(0,E.jsx)(`input`,{value:U.meshAdvertiseEndpoint,onChange:e=>W({...U,meshAdvertiseEndpoint:e.target.value}),placeholder:`quic://192.168.200.85:18080`})]}),(0,E.jsxs)(`label`,{className:`wideLabel`,children:[`Endpoint candidates`,(0,E.jsx)(`textarea`,{value:U.meshAdvertiseEndpoints,onChange:e=>W({...U,meshAdvertiseEndpoints:e.target.value}),rows:5,placeholder:`quic://192.168.200.85:18080 reachability=private connectivity=private_lan nat=none interface=lan priority=1 quic://94.141.118.222:19199 reachability=public connectivity=direct nat=port_restricted provider=isp1 maps_to=192.168.200.85:18080 priority=2`}),(0,E.jsx)(`small`,{children:`Сюда вносим все реальные адреса узла: LAN, разные адаптеры, публичные UDP NAT-пробросы разных провайдеров.`})]}),(0,E.jsxs)(`label`,{children:[`Advertise transport`,(0,E.jsxs)(`select`,{value:U.meshAdvertiseTransport,onChange:e=>W({...U,meshAdvertiseTransport:e.target.value}),children:[(0,E.jsx)(`option`,{value:`direct_quic`,children:`direct_quic`}),(0,E.jsx)(`option`,{value:`relay_quic`,children:`relay_quic`}),(0,E.jsx)(`option`,{value:`outbound_reverse`,children:`outbound_reverse`})]})]}),(0,E.jsxs)(`label`,{children:[`Connectivity`,(0,E.jsxs)(`select`,{value:U.meshConnectivityMode,onChange:e=>W({...U,meshConnectivityMode:e.target.value}),children:[(0,E.jsx)(`option`,{value:`direct`,children:`direct`}),(0,E.jsx)(`option`,{value:`private_lan`,children:`private_lan`}),(0,E.jsx)(`option`,{value:`outbound_only`,children:`outbound_only`}),(0,E.jsx)(`option`,{value:`relay_required`,children:`relay_required`})]})]}),(0,E.jsxs)(`label`,{children:[`NAT`,(0,E.jsxs)(`select`,{value:U.meshNATType,onChange:e=>W({...U,meshNATType:e.target.value}),children:[(0,E.jsx)(`option`,{value:`none`,children:`none`}),(0,E.jsx)(`option`,{value:`unknown`,children:`unknown`}),(0,E.jsx)(`option`,{value:`full_cone`,children:`full_cone`}),(0,E.jsx)(`option`,{value:`port_restricted`,children:`port_restricted`}),(0,E.jsx)(`option`,{value:`symmetric`,children:`symmetric`})]})]}),(0,E.jsxs)(`label`,{children:[`Region/site`,(0,E.jsx)(`input`,{value:U.meshRegion,onChange:e=>W({...U,meshRegion:e.target.value})})]}),U.installMode===`docker`&&(0,E.jsxs)(`label`,{className:`checkLine`,children:[(0,E.jsx)(`input`,{type:`checkbox`,checked:U.pullImage,onChange:e=>W({...U,pullImage:e.target.checked})}),`Pull image`]}),(0,E.jsxs)(`label`,{className:`checkLine`,children:[(0,E.jsx)(`input`,{type:`checkbox`,checked:U.replace,onChange:e=>W({...U,replace:e.target.checked})}),`Replace existing install`]})]})]}),(0,E.jsxs)(`section`,{className:`nodePanel`,children:[(0,E.jsx)(`h4`,{children:J.suggestedRoles}),(0,E.jsx)(`p`,{className:`muted`,children:`Роли записываются в install token и автоматически назначаются узлу при approval. После создания token изменение чекбоксов не меняет уже выданный token.`}),(0,E.jsx)(`div`,{className:`checkGrid`,children:ae.map(e=>(0,E.jsxs)(`label`,{className:`checkLine`,children:[(0,E.jsx)(`input`,{type:`checkbox`,checked:U.roles.includes(e),onChange:()=>W({...U,roles:On(U.roles,e)})}),rt(e)]},e))})]}),(0,E.jsxs)(`details`,{children:[(0,E.jsx)(`summary`,{children:J.generatedScope}),(0,E.jsx)(`p`,{className:`muted`,children:J.generatedScopeHelp}),(0,E.jsx)(`pre`,{className:`codePreview`,children:JSON.stringify(Ca,null,2)})]}),(0,E.jsxs)(`p`,{className:`muted`,children:[J.manualApprovalRequired,`.`]}),(0,E.jsx)(`button`,{className:`primary`,disabled:!T,onClick:()=>void Y(async()=>{ii(await q.createJoinToken(T,{ttlHours:U.ttlHours,maxUses:U.maxUses,scope:Ca}))},`Join token создан.`),children:`Создать install token`}),ri&&(0,E.jsxs)(`div`,{className:`secretOnce`,children:[(0,E.jsx)(`strong`,{children:`Исходный token, возвращается один раз`}),(0,E.jsx)(`code`,{children:ri.token}),(0,E.jsxs)(`span`,{className:`muted`,children:[`Authority key: `,B(ri.authority_signature?.key_fingerprint)]}),(0,E.jsx)(`strong`,{children:`Scope выданного token`}),(0,E.jsx)(`pre`,{className:`codePreview`,children:JSON.stringify(ri.scope,null,2)}),(0,E.jsx)(`strong`,{children:`Docker host-agent install`}),(0,E.jsx)(`pre`,{className:`codePreview`,children:on(ri,ha,wa)}),(0,E.jsx)(`strong`,{children:`Profile-based Docker install`}),(0,E.jsx)(`pre`,{className:`codePreview`,children:sn(ri,ha,wa)}),(0,E.jsx)(`strong`,{children:`Profile-based Ubuntu service install`}),(0,E.jsx)(`pre`,{className:`codePreview`,children:cn(ri,ha,wa)}),(0,E.jsx)(`strong`,{children:`Profile-based Windows PowerShell install`}),(0,E.jsx)(`pre`,{className:`codePreview`,children:ln(ri,ha,wa)}),(0,E.jsx)(`strong`,{children:`Profile-based Windows CMD install`}),(0,E.jsx)(`pre`,{className:`codePreview`,children:un(ri,ha,wa)})]})]}),(0,E.jsxs)(`article`,{className:`card`,children:[(0,E.jsx)(`h3`,{children:`Как добавить узел`}),(0,E.jsxs)(`div`,{className:`stateList`,children:[(0,E.jsxs)(`div`,{className:`stateLine`,children:[(0,E.jsx)(`span`,{children:`1`}),(0,E.jsx)(`strong`,{children:`Заполните Docker install profile слева.`})]}),(0,E.jsxs)(`div`,{className:`stateLine`,children:[(0,E.jsx)(`span`,{children:`2`}),(0,E.jsx)(`strong`,{children:`Нажмите “Создать install token”.`})]}),(0,E.jsxs)(`div`,{className:`stateLine`,children:[(0,E.jsx)(`span`,{children:`3`}),(0,E.jsx)(`strong`,{children:`Скопируйте “Profile-based Docker install” и выполните на Docker-хосте.`})]}),(0,E.jsxs)(`div`,{className:`stateLine`,children:[(0,E.jsx)(`span`,{children:`4`}),(0,E.jsx)(`strong`,{children:`Подтвердите join request в этой же вкладке.`})]})]})]}),(0,E.jsxs)(`article`,{className:`card`,children:[(0,E.jsx)(`h3`,{children:`Install tokens`}),(0,E.jsx)(N,{columns:[`scope`,`status`,`uses`,`expires`,`created`,`action`],rows:Pe.map(e=>[vt(e),H(e.status),`${e.used_count}/${e.max_uses}`,V(e.expires_at),V(e.created_at),e.status===`active`?(0,E.jsx)(`button`,{className:`danger`,onClick:()=>Jn(`Отозвать install token ${B(e.id)}`)&&void Y(()=>q.revokeJoinToken(T,e.id),`Install token отозван.`),children:`Отозвать`}):(0,E.jsx)(`span`,{className:`muted`,children:H(e.status)})])})]}),(0,E.jsxs)(`article`,{className:`card`,children:[(0,E.jsx)(`h3`,{children:`Заявки на подключение`}),(0,E.jsxs)(`div`,{className:`stack`,children:[Me.map(e=>(0,E.jsxs)(`div`,{className:`requestCard`,children:[(0,E.jsxs)(`div`,{children:[(0,E.jsx)(`strong`,{children:e.node_name}),(0,E.jsx)(`p`,{children:e.node_fingerprint}),(0,E.jsx)(_e,{value:e.status}),e.approval_signature?.key_fingerprint&&(0,E.jsxs)(`small`,{className:`muted`,children:[`approval key `,B(e.approval_signature.key_fingerprint)]})]}),(0,E.jsxs)(`div`,{className:`actions`,children:[(0,E.jsx)(`button`,{disabled:e.status!==`pending`,onClick:()=>void Y(()=>q.approveJoinRequest(T,e.id),`Заявка одобрена.`),children:`Одобрить`}),(0,E.jsx)(`button`,{disabled:e.status!==`pending`,onClick:()=>void Y(()=>q.rejectJoinRequest(T,e.id,`Отклонено из панели владельца платформы.`),`Заявка отклонена.`),children:`Отклонить`})]})]},e.id)),Me.length===0&&(0,E.jsx)(ye,{title:`Нет заявок`,text:`Новые подключения node-agent появятся здесь.`})]})]})]}),C===`roles`&&(0,E.jsxs)(`section`,{className:`stack`,children:[(0,E.jsxs)(`article`,{className:`card`,children:[(0,E.jsx)(`h3`,{children:`Область ролей`}),(0,E.jsx)(`p`,{className:`muted`,children:`Capabilities — технические факты. Роли — явные разрешения. Область организации может ограничивать сервисные роли.`}),(0,E.jsxs)(`label`,{children:[`UUID организации для новых назначений ролей, опционально`,(0,E.jsx)(`input`,{value:si,onChange:e=>ci(e.target.value),placeholder:`пусто = роль на весь кластер`})]})]}),j.map(e=>(0,E.jsxs)(`article`,{className:`card roleRow`,children:[(0,E.jsxs)(`div`,{children:[(0,E.jsx)(`h3`,{children:e.name}),(0,E.jsx)(`p`,{children:tt(Je[e.id]||[])})]}),(0,E.jsxs)(`select`,{defaultValue:``,onChange:t=>{let n=t.target.value;t.currentTarget.value=``,n&&Y(()=>q.assignRole(T,e.id,n,si||void 0),`${n} назначена узлу ${e.name}.`)},children:[(0,E.jsx)(`option`,{value:``,children:`Назначить роль...`}),ae.map(e=>(0,E.jsx)(`option`,{value:e,children:rt(e)},e))]})]},e.id))]}),C===`workloads`&&(0,E.jsxs)(`section`,{className:`grid two`,children:[(0,E.jsxs)(`article`,{className:`card`,children:[(0,E.jsx)(`h3`,{children:`Желаемое состояние сервиса`}),(0,E.jsx)(`p`,{className:`muted`,children:`Здесь задается только желаемое состояние. Runtime-исполнение остается под контролем node-agent и политик.`}),(0,E.jsxs)(Qe,{children:[(0,E.jsxs)(`label`,{children:[`Узел`,(0,E.jsxs)(`select`,{value:zi.nodeId,onChange:e=>Bi({...zi,nodeId:e.target.value}),children:[(0,E.jsx)(`option`,{value:``,children:`Выберите узел...`}),j.map(e=>(0,E.jsx)(`option`,{value:e.id,children:e.name},e.id))]})]}),(0,E.jsxs)(`label`,{children:[`Сервис`,(0,E.jsx)(`select`,{value:zi.serviceType,onChange:e=>Bi({...zi,serviceType:e.target.value}),children:ae.map(e=>(0,E.jsx)(`option`,{value:e,children:rt(e)},e))})]}),(0,E.jsxs)(`label`,{children:[`Желаемое состояние`,(0,E.jsxs)(`select`,{value:zi.desiredState,onChange:e=>Bi({...zi,desiredState:e.target.value}),children:[(0,E.jsx)(`option`,{value:`enabled`,children:`включено`}),(0,E.jsx)(`option`,{value:`disabled`,children:`выключено`})]})]}),(0,E.jsxs)(`label`,{children:[`Режим runtime`,(0,E.jsxs)(`select`,{value:zi.runtimeMode,onChange:e=>Bi({...zi,runtimeMode:e.target.value}),children:[(0,E.jsx)(`option`,{value:`container`,children:`контейнер`}),(0,E.jsx)(`option`,{value:`native`,children:`нативно`})]})]}),(0,E.jsxs)(`label`,{children:[`Версия`,(0,E.jsx)(`input`,{value:zi.version,onChange:e=>Bi({...zi,version:e.target.value})})]})]}),(0,E.jsxs)(`label`,{children:[`Config JSON`,(0,E.jsx)(`textarea`,{value:zi.configJson,onChange:e=>Bi({...zi,configJson:e.target.value})})]}),(0,E.jsxs)(`label`,{children:[`Environment JSON`,(0,E.jsx)(`textarea`,{value:zi.environmentJson,onChange:e=>Bi({...zi,environmentJson:e.target.value})})]}),(0,E.jsx)(`button`,{className:`primary`,disabled:!zi.nodeId||!T,onClick:()=>void Y(()=>q.setDesiredWorkload(T,zi.nodeId,zi.serviceType,{desiredState:zi.desiredState,runtimeMode:zi.runtimeMode,version:zi.version,config:$e(zi.configJson,`config сервиса`),environment:$e(zi.environmentJson,`environment сервиса`)}),`Желаемое состояние сервиса обновлено.`),children:`Задать желаемое состояние`})]}),(0,E.jsxs)(`article`,{className:`card`,children:[(0,E.jsx)(`h3`,{children:`Отчеты сервисов`}),(0,E.jsx)(`div`,{className:`stack`,children:j.map(e=>(0,E.jsxs)(`div`,{className:`workloadBlock`,children:[(0,E.jsx)(`strong`,{children:e.name}),(nt[e.id]||[]).length===0?(0,E.jsx)(`p`,{className:`muted`,children:`Статус пока не получен.`}):(0,E.jsx)(N,{columns:[`сервис`,`состояние`,`runtime`,`наблюдение`],rows:(nt[e.id]||[]).map(e=>[e.service_type,e.reported_state,e.runtime_mode,V(e.observed_at)])})]},e.id))})]})]}),C===`fabric`&&(0,E.jsxs)(`section`,{className:`fabricTransportView`,children:[(0,E.jsxs)(`article`,{className:`card fabricMapCard`,children:[(0,E.jsxs)(`div`,{className:`cardHead`,children:[(0,E.jsxs)(`div`,{children:[(0,E.jsx)(`h3`,{children:`Транспортный слой Fabric`}),(0,E.jsx)(`p`,{className:`muted`,children:`Карта показывает реальные свежие QUIC-соседства и проверенные relay/route-health маршруты. Прямые связи рисуются сплошной линией, relay и route-health отделены пунктиром, чтобы не смешивать физического соседа и достижимый маршрут.`})]}),(0,E.jsxs)(`div`,{className:`summaryChips`,children:[(0,E.jsxs)(`span`,{className:`pill good`,children:[`direct `,bt.length]}),(0,E.jsx)(`span`,{className:`pill`,children:go.label}),(0,E.jsx)(_e,{value:co?.synthetic_links_enabled?`enabled`:`disabled`})]})]}),(0,E.jsx)(Ee,{nodes:j,links:bt,heartbeatsByNode:st,rolesByNode:Je,workloadsByNode:nt,labels:J,emptyText:J.noLinks}),(0,E.jsxs)(`details`,{className:`sectionBlock fabricDiagnostics`,children:[(0,E.jsx)(`summary`,{children:`Диагностика transport/runtime receivers`}),(0,E.jsxs)(`div`,{className:`signalStrip compact`,children:[(0,E.jsx)(ge,{label:`Synthetic configs`,value:`${uo}/${j.length}`}),(0,E.jsx)(ge,{label:`Routes`,value:String(fo)}),(0,E.jsx)(ge,{label:`Endpoints / candidates`,value:`${po}/${mo}`}),(0,E.jsx)(ge,{label:`Scoped production`,value:ho===0?`false`:`true:${ho}`})]}),(0,E.jsx)(N,{columns:[`узел`,`status`,`reason`,`trusted keys`,`service classes`,`QUIC addr`,`ошибка`],rows:j.map(e=>{let t=F(st[e.id]?.[0]?.metadata?.web_ingress_runtime_receiver_report),n=ze(st[e.id]?.[0]),r=t?Yt(t.service_classes):[],i=Ve(Je[e.id]||[]),a=i.length>0&&!i.every(e=>r.includes(e));return[e.name,(0,E.jsx)(`span`,{className:`pill ${n===`ready`?`good`:n===`degraded`?`warn`:n===`blocked`?`bad`:``}`,children:n}),t?I(t,`reason`,`н/д`):`no report`,t?String(Ot(t,`trusted_key_count`)):`0`,(0,E.jsx)(`span`,{className:a?`pill warn`:``,children:t&&r.join(`, `)||`н/д`}),t?I(t,`quic_fabric_listen_addr`,`н/д`):`н/д`,a?`expected: ${i.join(`, `)}`:t&&(I(t,`quic_fabric_error`,``)||I(t,`error`,``))||`—`]})})]})]}),(0,E.jsxs)(`article`,{className:`card span2`,children:[(0,E.jsxs)(`div`,{className:`cardHead`,children:[(0,E.jsxs)(`div`,{children:[(0,E.jsx)(`h3`,{children:`Synthetic mesh config`}),(0,E.jsx)(`p`,{className:`muted`,children:`Node-scoped config from the Control/API layer. Endpoint candidates and scoring inputs are visible to the platform owner only; production forwarding for service traffic must remain disabled here.`})]}),(0,E.jsxs)(`span`,{className:ho===0?`pill good`:`pill bad`,children:[`production_forwarding=`,ho===0?`false`:`true`]})]}),(0,E.jsx)(N,{columns:[`узел`,`config`,`routes`,`peer endpoints`,`candidates`,`peer dir`,`recovery seeds`,`rendezvous leases`,`relay policy`,`path decisions`,`authority`,`scoped production`],rows:j.map(e=>{let t=Tt[e.id];return[e.name,t?t.enabled?`enabled`:`disabled`:`не загружен`,String(t?.routes.length??0),String(Object.keys(t?.peer_endpoints||{}).length),String(t?Lt(t):0),String(t?.peer_directory?.length??0),String(t?.recovery_seeds?.length??0),String(t?.rendezvous_leases?.length??0),Rt(t),zt(t),t?.authority_required?B(t.authority_signature?.key_fingerprint):`не требуется`,t?.production_forwarding?`true`:`false`]})}),(0,E.jsx)(`p`,{className:`muted`,children:`Health-aware scoring не выбирает service route и не открывает service-соединения. C17Z19 показывает управляющий route/path decisions, route generation status, synthetic route-health effective path и relay feedback scoring, но не переносит RDP/VPN/file/video/service payload.`})]}),(0,E.jsxs)(`article`,{className:`card span2`,children:[(0,E.jsxs)(`div`,{className:`cardHead`,children:[(0,E.jsxs)(`div`,{children:[(0,E.jsx)(`h3`,{children:`Route intents lifecycle`}),(0,E.jsx)(`p`,{className:`muted`,children:`Operator view for temporary fabric routes. Expired and disabled intents are not emitted into node-scoped synthetic config.`})]}),(0,E.jsxs)(`div`,{className:`summaryChips`,children:[(0,E.jsxs)(`span`,{className:`pill good`,children:[`active `,_o.length]}),(0,E.jsxs)(`span`,{className:vo.length>0?`pill warn`:`pill`,children:[`expired `,vo.length]}),(0,E.jsxs)(`span`,{className:`pill`,children:[`disabled `,yo.length]})]})]}),(0,E.jsx)(N,{columns:[`route`,`life`,`service`,`priority`,`source`,`destination`,`expires`,`updated`,`actions`],rows:P.slice(0,120).map(e=>{let t=pt(e);return[B(e.id),(0,E.jsx)(`span`,{className:`pill ${mt(e)}`,children:t}),e.service_class,String(e.priority),ht(e.source_selector||{}),ht(e.destination_selector||{}),e.policy_expires_at?V(e.policy_expires_at):`нет`,V(e.updated_at),(0,E.jsxs)(`div`,{className:`inlineActions`,children:[t===`active`?(0,E.jsx)(`button`,{type:`button`,className:`ghost`,onClick:()=>void Y(()=>q.expireRouteIntent(T,e.id,`operator expired stale route intent`),`Route intent expired.`),children:`expire`}):(0,E.jsx)(`span`,{className:`muted`,children:`expire`}),t===`disabled`?(0,E.jsx)(`span`,{className:`muted`,children:`disable`}):(0,E.jsx)(`button`,{type:`button`,className:`ghost`,onClick:()=>void Y(()=>q.disableRouteIntent(T,e.id,`operator disabled route intent`),`Route intent disabled.`),children:`disable`})]})]})}),P.length===0&&(0,E.jsx)(ye,{title:`Route intents отсутствуют`,text:`Нет настроенных fabric route intents для текущего кластера.`})]}),(0,E.jsxs)(`article`,{className:`card span2`,children:[(0,E.jsxs)(`div`,{className:`cardHead`,children:[(0,E.jsxs)(`div`,{children:[(0,E.jsx)(`h3`,{children:`Service-channel route feedback`}),(0,E.jsx)(`p`,{className:`muted`,children:`Cluster-level runtime feedback from the shared fabric channel. Fenced and no-alternate cases affect route selection for any service class.`})]}),(0,E.jsxs)(`div`,{className:`summaryChips`,children:[(0,E.jsxs)(`span`,{className:xo.length>0?`pill bad`:`pill good`,children:[`fenced `,xo.length]}),(0,E.jsxs)(`span`,{className:So.length>0?`pill warn`:`pill`,children:[`degraded `,So.length]}),(0,E.jsxs)(`span`,{className:Do.length>0?`pill warn`:`pill`,children:[`retry `,Do.length]}),(0,E.jsxs)(`span`,{className:wo.length>0?`pill warn`:`pill`,children:[`recovered `,wo.length]}),(0,E.jsxs)(`span`,{className:To.length>0?`pill good`:`pill`,children:[`promoted `,To.length]}),(0,E.jsxs)(`span`,{className:Eo.length>0?`pill bad`:`pill`,children:[`demoted `,Eo.length]}),(0,E.jsxs)(`span`,{className:`pill good`,children:[`healthy `,Co.length]}),(0,E.jsxs)(`span`,{className:ko.length>0?`pill bad`:`pill`,children:[`no alternate `,ko.length]}),(0,E.jsxs)(`span`,{className:Io.length>0?`pill warn`:`pill`,children:[`hysteresis `,Io.length]}),(0,E.jsxs)(`span`,{className:Lo.length>0?`pill good`:`pill`,children:[`promoted paths `,Lo.length]}),(0,E.jsxs)(`span`,{className:Ro.length>0?`pill bad`:`pill`,children:[`demoted paths `,Ro.length]}),(0,E.jsxs)(`span`,{className:(jn?.fingerprint||``).length>0?`pill good`:`pill warn`,children:[`policy fp `,jn?.fingerprint?B(jn.fingerprint):`нет`]}),(0,E.jsxs)(`span`,{className:jo.length>Mo.length?`pill warn`:`pill good`,children:[`rebuild `,Mo.length,`/`,jo.length]}),(0,E.jsxs)(`span`,{className:Po.length>0?`pill warn`:`pill good`,children:[`ledger `,No.length,`/`,It.length]}),(0,E.jsxs)(`span`,{className:Fo.length>0?`pill bad`:`pill good`,children:[`guard `,Fo.length]}),(0,E.jsx)(`span`,{className:Tn?`pill info`:`pill`,children:Tn?`deep ledger`:`fast ledger`})]})]}),ko.length>0&&(0,E.jsx)(`div`,{className:`noticePanel`,children:`Есть service-channel route без unfenced alternate. Для production-сервиса это означает деградацию: fabric не нашел безопасную замену и будет ждать нового маршрута или операторского решения.`}),pn&&(0,E.jsxs)(`div`,{className:`noticePanel ${pn.status===`blocked`?`badPanel`:`goodPanel`}`,children:[(0,E.jsxs)(`div`,{className:`cardHead compact`,children:[(0,E.jsxs)(`div`,{children:[(0,E.jsx)(`h4`,{children:`Fabric schema preflight`}),(0,E.jsx)(`p`,{className:`muted`,children:`Backend/runtime compatibility check for manual deploys before diagnostics or service channels depend on new DB fields.`})]}),(0,E.jsxs)(`div`,{className:`summaryChips`,children:[(0,E.jsx)(`span`,{className:`pill ${pn.status===`blocked`?`bad`:`good`}`,children:H(pn.status)}),(0,E.jsxs)(`span`,{className:pn.missing_check_count>0?`pill bad`:`pill good`,children:[pn.passed_check_count,`/`,pn.required_check_count]}),(0,E.jsx)(`button`,{className:`ghost`,onClick:()=>void Ha(),disabled:Vr,children:`warm snapshots`})]})]}),(0,E.jsxs)(`div`,{className:`stateList`,children:[(0,E.jsx)(A,{label:`reason`,value:H(pn.reason)}),(0,E.jsx)(A,{label:`required`,value:pn.required_migration}),(0,E.jsx)(A,{label:`missing`,value:(pn.missing_checks||[]).map(e=>e.check_id).slice(0,4).join(`, `)||`нет`}),(0,E.jsx)(A,{label:`action`,value:pn.recommended_operator_action||`schema is compatible`}),vn&&(0,E.jsx)(A,{label:`warmup`,value:`warmed ${vn.warmed_count}, fresh ${vn.already_fresh_count}, missing ${vn.missing_snapshot_count}, stale ${vn.stale_snapshot_count}, deferred ${vn.deferred_stale_count}, errors ${vn.error_count}`})]})]}),hn&&(0,E.jsxs)(`div`,{className:`noticePanel ${hn.status===`degraded`?`warnPanel`:`goodPanel`}`,children:[(0,E.jsxs)(`div`,{className:`cardHead compact`,children:[(0,E.jsxs)(`div`,{children:[(0,E.jsx)(`h4`,{children:`Snapshot maintenance`}),(0,E.jsx)(`p`,{className:`muted`,children:`Auto-warmup visibility for rebuild snapshot cache after node heartbeats.`})]}),(0,E.jsxs)(`div`,{className:`summaryChips`,children:[(0,E.jsx)(`span`,{className:`pill ${hn.status===`degraded`?`warn`:`good`}`,children:H(hn.status)}),(0,E.jsxs)(`span`,{className:hn.overdue_missing_snapshot_count>0?`pill bad`:`pill good`,children:[`overdue `,hn.overdue_missing_snapshot_count]}),(0,E.jsxs)(`span`,{className:hn.auto_warmup_error_count>0?`pill bad`:`pill good`,children:[`auto errors `,hn.auto_warmup_error_count]})]})]}),(0,E.jsxs)(`div`,{className:`stateList`,children:[(0,E.jsx)(A,{label:`reason`,value:H(hn.reason)}),(0,E.jsx)(A,{label:`snapshots`,value:`valid ${hn.valid_snapshot_count}, missing ${hn.missing_snapshot_count}, attempts ${hn.recent_attempt_count}`}),(0,E.jsx)(A,{label:`auto-warmup`,value:`events ${hn.auto_warmup_event_count}, warmed ${hn.auto_warmup_warmed_count}, fresh ${hn.auto_warmup_already_fresh_count}, latest ${V(hn.latest_auto_warmup_at)}`}),(0,E.jsx)(A,{label:`guard`,value:`age ${hn.min_age_seconds}s, heartbeats ${hn.heartbeat_threshold}`}),(0,E.jsx)(A,{label:`action`,value:hn.recommended_operator_action||`snapshot maintenance is current`})]}),(hn.nodes||[]).length>0&&(0,E.jsx)(N,{columns:[`node`,`snapshots`,`heartbeat`,`auto-warmup`,`latest`],rows:(hn.nodes||[]).slice(0,6).map(e=>[L(j,e.node_id),(0,E.jsxs)(`span`,{className:e.overdue_missing_snapshot_count>0?`pill bad`:e.missing_snapshot_count>0?`pill warn`:`pill good`,children:[e.valid_snapshot_count,`/`,e.recent_attempt_count,` overdue `,e.overdue_missing_snapshot_count]}),e.heartbeat_after_attempt_count,`${e.auto_warmup_warmed_count}/${e.auto_warmup_event_count} errors ${e.auto_warmup_error_count}`,V(e.latest_auto_warmup_at||e.last_heartbeat_at)])})]}),bn&&(0,E.jsxs)(`div`,{className:`noticePanel ${bn.status===`degraded`?`warnPanel`:`goodPanel`}`,children:[(0,E.jsxs)(`div`,{className:`cardHead compact`,children:[(0,E.jsxs)(`div`,{children:[(0,E.jsx)(`h4`,{children:`Service-channel leases`}),(0,E.jsx)(`p`,{className:`muted`,children:`Durable compatibility lease records for introspection after backend restarts.`})]}),(0,E.jsxs)(`div`,{className:`summaryChips`,children:[(0,E.jsx)(`span`,{className:`pill ${bn.status===`degraded`?`warn`:`good`}`,children:H(bn.status)}),(0,E.jsxs)(`span`,{className:`pill good`,children:[`active `,bn.active_count]}),(0,E.jsxs)(`span`,{className:bn.expired_count>0?`pill warn`:`pill`,children:[`expired `,bn.expired_count]}),(0,E.jsx)(`button`,{className:`ghost`,onClick:()=>void Ua(),disabled:Vr,children:`cleanup`})]})]}),(0,E.jsxs)(`div`,{className:`stateList`,children:[(0,E.jsx)(A,{label:`reason`,value:H(bn.reason)}),(0,E.jsx)(A,{label:`scanned`,value:`${bn.scanned_count}/${bn.window_limit}`}),(0,E.jsx)(A,{label:`deleted`,value:String(bn.deleted_expired_count||0)}),(0,E.jsx)(A,{label:`action`,value:bn.recommended_operator_action||`lease maintenance is current`})]}),(bn.leases||[]).length>0&&(0,E.jsx)(N,{columns:[`expires`,`resource`,`entry`,`exit`,`route`,`data plane`,`state`],rows:(bn.leases||[]).slice(0,8).map(e=>[V(e.expires_at),e.resource_id||B(e.channel_id),L(j,e.selected_entry_node_id||``),L(j,e.selected_exit_node_id||``),e.primary_route_id?`${B(e.primary_route_id)} / ${H(e.primary_route_status||``)}`:`backend fallback`,`${H(e.data_plane?.working_data_transport||`unknown`)} / ${H(e.data_plane?.backend_relay_policy||`unknown`)}`,(0,E.jsx)(`span`,{className:`pill ${e.expired||e.force_backend_fallback?`warn`:`good`}`,children:e.expired?`expired`:e.force_backend_fallback?`fallback`:H(e.status)})])})]}),R&&(0,E.jsxs)(`div`,{className:`noticePanel ${R.status===`degraded`?`warnPanel`:`goodPanel`}`,children:[(0,E.jsxs)(`div`,{className:`cardHead compact`,children:[(0,E.jsxs)(`div`,{children:[(0,E.jsx)(`h4`,{children:`Service-channel access`}),(0,E.jsx)(`p`,{className:`muted`,children:`Live accepted_by visibility from node telemetry and heartbeat metadata.`})]}),(0,E.jsxs)(`div`,{className:`summaryChips`,children:[(0,E.jsx)(`span`,{className:`pill ${R.status===`degraded`?`warn`:`good`}`,children:H(R.status)}),(0,E.jsxs)(`span`,{className:`pill good`,children:[`accepted `,R.total_accepted]}),(0,E.jsxs)(`span`,{className:R.backend_fallback_count>0?`pill warn`:`pill`,children:[`backend `,R.backend_fallback_count]}),(0,E.jsxs)(`span`,{className:(R.backend_fallback_blocked_count||0)>0?`pill bad`:`pill`,children:[`blocked `,R.backend_fallback_blocked_count||0]}),(0,E.jsxs)(`span`,{className:`pill ${R.last_working_data_transport===`fabric_service_channel`?`good`:R.data_plane_contract_count?`warn`:``}`,children:[`data-plane `,R.data_plane_contract_count||0]}),(0,E.jsxs)(`span`,{className:`pill ${R.last_backend_relay_policy===`disabled`?`good`:R.last_backend_relay_policy===`degraded_fallback_only`?`info`:``}`,children:[`relay `,H(R.last_backend_relay_policy||`unknown`)]}),(0,E.jsxs)(`span`,{className:R.degraded_fallback_channel_count>0||R.degraded_route_count>0?`pill warn`:`pill good`,children:[`channels `,R.active_channel_count]}),(0,E.jsxs)(`span`,{className:R.no_safe_recovery_decision_count?`pill warn`:R.route_decision_channel_count?`pill info`:`pill`,children:[`decisions `,R.route_decision_channel_count||0,R.replacement_decision_count?` / repl ${R.replacement_decision_count}`:``,R.applied_rebuild_decision_count?` / applied ${R.applied_rebuild_decision_count}`:``,R.recovery_decision_count?` / recovery ${R.recovery_decision_count}`:``,R.no_safe_recovery_decision_count?` / no-safe ${R.no_safe_recovery_decision_count}`:``]}),(0,E.jsx)(`span`,{className:`pill ${nr(R.flow_health_status,R.flow_dropped)}`,children:er(R.traffic_class_counts)}),(0,E.jsxs)(`span`,{className:`pill ${nr(R.flow_health_status,R.flow_dropped)}`,children:[`flow `,H(R.flow_health_status||`healthy`)]}),(0,E.jsxs)(`span`,{className:`pill ${R.adaptive_backpressure_active?`info`:`good`}`,children:[`windows `,tr(R.recommended_parallel_windows)]})]})]}),(0,E.jsxs)(`div`,{className:`stateList`,children:[(0,E.jsx)(A,{label:`reason`,value:H(R.reason)}),(0,E.jsx)(A,{label:`reporting nodes`,value:`${R.reporting_node_count}/${R.node_count}`}),(0,E.jsx)(A,{label:`accepted by`,value:`signed ${R.signed_accepted}, introspection ${R.introspection_accepted}, legacy ${R.legacy_unsigned_accepted}`}),(0,E.jsx)(A,{label:`data plane`,value:`${R.data_plane_contract_count||0} contracts, mode ${H(R.last_data_plane_mode||`unknown`)}, working ${H(R.last_working_data_transport||`unknown`)}, steady ${H(R.last_steady_state_transport||`unknown`)}, relay ${H(R.last_backend_relay_policy||`unknown`)}, flows ${H(R.last_logical_flow_mode||`unknown`)}, blocked ${R.backend_fallback_blocked_count||0}, route failures ${R.fabric_route_send_failure_count||0}`}),(0,E.jsx)(A,{label:`data-plane violation`,value:R.last_data_plane_violation_status?`${H(R.last_data_plane_violation_status)} / ${R.last_data_plane_violation_reason||`n/a`}`:`none`}),(0,E.jsx)(A,{label:`active channels`,value:`${R.active_channel_count||0}, fallback ${R.degraded_fallback_channel_count||0}, correlated routes ${R.correlated_route_count||0}, degraded routes ${R.degraded_route_count||0}`}),(0,E.jsx)(A,{label:`route decisions`,value:`channels ${R.route_decision_channel_count||0}, replacement ${R.replacement_decision_count||0}, applied ${R.applied_rebuild_decision_count||0}, recovery ${R.recovery_decision_count||0}, no-safe ${R.no_safe_recovery_decision_count||0}`}),(0,E.jsx)(A,{label:`flow QoS`,value:`${H(R.flow_health_status||`healthy`)} / ${H(R.flow_health_reason||`flow_health_ready`)}, ${er(R.traffic_class_counts)}, flows ${R.flow_channel_count||0}, in-flight ${R.flow_max_in_flight||0}, dropped ${R.flow_dropped||0}`}),(0,E.jsx)(A,{label:`adaptive windows`,value:`${R.adaptive_backpressure_active?H(R.adaptive_backpressure_reason||`adaptive`):`off`}, ${tr(R.recommended_parallel_windows)}, policy ${R.adaptive_policy_fingerprint?B(R.adaptive_policy_fingerprint):`n/a`}`}),(0,E.jsx)(A,{label:`latest accepted`,value:V(R.latest_accepted_at)}),(0,E.jsx)(A,{label:`action`,value:R.recommended_operator_action||`access telemetry is current`})]}),(R.active_channels||[]).length>0&&(0,E.jsx)(N,{columns:[`resource`,`entry -> exit`,`route`,`decision`,`entry access`,`data plane`,`flow health`,`windows`,`flow QoS`,`route quality`,`remediation`,`guard`,`execution`,`expires`],rows:(R.active_channels||[]).slice(0,10).map(e=>[e.resource_id||B(e.channel_id),`${L(j,e.selected_entry_node_id||``)} -> ${L(j,e.selected_exit_node_id||``)}`,e.primary_route_id?`${B(e.primary_route_id)} / ${H(e.primary_route_status||``)}`:`backend fallback`,(0,E.jsx)(`span`,{className:`pill ${ir(e.route_decision_source,e.route_decision_rebuild_status,e.route_decision_score_reasons)}`,children:e.route_decision_source?`${H(e.route_decision_source)}${e.route_decision_route_id?` ${B(e.route_decision_route_id)}`:``}${e.route_decision_replacement_route_id?` -> ${B(e.route_decision_replacement_route_id)}`:``}${e.route_decision_rebuild_status?` / ${H(e.route_decision_rebuild_status)}`:``}`:`n/a`}),`accepted ${e.entry_node_total_accepted}, introspection ${e.entry_node_introspection_accepted}, backend ${e.entry_node_backend_fallback_count}`,(0,E.jsx)(`span`,{className:`pill ${e.entry_node_last_working_data_transport===`fabric_service_channel`?`good`:e.entry_node_data_plane_contract_count?`warn`:``}`,children:`${e.entry_node_data_plane_contract_count||0} / ${H(e.entry_node_last_working_data_transport||`unknown`)} / ${H(e.entry_node_last_backend_relay_policy||`unknown`)}${e.entry_node_backend_fallback_blocked_count?` / blocked ${e.entry_node_backend_fallback_blocked_count}`:``}`}),(0,E.jsxs)(`span`,{className:`pill ${nr(e.entry_node_flow_health_status,e.entry_node_flow_dropped)}`,children:[H(e.entry_node_flow_health_status||`healthy`),e.entry_node_flow_health_reason?` / ${H(e.entry_node_flow_health_reason)}`:``]}),(0,E.jsx)(`span`,{className:`pill ${e.entry_node_adaptive_backpressure_active?`info`:`good`}`,children:tr(e.entry_node_recommended_parallel_windows)}),(0,E.jsxs)(`span`,{className:`pill ${nr(e.entry_node_flow_health_status,e.entry_node_flow_dropped)}`,children:[er(e.entry_node_traffic_class_counts),` / flows ${e.entry_node_flow_channel_count||0} / in ${e.entry_node_flow_max_in_flight||0}`]}),(0,E.jsx)(`span`,{className:`pill ${e.force_backend_fallback||e.route_feedback_status===`degraded`||e.route_feedback_status===`fenced`?`warn`:e.route_feedback_status?`good`:``}`,children:e.force_backend_fallback?`backend fallback`:e.route_feedback_status?`${H(e.route_feedback_status)} / ${e.last_send_duration_ms||0}ms / q ${e.route_quality_window_sample_count||0}`:`no route feedback`}),(0,E.jsx)(`span`,{className:`pill ${e.remediation_action===`none`?`good`:e.remediation_action===`prefer_alternate_route`?`warn`:e.remediation_action?`bad`:``}`,children:e.remediation_action?`${e.remediation_command?`cmd `:``}${H(e.remediation_action)}${e.remediation_command?.replacement_route_id?` -> ${B(e.remediation_command.replacement_route_id)}`:e.remediation_route_id?` -> ${B(e.remediation_route_id)}`:``}`:`n/a`}),(0,E.jsxs)(`span`,{className:`pill ${e.remediation_guard_status===`rejected`?`bad`:e.pool_policy_fingerprint?`good`:``}`,children:[e.remediation_guard_status?H(e.remediation_guard_status):e.pool_policy_fingerprint?`pool policy`:`n/a`,e.remediation_guard_reason?` / ${H(e.remediation_guard_reason)}`:``]}),(0,E.jsxs)(`span`,{className:`pill ${rr(e.remediation_execution_status)}`,children:[e.remediation_execution_status?H(e.remediation_execution_status):`n/a`,e.remediation_execution_generation?` / ${B(e.remediation_execution_generation)}`:``,e.remediation_execution_reason?` / ${H(e.remediation_execution_reason)}`:``]}),V(e.expires_at)])}),(R.nodes||[]).length>0&&(0,E.jsx)(N,{columns:[`node`,`accepted`,`signed`,`introspection`,`legacy`,`backend`,`data plane`,`flow health`,`windows`,`flow QoS`,`latest`],rows:(R.nodes||[]).slice(0,10).map(e=>[L(j,e.node_id)||e.node_name||B(e.node_id),e.total_accepted,e.signed_accepted,e.introspection_accepted,e.legacy_unsigned_accepted,(0,E.jsx)(`span`,{className:e.backend_fallback_count>0?`pill warn`:`pill`,children:e.backend_fallback_count}),(0,E.jsx)(`span`,{className:`pill ${e.last_working_data_transport===`fabric_service_channel`?`good`:e.data_plane_contract_count?`warn`:``}`,children:`${e.data_plane_contract_count||0} / ${H(e.last_working_data_transport||`unknown`)} / ${H(e.last_backend_relay_policy||`unknown`)}${e.backend_fallback_blocked_count?` / blocked ${e.backend_fallback_blocked_count}`:``}`}),(0,E.jsxs)(`span`,{className:`pill ${nr(e.flow_health_status,e.flow_dropped)}`,children:[H(e.flow_health_status||`healthy`),e.flow_health_reason?` / ${H(e.flow_health_reason)}`:``]}),(0,E.jsx)(`span`,{className:`pill ${e.adaptive_backpressure_active?`info`:`good`}`,children:tr(e.recommended_parallel_windows)}),(0,E.jsxs)(`span`,{className:`pill ${nr(e.flow_health_status,e.flow_dropped)}`,children:[er(e.traffic_class_counts),` / flows ${e.flow_channel_count||0} / in ${e.flow_max_in_flight||0}`]}),V(e.last_accepted_at||e.observed_at)])})]}),dn&&(0,E.jsxs)(`div`,{className:`noticePanel ${dn.status===`blocked`?`badPanel`:dn.status===`degraded`?`warnPanel`:`goodPanel`}`,children:[(0,E.jsxs)(`div`,{className:`cardHead compact`,children:[(0,E.jsxs)(`div`,{children:[(0,E.jsx)(`h4`,{children:`Fabric service-channel readiness`}),(0,E.jsx)(`p`,{className:`muted`,children:`Verdict for production service-channel use. Working service payloads should not depend on this fabric while the gate is blocked.`})]}),(0,E.jsxs)(`div`,{className:`summaryChips`,children:[(0,E.jsx)(`span`,{className:`pill ${dn.status===`blocked`?`bad`:dn.status===`degraded`?`warn`:`good`}`,children:H(dn.status)}),(0,E.jsxs)(`span`,{className:dn.active_alert_count>0?`pill bad`:`pill`,children:[`active `,dn.active_alert_count]}),(0,E.jsxs)(`span`,{className:dn.resurfaced_count>0?`pill bad`:`pill`,children:[`resurfaced `,dn.resurfaced_count]})]})]}),(0,E.jsxs)(`div`,{className:`stateList`,children:[(0,E.jsx)(A,{label:`reason`,value:H(dn.reason)}),(0,E.jsx)(A,{label:`blocking`,value:(dn.blocking_reasons||[]).map(H).join(`, `)||`нет`}),(0,E.jsx)(A,{label:`degraded`,value:(dn.degraded_reasons||[]).map(H).join(`, `)||`нет`}),(0,E.jsx)(A,{label:`missing/post`,value:`transition ${dn.missing_transition_count}, route-gen ${dn.missing_route_generation_count}, traffic ${dn.missing_post_rebuild_traffic_count}`})]})]}),Cn.length>0&&(0,E.jsxs)(`div`,{className:`subPanel`,children:[(0,E.jsxs)(`div`,{className:`cardHead compact`,children:[(0,E.jsxs)(`div`,{children:[(0,E.jsx)(`h4`,{children:`Rebuild incidents`}),(0,E.jsx)(`p`,{className:`muted`,children:`Grouped recent rebuild attempts by reporter, route, service, generation, and guard. Open an incident to load the exact deep ledger slice.`})]}),(0,E.jsx)(`span`,{className:`pill`,children:Cn.length})]}),(0,E.jsx)(N,{columns:[`last`,`source`,`reporter`,`route`,`service`,`guard`,`count`,`replacement`,`action`],rows:Cn.slice(0,10).map(e=>[V(e.last_seen_at),e.incident_source?H(e.incident_source):`ledger`,L(j,e.reporter_node_id),B(e.route_id),e.service_class,(0,E.jsxs)(`span`,{className:`pill ${e.alert_resurfaced||e.guard_severity===`bad`?`bad`:e.guard_severity===`warn`?`warn`:`good`}`,children:[H(e.guard_status),e.alert_silenced?` / silenced`:e.alert_resurfaced?` / resurfaced`:``]}),String(e.attempt_count),e.latest_replacement_route_id?B(e.latest_replacement_route_id):`нет`,(0,E.jsxs)(`div`,{className:`inlineActions`,children:[(0,E.jsxs)(`span`,{children:[H(e.recommended_operator_action||`inspect`),e.alert_resurfaced&&e.alert_resurfaced_cause?` (${H(e.alert_resurfaced_cause)})`:``,e.alert_resurfaced&&e.alert_resurfaced_previous_generation?` from ${B(e.alert_resurfaced_previous_generation)} until ${V(e.alert_resurfaced_previous_until)}`:``]}),(0,E.jsx)(`button`,{type:`button`,className:`ghost`,onClick:()=>void Y(()=>Wa(e),`Deep rebuild investigation opened.`),children:`open deep`}),e.alert_silenced?(0,E.jsx)(`span`,{className:`muted`,children:`silenced`}):(0,E.jsx)(`button`,{type:`button`,className:`ghost`,onClick:()=>void Y(()=>Ya(e),`Rebuild incident silenced for 6 hours.`),children:`silence 6h`})]})])})]}),(Nn||Fa.length>0)&&(0,E.jsxs)(`div`,{className:`subPanel`,children:[(0,E.jsxs)(`div`,{className:`cardHead compact`,children:[(0,E.jsxs)(`div`,{children:[(0,E.jsx)(`h4`,{children:`Recent investigations`}),(0,E.jsx)(`p`,{className:`muted`,children:`Recent operator drilldowns opened from rebuild incidents or feedback breakdown rows.`})]}),(0,E.jsxs)(`div`,{className:`summaryChips`,children:[(0,E.jsx)(`span`,{className:`pill info`,children:jr?.total_count||Fa.length}),(0,E.jsxs)(`span`,{className:`pill good`,children:[`linked `,jr?.correlated_count||0]}),(0,E.jsxs)(`span`,{className:(jr?.not_visible_count||0)>0?`pill warn`:`pill`,children:[`not visible `,jr?.not_visible_count||0]}),Object.entries(jr?.counts_by_breadcrumb_status||{}).map(([e,t])=>(0,E.jsxs)(`span`,{className:e===`current`?`pill good`:e===`stale`?`pill warn`:`pill bad`,children:[H(e),` `,t]},e)),Object.entries(jr?.counts_by_current_diagnostic_status||{}).slice(0,3).map(([e,t])=>(0,E.jsxs)(`span`,{className:e===`breakdown_active`||e===`incident_visible`?`pill good`:e===`not_visible`?`pill warn`:`pill`,children:[H(e),` `,t]},e))]})]}),Nn&&(0,E.jsxs)(`div`,{className:`inlineForm`,children:[(0,E.jsxs)(`label`,{children:[`current window, sec`,(0,E.jsx)(`input`,{type:`number`,min:`60`,value:ti.currentWindowSeconds,onChange:e=>ni(t=>({...t,currentWindowSeconds:e.target.value}))})]}),(0,E.jsxs)(`label`,{children:[`history window, sec`,(0,E.jsx)(`input`,{type:`number`,min:`60`,value:ti.historyWindowSeconds,onChange:e=>ni(t=>({...t,historyWindowSeconds:e.target.value}))})]}),(0,E.jsx)(`button`,{type:`button`,className:`ghost`,onClick:()=>void Y(async()=>{Ln(await q.updateFabricServiceChannelBreadcrumbWindowPolicy(T,{currentWindowSeconds:Number(ti.currentWindowSeconds),historyWindowSeconds:Number(ti.historyWindowSeconds)}));let e=await q.getFabricServiceChannelRebuildInvestigationBreadcrumbs(T,{limit:20});Ar(e.events),Mr(e.summary||null)},`Breadcrumb window policy updated.`),children:`apply windows`}),(0,E.jsxs)(`span`,{className:`muted`,children:[`source `,Nn.source,`, fp `,B(Nn.fingerprint||``)]})]}),jr&&(0,E.jsxs)(`div`,{className:`stateList`,children:[(0,E.jsx)(A,{label:`latest`,value:V(jr.latest_at)}),(0,E.jsx)(A,{label:`windows`,value:`${Nn?.current_window_seconds||`n/a`}s current / ${Nn?.history_window_seconds||`n/a`}s history`}),(0,E.jsx)(A,{label:`sources`,value:Object.entries(jr.counts_by_feedback_source||{}).slice(0,3).map(([e,t])=>`${H(e)} ${t}`).join(`, `)||`нет`}),(0,E.jsx)(A,{label:`violations`,value:Object.entries(jr.counts_by_feedback_violation_status||{}).slice(0,3).map(([e,t])=>`${H(e)} ${t}`).join(`, `)||`нет`})]}),(0,E.jsx)(N,{columns:[`time`,`freshness`,`source`,`feedback`,`target`,`current`,`actor`,`reason`],rows:Fa.map(e=>{let t=F(e.payload)||{},n=I(t,`feedback_channel_id`,``),r=I(t,`feedback_violation_status`,``),i=I(t,`feedback_source`,``),a=I(t,`reporter_node_id`,``),o=I(t,`route_id`,``),s=I(t,`drilldown_source`,``),c=e.correlation_hints?.current_diagnostic_status||``,l=e.correlation_hints?.breadcrumb_status||`current`,u=e.correlation_hints?.breadcrumb_age_seconds,d=e.correlation_hints?.feedback_breakdown||Ka(e),f=e.correlation_hints?.rebuild_incident||qa(e);return[V(e.created_at),(0,E.jsxs)(`div`,{className:`stackedText`,children:[(0,E.jsx)(`span`,{className:l===`current`?`pill good`:l===`stale`?`pill warn`:`pill bad`,children:H(l)}),(0,E.jsx)(`span`,{className:`muted`,children:Xn(u)})]}),(0,E.jsxs)(`div`,{className:`stackedText`,children:[(0,E.jsx)(`span`,{children:e.event_type.includes(`feedback_breakdown`)?`feedback breakdown`:`incident`}),(0,E.jsx)(`span`,{className:`muted`,children:H(s||e.target_type)})]}),i||n||r?(0,E.jsxs)(`div`,{className:`stackedText`,children:[(0,E.jsx)(`span`,{children:H(i||`feedback`)}),(0,E.jsx)(`span`,{className:`muted`,children:n?`ch ${B(n)}`:`any channel`}),(0,E.jsx)(`span`,{className:`muted`,children:H(r||`any violation`)})]}):(0,E.jsx)(`span`,{className:`muted`,children:`нет`}),(0,E.jsxs)(`div`,{className:`stackedText`,children:[(0,E.jsx)(`span`,{children:a?L(j,a):`any reporter`}),(0,E.jsx)(`span`,{className:`muted`,children:o?B(o):e.target_id?B(e.target_id):`any route`})]}),d?(0,E.jsxs)(`div`,{className:`inlineActions`,children:[(0,E.jsx)(`span`,{className:d.active_bad_count?`pill bad`:d.active_warn_count?`pill warn`:`pill good`,children:H(c||`breakdown_active`)}),(0,E.jsxs)(`span`,{className:`muted`,children:[`bad `,d.active_bad_count||0,` / warn `,d.active_warn_count||0]}),(0,E.jsx)(`button`,{type:`button`,className:`ghost`,onClick:()=>void Y(()=>Ja(d),`Rebuild ledger opened for current feedback breakdown.`),children:`open`})]}):f?(0,E.jsxs)(`div`,{className:`inlineActions`,children:[(0,E.jsx)(`span`,{className:`pill ${f.guard_severity===`bad`?`bad`:f.guard_severity===`warn`?`warn`:`good`}`,children:H(c||`incident_visible`)}),(0,E.jsx)(`span`,{className:`muted`,children:H(f.guard_status)}),(0,E.jsx)(`button`,{type:`button`,className:`ghost`,onClick:()=>void Y(()=>Wa(f),`Deep rebuild investigation opened for current incident.`),children:`open`})]}):(0,E.jsx)(`span`,{className:`muted`,children:H(c||`not_visible`)}),e.actor_user_id?B(e.actor_user_id):`system`,I(t,`reason`,`operator opened investigation`)]})})]}),$t.length>0&&(0,E.jsxs)(`div`,{className:`subPanel`,children:[(0,E.jsxs)(`div`,{className:`cardHead compact`,children:[(0,E.jsxs)(`div`,{children:[(0,E.jsx)(`h4`,{children:`Active rebuild silences`}),(0,E.jsx)(`p`,{className:`muted`,children:`Operator acknowledgements currently suppressing rebuild/access-decision alerts. Remove a silence to let the incident become active again.`})]}),(0,E.jsx)(`span`,{className:`pill info`,children:$t.length})]}),(0,E.jsx)(N,{columns:[`until`,`source`,`channel`,`reporter`,`route`,`guard`,`reason`,`action`],rows:$t.slice(0,10).map(e=>[V(e.expires_at),e.incident_source?H(e.incident_source):`ledger`,e.channel_id?B(e.channel_id):`нет`,L(j,e.reporter_node_id),B(e.display_route_id||e.route_id),H(e.guard_status),e.reason||`acknowledged`,(0,E.jsx)(`button`,{type:`button`,className:`ghost`,onClick:()=>void Y(()=>Xa(e),`Rebuild alert silence removed.`),children:`unsilence`})])})]}),Jt&&(0,E.jsxs)(`div`,{className:`subPanel`,children:[(0,E.jsxs)(`div`,{className:`cardHead compact`,children:[(0,E.jsxs)(`div`,{children:[(0,E.jsx)(`h4`,{children:`Rebuild health`}),(0,E.jsxs)(`p`,{className:`muted`,children:[`Сводка по последним `,Jt.total_attempts,` rebuild попыткам. Данные помогают быстро увидеть, где backend уже принял решение, но node-agent или post-rebuild traffic не подтвердили результат.`]})]}),(0,E.jsxs)(`div`,{className:`summaryChips`,children:[(0,E.jsxs)(`span`,{className:`pill good`,children:[`ok `,Jt.good_count]}),(0,E.jsxs)(`span`,{className:Jt.active_warn_count>0?`pill warn`:`pill`,children:[`warn `,Jt.active_warn_count,`/`,Jt.warn_count]}),(0,E.jsxs)(`span`,{className:Jt.active_bad_count>0?`pill bad`:`pill`,children:[`bad `,Jt.active_bad_count,`/`,Jt.bad_count]}),(0,E.jsxs)(`span`,{className:Jt.resurfaced_count>0?`pill bad`:`pill`,children:[`resurfaced `,Jt.resurfaced_count]}),(0,E.jsxs)(`span`,{className:Jt.silenced_count>0?`pill info`:`pill`,children:[`silenced `,Jt.silenced_count]}),(0,E.jsxs)(`span`,{className:`pill`,children:[`applied `,Jt.applied_count]}),(0,E.jsxs)(`span`,{className:Jt.access_no_safe_count?`pill bad`:Jt.access_route_decision_count?`pill info`:`pill`,children:[`access `,Jt.access_route_decision_count||0,Jt.access_no_safe_count?` / no-safe ${Jt.access_no_safe_count}`:``]})]})]}),(0,E.jsxs)(`div`,{className:`stateList`,children:[(0,E.jsx)(A,{label:`observed`,value:V(Jt.observed_at)}),(0,E.jsx)(A,{label:`affected nodes`,value:(Jt.affected_reporter_node_ids||[]).map(e=>L(j,e)).join(`, `)||`нет`}),(0,E.jsx)(A,{label:`affected routes`,value:(Jt.affected_route_ids||[]).map(B).join(`, `)||`нет`}),(0,E.jsx)(A,{label:`action`,value:H(Jt.recommended_operator_action||`no_operator_action_required`)})]}),(Jt.feedback_breakdowns||[]).length>0&&(0,E.jsx)(N,{columns:[`feedback`,`active`,`total`,`affected`,`incidents`,`latest`,`action`],rows:(Jt.feedback_breakdowns||[]).slice(0,8).map(e=>{let t=Ga(e);return[(0,E.jsxs)(`div`,{className:`stackedText`,children:[(0,E.jsx)(`span`,{children:H(e.feedback_source||`feedback`)}),(0,E.jsx)(`span`,{className:`muted`,children:e.feedback_channel_id?`ch ${B(e.feedback_channel_id)}`:`any channel`}),(0,E.jsx)(`span`,{className:`muted`,children:H(e.feedback_violation_status||`unknown`)})]}),(0,E.jsxs)(`span`,{className:e.active_bad_count?`pill bad`:e.active_warn_count?`pill warn`:`pill`,children:[`bad `,e.active_bad_count||0,` / warn `,e.active_warn_count||0]}),`total ${e.total_count} / bad ${e.bad_count||0} / warn ${e.warn_count||0} / silenced ${e.silenced_count||0}`,(0,E.jsxs)(`div`,{className:`stackedText`,children:[(0,E.jsx)(`span`,{children:(e.affected_reporter_node_ids||[]).map(e=>L(j,e)).join(`, `)||`нет узлов`}),(0,E.jsx)(`span`,{className:`muted`,children:(e.affected_route_ids||[]).map(B).join(`, `)||`нет routes`})]}),t.length>0?(0,E.jsxs)(`div`,{className:`stackedText`,children:[(0,E.jsx)(`span`,{className:`pill warn`,children:t.length}),(0,E.jsx)(`span`,{className:`muted`,children:t.slice(0,2).map(e=>H(e.guard_status)).join(`, `)})]}):(0,E.jsx)(`span`,{className:`muted`,children:`нет`}),V(e.latest_observed_at),(0,E.jsx)(`button`,{type:`button`,className:`ghost`,onClick:()=>void Y(()=>Ja(e),`Rebuild ledger opened for feedback breakdown.`),children:`open ledger`})]})}),(Jt.most_recent_bad_attempts||[]).length>0&&(0,E.jsx)(N,{columns:[`time`,`reporter`,`route`,`guard`,`reason`],rows:(Jt.most_recent_bad_attempts||[]).slice(0,5).map(e=>[V(e.updated_at),L(j,e.reporter_node_id),B(e.route_id),(0,E.jsx)(`span`,{className:`pill bad`,children:H(e.guard_status||`bad`)}),(0,E.jsxs)(`div`,{className:`inlineActions`,children:[(0,E.jsx)(`span`,{children:H(e.guard_reason||`unknown`)}),(0,E.jsx)(`button`,{type:`button`,className:`ghost`,onClick:()=>void Y(()=>q.silenceFabricServiceChannelRouteRebuildAlert(T,{reporterNodeId:e.reporter_node_id,routeId:e.route_id,guardStatus:e.guard_status||`unknown`,generation:e.generation||``,reason:`operator acknowledged known rebuild alert`,ttlSeconds:21600}),`Rebuild alert silenced for this route generation.`),children:`silence 6h`})]})])}),(Jt.resurfaced_attempts||[]).length>0&&(0,E.jsx)(N,{columns:[`time`,`reporter`,`route`,`guard`,`previous`,`action`],rows:(Jt.resurfaced_attempts||[]).slice(0,5).map(e=>[V(e.updated_at),L(j,e.reporter_node_id),B(e.route_id),(0,E.jsx)(`span`,{className:`pill bad`,children:H(e.guard_status||`bad`)}),`${B(e.alert_resurfaced_previous_generation)} until ${V(e.alert_resurfaced_previous_until)}`,(0,E.jsxs)(`div`,{className:`inlineActions`,children:[(0,E.jsx)(`span`,{children:H(e.guard_reason||`unknown`)}),(0,E.jsx)(`button`,{type:`button`,className:`ghost`,onClick:()=>void Y(()=>q.silenceFabricServiceChannelRouteRebuildAlert(T,{reporterNodeId:e.reporter_node_id,routeId:e.route_id,guardStatus:e.guard_status||`unknown`,generation:e.generation||``,reason:`operator acknowledged resurfaced rebuild alert`,ttlSeconds:21600}),`Resurfaced rebuild alert silenced for this generation.`),children:`silence 6h`})]})])})]}),jn&&(0,E.jsxs)(`div`,{className:`inlineForm`,children:[(0,E.jsxs)(`label`,{children:[`penalty`,(0,E.jsx)(`input`,{type:`number`,min:`0`,value:$r.hysteresisPenalty,onChange:e=>ei(t=>({...t,hysteresisPenalty:e.target.value}))})]}),(0,E.jsxs)(`label`,{children:[`promote samples`,(0,E.jsx)(`input`,{type:`number`,min:`1`,value:$r.promotionMinSamples,onChange:e=>ei(t=>({...t,promotionMinSamples:e.target.value}))})]}),(0,E.jsxs)(`label`,{children:[`fail`,(0,E.jsx)(`input`,{type:`number`,min:`1`,value:$r.demotionFailureThreshold,onChange:e=>ei(t=>({...t,demotionFailureThreshold:e.target.value}))})]}),(0,E.jsxs)(`label`,{children:[`drop`,(0,E.jsx)(`input`,{type:`number`,min:`1`,value:$r.demotionDropThreshold,onChange:e=>ei(t=>({...t,demotionDropThreshold:e.target.value}))})]}),(0,E.jsxs)(`label`,{children:[`slow`,(0,E.jsx)(`input`,{type:`number`,min:`1`,value:$r.demotionSlowThreshold,onChange:e=>ei(t=>({...t,demotionSlowThreshold:e.target.value}))})]}),(0,E.jsxs)(`label`,{className:`checkLine`,children:[(0,E.jsx)(`input`,{type:`checkbox`,checked:$r.demotionRebuildEnabled,onChange:e=>ei(t=>({...t,demotionRebuildEnabled:e.target.checked}))}),`rebuild`]}),(0,E.jsxs)(`label`,{className:`checkLine`,children:[(0,E.jsx)(`input`,{type:`checkbox`,checked:$r.demotionFencedEnabled,onChange:e=>ei(t=>({...t,demotionFencedEnabled:e.target.checked}))}),`fenced`]}),(0,E.jsx)(`button`,{type:`button`,className:`ghost`,onClick:()=>void Y(async()=>{Mn(await q.updateFabricServiceChannelRecoveryPolicy(T,{hysteresisPenalty:Number($r.hysteresisPenalty),promotionMinSamples:Number($r.promotionMinSamples),demotionFailureThreshold:Number($r.demotionFailureThreshold),demotionDropThreshold:Number($r.demotionDropThreshold),demotionSlowThreshold:Number($r.demotionSlowThreshold),demotionRebuildEnabled:$r.demotionRebuildEnabled,demotionFencedEnabled:$r.demotionFencedEnabled}))},`Recovery policy updated.`),children:`apply policy`}),(0,E.jsxs)(`span`,{className:`muted`,children:[`source `,jn.source]})]}),(0,E.jsx)(N,{columns:[`route`,`reporter`,`service`,`status`,`recovery`,`score`,`reasons`,`failures`,`retry/cooldown`,`expires`,`action`],rows:bo.slice(0,80).map(e=>[B(e.route_id),L(j,e.reporter_node_id),e.service_class,(0,E.jsx)(`span`,{className:`pill ${dt(e.feedback_status)}`,children:H(e.feedback_status)}),e.recovery_state?(0,E.jsxs)(`span`,{className:`pill ${ft(e.recovery_state)}`,children:[e.recovery_demoted?`demoted ${e.recovery_reason?H(e.recovery_reason):``}`:e.recovery_promoted?`promoted`:H(e.recovery_state),e.recovery_hysteresis_penalty?` -${e.recovery_hysteresis_penalty}`:``]}):e.stale_policy||e.stale_generation?(0,E.jsx)(`span`,{className:`pill warn`,children:H(e.stale_reason||`stale`)}):e.provenance_missing?(0,E.jsx)(`span`,{className:`pill warn`,children:`provenance missing`}):`нет`,String(e.score_adjustment),(e.reasons||[]).join(`, `)||`нет`,String(e.consecutive_failures||0),e.retry_cooldown_until?V(e.retry_cooldown_until):`нет`,V(e.expires_at),e.feedback_status===`healthy`||e.feedback_status===`operator_retry_cooldown`?(0,E.jsx)(`span`,{className:`muted`,children:`нет`}):(0,E.jsx)(`button`,{type:`button`,className:`ghost`,onClick:()=>void Y(()=>q.expireFabricServiceChannelRouteFeedback(T,{routeId:e.route_id,reporterNodeId:e.reporter_node_id,serviceClass:e.service_class,reason:`operator expired stale service-channel feedback`}),`Service-channel feedback expired.`),children:`expire`})])}),bo.length===0&&(0,E.jsx)(ye,{title:`Feedback отсутствует`,text:`Нет свежих route feedback наблюдений от fabric service-channel runtime.`}),(0,E.jsx)(N,{columns:[`local node`,`route`,`replacement`,`rebuild`,`attempt`,`feedback`,`source`,`destination`,`decision`,`score`,`expires`],rows:[...Ao,...ko,...jo].filter((e,t,n)=>n.findIndex(t=>t.decision_id===e.decision_id)===t).slice(0,80).map(e=>[L(j,e.local_node_id),B(e.route_id),e.replacement_route_id?B(e.replacement_route_id):`нет`,e.rebuild_status||`нет`,e.rebuild_attempt==null?`н/д`:String(e.rebuild_attempt),e.feedback_observation_id?(0,E.jsxs)(`div`,{className:`stackedText`,children:[(0,E.jsx)(`span`,{children:H(e.feedback_source||`feedback`)}),(0,E.jsxs)(`span`,{className:`muted`,children:[B(e.feedback_observation_id),` `,e.feedback_channel_id?`ch ${B(e.feedback_channel_id)}`:``]}),(0,E.jsx)(`span`,{className:`muted`,children:H(e.feedback_violation_status||``)})]}):`нет`,L(j,e.source_node_id),L(j,e.destination_node_id),e.decision_source,e.path_score==null?`н/д`:String(e.path_score),V(e.expires_at)])}),(0,E.jsxs)(`div`,{className:`inlineForm`,children:[(0,E.jsxs)(`label`,{children:[`reporter`,(0,E.jsxs)(`select`,{value:En.reporterNodeId,onChange:e=>Dn(t=>({...t,reporterNodeId:e.target.value,offset:0})),children:[(0,E.jsx)(`option`,{value:``,children:`all`}),j.map(e=>(0,E.jsx)(`option`,{value:e.id,children:e.name},e.id))]})]}),(0,E.jsxs)(`label`,{children:[`route`,(0,E.jsx)(`input`,{value:En.routeId,onChange:e=>Dn(t=>({...t,routeId:e.target.value.trim(),offset:0})),placeholder:`route id`})]}),(0,E.jsxs)(`label`,{children:[`generation`,(0,E.jsx)(`input`,{value:En.generation,onChange:e=>Dn(t=>({...t,generation:e.target.value.trim(),offset:0})),placeholder:`route generation`})]}),(0,E.jsxs)(`label`,{children:[`service`,(0,E.jsx)(`input`,{value:En.serviceClass,onChange:e=>Dn(t=>({...t,serviceClass:e.target.value.trim(),offset:0})),placeholder:`vpn_packets`})]}),(0,E.jsxs)(`label`,{children:[`feedback source`,(0,E.jsx)(`input`,{value:En.feedbackSource,onChange:e=>Dn(t=>({...t,feedbackSource:e.target.value.trim(),offset:0})),placeholder:`fabric_service_channel_access_report`})]}),(0,E.jsxs)(`label`,{children:[`channel`,(0,E.jsx)(`input`,{value:En.feedbackChannelId,onChange:e=>Dn(t=>({...t,feedbackChannelId:e.target.value.trim(),offset:0})),placeholder:`feedback channel id`})]}),(0,E.jsxs)(`label`,{children:[`violation`,(0,E.jsx)(`input`,{value:En.feedbackViolationStatus,onChange:e=>Dn(t=>({...t,feedbackViolationStatus:e.target.value.trim(),offset:0})),placeholder:`fabric_route_send_failed_backend_fallback_blocked`})]}),(0,E.jsx)(`button`,{type:`button`,className:`ghost`,onClick:()=>void Ba(Tn,{...En,offset:0}),children:`apply`}),(0,E.jsx)(`button`,{type:`button`,className:`ghost`,onClick:()=>{let e={...ie};Dn(e),Ba(!1,e)},children:`clear`})]}),(0,E.jsx)(N,{columns:[`time`,`reporter`,`route`,`replacement`,`feedback`,`guard`,`outcome`,`backend`,`agent`,`route-gen`,`traffic`,`policy`,`hops`],rows:It.slice(0,80).map(e=>[V(e.updated_at),L(j,e.reporter_node_id),B(e.route_id),e.replacement_route_id?B(e.replacement_route_id):`нет`,e.feedback_observation_id?(0,E.jsxs)(`div`,{className:`stackedText`,children:[(0,E.jsx)(`span`,{children:H(e.feedback_source||`feedback`)}),(0,E.jsxs)(`span`,{className:`muted`,children:[B(e.feedback_observation_id),` `,e.feedback_channel_id?`ch ${B(e.feedback_channel_id)}`:``]}),(0,E.jsx)(`span`,{className:`muted`,children:H(e.feedback_violation_status||``)})]}):e.feedback_status?H(e.feedback_status):`нет`,Tn?(0,E.jsxs)(`span`,{className:`pill ${e.guard_severity===`bad`?`bad`:e.guard_severity===`warn`?`warn`:`good`}`,children:[H(e.guard_status||`unknown`),e.alert_silenced?` / silenced`:e.alert_resurfaced?` / resurfaced`:``]}):(0,E.jsx)(`span`,{className:`pill info`,children:`summary`}),H(e.outcome),(0,E.jsx)(`span`,{className:`pill ${e.rebuild_status===`applied`?`good`:`warn`}`,children:H(e.rebuild_status)}),Tn?e.node_transition_matched?(0,E.jsx)(`span`,{className:`pill ${e.node_transition_status===`applied_rebuild`?`good`:`warn`}`,children:H(e.node_transition_status||`matched`)}):(0,E.jsx)(`span`,{className:`pill warn`,children:`not seen`}):(0,E.jsx)(`span`,{className:`pill info`,children:`deep only`}),Tn?e.node_route_generation_matched?(0,E.jsx)(`span`,{className:`pill good`,children:H(e.node_route_generation_status||`seen`)}):(0,E.jsx)(`span`,{className:`pill warn`,children:`not seen`}):(0,E.jsx)(`span`,{className:`pill info`,children:`deep only`}),Tn?e.post_rebuild_selected_route_id?`${B(e.post_rebuild_selected_route_id)} packets ${e.post_rebuild_send_flow_packets||e.post_rebuild_send_packets||0} drop ${e.post_rebuild_send_flow_dropped||0}`:`нет`:`deep only`,e.policy_fingerprint?B(e.policy_fingerprint):`нет`,`${(e.old_hops||[]).map(e=>L(j,e)).join(` -> `)||`нет`} => ${(e.replacement_hops||[]).map(e=>L(j,e)).join(` -> `)||`нет`}`])}),(0,E.jsxs)(`div`,{className:`inlineActions`,children:[(0,E.jsx)(`button`,{type:`button`,className:`ghost`,onClick:()=>void Ba(!Tn,{...En,offset:0}),children:Tn?`fast ledger`:`deep ledger`}),(0,E.jsx)(`button`,{type:`button`,className:`ghost`,disabled:!Tn||En.offset<=0,onClick:()=>void Ba(!0,{...En,offset:Math.max(0,En.offset-20)}),children:`prev`}),(0,E.jsx)(`button`,{type:`button`,className:`ghost`,disabled:!Tn||It.length<20,onClick:()=>void Ba(!0,{...En,offset:En.offset+20}),children:`next`}),(0,E.jsxs)(`span`,{className:`pill`,children:[`offset `,Tn?En.offset:0]}),(0,E.jsx)(`span`,{className:`muted`,children:`Deep ledger correlates heartbeat timeline and can be slower; default refresh stays fast.`})]}),It.length===0&&(0,E.jsx)(ye,{title:`Rebuild ledger пуст`,text:`Пока нет долговечной истории service-channel route rebuild решений.`})]}),(0,E.jsxs)(`article`,{className:`card span2`,children:[(0,E.jsx)(`h3`,{children:J.servicePlacement}),(0,E.jsx)(N,{columns:[`узел`,`runtime`,`адрес`,`здоровье`,`роли`,`желаемые / reported сервисы`,`последний heartbeat`],rows:j.map(e=>{let t=Dt(e,st[e.id]||[],bt);return[e.name,(0,E.jsx)(we,{runtime:t}),t.address,e.health_status,tt(Je[e.id]||[]),it(nt[e.id]||[]),V((st[e.id]||[])[0]?.observed_at||e.last_seen_at)]})})]}),(0,E.jsxs)(`article`,{className:`card`,children:[(0,E.jsx)(`h3`,{children:J.trafficFlow}),(0,E.jsx)(N,{columns:[`источник`,`цель`,`тип`,`route/path`,`статус`,`задержка`,`качество`,`наблюдение`],rows:yt(bt).filter(e=>e.source_node_id!==e.target_node_id).map(e=>{let t=j.find(t=>t.id===e.source_node_id),n=j.find(t=>t.id===e.target_node_id);return[(0,E.jsx)(Te,{node:t,fallback:L(j,e.source_node_id),heartbeatsByNode:st,meshLinks:bt}),(0,E.jsx)(Te,{node:n,fallback:L(j,e.target_node_id),heartbeatsByNode:st,meshLinks:bt}),xt(e),St(e,j),e.link_status,e.latency_ms==null?`н/д`:`${e.latency_ms} мс`,e.quality_score==null?`н/д`:`${e.quality_score}/100`,V(e.observed_at)]})})]}),(0,E.jsxs)(`article`,{className:`card`,children:[(0,E.jsx)(`h3`,{children:`Политики QoS`}),(0,E.jsx)(N,{columns:[`класс`,`приоритет`,`надежность`,`политика сброса`],rows:Rn.map(e=>[e.service_class,String(e.priority),e.reliability_mode,e.drop_policy])})]})]}),C===`vpn`&&(0,E.jsxs)(`section`,{className:`grid two`,children:[(0,E.jsxs)(`article`,{className:`card`,children:[(0,E.jsx)(`h3`,{children:`Создать желаемое состояние VPN-подключения`}),(0,E.jsx)(`p`,{className:`muted`,children:`Только Control/API слой. Здесь не выполняются TUN/TAP, маршруты, DNS, firewall, QoS или packet forwarding.`}),(0,E.jsxs)(Qe,{children:[(0,E.jsxs)(`label`,{children:[`ID организации`,(0,E.jsx)(`input`,{value:G.organizationId,onChange:e=>Vi({...G,organizationId:e.target.value})})]}),(0,E.jsxs)(`label`,{children:[`Название`,(0,E.jsx)(`input`,{value:G.name,onChange:e=>Vi({...G,name:e.target.value})})]}),(0,E.jsxs)(`label`,{children:[`Протокол`,(0,E.jsxs)(`select`,{value:G.protocolFamily,onChange:e=>Vi({...G,protocolFamily:e.target.value}),children:[(0,E.jsx)(`option`,{value:`generic`,children:`generic`}),(0,E.jsx)(`option`,{value:`wireguard`,children:`wireguard`}),(0,E.jsx)(`option`,{value:`ipsec`,children:`ipsec`}),(0,E.jsx)(`option`,{value:`openvpn`,children:`openvpn`})]})]}),(0,E.jsxs)(`label`,{children:[`Желаемое состояние`,(0,E.jsxs)(`select`,{value:G.desiredState,onChange:e=>Vi({...G,desiredState:e.target.value}),children:[(0,E.jsx)(`option`,{value:`disabled`,children:`выключено`}),(0,E.jsx)(`option`,{value:`enabled`,children:`включено`})]})]}),(0,E.jsxs)(`label`,{children:[`Ссылка на credential`,(0,E.jsx)(`input`,{value:G.credentialRef,onChange:e=>Vi({...G,credentialRef:e.target.value})})]})]}),(0,E.jsxs)(`label`,{children:[`Целевой endpoint JSON`,(0,E.jsx)(`textarea`,{value:G.targetEndpointJson,onChange:e=>Vi({...G,targetEndpointJson:e.target.value})})]}),(0,E.jsxs)(`label`,{children:[`Политика разрешенных узлов JSON`,(0,E.jsx)(`textarea`,{value:G.allowedNodePolicyJson,onChange:e=>Vi({...G,allowedNodePolicyJson:e.target.value})})]}),(0,E.jsxs)(`details`,{children:[(0,E.jsx)(`summary`,{children:`Расширенные routing / QoS / placement JSON`}),(0,E.jsxs)(`label`,{children:[`Использование маршрутизации JSON`,(0,E.jsx)(`textarea`,{value:G.routingUsageJson,onChange:e=>Vi({...G,routingUsageJson:e.target.value})})]}),(0,E.jsxs)(`label`,{children:[`Политика маршрута JSON`,(0,E.jsx)(`textarea`,{value:G.routePolicyJson,onChange:e=>Vi({...G,routePolicyJson:e.target.value})})]}),(0,E.jsxs)(`label`,{children:[`Политика QoS JSON`,(0,E.jsx)(`textarea`,{value:G.qosPolicyJson,onChange:e=>Vi({...G,qosPolicyJson:e.target.value})})]}),(0,E.jsxs)(`label`,{children:[`Политика размещения JSON`,(0,E.jsx)(`textarea`,{value:G.placementPolicyJson,onChange:e=>Vi({...G,placementPolicyJson:e.target.value})})]})]}),(0,E.jsx)(`button`,{className:`primary`,disabled:!T||!G.organizationId||!G.name,onClick:()=>void Y(()=>q.createVPNConnection(T,{organizationId:G.organizationId,name:G.name,protocolFamily:G.protocolFamily,credentialRef:G.credentialRef||null,desiredState:G.desiredState,targetEndpoint:$e(G.targetEndpointJson,`target endpoint`),allowedNodePolicy:$e(G.allowedNodePolicyJson,`allowed node policy`),routingUsage:et(G.routingUsageJson,`routing usage`),routePolicy:$e(G.routePolicyJson,`route policy`),qosPolicy:$e(G.qosPolicyJson,`qos policy`),placementPolicy:$e(G.placementPolicyJson,`placement policy`)}),`Желаемое состояние VPN создано.`),children:`Создать желаемое состояние VPN`})]}),(0,E.jsxs)(`article`,{className:`card`,children:[(0,E.jsxs)(`div`,{className:`cardHead`,children:[(0,E.jsxs)(`div`,{children:[(0,E.jsx)(`h3`,{children:`VPN-подключения`}),(0,E.jsx)(`p`,{className:`muted`,children:`Cluster-managed состояние, gateway packet stats и диагностика Android-клиента.`})]}),(0,E.jsxs)(`div`,{className:`actions compactActions`,children:[(0,E.jsx)(`button`,{onClick:()=>void Y(async()=>{Kr(`Истекшие VPN lease: ${(await q.expireStaleVPNLeases(T)).length}.`)},`Stale VPN lease проверены.`),children:`Проверить stale lease`}),(0,E.jsx)(`button`,{onClick:()=>void $a(),children:`Обновить клиент`})]})]}),(0,E.jsxs)(`div`,{className:`inlineForm`,children:[(0,E.jsxs)(`label`,{children:[`Android device id`,(0,E.jsx)(`input`,{value:ar,placeholder:`0315f630-...`,onChange:e=>or(e.target.value),onBlur:()=>localStorage.setItem(D.vpnDiagnosticDeviceId,ar.trim())})]}),sr.length>0&&(0,E.jsxs)(`label`,{children:[`Найденные клиенты`,(0,E.jsx)(`select`,{value:ar,onChange:e=>{let t=e.target.value;or(t),localStorage.setItem(D.vpnDiagnosticDeviceId,t),ur(sr.find(e=>e.device_id===t)||null)},children:sr.map(e=>{let t=F(e.payload)||{};return(0,E.jsxs)(`option`,{value:e.device_id,children:[B(e.device_id),` / `,I(t,`app_version`,`н/д`),` / `,V(e.observed_at)]},e.device_id)})})]})]}),(0,E.jsxs)(`div`,{className:`diagnosticCommandPanel`,children:[(0,E.jsxs)(`label`,{children:[`URL для теста`,(0,E.jsx)(`input`,{value:dr,onChange:e=>fr(e.target.value)})]}),(0,E.jsxs)(`div`,{className:`actions compactActions`,children:[(0,E.jsx)(`button`,{onClick:()=>void eo({type:`refresh_profile`},`Профиль`),children:`Обновить профиль`}),(0,E.jsx)(`button`,{onClick:()=>void eo({type:`start_vpn`},`VPN`),children:`Старт VPN`}),(0,E.jsx)(`button`,{onClick:()=>void eo({type:`stop_vpn`},`VPN`),children:`Стоп VPN`}),(0,E.jsx)(`button`,{onClick:()=>void eo({type:`vpn_stats`},`Stats`),children:`Stats`}),(0,E.jsx)(`button`,{onClick:()=>void eo({type:`vpn_http_get`,url:dr},`VPN HTTP`),children:`VPN HTTP`}),(0,E.jsx)(`button`,{onClick:()=>void eo({type:`open_url`,url:dr},`Открыть URL`),children:`Открыть URL`}),(0,E.jsx)(`button`,{className:`primary`,onClick:()=>void eo({type:`full_vpn_test`,url:dr,watch_seconds:45},`Полный VPN test`),children:`Полный тест`})]}),pr&&(0,E.jsxs)(`p`,{className:`muted`,children:[`Последняя команда: `,I(pr.payload,`type`,`н/д`),` / `,V(pr.created_at)]})]}),be(lr),(0,E.jsxs)(`div`,{className:`stack`,children:[Hn.map(e=>{let t=F(e.metadata?.client_config),n=F(t?.vpn_fabric_route),r=Yt(n?.entry_pool_node_ids||e.placement_policy?.entry_node_ids),i=Yt(n?.exit_pool_node_ids||e.placement_policy?.exit_node_ids),a=String(n?.selected_entry_node_id||r[0]||``),o=String(n?.selected_exit_node_id||Wn[e.id]?.owner_node_id||e.placement_policy?.exit_node_id||i[0]||``),s=qn[e.id]||{};return(0,E.jsxs)(`div`,{className:`vpnCard`,children:[(0,E.jsxs)(`div`,{children:[(0,E.jsx)(`strong`,{children:e.name}),(0,E.jsxs)(`p`,{className:`muted`,children:[e.protocol_family,` / `,e.mode,` / организация `,B(e.organization_id)]}),(0,E.jsx)(_e,{value:e.desired_state}),(0,E.jsx)(_e,{value:e.status}),(0,E.jsx)(`span`,{className:`pill ${t?.packet_forwarding?`good`:`warn`}`,children:t?.packet_forwarding?`gateway packet relay active`:`gateway packet relay inactive`}),(0,E.jsxs)(`span`,{className:`pill`,children:[String(n?.preferred_data_plane||`backend_relay`),` / fallback `,String(n?.fallback_data_plane||`н/д`)]})]}),(0,E.jsxs)(`div`,{className:`stateList`,children:[(0,E.jsx)(A,{label:`Секрет`,value:e.credential_ref?`задан`:`не задан`}),(0,E.jsx)(A,{label:`Активный lease`,value:Wn[e.id]?B(Wn[e.id]?.owner_node_id):`нет`}),(0,E.jsx)(A,{label:`Fabric route`,value:`${a?L(j,a):`entry auto`} -> ${o?L(j,o):`exit auto`}`}),(0,E.jsx)(A,{label:`Entry pool`,value:r.map(e=>L(j,e)).join(`, `)||`н/д`}),(0,E.jsx)(A,{label:`Exit pool`,value:i.map(e=>L(j,e)).join(`, `)||`н/д`}),(0,E.jsx)(A,{label:`Runtime`,value:String(t?.runtime_status||`н/д`)}),(0,E.jsx)(A,{label:`Gateway`,value:String(t?.gateway_assignment_status||`н/д`)}),(0,E.jsx)(A,{label:`Client -> gateway`,value:lt(s.client_to_gateway)}),(0,E.jsx)(A,{label:`Gateway -> client`,value:lt(s.gateway_to_client)}),(0,E.jsx)(A,{label:`Обновлено`,value:V(e.updated_at)})]}),(0,E.jsxs)(`div`,{className:`actions`,children:[(0,E.jsx)(`button`,{disabled:e.desired_state===`enabled`,onClick:()=>void Y(()=>q.updateVPNConnectionDesiredState(T,e.id,`enabled`),`Желаемое состояние VPN включено.`),children:`Включить`}),(0,E.jsx)(`button`,{disabled:e.desired_state===`disabled`,onClick:()=>void Y(()=>q.updateVPNConnectionDesiredState(T,e.id,`disabled`),`Желаемое состояние VPN выключено.`),children:`Выключить`})]})]},e.id)}),Hn.length===0&&(0,E.jsx)(ye,{title:`Нет желаемого состояния VPN`,text:`Control-plane записи C18 появятся здесь.`})]})]})]}),C===`org-safe`&&(0,E.jsxs)(`section`,{className:`grid two`,children:[(0,E.jsxs)(`article`,{className:`card span2`,children:[(0,E.jsxs)(`div`,{className:`cardHead`,children:[(0,E.jsxs)(`div`,{children:[(0,E.jsx)(`h3`,{children:`Организации и пользователи`}),(0,E.jsx)(`p`,{className:`muted`,children:`Операционный слой для владельца платформы: tenant scope, роли участников и безопасная сводка без раскрытия core mesh.`})]}),(0,E.jsx)(`span`,{className:`pill`,children:hr.length})]}),(0,E.jsxs)(Qe,{children:[(0,E.jsxs)(`label`,{children:[`Slug`,(0,E.jsx)(`input`,{value:Hi.slug,onChange:e=>Ui({...Hi,slug:e.target.value}),placeholder:`home`})]}),(0,E.jsxs)(`label`,{children:[`Название`,(0,E.jsx)(`input`,{value:Hi.name,onChange:e=>Ui({...Hi,name:e.target.value}),placeholder:`HOME`})]})]}),(0,E.jsx)(`div`,{className:`actions`,children:(0,E.jsx)(`button`,{className:`primary`,disabled:!Hi.slug.trim()||!Hi.name.trim(),onClick:()=>void Y(async()=>{let e=await q.createOrganization(Hi);Ui({slug:``,name:``}),Rr(e.id),qi(t=>({...t,organizationId:e.id})),na(t=>({...t,organizationId:e.id}))},`Организация создана.`),children:`Создать организацию`})}),(0,E.jsx)(N,{columns:[`организация`,`slug`,`статус`,`ресурсы`,`участники`,`действие`],rows:hr.map(e=>{let t=yr.filter(t=>t.organization_id===e.id),n=xr[e.id]||[];return[e.name,e.slug,(0,E.jsx)(_e,{value:e.status}),String(t.length),String(n.length),(0,E.jsx)(`div`,{className:`actions`,children:(0,E.jsx)(`button`,{onClick:()=>void Y(async()=>{Rr(e.id),Br(await q.getOrganizationAdminSummary(e.id))},`Сводка организации загружена.`),children:`Открыть`})},e.id)]})})]}),(0,E.jsxs)(`article`,{className:`card`,children:[(0,E.jsx)(`h3`,{children:`Пользователь`}),(0,E.jsxs)(Qe,{children:[(0,E.jsxs)(`label`,{children:[`Email / логин`,(0,E.jsx)(`input`,{value:Wi.email,onChange:e=>Gi({...Wi,email:e.target.value}),placeholder:`user@example.com`})]}),(0,E.jsxs)(`label`,{children:[`Пароль`,(0,E.jsx)(`input`,{type:`password`,value:Wi.password,onChange:e=>Gi({...Wi,password:e.target.value}),placeholder:`минимум 8 символов`})]}),(0,E.jsxs)(`label`,{children:[`Роль платформы`,(0,E.jsxs)(`select`,{value:Wi.platformRole,onChange:e=>Gi({...Wi,platformRole:e.target.value}),children:[(0,E.jsx)(`option`,{value:`user`,children:`user`}),(0,E.jsx)(`option`,{value:`platform_admin`,children:`platform_admin`}),(0,E.jsx)(`option`,{value:`platform_recovery_admin`,children:`platform_recovery_admin`})]})]})]}),(0,E.jsx)(`div`,{className:`actions`,children:(0,E.jsx)(`button`,{disabled:!Wi.email.trim()||Wi.password.length<8,onClick:()=>void Y(async()=>{let e=await q.createUser(Wi);vr(await q.listUsers()),Gi({email:``,password:``,platformRole:`user`}),qi(t=>({...t,userId:e.id}))},`Пользователь создан.`),children:`Создать пользователя`})}),(0,E.jsx)(N,{columns:[`пользователь`,`роль платформы`,`id`],rows:_r.map(e=>[e.email,(0,E.jsx)(_e,{value:e.platform_role||`user`}),(0,E.jsx)(`code`,{children:e.id})])})]}),(0,E.jsxs)(`article`,{className:`card`,children:[(0,E.jsx)(`h3`,{children:`Участник организации`}),(0,E.jsxs)(Qe,{children:[(0,E.jsxs)(`label`,{children:[`Организация`,(0,E.jsxs)(`select`,{value:Ki.organizationId,onChange:e=>qi({...Ki,organizationId:e.target.value}),children:[(0,E.jsx)(`option`,{value:``,children:`Выберите организацию`}),hr.map(e=>(0,E.jsx)(`option`,{value:e.id,children:e.name},e.id))]})]}),(0,E.jsxs)(`label`,{children:[`Пользователь`,(0,E.jsxs)(`select`,{value:Ki.userId,onChange:e=>qi({...Ki,userId:e.target.value}),children:[(0,E.jsx)(`option`,{value:``,children:`Выберите пользователя`}),_r.map(e=>(0,E.jsx)(`option`,{value:e.id,children:e.email},e.id))]})]}),(0,E.jsxs)(`label`,{children:[`Роль`,(0,E.jsxs)(`select`,{value:Ki.roleId,onChange:e=>qi({...Ki,roleId:e.target.value}),children:[(0,E.jsx)(`option`,{value:`org_owner`,children:`org_owner`}),(0,E.jsx)(`option`,{value:`org_admin`,children:`org_admin`}),(0,E.jsx)(`option`,{value:`org_operator`,children:`org_operator`}),(0,E.jsx)(`option`,{value:`org_member`,children:`org_member`}),(0,E.jsx)(`option`,{value:`org_viewer`,children:`org_viewer`})]})]})]}),(0,E.jsx)(`div`,{className:`actions`,children:(0,E.jsx)(`button`,{disabled:!Ki.organizationId||!Ki.userId.trim(),onClick:()=>void Y(()=>q.addOrganizationMembership(Ki.organizationId,{userId:Ki.userId,roleId:Ki.roleId}),`Участник организации сохранен.`),children:`Сохранить участника`})})]}),(0,E.jsxs)(`article`,{className:`card`,children:[(0,E.jsx)(`h3`,{children:`Безопасная сводка`}),(0,E.jsxs)(`div`,{className:`inlineForm`,children:[(0,E.jsxs)(`select`,{value:Lr,onChange:e=>Rr(e.target.value),children:[(0,E.jsx)(`option`,{value:``,children:`Выберите организацию`}),hr.map(e=>(0,E.jsx)(`option`,{value:e.id,children:e.name},e.id))]}),(0,E.jsx)(`button`,{disabled:!Lr,onClick:()=>void Y(async()=>{Br(await q.getOrganizationAdminSummary(Lr))},`Сводка организации загружена.`),children:`Обновить`})]}),zr?(0,E.jsxs)(`div`,{className:`stack`,children:[(0,E.jsx)(he,{label:`Ресурсы`,value:zr.resource_count,tone:`steel`}),(0,E.jsx)(he,{label:`Активные сессии`,value:zr.active_session_count,tone:`green`}),(0,E.jsx)(A,{label:`Topology exposure`,value:zr.topology_exposure}),(0,E.jsx)(N,{columns:[`контур`,`состояние`],rows:Object.entries(zr.connector_status||{}).map(([e,t])=>[e,typeof t==`string`?H(t):JSON.stringify(t)])}),(0,E.jsx)(N,{columns:[`протокол`,`количество`],rows:zr.service_endpoints.map(e=>[e.protocol,String(e.count)])})]}):(0,E.jsx)(ye,{title:`Сводка не выбрана`,text:`Выберите организацию, чтобы проверить tenant-safe состояние.`})]})]}),C===`servers`&&(0,E.jsx)(`section`,{className:`grid two`,children:(0,E.jsxs)(`article`,{className:`card span2`,children:[(0,E.jsxs)(`div`,{className:`cardHead`,children:[(0,E.jsxs)(`div`,{children:[(0,E.jsx)(`h3`,{children:`Справочник серверов`}),(0,E.jsx)(`p`,{className:`muted`,children:`Единый каталог целей для RDP/VPN: адрес сервера, организация, протокол и предпочтительный вход/выход маршрута.`})]}),(0,E.jsx)(`span`,{className:`pill`,children:yr.length})]}),(0,E.jsxs)(Qe,{children:[(0,E.jsxs)(`label`,{children:[`Организация`,(0,E.jsxs)(`select`,{value:K.organizationId,onChange:e=>na({...K,organizationId:e.target.value}),children:[(0,E.jsx)(`option`,{value:``,children:`Выберите организацию`}),hr.map(e=>(0,E.jsx)(`option`,{value:e.id,children:e.name},e.id))]})]}),(0,E.jsxs)(`label`,{children:[`Имя сервера`,(0,E.jsx)(`input`,{value:K.name,onChange:e=>na({...K,name:e.target.value}),placeholder:`Office RDP`})]}),(0,E.jsxs)(`label`,{children:[`Адрес`,(0,E.jsx)(`input`,{value:K.address,onChange:e=>na({...K,address:e.target.value}),placeholder:`192.168.1.10:3389`})]}),(0,E.jsxs)(`label`,{children:[`Протокол`,(0,E.jsxs)(`select`,{value:K.protocol,onChange:e=>na({...K,protocol:e.target.value}),children:[(0,E.jsx)(`option`,{value:`rdp`,children:`RDP`}),(0,E.jsx)(`option`,{value:`vpn`,children:`VPN`}),(0,E.jsx)(`option`,{value:`ssh`,children:`SSH`}),(0,E.jsx)(`option`,{value:`http`,children:`HTTP`})]})]}),(0,E.jsxs)(`label`,{children:[`Вход`,(0,E.jsxs)(`select`,{value:K.entryNode,onChange:e=>na({...K,entryNode:e.target.value}),children:[(0,E.jsx)(`option`,{value:``,children:`Автоматически`}),j.map(e=>(0,E.jsx)(`option`,{value:e.id,children:e.name},e.id))]})]}),(0,E.jsxs)(`label`,{children:[`Выход`,(0,E.jsxs)(`select`,{value:K.exitNode,onChange:e=>na({...K,exitNode:e.target.value}),children:[(0,E.jsx)(`option`,{value:``,children:`Автоматически`}),j.map(e=>(0,E.jsx)(`option`,{value:e.id,children:e.name},e.id))]})]}),(0,E.jsxs)(`label`,{children:[`Теги`,(0,E.jsx)(`input`,{value:K.tags,onChange:e=>na({...K,tags:e.target.value}),placeholder:`home, accounting`})]}),(0,E.jsxs)(`label`,{children:[`RDP пользователь`,(0,E.jsx)(`input`,{value:K.username,onChange:e=>na({...K,username:e.target.value}),placeholder:`user или DOMAIN\\\\user`})]}),(0,E.jsxs)(`label`,{children:[`RDP пароль`,(0,E.jsx)(`input`,{type:`password`,value:K.password,onChange:e=>na({...K,password:e.target.value}),placeholder:`хранится как secret`})]}),(0,E.jsxs)(`label`,{children:[`Домен`,(0,E.jsx)(`input`,{value:K.domain,onChange:e=>na({...K,domain:e.target.value}),placeholder:`опционально`})]})]}),(0,E.jsx)(`div`,{className:`actions`,children:(0,E.jsx)(`button`,{className:`primary`,disabled:!K.organizationId||!K.name.trim()||!K.address.trim(),onClick:()=>void Y(async()=>{let e=[`rdp`,`vnc`,`ssh`].includes(K.protocol)?`rap-secret://org/${K.organizationId}/resources/${crypto.randomUUID()}/primary`:null,t=await q.createResource({organizationId:K.organizationId,name:K.name,address:K.address,protocol:K.protocol,secretRef:e,certificateVerificationMode:K.protocol===`rdp`?`ignore`:`strict`,clipboardMode:K.protocol===`rdp`?`bidirectional`:`disabled`,fileTransferMode:K.protocol===`rdp`?`bidirectional`:`disabled`,metadata:{route_mode:K.routeMode,preferred_entry_node_id:K.entryNode||null,preferred_exit_node_id:K.exitNode||null,tags:K.tags.split(`,`).map(e=>e.trim()).filter(Boolean)}});[`rdp`,`vnc`,`ssh`].includes(K.protocol)&&(K.username.trim()||K.password)&&await q.upsertResourceSecret(t.id,{username:K.username.trim(),password:K.password,domain:K.domain.trim()}),na({...K,name:``,address:``,tags:``,username:``,password:``,domain:``})},`Сервер добавлен в справочник.`),children:`Добавить сервер`})}),(0,E.jsx)(N,{columns:[`сервер`,`адрес`,`протокол`,`секрет`,`организация`,`маршрут`,`создано`,`действия`],rows:yr.map(e=>{let t=e.metadata||{},n=hr.find(t=>t.id===e.organization_id);return[e.name,e.address,e.protocol,e.has_secret?`сохранен`:e.secret_ref?`нужен payload`:`нет`,n?.name||B(e.organization_id),`${B(String(t.preferred_entry_node_id||``))||`auto`} -> ${B(String(t.preferred_exit_node_id||``))||`auto`}`,V(e.created_at),(0,E.jsx)(`button`,{className:`ghost`,onClick:()=>{Yi(e),Zi({username:``,password:``,domain:``})},children:`Обновить secret`})]})}),Ji&&(0,E.jsx)(`div`,{className:`modalBackdrop`,role:`presentation`,children:(0,E.jsxs)(`div`,{className:`modalCard`,role:`dialog`,"aria-modal":`true`,"aria-labelledby":`resource-secret-title`,children:[(0,E.jsxs)(`div`,{className:`cardHead`,children:[(0,E.jsxs)(`div`,{children:[(0,E.jsx)(`h3`,{id:`resource-secret-title`,children:`Учетные данные RDP`}),(0,E.jsxs)(`p`,{className:`muted`,children:[Ji.name,` · `,Ji.address]})]}),(0,E.jsx)(`button`,{className:`ghost`,onClick:()=>Yi(null),children:`Закрыть`})]}),(0,E.jsxs)(Qe,{children:[(0,E.jsxs)(`label`,{children:[`Пользователь`,(0,E.jsx)(`input`,{value:Xi.username,onChange:e=>Zi({...Xi,username:e.target.value}),placeholder:`user или DOMAIN\\\\user`})]}),(0,E.jsxs)(`label`,{children:[`Пароль`,(0,E.jsx)(`input`,{type:`password`,value:Xi.password,onChange:e=>Zi({...Xi,password:e.target.value})})]}),(0,E.jsxs)(`label`,{children:[`Домен`,(0,E.jsx)(`input`,{value:Xi.domain,onChange:e=>Zi({...Xi,domain:e.target.value}),placeholder:`опционально`})]})]}),(0,E.jsx)(`p`,{className:`muted`,children:`Пароль сохраняется как encrypted resource secret. В metadata ресурса он не попадет.`}),(0,E.jsxs)(`div`,{className:`actions`,children:[(0,E.jsx)(`button`,{className:`primary`,disabled:!Xi.username.trim()||!Xi.password,onClick:()=>void Y(async()=>{await q.upsertResourceSecret(Ji.id,{username:Xi.username.trim(),password:Xi.password,domain:Xi.domain.trim()}),Yi(null),Zi({username:``,password:``,domain:``})},`Secret ресурса обновлен.`),children:`Сохранить secret`}),(0,E.jsx)(`button`,{onClick:()=>Yi(null),children:`Отмена`})]})]})})]})}),C===`audit`&&(0,E.jsxs)(`section`,{className:`card`,children:[(0,E.jsxs)(`div`,{className:`cardHead`,children:[(0,E.jsxs)(`div`,{children:[(0,E.jsx)(`h3`,{children:`Аудит кластера`}),Tr&&(0,E.jsxs)(`p`,{className:`muted`,children:[`Фильтр по узлу: `,(0,E.jsx)(`strong`,{children:Dr||B(Tr)})]})]}),Tr&&(0,E.jsx)(`button`,{className:`ghost`,onClick:()=>{Er(``),Or(``)},children:`Сбросить фильтр`})]}),(0,E.jsx)(N,{columns:[`событие`,`цель`,`actor`,`создано`],rows:Ma.map(e=>[e.event_type,`${e.target_type}${e.target_id?`:${B(e.target_id)}`:``}`,e.actor_user_id?B(e.actor_user_id):`system`,V(e.created_at)])})]})]})]})}function he({label:e,value:t,tone:n}){return(0,E.jsxs)(`article`,{className:`metric ${n}`,children:[(0,E.jsx)(`span`,{children:e}),(0,E.jsx)(`strong`,{children:t})]})}function ge({label:e,value:t}){return(0,E.jsxs)(`div`,{className:`signal`,children:[(0,E.jsx)(`span`,{children:e}),(0,E.jsx)(`strong`,{children:t})]})}function _e({value:e}){return(0,E.jsx)(`span`,{className:`status ${e.replace(/_/g,`-`)}`,children:H(e)})}function ve({label:e,value:t,tone:n}){return(0,E.jsxs)(`span`,{className:`functionState ${n||``}`,children:[(0,E.jsx)(`small`,{children:e}),(0,E.jsx)(`strong`,{children:t})]})}function A({label:e,value:t}){return(0,E.jsxs)(`div`,{className:`stateLine`,children:[(0,E.jsx)(`span`,{children:e}),(0,E.jsx)(`strong`,{children:t})]})}function ye({title:e,text:t}){return(0,E.jsxs)(`article`,{className:`empty`,children:[(0,E.jsx)(`h3`,{children:e}),(0,E.jsx)(`p`,{children:t})]})}function be(e){if(!e)return(0,E.jsx)(`p`,{className:`muted`,children:`Диагностика Android-клиента не загружена. Укажи device id из приложения и нажми “Обновить клиент”.`});let t=F(e.payload)||{},n=F(t.runtime),r=F(t.vpn_config),i=I(t,`app_version`,`н/д`),a=I(t,`service_state`,`н/д`),o=I(t,`control_network_mode`,`н/д`),s=I(r,`packet_relay_active_base_url`)||I(r,`packet_relay_base_url`,`н/д`),c=I(r,`packet_relay_profile_base_url`,`н/д`),l=I(r,`packet_relay_candidate_urls`,`н/д`),u=Ot(n,`uplink_read_total`),d=Ot(n,`uplink_sent_total`),f=Ot(n,`downlink_received_total`),p=Ot(n,`uplink_dropped_packets`)+Ot(n,`downlink_dropped_packets`),m=Ot(n,`uplink_bypassed_control_packets`),h=Ot(n,`downlink_received_bytes`),g=Ot(n,`uplink_sent_bytes`),_=I(n,`state`,`н/д`),v=I(n,`message`,``),y=Ot(n,`uplink_sent_mbps`),b=Ot(n,`downlink_received_mbps`),x=I(t,`last_command_type`,`н/д`),S=I(t,`last_command_result`,`н/д`);return(0,E.jsxs)(`div`,{className:`vpnCard diagnosticCard`,children:[(0,E.jsxs)(`div`,{children:[(0,E.jsxs)(`strong`,{children:[`Android client `,B(e.device_id)]}),(0,E.jsxs)(`p`,{className:`muted`,children:[i,` / `,a,` / `,V(e.observed_at)]}),(0,E.jsx)(_e,{value:Date.now()-new Date(e.observed_at).getTime()<3e4?`active`:`degraded`}),(0,E.jsx)(`span`,{className:`pill`,children:o})]}),(0,E.jsxs)(`div`,{className:`stateList`,children:[(0,E.jsx)(A,{label:`Relay active`,value:s}),(0,E.jsx)(A,{label:`Relay profile`,value:c}),(0,E.jsx)(A,{label:`Relay candidates`,value:l}),(0,E.jsx)(A,{label:`Packets read/sent/down`,value:`${u} / ${d} / ${f}`}),(0,E.jsx)(A,{label:`Drops / control bypass`,value:`${p} / ${m}`}),(0,E.jsx)(A,{label:`Bytes up/down`,value:`${$n(g)} / ${$n(h)}`}),(0,E.jsx)(A,{label:`Rate up/down`,value:`${y.toFixed(2)} / ${b.toFixed(2)} Mbps`}),(0,E.jsx)(A,{label:`Runtime`,value:v?`${_}: ${v}`:_}),(0,E.jsx)(A,{label:`Last command`,value:`${x}: ${S}`})]})]})}function xe({items:e,emptyText:t}){if(e.length===0)return(0,E.jsx)(ye,{title:t,text:`Тестовая телеметрия появится здесь после отчета node-agent.`});let n=[...e].reverse().slice(-24),r=e[0],i=Math.max(...n.map(e=>e.memory_used_bytes||0),1);return(0,E.jsxs)(`div`,{className:`telemetryBox`,children:[(0,E.jsxs)(`div`,{className:`signalStrip compact`,children:[(0,E.jsx)(ge,{label:`Память`,value:`${$n(r.memory_used_bytes)} / ${$n(r.memory_total_bytes)}`}),(0,E.jsx)(ge,{label:`Процессор`,value:r.cpu_percent==null?`н/д`:`${r.cpu_percent.toFixed(1)}%`}),(0,E.jsx)(ge,{label:`Процессы`,value:r.process_count==null?`н/д`:String(r.process_count)}),(0,E.jsx)(ge,{label:`Обновлено`,value:V(r.observed_at)})]}),(0,E.jsx)(`div`,{className:`sparkline`,"aria-label":`memory telemetry`,children:n.map(e=>(0,E.jsx)(`span`,{style:{height:`${Math.max(8,Math.round((e.memory_used_bytes||0)/i*100))}%`}},e.id))})]})}function Se({node:e,memberships:t,activeRoles:n,desiredWorkloads:r,observedWorkloads:i,heartbeats:a,telemetry:o,meshLinks:s,syntheticConfig:c,allNodes:l,onSetUpdatePolicy:u,updatePlan:d,updateStatuses:f,labels:p}){let m=a[0],h=o[0],g=F(m?.metadata?.mesh_listener_report),v=F(m?.metadata?.mesh_endpoint_report),y=F(m?.metadata?.mesh_outbound_session_report),b=c?.mesh_listener,x=F(m?.metadata?.mesh_peer_recovery_report),S=F(m?.metadata?.mesh_peer_connection_intent_report),C=F(m?.metadata?.mesh_peer_connection_manager_report),w=F(m?.metadata?.mesh_rendezvous_lease_report),T=F(m?.metadata?.mesh_route_path_decision_report),ee=F(m?.metadata?.mesh_route_generation_report),te=F(m?.metadata?.mesh_route_health_config_report),D=c?.service_channel_route_feedback,ne=D?.observations||[],re=c?.service_channel_remediation_commands||[],ie=yt(s).filter(e=>e.source_node_id!==e.target_node_id),ae=ie.filter(e=>e.link_status===`reachable`),oe=ie.filter(e=>e.link_status!==`reachable`),se=Object.entries(m?.capabilities||{}).sort(([e],[t])=>e.localeCompare(t)),O=Tt(C?.probe_results),[k,ce]=(0,_.useState)(`network`),le=ot(f,`rap-node-agent`),ue=ot(f,`rap-host-agent`),de=f[0],fe=gt(f),pe=t.find(t=>t.node.id===e.id)?.cluster.id||t[0]?.cluster.id||``,me=Tt(v?.endpoint_candidates),he=me[0],ve=Et(v,[`peer_endpoint`,`advertised_endpoint`,`endpoint`])||I(he,`address`,``)||``,ye=Et(v,[`transport`,`advertise_transport`])||I(he,`transport`,``)||`н/д`,be=Et(v,[`connectivity_mode`,`connectivity`])||I(he,`connectivity_mode`,``)||I(g,`inbound_reachability`,``)||`н/д`,Se=I(v,`nat_type`,I(he,`nat_type`,`н/д`)),we=I(v,`region`,I(g,`region`,I(he,`region`,`н/д`))),Te=I(v,`observed_at`,I(g,`observed_at`,m?.observed_at||`н/д`)),Ee=I(g,`status`,``)||(ve?`нет listener report, есть advertised endpoint`:`report отсутствует`),j=I(g,`effective_listen_addr`,``)||`н/д`,De=I(g,`configured_listen_addr`,``)||`н/д`,Oe=me.length>0?me:ve?[{endpoint_id:`${e.id}-reported`,address:ve,transport:ye,reachability:be,connectivity_mode:be,nat_type:Se,priority:`н/д`,last_verified_at:Te}]:[],ke=Tt(b?.endpoint_candidates),Ae=Object.entries(c?.peer_endpoints||{}),je=Object.entries(c?.peer_endpoint_candidates||{}).flatMap(([e,t])=>t.map(t=>({peerID:e,candidate:t}))),Me=new Set(ae.map(t=>t.source_node_id===e.id?t.target_node_id:t.source_node_id)),Ne=je.filter(({peerID:e})=>!Me.has(e)),Pe=[g?`listener report: есть`:`listener report: не прислан агентом`,v?`endpoint report: есть`:`endpoint report: не прислан агентом`,y?`outbound session: есть`:`outbound session: не прислан агентом`,c?`scoped config: ${c.enabled?`enabled`:`disabled`}`:`scoped config: не загружен`,D?`service-channel feedback: ${D.observation_count}`:`service-channel feedback: не загружен`,`active links: ${ae.length}/${ie.length}`];return(0,E.jsxs)(`div`,{className:`nodeDetails`,children:[(0,E.jsxs)(`section`,{className:`nodePanel`,children:[(0,E.jsx)(`h4`,{children:`Сводка runtime`}),(0,E.jsxs)(`div`,{className:`signalStrip compact nodeMetricGrid`,children:[(0,E.jsx)(ge,{label:`Heartbeat`,value:m?V(m.observed_at):`н/д`}),(0,E.jsx)(ge,{label:`Health`,value:H(m?.health_status||e.health_status)}),(0,E.jsx)(ge,{label:`Listener`,value:Wn(m)}),(0,E.jsx)(ge,{label:`Mesh links`,value:`${ae.length}/${ie.length}`}),(0,E.jsx)(ge,{label:`Web ingress`,value:Re(m)}),(0,E.jsx)(ge,{label:`Update`,value:st(de,d)})]}),(0,E.jsxs)(`div`,{className:`summaryChips`,children:[(0,E.jsx)(_e,{value:e.registration_status}),(0,E.jsx)(_e,{value:e.membership_status}),(0,E.jsx)(_e,{value:e.partition_state}),(0,E.jsx)(`span`,{className:`pill`,children:e.reported_version||m?.reported_version||`версия неизвестна`}),g?.one_way_connectivity===!0&&(0,E.jsx)(`span`,{className:`pill warn`,children:`one-way`}),g?.port_conflict===!0&&(0,E.jsx)(`span`,{className:`pill bad`,children:`port conflict`})]})]}),(0,E.jsx)(`div`,{className:`nodeTabs`,role:`tablist`,"aria-label":`Node analysis sheets`,children:[[`overview`,`Обзор`],[`network`,`Сеть и адреса`],[`mesh`,`Mesh`],[`services`,`Роли и сервисы`],[`telemetry`,`Телеметрия`],[`updates`,`Обновления`],[`raw`,`Raw`]].map(([e,t])=>(0,E.jsx)(`button`,{className:k===e?`active`:``,onClick:()=>ce(e),type:`button`,children:t},e))}),k===`overview`&&(0,E.jsxs)(`div`,{className:`nodeDetailGrid`,children:[(0,E.jsxs)(`section`,{className:`nodePanel`,children:[(0,E.jsx)(`h4`,{children:`Идентичность и размещение`}),(0,E.jsxs)(`div`,{className:`stateList`,children:[(0,E.jsx)(A,{label:`Node ID`,value:e.id}),(0,E.jsx)(A,{label:`Node key`,value:e.node_key}),(0,E.jsx)(A,{label:`Имя`,value:e.name}),(0,E.jsx)(A,{label:`Владение`,value:H(e.ownership_type)}),(0,E.jsx)(A,{label:`Owner org`,value:B(e.owner_organization_id)}),(0,E.jsx)(A,{label:`Группа`,value:e.node_group_name||p.ungroupedNodes}),(0,E.jsx)(A,{label:`Создан`,value:V(e.created_at)}),(0,E.jsx)(A,{label:`Обновлен`,value:V(e.updated_at)})]})]}),(0,E.jsxs)(`section`,{className:`nodePanel`,children:[(0,E.jsx)(`h4`,{children:`Участие в кластерах`}),(0,E.jsx)(`div`,{className:`membershipList`,children:t.map(t=>(0,E.jsxs)(`span`,{className:t.node.id===e.id&&t.node.membership_status===`active`?`pill good`:`pill`,children:[t.cluster.name,`: `,H(t.node.membership_status)]},t.cluster.id))}),(0,E.jsxs)(`div`,{className:`stateList`,children:[(0,E.jsx)(A,{label:`Активных ролей`,value:String(n.length)}),(0,E.jsx)(A,{label:`Desired workloads`,value:String(r.length)}),(0,E.jsx)(A,{label:`Observed workloads`,value:String(i.length)}),(0,E.jsx)(A,{label:`Последний сигнал`,value:V(e.last_seen_at||m?.observed_at)})]})]})]}),k===`network`&&(0,E.jsxs)(E.Fragment,{children:[(0,E.jsxs)(`div`,{className:`nodeDetailGrid`,children:[(0,E.jsxs)(`section`,{className:`nodePanel`,children:[(0,E.jsx)(`h4`,{children:`Локальный listener`}),(0,E.jsxs)(`div`,{className:`stateList`,children:[(0,E.jsx)(A,{label:`Статус`,value:Ee}),(0,E.jsx)(A,{label:`Режим порта`,value:I(g,`listen_port_mode`,`н/д`)}),(0,E.jsx)(A,{label:`Configured addr`,value:De}),(0,E.jsx)(A,{label:`Effective addr`,value:j}),(0,E.jsx)(A,{label:`Inbound`,value:I(g,`inbound_reachability`,be)}),(0,E.jsx)(A,{label:`One-way`,value:I(g,`one_way_connectivity`,`н/д`)}),(0,E.jsx)(A,{label:`Port conflict`,value:I(g,`port_conflict`,`false`)}),(0,E.jsx)(A,{label:`Failure`,value:I(g,`failure_error`,I(g,`failure_reason`,`нет`))})]})]}),(0,E.jsxs)(`section`,{className:`nodePanel`,children:[(0,E.jsx)(`h4`,{children:`Desired listener`}),(0,E.jsxs)(`div`,{className:`stateList`,children:[(0,E.jsx)(A,{label:`Состояние`,value:b?.desired_state||`н/д`}),(0,E.jsx)(A,{label:`Режим порта`,value:b?.listen_port_mode||`н/д`}),(0,E.jsx)(A,{label:`Listen addr`,value:b?.listen_addr||`н/д`}),(0,E.jsx)(A,{label:`Auto range`,value:b?`${b.auto_port_start||`н/д`}-${b.auto_port_end||`н/д`}`:`н/д`}),(0,E.jsx)(A,{label:`Advertise endpoint`,value:b?.advertise_endpoint||`auto-discovery`}),(0,E.jsx)(A,{label:`Endpoint candidates`,value:ke.length>0?String(ke.length):`auto-discovery`}),(0,E.jsx)(A,{label:`Advertise transport`,value:b?.advertise_transport||`н/д`}),(0,E.jsx)(A,{label:`Connectivity`,value:b?.connectivity_mode||`н/д`}),(0,E.jsx)(A,{label:`NAT`,value:b?.nat_type||`н/д`}),(0,E.jsx)(A,{label:`Region/site`,value:b?.region||`н/д`}),(0,E.jsx)(A,{label:`Version`,value:b?.config_version||`н/д`})]})]}),(0,E.jsxs)(`section`,{className:`nodePanel`,children:[(0,E.jsx)(`h4`,{children:`Что узел сообщает кластеру`}),(0,E.jsxs)(`div`,{className:`stateList`,children:[(0,E.jsx)(A,{label:`Advertised endpoint`,value:ve||`не прислан`}),(0,E.jsx)(A,{label:`Transport`,value:ye}),(0,E.jsx)(A,{label:`Connectivity`,value:be}),(0,E.jsx)(A,{label:`NAT`,value:Se}),(0,E.jsx)(A,{label:`Region/site`,value:we}),(0,E.jsx)(A,{label:`Observed`,value:Te})]})]})]}),(0,E.jsxs)(`section`,{className:`nodePanel`,children:[(0,E.jsx)(`h4`,{children:`Исходящий control-channel`}),(0,E.jsxs)(`div`,{className:`stateList`,children:[(0,E.jsx)(A,{label:`Status`,value:I(y,`status`,`не прислан`)}),(0,E.jsx)(A,{label:`Direction`,value:I(y,`direction`,`н/д`)}),(0,E.jsx)(A,{label:`Transport`,value:I(y,`transport`,`н/д`)}),(0,E.jsx)(A,{label:`Control API endpoint`,value:I(y,`control_plane_url`,`н/д`)}),(0,E.jsx)(A,{label:`Reverse usable`,value:I(y,`usable_for_inbound_control`,`н/д`)}),(0,E.jsx)(A,{label:`Inbound required`,value:I(y,`inbound_listener_required`,`н/д`)}),(0,E.jsx)(A,{label:`Relay ready`,value:I(y,`peer_connection_relay_ready`,`0`)}),(0,E.jsx)(A,{label:`Waiting rendezvous`,value:I(y,`peer_connection_waiting`,`0`)}),(0,E.jsx)(A,{label:`Rendezvous leases`,value:I(y,`rendezvous_lease_count`,`0`)}),(0,E.jsx)(A,{label:`Listener conflict`,value:I(y,`listener_port_conflict`,`false`)})]})]}),(0,E.jsxs)(`section`,{className:`nodePanel`,children:[(0,E.jsx)(`h4`,{children:`Наличие сетевых отчетов`}),(0,E.jsx)(`div`,{className:`summaryChips`,children:Pe.map(e=>(0,E.jsx)(`span`,{className:e.includes(`не прислан`)||e.includes(`не загружен`)?`pill warn`:`pill good`,children:e},e))}),!v&&!g&&(0,E.jsx)(`p`,{className:`muted`,children:`У этого узла есть heartbeat/mesh manager данные, но агент не передал адресный отчет. До обновления агента или включения endpoint/listener report панель может показать связи и config peers, но не может достоверно назвать локальный listen address.`})]}),(0,E.jsxs)(`section`,{className:`nodePanel`,children:[(0,E.jsx)(`h4`,{children:`Endpoint candidates узла`}),(0,E.jsx)(N,{columns:[`id`,`address`,`transport`,`reachability`,`mode`,`nat`,`priority`,`verified`],rows:Oe.map(e=>[I(e,`endpoint_id`,`н/д`),I(e,`address`,`н/д`),I(e,`transport`,`н/д`),I(e,`reachability`,`н/д`),I(e,`connectivity_mode`,`н/д`),I(e,`nat_type`,`н/д`),I(e,`priority`,`н/д`),I(e,`last_verified_at`,`н/д`)])})]}),(0,E.jsxs)(`div`,{className:`nodeDetailGrid`,children:[(0,E.jsxs)(`section`,{className:`nodePanel`,children:[(0,E.jsx)(`h4`,{children:`Рабочие peer endpoints из config`}),(0,E.jsx)(N,{columns:[`peer`,`endpoint`],rows:Ae.map(([e,t])=>[L(l,e),t])})]}),(0,E.jsxs)(`section`,{className:`nodePanel`,children:[(0,E.jsx)(`h4`,{children:`Резервные кандидаты peer`}),(0,E.jsx)(N,{columns:[`peer`,`address`,`transport`,`reachability`,`mode`,`priority`],rows:Ne.slice(0,20).map(({peerID:e,candidate:t})=>[L(l,e),t.address,t.transport,t.reachability,t.connectivity_mode,String(t.priority)])})]})]}),(0,E.jsxs)(`section`,{className:`nodePanel`,children:[(0,E.jsx)(`h4`,{children:`Активные связи этого узла`}),(0,E.jsx)(N,{columns:[`peer`,`направление`,`тип`,`статус`,`latency`,`quality`,`путь`,`наблюдение`],rows:ie.slice(0,20).map(t=>[L(l,t.source_node_id===e.id?t.target_node_id:t.source_node_id),t.source_node_id===e.id?`out`:`in`,xt(t),t.link_status,t.latency_ms==null?`н/д`:`${t.latency_ms}мс`,t.quality_score==null?`н/д`:String(t.quality_score),St(t,l),V(t.observed_at)])}),oe.length>0&&(0,E.jsxs)(`p`,{className:`muted`,children:[`Проблемных связей: `,oe.length,`. Их статус виден в таблице выше.`]})]}),(0,E.jsxs)(`section`,{className:`nodePanel`,children:[(0,E.jsx)(`h4`,{children:`Проверка адресов peer-to-peer`}),(0,E.jsx)(N,{columns:[`peer`,`status`,`selected endpoint`,`candidate`,`latency`,`attempts`,`failure`],rows:O.slice(0,20).map(e=>[L(l,I(e,`node_id`,``)),I(e,`link_status`,`н/д`),I(e,`selected_endpoint`,I(e,`endpoint`,`н/д`)),I(e,`selected_candidate_id`,`н/д`),I(e,`latency_ms`,`н/д`),It(e),I(e,`failure_reason`,`нет`)])})]})]}),k===`mesh`&&(0,E.jsxs)(E.Fragment,{children:[(0,E.jsxs)(`div`,{className:`nodeDetailGrid`,children:[(0,E.jsxs)(`section`,{className:`nodePanel`,children:[(0,E.jsx)(`h4`,{children:`Mesh control authority`}),(0,E.jsxs)(`div`,{className:`stateList`,children:[(0,E.jsx)(A,{label:`Recovery`,value:Ln(m)}),(0,E.jsx)(A,{label:`Intents`,value:Rn(m)}),(0,E.jsx)(A,{label:`Manager`,value:Un(m)}),(0,E.jsx)(A,{label:`Rendezvous`,value:zn(m)}),(0,E.jsx)(A,{label:`Path decisions`,value:Bn(m)}),(0,E.jsx)(A,{label:`Route generation`,value:Vn(m)}),(0,E.jsx)(A,{label:`Route health`,value:Hn(m)}),(0,E.jsx)(A,{label:`Service-channel feedback`,value:D?`${D.healthy_route_count} healthy / ${D.degraded_route_count} degraded / ${D.fenced_route_count} fenced`:`н/д`}),(0,E.jsx)(A,{label:`Recovery policy`,value:D?.recovery_policy?`${D.recovery_policy.source} p${D.recovery_policy.hysteresis_penalty} promote ${D.recovery_policy.promotion_min_samples}`:`н/д`}),(0,E.jsx)(A,{label:`Route policy`,value:c?.route_path_decisions?.recovery_policy?`${c.route_path_decisions.recovery_policy.source} fail/drop/slow ${c.route_path_decisions.recovery_policy.demotion_failure_threshold}/${c.route_path_decisions.recovery_policy.demotion_drop_threshold}/${c.route_path_decisions.recovery_policy.demotion_slow_threshold}`:`н/д`}),(0,E.jsx)(A,{label:`Config version`,value:c?.config_version||`н/д`})]})]}),(0,E.jsxs)(`section`,{className:`nodePanel`,children:[(0,E.jsx)(`h4`,{children:`Scoped config counts`}),(0,E.jsxs)(`div`,{className:`stateList`,children:[(0,E.jsx)(A,{label:`Peer endpoints`,value:String(Ae.length)}),(0,E.jsx)(A,{label:`Endpoint candidates`,value:String(je.length)}),(0,E.jsx)(A,{label:`Peer directory`,value:String(c?.peer_directory?.length||0)}),(0,E.jsx)(A,{label:`Recovery seeds`,value:String(c?.recovery_seeds?.length||0)}),(0,E.jsx)(A,{label:`Rendezvous leases`,value:String(c?.rendezvous_leases?.length||0)}),(0,E.jsx)(A,{label:`Routes`,value:String(c?.routes?.length||0)}),(0,E.jsx)(A,{label:`Fenced routes`,value:String(D?.fenced_route_count||0)}),(0,E.jsx)(A,{label:`Remediation commands`,value:String(re.length)}),(0,E.jsx)(A,{label:`Feedback provenance`,value:D?`missing ${D.missing_provenance_count||0} / stale policy ${D.stale_policy_count||0} / stale gen ${D.stale_generation_count||0}`:`н/д`})]})]})]}),(0,E.jsxs)(`section`,{className:`nodePanel`,children:[(0,E.jsx)(`h4`,{children:`Route decisions`}),(0,E.jsx)(N,{columns:[`route`,`replacement`,`source`,`destination`,`effective hops`,`decision`,`score`,`expires`],rows:(c?.route_path_decisions?.decisions||[]).map(e=>[B(e.route_id),e.replacement_route_id?B(e.replacement_route_id):`нет`,L(l,e.source_node_id),L(l,e.destination_node_id),e.effective_hops.map(e=>qn(L(l,e))).join(` > `),e.decision_source||(e.selected_relay_id?L(l,e.selected_relay_id):`direct`),e.path_score==null?`н/д`:String(e.path_score),V(e.expires_at)])})]}),re.length>0&&(0,E.jsxs)(`section`,{className:`nodePanel`,children:[(0,E.jsx)(`h4`,{children:`Service-channel remediation commands`}),(0,E.jsx)(N,{columns:[`channel`,`action`,`primary`,`replacement`,`guard`,`execution`,`reason`,`expires`],rows:re.slice(0,20).map(e=>[B(e?.channel_id||``),(0,E.jsx)(`span`,{className:`pill warn`,children:H(e?.action||``)}),e?.primary_route_id?B(e.primary_route_id):`н/д`,e?.replacement_route_id?B(e.replacement_route_id):`н/д`,(0,E.jsx)(`span`,{className:`pill ${e?.guard_status===`rejected`?`bad`:e?.guard_status===`allowed`?`good`:``}`,children:e?.guard_status?H(e.guard_status):`н/д`}),(0,E.jsxs)(`span`,{className:`pill ${rr(e?.execution_status)}`,children:[e?.execution_status?H(e.execution_status):`н/д`,e?.execution_reason?` / ${H(e.execution_reason)}`:``]}),e?.reason||`н/д`,e?.expires_at?V(e.expires_at):`н/д`])})]}),(0,E.jsxs)(`section`,{className:`nodePanel`,children:[(0,E.jsx)(`h4`,{children:`Service-channel route feedback`}),(0,E.jsx)(N,{columns:[`route`,`service`,`status`,`recovery`,`score`,`reasons`,`failures`,`duration`,`expires`],rows:ne.slice(0,40).map(e=>[B(e.route_id),e.service_class,(0,E.jsx)(`span`,{className:`pill ${dt(e.feedback_status)}`,children:H(e.feedback_status)}),e.recovery_state?(0,E.jsxs)(`span`,{className:`pill ${ft(e.recovery_state)}`,children:[e.recovery_demoted?`demoted ${e.recovery_reason?H(e.recovery_reason):``}`:e.recovery_promoted?`promoted`:H(e.recovery_state),e.recovery_hysteresis_penalty?` -${e.recovery_hysteresis_penalty}`:``]}):e.stale_policy||e.stale_generation?(0,E.jsx)(`span`,{className:`pill warn`,children:H(e.stale_reason||`stale`)}):e.provenance_missing?(0,E.jsx)(`span`,{className:`pill warn`,children:`provenance missing`}):`нет`,String(e.score_adjustment),(e.reasons||[]).join(`, `)||`нет`,String(e.consecutive_failures||0),e.last_send_duration_ms==null?`н/д`:`${e.last_send_duration_ms}мс`,V(e.expires_at)])}),ne.length===0&&(0,E.jsx)(`p`,{className:`muted`,children:`Пока нет свежих наблюдений. Узел будет присылать их после реального traffic через service-channel runtime.`})]})]}),k===`services`&&(0,E.jsxs)(E.Fragment,{children:[(0,E.jsxs)(`div`,{className:`nodeDetailGrid`,children:[(0,E.jsxs)(`section`,{className:`nodePanel`,children:[(0,E.jsx)(`h4`,{children:p.nodeRoles}),(0,E.jsxs)(`div`,{className:`serviceTags`,children:[n.length===0&&(0,E.jsx)(`p`,{className:`muted`,children:p.noRoles}),n.map(e=>(0,E.jsxs)(`div`,{className:`serviceTag`,children:[(0,E.jsx)(`strong`,{children:rt(e.role)}),(0,E.jsx)(`span`,{children:e.organization_id?`organization: ${B(e.organization_id)}`:`cluster-wide`}),(0,E.jsx)(`small`,{children:V(e.assigned_at)}),(0,E.jsx)(`span`,{className:`pill ${Pn(e.role,m)}`,children:Fn(e.role,m,p)})]},e.id))]})]}),(0,E.jsxs)(`section`,{className:`nodePanel`,children:[(0,E.jsx)(`h4`,{children:`Capabilities`}),(0,E.jsxs)(`div`,{className:`summaryChips`,children:[se.length===0&&(0,E.jsx)(`span`,{className:`muted`,children:`Нет capability heartbeat.`}),se.slice(0,40).map(([e,t])=>(0,E.jsx)(`span`,{className:t===!0?`pill good`:`pill`,children:e},e))]})]})]}),(0,E.jsxs)(`div`,{className:`nodeDetailGrid`,children:[(0,E.jsxs)(`section`,{className:`nodePanel`,children:[(0,E.jsx)(`h4`,{children:p.desiredServices}),(0,E.jsx)(N,{columns:[`service`,`desired`,`runtime`,`version`,`updated`],rows:r.map(e=>[e.service_type,H(e.desired_state),e.runtime_mode,e.version||`не закреплена`,V(e.updated_at)])})]}),(0,E.jsxs)(`section`,{className:`nodePanel`,children:[(0,E.jsx)(`h4`,{children:p.observedServices}),(0,E.jsx)(N,{columns:[`service`,`reported`,`runtime`,`version`,`observed`],rows:i.map(e=>[e.service_type,H(e.reported_state),e.runtime_mode,e.version||`н/д`,V(e.observed_at)])})]})]})]}),k===`telemetry`&&(0,E.jsxs)(E.Fragment,{children:[(0,E.jsxs)(`section`,{className:`nodePanel`,children:[(0,E.jsx)(`h4`,{children:p.nodeTelemetry}),(0,E.jsx)(xe,{items:o,emptyText:p.noTelemetry}),(0,E.jsxs)(`div`,{className:`stateList`,children:[(0,E.jsx)(A,{label:`Disk`,value:`${$n(h?.disk_used_bytes)} / ${$n(h?.disk_total_bytes)}`}),(0,E.jsx)(A,{label:`Network RX/TX`,value:`${$n(h?.network_rx_bytes)} / ${$n(h?.network_tx_bytes)}`}),(0,E.jsx)(A,{label:`Payload`,value:h?.payload?Ft(h.payload):`н/д`})]})]}),(0,E.jsxs)(`section`,{className:`nodePanel`,children:[(0,E.jsx)(`h4`,{children:p.recentHeartbeats}),(0,E.jsx)(N,{columns:[`состояние`,`версия`,`listener`,`mesh recovery`,`mesh intents`,`rv leases`,`path decisions`,`route gen`,`route health`,`наблюдение`],rows:a.slice(0,10).map(e=>[e.health_status,e.reported_version||`неизвестно`,Wn(e),Ln(e),Rn(e),zn(e),Bn(e),Vn(e),Hn(e),V(e.observed_at)])})]})]}),k===`updates`&&(0,E.jsxs)(E.Fragment,{children:[(0,E.jsxs)(`div`,{className:`nodeDetailGrid`,children:[(0,E.jsxs)(`section`,{className:`nodePanel`,children:[(0,E.jsx)(`h4`,{children:`Текущая сборка`}),(0,E.jsxs)(`div`,{className:`stateList`,children:[(0,E.jsx)(A,{label:`Node-agent version`,value:e.reported_version||m?.reported_version||`неизвестно`}),(0,E.jsx)(A,{label:`План`,value:d?`${d.action}: ${d.reason}`:`не загружен`}),(0,E.jsx)(A,{label:`Product`,value:d?.product||`rap-node-agent`}),(0,E.jsx)(A,{label:`Target`,value:d?.target_version||`н/д`}),(0,E.jsx)(A,{label:`Strategy`,value:d?.strategy||`н/д`}),(0,E.jsx)(A,{label:`Rollback`,value:d?.rollback_allowed?`разрешен`:`нет`}),(0,E.jsx)(A,{label:`Artifact`,value:d?.artifact?`${d.artifact.kind} ${d.artifact.os}/${d.artifact.arch}`:`н/д`})]}),(0,E.jsxs)(`div`,{className:`actions`,children:[(0,E.jsx)(`button`,{className:`primary`,disabled:!u,onClick:()=>u?.(e,`rap-node-agent`,null),children:`Node-agent latest`}),(0,E.jsx)(`button`,{className:`ghost`,disabled:!u||!d?.target_version,onClick:()=>u?.(e,`rap-node-agent`,d?.target_version||null),children:`Повторить target`}),(0,E.jsx)(`button`,{className:`ghost`,disabled:!u,onClick:()=>u?.(e,`rap-host-agent`,null),children:`Host-agent latest`})]}),(0,E.jsx)(`p`,{className:`muted`,children:`Latest означает policy без закрепленной версии: updater будет брать свежий active release своего канала при следующем цикле или heartbeat hint.`})]}),(0,E.jsxs)(`section`,{className:`nodePanel`,children:[(0,E.jsx)(`h4`,{children:`Последние отчеты updater`}),(0,E.jsxs)(`div`,{className:`stateList`,children:[(0,E.jsx)(A,{label:`Updater health`,value:`${fe.label}: ${fe.detail}`}),(0,E.jsx)(A,{label:`rap-node-agent`,value:ct(le)}),(0,E.jsx)(A,{label:`rap-host-agent`,value:ct(ue)}),(0,E.jsx)(A,{label:`Всего отчетов`,value:String(f.length)}),(0,E.jsx)(A,{label:`Последний отчет`,value:V(de?.observed_at)})]}),(0,E.jsxs)(`div`,{className:`summaryChips`,children:[(0,E.jsx)(`span`,{className:`pill ${fe.tone}`,children:fe.label}),le&&(0,E.jsxs)(`span`,{className:`pill ${ut(le)}`,children:[`node-agent: `,le.status]}),ue&&(0,E.jsxs)(`span`,{className:`pill ${ut(ue)}`,children:[`host-agent: `,ue.status]}),!le&&!ue&&(0,E.jsx)(`span`,{className:`pill warn`,children:`updater пока не отчитался`})]})]})]}),(0,E.jsxs)(`section`,{className:`nodePanel`,children:[(0,E.jsx)(`h4`,{children:`История обновлений`}),(0,E.jsx)(N,{columns:[`product`,`current`,`target`,`phase`,`status`,`attempt`,`error`,`observed`],rows:f.slice(0,40).map(e=>[e.product,e.current_version||`н/д`,e.target_version||`н/д`,e.phase,(0,E.jsx)(`span`,{className:`pill ${ut(e)}`,children:e.status}),e.attempt_id?B(e.attempt_id):`н/д`,e.error_message||`нет`,V(e.observed_at)])})]}),(0,E.jsxs)(`section`,{className:`nodePanel`,children:[(0,E.jsx)(`h4`,{children:`Windows repair/update command`}),(0,E.jsx)(`p`,{className:`muted`,children:`Для существующего Windows-узла эта команда переустанавливает wrapper updater без нового join-token, сохраняет local state и запускает обновление до актуальной сборки.`}),(0,E.jsxs)(`div`,{className:`stateList compact`,children:[(0,E.jsx)(A,{label:`Когда выполнять`,value:`если updater stale, host-agent не отчитался или Windows-узел не доходит до target version`}),(0,E.jsx)(A,{label:`Control API endpoint`,value:R()}),(0,E.jsx)(A,{label:`Join-token`,value:`не нужен для repair существующего узла`})]}),(0,E.jsxs)(`div`,{className:`actions`,children:[(0,E.jsx)(`button`,{className:`primary`,onClick:()=>hn(fn(e),dn(e,pe)),children:`Скачать repair .cmd`}),(0,E.jsx)(`button`,{className:`ghost`,onClick:()=>void gn(dn(e,pe)),children:`Скопировать команду`})]}),(0,E.jsx)(`pre`,{className:`codePreview`,children:dn(e,pe)})]}),(0,E.jsxs)(`section`,{className:`nodePanel`,children:[(0,E.jsx)(`h4`,{children:`Linux repair/update command`}),(0,E.jsx)(`p`,{className:`muted`,children:`Для существующего Ubuntu/Linux-узла эта команда восстанавливает systemd updater без нового join-token, сохраняет local state и делает одноразовую проверку обновления.`}),(0,E.jsxs)(`div`,{className:`stateList compact`,children:[(0,E.jsx)(A,{label:`Когда выполнять`,value:`если host-agent не отчитался, updater stale или Linux-узел не доходит до target version`}),(0,E.jsx)(A,{label:`Control API endpoint`,value:R()}),(0,E.jsx)(A,{label:`Join-token`,value:`не нужен для repair существующего узла`})]}),(0,E.jsxs)(`div`,{className:`actions`,children:[(0,E.jsx)(`button`,{className:`primary`,onClick:()=>hn(mn(e),pn(e,pe)),children:`Скачать repair .sh`}),(0,E.jsx)(`button`,{className:`ghost`,onClick:()=>void gn(pn(e,pe)),children:`Скопировать команду`})]}),(0,E.jsx)(`pre`,{className:`codePreview`,children:pn(e,pe)})]}),(0,E.jsxs)(`section`,{className:`nodePanel`,children:[(0,E.jsx)(`h4`,{children:`Payload последнего отчета`}),(0,E.jsxs)(`div`,{className:`rawDetailsGrid`,children:[(0,E.jsx)(Ce,{title:`rap-node-agent update status`,value:le}),(0,E.jsx)(Ce,{title:`rap-host-agent update status`,value:ue}),(0,E.jsx)(Ce,{title:`Update plan`,value:d})]})]})]}),k===`raw`&&(0,E.jsxs)(`section`,{className:`nodePanel`,children:[(0,E.jsx)(`h4`,{children:`Raw данные узла`}),(0,E.jsxs)(`div`,{className:`rawDetailsGrid`,children:[(0,E.jsx)(Ce,{title:`Последний heartbeat metadata`,value:m?.metadata}),(0,E.jsx)(Ce,{title:`Heartbeat capabilities`,value:m?.capabilities}),(0,E.jsx)(Ce,{title:`Heartbeat service states`,value:m?.service_states}),(0,E.jsx)(Ce,{title:`Synthetic mesh config`,value:c}),(0,E.jsx)(Ce,{title:`Listener report`,value:g}),(0,E.jsx)(Ce,{title:`Endpoint report`,value:v}),(0,E.jsx)(Ce,{title:`Peer recovery report`,value:x}),(0,E.jsx)(Ce,{title:`Connection intent report`,value:S}),(0,E.jsx)(Ce,{title:`Connection manager report`,value:C}),(0,E.jsx)(Ce,{title:`Rendezvous lease report`,value:w}),(0,E.jsx)(Ce,{title:`Route decision report`,value:T}),(0,E.jsx)(Ce,{title:`Route generation report`,value:ee}),(0,E.jsx)(Ce,{title:`Route health report`,value:te})]})]})]})}function Ce({title:e,value:t}){return(0,E.jsxs)(`details`,{className:`rawBlock`,children:[(0,E.jsx)(`summary`,{children:e}),(0,E.jsx)(`pre`,{children:t==null?`н/д`:JSON.stringify(t,null,2)})]})}function we({runtime:e}){return(0,E.jsxs)(`div`,{className:`runtimeBadges`,children:[(0,E.jsx)(`span`,{className:`pill ${e.agentTone}`,children:e.agentLabel}),(0,E.jsx)(`span`,{className:`pill ${e.clientTone}`,children:e.clientLabel}),(0,E.jsx)(`span`,{className:`pill ${e.outboundTone}`,children:e.outboundLabel}),(0,E.jsx)(`span`,{className:`pill ${e.inboundTone}`,children:e.inboundLabel})]})}function Te({node:e,fallback:t,heartbeatsByNode:n,meshLinks:r}){if(!e)return t;let i=Dt(e,n[e.id]||[],r);return(0,E.jsxs)(`div`,{className:`nodeEndpointCell`,children:[(0,E.jsx)(`strong`,{children:e.name}),(0,E.jsx)(we,{runtime:i}),(0,E.jsx)(`small`,{children:i.address})]})}function Ee({nodes:e,links:t,heartbeatsByNode:n,rolesByNode:r,workloadsByNode:i,labels:a,emptyText:o}){let[s,c]=(0,_.useState)(null);if(e.length===0)return(0,E.jsx)(ye,{title:`Нет узлов`,text:`Одобренные node-agent появятся на карте после первого heartbeat.`});let l=yt(t).filter(e=>e.source_node_id!==e.target_node_id),u=new Map(e.map(e=>[e.id,e])),d=l.filter(e=>Fe(e)&&!He(e,u)).map(e=>({link:e,status:Pe(e,l,u),kind:`direct`})).filter(e=>e.status===`reachable`||e.status===`one_way`),f=l.filter(e=>Ie(e)&&!He(e,u)).map(e=>({link:e,status:Pe(e,l,u),kind:`relay`})).filter(e=>e.status===`reachable`||e.status===`one_way`),p=l.filter(e=>P(e,`observation_type`)===`synthetic_route_health`&&!He(e,u)&&e.link_status===`reachable`).map(e=>({link:e,status:`reachable`,kind:`route`})),m=j(d,f,p),h=l.filter(e=>He(e,u)),g=l.filter(e=>!He(e,u)&&e.link_status!==`reachable`),v=Le(m.map(e=>e.link)),y=new Map(e.map(e=>[e.id,M(n[e.id]?.[0])])),b=[...y.values()].filter(e=>e.mode===`active`).length,x=[...y.values()].filter(e=>e.mode===`passive`).length,S=[...y.values()].filter(e=>e.mode===`mixed`).length,C=Ue(e.length),w=We(e.length),T=Ke(e,C.height,w),ee=new Map(e.map(e=>[e.id,De(e.id,m)]));return(0,E.jsxs)(`div`,{className:`topologyShell`,children:[(0,E.jsxs)(`svg`,{className:`topologySvg`,viewBox:`0 0 ${C.width} ${C.height}`,role:`img`,"aria-label":`Карта трафика узлов Fabric`,children:[(0,E.jsx)(`defs`,{children:(0,E.jsx)(`marker`,{id:`arrow`,markerHeight:`8`,markerWidth:`8`,orient:`auto`,refX:`7`,refY:`4`,children:(0,E.jsx)(`path`,{d:`M0,0 L8,4 L0,8 Z`,fill:`currentColor`})})}),m.map(({link:t,status:n,kind:r})=>{let i=T.get(t.source_node_id),a=T.get(t.target_node_id);if(!i||!a)return null;let o=m.some(e=>e.link.source_node_id===t.target_node_id&&e.link.target_node_id===t.source_node_id),s=Xe(t.source_node_id,t.target_node_id,r),l=Ze({source:i,target:a,sourceNodeID:t.source_node_id,targetNodeID:t.target_node_id,positions:T,nodeRadius:w,endpointOffset:w+8,laneOffset:o?9:0,laneSign:s,routeKind:r}),u=ke(Me(t,e,n)),d=Ae(l.labelX,l.labelY,C.width,C.height);return(0,E.jsxs)(`g`,{className:`topologyLinkGroup`,onMouseEnter:()=>c({...u,...d}),onMouseLeave:()=>c(null),children:[(0,E.jsx)(`title`,{children:[u.title,...u.lines].join(` `)}),(0,E.jsx)(`path`,{d:l.d,className:`topologyLink ${Kn(t,n)} ${r}`,markerEnd:`url(#arrow)`}),m.length<=Math.max(6,e.length)&&(0,E.jsx)(`text`,{x:l.labelX,y:l.labelY-8,className:`topologyLinkLabel`,children:Ne(t,n,r)})]},`${r}-${t.id||`${t.source_node_id}-${t.target_node_id}`}`)}),e.map(t=>{let a=T.get(t.id),o=Ge(e.length),s=ee.get(t.id)||`isolated`,l=y.get(t.id)||{mode:`unknown`,detail:`no heartbeat`},u=ze(n[t.id]?.[0]),d=ke(je(t,l,s,u,n[t.id]?.[0],r[t.id]||[],i[t.id]||[])),f=Ae(a.x,a.y+w+12,C.width,C.height);return(0,E.jsxs)(`g`,{className:`topologyNode`,onMouseEnter:()=>c({...d,...f}),onMouseLeave:()=>c(null),children:[(0,E.jsx)(`title`,{children:[d.title,...d.lines].join(` `)}),(0,E.jsx)(`circle`,{cx:a.x,cy:a.y,r:w,className:`topologyNodeCircle ${t.health_status} ${l.mode} web-${u}`}),(0,E.jsx)(`text`,{x:a.x,y:a.y-o.nameOffset,className:`topologyNodeName`,style:{fontSize:o.name},children:qn(t.name,o.maxChars)}),(0,E.jsx)(`text`,{x:a.x,y:a.y+o.metaOffset,className:`topologyNodeMeta`,style:{fontSize:o.meta},children:Oe(l.mode,s)})]},t.id)}),m.length===0&&(0,E.jsx)(`text`,{x:C.width/2,y:C.height-34,className:`topologyEmpty`,children:o}),s&&(0,E.jsx)(`foreignObject`,{x:s.x,y:s.y,width:`360`,height:`190`,className:`topologyTooltipObject`,children:(0,E.jsxs)(`div`,{className:`topologyTooltip`,children:[(0,E.jsx)(`strong`,{children:s.title}),s.lines.slice(0,6).map(e=>(0,E.jsx)(`span`,{children:e},e))]})})]}),(0,E.jsxs)(`div`,{className:`topologyLegend`,children:[(0,E.jsxs)(`span`,{children:[(0,E.jsx)(`i`,{className:`legendLine observed`}),` direct: `,d.length]}),(0,E.jsxs)(`span`,{children:[(0,E.jsx)(`i`,{className:`legendLine relay`}),` relay: `,f.length]}),(0,E.jsxs)(`span`,{children:[(0,E.jsx)(`i`,{className:`legendLine route`}),` route-health: `,p.length]}),(0,E.jsxs)(`span`,{children:[(0,E.jsx)(`i`,{className:`legendLine observed`}),` bidirectional pairs: `,v]}),(0,E.jsxs)(`span`,{children:[(0,E.jsx)(`i`,{className:`legendLine stale`}),` stale/problem: `,h.length,`/`,g.length]}),(0,E.jsxs)(`span`,{children:[(0,E.jsx)(`i`,{className:`legendDot webReady`}),` web ready`]}),(0,E.jsxs)(`span`,{children:[(0,E.jsx)(`i`,{className:`legendDot webDegraded`}),` web degraded`]}),(0,E.jsxs)(`span`,{children:[(0,E.jsx)(`i`,{className:`legendDot webBlocked`}),` web blocked`]}),(0,E.jsxs)(`span`,{children:[`active/passive/mixed: `,b,`/`,x,`/`,S]})]}),(0,E.jsxs)(`details`,{className:`sectionBlock fabricNodeDiagnostics`,children:[(0,E.jsxs)(`summary`,{children:[`Диагностика узлов (`,e.length,`)`]}),(0,E.jsx)(`div`,{className:`serviceTags`,children:e.map(e=>(0,E.jsxs)(`div`,{className:`serviceTag`,children:[(0,E.jsx)(`strong`,{children:e.name}),(0,E.jsxs)(`span`,{children:[H(e.health_status),` / `,H(y.get(e.id)?.mode||`unknown`),` / mesh `,H(ee.get(e.id)||`isolated`)]}),(0,E.jsx)(`small`,{children:Re(n[e.id]?.[0])}),(0,E.jsx)(`small`,{children:tt(r[e.id]||[])}),(0,E.jsx)(`small`,{children:it(i[e.id]||[])})]},e.id))})]})]})}function j(e,t,n){let r=[],i=new Set,a=e=>{let t=`${e.link.source_node_id}->${e.link.target_node_id}`;i.has(t)||(i.add(t),r.push(e))};return e.forEach(a),t.forEach(a),n.forEach(a),r}function De(e,t){let n=t.filter(t=>t.link.source_node_id!==t.link.target_node_id&&(t.link.source_node_id===e||t.link.target_node_id===e));return n.some(e=>e.status===`reachable`||e.status===`one_way`)?`connected`:n.some(e=>e.status!==`stale`)?`degraded`:`isolated`}function Oe(e,t){return`${e===`active`?`A`:e===`passive`?`P`:e===`mixed`?`M`:`?`} / ${t===`connected`?`mesh`:t===`degraded`?`degr`:`iso`}`}function ke(e){let[t,...n]=e.split(` `).filter(Boolean);return{title:t||`Fabric`,lines:n}}function Ae(e,t,n,r){return{x:Math.min(Math.max(18,e+16),Math.max(18,n-360-18)),y:Math.min(Math.max(18,t+12),Math.max(18,r-190-18))}}function je(e,t,n,r,i,a,o){return[e.name,`health: ${H(e.health_status)}`,`mode: ${H(t.mode)} (${t.detail})`,`mesh: ${H(n)}`,`web ingress: ${H(r)} - ${Re(i)}`,`roles: ${tt(a)}`,`services: ${it(o)}`].join(` `)}function Me(e,t,n){let r=L(t,e.source_node_id),i=L(t,e.target_node_id),a=V(e.observed_at),o=P(e,`observation_type`)||`link`,s=P(e,`transport_mode`)||`direct`,c=St(e,t),l=e.latency_ms==null?`н/д`:`${e.latency_ms}мс`;return[`${r} -> ${i}`,`status: ${Ct(e,t,n)}`,`type: ${o}`,`mode: ${s}`,`latency: ${l}`,`path: ${c}`,`observed: ${a}`].join(` `)}function Ne(e,t,n=`direct`){return t===`one_way`?`1w`:n===`relay`?`relay`:n===`route`?`route`:e.latency_ms!=null&&e.latency_ms>0?`${e.latency_ms}мс`:``}function Pe(e,t,n){if(He(e,n))return`stale`;if(e.link_status!==`reachable`)return e.link_status===`degraded`||e.link_status===`unreachable`?e.link_status:`unknown`;let r=t.find(t=>t.source_node_id===e.target_node_id&&t.target_node_id===e.source_node_id&&!He(t,n));return!r||r.link_status!==`reachable`?`one_way`:`reachable`}function Fe(e){if(e.link_status!==`reachable`||P(e,`observation_type`)!==`peer_connection_manager`)return!1;let t=P(e,`transport_mode`);return t===`relay_control`||P(e,`relay_node_id`)?!1:e.metadata?.direct_candidate===!0||t===`direct_quic`||t===`private_lan`}function Ie(e){return P(e,`observation_type`)===`peer_connection_manager`?P(e,`transport_mode`)===`relay_control`||!!P(e,`relay_node_id`):!1}function Le(e){let t=new Set(e.map(e=>`${e.source_node_id}->${e.target_node_id}`)),n=new Set;for(let r of e){if(!t.has(`${r.target_node_id}->${r.source_node_id}`))continue;let e=[r.source_node_id,r.target_node_id].sort().join(`<->`);n.add(e)}return n.size}function M(e){if(!e)return{mode:`unknown`,detail:`no heartbeat`};let t=e.metadata||{},n=F(t.mesh_endpoint_report),r=F(t.mesh_listener_report),i=F(t.mesh_peer_connection_manager_report),a=Ot(i,`peer_connection_ready`),o=Ot(i,`peer_connection_relay_ready`),s=Ot(i,`peer_connection_waiting_rendezvous`),c=I(r,`status`,``),l=I(n,`connectivity_mode`,``),u=Et(n,[`peer_endpoint`,`advertised_endpoint`,`endpoint`]),d=c===`listening`||c===`auto_rebound`,f=l===`outbound_only`||s>0||o>a,p=[d?`listen`:`no-listen`,a?`direct${a}`:``,o?`relay${o}`:``,u?u.replace(/^quic:\/\//,``):``].filter(Boolean);return f&&a>0?{mode:`mixed`,detail:p.join(` `)||`mixed`}:f?{mode:`passive`,detail:p.join(` `)||`outbound/relay`}:d||a>0?{mode:`active`,detail:p.join(` `)||`direct`}:{mode:`unknown`,detail:p.join(` `)||`no runtime`}}function Re(e){let t=F(e?.metadata?.web_ingress_runtime_receiver_report);if(!t)return`web ingress: no report`;let n=t.enabled===!0||t.handler_installed===!0,r=Ot(t,`trusted_key_count`),i=Yt(t.service_classes),a=I(t,`status`,``),o=t.quic_fabric_ready===!0||a===`ready`,s=I(t,`reason`,n?`ready`:`blocked`),c=I(t,`quic_fabric_error`,``),l=i.length>0?i.join(`,`):`no classes`;return n?`web ingress: ${o?`ready`:a||s||`handler`} / keys ${r} / ${c||l}`:`web ingress: ${s}`}function ze(e){let t=F(e?.metadata?.web_ingress_runtime_receiver_report);if(!t)return`missing`;let n=I(t,`status`,``);return n===`ready`||n===`degraded`||n===`blocked`?n:t.handler_installed===!0?`degraded`:`blocked`}function Be(e,t){let n={ready:0,degraded:0,blocked:0,missing:0};for(let r of e){let e=ze(t[r.id]?.[0]);e===`ready`?n.ready+=1:e===`blocked`?n.blocked+=1:e===`degraded`?n.degraded+=1:n.missing+=1}return{...n,label:`${n.ready}/${e.length} ready, ${n.degraded} degraded, ${n.blocked} blocked`}}function Ve(e){let t=new Set;for(let n of nt(e))switch(n.role){case`global-admin-runtime`:t.add(`platform_admin`);break;case`cluster-admin-runtime`:t.add(`cluster_admin`);break;case`organization-portal-runtime`:t.add(`organization_portal`);break;case`user-portal-runtime`:t.add(`user_portal`);break}return[...t]}function He(e,t){if(e.link_status===`stale`||e.metadata?.derived_link_stale===!0)return!0;let n=new Date(e.observed_at).getTime();if(!Number.isFinite(n)||Date.now()-n>900*1e3)return!0;if(!t)return!1;let r=t.get(e.source_node_id),i=t.get(e.target_node_id);return r?.health_status!==`healthy`||i?.health_status!==`healthy`}function Ue(e){let t=qe(e),n=Math.max(Math.ceil(e/t),1);return{width:1280,height:Math.max(720,220+n*148)}}function We(e){return e>48?22:e>24?26:e>12?32:e>6?40:46}function Ge(e){return e>48?{name:11,meta:8,nameOffset:5,metaOffset:10,memoryOffset:0,maxChars:9}:e>24?{name:13,meta:9,nameOffset:6,metaOffset:12,memoryOffset:0,maxChars:11}:e>12?{name:15,meta:10,nameOffset:7,metaOffset:14,memoryOffset:0,maxChars:13}:e>6?{name:18,meta:12,nameOffset:8,metaOffset:15,memoryOffset:0,maxChars:15}:{name:20,meta:13,nameOffset:9,metaOffset:16,memoryOffset:0,maxChars:18}}function Ke(e,t,n){let r=qe(e.length),i=Math.max(1,Math.ceil(e.length/r)),a=n+98,o=1280-n-98,s=r===1?0:(o-a)/(r-1),c=n+88,l=t-n-88,u=i===1?0:(l-c)/(i-1);return new Map(e.map((e,t)=>{let n=t%r,o=Math.floor(t/r);return[e.id,{x:Math.round(r===1?560:a+s*n),y:Math.round(i===1?(c+l)/2:c+u*o)}]}))}function qe(e){return e>48?8:e>24?6:e>12?5:e>6?4:e>3?3:Math.max(1,e)}function Je(e,t,n){let r=t.x-e.x,i=t.y-e.y,a=Math.max(Math.sqrt(r*r+i*i),1),o=r/a*n,s=i/a*n;return{x1:e.x+o,y1:e.y+s,x2:t.x-o,y2:t.y-s}}function Ye(e,t,n,r,i){let a=Je(e,t,n);if(r===0)return a;let o=t.x-e.x,s=t.y-e.y,c=Math.max(Math.sqrt(o*o+s*s),1),l=-s/c*r*i,u=o/c*r*i;return{x1:a.x1+l,y1:a.y1+u,x2:a.x2+l,y2:a.y2+u}}function Xe(e,t,n){let r=`${e}:${t}:${n}`,i=0;for(let e=0;e=.94)continue;let o=u.x1+i*d,s=u.y1+i*f,c=Math.sqrt((t.x-o)**2+(t.y-s)**2);c0?Math.max(72,a+34-_+g*28):0,b=(s+v+y)*c;if(Math.abs(b)<1)return{d:`M ${u.x1} ${u.y1} L ${u.x2} ${u.y2}`,labelX:(u.x1+u.x2)/2,labelY:(u.y1+u.y2)/2};let x=(u.x1+u.x2)/2,S=(u.y1+u.y2)/2,C=x+m*b,w=S+h*b;return{d:`M ${u.x1} ${u.y1} Q ${C} ${w} ${u.x2} ${u.y2}`,labelX:(u.x1+2*C+u.x2)/4,labelY:(u.y1+2*w+u.y2)/4}}function Qe({children:e}){return(0,E.jsx)(`div`,{className:`formGrid`,children:e})}function N({columns:e,rows:t}){return t.length===0?(0,E.jsx)(ye,{title:`Нет данных`,text:`В текущей области пока нечего показать.`}):(0,E.jsx)(`div`,{className:`tableWrap`,children:(0,E.jsxs)(`table`,{children:[(0,E.jsx)(`thead`,{children:(0,E.jsx)(`tr`,{children:e.map(e=>(0,E.jsx)(`th`,{children:e},e))})}),(0,E.jsx)(`tbody`,{children:t.map((e,t)=>(0,E.jsx)(`tr`,{children:e.map((e,n)=>(0,E.jsx)(`td`,{children:e},`${t}-${n}`))},t))})]})})}function $e(e,t){let n=JSON.parse(e||`{}`);if(!n||Array.isArray(n)||typeof n!=`object`)throw Error(`${t}: требуется JSON object.`);return n}function et(e,t){let n=JSON.parse(e||`[]`);if(!Array.isArray(n))throw Error(`${t}: требуется JSON array.`);return n}function tt(e){let t=nt(e);return t.length===0?`активные роли не назначены`:t.map(e=>`${rt(e.role)}${e.organization_id?` @ ${B(e.organization_id)}`:``}`).join(`, `)}function nt(e){return e.filter(e=>e.status===`active`)}function rt(e){let t=oe[e];return t?`${t} (${e})`:e}function it(e){return e.length===0?`нет сервисов`:e.map(e=>`${e.service_type}:${e.reported_state}`).join(`, `)}function at(e,t,n){let r=n.find(e=>e.product===`rap-node-agent`&&e.channel===`stable`&&e.status===`active`)||n.find(e=>e.product===`rap-node-agent`&&e.status===`active`),i=e.reported_version||``,a=t?.target_version||r?.version||``;return e.version_state&&e.version_state!==`unknown`?{status:e.version_state,targetLabel:a?`target ${a}`:`policy target unknown`}:i?t?.action===`update`?{status:`outdated`,targetLabel:`target ${t.target_version||a}`}:a&&i!==a?{status:`outdated`,targetLabel:`latest ${a}`}:a&&i===a?{status:`current`,targetLabel:`latest ${a}`}:{status:t?.reason===`no_update_policy`?`no_policy`:`unknown`,targetLabel:t?.reason||`release policy unknown`}:{status:`unknown`,targetLabel:a?`target ${a}`:`target unknown`}}function ot(e,t){return e.find(e=>e.product===t)}function st(e,t){return e?`${e.product}: ${e.phase}/${e.status}`:t?`${t.action}: ${t.reason}`:`нет отчета`}function ct(e){if(!e)return`нет отчета`;let t=e.target_version?` -> ${e.target_version}`:``,n=e.error_message?`, ошибка: ${e.error_message}`:``;return`${e.current_version||`н/д`}${t}, ${e.phase}/${e.status}, ${V(e.observed_at)}${n}`}function lt(e){return e?`push ${e.pushed||0} / pop ${e.popped||0} / q ${e.queue_depth||0} / drop ${e.dropped||0}`:`нет данных`}function ut(e){if(!e)return`warn`;let t=`${e.phase}:${e.status}`.toLowerCase();return t.includes(`error`)||t.includes(`failed`)||t.includes(`rollback`)?`bad`:t.includes(`success`)||t.includes(`updated`)||t.includes(`noop`)||t.includes(`already_current`)?`good`:t.includes(`download`)||t.includes(`replace`)||t.includes(`plan`)||t.includes(`apply`)?`warn`:``}function dt(e){let t=e.toLowerCase();return t===`healthy`?`good`:t===`fenced`?`bad`:t===`degraded`||t===`operator_retry_cooldown`?`warn`:``}function ft(e){let t=e.toLowerCase();return t===`healthy`?`good`:t===`recovered`||t===`cooldown`||t===`degraded`?`warn`:t===`fenced`||t===`demoted`?`bad`:``}function pt(e){if(e.status===`disabled`||e.lifecycle_status===`disabled`)return`disabled`;if(e.is_expired||e.lifecycle_status===`expired`)return`expired`;let t=Date.parse(e.policy_expires_at||``);return Number.isFinite(t)&&t<=Date.now()?`expired`:e.lifecycle_status||e.status||`active`}function mt(e){let t=pt(e);return t===`active`?`good`:t===`expired`?`warn`:t===`disabled`?``:`warn`}function ht(e){let t=typeof e.node_id==`string`?e.node_id:``;if(t)return B(t);let n=Array.isArray(e.node_ids)?e.node_ids.filter(e=>typeof e==`string`):[];return n.length>0?n.map(B).join(`, `):`selector`}function gt(e){let t=ot(e,`rap-node-agent`),n=ot(e,`rap-host-agent`);if(!t&&!n)return{label:`updater: нет отчета`,detail:`repair/update task не отчитался`,tone:`bad`};let r=[t,n].some(e=>e&&_t(e)),i=!n,a=n?.phase===`apply`&&n?.status===`staged`,o=[t,n].some(e=>e&&ut(e)===`bad`),s=t?`${t.current_version||`?`}->${t.target_version||`?`}`:`node ?`,c=n?`${n.current_version||`?`}->${n.target_version||`?`}`:`host ?`,l=V((n||t)?.observed_at);return o?{label:`updater: ошибка`,detail:`${s}; ${c}; ${l}`,tone:`bad`}:i?{label:`repair updater`,detail:`host-agent не отчитался; ${s}; ${l}`,tone:`warn`}:a?{label:`host-agent staged`,detail:`${c}; нужен следующий запуск updater`,tone:`warn`}:r?{label:`updater: stale`,detail:`${s}; ${c}; ${l}`,tone:`warn`}:{label:`updater: ok`,detail:`${s}; ${c}; ${l}`,tone:`good`}}function _t(e){let t=new Date(e.observed_at).getTime();return!Number.isFinite(t)||Date.now()-t>900*1e3}function vt(e){let t=typeof e.scope?.node_name==`string`?e.scope.node_name:``,n=typeof e.scope?.purpose==`string`?e.scope.purpose:``;return t||n||B(e.id)}function yt(e){let t=new Map;for(let n of e){let e=`${n.source_node_id}->${n.target_node_id}:${bt(n)}`,r=t.get(e);(!r||new Date(n.observed_at).getTime()>new Date(r.observed_at).getTime())&&t.set(e,n)}return[...t.values()]}function bt(e){let t=P(e,`observation_type`)||`default`;return t===`synthetic_route_health`?`${t}:${P(e,`route_id`)||e.id}`:t===`peer_connection_manager`?`${t}:${P(e,`transport_mode`)}:${P(e,`relay_node_id`)}`:t}function xt(e){let t=P(e,`observation_type`);if(t===`synthetic_route_health`){let t=e.metadata?.route_path_drift_detected===!0?`drift`:`ok`;return`route-health ${e.metadata?.route_path_decision_applied===!0?`decision`:`route`} ${t}`}if(t===`peer_connection_manager`){let t=P(e,`transport_mode`)||`manager`,n=P(e,`connection_state`);return n?`${t} ${n}`:t}return t||`link`}function St(e,t){let n=P(e,`route_id`),r=P(e,`route_path_decision_selected_relay_id`)||P(e,`relay_node_id`),i=wt(e,`expected_effective_hops`),a=wt(e,`observed_ack_path`),o=i.length>0?i:a,s=[];return n&&s.push(B(n)),r&&s.push(`via ${B(r)}`),o.length>0&&s.push(o.map(e=>qn(L(t,e))).join(` > `)),s.length>0?s.join(` / `):`н/д`}function Ct(e,t,n=e.link_status===`reachable`?`reachable`:`unknown`){if(n===`stale`)return`stale`;if(n===`one_way`)return`one-way`;let r=P(e,`observation_type`);if(r===`synthetic_route_health`){let n=P(e,`route_path_decision_selected_relay_id`);return n?`relay ${qn(L(t,n),10)}`:e.metadata?.route_path_drift_detected===!0?`drift`:`route`}if(r===`peer_connection_manager`){let n=P(e,`transport_mode`),r=P(e,`relay_node_id`);if(n===`relay_control`||r)return r?`relay ${qn(L(t,r),10)}`:`relay`;if(n===`direct_quic`||n===`private_lan`||P(e,`direct_candidate`)===`true`)return e.latency_ms==null?`direct`:`${e.latency_ms}мс`;if(n)return H(n)}return e.latency_ms==null?`связь`:`${e.latency_ms}мс`}function P(e,t){let n=e.metadata?.[t];return typeof n==`string`?n:``}function wt(e,t){let n=e.metadata?.[t];return Array.isArray(n)?n.filter(e=>typeof e==`string`):[]}function F(e){return e&&typeof e==`object`&&!Array.isArray(e)?e:void 0}function Tt(e){return Array.isArray(e)?e.map(e=>F(e)).filter(e=>!!e):[]}function I(e,t,n=``){let r=e?.[t];return typeof r==`string`?r:typeof r==`number`||typeof r==`boolean`?String(r):n}function Et(e,t){for(let n of t){let t=I(e,n,``);if(t)return t}return``}function Dt(e,t,n){let r=t[0],i=r?.metadata||{},a=F(i.mesh_listener_report),o=F(i.mesh_endpoint_report),s=F(i.mesh_outbound_session_report),c=F(i.mesh_peer_connection_manager_report),l=F(i.mesh_peer_recovery_report),u=Tt(o?.endpoint_candidates)[0],d=Et(o,[`peer_endpoint`,`advertised_endpoint`,`endpoint`])||I(u,`address`,``)||I(a,`effective_listen_addr`,``)||`адрес не прислан`;if(!r&&!e.last_seen_at)return{agentLabel:`agent: no heartbeat`,agentTone:`bad`,clientLabel:`client: unknown`,clientTone:`warn`,outboundLabel:`outbound: no heartbeat`,outboundTone:`bad`,inboundLabel:`inbound: unknown`,inboundTone:`warn`,address:d,detail:`Узел создан/одобрен, но node-agent еще ни разу не прислал heartbeat.`};let f=Ot(c,`peer_connection_ready`)||Ot(l,`peer_connection_ready`)||yt(n).filter(t=>(t.source_node_id===e.id||t.target_node_id===e.id)&&t.link_status===`reachable`).length,p=Ot(c,`peer_connection_total`)||Ot(l,`peer_connection_total`)||yt(n).filter(t=>t.source_node_id===e.id||t.target_node_id===e.id).length,m=Ot(c,`failed`),h=I(a,`status`,``),g=a?.port_conflict===!0,_=a?.one_way_connectivity===!0||I(o,`connectivity_mode`,``)===`outbound_only`||Ot(c,`peer_connection_relay_ready`)>0,v=`inbound: no report`,y=`warn`;h===`listening`||h===`auto_rebound`?(v=h===`auto_rebound`?`inbound: auto port`:`inbound: listening`,y=`good`):h===`listen_failed`?(v=g?`inbound: port busy`:`inbound: failed`,y=`bad`):h===`disabled`?(v=`inbound: disabled`,y=_?`warn`:`bad`):o&&(v=`inbound: advertised`,y=`good`);let b=`client: no peers`,x=`warn`;f>0?(b=`client: ready ${f}/${Math.max(p,f)}`,x=`good`):(m>0||p>0)&&(b=`client: backoff ${f}/${Math.max(p,m)}`,x=`bad`);let S=I(s,`status`,``),C=s?.usable_for_inbound_control===!0,w=Ot(s,`peer_connection_relay_ready`),T=Ot(s,`rendezvous_lease_count`),ee=`outbound: no report`,te=`warn`;S===`ready`?(ee=C?`outbound: ready reverse`:`outbound: ready`,te=`good`):S===`backoff`||S===`failed`?(ee=`outbound: ${S}`,te=`bad`):(_||w>0||T>0)&&(ee=`outbound: inferred`,te=`warn`);let E=e.health_status===`healthy`?`good`:e.health_status===`unknown`?`warn`:`bad`;return{agentLabel:r?`agent: heartbeat`:`agent: stale`,agentTone:E,clientLabel:_&&f>0?`${b} one-way`:b,clientTone:x,outboundLabel:ee,outboundTone:te,inboundLabel:v,inboundTone:y,address:d,detail:I(a,`failure_error`,I(a,`failure_reason`,``))}}function Ot(e,t,n=0){let r=e?.[t];return typeof r==`number`&&Number.isFinite(r)?r:n}function kt(e){let t=e.products.filter(e=>!e.compatible_artifact_found).map(e=>e.product);if(t.length>0)return`Добавить recovery artifacts для ${t.join(`, `)} и не снимать compatibility overlap.`;let n=e.risks.filter(e=>e.startsWith(`stale_node_legacy_recovery_contract_`)).map(e=>e.replace(`stale_node_legacy_recovery_contract_`,``));if(n.length>0)return e.recovery_bridge_replay_ready?`Узел застрял на старом recovery-контракте (${n.join(`, `)}): bridge replay уже готов, держать recovery bridge / compatibility aliases / overlap и ждать следующий recovery-цикл узла.`:`Узел застрял на старом recovery-контракте (${n.join(`, `)}): держать recovery bridge / compatibility aliases / overlap и не удалять старые recovery-форматы до возврата heartbeat.`;let r=e.risks.filter(e=>e.startsWith(`stale_node_unknown_profile_`)).map(e=>e.replace(`stale_node_unknown_profile_`,``));if(r.length>0)return`Неизвестен update profile (${r.join(`, `)}): нужен heartbeat/update-status или fallback-profile alias.`;let i=e.risks.filter(e=>e.startsWith(`stale_node_unknown_`)&&e.endsWith(`_version`)).map(e=>e.replace(`stale_node_unknown_`,``).replace(`_version`,``));if(i.length>0)return`Нет подтвержденной версии (${i.join(`, `)}): сохранить overlap и проверить last known good release mapping.`;let a=e.risks.filter(e=>e.startsWith(`stale_node_no_`)&&e.endsWith(`_update_status`)).map(e=>e.replace(`stale_node_no_`,``).replace(`_update_status`,``));return a.length>0?`Узел молчит и не прислал update-status (${a.join(`, `)}): держать compatibility и чинить recovery channel.`:e.risks.includes(`stale_heartbeat`)?`Узел stale, но recovery artifacts уже есть: не удалять совместимость, ждать исходящий recovery heartbeat и проверить bootstrap/registry gossip.`:`Риск под контролем: можно наблюдать heartbeat и готовить controlled cleanup после отдельной проверки.`}function At(e){let t=e.products.filter(e=>!e.compatible_artifact_found).map(e=>e.product);if(t.length>0)return`artifact gap: ${t.join(`, `)}`;let n=e.risks.filter(e=>e.startsWith(`stale_node_legacy_recovery_contract_`)).map(e=>e.replace(`stale_node_legacy_recovery_contract_`,``));if(n.length>0)return e.recovery_bridge_replay_ready?`bridge replay ready: ${n.join(`, `)}`:`recovery bridge required: ${n.join(`, `)}`;let r=e.risks.filter(e=>e.startsWith(`stale_node_unknown_profile_`)).map(e=>e.replace(`stale_node_unknown_profile_`,``));if(r.length>0)return`profile unknown: ${r.join(`, `)}`;let i=e.risks.filter(e=>e.startsWith(`stale_node_no_`)&&e.endsWith(`_update_status`)).map(e=>e.replace(`stale_node_no_`,``).replace(`_update_status`,``));if(i.length>0)return`waiting update status: ${i.join(`, `)}`;let a=e.risks.filter(e=>e.startsWith(`stale_node_unknown_`)&&e.endsWith(`_version`)).map(e=>e.replace(`stale_node_unknown_`,``).replace(`_version`,``));return a.length>0?`version unknown: ${a.join(`, `)}`:e.heartbeat_stale?`artifacts ready, waiting recovery heartbeat`:`recovery ready`}function jt(e,t){if(!t||e.target_id===t)return!0;let n=F(e.payload);return[`node_id`,`target_node_id`,`reporter_node_id`,`entry_node_id`,`exit_node_id`,`selected_node_id`].some(e=>I(n,e,``)===t)}function Mt(e){let t=Tt(e.endpoint_candidates);if(t.length>0)return t.map(e=>{let t=I(e,`address`,``);if(!t)return``;let n=[t];for(let t of[`reachability`,`connectivity_mode`,`nat_type`,`region`,`priority`]){let r=I(e,t,``);r&&n.push(`${t.replace(`_mode`,``).replace(`_type`,``)}=${r}`)}let r=F(e.metadata);for(let e of[`provider`,`interface`,`maps_to`]){let t=I(r,e,``);t&&n.push(`${e}=${t}`)}return n.join(` `)}).filter(Boolean).join(` `);let n=Array.isArray(e.advertise_endpoints)?e.advertise_endpoints:[];return n.length>0?n.map(e=>String(e||``).trim()).filter(Boolean).join(` `):I(e,`advertise_endpoint`,``)}function Nt(e,t){let n=e.endpointCandidates.split(/\r?\n/).map(e=>e.trim()).filter(e=>e&&!e.startsWith(`#`));n.length===0&&e.advertiseEndpoint.trim()&&n.push(e.advertiseEndpoint.trim());let r=new Set;return n.flatMap((n,i)=>{let a=n.split(/\s+/).filter(Boolean),o=(a.shift()||``).replace(/\/$/,``);if(!o||r.has(o))return[];r.add(o);let s={};for(let e of a){let t=e.indexOf(`=`);t>0?s[e.slice(0,t).trim().toLowerCase()]=e.slice(t+1).trim():[`public`,`private`,`relay`,`outbound_only`,`unknown`].includes(e)?s.reachability=e:[`direct`,`private_lan`,`relay_required`].includes(e)?s.connectivity=e:[`none`,`full_cone`,`restricted`,`port_restricted`,`symmetric`,`blocked`].includes(e)&&(s.nat=e)}let c=s.connectivity||s.connectivity_mode||e.connectivity||`direct`,l=s.reachability||Pt(o,c),u=s.nat||s.nat_type||e.nat||`unknown`,d=Object.fromEntries(Object.entries(s).filter(([e])=>![`reachability`,`connectivity`,`connectivity_mode`,`nat`,`nat_type`,`priority`,`region`,`transport`].includes(e)));return[{endpoint_id:`${t}-operator-${i+1}`,node_id:t,address:o,transport:s.transport||e.advertiseTransport||`direct_quic`,reachability:l,connectivity_mode:c,nat_type:u,region:s.region||e.region||void 0,priority:Number.isFinite(Number(s.priority))?Number(s.priority):i+1,policy_tags:[`operator-configured`,`desired-mesh-listener`],metadata:{source:`web-admin.mesh-listener`,verification_scope:l===`public`?`external-network-required`:`local-or-peer-probe`,...d}}]})}function Pt(e,t){if(t===`relay_required`)return`relay`;if(t===`outbound_only`)return`outbound_only`;let n=e.replace(/^[a-z][a-z0-9+.-]*:\/\//i,``).split(/[/:?#]/)[0]||``;return n===`localhost`||n.startsWith(`127.`)||n.startsWith(`10.`)||n.startsWith(`192.168.`)||/^172\.(1[6-9]|2\d|3[0-1])\./.test(n)?`private`:`public`}function Ft(e){if(e==null)return`н/д`;let t=JSON.stringify(e);return t.length>140?`${t.slice(0,137)}...`:t}function It(e){let t=Tt(e.candidate_results);return t.length===0?`н/д`:t.slice(0,4).map(e=>{let t=I(e,`candidate_id`,`candidate`),n=I(e,`link_status`,`unknown`),r=I(e,`latency_ms`,``);return r&&r!==`0`?`${t}:${n}:${r}мс`:`${t}:${n}`}).join(`, `)}function Lt(e){return Object.values(e.peer_endpoint_candidates||{}).reduce((e,t)=>e+t.length,0)}function Rt(e){let t=e?.rendezvous_relay_policy;if(!t)return`none`;let n=[`stale${t.stale_relay_count}`,`wd${t.withdrawn_lease_count}`,`repl${t.replacement_lease_count}`];t.scoring_mode.includes(`synthetic_route_health_feedback`)&&n.push(`rh feedback`);let r=t.decisions?.find(e=>e.selected_relay_id);return r?.selected_relay_id&&n.push(`via ${B(r.selected_relay_id)}`),n.join(` `)}function zt(e){let t=e?.route_path_decisions;if(!t)return`none`;let n=[`path${t.decision_count}`,`repl${t.replacement_decision_count}`];(t.degraded_decision_count||0)>0&&n.push(`degr${t.degraded_decision_count}`);let r=t.decisions?.find(e=>e.selected_relay_id||e.next_hop_id);return r?.selected_relay_id?n.push(`via ${B(r.selected_relay_id)}`):r?.next_hop_id&&n.push(`next ${B(r.next_hop_id)}`),n.join(` `)}function L(e,t){return e.find(e=>e.id===t)?.name||B(t)}function Bt(e,t){let n=new Map(t.map(e=>[e.id,e])),r=[e.name],i=e.parent_group_id,a=new Set([e.id]);for(;i&&!a.has(i);){a.add(i);let e=n.get(i);if(!e)break;r.unshift(e.name),i=e.parent_group_id}return r.join(` / `)}function Vt(e,t){let n=t.find(t=>t.id===e);return n?Bt(n,t):e}function Ht(e,t){let n=[],r=new Map;for(let e of t){let t=e.parent_group_id||``;r.set(t,[...r.get(t)||[],e])}let i=e=>{for(let t of r.get(e)||[])n.push(t.id),i(t.id)};return i(e),n}function Ut(e,t,n,r,i){let a=[],o=new Map,s=[],c=[];for(let t of e){let e=t.memberships.find(e=>e.cluster.id===n);if(!e){c.push(t);continue}let r=e.node.node_group_id;if(!r){s.push(t);continue}o.set(r,[...o.get(r)||[],t])}let l=new Map;for(let e of t){let t=e.parent_group_id||``;l.set(t,[...l.get(t)||[],e])}for(let e of l.values())e.sort((e,t)=>e.sort_order-t.sort_order||e.name.localeCompare(t.name));let u=new Map,d=e=>{let t=u.get(e.id);if(t!=null)return t;let n=o.get(e.id)?.length||0;for(let t of l.get(e.id)||[])n+=d(t);return u.set(e.id,n),n},f=(e,t)=>{let n=[...o.get(e.id)||[]].sort((e,t)=>e.node.name.localeCompare(t.node.name)),r=l.get(e.id)||[],s=`group-${e.id}`,c=d(e);if(a.push({kind:`group`,key:s,label:e.name,depth:t,count:c,groupId:e.id}),!i.has(s)){for(let r of n)a.push({kind:`node`,key:`node-${e.id}-${r.node.id}`,entry:r,depth:t+1});for(let e of r)f(e,t+1)}return c};for(let e of l.get(``)||[])f(e,0);if(s.length>0){let e=`group-ungrouped`;if(a.push({kind:`group`,key:e,label:r.ungroupedNodes,depth:0,count:s.length}),!i.has(e))for(let e of s.sort((e,t)=>e.node.name.localeCompare(t.node.name)))a.push({kind:`node`,key:`node-ungrouped-${e.node.id}`,entry:e,depth:1})}if(c.length>0){let e=`group-outside-active-cluster`;if(a.push({kind:`group`,key:e,label:r.notMemberOfActiveCluster,depth:0,count:c.length}),!i.has(e))for(let e of c.sort((e,t)=>e.node.name.localeCompare(t.node.name)))a.push({kind:`node`,key:`node-outside-${e.node.id}`,entry:e,depth:1})}return a}function Wt(e,t){return Object.entries(t).filter(([,t])=>t.some(t=>t.role===e&&t.status===`active`)).map(([e])=>e)}function Gt(e){let t=Jt(e),n=t.map(e=>String(e.address||``)).filter(Boolean),r=e.meshAdvertiseEndpoint.trim().replace(/\/$/,``)||n[0]||``,i={roles:e.roles,node_name:e.nodeName.trim()||null,node_group_id:e.nodeGroupId||null,ownership_type:e.ownershipType,purpose:e.purpose.trim()||null,approval:{mode:`manual`,auto_approve:!1,role_assignment:`manual_after_approval`},source:`platform_owner_console`};if(e.installMode===`docker`){let n=(e.controlPlaneEndpoint||Zt()).trim().replace(/\/$/,``);i.install_profile=`docker`,i.backend_url=n,i.control_plane_endpoints=[n],i.image=e.dockerImage||`rap-node-agent:latest`,e.dockerContainerName.trim()&&(i.container_name=e.dockerContainerName.trim()),i.artifact_endpoints=$t(e.artifactEndpoints||Qt()),e.dockerImageArtifactSHA256.trim()&&(i.docker_image_artifact_sha256=e.dockerImageArtifactSHA256.trim()),i.network=e.dockerNetwork||`host`,i.restart_policy=`unless-stopped`,i.pull_image=!!e.pullImage,i.replace=e.replace!==!1,i.mesh_synthetic_runtime_enabled=e.syntheticRuntime===!0,i.mesh_production_forwarding_enabled=!1,i.mesh_listen_addr=e.meshListenAddr||``,i.mesh_listen_port_mode=e.meshListenPortMode||`auto`,i.mesh_listen_auto_port_start=e.meshListenAutoPortStart||19131,i.mesh_listen_auto_port_end=e.meshListenAutoPortEnd||19231,r&&(i.mesh_advertise_endpoint=r),t.length>0&&(i.mesh_advertise_endpoints_json=JSON.stringify(t)),i.mesh_advertise_transport=e.meshAdvertiseTransport||`direct_quic`,i.mesh_connectivity_mode=e.meshConnectivityMode||`private_lan`,i.mesh_nat_type=e.meshNATType||`unknown`,i.mesh_region=e.meshRegion||null}if(e.installMode===`windows_service`){let n=(e.controlPlaneEndpoint||Zt()).trim().replace(/\/$/,``);i.install_profile=`windows_service`,i.backend_url=n,i.control_plane_endpoints=[n],i.artifact_endpoints=$t(e.artifactEndpoints||Qt()),i.startup_mode=e.windowsStartupMode||`auto`,e.windowsInstallDir.trim()&&(i.install_dir=e.windowsInstallDir.trim()),e.windowsNodeAgentSHA256.trim()&&(i.node_agent_artifact_sha256=e.windowsNodeAgentSHA256.trim()),i.mesh_synthetic_runtime_enabled=e.syntheticRuntime===!0,i.mesh_production_forwarding_enabled=!1,i.mesh_listen_addr=e.meshListenAddr||``,i.mesh_listen_port_mode=e.meshListenPortMode||`auto`,i.mesh_listen_auto_port_start=e.meshListenAutoPortStart||19131,i.mesh_listen_auto_port_end=e.meshListenAutoPortEnd||19231,r&&(i.mesh_advertise_endpoint=r),t.length>0&&(i.mesh_advertise_endpoints_json=JSON.stringify(t)),i.mesh_advertise_transport=e.meshAdvertiseTransport||`direct_quic`,i.mesh_connectivity_mode=e.meshConnectivityMode||`outbound_only`,i.mesh_nat_type=e.meshNATType||`unknown`,i.mesh_region=e.meshRegion||`windows`}if(e.installMode===`linux_binary`){let n=(e.controlPlaneEndpoint||Zt()).trim().replace(/\/$/,``);i.install_profile=`linux_binary`,i.backend_url=n,i.control_plane_endpoints=[n],i.artifact_endpoints=$t(e.artifactEndpoints||Qt()),i.startup_mode=`systemd`,e.linuxInstallDir.trim()&&(i.install_dir=e.linuxInstallDir.trim()),e.linuxNodeAgentSHA256.trim()&&(i.node_agent_artifact_sha256=e.linuxNodeAgentSHA256.trim()),i.replace=e.replace!==!1,i.mesh_synthetic_runtime_enabled=e.syntheticRuntime===!0,i.mesh_production_forwarding_enabled=!1,i.mesh_listen_addr=e.meshListenAddr||``,i.mesh_listen_port_mode=e.meshListenPortMode||`auto`,i.mesh_listen_auto_port_start=e.meshListenAutoPortStart||19131,i.mesh_listen_auto_port_end=e.meshListenAutoPortEnd||19231,r&&(i.mesh_advertise_endpoint=r),t.length>0&&(i.mesh_advertise_endpoints_json=JSON.stringify(t)),i.mesh_advertise_transport=e.meshAdvertiseTransport||`direct_quic`,i.mesh_connectivity_mode=e.meshConnectivityMode||`outbound_only`,i.mesh_nat_type=e.meshNATType||`unknown`,i.mesh_region=e.meshRegion||`linux`}return i}function Kt(e,t){let n=Yt(e.roles),r=Yt(e.artifact_endpoints).join(`, `);return{...t,roles:n.length>0?n:t.roles,nodeName:I(e,`node_name`,``)||t.nodeName,nodeGroupId:I(e,`node_group_id`,``)||t.nodeGroupId,ownershipType:I(e,`ownership_type`,t.ownershipType),purpose:I(e,`purpose`,``)||t.purpose,installMode:I(e,`install_profile`,t.installMode),dockerImage:I(e,`image`,t.dockerImage),dockerContainerName:I(e,`container_name`,``)||t.dockerContainerName,dockerNetwork:I(e,`network`,t.dockerNetwork),windowsStartupMode:I(e,`startup_mode`,t.windowsStartupMode),windowsInstallDir:I(e,`install_dir`,``)||t.windowsInstallDir,windowsNodeAgentSHA256:I(e,`node_agent_artifact_sha256`,``)||t.windowsNodeAgentSHA256,linuxInstallDir:I(e,`install_dir`,``)||t.linuxInstallDir,linuxNodeAgentSHA256:I(e,`node_agent_artifact_sha256`,``)||t.linuxNodeAgentSHA256,meshListenAddr:I(e,`mesh_listen_addr`,t.meshListenAddr),meshListenPortMode:I(e,`mesh_listen_port_mode`,t.meshListenPortMode),meshListenAutoPortStart:Ot(e,`mesh_listen_auto_port_start`,t.meshListenAutoPortStart),meshListenAutoPortEnd:Ot(e,`mesh_listen_auto_port_end`,t.meshListenAutoPortEnd),meshAdvertiseEndpoint:I(e,`mesh_advertise_endpoint`,``)||t.meshAdvertiseEndpoint,meshAdvertiseEndpoints:qt(e)||t.meshAdvertiseEndpoints,meshAdvertiseTransport:I(e,`mesh_advertise_transport`,t.meshAdvertiseTransport),meshConnectivityMode:I(e,`mesh_connectivity_mode`,t.meshConnectivityMode),meshNATType:I(e,`mesh_nat_type`,t.meshNATType),meshRegion:I(e,`mesh_region`,``)||t.meshRegion,controlPlaneEndpoint:Yt(e.control_plane_endpoints)[0]||I(e,`backend_url`,``)||t.controlPlaneEndpoint,artifactEndpoints:r||t.artifactEndpoints,dockerImageArtifactSHA256:I(e,`docker_image_artifact_sha256`,``)||t.dockerImageArtifactSHA256,pullImage:Xt(e,`pull_image`,t.pullImage),replace:Xt(e,`replace`,t.replace),syntheticRuntime:Xt(e,`mesh_synthetic_runtime_enabled`,t.syntheticRuntime)}}function qt(e){let t=I(e,`mesh_advertise_endpoints_json`,``);if(!t)return``;try{let e=JSON.parse(t);return Array.isArray(e)?e.map(e=>{let t=F(e);if(!t)return``;let n=I(t,`address`,``);if(!n)return``;let r=[n];for(let e of[`reachability`,`connectivity_mode`,`nat_type`,`region`,`priority`]){let n=I(t,e,``);n&&r.push(`${e.replace(`_mode`,``).replace(`_type`,``)}=${n}`)}let i=F(t.metadata);for(let e of[`provider`,`interface`,`maps_to`]){let t=I(i,e,``);t&&r.push(`${e}=${t}`)}return r.join(` `)}).filter(Boolean).join(` `):``}catch{return``}}function Jt(e){return Nt({endpointCandidates:e.meshAdvertiseEndpoints,advertiseEndpoint:e.meshAdvertiseEndpoint,advertiseTransport:e.meshAdvertiseTransport||`direct_quic`,connectivity:e.meshConnectivityMode,nat:e.meshNATType,region:e.meshRegion},e.nodeName.trim()||`install-node`)}function Yt(e){return Array.isArray(e)?e.filter(e=>typeof e==`string`).map(e=>e.trim()).filter(Boolean):[]}function Xt(e,t,n){let r=e[t];return typeof r==`boolean`?r:n}function Zt(){return typeof window>`u`||!window.location?.origin?`http://:18080/api/v1`:`${window.location.origin.replace(/\/$/,``)}/api/v1`}function Qt(){return typeof window>`u`||!window.location?.origin?`http://:18080/downloads`:`${window.location.origin.replace(/\/$/,``)}/downloads`}function $t(e){return e.split(`,`).map(e=>e.trim().replace(/\/$/,``)).filter(Boolean)}function en(e){return $t(e.artifactEndpoints||Qt()).map(e=>`${e}/rap-node-agent-dev-enrollment-bootstrap-smoke.tar`)}function tn(e){return e.meshConnectivityMode===`outbound_only`?`outbound_only`:e.meshConnectivityMode===`private_lan`?`private_lan`:e.meshNATType!==`none`&&e.meshAdvertiseEndpoint.trim()?`nat_forward`:`direct`}function nn(e,t){let n={...e};return t===`private_lan`?(n.meshConnectivityMode=`private_lan`,n.meshNATType=`none`):t===`direct`?(n.meshConnectivityMode=`direct`,n.meshNATType=`none`):t===`nat_forward`?(n.meshConnectivityMode=`direct`,n.meshNATType=`port_restricted`):(n.meshConnectivityMode=`outbound_only`,n.meshNATType=`symmetric`,n.meshAdvertiseEndpoint=``),n}function rn(e,t){return e.nodeName.trim()?e.nodeName.trim():`${Tn(t?.slug||t?.name||`rap-node`)}-node-1`}function an(e,t){return e.dockerContainerName.trim()?e.dockerContainerName.trim():`rap-node-agent-${Tn(rn(e,t))}`}function on(e,t,n=ue){let r=t?.id||e.cluster_id,i=rn(n,t),a=an(n,t),o=Tn(i),s=[`rap-host-agent install`,`--backend-url ${z(xn(n))}`,`--cluster-id ${z(r)}`,`--join-token ${z(e.token)}`,`--node-name ${z(i)}`,`--image ${z(n.dockerImage||`rap-node-agent:latest`)}`,`--container-name ${z(a)}`,`--state-dir ${z(`/var/lib/rap/nodes/${o}`)}`,`--network host`,`--replace`];for(let e of en(n))s.push(`--image-artifact-url ${z(e)}`);return n.dockerImageArtifactSHA256.trim()&&s.push(`--image-artifact-sha256 ${z(n.dockerImageArtifactSHA256.trim())}`),s.join(` \\ `)}function sn(e,t,n=ue){let r=t?.id||e.cluster_id,i=rn(n,t),a=[`sudo "$rap_host_agent" install`,`--profile-url ${z(xn(n))}`,`--cluster-id ${z(r)}`,`--install-token ${z(e.token)}`,`--node-name ${z(i)}`].join(` \\ `);return[`rap_host_agent="$(mktemp /tmp/rap-host-agent.XXXXXX)"`,`curl -fL --retry 3 --retry-delay 1 ${z(Cn(n))} -o "$rap_host_agent"`,`chmod +x "$rap_host_agent"`,a].join(` && \\ `)}function cn(e,t,n=ue){let r=t?.id||e.cluster_id,i=rn(n,t),a=[`sudo "$rap_host_agent" install-linux`,`--profile-url ${z(xn(n))}`,`--cluster-id ${z(r)}`,`--install-token ${z(e.token)}`,`--node-name ${z(i)}`].join(` \\ `);return[`rap_host_agent="$(mktemp /tmp/rap-host-agent.XXXXXX)"`,`curl -fL --retry 3 --retry-delay 1 ${z(Cn(n))} -o "$rap_host_agent"`,`chmod +x "$rap_host_agent"`,a].join(` && \\ `)}function ln(e,t,n=ue){let r=t?.id||e.cluster_id,i=rn(n,t),a=xn(n);return[`$rapHostAgent = Join-Path $env:TEMP "rap-host-agent.exe"`,`Invoke-WebRequest -UseBasicParsing ${En(wn(n))} -OutFile $rapHostAgent`,`& $rapHostAgent install-windows --profile-url ${En(a)} --cluster-id ${En(r)} --install-token ${En(e.token)} --node-name ${En(i)} --startup-mode ${En(n.windowsStartupMode||`auto`)}`].join(`\r `)}function un(e,t,n=ue){let r=t?.id||e.cluster_id,i=rn(n,t),a=xn(n),o=wn(n),s=n.windowsStartupMode||`auto`;return[`powershell -NoProfile -ExecutionPolicy Bypass -Command "Invoke-WebRequest -UseBasicParsing '${o}' -OutFile $env:TEMP\\rap-host-agent.exe"`,`%TEMP%\\rap-host-agent.exe install-windows --profile-url "${a}" --cluster-id "${r}" --install-token "${e.token}" --node-name "${i}" --startup-mode "${s}"`].join(`\r `)}function dn(e,t){let n=R(),r=n.replace(/\/api\/v1$/i,``).replace(/\/api$/i,``).replace(/\/$/,``),i=e.name||e.node_key||e.id,a=vn(i),o=`%ProgramFiles%\\RAP\\${a}`,s=`%ProgramData%\\RAP\\nodes\\${a}`,c=`RAP Node Agent ${a}`,l=`RAP Host Agent Updater ${a}`,u=`${o}\\rap-host-agent.exe`,d=`${u}.next`;return[`@echo off`,`echo === RAP Windows updater repair: ${Dn(i)} ===`,`echo Node ID: ${e.id}`,`echo Control API endpoint: ${n}`,`echo.`,`echo === Before repair: scheduled tasks ===`,`schtasks /Query /TN "${c}" /V /FO LIST`,`schtasks /Query /TN "${l}" /V /FO LIST`,`echo.`,`echo === Before repair: binaries ===`,`dir "${o}\\rap-*.exe*"`,`echo.`,`powershell -NoProfile -ExecutionPolicy Bypass -Command "Invoke-WebRequest -UseBasicParsing '${r}/downloads/rap-host-agent-windows-amd64.exe' -OutFile $env:TEMP\\rap-host-agent.exe"`,`%TEMP%\\rap-host-agent.exe install-windows --backend-url "${n}" --cluster-id "${t||``}" --node-id "${e.id}" --node-name "${Dn(i)}" --replace --startup-mode "auto" --auto-update-current-version "0.0.0" --auto-update-initial-delay-seconds 1`,`"${u}" update-loop --backend-url "${n}" --cluster-id "${t||``}" --node-id "${e.id}" --state-dir "${s}" --current-version "0.0.0" --os windows --arch amd64 --install-type windows_service --binary-path "${o}\\rap-node-agent.exe" --windows-task-name "${c}" --health-timeout-seconds 30 --interval-seconds 0 --initial-delay-seconds 0 --max-runs 1 --host-agent-update-status-enabled --host-agent-current-version "0.0.0" --host-agent-binary-path "${u}"`,`echo.`,`echo === Applying staged host-agent if present ===`,`if exist "${d}" copy /Y "${d}" "${u}"`,`if exist "${d}" del /F /Q "${d}"`,`schtasks /End /TN "${l}"`,`schtasks /Run /TN "${l}"`,`echo.`,`echo === After repair: binaries ===`,`dir "${o}\\rap-*.exe*"`,`echo.`,`echo === After repair: updater task ===`,`schtasks /Query /TN "${l}" /V /FO LIST`,`echo.`,`echo Repair command finished. Check the admin panel for rap-node-agent and rap-host-agent plan/noop reports.`].join(`\r `)}function fn(e){return`rap-repair-updater-${_n(e.name||e.node_key||e.id||`node`)}.cmd`}function pn(e,t){let n=R(),r=n.replace(/\/api\/v1$/i,``).replace(/\/api$/i,``).replace(/\/$/,``),i=e.name||e.node_key||e.id,a=yn(i),o=`/opt/rap/${a}`,s=`/var/lib/rap/nodes/${a}`,c=`rap-node-agent-${a}.service`,l=`rap-host-agent-updater-${a}.service`,u=`${o}/rap-host-agent`;return[`#!/usr/bin/env bash`,`set -euo pipefail`,`echo "=== RAP Linux updater repair: ${bn(i)} ==="`,`echo "Node ID: ${e.id}"`,`echo "Control API endpoint: ${n}"`,`echo`,`echo "=== Before repair: systemd units ==="`,`systemctl status ${z(c)} --no-pager || true`,`systemctl status ${z(l)} --no-pager || true`,`echo`,`echo "=== Before repair: binaries ==="`,`ls -la ${z(o)} || true`,`echo`,`rap_host_agent="$(mktemp /tmp/rap-host-agent.XXXXXX)"`,`curl -fL --retry 3 --retry-delay 1 ${z(`${r}/downloads/rap-host-agent-linux-amd64`)} -o "$rap_host_agent"`,`chmod +x "$rap_host_agent"`,`sudo "$rap_host_agent" install-linux --backend-url ${z(n)} --cluster-id ${z(t||``)} --node-id ${z(e.id)} --node-name ${z(i)} --replace --startup-mode systemd --auto-update-current-version 0.0.0 --auto-update-initial-delay-seconds 1`,`sudo ${z(u)} update-loop --backend-url ${z(n)} --cluster-id ${z(t||``)} --node-id ${z(e.id)} --state-dir ${z(s)} --current-version 0.0.0 --os linux --arch amd64 --install-type linux_binary --binary-path ${z(`${o}/rap-node-agent`)} --systemd-unit ${z(c)} --health-timeout-seconds 30 --interval-seconds 0 --initial-delay-seconds 0 --max-runs 1 --host-agent-update-status-enabled --host-agent-current-version 0.0.0 --host-agent-binary-path ${z(u)}`,`sudo systemctl daemon-reload`,`sudo systemctl restart ${z(l)}`,`echo`,`echo "=== After repair: systemd updater ==="`,`systemctl status ${z(l)} --no-pager || true`,`echo "Repair command finished. Check the admin panel for rap-node-agent and rap-host-agent plan/noop reports."`].join(` `)}function mn(e){return`rap-repair-updater-${_n(e.name||e.node_key||e.id||`node`)}.sh`}function hn(e,t){if(typeof document>`u`)return;let n=new Blob([t.endsWith(`\r `)?t:`${t}\r\n`],{type:`text/plain;charset=utf-8`}),r=URL.createObjectURL(n),i=document.createElement(`a`);i.href=r,i.download=e,document.body.appendChild(i),i.click(),i.remove(),URL.revokeObjectURL(r)}async function gn(e){await navigator.clipboard.writeText(e)}function _n(e){return e.trim().replace(/[\\/:*?"<>|]+/g,`-`).replace(/\s+/g,`-`).replace(/-+/g,`-`).replace(/^-|-$/g,``).slice(0,80)||`node`}function vn(e){return e.trim().replace(/[\\/:*?"<>|]+/g,`-`).replace(/\s+/g,`-`).replace(/-+/g,`-`).replace(/^-|-$/g,``)||`node`}function yn(e){return vn(e).slice(0,48)||`node`}function bn(e){return e.replace(/\\/g,`\\\\`).replace(/"/g,`\\"`).replace(/\$/g,`\\$`).replace(/`/g,"\\`")}function xn(e=ue){return(e.controlPlaneEndpoint||Zt()).trim().replace(/\/$/,``)}function R(){let e=typeof window>`u`?``:window.location?.origin||``;return/^(http:\/\/)?(192\.168\.200\.61|docker-test\.cin\.su)(:18080)?$/i.test(e.replace(/\/$/,``))?`https://vpn.cin.su/api/v1`:`${e.replace(/\/$/,``)}/api/v1`}function Sn(e=ue){let t=$t(e.artifactEndpoints)[0];return t?t.replace(/\/downloads$/i,``).replace(/\/$/,``):xn(e).replace(/\/api\/v1$/i,``).replace(/\/api$/i,``).replace(/\/$/,``)}function Cn(e=ue){return`${typeof window>`u`&&!e.controlPlaneEndpoint?`http://:18080`:Sn(e)}/downloads/rap-host-agent-linux-amd64`}function wn(e=ue){return`${typeof window>`u`&&!e.controlPlaneEndpoint?`http://:18080`:Sn(e)}/downloads/rap-host-agent-windows-amd64.exe`}function Tn(e){return e.trim().toLowerCase().replace(/[^a-z0-9-]+/g,`-`).replace(/^-+|-+$/g,``).slice(0,42)||`rap-node`}function z(e){return`'${e.replace(/'/g,`'\\''`)}'`}function En(e){return`'${e.replace(/'/g,`''`)}'`}function Dn(e){return e.replace(/"/g,`""`)}function On(e,t){return e.includes(t)?e.filter(e=>e!==t):[...e,t]}function kn(e,t,n,r,i){let a=n.trim().toLowerCase(),o=new Map;for(let n of e){if(a&&!An(n,a))continue;let e=jn(n,t,r,i);o.set(e,[...o.get(e)||[],n])}return Array.from(o.entries()).map(([e,t])=>({label:e,items:t.sort((e,t)=>e.node.name.localeCompare(t.node.name))})).sort((e,t)=>e.label.localeCompare(t.label))}function An(e,t){return[e.node.name,e.node.node_key,e.node.health_status,e.node.ownership_type,e.node.reported_version||``,...e.memberships.flatMap(e=>[e.cluster.name,e.cluster.slug,e.node.membership_status])].some(e=>e.toLowerCase().includes(t))}function jn(e,t,n,r){if(n===`health`)return H(e.node.health_status);if(n===`ownership`)return H(e.node.ownership_type);if(n===`cluster_count`)return Gn(e.memberships.length,r);let i=e.memberships.find(e=>e.cluster.id===t);return i?i.node.membership_status===`active`?r===`en`?`In active cluster`:`В активном кластере`:`${r===`en`?`Membership`:`Участие`}: ${H(i.node.membership_status)}`:r===`en`?`Not in active cluster`:`Не в активном кластере`}function Mn(e,t){let n=se[e]||[];if(n.length===0||!t)return`unknown`;if(Nn(t))return`stale`;let r=t.capabilities||{};return n.some(e=>!!r[e])?`confirmed`:`missing`}function Nn(e){if(!e?.observed_at)return!0;let t=new Date(e.observed_at).getTime();return!Number.isFinite(t)||Date.now()-t>60*1e3}function Pn(e,t){let n=Mn(e,t);return n===`confirmed`?`good`:n===`missing`?`bad`:n===`stale`?`warn`:``}function Fn(e,t,n){let r=Mn(e,t);return r===`confirmed`?n.capabilityConfirmed:r===`missing`?n.capabilityMissing:r===`stale`?`heartbeat устарел`:n.capabilityUnknown}function In(e,t,n){let r=Mn(e,t);return n===`en`?r===`confirmed`?`capable`:r===`missing`?`not reported`:r===`stale`?`stale heartbeat`:`unknown`:r===`confirmed`?`подходит`:r===`missing`?`не заявлено`:r===`stale`?`heartbeat устарел`:`неизвестно`}function Ln(e){let t=e?.metadata?.mesh_peer_recovery_report;if(!t||typeof t!=`object`||Array.isArray(t))return`н/д`;let n=t,r=typeof n.mode==`string`?n.mode:`unknown`,i=typeof n.ready_peer_count==`number`?n.ready_peer_count:null,a=typeof n.target_ready_peers==`number`?n.target_ready_peers:null,o=typeof n.deficit==`number`?n.deficit:0,s=i==null||a==null?r:`${r} ${i}/${a}`;return o>0?`${s} deficit ${o}`:s}function Rn(e){let t=e?.metadata?.mesh_peer_connection_intent_report;if(!t||typeof t!=`object`||Array.isArray(t))return Un(e);let n=t,r=typeof n.intent_count==`number`?n.intent_count:0,i=typeof n.maintain_count==`number`?n.maintain_count:0,a=typeof n.recover_count==`number`?n.recover_count:0,o=typeof n.rendezvous_required_count==`number`?n.rendezvous_required_count:0,s=typeof n.rendezvous_resolved_count==`number`?n.rendezvous_resolved_count:0,c=typeof n.relay_control_count==`number`?n.relay_control_count:0,l=[`rv${o}`];s>0&&l.push(`ok${s}`),c>0&&l.push(`relay${c}`);let u=o>0||s>0||c>0?`${r} intents m${i}/r${a} ${l.join(`/`)}`:`${r} intents m${i}/r${a}`,d=Un(e);return d===`н/д`?u:`${u}; ${d}`}function zn(e){let t=e?.metadata?.mesh_rendezvous_lease_report;if(!t||typeof t!=`object`||Array.isArray(t))return`н/д`;let n=t,r=typeof n.lease_count==`number`?n.lease_count:0,i=typeof n.active_count==`number`?n.active_count:0,a=typeof n.admitted_as_relay_count==`number`?n.admitted_as_relay_count:0,o=typeof n.admitted_as_peer_count==`number`?n.admitted_as_peer_count:0,s=typeof n.renewal_needed_count==`number`?n.renewal_needed_count:0,c=typeof n.relay_control_ready_count==`number`?n.relay_control_ready_count:0,l=typeof n.stale_relay_count==`number`?n.stale_relay_count:0,u=typeof n.refresh_attempt_count==`number`?n.refresh_attempt_count:0,d=typeof n.refresh_success_count==`number`?n.refresh_success_count:0,f=[`lease ${i}/${r}`];return a>0&&f.push(`relay${a}`),o>0&&f.push(`peer${o}`),s>0&&f.push(`renew${s}`),l>0&&f.push(`stale${l}`),c>0&&f.push(`ready${c}`),u>0&&f.push(`ref${d}/${u}`),f.join(` `)}function Bn(e){let t=e?.metadata?.mesh_route_path_decision_report;if(!t||typeof t!=`object`||Array.isArray(t))return`н/д`;let n=t,r=typeof n.decision_count==`number`?n.decision_count:0,i=typeof n.replacement_decision_count==`number`?n.replacement_decision_count:0,a=typeof n.degraded_decision_count==`number`?n.degraded_decision_count:0,o=typeof n.recovery_hysteresis_count==`number`?n.recovery_hysteresis_count:0,s=typeof n.recovery_promoted_count==`number`?n.recovery_promoted_count:0,c=typeof n.recovery_demoted_count==`number`?n.recovery_demoted_count:0,l=typeof n.local_effective_path_count==`number`?n.local_effective_path_count:0,u=typeof n.next_hop_available_count==`number`?n.next_hop_available_count:0,d=typeof n.withdrawn_local_relay_count==`number`?n.withdrawn_local_relay_count:0,f=[`path ${l}/${r}`];return i>0&&f.push(`repl${i}`),a>0&&f.push(`degr${a}`),o>0&&f.push(`rec${o}`),s>0&&f.push(`prom${s}`),c>0&&f.push(`dem${c}`),u>0&&f.push(`next${u}`),d>0&&f.push(`wd${d}`),f.join(` `)}function Vn(e){let t=e?.metadata?.mesh_route_generation_report;if(!t||typeof t!=`object`||Array.isArray(t))return`н/д`;let n=t,r=typeof n.active_decision_count==`number`?n.active_decision_count:0,i=typeof n.applied_decision_count==`number`?n.applied_decision_count:0,a=typeof n.withdrawn_decision_count==`number`?n.withdrawn_decision_count:0,o=n.generation_changed===!0,s=[`gen ${r}`];return i>0&&s.push(`ap${i}`),a>0&&s.push(`wd${a}`),o&&s.push(`chg`),s.join(` `)}function Hn(e){let t=e?.metadata?.mesh_route_health_config_report;if(!t||typeof t!=`object`||Array.isArray(t))return`н/д`;let n=t,r=e?.metadata?.mesh_route_health_feedback_refresh_report,i=r&&typeof r==`object`&&!Array.isArray(r)?r:{},a=typeof n.route_health_route_count==`number`?n.route_health_route_count:0,o=typeof n.route_path_decision_applied_count==`number`?n.route_path_decision_applied_count:0,s=typeof n.replacement_route_health_route_count==`number`?n.replacement_route_health_route_count:0,c=typeof n.route_health_decision_drift_candidate_count==`number`?n.route_health_decision_drift_candidate_count:0,l=typeof i.feedback_refresh_attempt_count==`number`?i.feedback_refresh_attempt_count:typeof n.feedback_refresh_attempt_count==`number`?n.feedback_refresh_attempt_count:0,u=typeof i.feedback_refresh_success_count==`number`?i.feedback_refresh_success_count:typeof n.feedback_refresh_success_count==`number`?n.feedback_refresh_success_count:0,d=typeof i.feedback_refresh_suppressed_count==`number`?i.feedback_refresh_suppressed_count:typeof n.feedback_refresh_suppressed_count==`number`?n.feedback_refresh_suppressed_count:0,f=[`rh ${o}/${a}`];return s>0&&f.push(`repl${s}`),c>0&&f.push(`drift${c}`),(l>0||d>0)&&f.push(`fb${u}/${l}`),d>0&&f.push(`sup${d}`),f.join(` `)}function Un(e){let t=e?.metadata?.mesh_peer_connection_manager_report;if(!t||typeof t!=`object`||Array.isArray(t))return`н/д`;let n=t;if(n.enabled===!1)return`manager off`;let r=typeof n.attempted==`number`?n.attempted:0,i=typeof n.succeeded==`number`?n.succeeded:0,a=typeof n.deferred==`number`?n.deferred:0,o=typeof n.relay_control_count==`number`?n.relay_control_count:0,s=o>0?`mgr ${i}/${r} relay${o}`:`mgr ${i}/${r}`;return a>0?`${s} def${a}`:s}function Wn(e){let t=e?.metadata?.mesh_listener_report;if(!t||typeof t!=`object`||Array.isArray(t))return`н/д`;let n=t,r=typeof n.status==`string`?n.status:`unknown`,i=typeof n.listen_port_mode==`string`?n.listen_port_mode:`manual`,a=typeof n.effective_listen_addr==`string`?n.effective_listen_addr:``,o=typeof n.failure_reason==`string`?n.failure_reason:``;return r===`listening`?a?`listen ${a}`:`listen`:r===`auto_rebound`?a?`auto ${a}`:`auto rebound`:r===`listen_failed`?o?`${i} failed: ${o}`:`${i} failed`:r===`disabled`?i===`disabled`?`inbound off`:`inbound unavailable`:r}function Gn(e,t){if(t===`en`)return e===1?`1 cluster`:`${e} clusters`;let n=e%10,r=e%100;return n===1&&r!==11?`${e} кластер`:n>=2&&n<=4&&(r<12||r>14)?`${e} кластера`:`${e} кластеров`}function Kn(e,t=e.link_status===`reachable`?`reachable`:`unknown`){return t===`stale`?`stale`:t===`one_way`?`oneWay`:t!==`reachable`||e.link_status!==`reachable`?`bad`:e.quality_score!=null&&e.quality_score<70||e.latency_ms!=null&&e.latency_ms>80?`weak`:`good`}function qn(e,t=16){return e.length>t?`${e.slice(0,Math.max(1,t-2))}…`:e}function Jn(e){return window.confirm(`${e}?\n\nЭто высокорисковая операция владельца платформы. Действие будет записано в аудит.`)}function Yn(e){let t=(e||``).replace(/\/$/,``);return!t||t===`/api/v1`?window.location.origin:t.endsWith(`/api/v1`)?t.slice(0,-7):t}function B(e){return e?e.length>12?`${e.slice(0,8)}...${e.slice(-4)}`:e:`нет`}function V(e){return e?new Intl.DateTimeFormat(void 0,{dateStyle:`medium`,timeStyle:`short`}).format(new Date(e)):`никогда`}function Xn(e){return e==null||Number.isNaN(e)?`age n/a`:e<60?`${Math.max(0,Math.round(e))}s ago`:e<3600?`${Math.round(e/60)}m ago`:e<86400?`${Math.round(e/3600)}h ago`:`${Math.round(e/86400)}d ago`}function Zn(e){if(!e)return`time n/a`;let t=Date.parse(e);return Number.isNaN(t)?`time n/a`:Xn(Math.max(0,Math.round((Date.now()-t)/1e3)))}function Qn(e){return e?new Intl.DateTimeFormat(void 0,{hour:`2-digit`,minute:`2-digit`,second:`2-digit`}).format(new Date(e)):`н/д`}function $n(e){if(e==null||Number.isNaN(e))return`н/д`;let t=[`B`,`KB`,`MB`,`GB`,`TB`],n=e,r=0;for(;n>=1024&&r(e[t]||0)>0).map(t=>`${t[0]}:${e[t]}`).join(` `)||`qos none`}function tr(e){return!e||Object.keys(e).length===0?`n/a`:[`control`,`interactive`,`reliable`,`bulk`,`droppable`].filter(t=>(e[t]||0)>0).map(t=>`${t[0]}:${e[t]}`).join(` `)||`n/a`}function nr(e,t){return(t||0)>0||e===`critical`?`bad`:e===`degraded`?`warn`:e===`watch`?`info`:`good`}function rr(e){switch(e){case`applied`:case`rebuild_request_applied`:return`good`;case`waiting_node_apply`:case`pending_rebuild_request`:case`pending_degraded_fallback`:case`rebuild_request_recorded`:case`rebuild_request_recorded_node_pending`:case`rebuild_request_no_alternate`:case`rebuild_request_deferred_by_policy`:case`route_rebuild_no_safe_recovery`:return`warn`;case`expired`:case`rejected_by_policy_guard`:case`rebuild_request_rejected`:case`rebuild_request_expired`:return`bad`;default:return e?`bad`:``}}function ir(e,t,n){return e===`service_channel_feedback_no_alternate`||t===`pending_degraded_fallback`||(n||[]).includes(`no_unfenced_alternate_route`)?`warn`:t===`applied`||(n||[]).includes(`service_channel_rebuild_applied`)?`good`:e?.includes(`replacement`)||e||t?`info`:``}function H(e){return{active:`активно`,approved:`одобрено`,authoritative:`authoritative`,connecting:`подключается`,connected:`связан`,critical:`критично`,current:`актуальна`,degraded:`degraded`,disabled:`выключено`,enabled:`включено`,failed:`ошибка`,healthy:`здоров`,watch:`наблюдение`,flow_health_ready:`flow ready`,flow_drops_reported:`flow drops`,route_quality_window_drops_reported:`route drops`,backend_fallback_observed:`backend fallback`,route_quality_window_failures_reported:`route failures`,route_quality_window_slow_samples_reported:`slow samples`,route_send_latency_high:`high latency`,flow_queue_pressure_high:`queue pressure high`,bulk_pressure_with_interactive_qos_observed:`bulk+interactive`,bulk_pressure_observed:`bulk pressure`,flow_queue_pressure_observed:`queue pressure`,flow_health_degraded:`flow degraded`,bulk_window_reduced_to_protect_interactive:`bulk reduced`,rebuild_request_applied:`planner applied`,rebuild_request_recorded:`rebuild recorded`,rebuild_request_recorded_node_pending:`node pending`,rebuild_request_no_alternate:`no alternate`,rebuild_request_deferred_by_policy:`deferred by policy`,rebuild_request_rejected:`rebuild rejected`,rebuild_request_expired:`rebuild expired`,route_rebuild_no_safe_recovery:`no safe recovery`,access_decision:`access decision`,access_no_safe_recovery:`access no-safe`,access_recovery_selected:`access recovery`,access_rebuild_applied:`access applied`,access_replacement_selected:`access replacement`,inspect_access_no_safe_recovery_route_pool_and_signed_policy:`inspect no-safe route pool`,watch_recovery_route_quality_and_confirm_post_recovery_traffic:`watch recovery traffic`,confirm_applied_rebuild_runtime_traffic_stays_on_replacement:`confirm applied traffic`,watch_replacement_route_quality_until_applied_or_recovered:`watch replacement`,pending_degraded_fallback:`pending fallback`,service_channel_feedback_no_alternate:`no safe route`,service_channel_feedback_replacement:`replacement`,service_channel_feedback_exit_pool_replacement:`exit replacement`,service_channel_feedback_entry_pool_replacement:`entry replacement`,service_channel_feedback_entry_exit_pool_replacement:`pool replacement`,service_channel_remediation_command:`remediation`,service_channel_feedback_rebuild_requested:`rebuild requested`,remediation_rebuild_applied_to_alternate:`planner selected alternate`,no_unfenced_alternate_route:`no safe alternate`,active_lease_not_found_for_rebuild_resolution:`lease missing`,remediation_command_ttl_expired:`command expired`,durable_rebuild_route_request_recorded:`rebuild recorded`,durable_rebuild_route_request_rejected:`request rejected`,durable_rebuild_route_request_applied:`request applied`,durable_rebuild_route_no_alternate:`no alternate`,durable_rebuild_route_deferred_by_policy:`deferred by policy`,durable_rebuild_route_expired:`request expired`,isolated:`изолирован`,offline:`нет связи`,one_way:`односторонняя`,outdated:`обновить`,pending:`ожидает`,platform_managed:`платформенный`,promoted:`promoted`,rejected:`отклонено`,ready:`готово`,revoked:`отозвано`,running:`работает`,customer_managed:`клиентский`,no_policy:`нет политики`,not_configured:`не задано`,missing:`нет отчета`,service_channel_recovery_demoted:`demoted`,service_channel_recovery_demoted_degraded:`degraded`,service_channel_recovery_demoted_degraded_fallback:`fallback`,service_channel_recovery_demoted_failure:`failure`,service_channel_recovery_demoted_fenced:`fenced`,service_channel_recovery_demoted_rebuild:`rebuild`,service_channel_recovery_demoted_slow:`slow`,service_channel_feedback_provenance_missing:`provenance missing`,service_channel_feedback_stale:`stale feedback`,service_channel_feedback_stale_generation:`stale generation`,service_channel_feedback_stale_policy:`stale policy`,service_channel_feedback_stale_policy_and_generation:`stale policy+generation`,schema_ready:`schema ready`,schema_migration_required:`schema migration required`,snapshots_warmed:`snapshots warmed`,missing_snapshots_warmed_stale_deferred:`missing warmed, stale deferred`,snapshot_warmup_partial:`warmup partial`,stopped:`остановлено`,stale:`устарело`,unknown:`неизвестно`}[e]||e}(0,v.createRoot)(document.getElementById(`root`)).render((0,E.jsx)(_.StrictMode,{children:(0,E.jsx)(me,{})}));