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 ee=Array.isArray;function S(){}var C={H:null,A:null,T:null,S:null},te=Object.prototype.hasOwnProperty;function ne(e,n,r){var i=r.ref;return{$$typeof:t,type:e,key:n,ref:i===void 0?null:i,props:r}}function re(e,t){return ne(e.type,t,e.props)}function ie(e){return typeof e==`object`&&!!e&&e.$$typeof===t}function w(e){var t={"=":`=0`,":":`=2`};return`$`+e.replace(/[=:]/g,function(e){return t[e]})}var ae=/\/+/g;function oe(e,t){return typeof e==`object`&&e&&e.key!=null?w(``+e.key):t.toString(36)}function T(e){switch(e.status){case`fulfilled`:return e.value;case`rejected`:throw e.reason;default:switch(typeof e.status==`string`?e.then(S,S):(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 se(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,se(c(e._payload),r,i,a,o)}}if(c)return o=o(e),c=a===``?`.`+oe(e,0):a,ee(o)?(i=``,c!=null&&(i=c.replace(ae,`$&/`)+`/`),se(o,r,i,``,function(e){return e})):o!=null&&(ie(o)&&(o=re(o,i+(o.key==null||e&&e.key===o.key?``:(``+o.key).replace(ae,`$&/`)+`/`)+c)),r.push(o)),1;c=0;var l=a===``?`.`:a+`:`;if(ee(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,ee||(ee=!0,ie());else{var t=n(l);t!==null&&oe(x,t.startTime-e)}}var ee=!1,S=-1,C=5,te=-1;function ne(){return g?!0:!(e.unstable_now()-tet&&ne());){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&&oe(x,u.startTime-t),i=!1}}break a}finally{d=null,f=a,p=!1}i=void 0}}finally{i?ie():ee=!1}}}var ie;if(typeof y==`function`)ie=function(){y(re)};else if(typeof MessageChannel<`u`){var w=new MessageChannel,ae=w.port2;w.port1.onmessage=re,ie=function(){ae.postMessage(null)}}else ie=function(){_(re,0)};function oe(t,n){S=_(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(S),S=-1):h=!0,oe(x,a-o))):(r.sortIndex=s,t(c,r),m||p||(m=!0,ee||(ee=!0,ie()))),r},e.unstable_shouldYield=ne,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(1fe||(e.current=de[fe],de[fe]=null,fe--)}function pe(e,t){fe++,de[fe]=e.current,e.current=t}var A=O(null),me=O(null),he=O(null),ge=O(null);function _e(e,t){switch(pe(he,t),pe(me,e),pe(A,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}}k(A),pe(A,e)}function ve(){k(A),k(me),k(he)}function ye(e){e.memoizedState!==null&&pe(ge,e);var t=A.current,n=Hd(t,e.type);t!==n&&(pe(me,e),pe(A,n))}function be(e){me.current===e&&(k(A),k(me)),ge.current===e&&(k(ge),Qf._currentValue=ue)}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 j(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 Ee(e){try{var t=``,n=null;do t+=j(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,Re=t.unstable_IdlePriority,ze=t.log,Be=t.unstable_setDisableYieldValue,Ve=null,He=null;function Ue(e){if(typeof ze==`function`&&Be(e),He&&typeof He.setStrictMode==`function`)try{He.setStrictMode(Ve,e)}catch{}}var We=Math.clz32?Math.clz32:qe,Ge=Math.log,Ke=Math.LN2;function qe(e){return e>>>=0,e===0?32:31-(Ge(e)/Ke|0)|0}var Je=256,M=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 $e(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 et(){var e=Ye;return Ye<<=1,!(Ye&62914560)&&(Ye=4194304),e}function tt(e){for(var t=[],n=0;31>n;n++)t.push(e);return t}function nt(e,t){e.pendingLanes|=t,t!==268435456&&(e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0)}function rt(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),L=!1;if(dn)try{var fn={};Object.defineProperty(fn,`passive`,{get:function(){L=!0}}),window.addEventListener(`test`,fn,fn),window.removeEventListener(`test`,fn,fn)}catch{L=!1}var pn=null,R=null,mn=null;function hn(){if(mn)return mn;var e,t=R,n=t.length,r,i=`value`in pn?pn.value:pn.textContent,a=i.length;for(e=0;e=Wn),Kn=` `,qn=!1;function Jn(e,t){switch(e){case`keyup`:return Hn.indexOf(t.keyCode)!==-1;case`keydown`:return t.keyCode!==229;case`keypress`:case`mousedown`:case`focusout`:return!0;default:return!1}}function Yn(e){return e=e.detail,typeof e==`object`&&`data`in e?e.data:null}var Xn=!1;function Zn(e,t){switch(e){case`compositionend`:return Yn(t);case`keypress`:return t.which===32?(qn=!0,Kn):null;case`textInput`:return e=t.data,e===Kn&&qn?null:e;default:return null}}function Qn(e,t){if(Xn)return e===`compositionend`||!Un&&Jn(e,t)?(e=hn(),mn=R=pn=null,Xn=!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=zt(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=zt(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=dn&&`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!==zt(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,xi=1<<32-We(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),G&&Ci(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),G&&Ci(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 G&&Ci(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)}),G&&Ci(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===ie&&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=ci(o.props.children,e.mode,c,o.key),c.return=e,e=c):(c=si(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=di(o,e.mode,c),c.return=e,e=c}return s(e);case ie:return o=ya(o),b(e,r,o,c)}if(le(o))return h(e,r,o,c);if(T(o)){if(l=T(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===S)return b(e,r,Ji(e,o),c);Y(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=li(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===pa||t===ha)throw t;var a=ri(29,t,null,e.mode);return a.lanes=r,a.return=e,a}}}var Oa=Da(!0),ka=Da(!1),Aa=!1;function ja(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function Ma(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 Na(e){return{lane:e,tag:0,payload:null,callback:null,next:null}}function Pa(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=ei(e),$r(e,null,n),t}return Xr(e,r,t,n),ei(e)}function Fa(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,at(e,n)}}function Ia(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 La=!1;function Ra(){if(La){var e=ia;if(e!==null)throw e}}function za(e,t,n,r){La=!1;var i=e.updateQueue;Aa=!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===ra&&(La=!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:Aa=!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 Ba(e,t){if(typeof e!=`function`)throw Error(i(191,e));e.call(t)}function Va(e,t){var n=e.callbacks;if(n!==null)for(e.callbacks=null,e=0;ea?a:8;var o=E.T,s={};E.T=s,Ds(e,!1,t,n);try{var c=i(),l=E.S;l!==null&&l(s,c),typeof c==`object`&&c&&typeof c.then==`function`?Es(e,t,sa(c,r),du(e)):Es(e,t,r,du(e))}catch(n){Es(e,t,{then:function(){},status:`rejected`,reason:n},du())}finally{D.p=a,o!==null&&s.types!==null&&(o.types=s.types),E.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,ue,n===null?gs:function(){return ys(e),n(r)})}function vs(e){var t=e.memoizedState;if(t!==null)return t;t={memoizedState:ue,baseState:ue,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Oo,lastRenderedState:ue},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 qi(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=Na(n);var r=Pa(t,e,n);r!==null&&(pu(r,t,n),Fa(r,t,n)),t={cache:$i()},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=Zr(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 Xr(e,t,i,0),Fl===null&&Yr(),!1}catch{}if(n=Zr(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=Zr(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,at(e,n)}}var js={readContext:qi,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:qi,use:Eo,useCallback:function(e,t){return So().memoizedState=[e,t===void 0?null:t],e},useContext:qi,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){Ue(!0);try{e()}finally{Ue(!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){Ue(!0);try{n(t)}finally{Ue(!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(G){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(G){var n=Si,r=xi;n=(r&~(1<<32-We(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[ft]=t,o[pt]=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=he.current,Fi(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[ft]=t,e=!!(e.nodeValue===n||r!==null&&!0===r.suppressHydrationWarning||jd(e.nodeValue,n)),e||Mi(t,!0)}else e=Bd(e).createTextNode(r),e[ft]=t,t.stateNode=e}return jc(t),null;case 31:if(n=t.memoizedState,e===null||e.memoizedState!==null){if(r=Fi(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[ft]=t}else K(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;jc(t),e=!1}else n=Ii(),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=Fi(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[ft]=t}else K(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;jc(t),a=!1}else a=Ii(),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 ve(),e===null&&xd(t.stateNode.containerInfo),jc(t),null;case 10:return Hi(t.type),jc(t),null;case 19:if(k(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;)oi(n,e),n=n.sibling;return pe(eo,eo.current&1|2),G&&Ci(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&&!G)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),G&&Ci(t,r.treeForkCount),e);case 22:case 23:return $a(t),Ka(),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&&k(la),null;case 24:return n=null,e!==null&&(n=e.memoizedState.cache),t.memoizedState.cache!==n&&(t.flags|=2048),Hi(Qi),jc(t),null;case 25:return null;case 30:return null}throw Error(i(156,t.tag))}function Nc(e,t){switch(W(t),t.tag){case 1:return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return Hi(Qi),ve(),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));K()}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));K()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return k(eo),null;case 4:return ve(),null;case 10:return Hi(t.type),null;case 22:case 23:return $a(t),Ka(),e!==null&&k(la),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 24:return Hi(Qi),null;case 25:return null;default:return null}}function Pc(e,t){switch(W(t),t.tag){case 3:Hi(Qi),ve();break;case 26:case 27:case 5:be(t);break;case 4:ve();break;case 31:t.memoizedState!==null&&$a(t);break;case 13:$a(t);break;case 19:k(eo);break;case 10:Hi(t.type);break;case 22:case 23:$a(t),Ka(),e!==null&&k(la);break;case 24:Hi(Qi)}}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{Va(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[pt]=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=tn));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[ft]=e,t[pt]=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[ft]=e,Ct(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,E.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),He&&typeof He.onPostCommitFiberRoot==`function`)try{He.onPostCommitFiberRoot(Ve,o)}catch{}return!0}finally{D.p=a,E.T=r,zu(e,t)}}function Hu(e,t,n){t=pi(n,t),t=Gs(e.stateNode,t,2),e=Pa(e,t,2),e!==null&&(nt(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=pi(n,e),n=Ks(2),r=Pa(t,n,2),r!==null&&(qs(n,r,t,e),nt(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=et()),e=Qr(e,t),e!==null&&(nt(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-We(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=Vt(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),Ct(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="`+Vt(t)+`"]`;t===`image`&&n&&n.imageSrcSet?(i+=`[imagesrcset="`+Vt(n.imageSrcSet)+`"]`,typeof n.imageSizes==`string`&&(i+=`[imagesizes="`+Vt(n.imageSizes)+`"]`)):i+=`[href="`+Vt(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),Ct(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="`+Vt(r)+`"][href="`+Vt(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),Ct(r),n.head.appendChild(r)}}}function Ef(e,t,n){_f.S(e,t,n);var r=bf;if(r&&e){var i=P(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`);Ct(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=P(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`),Ct(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=P(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`),Ct(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=he.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=P(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=P(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=P(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="`+Vt(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),Ct(t),e.head.appendChild(t))}function Pf(e){return`[src="`+Vt(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~="`+Vt(n.href)+`"]`);if(r)return t.instance=r,Ct(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`),Ct(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,Ct(o),o;r=Mf(n),(a=mf.get(a))&&Rf(r,a),o=(e.ownerDocument||e).createElement(`link`),Ct(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,Ct(a),a):(r=n,(a=mf.get(o))&&(r=h({},n),zf(r,a)),e=e.ownerDocument||e,a=e.createElement(`script`),Ct(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,Ct(a);return}a=t.ownerDocument||t,r=Mf(r),(i=mf.get(i))&&Rf(r,i),a=a.createElement(`link`),Ct(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:b(),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 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 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=t.error?.fallback_message||t.error?.code||e}catch{}throw Error(e)}return await n.json()}};function b(){let e=`rap.webAdmin.deviceFingerprint`,t=localStorage.getItem(e);if(t)return t;let n=`web-admin-${x()}`;return localStorage.setItem(e,n),n}function x(){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 ee=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})),S=o(((e,t)=>{t.exports=ee()}))(),C={baseUrl:`rap.webAdmin.baseUrl`,actorUserId:`rap.webAdmin.actorUserId`,auth:`rap.webAdmin.auth`,language:`rap.webAdmin.language`,vpnDiagnosticDeviceId:`rap.webAdmin.vpnDiagnosticDeviceId`},te=`/api/v1`,ne=`http://192.168.200.61:8080/api/v1`,re={reporterNodeId:``,routeId:``,serviceClass:``,generation:``,feedbackSource:``,feedbackChannelId:``,feedbackViolationStatus:``,offset:0},ie=[`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`],w={"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`},ae={"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`]},oe=[{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 T(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 se(e){let t=Date.parse(e);return!Number.isFinite(t)||t<=Date.now()}function ce(){try{let e=localStorage.getItem(C.auth);if(!e)return null;let t=T(JSON.parse(e));return!t||se(t.refreshTokenExpiresAt)?null:t}catch{return null}}var le={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:`:19131`,meshListenPortMode:`auto`,meshListenAutoPortStart:19131,meshListenAutoPortEnd:19231,meshAdvertiseEndpoint:``,meshAdvertiseTransport:`direct_http`,meshConnectivityMode:`private_lan`,meshNATType:`none`,meshRegion:`docker-test`,controlPlaneEndpoint:``,artifactEndpoints:``,dockerImageArtifactSHA256:``,pullImage:!1,replace:!0,syntheticRuntime:!0},E={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 Plane. Выберите активный кластер или раскройте карточку для подробностей.`,makeActive:`Сделать активным`,openSettings:`Открыть настройки`,selected:`Выбран`,createCluster:`Создать кластер`,clusterDetails:`Подробнее`,consoleTitle:`Панель владельца платформы`,boundary:`WEB является только представлением. Решения кластера проходят через Control Plane API, PostgreSQL как source of truth и аудит.`,noLoginError:`Войдите как владелец продукта или администратор платформы, чтобы загрузить панель.`,accessDenied:`Доступ к этой панели запрещен.`,sessionMode:`Режим сессии`,sessionModeAdmin:`Админ`,sessionModeUser:`Пользователь`,sessionRefreshedAt:`Сессия обновлена`,emptyLiveTitle:`Кластер пока пустой`,emptyLiveText:`Это реальные данные, не заглушка: в выбранном кластере ещё нет одобренных node-agent узлов. Создайте join token, запустите rap-node-agent и подтвердите join request.`,realDataNote:`Показываются только данные из PostgreSQL/Control Plane. Если значения нулевые, значит соответствующих узлов, ролей или сервисов пока нет.`,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:`control-plane назначение`,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 Plane`,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 Plane. 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. Cluster decisions go through Control Plane APIs, PostgreSQL source of truth, and audit.`,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/Control Plane 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-plane 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 D(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 ue(e){try{return await e.listClusterSummaries(),`admin`}catch{try{return await Promise.all([e.listOrganizations(),e.listResources()]),`user`}catch{return null}}}function de(){let[e,t]=(0,_.useState)(!1),[n,r]=(0,_.useState)(()=>!!ce()),[i]=(0,_.useState)(()=>{let e=localStorage.getItem(C.baseUrl)?.trim();return!e||e.startsWith(ne)?te:e}),[a,o]=(0,_.useState)(()=>ce()),[s,c]=(0,_.useState)(null),[l,u]=(0,_.useState)(``),[d,f]=(0,_.useState)(()=>localStorage.getItem(C.language)===`en`?`en`:`ru`),[p,m]=(0,_.useState)(a?.userId??localStorage.getItem(C.actorUserId)??``),[h,g]=(0,_.useState)({email:``,password:``,deviceLabel:`Панель владельца платформы`,trustDevice:!0,rememberMe:!0,showPassword:!1}),[v,b]=(0,_.useState)(null),[x,ee]=(0,_.useState)({email:``,password:``,activationPayload:``,activationSignature:``}),[w,ae]=(0,_.useState)(`command`),[T,de]=(0,_.useState)(``),[ge,ve]=(0,_.useState)([]),[Se,Ce]=(0,_.useState)([]),[we,Te]=(0,_.useState)(null),[j,Ee]=(0,_.useState)([]),[De,Oe]=(0,_.useState)([]),[ke,Ae]=(0,_.useState)({}),[je,Me]=(0,_.useState)([]),[Ne,Pe]=(0,_.useState)([]),[Re,ze]=(0,_.useState)([]),[Be,Ve]=(0,_.useState)({}),[He,Ue]=(0,_.useState)({}),[We,Ge]=(0,_.useState)({}),[Ke,qe]=(0,_.useState)({}),[Qe,nt]=(0,_.useState)({}),[rt,it]=(0,_.useState)({}),[ot,pt]=(0,_.useState)({}),[gt,yt]=(0,_.useState)([]),[bt,xt]=(0,_.useState)([]),[St,Ct]=(0,_.useState)({}),[Et,Dt]=(0,_.useState)([]),[zt,Ht]=(0,_.useState)([]),[I,Qt]=(0,_.useState)(null),[$t,en]=(0,_.useState)([]),[tn,nn]=(0,_.useState)(null),[rn,an]=(0,_.useState)(null),[on,sn]=(0,_.useState)(null),[cn,ln]=(0,_.useState)(null),[un,dn]=(0,_.useState)(null),[L,fn]=(0,_.useState)(null),[pn,R]=(0,_.useState)([]),[mn,hn]=(0,_.useState)(!1),[z,yn]=(0,_.useState)(re),[bn,wn]=(0,_.useState)(null),[Tn,En]=(0,_.useState)(null),[Dn,On]=(0,_.useState)([]),[kn,An]=(0,_.useState)([]),[jn,Nn]=(0,_.useState)([]),[Pn,zn]=(0,_.useState)({}),[Gn,Kn]=(0,_.useState)({}),[qn,Jn]=(0,_.useState)(()=>localStorage.getItem(C.vpnDiagnosticDeviceId)||``),[Yn,Xn]=(0,_.useState)([]),[Zn,Qn]=(0,_.useState)(null),[$n,er]=(0,_.useState)(`http://2ip.ru/`),[tr,nr]=(0,_.useState)(null),[rr,ir]=(0,_.useState)([]),[ar,or]=(0,_.useState)([]),[sr,cr]=(0,_.useState)([]),[lr,ur]=(0,_.useState)({}),[dr,fr]=(0,_.useState)([]),[pr,mr]=(0,_.useState)([]),[hr,gr]=(0,_.useState)(null),[_r,vr]=(0,_.useState)(``),[yr,br]=(0,_.useState)(`poll`),[xr,Sr]=(0,_.useState)(``),[Cr,wr]=(0,_.useState)(null),[Tr,Er]=(0,_.useState)(!1),[Dr,Or]=(0,_.useState)(``),[kr,Ar]=(0,_.useState)(``),[jr,Mr]=(0,_.useState)({slug:``,name:``,region:``}),[Nr,Pr]=(0,_.useState)({name:``,status:`active`,region:``,metadataJson:`{}`}),[Fr,Ir]=(0,_.useState)({name:``,parentGroupId:``}),[Lr,Rr]=(0,_.useState)({hysteresisPenalty:`150`,promotionMinSamples:`64`,demotionFailureThreshold:`1`,demotionDropThreshold:`1`,demotionSlowThreshold:`1`,demotionRebuildEnabled:!0,demotionFencedEnabled:!0}),[zr,Br]=(0,_.useState)({currentWindowSeconds:`1800`,historyWindowSeconds:`86400`}),[U,Vr]=(0,_.useState)(le),[Hr,Ur]=(0,_.useState)(null),[Wr,Gr]=(0,_.useState)({authorityState:`authoritative`,mutationMode:`normal`,notes:``}),[Kr,qr]=(0,_.useState)(``),[Jr,Yr]=(0,_.useState)(`cluster`),[Xr,Zr]=(0,_.useState)(``),[Qr,$r]=(0,_.useState)(``),[ei,ti]=(0,_.useState)([]),[ni,ri]=(0,_.useState)(`membership`),[ii,ai]=(0,_.useState)(null),[oi,si]=(0,_.useState)([]),[ci,li]=(0,_.useState)(null),[ui,di]=(0,_.useState)(`details`),[fi,pi]=(0,_.useState)({}),[mi,hi]=(0,_.useState)({}),[gi,_i]=(0,_.useState)({}),[vi,yi]=(0,_.useState)({}),[bi,xi]=(0,_.useState)(``),[Si,Ci]=(0,_.useState)({telemetry:!0,links:!0}),[wi,Ti]=(0,_.useState)({nodeId:``,serviceType:`entry-node`,desiredState:`enabled`,runtimeMode:`container`,version:``,configJson:`{}`,environmentJson:`{}`}),[W,Ei]=(0,_.useState)({organizationId:``,name:``,protocolFamily:`generic`,desiredState:`disabled`,credentialRef:``,targetEndpointJson:`{}`,allowedNodePolicyJson:`{"mode":"explicit","node_ids":[]}`,routingUsageJson:`[]`,routePolicyJson:`{}`,qosPolicyJson:`{}`,placementPolicyJson:`{}`}),[Di,Oi]=(0,_.useState)({slug:``,name:``}),[G,ki]=(0,_.useState)({email:``,password:``,platformRole:`user`}),[Ai,ji]=(0,_.useState)({organizationId:``,userId:``,roleId:`org_member`}),[Mi,Ni]=(0,_.useState)(null),[Pi,Fi]=(0,_.useState)({username:``,password:``,domain:``}),[K,Ii]=(0,_.useState)({organizationId:``,name:``,address:``,protocol:`rdp`,routeMode:`vpn_exit`,entryNode:``,exitNode:``,tags:``,username:``,password:``,domain:``}),[Li,Ri]=(0,_.useState)(``),[zi,Bi]=(0,_.useState)(``),[Vi,Hi]=(0,_.useState)(``),Ui=`rap-android-vpn-latest-release.apk`,[Wi,Gi]=(0,_.useState)(Ui),q=(0,_.useMemo)(()=>new y({baseUrl:i,actorUserId:p}),[i,p]),Ki=(0,_.useMemo)(()=>new y({baseUrl:i,actorUserId:``}),[i]),qi=(0,_.useRef)(0),Ji=(0,_.useRef)(!1),J=E[d],Yi=ge.find(e=>e.id===T)||null,Xi=Se.find(e=>e.cluster_id===T)||null,Zi=(0,_.useMemo)(()=>In(i),[i]),Qi=(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},[]),$i=Qi(Wi,Ui),ea=Vi?Qi(Vi,$i):$i,ta=Vi?ea:$i,na=`${/^https?:\/\//i.test(ta)?ta:`${Zi}/${ta}`}${zi?`?_v=${encodeURIComponent(zi)}`:``}`,ra=(0,_.useMemo)(()=>It(U),[U]),ia=(0,_.useMemo)(()=>Hr?Lt(Hr.scope,U):U,[Hr,U]),aa=(0,_.useMemo)(()=>{let e=new Map;for(let t of ge)for(let n of ke[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))},[ke,ge]);(0,_.useMemo)(()=>_n(aa,T,Xr,ni,d),[aa,ni,Xr,d,T]);let oa=(0,_.useMemo)(()=>{let e=Xr.trim().toLowerCase(),t=Qr?new Set([Qr,...Nt(Qr,De)]):null;return aa.filter(n=>{let r=n.memberships.some(e=>e.cluster.id===T);if(Jr!==`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||vn(n,e)})},[aa,Xr,Qr,De,Jr,T]),sa=(0,_.useCallback)((e,t=!1)=>{if(e&&t){localStorage.setItem(C.auth,JSON.stringify(e)),localStorage.setItem(C.actorUserId,e.userId),r(!0);return}r(!1),localStorage.removeItem(C.auth),localStorage.removeItem(C.actorUserId)},[]),ca=(0,_.useCallback)(async()=>{try{let e=`${Zi}/downloads/rap-android-vpn-build.json?_cb=${Date.now()}`,t=await fetch(e,{cache:`no-store`});if(!t.ok){Ri(``),Bi(new Date().toISOString()),Hi(``),Gi(Ui);return}let n=await t.json();Ri(n.version?.name||``),Bi(n.published?.timestamp_utc||``),Hi(n.release_paths?.versioned||``),Gi(n.published?.path||n.release_paths?.latest||Ui)}catch{Ri(``),Bi(new Date().toISOString()),Hi(``),Gi(Ui)}},[Zi]),la=(0,_.useMemo)(()=>Pt(oa,De,T,J,new Set(ei)),[ei,De,T,J,oa]),ua=(0,_.useMemo)(()=>pr.slice(0,8),[pr]);(0,_.useEffect)(()=>{if(e)return;t(!0);let n=ce();if(n){if(se(n.refreshTokenExpiresAt)){localStorage.removeItem(C.auth),localStorage.removeItem(C.actorUserId),r(!1);return}(async()=>{try{let e=D(await Ki.refresh({refreshToken:n.refreshToken}));if(!e.userId||!e.authSessionId)throw Error(`Не удалось восстановить сессию.`);let t=await ue(new y({baseUrl:i,actorUserId:e.userId}));if(!t)throw Error(`Доступ к этой панели запрещен.`);m(e.userId),sa(e,!0),o(e),u(new Date().toISOString()),g(t=>({...t,email:e.email})),c(t)}catch{localStorage.removeItem(C.auth),localStorage.removeItem(C.actorUserId),r(!1),u(``),o(null),m(``),c(null)}})()}},[Ki,e,i,sa]),(0,_.useEffect)(()=>{let e=!1;return Ki.getInstallationStatus().then(t=>{e||b(t)}).catch(t=>{e||Or(t instanceof Error?t.message:`Не удалось загрузить статус установки.`)}),()=>{e=!0}},[Ki]),(0,_.useEffect)(()=>{if(!Yi){Pr({name:``,status:`active`,region:``,metadataJson:`{}`});return}Pr({name:Yi.name,status:Yi.status||`active`,region:Yi.region||``,metadataJson:JSON.stringify(Yi.metadata||{},null,2)})},[Yi]),(0,_.useEffect)(()=>{$r(``),Ir({name:``,parentGroupId:``}),ti([])},[T]),(0,_.useEffect)(()=>{ai(null),si([])},[T]),(0,_.useEffect)(()=>{localStorage.setItem(C.baseUrl,i),localStorage.setItem(C.language,d),a&&localStorage.setItem(`${C.language}.${a.userId}`,d),(!a||!n)&&(localStorage.removeItem(C.auth),localStorage.removeItem(C.actorUserId))},[i,d,n,a]),(0,_.useEffect)(()=>{if(!a)return;let e=localStorage.getItem(`${C.language}.${a.userId}`);(e===`ru`||e===`en`)&&f(e)},[a?.userId]),(0,_.useEffect)(()=>{a&&da()},[a?.userId]),(0,_.useEffect)(()=>{if(!a||s!==`admin`||!T)return;let e=!1,t=()=>{e||Tr||Ji.current||document.visibilityState===`hidden`||(Ji.current=!0,pa(T).catch(t=>{e||Or(t instanceof Error?t.message:`Не удалось автообновить данные панели.`)}).finally(()=>{Ji.current=!1}))},n=null;typeof window.EventSource==`function`&&(n=new EventSource(q.clusterEventsURL(T)),n.onopen=()=>{e||br(`sse`)},n.onerror=()=>{e||br(`poll`)},n.addEventListener(`cluster.changed`,t));let r=window.setInterval(t,n?3e4:1e4);return()=>{e=!0,n?.close(),window.clearInterval(r)}},[q,s,Tr,T,a?.userId]);async function da(e=T){if(!p.trim()){Or(J.noLoginError);return}if(s===`user`){await fa();return}Er(!0),Or(``),Ar(``);try{let[t,n,r,i,a]=await Promise.all([q.listClusters(),q.listClusterSummaries(),q.listOrganizations(),q.listUsers(),q.listResources()]);ve(t),Ce(n),ir(r),or(i),cr(a),!xr&&r[0]?.id&&Sr(r[0].id),ji(e=>({...e,organizationId:e.organizationId||r[0]?.id||``})),Ii(e=>({...e,organizationId:e.organizationId||r[0]?.id||``}));let o=await Promise.all(r.map(async e=>[e.id,await q.listOrganizationMemberships(e.id)]));ur(Object.fromEntries(o));let s=await Promise.all(t.map(async e=>[e.id,await q.listNodes(e.id)]));Ae(Object.fromEntries(s));let c=e||t[0]?.id||``;de(c),c&&await ma(c),vr(new Date().toISOString())}catch(e){Or(e instanceof Error?e.message:`Неизвестная ошибка панели управления платформой.`)}finally{Er(!1)}}async function fa(){if(!p.trim()){Or(`Войдите, чтобы загрузить личный кабинет.`);return}Er(!0),Or(``),Ar(``);try{await ca();let[e,t]=await Promise.all([q.listOrganizations(),q.listResources()]);ir(e),cr(t),!xr&&e[0]?.id&&Sr(e[0].id);let n=await Promise.all(e.map(async e=>[e.id,await q.listOrganizationMemberships(e.id)]));ur(Object.fromEntries(n)),vr(new Date().toISOString())}catch(e){Or(e instanceof Error?e.message:`Не удалось загрузить личный кабинет.`)}finally{Er(!1)}}async function pa(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()]);Ce(t),ir(r),or(i),cr(a),Ae(t=>({...t,[e]:n})),await ma(e,{preserveEditableForms:!0}),vr(new Date().toISOString())}async function ma(e,t={}){let n=++qi.current,r=mn?20:10,i=mn?z.offset:0,a={reporterNodeId:z.reporterNodeId||void 0,routeId:z.routeId||void 0,serviceClass:z.serviceClass||void 0,generation:z.generation||void 0,feedbackSource:z.feedbackSource||void 0,feedbackChannelId:z.feedbackChannelId||void 0,feedbackViolationStatus:z.feedbackViolationStatus||void 0,limit:r,offset:i,enrichment:mn?`deep`:`summary`},[o,s,c,l,u,d,f,p,m,h,g,_,v,y,b,x,ee,S,te,ne,re,ie,w,ae,oe]=await Promise.all([q.listNodes(e),q.listNodeGroups(e),q.listJoinRequests(e),q.listJoinTokens(e),q.listReleaseVersions(e,`rap-node-agent`,`dev`),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!==qi.current)return;Ee(o),Oe(s),Me(c),Pe(l),ze(u),Te(d),t.preserveEditableForms||Gr({authorityState:d.authority_state,mutationMode:d.mutation_mode,notes:d.notes||``}),fr(f),mr(p.events),gr(p.summary||null),yt(m),xt(h),Dt(g),Ht(_),Qt(v),en(y),nn(b),an(x),sn(ee),dn(S),fn(te),R(ne),wn(re),En(ie),t.preserveEditableForms||Br({currentWindowSeconds:String(ie.current_window_seconds||1800),historyWindowSeconds:String(ie.history_window_seconds||86400)}),Rr({hysteresisPenalty:String(re.hysteresis_penalty),promotionMinSamples:String(re.promotion_min_samples),demotionFailureThreshold:String(re.demotion_failure_threshold),demotionDropThreshold:String(re.demotion_drop_threshold),demotionSlowThreshold:String(re.demotion_slow_threshold),demotionRebuildEnabled:re.demotion_rebuild_enabled,demotionFencedEnabled:re.demotion_fenced_enabled}),On(w),Nn(ae),An(oe);let T=await q.listVPNClientDiagnosticStatuses(e);if(n!==qi.current)return;Xn(T);let se=T.find(e=>e.device_id===qn.trim())||T[0]||null;Qn(se),!qn.trim()&&se&&(Jn(se.device_id),localStorage.setItem(C.vpnDiagnosticDeviceId,se.device_id));let ce=await Promise.all(o.map(async t=>[t.id,await q.listNodeRoles(e,t.id)]));if(n!==qi.current)return;Ge(Object.fromEntries(ce));let le=await Promise.all(o.map(async t=>[t.id,await q.listDesiredWorkloads(e,t.id)]));if(n!==qi.current)return;qe(Object.fromEntries(le));let E=await Promise.all(o.map(async t=>[t.id,await q.listWorkloadStatuses(e,t.id)]));if(n!==qi.current)return;nt(Object.fromEntries(E));let D=await Promise.all(o.map(async t=>[t.id,await q.listNodeHeartbeats(e,t.id,60)]));if(n!==qi.current)return;it(Object.fromEntries(D));let ue=await Promise.all(o.map(async t=>[t.id,await q.getNodeUpdatePlan(e,t.id,{currentVersion:t.reported_version})]));if(n!==qi.current)return;Ve(Object.fromEntries(ue));let de=await Promise.all(o.map(async t=>[t.id,await q.listNodeUpdateStatuses(e,t.id,80)]));if(n!==qi.current)return;Ue(Object.fromEntries(de));let fe=await Promise.all(o.map(async t=>[t.id,await q.listNodeTelemetry(e,t.id,120)]));if(n!==qi.current)return;pt(Object.fromEntries(fe));let O=await Promise.all(o.map(async t=>[t.id,await q.getNodeSyntheticMeshConfig(e,t.id)]));if(n!==qi.current)return;Ct(Object.fromEntries(O));let k=await Promise.all(ae.map(async t=>[t.id,await q.getActiveVPNLease(e,t.id)]));if(n!==qi.current)return;zn(Object.fromEntries(k));let pe=await Promise.all(ae.map(async t=>[t.id,await q.getVPNPacketStats(e,t.id)]));n===qi.current&&Kn(Object.fromEntries(pe))}async function ha(e=mn,t=z){if(T){Er(!0),Or(``),Ar(``);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`});hn(e),yn(t),Ht(n),Ar(e?`Deep rebuild ledger loaded.`:`Fast rebuild ledger loaded.`)}catch(e){Or(e instanceof Error?e.message:`Не удалось загрузить rebuild ledger.`)}finally{Er(!1)}}}async function ga(){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)]);Qt(e),en(t),nn(n),an(r),sn(i),dn(a),fn(o),R(s),mr(c.events),gr(c.summary||null),En(l),Br({currentWindowSeconds:String(l.current_window_seconds||1800),historyWindowSeconds:String(l.history_window_seconds||86400)})}async function _a(){if(T)try{Er(!0);let e=await q.warmupFabricServiceChannelRebuildSnapshots(T,{limit:10,staleAfterSeconds:60});ln(e),await ga(),Ar(`Snapshot warmup: warmed ${e.warmed_count}, fresh ${e.already_fresh_count}, errors ${e.error_count}.`)}catch(e){Or(e instanceof Error?e.message:`Не удалось прогреть rebuild snapshots.`)}finally{Er(!1)}}async function va(){if(T)try{Er(!0);let e=await q.cleanupFabricServiceChannelLeases(T,{limit:100});dn(e),Ar(`Service-channel lease cleanup: deleted ${e.deleted_expired_count||0}, active ${e.active_count}, expired ${e.expired_count}.`)}catch(e){Or(e instanceof Error?e.message:`Не удалось очистить service-channel leases.`)}finally{Er(!1)}}async function ya(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});mr(n.events),gr(n.summary||null),yn(t),await ha(!0,t)}function ba(e){let t=new Set(e.affected_reporter_node_ids||[]),n=new Set(e.affected_route_ids||[]);return pn.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 xa(e){let t=N(e.payload)||{},n=P(t,`feedback_source`,``),r=P(t,`feedback_channel_id`,``),i=P(t,`feedback_violation_status`,``),a=P(t,`reporter_node_id`,``),o=P(t,`route_id`,``);return!n&&!r&&!i?null:(I?.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 Sa(e){let t=N(e.payload)||{},n=P(t,`reporter_node_id`,``),r=P(t,`route_id`,e.target_type===`fabric_service_channel_route_rebuild_incident`&&e.target_id||``),i=P(t,`service_class`,``),a=P(t,`generation`,``),o=P(t,`guard_status`,``);return pn.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 Ca(e){let t={...re,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});mr(n.events),gr(n.summary||null),ae(`fabric`),yn(t),await ha(!0,t)}async function wa(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 ga()}async function Ta(e){await q.unsilenceFabricServiceChannelRouteRebuildAlert(T,e.id,`operator removed rebuild alert silence`),await ga()}function Ea(){Ee([]),Oe([]),Me([]),Pe([]),ze([]),Ve({}),Te(null),Ge({}),qe({}),nt({}),it({}),Ue({}),pt({}),yt([]),xt([]),Ct({}),Dt([]),Ht([]),Qt(null),en([]),nn(null),an(null),ln(null),R([]),hn(!1),yn(re),On([]),An([]),Nn([]),zn({}),Kn({}),Xn([]),Qn(null),ir([]),or([]),cr([]),ur({}),fr([]),mr([]),gr(null)}async function Y(e,t){Er(!0),Or(``),Ar(``);try{await e(),Ar(t),await da()}catch(e){Or(e instanceof Error?e.message:`Действие не выполнено.`)}finally{Er(!1)}}async function Da(){if(!T){Qn(null);return}let e=await q.listVPNClientDiagnosticStatuses(T);Xn(e);let t=qn.trim()||e[0]?.device_id||``;t&&(localStorage.setItem(C.vpnDiagnosticDeviceId,t),Jn(t));let n=e.find(e=>e.device_id===t)||(t?await q.getVPNClientDiagnosticStatus(T,t):null);Qn(n),Ar(n?`Диагностика VPN-клиента обновлена.`:`Диагностика VPN-клиента не найдена.`)}async function Oa(e,t){if(!T){Or(`Выбери кластер перед отправкой команды.`);return}let n=qn.trim();if(!n){Or(`Укажи Android device id или выбери найденный клиент.`);return}Er(!0),Or(``),Ar(``);try{nr(await q.enqueueVPNClientDiagnosticCommand(T,n,e)),Ar(`${t}: команда поставлена в очередь. Клиент заберет ее через диагностический канал.`),window.setTimeout(()=>{Da()},3500)}catch(e){Or(e instanceof Error?e.message:`Команда VPN-клиенту не отправлена.`)}finally{Er(!1)}}async function ka(){Er(!0),Or(``),Ar(``);try{let e=D(await Ki.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()]);ir(e),cr(r),e[0]?.id&&Sr(e[0].id);let i=await Promise.all(e.map(async e=>[e.id,await t.listOrganizationMemberships(e.id)]));ur(Object.fromEntries(i)),n=`user`}catch{try{await Ki.revokeAuthSession({userId:e.userId,authSessionId:e.authSessionId,reason:`user_portal_access_denied`})}catch{}throw Error(J.accessDenied)}}r(h.rememberMe),sa(e,h.rememberMe),o(e),m(e.userId),g(t=>({...t,email:e.email,password:``})),u(new Date().toISOString()),c(n),Ar(`${J.signedInAs}: ${e.email}`)}catch(e){Or(e instanceof Error?e.message:`Вход не выполнен.`)}finally{Er(!1)}}async function Aa(){Er(!0),Or(``),Ar(``);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 Ki.bootstrapOwner({email:x.email,password:x.password,activationPayload:e,activationSignature:x.activationSignature})).installation),g({...h,email:x.email,password:x.password}),Ar(J.ownerCreated)}catch(e){Or(e instanceof Error?e.message:`Создание владельца не выполнено.`)}finally{Er(!1)}}async function ja(){let e=a;if(o(null),r(!1),u(``),sa(null),c(null),m(``),ve([]),Ce([]),Ea(),Ae({}),de(``),e?.userId&&e.authSessionId)try{await Ki.revokeAuthSession({userId:e.userId,authSessionId:e.authSessionId,reason:`platform_owner_console_logout`})}catch{}}async function Ma(e){de(e),Ea(),Er(!0),Or(``),Ar(``);try{await ma(e)}catch(e){Or(e instanceof Error?e.message:`Не удалось загрузить кластер.`)}finally{Er(!1)}}let Na=je.filter(e=>e.status===`pending`).length,Pa=j.filter(e=>e.health_status===`healthy`).length,Fa=j.filter(e=>e.health_status!==`healthy`||e.membership_status!==`active`).length,Ia=Object.values(We).flat().filter(e=>e.status===`active`).length,La=kn.find(e=>e.scope_type===`platform`&&!e.scope_id)||null;kn.find(e=>e.scope_type===`organization`&&e.scope_id===bi&&(!e.cluster_id||e.cluster_id===T));let Ra=Object.values(St),za=Ra.filter(e=>e.enabled).length,Ba=Ra.reduce((e,t)=>e+t.routes.length,0),Va=Ra.reduce((e,t)=>e+Object.keys(t.peer_endpoints||{}).length,0),Ha=Ra.reduce((e,t)=>e+Ot(t),0);Ra.reduce((e,t)=>e+(t.peer_directory?.length??0),0),Ra.reduce((e,t)=>e+(t.recovery_seeds?.length??0),0);let Ua=Ra.filter(e=>e.production_forwarding).length,Wa=Ie(j,rt),Ga=bt.filter(e=>lt(e)===`active`),Ka=bt.filter(e=>lt(e)===`expired`),qa=bt.filter(e=>lt(e)===`disabled`),Ja=Et.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()}),Ya=Ja.filter(e=>e.feedback_status===`fenced`),Xa=Ja.filter(e=>e.feedback_status===`degraded`),Za=Ja.filter(e=>e.feedback_status===`healthy`),Qa=Ja.filter(e=>e.recovery_state===`recovered`||e.recovery_hysteresis_active),$a=Ja.filter(e=>e.recovery_promoted),eo=Ja.filter(e=>e.recovery_demoted),to=Ja.filter(e=>e.feedback_status===`operator_retry_cooldown`||e.retry_cooldown_until),no=Ra.flatMap(e=>e.route_path_decisions?.decisions||[]),X=no.filter(e=>e.decision_source===`service_channel_feedback_no_alternate`),ro=no.filter(e=>e.decision_source===`service_channel_feedback_replacement`),io=no.filter(e=>e.rebuild_status),ao=io.filter(e=>e.rebuild_status===`applied`),oo=zt.filter(e=>e.rebuild_status===`applied`),so=zt.filter(e=>e.rebuild_status&&e.rebuild_status!==`applied`),co=zt.filter(e=>e.guard_severity===`bad`),lo=no.filter(e=>(e.score_reasons||[]).includes(`service_channel_recovery_hysteresis`)),uo=no.filter(e=>(e.score_reasons||[]).includes(`service_channel_recovery_promoted`)),fo=no.filter(e=>(e.score_reasons||[]).includes(`service_channel_recovery_demoted`)),po=v?.bootstrapped===!1,mo=po&&!v?.strict_authority&&!v?.insecure_bootstrap_allowed,ho=s===`admin`?J.sessionModeAdmin:J.sessionModeUser;if(!a)return(0,S.jsxs)(`main`,{className:`loginShell`,children:[v&&(0,S.jsxs)(`section`,{className:`loginCard`,children:[(0,S.jsx)(`h1`,{children:v.bootstrapped?J.installationLocked:J.bootstrapTitle}),(0,S.jsx)(A,{label:`Authority`,value:`${v.authority_mode}/${v.authority_state}`}),(0,S.jsx)(A,{label:`Strict`,value:v.strict_authority?`enabled`:`legacy`}),v.root_fingerprint&&(0,S.jsx)(A,{label:`Root key`,value:B(v.root_fingerprint)})]}),po?(0,S.jsxs)(`section`,{className:`loginCard`,children:[(0,S.jsx)(`h1`,{children:J.bootstrapTitle}),(0,S.jsx)(`p`,{className:`loginHint`,children:mo?J.insecureBootstrapDisabled:J.bootstrapText}),(0,S.jsxs)(`label`,{children:[J.email,(0,S.jsx)(`input`,{value:x.email,onChange:e=>ee({...x,email:e.target.value}),autoComplete:`username`})]}),(0,S.jsxs)(`label`,{children:[J.password,(0,S.jsx)(`input`,{value:x.password,onChange:e=>ee({...x,password:e.target.value}),type:`password`,autoComplete:`new-password`})]}),v?.strict_authority&&(0,S.jsxs)(S.Fragment,{children:[(0,S.jsxs)(`label`,{children:[J.activationPayload,(0,S.jsx)(`textarea`,{value:x.activationPayload,onChange:e=>ee({...x,activationPayload:e.target.value}),spellCheck:!1})]}),(0,S.jsxs)(`label`,{children:[J.activationSignature,(0,S.jsx)(`input`,{value:x.activationSignature,onChange:e=>ee({...x,activationSignature:e.target.value}),spellCheck:!1})]})]}),Dr&&(0,S.jsx)(`div`,{className:`errorPanel`,children:Dr}),kr&&(0,S.jsx)(`div`,{className:`noticePanel`,children:kr}),(0,S.jsx)(`button`,{className:`primary wide`,onClick:()=>void Aa(),disabled:Tr||mo||!x.email||x.password.length<12||v?.strict_authority&&(!x.activationPayload||!x.activationSignature),children:Tr?J.creatingOwner:J.createOwner})]}):(0,S.jsxs)(`section`,{className:`loginCard`,children:[(0,S.jsx)(`h1`,{children:J.signInTitle}),(0,S.jsxs)(`label`,{children:[J.email,(0,S.jsx)(`input`,{value:h.email,onChange:e=>g({...h,email:e.target.value.trim()}),autoComplete:`username`,autoCapitalize:`none`,autoCorrect:`off`,spellCheck:!1})]}),(0,S.jsxs)(`label`,{children:[J.password,(0,S.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`&&ka()}})]}),(0,S.jsxs)(`label`,{className:`checkLine`,children:[(0,S.jsx)(`input`,{type:`checkbox`,checked:h.showPassword,onChange:e=>g({...h,showPassword:e.target.checked})}),`Показать пароль`]}),(0,S.jsxs)(`label`,{className:`checkLine`,children:[(0,S.jsx)(`input`,{type:`checkbox`,checked:h.trustDevice,onChange:e=>g({...h,trustDevice:e.target.checked})}),J.trustDevice]}),(0,S.jsxs)(`label`,{className:`checkLine`,children:[(0,S.jsx)(`input`,{type:`checkbox`,checked:h.rememberMe,onChange:e=>g({...h,rememberMe:e.target.checked})}),J.rememberMe]}),Dr&&(0,S.jsx)(`div`,{className:`errorPanel`,children:Dr}),kr&&(0,S.jsx)(`div`,{className:`noticePanel`,children:kr}),(0,S.jsx)(`button`,{className:`primary wide`,onClick:()=>void ka(),disabled:Tr||!h.email||!h.password,children:Tr?J.signingIn:J.signIn})]})]});if(a&&!s)return(0,S.jsx)(`main`,{className:`loginShell`,children:(0,S.jsx)(`section`,{className:`loginCard`,children:(0,S.jsx)(`p`,{children:Tr?J.lastRefresh:`Восстанавливаем сессию...`})})});if(s===`user`){let e=rr.find(e=>e.id===xr)||rr[0]||null,t=e?sr.filter(t=>t.organization_id===e.id):sr,n=e?(lr[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,S.jsxs)(`main`,{className:`portalShell`,children:[(0,S.jsxs)(`aside`,{className:`portalRail`,children:[(0,S.jsx)(`div`,{className:`brandMark`,children:`RAP`}),(0,S.jsx)(`p`,{className:`sideKicker`,children:`Личный кабинет`}),(0,S.jsx)(`h1`,{children:`Мой доступ`}),(0,S.jsx)(`p`,{className:`sideText`,children:`Установки, доступные серверы и состояние рабочей области пользователя.`}),(0,S.jsx)(A,{label:J.sessionMode,value:`${ho} • ${l?Rn(l):`н/д`}`}),(0,S.jsx)(A,{label:J.actorUser,value:a.email}),(0,S.jsx)(`button`,{className:`ghost`,onClick:()=>void ja(),disabled:Tr,children:J.logout})]}),(0,S.jsxs)(`section`,{className:`portalWorkspace`,children:[(0,S.jsxs)(`header`,{className:`portalTop`,children:[(0,S.jsxs)(`div`,{children:[(0,S.jsx)(`p`,{className:`eyebrow`,children:`Secure Access Fabric`}),(0,S.jsx)(`h2`,{children:e?.name||`Личный кабинет`}),(0,S.jsx)(`p`,{className:`muted`,children:a.email})]}),(0,S.jsxs)(`label`,{children:[`Организация`,(0,S.jsx)(`select`,{value:e?.id||``,onChange:e=>Sr(e.target.value),children:rr.map(e=>(0,S.jsx)(`option`,{value:e.id,children:e.name},e.id))})]}),(0,S.jsx)(`button`,{className:`primary`,onClick:()=>void fa(),disabled:Tr,children:Tr?J.refreshing:J.refresh})]}),Dr&&(0,S.jsx)(`div`,{className:`errorPanel`,children:Dr}),kr&&(0,S.jsx)(`div`,{className:`noticePanel`,children:kr}),(0,S.jsxs)(`section`,{className:`grid three`,children:[(0,S.jsx)(fe,{label:`Организации`,value:rr.length,tone:`steel`}),(0,S.jsx)(fe,{label:`Серверы`,value:t.length,tone:`green`}),(0,S.jsx)(fe,{label:`Установки`,value:2,tone:`amber`})]}),(0,S.jsxs)(`section`,{className:`grid two`,children:[(0,S.jsxs)(`article`,{className:`card`,children:[(0,S.jsxs)(`div`,{className:`cardHead`,children:[(0,S.jsxs)(`div`,{children:[(0,S.jsx)(`h3`,{children:`Установки`}),(0,S.jsx)(`p`,{className:`muted`,children:Li?`Актуальная версия Android: ${Li}`:`Скачивайте актуальные клиенты только отсюда, чтобы не ловить старую сборку.`})]}),(0,S.jsx)(`span`,{className:`status active`,children:`latest`})]}),(0,S.jsxs)(`div`,{className:`portalInstallList`,children:[(0,S.jsxs)(`a`,{className:`installTile primaryInstall`,href:na,children:[(0,S.jsx)(`strong`,{children:`Android VPN`}),(0,S.jsx)(`span`,{children:`Последняя сборка RAP HOME VPN для телефона`}),(0,S.jsx)(`small`,{children:Vi||ta})]}),(0,S.jsxs)(`a`,{className:`installTile`,href:`${Zi}/downloads/rap-windows-rdp-client-latest-win-x64.zip`,children:[(0,S.jsx)(`strong`,{children:`Windows RDP клиент`}),(0,S.jsx)(`span`,{children:`Клиент удаленного рабочего стола, когда нужен доступ к серверам`}),(0,S.jsx)(`small`,{children:`latest win-x64`})]})]})]}),(0,S.jsxs)(`article`,{className:`card`,children:[(0,S.jsx)(`h3`,{children:`Профиль`}),(0,S.jsx)(A,{label:`Пользователь`,value:a.email}),(0,S.jsx)(A,{label:`Роль в организации`,value:n?.role_id||`участник`}),(0,S.jsx)(A,{label:`Организация`,value:e?.name||`нет`}),(0,S.jsx)(A,{label:`Последнее обновление`,value:_r?V(_r):`нет`})]}),(0,S.jsxs)(`article`,{className:`card span2`,children:[(0,S.jsx)(`div`,{className:`cardHead`,children:(0,S.jsxs)(`div`,{children:[(0,S.jsx)(`h3`,{children:`Доступные серверы`}),(0,S.jsx)(`p`,{className:`muted`,children:`Список ресурсов, которые уже разрешены пользователю через организацию.`})]})}),(0,S.jsx)(M,{columns:[`имя`,`адрес`,`протокол`,`секрет`,`передача файлов`],rows:t.map(e=>[e.name,e.address,e.protocol,e.has_secret?`настроен`:`нет`,H(e.file_transfer_mode||`disabled`)])})]}),(0,S.jsxs)(`article`,{className:`card`,children:[(0,S.jsx)(`h3`,{children:`Сервисы`}),(0,S.jsx)(M,{columns:[`тип`,`количество`],rows:Object.entries(r).map(([e,t])=>[e,String(t)])})]}),(0,S.jsxs)(`article`,{className:`card`,children:[(0,S.jsx)(`h3`,{children:`Что здесь будет дальше`}),(0,S.jsxs)(`div`,{className:`portalRoadmap`,children:[(0,S.jsx)(`span`,{children:`Устройства и доверенные входы`}),(0,S.jsx)(`span`,{children:`Активные VPN-сессии`}),(0,S.jsx)(`span`,{children:`Обновление профиля VPN без ручных ключей`}),(0,S.jsx)(`span`,{children:`Самостоятельная смена пароля`})]})]})]})]})]})}return(0,S.jsxs)(`main`,{className:`consoleShell`,children:[(0,S.jsxs)(`aside`,{className:`sideRail`,children:[(0,S.jsx)(`div`,{className:`brandMark`,children:`SAF`}),(0,S.jsx)(`p`,{className:`sideKicker`,children:J.productOwner}),(0,S.jsx)(`h1`,{children:J.controlPlane}),(0,S.jsx)(`p`,{className:`sideText`,children:J.sideText}),(0,S.jsx)(`nav`,{className:`railNav`,children:oe.filter(e=>e.id!==`roles`).map(e=>(0,S.jsx)(`button`,{className:w===e.id?`active`:``,onClick:()=>ae(e.id),children:e[d]},e.id))})]}),(0,S.jsxs)(`section`,{className:`workspace`,children:[(0,S.jsxs)(`header`,{className:`topBar`,children:[(0,S.jsxs)(`div`,{children:[(0,S.jsx)(`p`,{className:`eyebrow`,children:`Secure Access Fabric`}),(0,S.jsx)(`h2`,{children:Yi?Yi.name:J.consoleTitle}),(0,S.jsx)(`p`,{className:`muted`,children:J.boundary})]}),(0,S.jsxs)(`div`,{className:`clusterPicker`,children:[(0,S.jsxs)(`label`,{children:[J.activeCluster,(0,S.jsx)(`select`,{value:T,onChange:e=>void Ma(e.target.value),children:ge.map(e=>(0,S.jsx)(`option`,{value:e.id,children:e.name},e.id))})]}),(0,S.jsxs)(`span`,{children:[J.slugLabel,`: `,Yi?.slug||`н/д`]})]}),(0,S.jsx)(`button`,{className:`primary`,onClick:()=>void da(),disabled:Tr,children:Tr?J.refreshing:J.refresh}),(0,S.jsxs)(`div`,{className:`refreshStatus`,children:[(0,S.jsx)(`strong`,{children:J.autoRefresh}),(0,S.jsx)(`span`,{children:_r?`${J.lastRefresh}: ${Rn(_r)} / ${yr.toUpperCase()}`:yr.toUpperCase()})]}),(0,S.jsxs)(`div`,{className:`profilePanel`,children:[(0,S.jsx)(`strong`,{children:J.profile}),(0,S.jsx)(`span`,{children:a.email}),(0,S.jsxs)(`span`,{children:[J.sessionMode,`: `,ho,` | `,J.sessionRefreshedAt,`: `,l?Rn(l):`н/д`]}),(0,S.jsxs)(`label`,{children:[J.language,(0,S.jsxs)(`select`,{value:d,onChange:e=>f(e.target.value),children:[(0,S.jsx)(`option`,{value:`ru`,children:`Русский`}),(0,S.jsx)(`option`,{value:`en`,children:d===`ru`?`Английский`:`English`})]})]}),(0,S.jsx)(`button`,{className:`ghost`,onClick:()=>void ja(),disabled:Tr,children:J.logout})]})]}),Dr&&(0,S.jsx)(`div`,{className:`errorPanel`,children:Dr}),kr&&(0,S.jsx)(`div`,{className:`noticePanel`,children:kr}),Yi&&j.length===0&&(0,S.jsxs)(`div`,{className:`noticePanel`,children:[(0,S.jsxs)(`strong`,{children:[J.emptyLiveTitle,`.`]}),` `,J.emptyLiveText]}),w===`command`&&(0,S.jsxs)(`section`,{className:`grid five`,children:[(0,S.jsx)(fe,{label:`Кластеры`,value:ge.length,tone:`steel`}),(0,S.jsx)(fe,{label:`Узлы в области`,value:j.length,tone:`green`}),(0,S.jsx)(fe,{label:`Здоровые узлы`,value:Pa,tone:`green`}),(0,S.jsx)(fe,{label:`Ожидают подключения`,value:Na,tone:`amber`}),(0,S.jsx)(fe,{label:`Рискованные состояния`,value:Fa,tone:`red`}),(0,S.jsxs)(`article`,{className:`card span3`,children:[(0,S.jsx)(`h3`,{children:`Общее состояние кластеров`}),(0,S.jsx)(M,{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,S.jsxs)(`article`,{className:`card span2`,children:[(0,S.jsx)(`h3`,{children:`Authority выбранного кластера`}),we?(0,S.jsxs)(`div`,{className:`stateList`,children:[(0,S.jsx)(A,{label:`Authority`,value:we.authority_state}),(0,S.jsx)(A,{label:`Режим изменений`,value:we.mutation_mode}),(0,S.jsx)(A,{label:`Терм`,value:String(we.term)}),(0,S.jsx)(A,{label:`Cluster key`,value:B(Xi?.cluster_key_fingerprint)}),(0,S.jsx)(A,{label:`Обновлено`,value:V(we.updated_at)})]}):(0,S.jsx)(me,{title:`Нет состояния authority`,text:`Выберите кластер, чтобы загрузить состояние authority.`})]}),(0,S.jsxs)(`article`,{className:`card span2`,children:[(0,S.jsx)(`h3`,{children:`Граница платформы`}),(0,S.jsx)(`p`,{className:`muted`,children:`Эта панель предназначена для владельца продукта / владельца платформы. Панели организаций должны использовать безопасные проекции и не раскрывать mesh internals, peer cache, route cache, секреты или данные других tenants.`})]}),(0,S.jsxs)(`article`,{className:`card span3`,children:[(0,S.jsx)(`h3`,{children:`Текущие сигналы кластера`}),(0,S.jsxs)(`div`,{className:`signalStrip`,children:[(0,S.jsx)(O,{label:`Активные роли`,value:String(Ia)}),(0,S.jsx)(O,{label:`Отчеты сервисов`,value:String(Object.values(Qe).filter(e=>e.length>0).length)}),(0,S.jsx)(O,{label:`Наблюдения связей`,value:String(gt.length)}),(0,S.jsx)(O,{label:`Synthetic configs`,value:`${za}/${j.length}`})]})]})]}),w===`clusters`&&(0,S.jsxs)(`section`,{className:`grid two`,children:[(0,S.jsxs)(`article`,{className:`card span2`,children:[(0,S.jsxs)(`div`,{className:`cardHead`,children:[(0,S.jsxs)(`div`,{children:[(0,S.jsx)(`h3`,{children:J.clusterCatalog}),(0,S.jsx)(`p`,{className:`muted`,children:J.clusterCatalogText})]}),(0,S.jsx)(`span`,{className:`pill`,children:Mn(ge.length,d)})]}),(0,S.jsxs)(`div`,{className:`clusterCatalog`,children:[ge.map(e=>{let t=Se.find(t=>t.cluster_id===e.id),n=e.id===T;return(0,S.jsxs)(`article`,{className:`clusterCard ${n?`selected`:``}`,children:[(0,S.jsxs)(`div`,{className:`clusterCardMain`,children:[(0,S.jsxs)(`div`,{children:[(0,S.jsx)(`p`,{className:`eyebrow`,children:e.region||`регион не задан`}),(0,S.jsx)(`h4`,{children:e.name}),(0,S.jsxs)(`p`,{className:`muted`,children:[J.slugLabel,`: `,(0,S.jsx)(`strong`,{children:e.slug})]})]}),(0,S.jsxs)(`div`,{className:`clusterCardActions`,children:[(0,S.jsx)(k,{value:e.status}),n?(0,S.jsx)(`span`,{className:`pill good`,children:J.selected}):(0,S.jsx)(`button`,{onClick:()=>void Ma(e.id),children:J.makeActive}),(0,S.jsx)(`button`,{className:`ghost`,onClick:()=>{Ma(e.id),ae(`cluster-settings`)},children:J.openSettings})]})]}),(0,S.jsxs)(`div`,{className:`signalStrip compact`,children:[(0,S.jsx)(O,{label:`Узлы`,value:t?`${t.healthy_node_count}/${t.node_count}`:`н/д`}),(0,S.jsx)(O,{label:`Заявки`,value:String(t?.pending_join_count??`н/д`)}),(0,S.jsx)(O,{label:`Роли`,value:String(t?.active_role_assignment_count??`н/д`)}),(0,S.jsx)(O,{label:`Последний сигнал`,value:V(t?.last_node_seen_at)})]}),(0,S.jsxs)(`details`,{children:[(0,S.jsx)(`summary`,{children:J.clusterDetails}),(0,S.jsxs)(`div`,{className:`stateList`,children:[(0,S.jsx)(A,{label:`ID`,value:e.id}),(0,S.jsx)(A,{label:J.slugLabel,value:e.slug}),(0,S.jsx)(A,{label:`Статус`,value:H(e.status)}),(0,S.jsx)(A,{label:`Authority`,value:t?`${t.authority_state}/${t.mutation_mode}`:`неизвестно`}),(0,S.jsx)(A,{label:`Создан`,value:V(e.created_at)}),(0,S.jsx)(A,{label:`Обновлен`,value:V(e.updated_at||e.created_at)})]})]})]},e.id)}),ge.length===0&&(0,S.jsx)(me,{title:`Кластеров нет`,text:`Создайте первый кластер, затем подключите стартовый node-agent.`})]})]}),(0,S.jsxs)(`article`,{className:`card`,children:[(0,S.jsx)(`h3`,{children:J.createCluster}),(0,S.jsxs)(Je,{children:[(0,S.jsxs)(`label`,{children:[J.slugLabel,(0,S.jsx)(`input`,{value:jr.slug,onChange:e=>Mr({...jr,slug:e.target.value})})]}),(0,S.jsxs)(`label`,{children:[`Название`,(0,S.jsx)(`input`,{value:jr.name,onChange:e=>Mr({...jr,name:e.target.value})})]}),(0,S.jsxs)(`label`,{children:[`Регион`,(0,S.jsx)(`input`,{value:jr.region,onChange:e=>Mr({...jr,region:e.target.value})})]})]}),(0,S.jsx)(`p`,{className:`muted`,children:J.slugHelp}),(0,S.jsx)(`button`,{className:`primary`,disabled:!jr.slug||!jr.name,onClick:()=>void Y(async()=>{await q.createCluster({slug:jr.slug,name:jr.name,region:jr.region||null}),Mr({slug:``,name:``,region:``})},`Кластер создан.`),children:J.createCluster})]}),(0,S.jsxs)(`article`,{className:`card`,children:[(0,S.jsx)(`h3`,{children:`Что такое технический код?`}),(0,S.jsx)(`p`,{className:`muted`,children:J.slugHelp}),(0,S.jsx)(`p`,{className:`muted`,children:`Для человека основное поле — название. Для системы и операторов — технический код. Он нужен, чтобы сценарии, логи и будущие endpoint-адреса не зависели от переименования кластера.`})]})]}),w===`cluster-settings`&&(0,S.jsxs)(`section`,{className:`grid two`,children:[!Yi&&(0,S.jsx)(me,{title:`Кластер не выбран`,text:`Выберите активный кластер, чтобы открыть настройки.`}),Yi&&(0,S.jsxs)(S.Fragment,{children:[(0,S.jsxs)(`article`,{className:`card`,children:[(0,S.jsx)(`h3`,{children:`Identity кластера`}),(0,S.jsx)(`p`,{className:`muted`,children:`Базовые параметры хранятся в PostgreSQL. Slug остается неизменяемым идентификатором для операторов и скриптов.`}),(0,S.jsxs)(Je,{children:[(0,S.jsxs)(`label`,{children:[`ID`,(0,S.jsx)(`input`,{value:Yi.id,readOnly:!0})]}),(0,S.jsxs)(`label`,{children:[`Slug`,(0,S.jsx)(`input`,{value:Yi.slug,readOnly:!0})]}),(0,S.jsxs)(`label`,{children:[`Название`,(0,S.jsx)(`input`,{value:Nr.name,onChange:e=>Pr({...Nr,name:e.target.value})})]}),(0,S.jsxs)(`label`,{children:[`Статус`,(0,S.jsxs)(`select`,{value:Nr.status,onChange:e=>Pr({...Nr,status:e.target.value}),children:[(0,S.jsx)(`option`,{value:`active`,children:`active, работает`}),(0,S.jsx)(`option`,{value:`disabled`,children:`disabled, отключен`})]})]}),(0,S.jsxs)(`label`,{children:[`Регион`,(0,S.jsx)(`input`,{value:Nr.region,onChange:e=>Pr({...Nr,region:e.target.value}),placeholder:`например ru-msk-1`})]}),(0,S.jsxs)(`label`,{children:[`Обновлен`,(0,S.jsx)(`input`,{value:V(Yi.updated_at||Yi.created_at),readOnly:!0})]})]}),(0,S.jsxs)(`label`,{className:`wideLabel`,children:[`Metadata JSON`,(0,S.jsx)(`textarea`,{value:Nr.metadataJson,onChange:e=>Pr({...Nr,metadataJson:e.target.value}),rows:8,spellCheck:!1})]}),(0,S.jsx)(`button`,{className:`primary`,disabled:!Nr.name.trim(),onClick:()=>Fn(`Сохранить базовые настройки кластера`)&&void Y(async()=>{let e=Ye(Nr.metadataJson||`{}`,`Metadata JSON`);await q.updateCluster(Yi.id,{name:Nr.name,status:Nr.status,region:Nr.region||null,metadata:e})},`Настройки кластера сохранены.`),children:`Сохранить настройки кластера`})]}),(0,S.jsxs)(`article`,{className:`card`,children:[(0,S.jsx)(`h3`,{children:`Authority и режим изменений`}),(0,S.jsx)(`p`,{className:`muted`,children:`Эта секция защищает кластер от split-brain: minority/read-only сегменты не должны принимать изменения политик.`}),(0,S.jsxs)(`div`,{className:`stateGrid`,children:[(0,S.jsx)(A,{label:`Authority`,value:we?.authority_state||`неизвестно`}),(0,S.jsx)(A,{label:`Mutation mode`,value:we?.mutation_mode||`неизвестно`}),(0,S.jsx)(A,{label:`Term`,value:String(we?.term??`н/д`)}),(0,S.jsx)(A,{label:`Cluster key`,value:B(Xi?.cluster_key_fingerprint)}),(0,S.jsx)(A,{label:`Последнее изменение`,value:V(we?.updated_at)})]}),(0,S.jsxs)(Je,{children:[(0,S.jsxs)(`label`,{children:[`Состояние authority`,(0,S.jsxs)(`select`,{value:Wr.authorityState,onChange:e=>Gr({...Wr,authorityState:e.target.value}),children:[(0,S.jsx)(`option`,{value:`authoritative`,children:`authoritative, основной`}),(0,S.jsx)(`option`,{value:`minority`,children:`minority, меньшинство`}),(0,S.jsx)(`option`,{value:`isolated`,children:`isolated, изолирован`}),(0,S.jsx)(`option`,{value:`recovery`,children:`recovery, восстановление`})]})]}),(0,S.jsxs)(`label`,{children:[`Режим изменений`,(0,S.jsxs)(`select`,{value:Wr.mutationMode,onChange:e=>Gr({...Wr,mutationMode:e.target.value}),children:[(0,S.jsx)(`option`,{value:`normal`,children:`normal, обычный`}),(0,S.jsx)(`option`,{value:`read_only`,children:`read_only, только чтение`}),(0,S.jsx)(`option`,{value:`recovery_override`,children:`recovery_override, восстановление`})]})]}),(0,S.jsxs)(`label`,{children:[`Примечание`,(0,S.jsx)(`input`,{value:Wr.notes,onChange:e=>Gr({...Wr,notes:e.target.value})})]})]}),(0,S.jsx)(`button`,{disabled:!T,onClick:()=>Fn(`Изменить authority state кластера`)&&void Y(()=>q.updateClusterAuthority(T,{authorityState:Wr.authorityState,mutationMode:Wr.mutationMode,notes:Wr.notes}),`Authority кластера обновлен.`),children:`Обновить authority`})]}),(0,S.jsxs)(`article`,{className:`card`,children:[(0,S.jsx)(`h3`,{children:`Safety / quorum`}),(0,S.jsxs)(`div`,{className:`stateGrid`,children:[(0,S.jsx)(A,{label:`Узлы`,value:String(Xi?.node_count??j.length)}),(0,S.jsx)(A,{label:`Healthy`,value:String(Xi?.healthy_node_count??Pa)}),(0,S.jsx)(A,{label:`Pending join`,value:String(Xi?.pending_join_count??je.filter(e=>e.status===`pending`).length)}),(0,S.jsx)(A,{label:`Последний узел`,value:V(Xi?.last_node_seen_at)})]}),(0,S.jsx)(`p`,{className:`muted`,children:`Минимальный размер, quorum policy и split-brain rules пока не имеют отдельного runtime-переключателя. Сейчас защита выполняется через authority/mutation mode, explicit node approval и аудит.`})]}),(0,S.jsxs)(`article`,{className:`card`,children:[(0,S.jsx)(`h3`,{children:`Telemetry / testing`}),(0,S.jsxs)(`div`,{className:`stateGrid`,children:[(0,S.jsx)(A,{label:`Telemetry flag`,value:La?.telemetry_enabled?`включен`:`выключен`}),(0,S.jsx)(A,{label:`Synthetic links`,value:La?.synthetic_links_enabled?`включены`:`выключены`}),(0,S.jsx)(A,{label:`Хранение истории, часов`,value:String(La?.history_retention_hours??`н/д`)})]}),(0,S.jsx)(`p`,{className:`muted`,children:`Это тестовый контур наблюдаемости: heartbeat/telemetry реальные, а связи Fabric сейчас synthetic. Production mesh traffic здесь пока не отображается.`})]}),(0,S.jsxs)(`article`,{className:`card`,children:[(0,S.jsx)(`h3`,{children:`Storage / updates`}),(0,S.jsxs)(`div`,{className:`stateGrid`,children:[(0,S.jsx)(A,{label:`Version Storage`,value:`архитектура зафиксирована, runtime не реализован`}),(0,S.jsx)(A,{label:`Update cache`,value:`${Ft(`update-cache`,We).length} узл.`}),(0,S.jsx)(A,{label:`File/config cache`,value:`${Ft(`file-storage-cache`,We).length} узл.`})]}),(0,S.jsx)(`p`,{className:`muted`,children:`Version Storage будет хранить stable/current/candidate и signed artifacts. Сейчас это не production updater runtime.`})]}),(0,S.jsxs)(`article`,{className:`card`,children:[(0,S.jsx)(`h3`,{children:`Admin endpoints`}),(0,S.jsxs)(`div`,{className:`stateGrid`,children:[(0,S.jsx)(A,{label:`Entry nodes`,value:`${Ft(`entry-node`,We).length} узл.`}),(0,S.jsx)(A,{label:`Relay nodes`,value:`${Ft(`relay-node`,We).length} узл.`}),(0,S.jsx)(A,{label:`Core mesh`,value:`${Ft(`core-mesh`,We).length} узл.`})]}),(0,S.jsx)(`p`,{className:`muted`,children:`Панель кластера не переезжает автоматически на storage-узел. Cluster Admin Endpoint должен быть назначен отдельной explicit ролью на ingress/admin-capable узле.`})]})]})]}),w===`nodes`&&(0,S.jsxs)(`section`,{className:`grid two`,children:[(0,S.jsxs)(`article`,{className:`card span2`,children:[(0,S.jsxs)(`div`,{className:`cardHead`,children:[(0,S.jsxs)(`div`,{children:[(0,S.jsx)(`h3`,{children:J.nodeManagement}),(0,S.jsx)(`p`,{className:`muted`,children:`Единый краткий список узлов. По умолчанию показан активный кластер; включите общий режим, чтобы увидеть весь инвентарь платформы.`})]}),(0,S.jsxs)(`div`,{className:`actions`,children:[(0,S.jsxs)(`label`,{className:`checkLine`,children:[(0,S.jsx)(`input`,{type:`checkbox`,checked:Jr===`all`,onChange:e=>Yr(e.target.checked?`all`:`cluster`)}),J.showAllPlatformNodes]}),(0,S.jsx)(`button`,{className:`ghost`,onClick:()=>{Yr(`all`),Zr(``)},children:J.showAllPlatformNodes})]})]}),(0,S.jsxs)(`div`,{className:`signalStrip compact`,children:[(0,S.jsx)(O,{label:`Узлы активного кластера`,value:String(j.length)}),(0,S.jsx)(O,{label:`Все узлы`,value:String(aa.length)}),(0,S.jsx)(O,{label:`Заявки`,value:String(Na)}),(0,S.jsx)(O,{label:`Активные роли`,value:String(Ia)})]}),(0,S.jsx)(`p`,{className:`muted`,children:J.addNodeText})]}),(0,S.jsxs)(`article`,{className:`card span2`,children:[(0,S.jsxs)(`div`,{className:`cardHead`,children:[(0,S.jsxs)(`div`,{children:[(0,S.jsx)(`h3`,{children:J.nodeBriefList}),(0,S.jsx)(`p`,{className:`muted`,children:J.nodeBriefListHelp})]}),(0,S.jsx)(`span`,{className:`pill`,children:oa.length})]}),(0,S.jsxs)(Je,{children:[(0,S.jsxs)(`label`,{children:[J.nodeSearch,(0,S.jsx)(`input`,{value:Xr,onChange:e=>Zr(e.target.value),placeholder:J.nodeSearchPlaceholder})]}),(0,S.jsxs)(`label`,{children:[J.nodeGroupFilter,(0,S.jsxs)(`select`,{value:Qr,onChange:e=>$r(e.target.value),children:[(0,S.jsx)(`option`,{value:``,children:J.allNodeGroups}),De.map(e=>(0,S.jsx)(`option`,{value:e.id,children:jt(e,De)},e.id))]})]})]}),(0,S.jsx)(`p`,{className:`muted`,children:J.nodeGroupInventoryText}),(0,S.jsx)(`h4`,{children:J.nodeGroupCreatePanel}),(0,S.jsxs)(Je,{children:[(0,S.jsxs)(`label`,{children:[J.nodeGroupName,(0,S.jsx)(`input`,{value:Fr.name,onChange:e=>Ir({...Fr,name:e.target.value})})]}),(0,S.jsxs)(`label`,{children:[J.parentNodeGroup,(0,S.jsxs)(`select`,{value:Fr.parentGroupId,onChange:e=>Ir({...Fr,parentGroupId:e.target.value}),children:[(0,S.jsx)(`option`,{value:``,children:J.rootNodeGroup}),De.map(e=>(0,S.jsx)(`option`,{value:e.id,children:jt(e,De)},e.id))]})]}),(0,S.jsxs)(`label`,{children:[J.createNodeGroup,(0,S.jsx)(`button`,{className:`primary`,disabled:!Fr.name.trim(),onClick:()=>void Y(async()=>{await q.createNodeGroup(T,{name:Fr.name,parentGroupId:Fr.parentGroupId||null}),Ir({name:``,parentGroupId:``})},J.nodeGroupCreated),children:J.createNodeGroup})]})]}),(0,S.jsxs)(`div`,{className:`nodeList`,children:[la.map(e=>{if(e.kind===`group`){let t=ei.includes(e.key);return(0,S.jsxs)(`div`,{className:`nodeListGroup`,style:{paddingLeft:`${e.depth*18}px`},children:[(0,S.jsxs)(`div`,{className:`nodeListMain`,children:[(0,S.jsx)(`strong`,{children:e.label}),e.groupId&&(0,S.jsx)(`span`,{children:Mt(e.groupId,De)})]}),(0,S.jsxs)(`div`,{className:`actions`,children:[(0,S.jsx)(`span`,{className:`pill`,children:e.count}),(0,S.jsx)(`button`,{className:`ghost`,onClick:()=>ti(gn(ei,e.key)),children:t?J.expandGroup:J.collapseGroup}),e.groupId&&(0,S.jsx)(`button`,{className:`ghost`,onClick:()=>Ir({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=wt(r,rt[r.id]||[],gt),a=tt(r,Be[r.id],Re),o=ft(He[r.id]||[]),s=n?.node.membership_status===`active`,c=n?.node.membership_status===`revoked`;return(0,S.jsxs)(`div`,{className:`nodeListRow`,style:{marginLeft:`${e.depth*18}px`},children:[(0,S.jsxs)(`div`,{className:`nodeListMain`,children:[(0,S.jsx)(`strong`,{children:r.name}),(0,S.jsx)(`span`,{children:r.node_key}),(0,S.jsx)(`small`,{className:`muted`,children:i.address})]}),(0,S.jsx)(k,{value:r.health_status}),(0,S.jsx)(ye,{runtime:i}),(0,S.jsxs)(`div`,{className:`nodeEndpointCell`,children:[(0,S.jsx)(`strong`,{children:r.reported_version||`версия неизвестна`}),(0,S.jsx)(`small`,{children:a.targetLabel})]}),(0,S.jsx)(k,{value:a.status}),(0,S.jsxs)(`div`,{className:`nodeEndpointCell`,children:[(0,S.jsx)(`strong`,{className:`pill ${o.tone}`,children:o.label}),(0,S.jsx)(`small`,{children:o.detail})]}),(0,S.jsx)(`span`,{className:`muted`,children:V(r.last_seen_at)}),n?(0,S.jsx)(k,{value:n.node.membership_status}):(0,S.jsx)(`span`,{className:`muted`,children:J.notMemberOfActiveCluster}),(0,S.jsxs)(`div`,{className:`actions`,children:[(0,S.jsx)(`button`,{onClick:()=>{li(t),di(`details`)},children:J.nodeDetails}),s?(0,S.jsxs)(S.Fragment,{children:[(0,S.jsx)(`button`,{className:`primary`,onClick:()=>{li(t),di(`manage`)},children:J.manageNode}),(0,S.jsx)(`button`,{className:`danger`,onClick:()=>Fn(`Удалить узел ${r.name} из кластера`)&&void Y(()=>q.deleteClusterNode(T,r.id,`Удалено из списка узлов панели владельца платформы.`),`Узел удален из кластера.`),children:`Удалить`})]}):c?(0,S.jsx)(`span`,{className:`muted`,children:J.revokedMembership}):(0,S.jsx)(`button`,{className:`primary`,onClick:()=>{ai(t),si([])},children:J.connectExistingNode})]})]},e.key)}),la.length===0&&(0,S.jsx)(me,{title:J.noNodesTitle,text:J.noNodesByFilter})]})]}),ii&&(0,S.jsx)(`div`,{className:`modalBackdrop`,role:`presentation`,children:(0,S.jsxs)(`div`,{className:`modalCard`,role:`dialog`,"aria-modal":`true`,"aria-labelledby":`attach-node-title`,children:[(0,S.jsxs)(`div`,{className:`cardHead`,children:[(0,S.jsxs)(`div`,{children:[(0,S.jsx)(`h3`,{id:`attach-node-title`,children:J.connectExistingNodeTitle}),(0,S.jsx)(`p`,{className:`muted`,children:J.connectExistingNodeText})]}),(0,S.jsx)(`button`,{className:`ghost`,onClick:()=>ai(null),children:J.cancel})]}),(0,S.jsxs)(`div`,{className:`stateList`,children:[(0,S.jsx)(A,{label:`Узел`,value:ii.node.name}),(0,S.jsx)(A,{label:`Node key`,value:ii.node.node_key}),(0,S.jsx)(A,{label:J.activeCluster,value:Yi?.name||T})]}),(0,S.jsx)(`div`,{className:`checkGrid`,children:ie.map(e=>(0,S.jsxs)(`label`,{className:`checkLine`,children:[(0,S.jsx)(`input`,{type:`checkbox`,checked:oi.includes(e),onChange:()=>si(gn(oi,e))}),$e(e)]},e))}),(0,S.jsxs)(`div`,{className:`actions`,children:[(0,S.jsx)(`button`,{className:`primary`,onClick:()=>void Y(async()=>{await q.attachExistingNode(T,ii.node.id,oi),ai(null),si([]),Yr(`cluster`)},`Узел подключен к активному кластеру.`),children:J.connectWithRoles}),(0,S.jsx)(`button`,{onClick:()=>ai(null),children:J.cancel})]})]})}),ci&&(()=>{let e=ci.memberships.find(e=>e.cluster.id===T),t=e?.node||ci.node,n=e?(rt[t.id]||[])[0]:void 0,r=e?(We[t.id]||[]).filter(e=>e.status===`active`):[],i=e&&Ke[t.id]||[],a=e&&Qe[t.id]||[];return(0,S.jsx)(`div`,{className:`modalBackdrop`,role:`presentation`,children:(0,S.jsxs)(`div`,{className:`modalCard wide`,role:`dialog`,"aria-modal":`true`,"aria-labelledby":`node-info-title`,children:[(0,S.jsxs)(`div`,{className:`cardHead`,children:[(0,S.jsxs)(`div`,{children:[(0,S.jsxs)(`h3`,{id:`node-info-title`,children:[ui===`manage`?J.manageNode:J.nodeDetails,`: `,t.name]}),(0,S.jsx)(`p`,{className:`muted`,children:t.node_key})]}),(0,S.jsx)(`button`,{className:`ghost`,onClick:()=>{li(null),di(`details`)},children:J.close})]}),(0,S.jsxs)(`section`,{className:`nodePanel`,children:[(0,S.jsx)(`h4`,{children:J.nodeIdentity}),(0,S.jsxs)(`div`,{className:`stateList`,children:[(0,S.jsx)(A,{label:`Node ID`,value:B(t.id)}),(0,S.jsx)(A,{label:`Ключ узла`,value:t.node_key}),(0,S.jsx)(A,{label:`Тип владения`,value:H(t.ownership_type)}),(0,S.jsx)(A,{label:`Owner org`,value:B(t.owner_organization_id)}),(0,S.jsx)(A,{label:`Регистрация`,value:H(t.registration_status)}),(0,S.jsx)(A,{label:`Здоровье`,value:H(t.health_status)}),(0,S.jsx)(A,{label:`Версия`,value:t.reported_version||`неизвестно`}),(0,S.jsx)(A,{label:`Последний сигнал`,value:V(t.last_seen_at)})]})]}),(0,S.jsxs)(`section`,{className:`nodePanel`,children:[(0,S.jsx)(`h4`,{children:J.clusterMemberships}),(0,S.jsx)(`div`,{className:`membershipList`,children:ci.memberships.map(e=>(0,S.jsxs)(`span`,{className:e.cluster.id===T?`pill good`:`pill`,children:[e.cluster.name,`: `,H(e.node.membership_status)]},e.cluster.id))})]}),e?(0,S.jsxs)(S.Fragment,{children:[(0,S.jsxs)(`section`,{className:`nodePanel`,children:[(0,S.jsx)(`h4`,{children:J.activeClusterScope}),(0,S.jsxs)(`div`,{className:`stateList`,children:[(0,S.jsx)(A,{label:`Участие`,value:H(t.membership_status)}),(0,S.jsx)(A,{label:`Сегмент`,value:H(t.partition_state)}),(0,S.jsx)(A,{label:`Группа`,value:t.node_group_name||J.ungroupedNodes}),(0,S.jsx)(A,{label:`Ролей`,value:String(r.length)}),(0,S.jsx)(A,{label:`Desired-сервисов`,value:String(i.length)}),(0,S.jsx)(A,{label:`Observed-сервисов`,value:String(a.length)})]})]}),ui===`details`&&(0,S.jsx)(_e,{node:t,memberships:ci.memberships,activeRoles:r,desiredWorkloads:i,observedWorkloads:a,heartbeats:rt[t.id]||[],telemetry:ot[t.id]||[],updatePlan:Be[t.id],updateStatuses:He[t.id]||[],meshLinks:gt.filter(e=>e.source_node_id===t.id||e.target_node_id===t.id),syntheticConfig:St[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}),ui===`manage`&&(0,S.jsxs)(`section`,{className:`nodePanel`,children:[(0,S.jsx)(`h4`,{children:J.nodeFunctions}),(0,S.jsx)(`p`,{className:`muted`,children:J.nodeFunctionsText}),(0,S.jsxs)(`label`,{className:`wideLabel`,children:[J.organizationScopeForEnable,(0,S.jsx)(`input`,{value:Kr,onChange:e=>qr(e.target.value),placeholder:J.clusterWideRolePlaceholder})]}),(0,S.jsx)(`div`,{className:`functionList`,children:ie.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=xn(e,n),u=s?.desired_state||`not_configured`,f=c?.reported_state||`missing`,p=!!o&&u===`enabled`;return(0,S.jsxs)(`div`,{className:`functionRow`,children:[(0,S.jsxs)(`div`,{className:`nodeListMain`,children:[(0,S.jsx)(`strong`,{children:$e(e)}),(0,S.jsx)(`span`,{children:Cn(e,n,d)})]}),(0,S.jsx)(pe,{label:J.rolePermission,value:o?J.permissionGranted:J.permissionDenied,tone:o?`info`:``}),(0,S.jsx)(pe,{label:J.desiredRuntime,value:H(u),tone:u===`enabled`?`good`:``}),(0,S.jsx)(pe,{label:J.observedRuntime,value:H(f),tone:f===`running`?`good`:f===`missing`?`warn`:``}),(0,S.jsx)(`span`,{className:`pill ${l}`,children:Sn(e,n,J)}),(0,S.jsxs)(`div`,{className:`actions`,children:[(0,S.jsx)(`button`,{className:p?``:`primary`,disabled:p,onClick:()=>void Y(async()=>{o||await q.setRoleStatus(T,t.id,e,`active`,Kr||void 0),await q.setDesiredWorkload(T,t.id,e,{desiredState:`enabled`,runtimeMode:`container`,config:{},environment:{}})},`${e}: функция включена.`),children:J.enableFunction}),(0,S.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=gi[t.id]||{listenAddr:String(e.listen_addr||`:19131`),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||``),advertiseTransport:String(e.advertise_transport||`direct_http`),connectivity:String(e.connectivity_mode||`private_lan`),nat:String(e.nat_type||`none`),region:String(e.region||``)},r=e=>_i({...gi,[t.id]:{...n,...e}});return(0,S.jsxs)(`section`,{className:`nodePanel nestedPanel`,children:[(0,S.jsx)(`h4`,{children:`Mesh listener`}),(0,S.jsxs)(Je,{children:[(0,S.jsxs)(`label`,{children:[`Listen addr`,(0,S.jsx)(`input`,{value:n.listenAddr,onChange:e=>r({listenAddr:e.target.value}),placeholder:`0.0.0.0:19131 или :19131`})]}),(0,S.jsxs)(`label`,{children:[`Port mode`,(0,S.jsxs)(`select`,{value:n.mode,onChange:e=>r({mode:e.target.value}),children:[(0,S.jsx)(`option`,{value:`auto`,children:`auto`}),(0,S.jsx)(`option`,{value:`manual`,children:`manual`}),(0,S.jsx)(`option`,{value:`disabled`,children:`disabled`})]})]}),(0,S.jsxs)(`label`,{children:[`Auto ports`,(0,S.jsx)(`input`,{value:n.autoRange,onChange:e=>r({autoRange:e.target.value}),placeholder:`19131-19231`})]}),(0,S.jsxs)(`label`,{children:[`Advertise endpoint`,(0,S.jsx)(`input`,{value:n.advertiseEndpoint,onChange:e=>r({advertiseEndpoint:e.target.value}),placeholder:`http://external-or-lan-ip:19131`})]}),(0,S.jsxs)(`label`,{children:[`Advertise transport`,(0,S.jsxs)(`select`,{value:n.advertiseTransport,onChange:e=>r({advertiseTransport:e.target.value}),children:[(0,S.jsx)(`option`,{value:`direct_http`,children:`direct_http`}),(0,S.jsx)(`option`,{value:`direct_https`,children:`direct_https`}),(0,S.jsx)(`option`,{value:`wss`,children:`wss`})]})]}),(0,S.jsxs)(`label`,{children:[`Connectivity`,(0,S.jsxs)(`select`,{value:n.connectivity,onChange:e=>r({connectivity:e.target.value}),children:[(0,S.jsx)(`option`,{value:`private_lan`,children:`private_lan`}),(0,S.jsx)(`option`,{value:`direct`,children:`direct`}),(0,S.jsx)(`option`,{value:`outbound_only`,children:`outbound_only`}),(0,S.jsx)(`option`,{value:`relay_required`,children:`relay_required`})]})]}),(0,S.jsxs)(`label`,{children:[`NAT`,(0,S.jsxs)(`select`,{value:n.nat,onChange:e=>r({nat:e.target.value}),children:[(0,S.jsx)(`option`,{value:`none`,children:`none`}),(0,S.jsx)(`option`,{value:`unknown`,children:`unknown`}),(0,S.jsx)(`option`,{value:`port_restricted`,children:`port_restricted`}),(0,S.jsx)(`option`,{value:`symmetric`,children:`symmetric`})]})]}),(0,S.jsxs)(`label`,{children:[`Region/site`,(0,S.jsx)(`input`,{value:n.region,onChange:e=>r({region:e.target.value}),placeholder:`dc1, office, docker-test`})]})]}),(0,S.jsx)(`div`,{className:`actions`,children:(0,S.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;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:n.advertiseEndpoint.trim().replace(/\/$/,``)||null,advertise_transport:n.advertiseTransport||`direct_http`,connectivity_mode:n.connectivity,nat_type:n.nat,region:n.region||null},environment:{}})},`Mesh listener config обновлен.`),children:`Применить listener`})})]})})(),(0,S.jsx)(`div`,{className:`actions`,children:(0,S.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,S.jsx)(`option`,{value:``,children:J.ungroupedNodes}),De.map(e=>(0,S.jsx)(`option`,{value:e.id,children:jt(e,De)},e.id))]})}),(0,S.jsxs)(`div`,{className:`actions`,children:[(0,S.jsx)(`button`,{onClick:()=>Fn(`Отключить участие узла ${t.name}`)&&void Y(()=>q.disableMembership(T,t.id,`Отключено из панели владельца платформы.`),`Участие узла отключено.`),children:`Отключить участие`}),(0,S.jsx)(`button`,{className:`danger`,onClick:()=>Fn(`Отозвать identity узла ${t.name}`)&&void Y(()=>q.revokeNodeIdentity(T,t.id,`Отозвано из панели владельца платформы.`),`Identity узла отозван.`),children:`Отозвать identity`})]})]})]}):(0,S.jsxs)(`section`,{className:`nodePanel`,children:[(0,S.jsx)(`h4`,{children:J.noActiveClusterMembership}),(0,S.jsx)(`div`,{className:`actions`,children:(0,S.jsx)(`button`,{className:`primary`,onClick:()=>{ai(ci),si([]),li(null)},children:J.connectExistingNode})})]})]})})})(),!1]}),w===`enrollment`&&(0,S.jsxs)(`section`,{className:`grid two`,children:[(0,S.jsxs)(`article`,{className:`card`,children:[(0,S.jsx)(`h3`,{children:J.joinTokenTitle}),(0,S.jsx)(`p`,{className:`muted`,children:J.joinTokenText}),(0,S.jsxs)(Je,{children:[(0,S.jsxs)(`label`,{children:[J.ttlHours,(0,S.jsx)(`input`,{type:`number`,min:1,max:720,value:U.ttlHours,onChange:e=>Vr({...U,ttlHours:Number(e.target.value)})}),(0,S.jsx)(`small`,{children:J.ttlHelp})]}),(0,S.jsxs)(`label`,{children:[J.maxUses,(0,S.jsx)(`input`,{type:`number`,min:1,max:100,value:U.maxUses,onChange:e=>Vr({...U,maxUses:Number(e.target.value)})}),(0,S.jsx)(`small`,{children:J.maxUsesHelp})]}),(0,S.jsxs)(`label`,{children:[J.nodeOwnership,(0,S.jsxs)(`select`,{value:U.ownershipType,onChange:e=>Vr({...U,ownershipType:e.target.value}),children:[(0,S.jsx)(`option`,{value:`platform_managed`,children:`platform_managed, управляется платформой`}),(0,S.jsx)(`option`,{value:`customer_managed`,children:`customer_managed, управляется клиентом`})]})]}),(0,S.jsxs)(`label`,{children:[J.tokenPurpose,(0,S.jsx)(`input`,{value:U.purpose,onChange:e=>Vr({...U,purpose:e.target.value}),placeholder:`например: стартовый entry-node в ru-msk-1`})]}),(0,S.jsxs)(`label`,{children:[`Имя нового узла`,(0,S.jsx)(`input`,{value:U.nodeName,onChange:e=>Vr({...U,nodeName:e.target.value}),placeholder:Gt(U,Yi)}),(0,S.jsx)(`small`,{children:`Если оставить пустым, панель подставит имя автоматически.`})]}),(0,S.jsxs)(`label`,{children:[`Группа узла`,(0,S.jsxs)(`select`,{value:U.nodeGroupId,onChange:e=>Vr({...U,nodeGroupId:e.target.value}),children:[(0,S.jsx)(`option`,{value:``,children:`Без группы`}),De.map(e=>(0,S.jsx)(`option`,{value:e.id,children:jt(e,De)},e.id))]})]})]}),(0,S.jsxs)(`section`,{className:`nodePanel`,children:[(0,S.jsx)(`h4`,{children:`Install profile`}),(0,S.jsx)(`p`,{className:`muted`,children:`Эти поля попадут в install profile. Для Windows без админ-прав будет создан user startup task, с админ-правами - system startup task.`}),(0,S.jsx)(`div`,{className:`segmented`,children:[[`docker`,`Docker Linux`],[`linux_binary`,`Ubuntu service`],[`windows_service`,`Windows`]].map(([e,t])=>(0,S.jsx)(`button`,{type:`button`,className:U.installMode===e?`active`:``,onClick:()=>Vr({...U,installMode:e}),children:t},e))}),(0,S.jsx)(`div`,{className:`segmented`,children:[[`private_lan`,`LAN`],[`direct`,`Public`],[`nat_forward`,`NAT`],[`outbound_only`,`Outbound`]].map(([e,t])=>(0,S.jsx)(`button`,{type:`button`,className:Ut(U)===e?`active`:``,onClick:()=>Vr(Wt(U,e)),children:t},e))}),(0,S.jsxs)(Je,{children:[(0,S.jsxs)(`label`,{children:[`Control-plane endpoint`,(0,S.jsx)(`input`,{value:U.controlPlaneEndpoint,onChange:e=>Vr({...U,controlPlaneEndpoint:e.target.value}),placeholder:Bt()})]}),(0,S.jsxs)(`label`,{children:[U.installMode===`windows_service`?`Windows node-agent artifact`:U.installMode===`linux_binary`?`Linux node-agent artifact`:`Docker image`,(0,S.jsx)(`input`,{value:U.dockerImage,onChange:e=>Vr({...U,dockerImage:e.target.value})})]}),U.installMode===`windows_service`&&(0,S.jsxs)(S.Fragment,{children:[(0,S.jsxs)(`label`,{children:[`Windows startup`,(0,S.jsxs)(`select`,{value:U.windowsStartupMode,onChange:e=>Vr({...U,windowsStartupMode:e.target.value}),children:[(0,S.jsx)(`option`,{value:`auto`,children:`auto: system task, fallback user task`}),(0,S.jsx)(`option`,{value:`system-task`,children:`system task, admin required`}),(0,S.jsx)(`option`,{value:`user-task`,children:`user task, no admin`}),(0,S.jsx)(`option`,{value:`none`,children:`none`})]})]}),(0,S.jsxs)(`label`,{children:[`Install dir`,(0,S.jsx)(`input`,{value:U.windowsInstallDir,onChange:e=>Vr({...U,windowsInstallDir:e.target.value}),placeholder:`C:\\\\Program Files\\\\RAP\\\\node-name`})]}),(0,S.jsxs)(`label`,{children:[`Windows node-agent SHA256`,(0,S.jsx)(`input`,{value:U.windowsNodeAgentSHA256,onChange:e=>Vr({...U,windowsNodeAgentSHA256:e.target.value}),placeholder:`опционально, но желательно для production`})]})]}),U.installMode===`linux_binary`&&(0,S.jsxs)(S.Fragment,{children:[(0,S.jsxs)(`label`,{children:[`Linux install dir`,(0,S.jsx)(`input`,{value:U.linuxInstallDir,onChange:e=>Vr({...U,linuxInstallDir:e.target.value}),placeholder:`/opt/rap/node-name`})]}),(0,S.jsxs)(`label`,{children:[`Linux node-agent SHA256`,(0,S.jsx)(`input`,{value:U.linuxNodeAgentSHA256,onChange:e=>Vr({...U,linuxNodeAgentSHA256:e.target.value}),placeholder:`опционально, но желательно для production`})]})]}),U.installMode===`docker`&&(0,S.jsxs)(`label`,{children:[`Container name`,(0,S.jsx)(`input`,{value:U.dockerContainerName,onChange:e=>Vr({...U,dockerContainerName:e.target.value}),placeholder:Kt(U,Yi)})]}),(0,S.jsxs)(`label`,{children:[`Artifact endpoints`,(0,S.jsx)(`input`,{value:U.artifactEndpoints,onChange:e=>Vr({...U,artifactEndpoints:e.target.value}),placeholder:Vt()}),(0,S.jsx)(`small`,{children:`Через запятую: public/LAN/cache узлы, где host-agent сможет скачать image tar до входа в mesh.`})]}),U.installMode===`docker`&&(0,S.jsxs)(`label`,{children:[`Docker image tar SHA256`,(0,S.jsx)(`input`,{value:U.dockerImageArtifactSHA256,onChange:e=>Vr({...U,dockerImageArtifactSHA256:e.target.value}),placeholder:`опционально, но желательно для production`})]}),U.installMode===`docker`&&(0,S.jsxs)(`label`,{children:[`Docker network`,(0,S.jsxs)(`select`,{value:U.dockerNetwork,onChange:e=>Vr({...U,dockerNetwork:e.target.value}),children:[(0,S.jsx)(`option`,{value:`host`,children:`host`}),(0,S.jsx)(`option`,{value:`bridge`,children:`bridge`})]})]}),(0,S.jsxs)(`label`,{children:[`Listen addr`,(0,S.jsx)(`input`,{value:U.meshListenAddr,onChange:e=>Vr({...U,meshListenAddr:e.target.value})})]}),(0,S.jsxs)(`label`,{children:[`Listen mode`,(0,S.jsxs)(`select`,{value:U.meshListenPortMode,onChange:e=>Vr({...U,meshListenPortMode:e.target.value}),children:[(0,S.jsx)(`option`,{value:`auto`,children:`auto`}),(0,S.jsx)(`option`,{value:`manual`,children:`manual`}),(0,S.jsx)(`option`,{value:`disabled`,children:`disabled`})]})]}),(0,S.jsxs)(`label`,{children:[`Auto ports`,(0,S.jsx)(`input`,{value:`${U.meshListenAutoPortStart}-${U.meshListenAutoPortEnd}`,onChange:e=>{let[t,n]=e.target.value.split(`-`).map(e=>Number(e.trim()));Vr({...U,meshListenAutoPortStart:Number.isFinite(t)?t:U.meshListenAutoPortStart,meshListenAutoPortEnd:Number.isFinite(n)?n:U.meshListenAutoPortEnd})}})]}),(0,S.jsxs)(`label`,{children:[`Advertise endpoint`,(0,S.jsx)(`input`,{value:U.meshAdvertiseEndpoint,onChange:e=>Vr({...U,meshAdvertiseEndpoint:e.target.value}),placeholder:`http://public-or-private-ip:19131`})]}),(0,S.jsxs)(`label`,{children:[`Connectivity`,(0,S.jsxs)(`select`,{value:U.meshConnectivityMode,onChange:e=>Vr({...U,meshConnectivityMode:e.target.value}),children:[(0,S.jsx)(`option`,{value:`direct`,children:`direct`}),(0,S.jsx)(`option`,{value:`private_lan`,children:`private_lan`}),(0,S.jsx)(`option`,{value:`outbound_only`,children:`outbound_only`}),(0,S.jsx)(`option`,{value:`relay_required`,children:`relay_required`})]})]}),(0,S.jsxs)(`label`,{children:[`NAT`,(0,S.jsxs)(`select`,{value:U.meshNATType,onChange:e=>Vr({...U,meshNATType:e.target.value}),children:[(0,S.jsx)(`option`,{value:`none`,children:`none`}),(0,S.jsx)(`option`,{value:`unknown`,children:`unknown`}),(0,S.jsx)(`option`,{value:`full_cone`,children:`full_cone`}),(0,S.jsx)(`option`,{value:`port_restricted`,children:`port_restricted`}),(0,S.jsx)(`option`,{value:`symmetric`,children:`symmetric`})]})]}),(0,S.jsxs)(`label`,{children:[`Region/site`,(0,S.jsx)(`input`,{value:U.meshRegion,onChange:e=>Vr({...U,meshRegion:e.target.value})})]}),U.installMode===`docker`&&(0,S.jsxs)(`label`,{className:`checkLine`,children:[(0,S.jsx)(`input`,{type:`checkbox`,checked:U.pullImage,onChange:e=>Vr({...U,pullImage:e.target.checked})}),`Pull image`]}),(0,S.jsxs)(`label`,{className:`checkLine`,children:[(0,S.jsx)(`input`,{type:`checkbox`,checked:U.replace,onChange:e=>Vr({...U,replace:e.target.checked})}),`Replace existing install`]})]})]}),(0,S.jsxs)(`section`,{className:`nodePanel`,children:[(0,S.jsx)(`h4`,{children:J.suggestedRoles}),(0,S.jsx)(`p`,{className:`muted`,children:`Роли записываются в install token и автоматически назначаются узлу при approval. После создания token изменение чекбоксов не меняет уже выданный token.`}),(0,S.jsx)(`div`,{className:`checkGrid`,children:ie.map(e=>(0,S.jsxs)(`label`,{className:`checkLine`,children:[(0,S.jsx)(`input`,{type:`checkbox`,checked:U.roles.includes(e),onChange:()=>Vr({...U,roles:gn(U.roles,e)})}),$e(e)]},e))})]}),(0,S.jsxs)(`details`,{children:[(0,S.jsx)(`summary`,{children:J.generatedScope}),(0,S.jsx)(`p`,{className:`muted`,children:J.generatedScopeHelp}),(0,S.jsx)(`pre`,{className:`codePreview`,children:JSON.stringify(ra,null,2)})]}),(0,S.jsxs)(`p`,{className:`muted`,children:[J.manualApprovalRequired,`.`]}),(0,S.jsx)(`button`,{className:`primary`,disabled:!T,onClick:()=>void Y(async()=>{Ur(await q.createJoinToken(T,{ttlHours:U.ttlHours,maxUses:U.maxUses,scope:ra}))},`Join token создан.`),children:`Создать install token`}),Hr&&(0,S.jsxs)(`div`,{className:`secretOnce`,children:[(0,S.jsx)(`strong`,{children:`Исходный token, возвращается один раз`}),(0,S.jsx)(`code`,{children:Hr.token}),(0,S.jsxs)(`span`,{className:`muted`,children:[`Authority key: `,B(Hr.authority_signature?.key_fingerprint)]}),(0,S.jsx)(`strong`,{children:`Scope выданного token`}),(0,S.jsx)(`pre`,{className:`codePreview`,children:JSON.stringify(Hr.scope,null,2)}),(0,S.jsx)(`strong`,{children:`Docker host-agent install`}),(0,S.jsx)(`pre`,{className:`codePreview`,children:qt(Hr,Yi,ia)}),(0,S.jsx)(`strong`,{children:`Profile-based Docker install`}),(0,S.jsx)(`pre`,{className:`codePreview`,children:Jt(Hr,Yi,ia)}),(0,S.jsx)(`strong`,{children:`Profile-based Ubuntu service install`}),(0,S.jsx)(`pre`,{className:`codePreview`,children:Yt(Hr,Yi,ia)}),(0,S.jsx)(`strong`,{children:`Profile-based Windows PowerShell install`}),(0,S.jsx)(`pre`,{className:`codePreview`,children:Xt(Hr,Yi,ia)}),(0,S.jsx)(`strong`,{children:`Profile-based Windows CMD install`}),(0,S.jsx)(`pre`,{className:`codePreview`,children:Zt(Hr,Yi,ia)})]})]}),(0,S.jsxs)(`article`,{className:`card`,children:[(0,S.jsx)(`h3`,{children:`Как добавить узел`}),(0,S.jsxs)(`div`,{className:`stateList`,children:[(0,S.jsxs)(`div`,{className:`stateLine`,children:[(0,S.jsx)(`span`,{children:`1`}),(0,S.jsx)(`strong`,{children:`Заполните Docker install profile слева.`})]}),(0,S.jsxs)(`div`,{className:`stateLine`,children:[(0,S.jsx)(`span`,{children:`2`}),(0,S.jsx)(`strong`,{children:`Нажмите “Создать install token”.`})]}),(0,S.jsxs)(`div`,{className:`stateLine`,children:[(0,S.jsx)(`span`,{children:`3`}),(0,S.jsx)(`strong`,{children:`Скопируйте “Profile-based Docker install” и выполните на Docker-хосте.`})]}),(0,S.jsxs)(`div`,{className:`stateLine`,children:[(0,S.jsx)(`span`,{children:`4`}),(0,S.jsx)(`strong`,{children:`Подтвердите join request в этой же вкладке.`})]})]})]}),(0,S.jsxs)(`article`,{className:`card`,children:[(0,S.jsx)(`h3`,{children:`Install tokens`}),(0,S.jsx)(M,{columns:[`scope`,`status`,`uses`,`expires`,`created`,`action`],rows:Ne.map(e=>[mt(e),H(e.status),`${e.used_count}/${e.max_uses}`,V(e.expires_at),V(e.created_at),e.status===`active`?(0,S.jsx)(`button`,{className:`danger`,onClick:()=>Fn(`Отозвать install token ${B(e.id)}`)&&void Y(()=>q.revokeJoinToken(T,e.id),`Install token отозван.`),children:`Отозвать`}):(0,S.jsx)(`span`,{className:`muted`,children:H(e.status)})])})]}),(0,S.jsxs)(`article`,{className:`card`,children:[(0,S.jsx)(`h3`,{children:`Заявки на подключение`}),(0,S.jsxs)(`div`,{className:`stack`,children:[je.map(e=>(0,S.jsxs)(`div`,{className:`requestCard`,children:[(0,S.jsxs)(`div`,{children:[(0,S.jsx)(`strong`,{children:e.node_name}),(0,S.jsx)(`p`,{children:e.node_fingerprint}),(0,S.jsx)(k,{value:e.status}),e.approval_signature?.key_fingerprint&&(0,S.jsxs)(`small`,{className:`muted`,children:[`approval key `,B(e.approval_signature.key_fingerprint)]})]}),(0,S.jsxs)(`div`,{className:`actions`,children:[(0,S.jsx)(`button`,{disabled:e.status!==`pending`,onClick:()=>void Y(()=>q.approveJoinRequest(T,e.id),`Заявка одобрена.`),children:`Одобрить`}),(0,S.jsx)(`button`,{disabled:e.status!==`pending`,onClick:()=>void Y(()=>q.rejectJoinRequest(T,e.id,`Отклонено из панели владельца платформы.`),`Заявка отклонена.`),children:`Отклонить`})]})]},e.id)),je.length===0&&(0,S.jsx)(me,{title:`Нет заявок`,text:`Новые подключения node-agent появятся здесь.`})]})]})]}),w===`roles`&&(0,S.jsxs)(`section`,{className:`stack`,children:[(0,S.jsxs)(`article`,{className:`card`,children:[(0,S.jsx)(`h3`,{children:`Область ролей`}),(0,S.jsx)(`p`,{className:`muted`,children:`Capabilities — технические факты. Роли — явные разрешения. Область организации может ограничивать сервисные роли.`}),(0,S.jsxs)(`label`,{children:[`UUID организации для новых назначений ролей, опционально`,(0,S.jsx)(`input`,{value:Kr,onChange:e=>qr(e.target.value),placeholder:`пусто = роль на весь кластер`})]})]}),j.map(e=>(0,S.jsxs)(`article`,{className:`card roleRow`,children:[(0,S.jsxs)(`div`,{children:[(0,S.jsx)(`h3`,{children:e.name}),(0,S.jsx)(`p`,{children:Ze(We[e.id]||[])})]}),(0,S.jsxs)(`select`,{defaultValue:``,onChange:t=>{let n=t.target.value;t.currentTarget.value=``,n&&Y(()=>q.assignRole(T,e.id,n,Kr||void 0),`${n} назначена узлу ${e.name}.`)},children:[(0,S.jsx)(`option`,{value:``,children:`Назначить роль...`}),ie.map(e=>(0,S.jsx)(`option`,{value:e,children:$e(e)},e))]})]},e.id))]}),w===`workloads`&&(0,S.jsxs)(`section`,{className:`grid two`,children:[(0,S.jsxs)(`article`,{className:`card`,children:[(0,S.jsx)(`h3`,{children:`Желаемое состояние сервиса`}),(0,S.jsx)(`p`,{className:`muted`,children:`Здесь задается только желаемое состояние. Runtime-исполнение остается под контролем node-agent и политик.`}),(0,S.jsxs)(Je,{children:[(0,S.jsxs)(`label`,{children:[`Узел`,(0,S.jsxs)(`select`,{value:wi.nodeId,onChange:e=>Ti({...wi,nodeId:e.target.value}),children:[(0,S.jsx)(`option`,{value:``,children:`Выберите узел...`}),j.map(e=>(0,S.jsx)(`option`,{value:e.id,children:e.name},e.id))]})]}),(0,S.jsxs)(`label`,{children:[`Сервис`,(0,S.jsx)(`select`,{value:wi.serviceType,onChange:e=>Ti({...wi,serviceType:e.target.value}),children:ie.map(e=>(0,S.jsx)(`option`,{value:e,children:$e(e)},e))})]}),(0,S.jsxs)(`label`,{children:[`Желаемое состояние`,(0,S.jsxs)(`select`,{value:wi.desiredState,onChange:e=>Ti({...wi,desiredState:e.target.value}),children:[(0,S.jsx)(`option`,{value:`enabled`,children:`включено`}),(0,S.jsx)(`option`,{value:`disabled`,children:`выключено`})]})]}),(0,S.jsxs)(`label`,{children:[`Режим runtime`,(0,S.jsxs)(`select`,{value:wi.runtimeMode,onChange:e=>Ti({...wi,runtimeMode:e.target.value}),children:[(0,S.jsx)(`option`,{value:`container`,children:`контейнер`}),(0,S.jsx)(`option`,{value:`native`,children:`нативно`})]})]}),(0,S.jsxs)(`label`,{children:[`Версия`,(0,S.jsx)(`input`,{value:wi.version,onChange:e=>Ti({...wi,version:e.target.value})})]})]}),(0,S.jsxs)(`label`,{children:[`Config JSON`,(0,S.jsx)(`textarea`,{value:wi.configJson,onChange:e=>Ti({...wi,configJson:e.target.value})})]}),(0,S.jsxs)(`label`,{children:[`Environment JSON`,(0,S.jsx)(`textarea`,{value:wi.environmentJson,onChange:e=>Ti({...wi,environmentJson:e.target.value})})]}),(0,S.jsx)(`button`,{className:`primary`,disabled:!wi.nodeId||!T,onClick:()=>void Y(()=>q.setDesiredWorkload(T,wi.nodeId,wi.serviceType,{desiredState:wi.desiredState,runtimeMode:wi.runtimeMode,version:wi.version,config:Ye(wi.configJson,`config сервиса`),environment:Ye(wi.environmentJson,`environment сервиса`)}),`Желаемое состояние сервиса обновлено.`),children:`Задать желаемое состояние`})]}),(0,S.jsxs)(`article`,{className:`card`,children:[(0,S.jsx)(`h3`,{children:`Отчеты сервисов`}),(0,S.jsx)(`div`,{className:`stack`,children:j.map(e=>(0,S.jsxs)(`div`,{className:`workloadBlock`,children:[(0,S.jsx)(`strong`,{children:e.name}),(Qe[e.id]||[]).length===0?(0,S.jsx)(`p`,{className:`muted`,children:`Статус пока не получен.`}):(0,S.jsx)(M,{columns:[`сервис`,`состояние`,`runtime`,`наблюдение`],rows:(Qe[e.id]||[]).map(e=>[e.service_type,e.reported_state,e.runtime_mode,V(e.observed_at)])})]},e.id))})]})]}),w===`fabric`&&(0,S.jsxs)(`section`,{className:`fabricTransportView`,children:[(0,S.jsxs)(`article`,{className:`card fabricMapCard`,children:[(0,S.jsxs)(`div`,{className:`cardHead`,children:[(0,S.jsxs)(`div`,{children:[(0,S.jsx)(`h3`,{children:`Транспортный слой Fabric`}),(0,S.jsx)(`p`,{className:`muted`,children:`Карта показывает реальные свежие QUIC-соседства и проверенные relay/route-health маршруты. Прямые связи рисуются сплошной линией, relay и route-health отделены пунктиром, чтобы не смешивать физического соседа и достижимый маршрут.`})]}),(0,S.jsxs)(`div`,{className:`summaryChips`,children:[(0,S.jsxs)(`span`,{className:`pill good`,children:[`direct `,gt.length]}),(0,S.jsx)(`span`,{className:`pill`,children:Wa.label}),(0,S.jsx)(k,{value:La?.synthetic_links_enabled?`enabled`:`disabled`})]})]}),(0,S.jsx)(xe,{nodes:j,links:gt,heartbeatsByNode:rt,rolesByNode:We,workloadsByNode:Qe,labels:J,emptyText:J.noLinks}),(0,S.jsxs)(`details`,{className:`sectionBlock fabricDiagnostics`,children:[(0,S.jsx)(`summary`,{children:`Диагностика transport/runtime receivers`}),(0,S.jsxs)(`div`,{className:`signalStrip compact`,children:[(0,S.jsx)(O,{label:`Synthetic configs`,value:`${za}/${j.length}`}),(0,S.jsx)(O,{label:`Routes`,value:String(Ba)}),(0,S.jsx)(O,{label:`Endpoints / candidates`,value:`${Va}/${Ha}`}),(0,S.jsx)(O,{label:`Scoped production`,value:Ua===0?`false`:`true:${Ua}`})]}),(0,S.jsx)(M,{columns:[`узел`,`status`,`reason`,`trusted keys`,`service classes`,`QUIC addr`,`ошибка`],rows:j.map(e=>{let t=N(rt[e.id]?.[0]?.metadata?.web_ingress_runtime_receiver_report),n=Fe(rt[e.id]?.[0]),r=t?Rt(t.service_classes):[],i=Le(We[e.id]||[]),a=i.length>0&&!i.every(e=>r.includes(e));return[e.name,(0,S.jsx)(`span`,{className:`pill ${n===`ready`?`good`:n===`degraded`?`warn`:n===`blocked`?`bad`:``}`,children:n}),t?P(t,`reason`,`н/д`):`no report`,t?String(Tt(t,`trusted_key_count`)):`0`,(0,S.jsx)(`span`,{className:a?`pill warn`:``,children:t&&r.join(`, `)||`н/д`}),t?P(t,`quic_fabric_listen_addr`,`н/д`):`н/д`,a?`expected: ${i.join(`, `)}`:t&&(P(t,`quic_fabric_error`,``)||P(t,`error`,``))||`—`]})})]})]}),(0,S.jsxs)(`article`,{className:`card span2`,children:[(0,S.jsxs)(`div`,{className:`cardHead`,children:[(0,S.jsxs)(`div`,{children:[(0,S.jsx)(`h3`,{children:`Synthetic mesh config`}),(0,S.jsx)(`p`,{className:`muted`,children:`Node-scoped config from Control Plane. Endpoint candidates and scoring inputs are visible to the platform owner only; production forwarding for service traffic must remain disabled here.`})]}),(0,S.jsxs)(`span`,{className:Ua===0?`pill good`:`pill bad`,children:[`production_forwarding=`,Ua===0?`false`:`true`]})]}),(0,S.jsx)(M,{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=St[e.id];return[e.name,t?t.enabled?`enabled`:`disabled`:`не загружен`,String(t?.routes.length??0),String(Object.keys(t?.peer_endpoints||{}).length),String(t?Ot(t):0),String(t?.peer_directory?.length??0),String(t?.recovery_seeds?.length??0),String(t?.rendezvous_leases?.length??0),kt(t),At(t),t?.authority_required?B(t.authority_signature?.key_fingerprint):`не требуется`,t?.production_forwarding?`true`:`false`]})}),(0,S.jsx)(`p`,{className:`muted`,children:`Health-aware scoring не выбирает service route и не открывает service-соединения. C17Z19 показывает control-plane route/path decisions, route generation status, synthetic route-health effective path и relay feedback scoring, но не переносит RDP/VPN/file/video/service payload.`})]}),(0,S.jsxs)(`article`,{className:`card span2`,children:[(0,S.jsxs)(`div`,{className:`cardHead`,children:[(0,S.jsxs)(`div`,{children:[(0,S.jsx)(`h3`,{children:`Route intents lifecycle`}),(0,S.jsx)(`p`,{className:`muted`,children:`Operator view for temporary fabric routes. Expired and disabled intents are not emitted into node-scoped synthetic config.`})]}),(0,S.jsxs)(`div`,{className:`summaryChips`,children:[(0,S.jsxs)(`span`,{className:`pill good`,children:[`active `,Ga.length]}),(0,S.jsxs)(`span`,{className:Ka.length>0?`pill warn`:`pill`,children:[`expired `,Ka.length]}),(0,S.jsxs)(`span`,{className:`pill`,children:[`disabled `,qa.length]})]})]}),(0,S.jsx)(M,{columns:[`route`,`life`,`service`,`priority`,`source`,`destination`,`expires`,`updated`,`actions`],rows:bt.slice(0,120).map(e=>{let t=lt(e);return[B(e.id),(0,S.jsx)(`span`,{className:`pill ${ut(e)}`,children:t}),e.service_class,String(e.priority),dt(e.source_selector||{}),dt(e.destination_selector||{}),e.policy_expires_at?V(e.policy_expires_at):`нет`,V(e.updated_at),(0,S.jsxs)(`div`,{className:`inlineActions`,children:[t===`active`?(0,S.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,S.jsx)(`span`,{className:`muted`,children:`expire`}),t===`disabled`?(0,S.jsx)(`span`,{className:`muted`,children:`disable`}):(0,S.jsx)(`button`,{type:`button`,className:`ghost`,onClick:()=>void Y(()=>q.disableRouteIntent(T,e.id,`operator disabled route intent`),`Route intent disabled.`),children:`disable`})]})]})}),bt.length===0&&(0,S.jsx)(me,{title:`Route intents отсутствуют`,text:`Нет настроенных fabric route intents для текущего кластера.`})]}),(0,S.jsxs)(`article`,{className:`card span2`,children:[(0,S.jsxs)(`div`,{className:`cardHead`,children:[(0,S.jsxs)(`div`,{children:[(0,S.jsx)(`h3`,{children:`Service-channel route feedback`}),(0,S.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,S.jsxs)(`div`,{className:`summaryChips`,children:[(0,S.jsxs)(`span`,{className:Ya.length>0?`pill bad`:`pill good`,children:[`fenced `,Ya.length]}),(0,S.jsxs)(`span`,{className:Xa.length>0?`pill warn`:`pill`,children:[`degraded `,Xa.length]}),(0,S.jsxs)(`span`,{className:to.length>0?`pill warn`:`pill`,children:[`retry `,to.length]}),(0,S.jsxs)(`span`,{className:Qa.length>0?`pill warn`:`pill`,children:[`recovered `,Qa.length]}),(0,S.jsxs)(`span`,{className:$a.length>0?`pill good`:`pill`,children:[`promoted `,$a.length]}),(0,S.jsxs)(`span`,{className:eo.length>0?`pill bad`:`pill`,children:[`demoted `,eo.length]}),(0,S.jsxs)(`span`,{className:`pill good`,children:[`healthy `,Za.length]}),(0,S.jsxs)(`span`,{className:X.length>0?`pill bad`:`pill`,children:[`no alternate `,X.length]}),(0,S.jsxs)(`span`,{className:lo.length>0?`pill warn`:`pill`,children:[`hysteresis `,lo.length]}),(0,S.jsxs)(`span`,{className:uo.length>0?`pill good`:`pill`,children:[`promoted paths `,uo.length]}),(0,S.jsxs)(`span`,{className:fo.length>0?`pill bad`:`pill`,children:[`demoted paths `,fo.length]}),(0,S.jsxs)(`span`,{className:(bn?.fingerprint||``).length>0?`pill good`:`pill warn`,children:[`policy fp `,bn?.fingerprint?B(bn.fingerprint):`нет`]}),(0,S.jsxs)(`span`,{className:io.length>ao.length?`pill warn`:`pill good`,children:[`rebuild `,ao.length,`/`,io.length]}),(0,S.jsxs)(`span`,{className:so.length>0?`pill warn`:`pill good`,children:[`ledger `,oo.length,`/`,zt.length]}),(0,S.jsxs)(`span`,{className:co.length>0?`pill bad`:`pill good`,children:[`guard `,co.length]}),(0,S.jsx)(`span`,{className:mn?`pill info`:`pill`,children:mn?`deep ledger`:`fast ledger`})]})]}),X.length>0&&(0,S.jsx)(`div`,{className:`noticePanel`,children:`Есть service-channel route без unfenced alternate. Для production-сервиса это означает деградацию: fabric не нашел безопасную замену и будет ждать нового маршрута или операторского решения.`}),rn&&(0,S.jsxs)(`div`,{className:`noticePanel ${rn.status===`blocked`?`badPanel`:`goodPanel`}`,children:[(0,S.jsxs)(`div`,{className:`cardHead compact`,children:[(0,S.jsxs)(`div`,{children:[(0,S.jsx)(`h4`,{children:`Fabric schema preflight`}),(0,S.jsx)(`p`,{className:`muted`,children:`Backend/runtime compatibility check for manual deploys before diagnostics or service channels depend on new DB fields.`})]}),(0,S.jsxs)(`div`,{className:`summaryChips`,children:[(0,S.jsx)(`span`,{className:`pill ${rn.status===`blocked`?`bad`:`good`}`,children:H(rn.status)}),(0,S.jsxs)(`span`,{className:rn.missing_check_count>0?`pill bad`:`pill good`,children:[rn.passed_check_count,`/`,rn.required_check_count]}),(0,S.jsx)(`button`,{className:`ghost`,onClick:()=>void _a(),disabled:Tr,children:`warm snapshots`})]})]}),(0,S.jsxs)(`div`,{className:`stateList`,children:[(0,S.jsx)(A,{label:`reason`,value:H(rn.reason)}),(0,S.jsx)(A,{label:`required`,value:rn.required_migration}),(0,S.jsx)(A,{label:`missing`,value:(rn.missing_checks||[]).map(e=>e.check_id).slice(0,4).join(`, `)||`нет`}),(0,S.jsx)(A,{label:`action`,value:rn.recommended_operator_action||`schema is compatible`}),cn&&(0,S.jsx)(A,{label:`warmup`,value:`warmed ${cn.warmed_count}, fresh ${cn.already_fresh_count}, missing ${cn.missing_snapshot_count}, stale ${cn.stale_snapshot_count}, deferred ${cn.deferred_stale_count}, errors ${cn.error_count}`})]})]}),on&&(0,S.jsxs)(`div`,{className:`noticePanel ${on.status===`degraded`?`warnPanel`:`goodPanel`}`,children:[(0,S.jsxs)(`div`,{className:`cardHead compact`,children:[(0,S.jsxs)(`div`,{children:[(0,S.jsx)(`h4`,{children:`Snapshot maintenance`}),(0,S.jsx)(`p`,{className:`muted`,children:`Auto-warmup visibility for rebuild snapshot cache after node heartbeats.`})]}),(0,S.jsxs)(`div`,{className:`summaryChips`,children:[(0,S.jsx)(`span`,{className:`pill ${on.status===`degraded`?`warn`:`good`}`,children:H(on.status)}),(0,S.jsxs)(`span`,{className:on.overdue_missing_snapshot_count>0?`pill bad`:`pill good`,children:[`overdue `,on.overdue_missing_snapshot_count]}),(0,S.jsxs)(`span`,{className:on.auto_warmup_error_count>0?`pill bad`:`pill good`,children:[`auto errors `,on.auto_warmup_error_count]})]})]}),(0,S.jsxs)(`div`,{className:`stateList`,children:[(0,S.jsx)(A,{label:`reason`,value:H(on.reason)}),(0,S.jsx)(A,{label:`snapshots`,value:`valid ${on.valid_snapshot_count}, missing ${on.missing_snapshot_count}, attempts ${on.recent_attempt_count}`}),(0,S.jsx)(A,{label:`auto-warmup`,value:`events ${on.auto_warmup_event_count}, warmed ${on.auto_warmup_warmed_count}, fresh ${on.auto_warmup_already_fresh_count}, latest ${V(on.latest_auto_warmup_at)}`}),(0,S.jsx)(A,{label:`guard`,value:`age ${on.min_age_seconds}s, heartbeats ${on.heartbeat_threshold}`}),(0,S.jsx)(A,{label:`action`,value:on.recommended_operator_action||`snapshot maintenance is current`})]}),(on.nodes||[]).length>0&&(0,S.jsx)(M,{columns:[`node`,`snapshots`,`heartbeat`,`auto-warmup`,`latest`],rows:(on.nodes||[]).slice(0,6).map(e=>[F(j,e.node_id),(0,S.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)])})]}),un&&(0,S.jsxs)(`div`,{className:`noticePanel ${un.status===`degraded`?`warnPanel`:`goodPanel`}`,children:[(0,S.jsxs)(`div`,{className:`cardHead compact`,children:[(0,S.jsxs)(`div`,{children:[(0,S.jsx)(`h4`,{children:`Service-channel leases`}),(0,S.jsx)(`p`,{className:`muted`,children:`Durable compatibility lease records for introspection after backend restarts.`})]}),(0,S.jsxs)(`div`,{className:`summaryChips`,children:[(0,S.jsx)(`span`,{className:`pill ${un.status===`degraded`?`warn`:`good`}`,children:H(un.status)}),(0,S.jsxs)(`span`,{className:`pill good`,children:[`active `,un.active_count]}),(0,S.jsxs)(`span`,{className:un.expired_count>0?`pill warn`:`pill`,children:[`expired `,un.expired_count]}),(0,S.jsx)(`button`,{className:`ghost`,onClick:()=>void va(),disabled:Tr,children:`cleanup`})]})]}),(0,S.jsxs)(`div`,{className:`stateList`,children:[(0,S.jsx)(A,{label:`reason`,value:H(un.reason)}),(0,S.jsx)(A,{label:`scanned`,value:`${un.scanned_count}/${un.window_limit}`}),(0,S.jsx)(A,{label:`deleted`,value:String(un.deleted_expired_count||0)}),(0,S.jsx)(A,{label:`action`,value:un.recommended_operator_action||`lease maintenance is current`})]}),(un.leases||[]).length>0&&(0,S.jsx)(M,{columns:[`expires`,`resource`,`entry`,`exit`,`route`,`data plane`,`state`],rows:(un.leases||[]).slice(0,8).map(e=>[V(e.expires_at),e.resource_id||B(e.channel_id),F(j,e.selected_entry_node_id||``),F(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,S.jsx)(`span`,{className:`pill ${e.expired||e.force_backend_fallback?`warn`:`good`}`,children:e.expired?`expired`:e.force_backend_fallback?`fallback`:H(e.status)})])})]}),L&&(0,S.jsxs)(`div`,{className:`noticePanel ${L.status===`degraded`?`warnPanel`:`goodPanel`}`,children:[(0,S.jsxs)(`div`,{className:`cardHead compact`,children:[(0,S.jsxs)(`div`,{children:[(0,S.jsx)(`h4`,{children:`Service-channel access`}),(0,S.jsx)(`p`,{className:`muted`,children:`Live accepted_by visibility from node telemetry and heartbeat metadata.`})]}),(0,S.jsxs)(`div`,{className:`summaryChips`,children:[(0,S.jsx)(`span`,{className:`pill ${L.status===`degraded`?`warn`:`good`}`,children:H(L.status)}),(0,S.jsxs)(`span`,{className:`pill good`,children:[`accepted `,L.total_accepted]}),(0,S.jsxs)(`span`,{className:L.backend_fallback_count>0?`pill warn`:`pill`,children:[`backend `,L.backend_fallback_count]}),(0,S.jsxs)(`span`,{className:(L.backend_fallback_blocked_count||0)>0?`pill bad`:`pill`,children:[`blocked `,L.backend_fallback_blocked_count||0]}),(0,S.jsxs)(`span`,{className:`pill ${L.last_working_data_transport===`fabric_service_channel`?`good`:L.data_plane_contract_count?`warn`:``}`,children:[`data-plane `,L.data_plane_contract_count||0]}),(0,S.jsxs)(`span`,{className:`pill ${L.last_backend_relay_policy===`disabled`?`good`:L.last_backend_relay_policy===`degraded_fallback_only`?`info`:``}`,children:[`relay `,H(L.last_backend_relay_policy||`unknown`)]}),(0,S.jsxs)(`span`,{className:L.degraded_fallback_channel_count>0||L.degraded_route_count>0?`pill warn`:`pill good`,children:[`channels `,L.active_channel_count]}),(0,S.jsxs)(`span`,{className:L.no_safe_recovery_decision_count?`pill warn`:L.route_decision_channel_count?`pill info`:`pill`,children:[`decisions `,L.route_decision_channel_count||0,L.replacement_decision_count?` / repl ${L.replacement_decision_count}`:``,L.applied_rebuild_decision_count?` / applied ${L.applied_rebuild_decision_count}`:``,L.recovery_decision_count?` / recovery ${L.recovery_decision_count}`:``,L.no_safe_recovery_decision_count?` / no-safe ${L.no_safe_recovery_decision_count}`:``]}),(0,S.jsx)(`span`,{className:`pill ${Hn(L.flow_health_status,L.flow_dropped)}`,children:Bn(L.traffic_class_counts)}),(0,S.jsxs)(`span`,{className:`pill ${Hn(L.flow_health_status,L.flow_dropped)}`,children:[`flow `,H(L.flow_health_status||`healthy`)]}),(0,S.jsxs)(`span`,{className:`pill ${L.adaptive_backpressure_active?`info`:`good`}`,children:[`windows `,Vn(L.recommended_parallel_windows)]})]})]}),(0,S.jsxs)(`div`,{className:`stateList`,children:[(0,S.jsx)(A,{label:`reason`,value:H(L.reason)}),(0,S.jsx)(A,{label:`reporting nodes`,value:`${L.reporting_node_count}/${L.node_count}`}),(0,S.jsx)(A,{label:`accepted by`,value:`signed ${L.signed_accepted}, introspection ${L.introspection_accepted}, legacy ${L.legacy_unsigned_accepted}`}),(0,S.jsx)(A,{label:`data plane`,value:`${L.data_plane_contract_count||0} contracts, mode ${H(L.last_data_plane_mode||`unknown`)}, working ${H(L.last_working_data_transport||`unknown`)}, steady ${H(L.last_steady_state_transport||`unknown`)}, relay ${H(L.last_backend_relay_policy||`unknown`)}, flows ${H(L.last_logical_flow_mode||`unknown`)}, blocked ${L.backend_fallback_blocked_count||0}, route failures ${L.fabric_route_send_failure_count||0}`}),(0,S.jsx)(A,{label:`data-plane violation`,value:L.last_data_plane_violation_status?`${H(L.last_data_plane_violation_status)} / ${L.last_data_plane_violation_reason||`n/a`}`:`none`}),(0,S.jsx)(A,{label:`active channels`,value:`${L.active_channel_count||0}, fallback ${L.degraded_fallback_channel_count||0}, correlated routes ${L.correlated_route_count||0}, degraded routes ${L.degraded_route_count||0}`}),(0,S.jsx)(A,{label:`route decisions`,value:`channels ${L.route_decision_channel_count||0}, replacement ${L.replacement_decision_count||0}, applied ${L.applied_rebuild_decision_count||0}, recovery ${L.recovery_decision_count||0}, no-safe ${L.no_safe_recovery_decision_count||0}`}),(0,S.jsx)(A,{label:`flow QoS`,value:`${H(L.flow_health_status||`healthy`)} / ${H(L.flow_health_reason||`flow_health_ready`)}, ${Bn(L.traffic_class_counts)}, flows ${L.flow_channel_count||0}, in-flight ${L.flow_max_in_flight||0}, dropped ${L.flow_dropped||0}`}),(0,S.jsx)(A,{label:`adaptive windows`,value:`${L.adaptive_backpressure_active?H(L.adaptive_backpressure_reason||`adaptive`):`off`}, ${Vn(L.recommended_parallel_windows)}, policy ${L.adaptive_policy_fingerprint?B(L.adaptive_policy_fingerprint):`n/a`}`}),(0,S.jsx)(A,{label:`latest accepted`,value:V(L.latest_accepted_at)}),(0,S.jsx)(A,{label:`action`,value:L.recommended_operator_action||`access telemetry is current`})]}),(L.active_channels||[]).length>0&&(0,S.jsx)(M,{columns:[`resource`,`entry -> exit`,`route`,`decision`,`entry access`,`data plane`,`flow health`,`windows`,`flow QoS`,`route quality`,`remediation`,`guard`,`execution`,`expires`],rows:(L.active_channels||[]).slice(0,10).map(e=>[e.resource_id||B(e.channel_id),`${F(j,e.selected_entry_node_id||``)} -> ${F(j,e.selected_exit_node_id||``)}`,e.primary_route_id?`${B(e.primary_route_id)} / ${H(e.primary_route_status||``)}`:`backend fallback`,(0,S.jsx)(`span`,{className:`pill ${Wn(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,S.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,S.jsxs)(`span`,{className:`pill ${Hn(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,S.jsx)(`span`,{className:`pill ${e.entry_node_adaptive_backpressure_active?`info`:`good`}`,children:Vn(e.entry_node_recommended_parallel_windows)}),(0,S.jsxs)(`span`,{className:`pill ${Hn(e.entry_node_flow_health_status,e.entry_node_flow_dropped)}`,children:[Bn(e.entry_node_traffic_class_counts),` / flows ${e.entry_node_flow_channel_count||0} / in ${e.entry_node_flow_max_in_flight||0}`]}),(0,S.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,S.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,S.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,S.jsxs)(`span`,{className:`pill ${Un(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)])}),(L.nodes||[]).length>0&&(0,S.jsx)(M,{columns:[`node`,`accepted`,`signed`,`introspection`,`legacy`,`backend`,`data plane`,`flow health`,`windows`,`flow QoS`,`latest`],rows:(L.nodes||[]).slice(0,10).map(e=>[F(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,S.jsx)(`span`,{className:e.backend_fallback_count>0?`pill warn`:`pill`,children:e.backend_fallback_count}),(0,S.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,S.jsxs)(`span`,{className:`pill ${Hn(e.flow_health_status,e.flow_dropped)}`,children:[H(e.flow_health_status||`healthy`),e.flow_health_reason?` / ${H(e.flow_health_reason)}`:``]}),(0,S.jsx)(`span`,{className:`pill ${e.adaptive_backpressure_active?`info`:`good`}`,children:Vn(e.recommended_parallel_windows)}),(0,S.jsxs)(`span`,{className:`pill ${Hn(e.flow_health_status,e.flow_dropped)}`,children:[Bn(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)])})]}),tn&&(0,S.jsxs)(`div`,{className:`noticePanel ${tn.status===`blocked`?`badPanel`:tn.status===`degraded`?`warnPanel`:`goodPanel`}`,children:[(0,S.jsxs)(`div`,{className:`cardHead compact`,children:[(0,S.jsxs)(`div`,{children:[(0,S.jsx)(`h4`,{children:`Fabric service-channel readiness`}),(0,S.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,S.jsxs)(`div`,{className:`summaryChips`,children:[(0,S.jsx)(`span`,{className:`pill ${tn.status===`blocked`?`bad`:tn.status===`degraded`?`warn`:`good`}`,children:H(tn.status)}),(0,S.jsxs)(`span`,{className:tn.active_alert_count>0?`pill bad`:`pill`,children:[`active `,tn.active_alert_count]}),(0,S.jsxs)(`span`,{className:tn.resurfaced_count>0?`pill bad`:`pill`,children:[`resurfaced `,tn.resurfaced_count]})]})]}),(0,S.jsxs)(`div`,{className:`stateList`,children:[(0,S.jsx)(A,{label:`reason`,value:H(tn.reason)}),(0,S.jsx)(A,{label:`blocking`,value:(tn.blocking_reasons||[]).map(H).join(`, `)||`нет`}),(0,S.jsx)(A,{label:`degraded`,value:(tn.degraded_reasons||[]).map(H).join(`, `)||`нет`}),(0,S.jsx)(A,{label:`missing/post`,value:`transition ${tn.missing_transition_count}, route-gen ${tn.missing_route_generation_count}, traffic ${tn.missing_post_rebuild_traffic_count}`})]})]}),pn.length>0&&(0,S.jsxs)(`div`,{className:`subPanel`,children:[(0,S.jsxs)(`div`,{className:`cardHead compact`,children:[(0,S.jsxs)(`div`,{children:[(0,S.jsx)(`h4`,{children:`Rebuild incidents`}),(0,S.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,S.jsx)(`span`,{className:`pill`,children:pn.length})]}),(0,S.jsx)(M,{columns:[`last`,`source`,`reporter`,`route`,`service`,`guard`,`count`,`replacement`,`action`],rows:pn.slice(0,10).map(e=>[V(e.last_seen_at),e.incident_source?H(e.incident_source):`ledger`,F(j,e.reporter_node_id),B(e.route_id),e.service_class,(0,S.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,S.jsxs)(`div`,{className:`inlineActions`,children:[(0,S.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,S.jsx)(`button`,{type:`button`,className:`ghost`,onClick:()=>void Y(()=>ya(e),`Deep rebuild investigation opened.`),children:`open deep`}),e.alert_silenced?(0,S.jsx)(`span`,{className:`muted`,children:`silenced`}):(0,S.jsx)(`button`,{type:`button`,className:`ghost`,onClick:()=>void Y(()=>wa(e),`Rebuild incident silenced for 6 hours.`),children:`silence 6h`})]})])})]}),(Tn||ua.length>0)&&(0,S.jsxs)(`div`,{className:`subPanel`,children:[(0,S.jsxs)(`div`,{className:`cardHead compact`,children:[(0,S.jsxs)(`div`,{children:[(0,S.jsx)(`h4`,{children:`Recent investigations`}),(0,S.jsx)(`p`,{className:`muted`,children:`Recent operator drilldowns opened from rebuild incidents or feedback breakdown rows.`})]}),(0,S.jsxs)(`div`,{className:`summaryChips`,children:[(0,S.jsx)(`span`,{className:`pill info`,children:hr?.total_count||ua.length}),(0,S.jsxs)(`span`,{className:`pill good`,children:[`linked `,hr?.correlated_count||0]}),(0,S.jsxs)(`span`,{className:(hr?.not_visible_count||0)>0?`pill warn`:`pill`,children:[`not visible `,hr?.not_visible_count||0]}),Object.entries(hr?.counts_by_breadcrumb_status||{}).map(([e,t])=>(0,S.jsxs)(`span`,{className:e===`current`?`pill good`:e===`stale`?`pill warn`:`pill bad`,children:[H(e),` `,t]},e)),Object.entries(hr?.counts_by_current_diagnostic_status||{}).slice(0,3).map(([e,t])=>(0,S.jsxs)(`span`,{className:e===`breakdown_active`||e===`incident_visible`?`pill good`:e===`not_visible`?`pill warn`:`pill`,children:[H(e),` `,t]},e))]})]}),Tn&&(0,S.jsxs)(`div`,{className:`inlineForm`,children:[(0,S.jsxs)(`label`,{children:[`current window, sec`,(0,S.jsx)(`input`,{type:`number`,min:`60`,value:zr.currentWindowSeconds,onChange:e=>Br(t=>({...t,currentWindowSeconds:e.target.value}))})]}),(0,S.jsxs)(`label`,{children:[`history window, sec`,(0,S.jsx)(`input`,{type:`number`,min:`60`,value:zr.historyWindowSeconds,onChange:e=>Br(t=>({...t,historyWindowSeconds:e.target.value}))})]}),(0,S.jsx)(`button`,{type:`button`,className:`ghost`,onClick:()=>void Y(async()=>{En(await q.updateFabricServiceChannelBreadcrumbWindowPolicy(T,{currentWindowSeconds:Number(zr.currentWindowSeconds),historyWindowSeconds:Number(zr.historyWindowSeconds)}));let e=await q.getFabricServiceChannelRebuildInvestigationBreadcrumbs(T,{limit:20});mr(e.events),gr(e.summary||null)},`Breadcrumb window policy updated.`),children:`apply windows`}),(0,S.jsxs)(`span`,{className:`muted`,children:[`source `,Tn.source,`, fp `,B(Tn.fingerprint||``)]})]}),hr&&(0,S.jsxs)(`div`,{className:`stateList`,children:[(0,S.jsx)(A,{label:`latest`,value:V(hr.latest_at)}),(0,S.jsx)(A,{label:`windows`,value:`${Tn?.current_window_seconds||`n/a`}s current / ${Tn?.history_window_seconds||`n/a`}s history`}),(0,S.jsx)(A,{label:`sources`,value:Object.entries(hr.counts_by_feedback_source||{}).slice(0,3).map(([e,t])=>`${H(e)} ${t}`).join(`, `)||`нет`}),(0,S.jsx)(A,{label:`violations`,value:Object.entries(hr.counts_by_feedback_violation_status||{}).slice(0,3).map(([e,t])=>`${H(e)} ${t}`).join(`, `)||`нет`})]}),(0,S.jsx)(M,{columns:[`time`,`freshness`,`source`,`feedback`,`target`,`current`,`actor`,`reason`],rows:ua.map(e=>{let t=N(e.payload)||{},n=P(t,`feedback_channel_id`,``),r=P(t,`feedback_violation_status`,``),i=P(t,`feedback_source`,``),a=P(t,`reporter_node_id`,``),o=P(t,`route_id`,``),s=P(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||xa(e),f=e.correlation_hints?.rebuild_incident||Sa(e);return[V(e.created_at),(0,S.jsxs)(`div`,{className:`stackedText`,children:[(0,S.jsx)(`span`,{className:l===`current`?`pill good`:l===`stale`?`pill warn`:`pill bad`,children:H(l)}),(0,S.jsx)(`span`,{className:`muted`,children:Ln(u)})]}),(0,S.jsxs)(`div`,{className:`stackedText`,children:[(0,S.jsx)(`span`,{children:e.event_type.includes(`feedback_breakdown`)?`feedback breakdown`:`incident`}),(0,S.jsx)(`span`,{className:`muted`,children:H(s||e.target_type)})]}),i||n||r?(0,S.jsxs)(`div`,{className:`stackedText`,children:[(0,S.jsx)(`span`,{children:H(i||`feedback`)}),(0,S.jsx)(`span`,{className:`muted`,children:n?`ch ${B(n)}`:`any channel`}),(0,S.jsx)(`span`,{className:`muted`,children:H(r||`any violation`)})]}):(0,S.jsx)(`span`,{className:`muted`,children:`нет`}),(0,S.jsxs)(`div`,{className:`stackedText`,children:[(0,S.jsx)(`span`,{children:a?F(j,a):`any reporter`}),(0,S.jsx)(`span`,{className:`muted`,children:o?B(o):e.target_id?B(e.target_id):`any route`})]}),d?(0,S.jsxs)(`div`,{className:`inlineActions`,children:[(0,S.jsx)(`span`,{className:d.active_bad_count?`pill bad`:d.active_warn_count?`pill warn`:`pill good`,children:H(c||`breakdown_active`)}),(0,S.jsxs)(`span`,{className:`muted`,children:[`bad `,d.active_bad_count||0,` / warn `,d.active_warn_count||0]}),(0,S.jsx)(`button`,{type:`button`,className:`ghost`,onClick:()=>void Y(()=>Ca(d),`Rebuild ledger opened for current feedback breakdown.`),children:`open`})]}):f?(0,S.jsxs)(`div`,{className:`inlineActions`,children:[(0,S.jsx)(`span`,{className:`pill ${f.guard_severity===`bad`?`bad`:f.guard_severity===`warn`?`warn`:`good`}`,children:H(c||`incident_visible`)}),(0,S.jsx)(`span`,{className:`muted`,children:H(f.guard_status)}),(0,S.jsx)(`button`,{type:`button`,className:`ghost`,onClick:()=>void Y(()=>ya(f),`Deep rebuild investigation opened for current incident.`),children:`open`})]}):(0,S.jsx)(`span`,{className:`muted`,children:H(c||`not_visible`)}),e.actor_user_id?B(e.actor_user_id):`system`,P(t,`reason`,`operator opened investigation`)]})})]}),$t.length>0&&(0,S.jsxs)(`div`,{className:`subPanel`,children:[(0,S.jsxs)(`div`,{className:`cardHead compact`,children:[(0,S.jsxs)(`div`,{children:[(0,S.jsx)(`h4`,{children:`Active rebuild silences`}),(0,S.jsx)(`p`,{className:`muted`,children:`Operator acknowledgements currently suppressing rebuild/access-decision alerts. Remove a silence to let the incident become active again.`})]}),(0,S.jsx)(`span`,{className:`pill info`,children:$t.length})]}),(0,S.jsx)(M,{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):`нет`,F(j,e.reporter_node_id),B(e.display_route_id||e.route_id),H(e.guard_status),e.reason||`acknowledged`,(0,S.jsx)(`button`,{type:`button`,className:`ghost`,onClick:()=>void Y(()=>Ta(e),`Rebuild alert silence removed.`),children:`unsilence`})])})]}),I&&(0,S.jsxs)(`div`,{className:`subPanel`,children:[(0,S.jsxs)(`div`,{className:`cardHead compact`,children:[(0,S.jsxs)(`div`,{children:[(0,S.jsx)(`h4`,{children:`Rebuild health`}),(0,S.jsxs)(`p`,{className:`muted`,children:[`Сводка по последним `,I.total_attempts,` rebuild попыткам. Данные помогают быстро увидеть, где backend уже принял решение, но node-agent или post-rebuild traffic не подтвердили результат.`]})]}),(0,S.jsxs)(`div`,{className:`summaryChips`,children:[(0,S.jsxs)(`span`,{className:`pill good`,children:[`ok `,I.good_count]}),(0,S.jsxs)(`span`,{className:I.active_warn_count>0?`pill warn`:`pill`,children:[`warn `,I.active_warn_count,`/`,I.warn_count]}),(0,S.jsxs)(`span`,{className:I.active_bad_count>0?`pill bad`:`pill`,children:[`bad `,I.active_bad_count,`/`,I.bad_count]}),(0,S.jsxs)(`span`,{className:I.resurfaced_count>0?`pill bad`:`pill`,children:[`resurfaced `,I.resurfaced_count]}),(0,S.jsxs)(`span`,{className:I.silenced_count>0?`pill info`:`pill`,children:[`silenced `,I.silenced_count]}),(0,S.jsxs)(`span`,{className:`pill`,children:[`applied `,I.applied_count]}),(0,S.jsxs)(`span`,{className:I.access_no_safe_count?`pill bad`:I.access_route_decision_count?`pill info`:`pill`,children:[`access `,I.access_route_decision_count||0,I.access_no_safe_count?` / no-safe ${I.access_no_safe_count}`:``]})]})]}),(0,S.jsxs)(`div`,{className:`stateList`,children:[(0,S.jsx)(A,{label:`observed`,value:V(I.observed_at)}),(0,S.jsx)(A,{label:`affected nodes`,value:(I.affected_reporter_node_ids||[]).map(e=>F(j,e)).join(`, `)||`нет`}),(0,S.jsx)(A,{label:`affected routes`,value:(I.affected_route_ids||[]).map(B).join(`, `)||`нет`}),(0,S.jsx)(A,{label:`action`,value:H(I.recommended_operator_action||`no_operator_action_required`)})]}),(I.feedback_breakdowns||[]).length>0&&(0,S.jsx)(M,{columns:[`feedback`,`active`,`total`,`affected`,`incidents`,`latest`,`action`],rows:(I.feedback_breakdowns||[]).slice(0,8).map(e=>{let t=ba(e);return[(0,S.jsxs)(`div`,{className:`stackedText`,children:[(0,S.jsx)(`span`,{children:H(e.feedback_source||`feedback`)}),(0,S.jsx)(`span`,{className:`muted`,children:e.feedback_channel_id?`ch ${B(e.feedback_channel_id)}`:`any channel`}),(0,S.jsx)(`span`,{className:`muted`,children:H(e.feedback_violation_status||`unknown`)})]}),(0,S.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,S.jsxs)(`div`,{className:`stackedText`,children:[(0,S.jsx)(`span`,{children:(e.affected_reporter_node_ids||[]).map(e=>F(j,e)).join(`, `)||`нет узлов`}),(0,S.jsx)(`span`,{className:`muted`,children:(e.affected_route_ids||[]).map(B).join(`, `)||`нет routes`})]}),t.length>0?(0,S.jsxs)(`div`,{className:`stackedText`,children:[(0,S.jsx)(`span`,{className:`pill warn`,children:t.length}),(0,S.jsx)(`span`,{className:`muted`,children:t.slice(0,2).map(e=>H(e.guard_status)).join(`, `)})]}):(0,S.jsx)(`span`,{className:`muted`,children:`нет`}),V(e.latest_observed_at),(0,S.jsx)(`button`,{type:`button`,className:`ghost`,onClick:()=>void Y(()=>Ca(e),`Rebuild ledger opened for feedback breakdown.`),children:`open ledger`})]})}),(I.most_recent_bad_attempts||[]).length>0&&(0,S.jsx)(M,{columns:[`time`,`reporter`,`route`,`guard`,`reason`],rows:(I.most_recent_bad_attempts||[]).slice(0,5).map(e=>[V(e.updated_at),F(j,e.reporter_node_id),B(e.route_id),(0,S.jsx)(`span`,{className:`pill bad`,children:H(e.guard_status||`bad`)}),(0,S.jsxs)(`div`,{className:`inlineActions`,children:[(0,S.jsx)(`span`,{children:H(e.guard_reason||`unknown`)}),(0,S.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`})]})])}),(I.resurfaced_attempts||[]).length>0&&(0,S.jsx)(M,{columns:[`time`,`reporter`,`route`,`guard`,`previous`,`action`],rows:(I.resurfaced_attempts||[]).slice(0,5).map(e=>[V(e.updated_at),F(j,e.reporter_node_id),B(e.route_id),(0,S.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,S.jsxs)(`div`,{className:`inlineActions`,children:[(0,S.jsx)(`span`,{children:H(e.guard_reason||`unknown`)}),(0,S.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`})]})])})]}),bn&&(0,S.jsxs)(`div`,{className:`inlineForm`,children:[(0,S.jsxs)(`label`,{children:[`penalty`,(0,S.jsx)(`input`,{type:`number`,min:`0`,value:Lr.hysteresisPenalty,onChange:e=>Rr(t=>({...t,hysteresisPenalty:e.target.value}))})]}),(0,S.jsxs)(`label`,{children:[`promote samples`,(0,S.jsx)(`input`,{type:`number`,min:`1`,value:Lr.promotionMinSamples,onChange:e=>Rr(t=>({...t,promotionMinSamples:e.target.value}))})]}),(0,S.jsxs)(`label`,{children:[`fail`,(0,S.jsx)(`input`,{type:`number`,min:`1`,value:Lr.demotionFailureThreshold,onChange:e=>Rr(t=>({...t,demotionFailureThreshold:e.target.value}))})]}),(0,S.jsxs)(`label`,{children:[`drop`,(0,S.jsx)(`input`,{type:`number`,min:`1`,value:Lr.demotionDropThreshold,onChange:e=>Rr(t=>({...t,demotionDropThreshold:e.target.value}))})]}),(0,S.jsxs)(`label`,{children:[`slow`,(0,S.jsx)(`input`,{type:`number`,min:`1`,value:Lr.demotionSlowThreshold,onChange:e=>Rr(t=>({...t,demotionSlowThreshold:e.target.value}))})]}),(0,S.jsxs)(`label`,{className:`checkLine`,children:[(0,S.jsx)(`input`,{type:`checkbox`,checked:Lr.demotionRebuildEnabled,onChange:e=>Rr(t=>({...t,demotionRebuildEnabled:e.target.checked}))}),`rebuild`]}),(0,S.jsxs)(`label`,{className:`checkLine`,children:[(0,S.jsx)(`input`,{type:`checkbox`,checked:Lr.demotionFencedEnabled,onChange:e=>Rr(t=>({...t,demotionFencedEnabled:e.target.checked}))}),`fenced`]}),(0,S.jsx)(`button`,{type:`button`,className:`ghost`,onClick:()=>void Y(async()=>{wn(await q.updateFabricServiceChannelRecoveryPolicy(T,{hysteresisPenalty:Number(Lr.hysteresisPenalty),promotionMinSamples:Number(Lr.promotionMinSamples),demotionFailureThreshold:Number(Lr.demotionFailureThreshold),demotionDropThreshold:Number(Lr.demotionDropThreshold),demotionSlowThreshold:Number(Lr.demotionSlowThreshold),demotionRebuildEnabled:Lr.demotionRebuildEnabled,demotionFencedEnabled:Lr.demotionFencedEnabled}))},`Recovery policy updated.`),children:`apply policy`}),(0,S.jsxs)(`span`,{className:`muted`,children:[`source `,bn.source]})]}),(0,S.jsx)(M,{columns:[`route`,`reporter`,`service`,`status`,`recovery`,`score`,`reasons`,`failures`,`retry/cooldown`,`expires`,`action`],rows:Ja.slice(0,80).map(e=>[B(e.route_id),F(j,e.reporter_node_id),e.service_class,(0,S.jsx)(`span`,{className:`pill ${st(e.feedback_status)}`,children:H(e.feedback_status)}),e.recovery_state?(0,S.jsxs)(`span`,{className:`pill ${ct(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,S.jsx)(`span`,{className:`pill warn`,children:H(e.stale_reason||`stale`)}):e.provenance_missing?(0,S.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,S.jsx)(`span`,{className:`muted`,children:`нет`}):(0,S.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`})])}),Ja.length===0&&(0,S.jsx)(me,{title:`Feedback отсутствует`,text:`Нет свежих route feedback наблюдений от fabric service-channel runtime.`}),(0,S.jsx)(M,{columns:[`local node`,`route`,`replacement`,`rebuild`,`attempt`,`feedback`,`source`,`destination`,`decision`,`score`,`expires`],rows:[...ro,...X,...io].filter((e,t,n)=>n.findIndex(t=>t.decision_id===e.decision_id)===t).slice(0,80).map(e=>[F(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,S.jsxs)(`div`,{className:`stackedText`,children:[(0,S.jsx)(`span`,{children:H(e.feedback_source||`feedback`)}),(0,S.jsxs)(`span`,{className:`muted`,children:[B(e.feedback_observation_id),` `,e.feedback_channel_id?`ch ${B(e.feedback_channel_id)}`:``]}),(0,S.jsx)(`span`,{className:`muted`,children:H(e.feedback_violation_status||``)})]}):`нет`,F(j,e.source_node_id),F(j,e.destination_node_id),e.decision_source,e.path_score==null?`н/д`:String(e.path_score),V(e.expires_at)])}),(0,S.jsxs)(`div`,{className:`inlineForm`,children:[(0,S.jsxs)(`label`,{children:[`reporter`,(0,S.jsxs)(`select`,{value:z.reporterNodeId,onChange:e=>yn(t=>({...t,reporterNodeId:e.target.value,offset:0})),children:[(0,S.jsx)(`option`,{value:``,children:`all`}),j.map(e=>(0,S.jsx)(`option`,{value:e.id,children:e.name},e.id))]})]}),(0,S.jsxs)(`label`,{children:[`route`,(0,S.jsx)(`input`,{value:z.routeId,onChange:e=>yn(t=>({...t,routeId:e.target.value.trim(),offset:0})),placeholder:`route id`})]}),(0,S.jsxs)(`label`,{children:[`generation`,(0,S.jsx)(`input`,{value:z.generation,onChange:e=>yn(t=>({...t,generation:e.target.value.trim(),offset:0})),placeholder:`route generation`})]}),(0,S.jsxs)(`label`,{children:[`service`,(0,S.jsx)(`input`,{value:z.serviceClass,onChange:e=>yn(t=>({...t,serviceClass:e.target.value.trim(),offset:0})),placeholder:`vpn_packets`})]}),(0,S.jsxs)(`label`,{children:[`feedback source`,(0,S.jsx)(`input`,{value:z.feedbackSource,onChange:e=>yn(t=>({...t,feedbackSource:e.target.value.trim(),offset:0})),placeholder:`fabric_service_channel_access_report`})]}),(0,S.jsxs)(`label`,{children:[`channel`,(0,S.jsx)(`input`,{value:z.feedbackChannelId,onChange:e=>yn(t=>({...t,feedbackChannelId:e.target.value.trim(),offset:0})),placeholder:`feedback channel id`})]}),(0,S.jsxs)(`label`,{children:[`violation`,(0,S.jsx)(`input`,{value:z.feedbackViolationStatus,onChange:e=>yn(t=>({...t,feedbackViolationStatus:e.target.value.trim(),offset:0})),placeholder:`fabric_route_send_failed_backend_fallback_blocked`})]}),(0,S.jsx)(`button`,{type:`button`,className:`ghost`,onClick:()=>void ha(mn,{...z,offset:0}),children:`apply`}),(0,S.jsx)(`button`,{type:`button`,className:`ghost`,onClick:()=>{let e={...re};yn(e),ha(!1,e)},children:`clear`})]}),(0,S.jsx)(M,{columns:[`time`,`reporter`,`route`,`replacement`,`feedback`,`guard`,`outcome`,`backend`,`agent`,`route-gen`,`traffic`,`policy`,`hops`],rows:zt.slice(0,80).map(e=>[V(e.updated_at),F(j,e.reporter_node_id),B(e.route_id),e.replacement_route_id?B(e.replacement_route_id):`нет`,e.feedback_observation_id?(0,S.jsxs)(`div`,{className:`stackedText`,children:[(0,S.jsx)(`span`,{children:H(e.feedback_source||`feedback`)}),(0,S.jsxs)(`span`,{className:`muted`,children:[B(e.feedback_observation_id),` `,e.feedback_channel_id?`ch ${B(e.feedback_channel_id)}`:``]}),(0,S.jsx)(`span`,{className:`muted`,children:H(e.feedback_violation_status||``)})]}):e.feedback_status?H(e.feedback_status):`нет`,mn?(0,S.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,S.jsx)(`span`,{className:`pill info`,children:`summary`}),H(e.outcome),(0,S.jsx)(`span`,{className:`pill ${e.rebuild_status===`applied`?`good`:`warn`}`,children:H(e.rebuild_status)}),mn?e.node_transition_matched?(0,S.jsx)(`span`,{className:`pill ${e.node_transition_status===`applied_rebuild`?`good`:`warn`}`,children:H(e.node_transition_status||`matched`)}):(0,S.jsx)(`span`,{className:`pill warn`,children:`not seen`}):(0,S.jsx)(`span`,{className:`pill info`,children:`deep only`}),mn?e.node_route_generation_matched?(0,S.jsx)(`span`,{className:`pill good`,children:H(e.node_route_generation_status||`seen`)}):(0,S.jsx)(`span`,{className:`pill warn`,children:`not seen`}):(0,S.jsx)(`span`,{className:`pill info`,children:`deep only`}),mn?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=>F(j,e)).join(` -> `)||`нет`} => ${(e.replacement_hops||[]).map(e=>F(j,e)).join(` -> `)||`нет`}`])}),(0,S.jsxs)(`div`,{className:`inlineActions`,children:[(0,S.jsx)(`button`,{type:`button`,className:`ghost`,onClick:()=>void ha(!mn,{...z,offset:0}),children:mn?`fast ledger`:`deep ledger`}),(0,S.jsx)(`button`,{type:`button`,className:`ghost`,disabled:!mn||z.offset<=0,onClick:()=>void ha(!0,{...z,offset:Math.max(0,z.offset-20)}),children:`prev`}),(0,S.jsx)(`button`,{type:`button`,className:`ghost`,disabled:!mn||zt.length<20,onClick:()=>void ha(!0,{...z,offset:z.offset+20}),children:`next`}),(0,S.jsxs)(`span`,{className:`pill`,children:[`offset `,mn?z.offset:0]}),(0,S.jsx)(`span`,{className:`muted`,children:`Deep ledger correlates heartbeat timeline and can be slower; default refresh stays fast.`})]}),zt.length===0&&(0,S.jsx)(me,{title:`Rebuild ledger пуст`,text:`Пока нет долговечной истории service-channel route rebuild решений.`})]}),(0,S.jsxs)(`article`,{className:`card span2`,children:[(0,S.jsx)(`h3`,{children:J.servicePlacement}),(0,S.jsx)(M,{columns:[`узел`,`runtime`,`адрес`,`здоровье`,`роли`,`желаемые / reported сервисы`,`последний heartbeat`],rows:j.map(e=>{let t=wt(e,rt[e.id]||[],gt);return[e.name,(0,S.jsx)(ye,{runtime:t}),t.address,e.health_status,Ze(We[e.id]||[]),et(Qe[e.id]||[]),V((rt[e.id]||[])[0]?.observed_at||e.last_seen_at)]})})]}),(0,S.jsxs)(`article`,{className:`card`,children:[(0,S.jsx)(`h3`,{children:J.trafficFlow}),(0,S.jsx)(M,{columns:[`источник`,`цель`,`тип`,`route/path`,`статус`,`задержка`,`качество`,`наблюдение`],rows:ht(gt).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,S.jsx)(be,{node:t,fallback:F(j,e.source_node_id),heartbeatsByNode:rt,meshLinks:gt}),(0,S.jsx)(be,{node:n,fallback:F(j,e.target_node_id),heartbeatsByNode:rt,meshLinks:gt}),_t(e),vt(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,S.jsxs)(`article`,{className:`card`,children:[(0,S.jsx)(`h3`,{children:`Политики QoS`}),(0,S.jsx)(M,{columns:[`класс`,`приоритет`,`надежность`,`политика сброса`],rows:Dn.map(e=>[e.service_class,String(e.priority),e.reliability_mode,e.drop_policy])})]})]}),w===`vpn`&&(0,S.jsxs)(`section`,{className:`grid two`,children:[(0,S.jsxs)(`article`,{className:`card`,children:[(0,S.jsx)(`h3`,{children:`Создать желаемое состояние VPN-подключения`}),(0,S.jsx)(`p`,{className:`muted`,children:`Только control-plane. Здесь не выполняются TUN/TAP, маршруты, DNS, firewall, QoS или packet forwarding.`}),(0,S.jsxs)(Je,{children:[(0,S.jsxs)(`label`,{children:[`ID организации`,(0,S.jsx)(`input`,{value:W.organizationId,onChange:e=>Ei({...W,organizationId:e.target.value})})]}),(0,S.jsxs)(`label`,{children:[`Название`,(0,S.jsx)(`input`,{value:W.name,onChange:e=>Ei({...W,name:e.target.value})})]}),(0,S.jsxs)(`label`,{children:[`Протокол`,(0,S.jsxs)(`select`,{value:W.protocolFamily,onChange:e=>Ei({...W,protocolFamily:e.target.value}),children:[(0,S.jsx)(`option`,{value:`generic`,children:`generic`}),(0,S.jsx)(`option`,{value:`wireguard`,children:`wireguard`}),(0,S.jsx)(`option`,{value:`ipsec`,children:`ipsec`}),(0,S.jsx)(`option`,{value:`openvpn`,children:`openvpn`})]})]}),(0,S.jsxs)(`label`,{children:[`Желаемое состояние`,(0,S.jsxs)(`select`,{value:W.desiredState,onChange:e=>Ei({...W,desiredState:e.target.value}),children:[(0,S.jsx)(`option`,{value:`disabled`,children:`выключено`}),(0,S.jsx)(`option`,{value:`enabled`,children:`включено`})]})]}),(0,S.jsxs)(`label`,{children:[`Ссылка на credential`,(0,S.jsx)(`input`,{value:W.credentialRef,onChange:e=>Ei({...W,credentialRef:e.target.value})})]})]}),(0,S.jsxs)(`label`,{children:[`Целевой endpoint JSON`,(0,S.jsx)(`textarea`,{value:W.targetEndpointJson,onChange:e=>Ei({...W,targetEndpointJson:e.target.value})})]}),(0,S.jsxs)(`label`,{children:[`Политика разрешенных узлов JSON`,(0,S.jsx)(`textarea`,{value:W.allowedNodePolicyJson,onChange:e=>Ei({...W,allowedNodePolicyJson:e.target.value})})]}),(0,S.jsxs)(`details`,{children:[(0,S.jsx)(`summary`,{children:`Расширенные routing / QoS / placement JSON`}),(0,S.jsxs)(`label`,{children:[`Использование маршрутизации JSON`,(0,S.jsx)(`textarea`,{value:W.routingUsageJson,onChange:e=>Ei({...W,routingUsageJson:e.target.value})})]}),(0,S.jsxs)(`label`,{children:[`Политика маршрута JSON`,(0,S.jsx)(`textarea`,{value:W.routePolicyJson,onChange:e=>Ei({...W,routePolicyJson:e.target.value})})]}),(0,S.jsxs)(`label`,{children:[`Политика QoS JSON`,(0,S.jsx)(`textarea`,{value:W.qosPolicyJson,onChange:e=>Ei({...W,qosPolicyJson:e.target.value})})]}),(0,S.jsxs)(`label`,{children:[`Политика размещения JSON`,(0,S.jsx)(`textarea`,{value:W.placementPolicyJson,onChange:e=>Ei({...W,placementPolicyJson:e.target.value})})]})]}),(0,S.jsx)(`button`,{className:`primary`,disabled:!T||!W.organizationId||!W.name,onClick:()=>void Y(()=>q.createVPNConnection(T,{organizationId:W.organizationId,name:W.name,protocolFamily:W.protocolFamily,credentialRef:W.credentialRef||null,desiredState:W.desiredState,targetEndpoint:Ye(W.targetEndpointJson,`target endpoint`),allowedNodePolicy:Ye(W.allowedNodePolicyJson,`allowed node policy`),routingUsage:Xe(W.routingUsageJson,`routing usage`),routePolicy:Ye(W.routePolicyJson,`route policy`),qosPolicy:Ye(W.qosPolicyJson,`qos policy`),placementPolicy:Ye(W.placementPolicyJson,`placement policy`)}),`Желаемое состояние VPN создано.`),children:`Создать желаемое состояние VPN`})]}),(0,S.jsxs)(`article`,{className:`card`,children:[(0,S.jsxs)(`div`,{className:`cardHead`,children:[(0,S.jsxs)(`div`,{children:[(0,S.jsx)(`h3`,{children:`VPN-подключения`}),(0,S.jsx)(`p`,{className:`muted`,children:`Cluster-managed состояние, gateway packet stats и диагностика Android-клиента.`})]}),(0,S.jsxs)(`div`,{className:`actions compactActions`,children:[(0,S.jsx)(`button`,{onClick:()=>void Y(async()=>{Ar(`Истекшие VPN lease: ${(await q.expireStaleVPNLeases(T)).length}.`)},`Stale VPN lease проверены.`),children:`Проверить stale lease`}),(0,S.jsx)(`button`,{onClick:()=>void Da(),children:`Обновить клиент`})]})]}),(0,S.jsxs)(`div`,{className:`inlineForm`,children:[(0,S.jsxs)(`label`,{children:[`Android device id`,(0,S.jsx)(`input`,{value:qn,placeholder:`0315f630-...`,onChange:e=>Jn(e.target.value),onBlur:()=>localStorage.setItem(C.vpnDiagnosticDeviceId,qn.trim())})]}),Yn.length>0&&(0,S.jsxs)(`label`,{children:[`Найденные клиенты`,(0,S.jsx)(`select`,{value:qn,onChange:e=>{let t=e.target.value;Jn(t),localStorage.setItem(C.vpnDiagnosticDeviceId,t),Qn(Yn.find(e=>e.device_id===t)||null)},children:Yn.map(e=>{let t=N(e.payload)||{};return(0,S.jsxs)(`option`,{value:e.device_id,children:[B(e.device_id),` / `,P(t,`app_version`,`н/д`),` / `,V(e.observed_at)]},e.device_id)})})]})]}),(0,S.jsxs)(`div`,{className:`diagnosticCommandPanel`,children:[(0,S.jsxs)(`label`,{children:[`URL для теста`,(0,S.jsx)(`input`,{value:$n,onChange:e=>er(e.target.value)})]}),(0,S.jsxs)(`div`,{className:`actions compactActions`,children:[(0,S.jsx)(`button`,{onClick:()=>void Oa({type:`refresh_profile`},`Профиль`),children:`Обновить профиль`}),(0,S.jsx)(`button`,{onClick:()=>void Oa({type:`start_vpn`},`VPN`),children:`Старт VPN`}),(0,S.jsx)(`button`,{onClick:()=>void Oa({type:`stop_vpn`},`VPN`),children:`Стоп VPN`}),(0,S.jsx)(`button`,{onClick:()=>void Oa({type:`vpn_stats`},`Stats`),children:`Stats`}),(0,S.jsx)(`button`,{onClick:()=>void Oa({type:`vpn_http_get`,url:$n},`VPN HTTP`),children:`VPN HTTP`}),(0,S.jsx)(`button`,{onClick:()=>void Oa({type:`open_url`,url:$n},`Открыть URL`),children:`Открыть URL`}),(0,S.jsx)(`button`,{className:`primary`,onClick:()=>void Oa({type:`full_vpn_test`,url:$n,watch_seconds:45},`Полный VPN test`),children:`Полный тест`})]}),tr&&(0,S.jsxs)(`p`,{className:`muted`,children:[`Последняя команда: `,P(tr.payload,`type`,`н/д`),` / `,V(tr.created_at)]})]}),he(Zn),(0,S.jsxs)(`div`,{className:`stack`,children:[jn.map(e=>{let t=N(e.metadata?.client_config),n=N(t?.vpn_fabric_route),r=Rt(n?.entry_pool_node_ids||e.placement_policy?.entry_node_ids),i=Rt(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||Pn[e.id]?.owner_node_id||e.placement_policy?.exit_node_id||i[0]||``),s=Gn[e.id]||{};return(0,S.jsxs)(`div`,{className:`vpnCard`,children:[(0,S.jsxs)(`div`,{children:[(0,S.jsx)(`strong`,{children:e.name}),(0,S.jsxs)(`p`,{className:`muted`,children:[e.protocol_family,` / `,e.mode,` / организация `,B(e.organization_id)]}),(0,S.jsx)(k,{value:e.desired_state}),(0,S.jsx)(k,{value:e.status}),(0,S.jsx)(`span`,{className:`pill ${t?.packet_forwarding?`good`:`warn`}`,children:t?.packet_forwarding?`gateway packet relay active`:`gateway packet relay inactive`}),(0,S.jsxs)(`span`,{className:`pill`,children:[String(n?.preferred_data_plane||`backend_relay`),` / fallback `,String(n?.fallback_data_plane||`н/д`)]})]}),(0,S.jsxs)(`div`,{className:`stateList`,children:[(0,S.jsx)(A,{label:`Секрет`,value:e.credential_ref?`задан`:`не задан`}),(0,S.jsx)(A,{label:`Активный lease`,value:Pn[e.id]?B(Pn[e.id]?.owner_node_id):`нет`}),(0,S.jsx)(A,{label:`Fabric route`,value:`${a?F(j,a):`entry auto`} -> ${o?F(j,o):`exit auto`}`}),(0,S.jsx)(A,{label:`Entry pool`,value:r.map(e=>F(j,e)).join(`, `)||`н/д`}),(0,S.jsx)(A,{label:`Exit pool`,value:i.map(e=>F(j,e)).join(`, `)||`н/д`}),(0,S.jsx)(A,{label:`Runtime`,value:String(t?.runtime_status||`н/д`)}),(0,S.jsx)(A,{label:`Gateway`,value:String(t?.gateway_assignment_status||`н/д`)}),(0,S.jsx)(A,{label:`Client -> gateway`,value:at(s.client_to_gateway)}),(0,S.jsx)(A,{label:`Gateway -> client`,value:at(s.gateway_to_client)}),(0,S.jsx)(A,{label:`Обновлено`,value:V(e.updated_at)})]}),(0,S.jsxs)(`div`,{className:`actions`,children:[(0,S.jsx)(`button`,{disabled:e.desired_state===`enabled`,onClick:()=>void Y(()=>q.updateVPNConnectionDesiredState(T,e.id,`enabled`),`Желаемое состояние VPN включено.`),children:`Включить`}),(0,S.jsx)(`button`,{disabled:e.desired_state===`disabled`,onClick:()=>void Y(()=>q.updateVPNConnectionDesiredState(T,e.id,`disabled`),`Желаемое состояние VPN выключено.`),children:`Выключить`})]})]},e.id)}),jn.length===0&&(0,S.jsx)(me,{title:`Нет желаемого состояния VPN`,text:`Control-plane записи C18 появятся здесь.`})]})]})]}),w===`org-safe`&&(0,S.jsxs)(`section`,{className:`grid two`,children:[(0,S.jsxs)(`article`,{className:`card span2`,children:[(0,S.jsxs)(`div`,{className:`cardHead`,children:[(0,S.jsxs)(`div`,{children:[(0,S.jsx)(`h3`,{children:`Организации и пользователи`}),(0,S.jsx)(`p`,{className:`muted`,children:`Операционный слой для владельца платформы: tenant scope, роли участников и безопасная сводка без раскрытия core mesh.`})]}),(0,S.jsx)(`span`,{className:`pill`,children:rr.length})]}),(0,S.jsxs)(Je,{children:[(0,S.jsxs)(`label`,{children:[`Slug`,(0,S.jsx)(`input`,{value:Di.slug,onChange:e=>Oi({...Di,slug:e.target.value}),placeholder:`home`})]}),(0,S.jsxs)(`label`,{children:[`Название`,(0,S.jsx)(`input`,{value:Di.name,onChange:e=>Oi({...Di,name:e.target.value}),placeholder:`HOME`})]})]}),(0,S.jsx)(`div`,{className:`actions`,children:(0,S.jsx)(`button`,{className:`primary`,disabled:!Di.slug.trim()||!Di.name.trim(),onClick:()=>void Y(async()=>{let e=await q.createOrganization(Di);Oi({slug:``,name:``}),Sr(e.id),ji(t=>({...t,organizationId:e.id})),Ii(t=>({...t,organizationId:e.id}))},`Организация создана.`),children:`Создать организацию`})}),(0,S.jsx)(M,{columns:[`организация`,`slug`,`статус`,`ресурсы`,`участники`,`действие`],rows:rr.map(e=>{let t=sr.filter(t=>t.organization_id===e.id),n=lr[e.id]||[];return[e.name,e.slug,(0,S.jsx)(k,{value:e.status}),String(t.length),String(n.length),(0,S.jsx)(`div`,{className:`actions`,children:(0,S.jsx)(`button`,{onClick:()=>void Y(async()=>{Sr(e.id),wr(await q.getOrganizationAdminSummary(e.id))},`Сводка организации загружена.`),children:`Открыть`})},e.id)]})})]}),(0,S.jsxs)(`article`,{className:`card`,children:[(0,S.jsx)(`h3`,{children:`Пользователь`}),(0,S.jsxs)(Je,{children:[(0,S.jsxs)(`label`,{children:[`Email / логин`,(0,S.jsx)(`input`,{value:G.email,onChange:e=>ki({...G,email:e.target.value}),placeholder:`user@example.com`})]}),(0,S.jsxs)(`label`,{children:[`Пароль`,(0,S.jsx)(`input`,{type:`password`,value:G.password,onChange:e=>ki({...G,password:e.target.value}),placeholder:`минимум 8 символов`})]}),(0,S.jsxs)(`label`,{children:[`Роль платформы`,(0,S.jsxs)(`select`,{value:G.platformRole,onChange:e=>ki({...G,platformRole:e.target.value}),children:[(0,S.jsx)(`option`,{value:`user`,children:`user`}),(0,S.jsx)(`option`,{value:`platform_admin`,children:`platform_admin`}),(0,S.jsx)(`option`,{value:`platform_recovery_admin`,children:`platform_recovery_admin`})]})]})]}),(0,S.jsx)(`div`,{className:`actions`,children:(0,S.jsx)(`button`,{disabled:!G.email.trim()||G.password.length<8,onClick:()=>void Y(async()=>{let e=await q.createUser(G);or(await q.listUsers()),ki({email:``,password:``,platformRole:`user`}),ji(t=>({...t,userId:e.id}))},`Пользователь создан.`),children:`Создать пользователя`})}),(0,S.jsx)(M,{columns:[`пользователь`,`роль платформы`,`id`],rows:ar.map(e=>[e.email,(0,S.jsx)(k,{value:e.platform_role||`user`}),(0,S.jsx)(`code`,{children:e.id})])})]}),(0,S.jsxs)(`article`,{className:`card`,children:[(0,S.jsx)(`h3`,{children:`Участник организации`}),(0,S.jsxs)(Je,{children:[(0,S.jsxs)(`label`,{children:[`Организация`,(0,S.jsxs)(`select`,{value:Ai.organizationId,onChange:e=>ji({...Ai,organizationId:e.target.value}),children:[(0,S.jsx)(`option`,{value:``,children:`Выберите организацию`}),rr.map(e=>(0,S.jsx)(`option`,{value:e.id,children:e.name},e.id))]})]}),(0,S.jsxs)(`label`,{children:[`Пользователь`,(0,S.jsxs)(`select`,{value:Ai.userId,onChange:e=>ji({...Ai,userId:e.target.value}),children:[(0,S.jsx)(`option`,{value:``,children:`Выберите пользователя`}),ar.map(e=>(0,S.jsx)(`option`,{value:e.id,children:e.email},e.id))]})]}),(0,S.jsxs)(`label`,{children:[`Роль`,(0,S.jsxs)(`select`,{value:Ai.roleId,onChange:e=>ji({...Ai,roleId:e.target.value}),children:[(0,S.jsx)(`option`,{value:`org_owner`,children:`org_owner`}),(0,S.jsx)(`option`,{value:`org_admin`,children:`org_admin`}),(0,S.jsx)(`option`,{value:`org_operator`,children:`org_operator`}),(0,S.jsx)(`option`,{value:`org_member`,children:`org_member`}),(0,S.jsx)(`option`,{value:`org_viewer`,children:`org_viewer`})]})]})]}),(0,S.jsx)(`div`,{className:`actions`,children:(0,S.jsx)(`button`,{disabled:!Ai.organizationId||!Ai.userId.trim(),onClick:()=>void Y(()=>q.addOrganizationMembership(Ai.organizationId,{userId:Ai.userId,roleId:Ai.roleId}),`Участник организации сохранен.`),children:`Сохранить участника`})})]}),(0,S.jsxs)(`article`,{className:`card`,children:[(0,S.jsx)(`h3`,{children:`Безопасная сводка`}),(0,S.jsxs)(`div`,{className:`inlineForm`,children:[(0,S.jsxs)(`select`,{value:xr,onChange:e=>Sr(e.target.value),children:[(0,S.jsx)(`option`,{value:``,children:`Выберите организацию`}),rr.map(e=>(0,S.jsx)(`option`,{value:e.id,children:e.name},e.id))]}),(0,S.jsx)(`button`,{disabled:!xr,onClick:()=>void Y(async()=>{wr(await q.getOrganizationAdminSummary(xr))},`Сводка организации загружена.`),children:`Обновить`})]}),Cr?(0,S.jsxs)(`div`,{className:`stack`,children:[(0,S.jsx)(fe,{label:`Ресурсы`,value:Cr.resource_count,tone:`steel`}),(0,S.jsx)(fe,{label:`Активные сессии`,value:Cr.active_session_count,tone:`green`}),(0,S.jsx)(A,{label:`Topology exposure`,value:Cr.topology_exposure}),(0,S.jsx)(M,{columns:[`контур`,`состояние`],rows:Object.entries(Cr.connector_status||{}).map(([e,t])=>[e,typeof t==`string`?H(t):JSON.stringify(t)])}),(0,S.jsx)(M,{columns:[`протокол`,`количество`],rows:Cr.service_endpoints.map(e=>[e.protocol,String(e.count)])})]}):(0,S.jsx)(me,{title:`Сводка не выбрана`,text:`Выберите организацию, чтобы проверить tenant-safe состояние.`})]})]}),w===`servers`&&(0,S.jsx)(`section`,{className:`grid two`,children:(0,S.jsxs)(`article`,{className:`card span2`,children:[(0,S.jsxs)(`div`,{className:`cardHead`,children:[(0,S.jsxs)(`div`,{children:[(0,S.jsx)(`h3`,{children:`Справочник серверов`}),(0,S.jsx)(`p`,{className:`muted`,children:`Единый каталог целей для RDP/VPN: адрес сервера, организация, протокол и предпочтительный вход/выход маршрута.`})]}),(0,S.jsx)(`span`,{className:`pill`,children:sr.length})]}),(0,S.jsxs)(Je,{children:[(0,S.jsxs)(`label`,{children:[`Организация`,(0,S.jsxs)(`select`,{value:K.organizationId,onChange:e=>Ii({...K,organizationId:e.target.value}),children:[(0,S.jsx)(`option`,{value:``,children:`Выберите организацию`}),rr.map(e=>(0,S.jsx)(`option`,{value:e.id,children:e.name},e.id))]})]}),(0,S.jsxs)(`label`,{children:[`Имя сервера`,(0,S.jsx)(`input`,{value:K.name,onChange:e=>Ii({...K,name:e.target.value}),placeholder:`Office RDP`})]}),(0,S.jsxs)(`label`,{children:[`Адрес`,(0,S.jsx)(`input`,{value:K.address,onChange:e=>Ii({...K,address:e.target.value}),placeholder:`192.168.1.10:3389`})]}),(0,S.jsxs)(`label`,{children:[`Протокол`,(0,S.jsxs)(`select`,{value:K.protocol,onChange:e=>Ii({...K,protocol:e.target.value}),children:[(0,S.jsx)(`option`,{value:`rdp`,children:`RDP`}),(0,S.jsx)(`option`,{value:`vpn`,children:`VPN`}),(0,S.jsx)(`option`,{value:`ssh`,children:`SSH`}),(0,S.jsx)(`option`,{value:`http`,children:`HTTP`})]})]}),(0,S.jsxs)(`label`,{children:[`Вход`,(0,S.jsxs)(`select`,{value:K.entryNode,onChange:e=>Ii({...K,entryNode:e.target.value}),children:[(0,S.jsx)(`option`,{value:``,children:`Автоматически`}),j.map(e=>(0,S.jsx)(`option`,{value:e.id,children:e.name},e.id))]})]}),(0,S.jsxs)(`label`,{children:[`Выход`,(0,S.jsxs)(`select`,{value:K.exitNode,onChange:e=>Ii({...K,exitNode:e.target.value}),children:[(0,S.jsx)(`option`,{value:``,children:`Автоматически`}),j.map(e=>(0,S.jsx)(`option`,{value:e.id,children:e.name},e.id))]})]}),(0,S.jsxs)(`label`,{children:[`Теги`,(0,S.jsx)(`input`,{value:K.tags,onChange:e=>Ii({...K,tags:e.target.value}),placeholder:`home, accounting`})]}),(0,S.jsxs)(`label`,{children:[`RDP пользователь`,(0,S.jsx)(`input`,{value:K.username,onChange:e=>Ii({...K,username:e.target.value}),placeholder:`user или DOMAIN\\\\user`})]}),(0,S.jsxs)(`label`,{children:[`RDP пароль`,(0,S.jsx)(`input`,{type:`password`,value:K.password,onChange:e=>Ii({...K,password:e.target.value}),placeholder:`хранится как secret`})]}),(0,S.jsxs)(`label`,{children:[`Домен`,(0,S.jsx)(`input`,{value:K.domain,onChange:e=>Ii({...K,domain:e.target.value}),placeholder:`опционально`})]})]}),(0,S.jsx)(`div`,{className:`actions`,children:(0,S.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()}),Ii({...K,name:``,address:``,tags:``,username:``,password:``,domain:``})},`Сервер добавлен в справочник.`),children:`Добавить сервер`})}),(0,S.jsx)(M,{columns:[`сервер`,`адрес`,`протокол`,`секрет`,`организация`,`маршрут`,`создано`,`действия`],rows:sr.map(e=>{let t=e.metadata||{},n=rr.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,S.jsx)(`button`,{className:`ghost`,onClick:()=>{Ni(e),Fi({username:``,password:``,domain:``})},children:`Обновить secret`})]})}),Mi&&(0,S.jsx)(`div`,{className:`modalBackdrop`,role:`presentation`,children:(0,S.jsxs)(`div`,{className:`modalCard`,role:`dialog`,"aria-modal":`true`,"aria-labelledby":`resource-secret-title`,children:[(0,S.jsxs)(`div`,{className:`cardHead`,children:[(0,S.jsxs)(`div`,{children:[(0,S.jsx)(`h3`,{id:`resource-secret-title`,children:`Учетные данные RDP`}),(0,S.jsxs)(`p`,{className:`muted`,children:[Mi.name,` · `,Mi.address]})]}),(0,S.jsx)(`button`,{className:`ghost`,onClick:()=>Ni(null),children:`Закрыть`})]}),(0,S.jsxs)(Je,{children:[(0,S.jsxs)(`label`,{children:[`Пользователь`,(0,S.jsx)(`input`,{value:Pi.username,onChange:e=>Fi({...Pi,username:e.target.value}),placeholder:`user или DOMAIN\\\\user`})]}),(0,S.jsxs)(`label`,{children:[`Пароль`,(0,S.jsx)(`input`,{type:`password`,value:Pi.password,onChange:e=>Fi({...Pi,password:e.target.value})})]}),(0,S.jsxs)(`label`,{children:[`Домен`,(0,S.jsx)(`input`,{value:Pi.domain,onChange:e=>Fi({...Pi,domain:e.target.value}),placeholder:`опционально`})]})]}),(0,S.jsx)(`p`,{className:`muted`,children:`Пароль сохраняется как encrypted resource secret. В metadata ресурса он не попадет.`}),(0,S.jsxs)(`div`,{className:`actions`,children:[(0,S.jsx)(`button`,{className:`primary`,disabled:!Pi.username.trim()||!Pi.password,onClick:()=>void Y(async()=>{await q.upsertResourceSecret(Mi.id,{username:Pi.username.trim(),password:Pi.password,domain:Pi.domain.trim()}),Ni(null),Fi({username:``,password:``,domain:``})},`Secret ресурса обновлен.`),children:`Сохранить secret`}),(0,S.jsx)(`button`,{onClick:()=>Ni(null),children:`Отмена`})]})]})})]})}),w===`audit`&&(0,S.jsxs)(`section`,{className:`card`,children:[(0,S.jsx)(`h3`,{children:`Аудит кластера`}),(0,S.jsx)(M,{columns:[`событие`,`цель`,`actor`,`создано`],rows:dr.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 fe({label:e,value:t,tone:n}){return(0,S.jsxs)(`article`,{className:`metric ${n}`,children:[(0,S.jsx)(`span`,{children:e}),(0,S.jsx)(`strong`,{children:t})]})}function O({label:e,value:t}){return(0,S.jsxs)(`div`,{className:`signal`,children:[(0,S.jsx)(`span`,{children:e}),(0,S.jsx)(`strong`,{children:t})]})}function k({value:e}){return(0,S.jsx)(`span`,{className:`status ${e.replace(/_/g,`-`)}`,children:H(e)})}function pe({label:e,value:t,tone:n}){return(0,S.jsxs)(`span`,{className:`functionState ${n||``}`,children:[(0,S.jsx)(`small`,{children:e}),(0,S.jsx)(`strong`,{children:t})]})}function A({label:e,value:t}){return(0,S.jsxs)(`div`,{className:`stateLine`,children:[(0,S.jsx)(`span`,{children:e}),(0,S.jsx)(`strong`,{children:t})]})}function me({title:e,text:t}){return(0,S.jsxs)(`article`,{className:`empty`,children:[(0,S.jsx)(`h3`,{children:e}),(0,S.jsx)(`p`,{children:t})]})}function he(e){if(!e)return(0,S.jsx)(`p`,{className:`muted`,children:`Диагностика Android-клиента не загружена. Укажи device id из приложения и нажми “Обновить клиент”.`});let t=N(e.payload)||{},n=N(t.runtime),r=N(t.vpn_config),i=P(t,`app_version`,`н/д`),a=P(t,`service_state`,`н/д`),o=P(t,`control_network_mode`,`н/д`),s=P(r,`packet_relay_active_base_url`)||P(r,`packet_relay_base_url`,`н/д`),c=P(r,`packet_relay_profile_base_url`,`н/д`),l=P(r,`packet_relay_candidate_urls`,`н/д`),u=Tt(n,`uplink_read_total`),d=Tt(n,`uplink_sent_total`),f=Tt(n,`downlink_received_total`),p=Tt(n,`uplink_dropped_packets`)+Tt(n,`downlink_dropped_packets`),m=Tt(n,`uplink_bypassed_control_packets`),h=Tt(n,`downlink_received_bytes`),g=Tt(n,`uplink_sent_bytes`),_=P(n,`state`,`н/д`),v=P(n,`message`,``),y=Tt(n,`uplink_sent_mbps`),b=Tt(n,`downlink_received_mbps`),x=P(t,`last_command_type`,`н/д`),ee=P(t,`last_command_result`,`н/д`);return(0,S.jsxs)(`div`,{className:`vpnCard diagnosticCard`,children:[(0,S.jsxs)(`div`,{children:[(0,S.jsxs)(`strong`,{children:[`Android client `,B(e.device_id)]}),(0,S.jsxs)(`p`,{className:`muted`,children:[i,` / `,a,` / `,V(e.observed_at)]}),(0,S.jsx)(k,{value:Date.now()-new Date(e.observed_at).getTime()<3e4?`active`:`degraded`}),(0,S.jsx)(`span`,{className:`pill`,children:o})]}),(0,S.jsxs)(`div`,{className:`stateList`,children:[(0,S.jsx)(A,{label:`Relay active`,value:s}),(0,S.jsx)(A,{label:`Relay profile`,value:c}),(0,S.jsx)(A,{label:`Relay candidates`,value:l}),(0,S.jsx)(A,{label:`Packets read/sent/down`,value:`${u} / ${d} / ${f}`}),(0,S.jsx)(A,{label:`Drops / control bypass`,value:`${p} / ${m}`}),(0,S.jsx)(A,{label:`Bytes up/down`,value:`${zn(g)} / ${zn(h)}`}),(0,S.jsx)(A,{label:`Rate up/down`,value:`${y.toFixed(2)} / ${b.toFixed(2)} Mbps`}),(0,S.jsx)(A,{label:`Runtime`,value:v?`${_}: ${v}`:_}),(0,S.jsx)(A,{label:`Last command`,value:`${x}: ${ee}`})]})]})}function ge({items:e,emptyText:t}){if(e.length===0)return(0,S.jsx)(me,{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,S.jsxs)(`div`,{className:`telemetryBox`,children:[(0,S.jsxs)(`div`,{className:`signalStrip compact`,children:[(0,S.jsx)(O,{label:`Память`,value:`${zn(r.memory_used_bytes)} / ${zn(r.memory_total_bytes)}`}),(0,S.jsx)(O,{label:`Процессор`,value:r.cpu_percent==null?`н/д`:`${r.cpu_percent.toFixed(1)}%`}),(0,S.jsx)(O,{label:`Процессы`,value:r.process_count==null?`н/д`:String(r.process_count)}),(0,S.jsx)(O,{label:`Обновлено`,value:V(r.observed_at)})]}),(0,S.jsx)(`div`,{className:`sparkline`,"aria-label":`memory telemetry`,children:n.map(e=>(0,S.jsx)(`span`,{style:{height:`${Math.max(8,Math.round((e.memory_used_bytes||0)/i*100))}%`}},e.id))})]})}function _e({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=N(m?.metadata?.mesh_listener_report),v=N(m?.metadata?.mesh_endpoint_report),y=N(m?.metadata?.mesh_outbound_session_report),b=c?.mesh_listener,x=N(m?.metadata?.mesh_peer_recovery_report),ee=N(m?.metadata?.mesh_peer_connection_intent_report),C=N(m?.metadata?.mesh_peer_connection_manager_report),te=N(m?.metadata?.mesh_rendezvous_lease_report),ne=N(m?.metadata?.mesh_route_path_decision_report),re=N(m?.metadata?.mesh_route_generation_report),ie=N(m?.metadata?.mesh_route_health_config_report),w=c?.service_channel_route_feedback,ae=w?.observations||[],oe=c?.service_channel_remediation_commands||[],T=ht(s).filter(e=>e.source_node_id!==e.target_node_id),se=T.filter(e=>e.link_status===`reachable`),ce=T.filter(e=>e.link_status!==`reachable`),le=Object.entries(m?.capabilities||{}).sort(([e],[t])=>e.localeCompare(t)),E=St(C?.probe_results),[D,ue]=(0,_.useState)(`network`),de=nt(f,`rap-node-agent`),fe=nt(f,`rap-host-agent`),pe=f[0],me=ft(f),he=t.find(t=>t.node.id===e.id)?.cluster.id||t[0]?.cluster.id||``,_e=St(v?.endpoint_candidates),ye=_e[0],be=Ct(v,[`peer_endpoint`,`advertised_endpoint`,`endpoint`])||P(ye,`address`,``)||``,xe=Ct(v,[`transport`,`advertise_transport`])||P(ye,`transport`,``)||`н/д`,Se=Ct(v,[`connectivity_mode`,`connectivity`])||P(ye,`connectivity_mode`,``)||P(g,`inbound_reachability`,``)||`н/д`,Ce=P(v,`nat_type`,P(ye,`nat_type`,`н/д`)),we=P(v,`region`,P(g,`region`,P(ye,`region`,`н/д`))),Te=P(v,`observed_at`,P(g,`observed_at`,m?.observed_at||`н/д`)),j=P(g,`status`,``)||(be?`нет listener report, есть advertised endpoint`:`report отсутствует`),Ee=P(g,`effective_listen_addr`,``)||`н/д`,De=P(g,`configured_listen_addr`,``)||`н/д`,Oe=_e.length>0?_e:be?[{endpoint_id:`${e.id}-reported`,address:be,transport:xe,reachability:Se,connectivity_mode:Se,nat_type:Ce,priority:`н/д`,last_verified_at:Te}]:[],ke=Object.entries(c?.peer_endpoints||{}),Ae=Object.entries(c?.peer_endpoint_candidates||{}).flatMap(([e,t])=>t.map(t=>({peerID:e,candidate:t}))),je=new Set(se.map(t=>t.source_node_id===e.id?t.target_node_id:t.source_node_id)),Me=Ae.filter(({peerID:e})=>!je.has(e)),Ne=[g?`listener report: есть`:`listener report: не прислан агентом`,v?`endpoint report: есть`:`endpoint report: не прислан агентом`,y?`outbound session: есть`:`outbound session: не прислан агентом`,c?`scoped config: ${c.enabled?`enabled`:`disabled`}`:`scoped config: не загружен`,w?`service-channel feedback: ${w.observation_count}`:`service-channel feedback: не загружен`,`active links: ${se.length}/${T.length}`];return(0,S.jsxs)(`div`,{className:`nodeDetails`,children:[(0,S.jsxs)(`section`,{className:`nodePanel`,children:[(0,S.jsx)(`h4`,{children:`Сводка runtime`}),(0,S.jsxs)(`div`,{className:`signalStrip compact nodeMetricGrid`,children:[(0,S.jsx)(O,{label:`Heartbeat`,value:m?V(m.observed_at):`н/д`}),(0,S.jsx)(O,{label:`Health`,value:H(m?.health_status||e.health_status)}),(0,S.jsx)(O,{label:`Listener`,value:jn(m)}),(0,S.jsx)(O,{label:`Mesh links`,value:`${se.length}/${T.length}`}),(0,S.jsx)(O,{label:`Web ingress`,value:Pe(m)}),(0,S.jsx)(O,{label:`Update`,value:rt(pe,d)})]}),(0,S.jsxs)(`div`,{className:`summaryChips`,children:[(0,S.jsx)(k,{value:e.registration_status}),(0,S.jsx)(k,{value:e.membership_status}),(0,S.jsx)(k,{value:e.partition_state}),(0,S.jsx)(`span`,{className:`pill`,children:e.reported_version||m?.reported_version||`версия неизвестна`}),g?.one_way_connectivity===!0&&(0,S.jsx)(`span`,{className:`pill warn`,children:`one-way`}),g?.port_conflict===!0&&(0,S.jsx)(`span`,{className:`pill bad`,children:`port conflict`})]})]}),(0,S.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,S.jsx)(`button`,{className:D===e?`active`:``,onClick:()=>ue(e),type:`button`,children:t},e))}),D===`overview`&&(0,S.jsxs)(`div`,{className:`nodeDetailGrid`,children:[(0,S.jsxs)(`section`,{className:`nodePanel`,children:[(0,S.jsx)(`h4`,{children:`Идентичность и размещение`}),(0,S.jsxs)(`div`,{className:`stateList`,children:[(0,S.jsx)(A,{label:`Node ID`,value:e.id}),(0,S.jsx)(A,{label:`Node key`,value:e.node_key}),(0,S.jsx)(A,{label:`Имя`,value:e.name}),(0,S.jsx)(A,{label:`Владение`,value:H(e.ownership_type)}),(0,S.jsx)(A,{label:`Owner org`,value:B(e.owner_organization_id)}),(0,S.jsx)(A,{label:`Группа`,value:e.node_group_name||p.ungroupedNodes}),(0,S.jsx)(A,{label:`Создан`,value:V(e.created_at)}),(0,S.jsx)(A,{label:`Обновлен`,value:V(e.updated_at)})]})]}),(0,S.jsxs)(`section`,{className:`nodePanel`,children:[(0,S.jsx)(`h4`,{children:`Участие в кластерах`}),(0,S.jsx)(`div`,{className:`membershipList`,children:t.map(t=>(0,S.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,S.jsxs)(`div`,{className:`stateList`,children:[(0,S.jsx)(A,{label:`Активных ролей`,value:String(n.length)}),(0,S.jsx)(A,{label:`Desired workloads`,value:String(r.length)}),(0,S.jsx)(A,{label:`Observed workloads`,value:String(i.length)}),(0,S.jsx)(A,{label:`Последний сигнал`,value:V(e.last_seen_at||m?.observed_at)})]})]})]}),D===`network`&&(0,S.jsxs)(S.Fragment,{children:[(0,S.jsxs)(`div`,{className:`nodeDetailGrid`,children:[(0,S.jsxs)(`section`,{className:`nodePanel`,children:[(0,S.jsx)(`h4`,{children:`Локальный listener`}),(0,S.jsxs)(`div`,{className:`stateList`,children:[(0,S.jsx)(A,{label:`Статус`,value:j}),(0,S.jsx)(A,{label:`Режим порта`,value:P(g,`listen_port_mode`,`н/д`)}),(0,S.jsx)(A,{label:`Configured addr`,value:De}),(0,S.jsx)(A,{label:`Effective addr`,value:Ee}),(0,S.jsx)(A,{label:`Inbound`,value:P(g,`inbound_reachability`,Se)}),(0,S.jsx)(A,{label:`One-way`,value:P(g,`one_way_connectivity`,`н/д`)}),(0,S.jsx)(A,{label:`Port conflict`,value:P(g,`port_conflict`,`false`)}),(0,S.jsx)(A,{label:`Failure`,value:P(g,`failure_error`,P(g,`failure_reason`,`нет`))})]})]}),(0,S.jsxs)(`section`,{className:`nodePanel`,children:[(0,S.jsx)(`h4`,{children:`Desired listener`}),(0,S.jsxs)(`div`,{className:`stateList`,children:[(0,S.jsx)(A,{label:`Состояние`,value:b?.desired_state||`н/д`}),(0,S.jsx)(A,{label:`Режим порта`,value:b?.listen_port_mode||`н/д`}),(0,S.jsx)(A,{label:`Listen addr`,value:b?.listen_addr||`н/д`}),(0,S.jsx)(A,{label:`Auto range`,value:b?`${b.auto_port_start||`н/д`}-${b.auto_port_end||`н/д`}`:`н/д`}),(0,S.jsx)(A,{label:`Advertise endpoint`,value:b?.advertise_endpoint||`auto-discovery`}),(0,S.jsx)(A,{label:`Advertise transport`,value:b?.advertise_transport||`н/д`}),(0,S.jsx)(A,{label:`Connectivity`,value:b?.connectivity_mode||`н/д`}),(0,S.jsx)(A,{label:`NAT`,value:b?.nat_type||`н/д`}),(0,S.jsx)(A,{label:`Region/site`,value:b?.region||`н/д`}),(0,S.jsx)(A,{label:`Version`,value:b?.config_version||`н/д`})]})]}),(0,S.jsxs)(`section`,{className:`nodePanel`,children:[(0,S.jsx)(`h4`,{children:`Что узел сообщает кластеру`}),(0,S.jsxs)(`div`,{className:`stateList`,children:[(0,S.jsx)(A,{label:`Advertised endpoint`,value:be||`не прислан`}),(0,S.jsx)(A,{label:`Transport`,value:xe}),(0,S.jsx)(A,{label:`Connectivity`,value:Se}),(0,S.jsx)(A,{label:`NAT`,value:Ce}),(0,S.jsx)(A,{label:`Region/site`,value:we}),(0,S.jsx)(A,{label:`Observed`,value:Te})]})]})]}),(0,S.jsxs)(`section`,{className:`nodePanel`,children:[(0,S.jsx)(`h4`,{children:`Исходящий control-channel`}),(0,S.jsxs)(`div`,{className:`stateList`,children:[(0,S.jsx)(A,{label:`Status`,value:P(y,`status`,`не прислан`)}),(0,S.jsx)(A,{label:`Direction`,value:P(y,`direction`,`н/д`)}),(0,S.jsx)(A,{label:`Transport`,value:P(y,`transport`,`н/д`)}),(0,S.jsx)(A,{label:`Control Plane`,value:P(y,`control_plane_url`,`н/д`)}),(0,S.jsx)(A,{label:`Reverse usable`,value:P(y,`usable_for_inbound_control`,`н/д`)}),(0,S.jsx)(A,{label:`Inbound required`,value:P(y,`inbound_listener_required`,`н/д`)}),(0,S.jsx)(A,{label:`Relay ready`,value:P(y,`peer_connection_relay_ready`,`0`)}),(0,S.jsx)(A,{label:`Waiting rendezvous`,value:P(y,`peer_connection_waiting`,`0`)}),(0,S.jsx)(A,{label:`Rendezvous leases`,value:P(y,`rendezvous_lease_count`,`0`)}),(0,S.jsx)(A,{label:`Listener conflict`,value:P(y,`listener_port_conflict`,`false`)})]})]}),(0,S.jsxs)(`section`,{className:`nodePanel`,children:[(0,S.jsx)(`h4`,{children:`Наличие сетевых отчетов`}),(0,S.jsx)(`div`,{className:`summaryChips`,children:Ne.map(e=>(0,S.jsx)(`span`,{className:e.includes(`не прислан`)||e.includes(`не загружен`)?`pill warn`:`pill good`,children:e},e))}),!v&&!g&&(0,S.jsx)(`p`,{className:`muted`,children:`У этого узла есть heartbeat/mesh manager данные, но агент не передал адресный отчет. До обновления агента или включения endpoint/listener report панель может показать связи и config peers, но не может достоверно назвать локальный listen address.`})]}),(0,S.jsxs)(`section`,{className:`nodePanel`,children:[(0,S.jsx)(`h4`,{children:`Endpoint candidates узла`}),(0,S.jsx)(M,{columns:[`id`,`address`,`transport`,`reachability`,`mode`,`nat`,`priority`,`verified`],rows:Oe.map(e=>[P(e,`endpoint_id`,`н/д`),P(e,`address`,`н/д`),P(e,`transport`,`н/д`),P(e,`reachability`,`н/д`),P(e,`connectivity_mode`,`н/д`),P(e,`nat_type`,`н/д`),P(e,`priority`,`н/д`),P(e,`last_verified_at`,`н/д`)])})]}),(0,S.jsxs)(`div`,{className:`nodeDetailGrid`,children:[(0,S.jsxs)(`section`,{className:`nodePanel`,children:[(0,S.jsx)(`h4`,{children:`Рабочие peer endpoints из config`}),(0,S.jsx)(M,{columns:[`peer`,`endpoint`],rows:ke.map(([e,t])=>[F(l,e),t])})]}),(0,S.jsxs)(`section`,{className:`nodePanel`,children:[(0,S.jsx)(`h4`,{children:`Резервные кандидаты peer`}),(0,S.jsx)(M,{columns:[`peer`,`address`,`transport`,`reachability`,`mode`,`priority`],rows:Me.slice(0,20).map(({peerID:e,candidate:t})=>[F(l,e),t.address,t.transport,t.reachability,t.connectivity_mode,String(t.priority)])})]})]}),(0,S.jsxs)(`section`,{className:`nodePanel`,children:[(0,S.jsx)(`h4`,{children:`Активные связи этого узла`}),(0,S.jsx)(M,{columns:[`peer`,`направление`,`тип`,`статус`,`latency`,`quality`,`путь`,`наблюдение`],rows:T.slice(0,20).map(t=>[F(l,t.source_node_id===e.id?t.target_node_id:t.source_node_id),t.source_node_id===e.id?`out`:`in`,_t(t),t.link_status,t.latency_ms==null?`н/д`:`${t.latency_ms}мс`,t.quality_score==null?`н/д`:String(t.quality_score),vt(t,l),V(t.observed_at)])}),ce.length>0&&(0,S.jsxs)(`p`,{className:`muted`,children:[`Проблемных связей: `,ce.length,`. Их статус виден в таблице выше.`]})]}),(0,S.jsxs)(`section`,{className:`nodePanel`,children:[(0,S.jsx)(`h4`,{children:`Проверка адресов peer-to-peer`}),(0,S.jsx)(M,{columns:[`peer`,`status`,`selected endpoint`,`candidate`,`latency`,`attempts`,`failure`],rows:E.slice(0,20).map(e=>[F(l,P(e,`node_id`,``)),P(e,`link_status`,`н/д`),P(e,`selected_endpoint`,P(e,`endpoint`,`н/д`)),P(e,`selected_candidate_id`,`н/д`),P(e,`latency_ms`,`н/д`),Dt(e),P(e,`failure_reason`,`нет`)])})]})]}),D===`mesh`&&(0,S.jsxs)(S.Fragment,{children:[(0,S.jsxs)(`div`,{className:`nodeDetailGrid`,children:[(0,S.jsxs)(`section`,{className:`nodePanel`,children:[(0,S.jsx)(`h4`,{children:`Mesh control-plane`}),(0,S.jsxs)(`div`,{className:`stateList`,children:[(0,S.jsx)(A,{label:`Recovery`,value:wn(m)}),(0,S.jsx)(A,{label:`Intents`,value:Tn(m)}),(0,S.jsx)(A,{label:`Manager`,value:An(m)}),(0,S.jsx)(A,{label:`Rendezvous`,value:En(m)}),(0,S.jsx)(A,{label:`Path decisions`,value:Dn(m)}),(0,S.jsx)(A,{label:`Route generation`,value:On(m)}),(0,S.jsx)(A,{label:`Route health`,value:kn(m)}),(0,S.jsx)(A,{label:`Service-channel feedback`,value:w?`${w.healthy_route_count} healthy / ${w.degraded_route_count} degraded / ${w.fenced_route_count} fenced`:`н/д`}),(0,S.jsx)(A,{label:`Recovery policy`,value:w?.recovery_policy?`${w.recovery_policy.source} p${w.recovery_policy.hysteresis_penalty} promote ${w.recovery_policy.promotion_min_samples}`:`н/д`}),(0,S.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,S.jsx)(A,{label:`Config version`,value:c?.config_version||`н/д`})]})]}),(0,S.jsxs)(`section`,{className:`nodePanel`,children:[(0,S.jsx)(`h4`,{children:`Scoped config counts`}),(0,S.jsxs)(`div`,{className:`stateList`,children:[(0,S.jsx)(A,{label:`Peer endpoints`,value:String(ke.length)}),(0,S.jsx)(A,{label:`Endpoint candidates`,value:String(Ae.length)}),(0,S.jsx)(A,{label:`Peer directory`,value:String(c?.peer_directory?.length||0)}),(0,S.jsx)(A,{label:`Recovery seeds`,value:String(c?.recovery_seeds?.length||0)}),(0,S.jsx)(A,{label:`Rendezvous leases`,value:String(c?.rendezvous_leases?.length||0)}),(0,S.jsx)(A,{label:`Routes`,value:String(c?.routes?.length||0)}),(0,S.jsx)(A,{label:`Fenced routes`,value:String(w?.fenced_route_count||0)}),(0,S.jsx)(A,{label:`Remediation commands`,value:String(oe.length)}),(0,S.jsx)(A,{label:`Feedback provenance`,value:w?`missing ${w.missing_provenance_count||0} / stale policy ${w.stale_policy_count||0} / stale gen ${w.stale_generation_count||0}`:`н/д`})]})]})]}),(0,S.jsxs)(`section`,{className:`nodePanel`,children:[(0,S.jsx)(`h4`,{children:`Route decisions`}),(0,S.jsx)(M,{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):`нет`,F(l,e.source_node_id),F(l,e.destination_node_id),e.effective_hops.map(e=>Pn(F(l,e))).join(` > `),e.decision_source||(e.selected_relay_id?F(l,e.selected_relay_id):`direct`),e.path_score==null?`н/д`:String(e.path_score),V(e.expires_at)])})]}),oe.length>0&&(0,S.jsxs)(`section`,{className:`nodePanel`,children:[(0,S.jsx)(`h4`,{children:`Service-channel remediation commands`}),(0,S.jsx)(M,{columns:[`channel`,`action`,`primary`,`replacement`,`guard`,`execution`,`reason`,`expires`],rows:oe.slice(0,20).map(e=>[B(e?.channel_id||``),(0,S.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,S.jsx)(`span`,{className:`pill ${e?.guard_status===`rejected`?`bad`:e?.guard_status===`allowed`?`good`:``}`,children:e?.guard_status?H(e.guard_status):`н/д`}),(0,S.jsxs)(`span`,{className:`pill ${Un(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,S.jsxs)(`section`,{className:`nodePanel`,children:[(0,S.jsx)(`h4`,{children:`Service-channel route feedback`}),(0,S.jsx)(M,{columns:[`route`,`service`,`status`,`recovery`,`score`,`reasons`,`failures`,`duration`,`expires`],rows:ae.slice(0,40).map(e=>[B(e.route_id),e.service_class,(0,S.jsx)(`span`,{className:`pill ${st(e.feedback_status)}`,children:H(e.feedback_status)}),e.recovery_state?(0,S.jsxs)(`span`,{className:`pill ${ct(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,S.jsx)(`span`,{className:`pill warn`,children:H(e.stale_reason||`stale`)}):e.provenance_missing?(0,S.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)])}),ae.length===0&&(0,S.jsx)(`p`,{className:`muted`,children:`Пока нет свежих наблюдений. Узел будет присылать их после реального traffic через service-channel runtime.`})]})]}),D===`services`&&(0,S.jsxs)(S.Fragment,{children:[(0,S.jsxs)(`div`,{className:`nodeDetailGrid`,children:[(0,S.jsxs)(`section`,{className:`nodePanel`,children:[(0,S.jsx)(`h4`,{children:p.nodeRoles}),(0,S.jsxs)(`div`,{className:`serviceTags`,children:[n.length===0&&(0,S.jsx)(`p`,{className:`muted`,children:p.noRoles}),n.map(e=>(0,S.jsxs)(`div`,{className:`serviceTag`,children:[(0,S.jsx)(`strong`,{children:$e(e.role)}),(0,S.jsx)(`span`,{children:e.organization_id?`organization: ${B(e.organization_id)}`:`cluster-wide`}),(0,S.jsx)(`small`,{children:V(e.assigned_at)}),(0,S.jsx)(`span`,{className:`pill ${xn(e.role,m)}`,children:Sn(e.role,m,p)})]},e.id))]})]}),(0,S.jsxs)(`section`,{className:`nodePanel`,children:[(0,S.jsx)(`h4`,{children:`Capabilities`}),(0,S.jsxs)(`div`,{className:`summaryChips`,children:[le.length===0&&(0,S.jsx)(`span`,{className:`muted`,children:`Нет capability heartbeat.`}),le.slice(0,40).map(([e,t])=>(0,S.jsx)(`span`,{className:t===!0?`pill good`:`pill`,children:e},e))]})]})]}),(0,S.jsxs)(`div`,{className:`nodeDetailGrid`,children:[(0,S.jsxs)(`section`,{className:`nodePanel`,children:[(0,S.jsx)(`h4`,{children:p.desiredServices}),(0,S.jsx)(M,{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,S.jsxs)(`section`,{className:`nodePanel`,children:[(0,S.jsx)(`h4`,{children:p.observedServices}),(0,S.jsx)(M,{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)])})]})]})]}),D===`telemetry`&&(0,S.jsxs)(S.Fragment,{children:[(0,S.jsxs)(`section`,{className:`nodePanel`,children:[(0,S.jsx)(`h4`,{children:p.nodeTelemetry}),(0,S.jsx)(ge,{items:o,emptyText:p.noTelemetry}),(0,S.jsxs)(`div`,{className:`stateList`,children:[(0,S.jsx)(A,{label:`Disk`,value:`${zn(h?.disk_used_bytes)} / ${zn(h?.disk_total_bytes)}`}),(0,S.jsx)(A,{label:`Network RX/TX`,value:`${zn(h?.network_rx_bytes)} / ${zn(h?.network_tx_bytes)}`}),(0,S.jsx)(A,{label:`Payload`,value:h?.payload?Et(h.payload):`н/д`})]})]}),(0,S.jsxs)(`section`,{className:`nodePanel`,children:[(0,S.jsx)(`h4`,{children:p.recentHeartbeats}),(0,S.jsx)(M,{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||`неизвестно`,jn(e),wn(e),Tn(e),En(e),Dn(e),On(e),kn(e),V(e.observed_at)])})]})]}),D===`updates`&&(0,S.jsxs)(S.Fragment,{children:[(0,S.jsxs)(`div`,{className:`nodeDetailGrid`,children:[(0,S.jsxs)(`section`,{className:`nodePanel`,children:[(0,S.jsx)(`h4`,{children:`Текущая сборка`}),(0,S.jsxs)(`div`,{className:`stateList`,children:[(0,S.jsx)(A,{label:`Node-agent version`,value:e.reported_version||m?.reported_version||`неизвестно`}),(0,S.jsx)(A,{label:`План`,value:d?`${d.action}: ${d.reason}`:`не загружен`}),(0,S.jsx)(A,{label:`Product`,value:d?.product||`rap-node-agent`}),(0,S.jsx)(A,{label:`Target`,value:d?.target_version||`н/д`}),(0,S.jsx)(A,{label:`Strategy`,value:d?.strategy||`н/д`}),(0,S.jsx)(A,{label:`Rollback`,value:d?.rollback_allowed?`разрешен`:`нет`}),(0,S.jsx)(A,{label:`Artifact`,value:d?.artifact?`${d.artifact.kind} ${d.artifact.os}/${d.artifact.arch}`:`н/д`})]}),(0,S.jsxs)(`div`,{className:`actions`,children:[(0,S.jsx)(`button`,{className:`primary`,disabled:!u,onClick:()=>u?.(e,`rap-node-agent`,null),children:`Node-agent latest`}),(0,S.jsx)(`button`,{className:`ghost`,disabled:!u||!d?.target_version,onClick:()=>u?.(e,`rap-node-agent`,d?.target_version||null),children:`Повторить target`}),(0,S.jsx)(`button`,{className:`ghost`,disabled:!u,onClick:()=>u?.(e,`rap-host-agent`,null),children:`Host-agent latest`})]}),(0,S.jsx)(`p`,{className:`muted`,children:`Latest означает policy без закрепленной версии: updater будет брать свежий active release своего канала при следующем цикле или heartbeat hint.`})]}),(0,S.jsxs)(`section`,{className:`nodePanel`,children:[(0,S.jsx)(`h4`,{children:`Последние отчеты updater`}),(0,S.jsxs)(`div`,{className:`stateList`,children:[(0,S.jsx)(A,{label:`Updater health`,value:`${me.label}: ${me.detail}`}),(0,S.jsx)(A,{label:`rap-node-agent`,value:it(de)}),(0,S.jsx)(A,{label:`rap-host-agent`,value:it(fe)}),(0,S.jsx)(A,{label:`Всего отчетов`,value:String(f.length)}),(0,S.jsx)(A,{label:`Последний отчет`,value:V(pe?.observed_at)})]}),(0,S.jsxs)(`div`,{className:`summaryChips`,children:[(0,S.jsx)(`span`,{className:`pill ${me.tone}`,children:me.label}),de&&(0,S.jsxs)(`span`,{className:`pill ${ot(de)}`,children:[`node-agent: `,de.status]}),fe&&(0,S.jsxs)(`span`,{className:`pill ${ot(fe)}`,children:[`host-agent: `,fe.status]}),!de&&!fe&&(0,S.jsx)(`span`,{className:`pill warn`,children:`updater пока не отчитался`})]})]})]}),(0,S.jsxs)(`section`,{className:`nodePanel`,children:[(0,S.jsx)(`h4`,{children:`История обновлений`}),(0,S.jsx)(M,{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,S.jsx)(`span`,{className:`pill ${ot(e)}`,children:e.status}),e.attempt_id?B(e.attempt_id):`н/д`,e.error_message||`нет`,V(e.observed_at)])})]}),(0,S.jsxs)(`section`,{className:`nodePanel`,children:[(0,S.jsx)(`h4`,{children:`Windows repair/update command`}),(0,S.jsx)(`p`,{className:`muted`,children:`Для существующего Windows-узла эта команда переустанавливает wrapper updater без нового join-token, сохраняет local state и запускает обновление до актуальной сборки.`}),(0,S.jsxs)(`div`,{className:`stateList compact`,children:[(0,S.jsx)(A,{label:`Когда выполнять`,value:`если updater stale, host-agent не отчитался или Windows-узел не доходит до target version`}),(0,S.jsx)(A,{label:`Control Plane`,value:un()}),(0,S.jsx)(A,{label:`Join-token`,value:`не нужен для repair существующего узла`})]}),(0,S.jsxs)(`div`,{className:`actions`,children:[(0,S.jsx)(`button`,{className:`primary`,onClick:()=>nn($t(e),Qt(e,he)),children:`Скачать repair .cmd`}),(0,S.jsx)(`button`,{className:`ghost`,onClick:()=>void rn(Qt(e,he)),children:`Скопировать команду`})]}),(0,S.jsx)(`pre`,{className:`codePreview`,children:Qt(e,he)})]}),(0,S.jsxs)(`section`,{className:`nodePanel`,children:[(0,S.jsx)(`h4`,{children:`Linux repair/update command`}),(0,S.jsx)(`p`,{className:`muted`,children:`Для существующего Ubuntu/Linux-узла эта команда восстанавливает systemd updater без нового join-token, сохраняет local state и делает одноразовую проверку обновления.`}),(0,S.jsxs)(`div`,{className:`stateList compact`,children:[(0,S.jsx)(A,{label:`Когда выполнять`,value:`если host-agent не отчитался, updater stale или Linux-узел не доходит до target version`}),(0,S.jsx)(A,{label:`Control Plane`,value:un()}),(0,S.jsx)(A,{label:`Join-token`,value:`не нужен для repair существующего узла`})]}),(0,S.jsxs)(`div`,{className:`actions`,children:[(0,S.jsx)(`button`,{className:`primary`,onClick:()=>nn(tn(e),en(e,he)),children:`Скачать repair .sh`}),(0,S.jsx)(`button`,{className:`ghost`,onClick:()=>void rn(en(e,he)),children:`Скопировать команду`})]}),(0,S.jsx)(`pre`,{className:`codePreview`,children:en(e,he)})]}),(0,S.jsxs)(`section`,{className:`nodePanel`,children:[(0,S.jsx)(`h4`,{children:`Payload последнего отчета`}),(0,S.jsxs)(`div`,{className:`rawDetailsGrid`,children:[(0,S.jsx)(ve,{title:`rap-node-agent update status`,value:de}),(0,S.jsx)(ve,{title:`rap-host-agent update status`,value:fe}),(0,S.jsx)(ve,{title:`Update plan`,value:d})]})]})]}),D===`raw`&&(0,S.jsxs)(`section`,{className:`nodePanel`,children:[(0,S.jsx)(`h4`,{children:`Raw данные узла`}),(0,S.jsxs)(`div`,{className:`rawDetailsGrid`,children:[(0,S.jsx)(ve,{title:`Последний heartbeat metadata`,value:m?.metadata}),(0,S.jsx)(ve,{title:`Heartbeat capabilities`,value:m?.capabilities}),(0,S.jsx)(ve,{title:`Heartbeat service states`,value:m?.service_states}),(0,S.jsx)(ve,{title:`Synthetic mesh config`,value:c}),(0,S.jsx)(ve,{title:`Listener report`,value:g}),(0,S.jsx)(ve,{title:`Endpoint report`,value:v}),(0,S.jsx)(ve,{title:`Peer recovery report`,value:x}),(0,S.jsx)(ve,{title:`Connection intent report`,value:ee}),(0,S.jsx)(ve,{title:`Connection manager report`,value:C}),(0,S.jsx)(ve,{title:`Rendezvous lease report`,value:te}),(0,S.jsx)(ve,{title:`Route decision report`,value:ne}),(0,S.jsx)(ve,{title:`Route generation report`,value:re}),(0,S.jsx)(ve,{title:`Route health report`,value:ie})]})]})]})}function ve({title:e,value:t}){return(0,S.jsxs)(`details`,{className:`rawBlock`,children:[(0,S.jsx)(`summary`,{children:e}),(0,S.jsx)(`pre`,{children:t==null?`н/д`:JSON.stringify(t,null,2)})]})}function ye({runtime:e}){return(0,S.jsxs)(`div`,{className:`runtimeBadges`,children:[(0,S.jsx)(`span`,{className:`pill ${e.agentTone}`,children:e.agentLabel}),(0,S.jsx)(`span`,{className:`pill ${e.clientTone}`,children:e.clientLabel}),(0,S.jsx)(`span`,{className:`pill ${e.outboundTone}`,children:e.outboundLabel}),(0,S.jsx)(`span`,{className:`pill ${e.inboundTone}`,children:e.inboundLabel})]})}function be({node:e,fallback:t,heartbeatsByNode:n,meshLinks:r}){if(!e)return t;let i=wt(e,n[e.id]||[],r);return(0,S.jsxs)(`div`,{className:`nodeEndpointCell`,children:[(0,S.jsx)(`strong`,{children:e.name}),(0,S.jsx)(ye,{runtime:i}),(0,S.jsx)(`small`,{children:i.address})]})}function xe({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,S.jsx)(me,{title:`Нет узлов`,text:`Одобренные node-agent появятся на карте после первого heartbeat.`});let l=ht(t).filter(e=>e.source_node_id!==e.target_node_id),u=new Map(e.map(e=>[e.id,e])),d=l.filter(e=>Ae(e)&&!Re(e,u)).map(e=>({link:e,status:ke(e,l,u),kind:`direct`})).filter(e=>e.status===`reachable`||e.status===`one_way`),f=l.filter(e=>je(e)&&!Re(e,u)).map(e=>({link:e,status:ke(e,l,u),kind:`relay`})).filter(e=>e.status===`reachable`||e.status===`one_way`),p=l.filter(e=>bt(e,`observation_type`)===`synthetic_route_health`&&!Re(e,u)&&e.link_status===`reachable`).map(e=>({link:e,status:`reachable`,kind:`route`})),m=Se(d,f,p),h=l.filter(e=>Re(e,u)),g=l.filter(e=>!Re(e,u)&&e.link_status!==`reachable`),v=Me(m.map(e=>e.link)),y=new Map(e.map(e=>[e.id,Ne(n[e.id]?.[0])])),b=[...y.values()].filter(e=>e.mode===`active`).length,x=[...y.values()].filter(e=>e.mode===`passive`).length,ee=[...y.values()].filter(e=>e.mode===`mixed`).length,C=ze(e.length),te=Be(e.length),ne=He(e,C.height,te),re=new Map(e.map(e=>[e.id,Ce(e.id,m)]));return(0,S.jsxs)(`div`,{className:`topologyShell`,children:[(0,S.jsxs)(`svg`,{className:`topologySvg`,viewBox:`0 0 ${C.width} ${C.height}`,role:`img`,"aria-label":`Карта трафика узлов Fabric`,children:[(0,S.jsx)(`defs`,{children:(0,S.jsx)(`marker`,{id:`arrow`,markerHeight:`8`,markerWidth:`8`,orient:`auto`,refX:`7`,refY:`4`,children:(0,S.jsx)(`path`,{d:`M0,0 L8,4 L0,8 Z`,fill:`currentColor`})})}),m.map(({link:t,status:n,kind:r})=>{let i=ne.get(t.source_node_id),a=ne.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=Ke(t.source_node_id,t.target_node_id,r),l=qe({source:i,target:a,sourceNodeID:t.source_node_id,targetNodeID:t.target_node_id,positions:ne,nodeRadius:te,endpointOffset:te+8,laneOffset:o?9:0,laneSign:s,routeKind:r}),u=Te(De(t,e,n)),d=j(l.labelX,l.labelY,C.width,C.height);return(0,S.jsxs)(`g`,{className:`topologyLinkGroup`,onMouseEnter:()=>c({...u,...d}),onMouseLeave:()=>c(null),children:[(0,S.jsx)(`title`,{children:[u.title,...u.lines].join(` `)}),(0,S.jsx)(`path`,{d:l.d,className:`topologyLink ${Nn(t,n)} ${r}`,markerEnd:`url(#arrow)`}),m.length<=Math.max(6,e.length)&&(0,S.jsx)(`text`,{x:l.labelX,y:l.labelY-8,className:`topologyLinkLabel`,children:Oe(t,n,r)})]},`${r}-${t.id||`${t.source_node_id}-${t.target_node_id}`}`)}),e.map(t=>{let a=ne.get(t.id),o=Ve(e.length),s=re.get(t.id)||`isolated`,l=y.get(t.id)||{mode:`unknown`,detail:`no heartbeat`},u=Fe(n[t.id]?.[0]),d=Te(Ee(t,l,s,u,n[t.id]?.[0],r[t.id]||[],i[t.id]||[])),f=j(a.x,a.y+te+12,C.width,C.height);return(0,S.jsxs)(`g`,{className:`topologyNode`,onMouseEnter:()=>c({...d,...f}),onMouseLeave:()=>c(null),children:[(0,S.jsx)(`title`,{children:[d.title,...d.lines].join(` `)}),(0,S.jsx)(`circle`,{cx:a.x,cy:a.y,r:te,className:`topologyNodeCircle ${t.health_status} ${l.mode} web-${u}`}),(0,S.jsx)(`text`,{x:a.x,y:a.y-o.nameOffset,className:`topologyNodeName`,style:{fontSize:o.name},children:Pn(t.name,o.maxChars)}),(0,S.jsx)(`text`,{x:a.x,y:a.y+o.metaOffset,className:`topologyNodeMeta`,style:{fontSize:o.meta},children:we(l.mode,s)})]},t.id)}),m.length===0&&(0,S.jsx)(`text`,{x:C.width/2,y:C.height-34,className:`topologyEmpty`,children:o}),s&&(0,S.jsx)(`foreignObject`,{x:s.x,y:s.y,width:`360`,height:`190`,className:`topologyTooltipObject`,children:(0,S.jsxs)(`div`,{className:`topologyTooltip`,children:[(0,S.jsx)(`strong`,{children:s.title}),s.lines.slice(0,6).map(e=>(0,S.jsx)(`span`,{children:e},e))]})})]}),(0,S.jsxs)(`div`,{className:`topologyLegend`,children:[(0,S.jsxs)(`span`,{children:[(0,S.jsx)(`i`,{className:`legendLine observed`}),` direct: `,d.length]}),(0,S.jsxs)(`span`,{children:[(0,S.jsx)(`i`,{className:`legendLine relay`}),` relay: `,f.length]}),(0,S.jsxs)(`span`,{children:[(0,S.jsx)(`i`,{className:`legendLine route`}),` route-health: `,p.length]}),(0,S.jsxs)(`span`,{children:[(0,S.jsx)(`i`,{className:`legendLine observed`}),` bidirectional pairs: `,v]}),(0,S.jsxs)(`span`,{children:[(0,S.jsx)(`i`,{className:`legendLine stale`}),` stale/problem: `,h.length,`/`,g.length]}),(0,S.jsxs)(`span`,{children:[(0,S.jsx)(`i`,{className:`legendDot webReady`}),` web ready`]}),(0,S.jsxs)(`span`,{children:[(0,S.jsx)(`i`,{className:`legendDot webDegraded`}),` web degraded`]}),(0,S.jsxs)(`span`,{children:[(0,S.jsx)(`i`,{className:`legendDot webBlocked`}),` web blocked`]}),(0,S.jsxs)(`span`,{children:[`active/passive/mixed: `,b,`/`,x,`/`,ee]})]}),(0,S.jsxs)(`details`,{className:`sectionBlock fabricNodeDiagnostics`,children:[(0,S.jsxs)(`summary`,{children:[`Диагностика узлов (`,e.length,`)`]}),(0,S.jsx)(`div`,{className:`serviceTags`,children:e.map(e=>(0,S.jsxs)(`div`,{className:`serviceTag`,children:[(0,S.jsx)(`strong`,{children:e.name}),(0,S.jsxs)(`span`,{children:[H(e.health_status),` / `,H(y.get(e.id)?.mode||`unknown`),` / mesh `,H(re.get(e.id)||`isolated`)]}),(0,S.jsx)(`small`,{children:Pe(n[e.id]?.[0])}),(0,S.jsx)(`small`,{children:Ze(r[e.id]||[])}),(0,S.jsx)(`small`,{children:et(i[e.id]||[])})]},e.id))})]})]})}function Se(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 Ce(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 we(e,t){return`${e===`active`?`A`:e===`passive`?`P`:e===`mixed`?`M`:`?`} / ${t===`connected`?`mesh`:t===`degraded`?`degr`:`iso`}`}function Te(e){let[t,...n]=e.split(` `).filter(Boolean);return{title:t||`Fabric`,lines:n}}function j(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 Ee(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)} - ${Pe(i)}`,`roles: ${Ze(a)}`,`services: ${et(o)}`].join(` `)}function De(e,t,n){let r=F(t,e.source_node_id),i=F(t,e.target_node_id),a=V(e.observed_at),o=bt(e,`observation_type`)||`link`,s=bt(e,`transport_mode`)||`direct`,c=vt(e,t),l=e.latency_ms==null?`н/д`:`${e.latency_ms}мс`;return[`${r} -> ${i}`,`status: ${yt(e,t,n)}`,`type: ${o}`,`mode: ${s}`,`latency: ${l}`,`path: ${c}`,`observed: ${a}`].join(` `)}function Oe(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 ke(e,t,n){if(Re(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&&!Re(t,n));return!r||r.link_status!==`reachable`?`one_way`:`reachable`}function Ae(e){if(e.link_status!==`reachable`||bt(e,`observation_type`)!==`peer_connection_manager`)return!1;let t=bt(e,`transport_mode`);return t===`relay_control`||bt(e,`relay_node_id`)?!1:e.metadata?.direct_candidate===!0||t===`direct_quic`||t===`private_lan`}function je(e){return bt(e,`observation_type`)===`peer_connection_manager`?bt(e,`transport_mode`)===`relay_control`||!!bt(e,`relay_node_id`):!1}function Me(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 Ne(e){if(!e)return{mode:`unknown`,detail:`no heartbeat`};let t=e.metadata||{},n=N(t.mesh_endpoint_report),r=N(t.mesh_listener_report),i=N(t.mesh_peer_connection_manager_report),a=Tt(i,`peer_connection_ready`),o=Tt(i,`peer_connection_relay_ready`),s=Tt(i,`peer_connection_waiting_rendezvous`),c=P(r,`status`,``),l=P(n,`connectivity_mode`,``),u=Ct(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 Pe(e){let t=N(e?.metadata?.web_ingress_runtime_receiver_report);if(!t)return`web ingress: no report`;let n=t.enabled===!0||t.handler_installed===!0,r=Tt(t,`trusted_key_count`),i=Rt(t.service_classes),a=P(t,`status`,``),o=t.quic_fabric_ready===!0||a===`ready`,s=P(t,`reason`,n?`ready`:`blocked`),c=P(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 Fe(e){let t=N(e?.metadata?.web_ingress_runtime_receiver_report);if(!t)return`missing`;let n=P(t,`status`,``);return n===`ready`||n===`degraded`||n===`blocked`?n:t.handler_installed===!0?`degraded`:`blocked`}function Ie(e,t){let n={ready:0,degraded:0,blocked:0,missing:0};for(let r of e){let e=Fe(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 Le(e){let t=new Set;for(let n of Qe(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 Re(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 ze(e){let t=Ue(e),n=Math.max(Math.ceil(e/t),1);return{width:1280,height:Math.max(720,220+n*148)}}function Be(e){return e>48?22:e>24?26:e>12?32:e>6?40:46}function Ve(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 He(e,t,n){let r=Ue(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 Ue(e){return e>48?8:e>24?6:e>12?5:e>6?4:e>3?3:Math.max(1,e)}function We(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 Ge(e,t,n,r,i){let a=We(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 Ke(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,ee=(u.y1+u.y2)/2,S=x+m*b,C=ee+h*b;return{d:`M ${u.x1} ${u.y1} Q ${S} ${C} ${u.x2} ${u.y2}`,labelX:(u.x1+2*S+u.x2)/4,labelY:(u.y1+2*C+u.y2)/4}}function Je({children:e}){return(0,S.jsx)(`div`,{className:`formGrid`,children:e})}function M({columns:e,rows:t}){return t.length===0?(0,S.jsx)(me,{title:`Нет данных`,text:`В текущей области пока нечего показать.`}):(0,S.jsx)(`div`,{className:`tableWrap`,children:(0,S.jsxs)(`table`,{children:[(0,S.jsx)(`thead`,{children:(0,S.jsx)(`tr`,{children:e.map(e=>(0,S.jsx)(`th`,{children:e},e))})}),(0,S.jsx)(`tbody`,{children:t.map((e,t)=>(0,S.jsx)(`tr`,{children:e.map((e,n)=>(0,S.jsx)(`td`,{children:e},`${t}-${n}`))},t))})]})})}function Ye(e,t){let n=JSON.parse(e||`{}`);if(!n||Array.isArray(n)||typeof n!=`object`)throw Error(`${t}: требуется JSON object.`);return n}function Xe(e,t){let n=JSON.parse(e||`[]`);if(!Array.isArray(n))throw Error(`${t}: требуется JSON array.`);return n}function Ze(e){let t=Qe(e);return t.length===0?`активные роли не назначены`:t.map(e=>`${$e(e.role)}${e.organization_id?` @ ${B(e.organization_id)}`:``}`).join(`, `)}function Qe(e){return e.filter(e=>e.status===`active`)}function $e(e){let t=w[e];return t?`${t} (${e})`:e}function et(e){return e.length===0?`нет сервисов`:e.map(e=>`${e.service_type}:${e.reported_state}`).join(`, `)}function tt(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 nt(e,t){return e.find(e=>e.product===t)}function rt(e,t){return e?`${e.product}: ${e.phase}/${e.status}`:t?`${t.action}: ${t.reason}`:`нет отчета`}function it(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 at(e){return e?`push ${e.pushed||0} / pop ${e.popped||0} / q ${e.queue_depth||0} / drop ${e.dropped||0}`:`нет данных`}function ot(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 st(e){let t=e.toLowerCase();return t===`healthy`?`good`:t===`fenced`?`bad`:t===`degraded`||t===`operator_retry_cooldown`?`warn`:``}function ct(e){let t=e.toLowerCase();return t===`healthy`?`good`:t===`recovered`||t===`cooldown`||t===`degraded`?`warn`:t===`fenced`||t===`demoted`?`bad`:``}function lt(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 ut(e){let t=lt(e);return t===`active`?`good`:t===`expired`?`warn`:t===`disabled`?``:`warn`}function dt(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 ft(e){let t=nt(e,`rap-node-agent`),n=nt(e,`rap-host-agent`);if(!t&&!n)return{label:`updater: нет отчета`,detail:`repair/update task не отчитался`,tone:`bad`};let r=[t,n].some(e=>e&&pt(e)),i=!n,a=n?.phase===`apply`&&n?.status===`staged`,o=[t,n].some(e=>e&&ot(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 pt(e){let t=new Date(e.observed_at).getTime();return!Number.isFinite(t)||Date.now()-t>900*1e3}function mt(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 ht(e){let t=new Map;for(let n of e){let e=`${n.source_node_id}->${n.target_node_id}:${gt(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 gt(e){let t=bt(e,`observation_type`)||`default`;return t===`synthetic_route_health`?`${t}:${bt(e,`route_id`)||e.id}`:t===`peer_connection_manager`?`${t}:${bt(e,`transport_mode`)}:${bt(e,`relay_node_id`)}`:t}function _t(e){let t=bt(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=bt(e,`transport_mode`)||`manager`,n=bt(e,`connection_state`);return n?`${t} ${n}`:t}return t||`link`}function vt(e,t){let n=bt(e,`route_id`),r=bt(e,`route_path_decision_selected_relay_id`)||bt(e,`relay_node_id`),i=xt(e,`expected_effective_hops`),a=xt(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=>Pn(F(t,e))).join(` > `)),s.length>0?s.join(` / `):`н/д`}function yt(e,t,n=e.link_status===`reachable`?`reachable`:`unknown`){if(n===`stale`)return`stale`;if(n===`one_way`)return`one-way`;let r=bt(e,`observation_type`);if(r===`synthetic_route_health`){let n=bt(e,`route_path_decision_selected_relay_id`);return n?`relay ${Pn(F(t,n),10)}`:e.metadata?.route_path_drift_detected===!0?`drift`:`route`}if(r===`peer_connection_manager`){let n=bt(e,`transport_mode`),r=bt(e,`relay_node_id`);if(n===`relay_control`||r)return r?`relay ${Pn(F(t,r),10)}`:`relay`;if(n===`direct_quic`||n===`private_lan`||bt(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 bt(e,t){let n=e.metadata?.[t];return typeof n==`string`?n:``}function xt(e,t){let n=e.metadata?.[t];return Array.isArray(n)?n.filter(e=>typeof e==`string`):[]}function N(e){return e&&typeof e==`object`&&!Array.isArray(e)?e:void 0}function St(e){return Array.isArray(e)?e.map(e=>N(e)).filter(e=>!!e):[]}function P(e,t,n=``){let r=e?.[t];return typeof r==`string`?r:typeof r==`number`||typeof r==`boolean`?String(r):n}function Ct(e,t){for(let n of t){let t=P(e,n,``);if(t)return t}return``}function wt(e,t,n){let r=t[0],i=r?.metadata||{},a=N(i.mesh_listener_report),o=N(i.mesh_endpoint_report),s=N(i.mesh_outbound_session_report),c=N(i.mesh_peer_connection_manager_report),l=N(i.mesh_peer_recovery_report),u=St(o?.endpoint_candidates)[0],d=Ct(o,[`peer_endpoint`,`advertised_endpoint`,`endpoint`])||P(u,`address`,``)||P(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=Tt(c,`peer_connection_ready`)||Tt(l,`peer_connection_ready`)||ht(n).filter(t=>(t.source_node_id===e.id||t.target_node_id===e.id)&&t.link_status===`reachable`).length,p=Tt(c,`peer_connection_total`)||Tt(l,`peer_connection_total`)||ht(n).filter(t=>t.source_node_id===e.id||t.target_node_id===e.id).length,m=Tt(c,`failed`),h=P(a,`status`,``),g=a?.port_conflict===!0,_=a?.one_way_connectivity===!0||P(o,`connectivity_mode`,``)===`outbound_only`||Tt(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 ee=P(s,`status`,``),S=s?.usable_for_inbound_control===!0,C=Tt(s,`peer_connection_relay_ready`),te=Tt(s,`rendezvous_lease_count`),ne=`outbound: no report`,re=`warn`;ee===`ready`?(ne=S?`outbound: ready reverse`:`outbound: ready`,re=`good`):ee===`backoff`||ee===`failed`?(ne=`outbound: ${ee}`,re=`bad`):(_||C>0||te>0)&&(ne=`outbound: inferred`,re=`warn`);let ie=e.health_status===`healthy`?`good`:e.health_status===`unknown`?`warn`:`bad`;return{agentLabel:r?`agent: heartbeat`:`agent: stale`,agentTone:ie,clientLabel:_&&f>0?`${b} one-way`:b,clientTone:x,outboundLabel:ne,outboundTone:re,inboundLabel:v,inboundTone:y,address:d,detail:P(a,`failure_error`,P(a,`failure_reason`,``))}}function Tt(e,t,n=0){let r=e?.[t];return typeof r==`number`&&Number.isFinite(r)?r:n}function Et(e){if(e==null)return`н/д`;let t=JSON.stringify(e);return t.length>140?`${t.slice(0,137)}...`:t}function Dt(e){let t=St(e.candidate_results);return t.length===0?`н/д`:t.slice(0,4).map(e=>{let t=P(e,`candidate_id`,`candidate`),n=P(e,`link_status`,`unknown`),r=P(e,`latency_ms`,``);return r&&r!==`0`?`${t}:${n}:${r}мс`:`${t}:${n}`}).join(`, `)}function Ot(e){return Object.values(e.peer_endpoint_candidates||{}).reduce((e,t)=>e+t.length,0)}function kt(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 At(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 F(e,t){return e.find(e=>e.id===t)?.name||B(t)}function jt(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 Mt(e,t){let n=t.find(t=>t.id===e);return n?jt(n,t):e}function Nt(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 Pt(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 Ft(e,t){return Object.entries(t).filter(([,t])=>t.some(t=>t.role===e&&t.status===`active`)).map(([e])=>e)}function It(e){let t={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||Bt()).trim().replace(/\/$/,``);t.install_profile=`docker`,t.backend_url=n,t.control_plane_endpoints=[n],t.image=e.dockerImage||`rap-node-agent:latest`,e.dockerContainerName.trim()&&(t.container_name=e.dockerContainerName.trim()),t.artifact_endpoints=Ht(e.artifactEndpoints||Vt()),e.dockerImageArtifactSHA256.trim()&&(t.docker_image_artifact_sha256=e.dockerImageArtifactSHA256.trim()),t.network=e.dockerNetwork||`host`,t.restart_policy=`unless-stopped`,t.pull_image=!!e.pullImage,t.replace=e.replace!==!1,t.mesh_synthetic_runtime_enabled=e.syntheticRuntime!==!1,t.mesh_production_forwarding_enabled=!1,t.mesh_listen_addr=e.meshListenAddr||`:19131`,t.mesh_listen_port_mode=e.meshListenPortMode||`auto`,t.mesh_listen_auto_port_start=e.meshListenAutoPortStart||19131,t.mesh_listen_auto_port_end=e.meshListenAutoPortEnd||19231,e.meshAdvertiseEndpoint?.trim()&&(t.mesh_advertise_endpoint=e.meshAdvertiseEndpoint.trim().replace(/\/$/,``)),t.mesh_advertise_transport=e.meshAdvertiseTransport||`direct_http`,t.mesh_connectivity_mode=e.meshConnectivityMode||`private_lan`,t.mesh_nat_type=e.meshNATType||`unknown`,t.mesh_region=e.meshRegion||null}if(e.installMode===`windows_service`){let n=(e.controlPlaneEndpoint||Bt()).trim().replace(/\/$/,``);t.install_profile=`windows_service`,t.backend_url=n,t.control_plane_endpoints=[n],t.artifact_endpoints=Ht(e.artifactEndpoints||Vt()),t.startup_mode=e.windowsStartupMode||`auto`,e.windowsInstallDir.trim()&&(t.install_dir=e.windowsInstallDir.trim()),e.windowsNodeAgentSHA256.trim()&&(t.node_agent_artifact_sha256=e.windowsNodeAgentSHA256.trim()),t.mesh_synthetic_runtime_enabled=e.syntheticRuntime!==!1,t.mesh_production_forwarding_enabled=!1,t.mesh_listen_addr=e.meshListenAddr||`:19131`,t.mesh_listen_port_mode=e.meshListenPortMode||`auto`,t.mesh_listen_auto_port_start=e.meshListenAutoPortStart||19131,t.mesh_listen_auto_port_end=e.meshListenAutoPortEnd||19231,e.meshAdvertiseEndpoint?.trim()&&(t.mesh_advertise_endpoint=e.meshAdvertiseEndpoint.trim().replace(/\/$/,``)),t.mesh_advertise_transport=e.meshAdvertiseTransport||`direct_http`,t.mesh_connectivity_mode=e.meshConnectivityMode||`outbound_only`,t.mesh_nat_type=e.meshNATType||`unknown`,t.mesh_region=e.meshRegion||`windows`}if(e.installMode===`linux_binary`){let n=(e.controlPlaneEndpoint||Bt()).trim().replace(/\/$/,``);t.install_profile=`linux_binary`,t.backend_url=n,t.control_plane_endpoints=[n],t.artifact_endpoints=Ht(e.artifactEndpoints||Vt()),t.startup_mode=`systemd`,e.linuxInstallDir.trim()&&(t.install_dir=e.linuxInstallDir.trim()),e.linuxNodeAgentSHA256.trim()&&(t.node_agent_artifact_sha256=e.linuxNodeAgentSHA256.trim()),t.replace=e.replace!==!1,t.mesh_synthetic_runtime_enabled=e.syntheticRuntime!==!1,t.mesh_production_forwarding_enabled=!1,t.mesh_listen_addr=e.meshListenAddr||`:19131`,t.mesh_listen_port_mode=e.meshListenPortMode||`auto`,t.mesh_listen_auto_port_start=e.meshListenAutoPortStart||19131,t.mesh_listen_auto_port_end=e.meshListenAutoPortEnd||19231,e.meshAdvertiseEndpoint?.trim()&&(t.mesh_advertise_endpoint=e.meshAdvertiseEndpoint.trim().replace(/\/$/,``)),t.mesh_advertise_transport=e.meshAdvertiseTransport||`direct_http`,t.mesh_connectivity_mode=e.meshConnectivityMode||`outbound_only`,t.mesh_nat_type=e.meshNATType||`unknown`,t.mesh_region=e.meshRegion||`linux`}return t}function Lt(e,t){let n=Rt(e.roles),r=Rt(e.artifact_endpoints).join(`, `);return{...t,roles:n.length>0?n:t.roles,nodeName:P(e,`node_name`,``)||t.nodeName,nodeGroupId:P(e,`node_group_id`,``)||t.nodeGroupId,ownershipType:P(e,`ownership_type`,t.ownershipType),purpose:P(e,`purpose`,``)||t.purpose,installMode:P(e,`install_profile`,t.installMode),dockerImage:P(e,`image`,t.dockerImage),dockerContainerName:P(e,`container_name`,``)||t.dockerContainerName,dockerNetwork:P(e,`network`,t.dockerNetwork),windowsStartupMode:P(e,`startup_mode`,t.windowsStartupMode),windowsInstallDir:P(e,`install_dir`,``)||t.windowsInstallDir,windowsNodeAgentSHA256:P(e,`node_agent_artifact_sha256`,``)||t.windowsNodeAgentSHA256,linuxInstallDir:P(e,`install_dir`,``)||t.linuxInstallDir,linuxNodeAgentSHA256:P(e,`node_agent_artifact_sha256`,``)||t.linuxNodeAgentSHA256,meshListenAddr:P(e,`mesh_listen_addr`,t.meshListenAddr),meshListenPortMode:P(e,`mesh_listen_port_mode`,t.meshListenPortMode),meshListenAutoPortStart:Tt(e,`mesh_listen_auto_port_start`,t.meshListenAutoPortStart),meshListenAutoPortEnd:Tt(e,`mesh_listen_auto_port_end`,t.meshListenAutoPortEnd),meshAdvertiseEndpoint:P(e,`mesh_advertise_endpoint`,``)||t.meshAdvertiseEndpoint,meshAdvertiseTransport:P(e,`mesh_advertise_transport`,t.meshAdvertiseTransport),meshConnectivityMode:P(e,`mesh_connectivity_mode`,t.meshConnectivityMode),meshNATType:P(e,`mesh_nat_type`,t.meshNATType),meshRegion:P(e,`mesh_region`,``)||t.meshRegion,controlPlaneEndpoint:Rt(e.control_plane_endpoints)[0]||P(e,`backend_url`,``)||t.controlPlaneEndpoint,artifactEndpoints:r||t.artifactEndpoints,dockerImageArtifactSHA256:P(e,`docker_image_artifact_sha256`,``)||t.dockerImageArtifactSHA256,pullImage:zt(e,`pull_image`,t.pullImage),replace:zt(e,`replace`,t.replace),syntheticRuntime:zt(e,`mesh_synthetic_runtime_enabled`,t.syntheticRuntime)}}function Rt(e){return Array.isArray(e)?e.filter(e=>typeof e==`string`).map(e=>e.trim()).filter(Boolean):[]}function zt(e,t,n){let r=e[t];return typeof r==`boolean`?r:n}function Bt(){return typeof window>`u`||!window.location?.origin?`http://:18080/api/v1`:`${window.location.origin.replace(/\/$/,``)}/api/v1`}function Vt(){return typeof window>`u`||!window.location?.origin?`http://:18080/downloads`:`${window.location.origin.replace(/\/$/,``)}/downloads`}function Ht(e){return e.split(`,`).map(e=>e.trim().replace(/\/$/,``)).filter(Boolean)}function I(e){return Ht(e.artifactEndpoints||Vt()).map(e=>`${e}/rap-node-agent-dev-enrollment-bootstrap-smoke.tar`)}function Ut(e){return e.meshConnectivityMode===`outbound_only`?`outbound_only`:e.meshConnectivityMode===`private_lan`?`private_lan`:e.meshNATType!==`none`&&e.meshAdvertiseEndpoint.trim()?`nat_forward`:`direct`}function Wt(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 Gt(e,t){return e.nodeName.trim()?e.nodeName.trim():`${pn(t?.slug||t?.name||`rap-node`)}-node-1`}function Kt(e,t){return e.dockerContainerName.trim()?e.dockerContainerName.trim():`rap-node-agent-${pn(Gt(e,t))}`}function qt(e,t,n=le){let r=t?.id||e.cluster_id,i=Gt(n,t),a=Kt(n,t),o=pn(i),s=[`rap-host-agent install`,`--backend-url ${R(ln(n))}`,`--cluster-id ${R(r)}`,`--join-token ${R(e.token)}`,`--node-name ${R(i)}`,`--image ${R(n.dockerImage||`rap-node-agent:latest`)}`,`--container-name ${R(a)}`,`--state-dir ${R(`/var/lib/rap/nodes/${o}`)}`,`--network host`,`--replace`];for(let e of I(n))s.push(`--image-artifact-url ${R(e)}`);return n.dockerImageArtifactSHA256.trim()&&s.push(`--image-artifact-sha256 ${R(n.dockerImageArtifactSHA256.trim())}`),s.join(` \\ `)}function Jt(e,t,n=le){let r=t?.id||e.cluster_id,i=Gt(n,t),a=[`sudo "$rap_host_agent" install`,`--profile-url ${R(ln(n))}`,`--cluster-id ${R(r)}`,`--install-token ${R(e.token)}`,`--node-name ${R(i)}`].join(` \\ `);return[`rap_host_agent="$(mktemp /tmp/rap-host-agent.XXXXXX)"`,`curl -fL --retry 3 --retry-delay 1 ${R(L(n))} -o "$rap_host_agent"`,`chmod +x "$rap_host_agent"`,a].join(` && \\ `)}function Yt(e,t,n=le){let r=t?.id||e.cluster_id,i=Gt(n,t),a=[`sudo "$rap_host_agent" install-linux`,`--profile-url ${R(ln(n))}`,`--cluster-id ${R(r)}`,`--install-token ${R(e.token)}`,`--node-name ${R(i)}`].join(` \\ `);return[`rap_host_agent="$(mktemp /tmp/rap-host-agent.XXXXXX)"`,`curl -fL --retry 3 --retry-delay 1 ${R(L(n))} -o "$rap_host_agent"`,`chmod +x "$rap_host_agent"`,a].join(` && \\ `)}function Xt(e,t,n=le){let r=t?.id||e.cluster_id,i=Gt(n,t),a=ln(n);return[`$rapHostAgent = Join-Path $env:TEMP "rap-host-agent.exe"`,`Invoke-WebRequest -UseBasicParsing ${mn(fn(n))} -OutFile $rapHostAgent`,`& $rapHostAgent install-windows --profile-url ${mn(a)} --cluster-id ${mn(r)} --install-token ${mn(e.token)} --node-name ${mn(i)} --startup-mode ${mn(n.windowsStartupMode||`auto`)}`].join(`\r `)}function Zt(e,t,n=le){let r=t?.id||e.cluster_id,i=Gt(n,t),a=ln(n),o=fn(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 Qt(e,t){let n=un(),r=n.replace(/\/api\/v1$/i,``).replace(/\/api$/i,``).replace(/\/$/,``),i=e.name||e.node_key||e.id,a=on(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: ${hn(i)} ===`,`echo Node ID: ${e.id}`,`echo Control Plane: ${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 "${hn(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 $t(e){return`rap-repair-updater-${an(e.name||e.node_key||e.id||`node`)}.cmd`}function en(e,t){let n=un(),r=n.replace(/\/api\/v1$/i,``).replace(/\/api$/i,``).replace(/\/$/,``),i=e.name||e.node_key||e.id,a=sn(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: ${cn(i)} ==="`,`echo "Node ID: ${e.id}"`,`echo "Control Plane: ${n}"`,`echo`,`echo "=== Before repair: systemd units ==="`,`systemctl status ${R(c)} --no-pager || true`,`systemctl status ${R(l)} --no-pager || true`,`echo`,`echo "=== Before repair: binaries ==="`,`ls -la ${R(o)} || true`,`echo`,`rap_host_agent="$(mktemp /tmp/rap-host-agent.XXXXXX)"`,`curl -fL --retry 3 --retry-delay 1 ${R(`${r}/downloads/rap-host-agent-linux-amd64`)} -o "$rap_host_agent"`,`chmod +x "$rap_host_agent"`,`sudo "$rap_host_agent" install-linux --backend-url ${R(n)} --cluster-id ${R(t||``)} --node-id ${R(e.id)} --node-name ${R(i)} --replace --startup-mode systemd --auto-update-current-version 0.0.0 --auto-update-initial-delay-seconds 1`,`sudo ${R(u)} update-loop --backend-url ${R(n)} --cluster-id ${R(t||``)} --node-id ${R(e.id)} --state-dir ${R(s)} --current-version 0.0.0 --os linux --arch amd64 --install-type linux_binary --binary-path ${R(`${o}/rap-node-agent`)} --systemd-unit ${R(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 ${R(u)}`,`sudo systemctl daemon-reload`,`sudo systemctl restart ${R(l)}`,`echo`,`echo "=== After repair: systemd updater ==="`,`systemctl status ${R(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 tn(e){return`rap-repair-updater-${an(e.name||e.node_key||e.id||`node`)}.sh`}function nn(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 rn(e){await navigator.clipboard.writeText(e)}function an(e){return e.trim().replace(/[\\/:*?"<>|]+/g,`-`).replace(/\s+/g,`-`).replace(/-+/g,`-`).replace(/^-|-$/g,``).slice(0,80)||`node`}function on(e){return e.trim().replace(/[\\/:*?"<>|]+/g,`-`).replace(/\s+/g,`-`).replace(/-+/g,`-`).replace(/^-|-$/g,``)||`node`}function sn(e){return on(e).slice(0,48)||`node`}function cn(e){return e.replace(/\\/g,`\\\\`).replace(/"/g,`\\"`).replace(/\$/g,`\\$`).replace(/`/g,"\\`")}function ln(e=le){return(e.controlPlaneEndpoint||Bt()).trim().replace(/\/$/,``)}function un(){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 dn(e=le){let t=Ht(e.artifactEndpoints)[0];return t?t.replace(/\/downloads$/i,``).replace(/\/$/,``):ln(e).replace(/\/api\/v1$/i,``).replace(/\/api$/i,``).replace(/\/$/,``)}function L(e=le){return`${typeof window>`u`&&!e.controlPlaneEndpoint?`http://:18080`:dn(e)}/downloads/rap-host-agent-linux-amd64`}function fn(e=le){return`${typeof window>`u`&&!e.controlPlaneEndpoint?`http://:18080`:dn(e)}/downloads/rap-host-agent-windows-amd64.exe`}function pn(e){return e.trim().toLowerCase().replace(/[^a-z0-9-]+/g,`-`).replace(/^-+|-+$/g,``).slice(0,42)||`rap-node`}function R(e){return`'${e.replace(/'/g,`'\\''`)}'`}function mn(e){return`'${e.replace(/'/g,`''`)}'`}function hn(e){return e.replace(/"/g,`""`)}function gn(e,t){return e.includes(t)?e.filter(e=>e!==t):[...e,t]}function _n(e,t,n,r,i){let a=n.trim().toLowerCase(),o=new Map;for(let n of e){if(a&&!vn(n,a))continue;let e=z(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 vn(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 z(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 Mn(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 yn(e,t){let n=ae[e]||[];if(n.length===0||!t)return`unknown`;if(bn(t))return`stale`;let r=t.capabilities||{};return n.some(e=>!!r[e])?`confirmed`:`missing`}function bn(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 xn(e,t){let n=yn(e,t);return n===`confirmed`?`good`:n===`missing`?`bad`:n===`stale`?`warn`:``}function Sn(e,t,n){let r=yn(e,t);return r===`confirmed`?n.capabilityConfirmed:r===`missing`?n.capabilityMissing:r===`stale`?`heartbeat устарел`:n.capabilityUnknown}function Cn(e,t,n){let r=yn(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 wn(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 Tn(e){let t=e?.metadata?.mesh_peer_connection_intent_report;if(!t||typeof t!=`object`||Array.isArray(t))return An(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=An(e);return d===`н/д`?u:`${u}; ${d}`}function En(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 Dn(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 On(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 kn(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 An(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 jn(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 Mn(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 Nn(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 Pn(e,t=16){return e.length>t?`${e.slice(0,Math.max(1,t-2))}…`:e}function Fn(e){return window.confirm(`${e}?\n\nЭто высокорисковая операция владельца платформы. Действие будет записано в аудит.`)}function In(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 Ln(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 Rn(e){return e?new Intl.DateTimeFormat(void 0,{hour:`2-digit`,minute:`2-digit`,second:`2-digit`}).format(new Date(e)):`н/д`}function zn(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 Vn(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 Hn(e,t){return(t||0)>0||e===`critical`?`bad`:e===`degraded`?`warn`:e===`watch`?`info`:`good`}function Un(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 Wn(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,S.jsx)(_.StrictMode,{children:(0,S.jsx)(de,{})}));