@bitkyc08/opencodex 2.61.0 → 2.62.0-preview.20260923

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/App-CH6C5H7x.js","assets/usage-companion-chart-a0N58rRI.js"])))=>i.map(i=>d[i]);
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/App-CANWata-.js","assets/usage-companion-chart-BIhvlbQW.js"])))=>i.map(i=>d[i]);
2
2
  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;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},c=(n,r,o)=>(o=n==null?{}:e(i(n)),s(r||!n||!n.__esModule||!a.call(n,`default`)?t(o,`default`,{value:n,enumerable:!0}):o,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),t.credentials=e.crossOrigin===`use-credentials`?`include`:e.crossOrigin===`anonymous`?`omit`:`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 ae(e){var t={"=":`=0`,":":`=2`};return`$`+e.replace(/[=:]/g,function(e){return t[e]})}var oe=/\/+/g;function se(e,t){return typeof e==`object`&&e&&e.key!=null?ae(``+e.key):t.toString(36)}function ce(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 le(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,le(c(e._payload),r,i,a,o)}}if(c)return o=o(e),c=a===``?`.`+se(e,0):a,ee(o)?(i=``,c!=null&&(i=c.replace(oe,`$&/`)+`/`),le(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(oe,`$&/`)+`/`)+c)),r.push(o)),1;c=0;var l=a===``?`.`:a+`:`;if(ee(e))for(var u=0;u<e.length;u++)a=e[u],s=l+se(a,u),c+=le(a,r,i,s,o);else if(u=m(e),typeof u==`function`)for(e=u.call(e),u=0;!(a=e.next()).done;)a=a.value,s=l+se(a,u++),c+=le(a,r,i,s,o);else if(s===`object`){if(typeof e.then==`function`)return le(ce(e),r,i,a,o);throw r=String(e),Error(`Objects are not valid as a React child (found: `+(r===`[object Object]`?`object with keys {`+Object.keys(e).join(`, `)+`}`:r)+`). If you meant to render a collection of children, use an array instead.`)}return c}function ue(e,t,n){if(e==null)return e;var r=[],i=0;return le(e,r,``,``,function(e){return t.call(n,e,i++)}),r}function de(e){if(e._status===-1){var t=e._result;t=t(),t.then(function(t){(e._status===0||e._status===-1)&&(e._status=1,e._result=t)},function(t){(e._status===0||e._status===-1)&&(e._status=2,e._result=t)}),e._status===-1&&(e._status=0,e._result=t)}if(e._status===1)return e._result.default;throw e._result}var w=typeof reportError==`function`?reportError:function(e){if(typeof window==`object`&&typeof window.ErrorEvent==`function`){var t=new window.ErrorEvent(`error`,{bubbles:!0,cancelable:!0,message:typeof e==`object`&&e&&typeof e.message==`string`?String(e.message):String(e),error:e});if(!window.dispatchEvent(t))return}else if(typeof process==`object`&&typeof process.emit==`function`){process.emit(`uncaughtException`,e);return}console.error(e)},T={map:ue,forEach:function(e,t,n){ue(e,function(){t.apply(this,arguments)},n)},count:function(e){var t=0;return ue(e,function(){t++}),t},toArray:function(e){return ue(e,function(e){return e})||[]},only:function(e){if(!ie(e))throw Error(`React.Children.only expected to receive a single React element child.`);return e}};e.Activity=f,e.Children=T,e.Component=v,e.Fragment=r,e.Profiler=a,e.PureComponent=b,e.StrictMode=i,e.Suspense=l,e.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE=C,e.__COMPILER_RUNTIME={__proto__:null,c:function(e){return C.H.useMemoCache(e)}},e.cache=function(e){return function(){return e.apply(null,arguments)}},e.cacheSignal=function(){return null},e.cloneElement=function(e,t,n){if(e==null)throw Error(`The argument must be a React element, but you passed `+e+`.`);var r=g({},e.props),i=e.key;if(t!=null)for(a in t.key!==void 0&&(i=``+t.key),t)!te.call(t,a)||a===`key`||a===`__self`||a===`__source`||a===`ref`&&t.ref===void 0||(r[a]=t[a]);var a=arguments.length-2;if(a===1)r.children=n;else if(1<a){for(var o=Array(a),s=0;s<a;s++)o[s]=arguments[s+2];r.children=o}return ne(e.type,i,r)},e.createContext=function(e){return e={$$typeof:s,_currentValue:e,_currentValue2:e,_threadCount:0,Provider:null,Consumer:null},e.Provider=e,e.Consumer={$$typeof:o,_context:e},e},e.createElement=function(e,t,n){var r,i={},a=null;if(t!=null)for(r in t.key!==void 0&&(a=``+t.key),t)te.call(t,r)&&r!==`key`&&r!==`__self`&&r!==`__source`&&(i[r]=t[r]);var o=arguments.length-2;if(o===1)i.children=n;else if(1<o){for(var s=Array(o),c=0;c<o;c++)s[c]=arguments[c+2];i.children=s}if(e&&e.defaultProps)for(r in o=e.defaultProps,o)i[r]===void 0&&(i[r]=o[r]);return ne(e,a,i)},e.createRef=function(){return{current:null}},e.forwardRef=function(e){return{$$typeof:c,render:e}},e.isValidElement=ie,e.lazy=function(e){return{$$typeof:d,_payload:{_status:-1,_result:e},_init:de}},e.memo=function(e,t){return{$$typeof:u,type:e,compare:t===void 0?null:t}},e.startTransition=function(e){var t=C.T,n={};C.T=n;try{var r=e(),i=C.S;i!==null&&i(n,r),typeof r==`object`&&r&&typeof r.then==`function`&&r.then(S,w)}catch(e){w(e)}finally{t!==null&&n.types!==null&&(t.types=n.types),C.T=t}},e.unstable_useCacheRefresh=function(){return C.H.useCacheRefresh()},e.use=function(e){return C.H.use(e)},e.useActionState=function(e,t,n){return C.H.useActionState(e,t,n)},e.useCallback=function(e,t){return C.H.useCallback(e,t)},e.useContext=function(e){return C.H.useContext(e)},e.useDebugValue=function(){},e.useDeferredValue=function(e,t){return C.H.useDeferredValue(e,t)},e.useEffect=function(e,t){return C.H.useEffect(e,t)},e.useEffectEvent=function(e){return C.H.useEffectEvent(e)},e.useId=function(){return C.H.useId()},e.useImperativeHandle=function(e,t,n){return C.H.useImperativeHandle(e,t,n)},e.useInsertionEffect=function(e,t){return C.H.useInsertionEffect(e,t)},e.useLayoutEffect=function(e,t){return C.H.useLayoutEffect(e,t)},e.useMemo=function(e,t){return C.H.useMemo(e,t)},e.useOptimistic=function(e,t){return C.H.useOptimistic(e,t)},e.useReducer=function(e,t,n){return C.H.useReducer(e,t,n)},e.useRef=function(e){return C.H.useRef(e)},e.useState=function(e){return C.H.useState(e)},e.useSyncExternalStore=function(e,t,n){return C.H.useSyncExternalStore(e,t,n)},e.useTransition=function(){return C.H.useTransition()},e.version=`19.2.8`})),u=o(((e,t)=>{t.exports=l()})),d=o((e=>{function t(e,t){var n=e.length;e.push(t);a:for(;0<n;){var r=n-1>>>1,a=e[r];if(0<i(a,t))e[r]=t,e[n]=a,n=r;else break a}}function n(e){return e.length===0?null:e[0]}function r(e){if(e.length===0)return null;var t=e[0],n=e.pop();if(n!==t){e[0]=n;a:for(var r=0,a=e.length,o=a>>>1;r<o;){var s=2*(r+1)-1,c=e[s],l=s+1,u=e[l];if(0>i(c,n))l<a&&0>i(u,c)?(e[r]=u,e[l]=n,r=l):(e[r]=c,e[s]=n,r=s);else if(l<a&&0>i(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&&se(x,t.startTime-e)}}}var ee=!1,S=-1,C=5,te=-1;function ne(){return g?!0:!(e.unstable_now()-te<C)}function re(){if(g=!1,ee){var t=e.unstable_now();te=t;var i=!0;try{a:{m=!1,h&&(h=!1,v(S),S=-1),p=!0;var a=f;try{b:{for(b(t),d=n(c);d!==null&&!(d.expirationTime>t&&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&&se(x,u.startTime-t),i=!1}}break a}finally{d=null,f=a,p=!1}}}finally{i?ie():ee=!1}}}var ie;if(typeof y==`function`)ie=function(){y(re)};else if(typeof MessageChannel<`u`){var ae=new MessageChannel,oe=ae.port2;ae.port1.onmessage=re,ie=function(){oe.postMessage(null)}}else ie=function(){_(re,0)};function se(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||125<e?console.error(`forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported`):C=0<e?Math.floor(1e3/e):5},e.unstable_getCurrentPriorityLevel=function(){return f},e.unstable_next=function(e){switch(f){case 1:case 2:case 3:var t=3;break;default:t=f}var n=f;f=t;try{return e()}finally{f=n}},e.unstable_requestPaint=function(){g=!0},e.unstable_runWithPriority=function(e,t){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=f;f=e;try{return t()}finally{f=n}},e.unstable_scheduleCallback=function(r,i,a){var o=e.unstable_now();switch(typeof a==`object`&&a?(a=a.delay,a=typeof a==`number`&&0<a?o+a:o):a=o,r){case 1:var s=-1;break;case 2:s=250;break;case 5:s=1073741823;break;case 4:s=1e4;break;default:s=5e3}return s=a+s,r={id:u++,callback:i,priorityLevel:r,startTime:a,expirationTime:s,sortIndex:-1},a>o?(r.sortIndex=a,t(l,r),n(c)===null&&r===n(l)&&(h?(v(S),S=-1):h=!0,se(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<arguments.length){t+=`?args[]=`+encodeURIComponent(arguments[1]);for(var n=2;n<arguments.length;n++)t+=`&args[]=`+encodeURIComponent(arguments[n])}return`Minified React error #`+e+`; visit `+t+` for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`}function r(){}var i={d:{f:r,r:function(){throw Error(n(522))},D:r,C:r,L:r,m:r,X:r,S:r,M:r},p:0,findDOMNode:null},a=Symbol.for(`react.portal`);function o(e,t,n){var r=3<arguments.length&&arguments[3]!==void 0?arguments[3]:null;return{$$typeof:a,key:r==null?null:``+r,children:e,containerInfo:t,implementation:n}}var s=t.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;function c(e,t){if(e===`font`)return``;if(typeof t==`string`)return t===`use-credentials`?t:``}e.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE=i,e.createPortal=function(e,t){var r=2<arguments.length&&arguments[2]!==void 0?arguments[2]:null;if(!t||t.nodeType!==1&&t.nodeType!==9&&t.nodeType!==11)throw Error(n(299));return o(e,t,null,r)},e.flushSync=function(e){var t=s.T,n=i.p;try{if(s.T=null,i.p=2,e)return e()}finally{s.T=t,i.p=n,i.d.f()}},e.preconnect=function(e,t){typeof e==`string`&&(t?(t=t.crossOrigin,t=typeof t==`string`?t===`use-credentials`?t:``:void 0):t=null,i.d.C(e,t))},e.prefetchDNS=function(e){typeof e==`string`&&i.d.D(e)},e.preinit=function(e,t){if(typeof e==`string`&&t&&typeof t.as==`string`){var n=t.as,r=c(n,t.crossOrigin),a=typeof t.integrity==`string`?t.integrity:void 0,o=typeof t.fetchPriority==`string`?t.fetchPriority:void 0;n===`style`?i.d.S(e,typeof t.precedence==`string`?t.precedence:void 0,{crossOrigin:r,integrity:a,fetchPriority:o}):n===`script`&&i.d.X(e,{crossOrigin:r,integrity:a,fetchPriority:o,nonce:typeof t.nonce==`string`?t.nonce:void 0})}},e.preinitModule=function(e,t){if(typeof e==`string`){if(typeof t==`object`&&t){if(t.as==null||t.as===`script`){var n=c(t.as,t.crossOrigin);i.d.M(e,{crossOrigin:n,integrity:typeof t.integrity==`string`?t.integrity:void 0,nonce:typeof t.nonce==`string`?t.nonce:void 0})}}else t??i.d.M(e)}},e.preload=function(e,t){if(typeof e==`string`&&typeof t==`object`&&t&&typeof t.as==`string`){var n=t.as,r=c(n,t.crossOrigin);i.d.L(e,n,{crossOrigin:r,integrity:typeof t.integrity==`string`?t.integrity:void 0,nonce:typeof t.nonce==`string`?t.nonce:void 0,type:typeof t.type==`string`?t.type:void 0,fetchPriority:typeof t.fetchPriority==`string`?t.fetchPriority:void 0,referrerPolicy:typeof t.referrerPolicy==`string`?t.referrerPolicy:void 0,imageSrcSet:typeof t.imageSrcSet==`string`?t.imageSrcSet:void 0,imageSizes:typeof t.imageSizes==`string`?t.imageSizes:void 0,media:typeof t.media==`string`?t.media:void 0})}},e.preloadModule=function(e,t){if(typeof e==`string`){if(t){var n=c(t.as,t.crossOrigin);i.d.m(e,{as:typeof t.as==`string`&&t.as!==`script`?t.as:void 0,crossOrigin:n,integrity:typeof t.integrity==`string`?t.integrity:void 0})}else i.d.m(e)}},e.requestFormReset=function(e){i.d.r(e)},e.unstable_batchedUpdates=function(e,t){return e(t)},e.useFormState=function(e,t,n){return s.H.useFormState(e,t,n)},e.useFormStatus=function(){return s.H.useHostTransitionStatus()},e.version=`19.2.8`})),m=o(((e,t)=>{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(1<arguments.length){t+=`?args[]=`+encodeURIComponent(arguments[1]);for(var n=2;n<arguments.length;n++)t+=`&args[]=`+encodeURIComponent(arguments[n])}return`Minified React error #`+e+`; visit `+t+` for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`}function a(e){return!(!e||e.nodeType!==1&&e.nodeType!==9&&e.nodeType!==11)}function o(e){var t=e,n=e;if(e.alternate)for(;t.return;)t=t.return;else{e=t;do t=e,t.flags&4098&&(n=t.return),e=t.return;while(e)}return t.tag===3?n:null}function s(e){if(e.tag===13){var t=e.memoizedState;if(t===null&&(e=e.alternate,e!==null&&(t=e.memoizedState)),t!==null)return t.dehydrated}return null}function c(e){if(e.tag===31){var t=e.memoizedState;if(t===null&&(e=e.alternate,e!==null&&(t=e.memoizedState)),t!==null)return t.dehydrated}return null}function l(e){if(o(e)!==e)throw Error(i(188))}function d(e){var t=e.alternate;if(!t){if(t=o(e),t===null)throw Error(i(188));return t===e?e:null}for(var n=e,r=t;;){var a=n.return;if(a===null)break;var s=a.alternate;if(s===null){if(r=a.return,r!==null){n=r;continue}break}if(a.child===s.child){for(s=a.child;s;){if(s===n)return l(a),e;if(s===r)return l(a),t;s=s.sibling}throw Error(i(188))}if(n.return!==r.return)n=a,r=s;else{for(var c=!1,u=a.child;u;){if(u===n){c=!0,n=a,r=s;break}if(u===r){c=!0,r=a,n=s;break}u=u.sibling}if(!c){for(u=s.child;u;){if(u===n){c=!0,n=s,r=a;break}if(u===r){c=!0,r=s,n=a;break}u=u.sibling}if(!c)throw Error(i(189))}}if(n.alternate!==r)throw Error(i(190))}if(n.tag!==3)throw Error(i(188));return n.stateNode.current===n?e:t}function p(e){var t=e.tag;if(t===5||t===26||t===27||t===6)return e;for(e=e.child;e!==null;){if(t=p(e),t!==null)return t;e=e.sibling}return null}var h=Object.assign,g=Symbol.for(`react.element`),_=Symbol.for(`react.transitional.element`),v=Symbol.for(`react.portal`),y=Symbol.for(`react.fragment`),b=Symbol.for(`react.strict_mode`),x=Symbol.for(`react.profiler`),ee=Symbol.for(`react.consumer`),S=Symbol.for(`react.context`),C=Symbol.for(`react.forward_ref`),te=Symbol.for(`react.suspense`),ne=Symbol.for(`react.suspense_list`),re=Symbol.for(`react.memo`),ie=Symbol.for(`react.lazy`),ae=Symbol.for(`react.activity`),oe=Symbol.for(`react.memo_cache_sentinel`),se=Symbol.iterator;function ce(e){return typeof e!=`object`||!e?null:(e=se&&e[se]||e[`@@iterator`],typeof e==`function`?e:null)}var le=Symbol.for(`react.client.reference`);function ue(e){if(e==null)return null;if(typeof e==`function`)return e.$$typeof===le?null:e.displayName||e.name||null;if(typeof e==`string`)return e;switch(e){case y:return`Fragment`;case x:return`Profiler`;case b:return`StrictMode`;case te:return`Suspense`;case ne:return`SuspenseList`;case ae:return`Activity`}if(typeof e==`object`)switch(e.$$typeof){case v:return`Portal`;case S:return e.displayName||`Context`;case ee:return(e._context.displayName||`Context`)+`.Consumer`;case C:var t=e.render;return e=e.displayName,e||=(e=t.displayName||t.name||``,e===``?`ForwardRef`:`ForwardRef(`+e+`)`),e;case re:return t=e.displayName||null,t===null?ue(e.type)||`Memo`:t;case ie:t=e._payload,e=e._init;try{return ue(e(t))}catch{}}return null}var de=Array.isArray,w=n.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,T=r.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,fe={pending:!1,data:null,method:null,action:null},pe=[],me=-1;function he(e){return{current:e}}function E(e){0>me||(e.current=pe[me],pe[me]=null,me--)}function D(e,t){me++,pe[me]=e.current,e.current=t}var ge=he(null),_e=he(null),ve=he(null),ye=he(null);function be(e,t){switch(D(ve,t),D(_e,e),D(ge,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}}E(ge),D(ge,e)}function xe(){E(ge),E(_e),E(ve)}function Se(e){e.memoizedState!==null&&D(ye,e);var t=ge.current,n=Hd(t,e.type);t!==n&&(D(_e,e),D(ge,n))}function Ce(e){_e.current===e&&(E(ge),E(_e)),ye.current===e&&(E(ye),Qf._currentValue=fe)}var we,Te;function Ee(e){if(we===void 0)try{throw Error()}catch(e){var t=e.stack.trim().match(/\n( *(at )?)/);we=t&&t[1]||``,Te=-1<e.stack.indexOf(`
3
3
  at`)?` (<anonymous>)`:-1<e.stack.indexOf(`@`)?`@unknown:0:0`:``}return`
4
4
  `+we+e+Te}var De=!1;function Oe(e,t){if(!e||De)return``;De=!0;var n=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{var r={DetermineComponentFrameRoot:function(){try{if(t){var n=function(){throw Error()};if(Object.defineProperty(n.prototype,"props",{set:function(){throw Error()}}),typeof Reflect==`object`&&Reflect.construct){try{Reflect.construct(n,[])}catch(e){var r=e}Reflect.construct(e,[],n)}else{try{n.call()}catch(e){r=e}e.call(n.prototype)}}else{try{throw Error()}catch(e){r=e}(n=e())&&typeof n.catch==`function`&&n.catch(function(){})}}catch(e){if(e&&r&&typeof e.stack==`string`)return[e.stack,r.stack]}return[null,null]}};r.DetermineComponentFrameRoot.displayName=`DetermineComponentFrameRoot`;var i=Object.getOwnPropertyDescriptor(r.DetermineComponentFrameRoot,`name`);i&&i.configurable&&Object.defineProperty(r.DetermineComponentFrameRoot,"name",{value:`DetermineComponentFrameRoot`});var a=r.DetermineComponentFrameRoot(),o=a[0],s=a[1];if(o&&s){var c=o.split(`
@@ -83,4 +83,4 @@ v2: Agent đa luồng với spawn_agent. Mọi model đều sử dụng giao di
83
83
 
84
84
  Ở v2, tuỳ chọn Giữ ChatGPT ở v1 sẽ giữ Sol/Terra ở giao diện v1 để chúng vẫn có thể gọi Grok hoặc Claude. ChatGPT mã hoá các task con v2; các model được định tuyến không thể đọc được chúng. Các model cha được định tuyến vẫn giữ ở v2.
85
85
 
86
- Các thay đổi sẽ áp dụng cho các phiên (sessions) mới.`,"dash.multiAgent":`Agent con (Sub-agent)`,"dash.codexDesktopAuthless":`Mở Codex không cần đăng nhập`,"dash.codexDesktopAuthlessHint":`Mặc định tắt. Bỏ qua bước đăng nhập Desktop riêng cho các kết nối cục bộ hợp lệ. Vẫn cần thông tin xác thực upstream. Khởi động lại Codex sau khi thay đổi cài đặt này. Các tính năng Desktop yêu cầu tài khoản có thể không khả dụng.`,"dash.codexClientCompaction":`Sử dụng tính năng thu gọn phía client (client-side compaction)`,"dash.codexClientCompactionHint":`Mặc định tắt; chỉ dành cho authenticated loopback. Các compactions trong tương lai sẽ lưu trữ các bản tóm tắt văn bản thuần trong khi OpenCodeX và V2 provider routing vẫn hoạt động; provider được cấu hình có thể xử lý chúng và tiêu tốn quota. Lịch sử được giữ nguyên, và các luồng (threads) hiện tại tiếp tục định tuyến qua proxy thông qua ghi đè openai_base_url mà OpenCodeX quản lý; nếu bạn tự thiết lập dòng đó, nó sẽ được giữ lại và các luồng đó sẽ tuân theo đích đến của bạn thay thế. Lịch sử ocx1 hiện tại vẫn có thể khôi phục được; chỉ khôi phục một luồng riêng biệt trước khi phát lại (replay) trong Codex native. Khởi động lại Codex sau khi thay đổi cài đặt này.`,"models.v2Conflict":`[agents] max_threads đã được thiết lập — codex sẽ từ chối khởi động; hãy xoá nó khỏi config.toml`,"models.v2Applied":`Chế độ agent con đã được cập nhật — áp dụng cho các phiên mới (khởi động lại ứng dụng Codex để làm mới picker)`,"models.v2ThreadsLabel":`Luồng tối đa (Max threads)`,"models.v2ThreadsDefault":`mặc định (4)`,"models.v2ThreadsApplied":`Giới hạn luồng đã được cập nhật — áp dụng cho các phiên mới`,"models.v2ThreadsInvalid":`Giới hạn luồng phải là số nguyên >= 1`,"models.v2ThreadsApply":`Áp dụng`,"models.capValue":`Mặc định {value}`,"models.contextSettings":`Cửa sổ tuỳ chỉnh (Custom windows)`,"models.contextSettingsTitle":`Cửa sổ tuỳ chỉnh — {provider}`,"models.contextDefault":`Mặc định của provider`,"models.contextModel":`Model`,"models.contextModelOverride":`Ghi đè model`,"models.contextHint":`Ghi cửa sổ (window) Codex thực tế vào đây khi bạn đã biết nó. Việc này điền vào một cửa sổ upstream bị thiếu và chỉ làm giảm bớt nếu cửa sổ được báo cáo lớn hơn. Để trống để sử dụng cửa sổ/giới hạn Mặc định của provider, hoặc 128k nếu giới hạn đó đã bị tắt.`,"models.contextAutomatic":`Khám phá tự động (Automatic discovery)`,"models.contextSaved":`Cửa sổ ngữ cảnh (Context windows) đã được cập nhật — có hiệu lực ở lượt Codex tiếp theo.`,"models.contextUnchanged":`Không có thay đổi nào về cửa sổ ngữ cảnh để lưu.`,"models.contextSaveFailed":`Lỗi lưu cửa sổ ngữ cảnh`,"models.contextInvalid":`Cửa sổ ngữ cảnh phải là số nguyên dương`,"models.contextCappedValue":`giới hạn {value}`,"models.setAll":`Thiết lập tất cả`,"models.setAllHint":`Bật cửa sổ mặc định {value} cho mọi provider được định tuyến. Các relay bỏ qua context_window / context_length sẽ nhận giá trị này làm cửa sổ Codex thực tế. Sử dụng Cửa sổ tuỳ chỉnh trên một hàng provider để thiết lập một model bằng tay. Các native provider không bị ảnh hưởng.`,"models.collapseAll":`Thu gọn tất cả`,"models.expandAll":`Mở rộng tất cả`,"models.orderHint":`Thứ tự mặc định tuân theo các lựa chọn nổi bật và độ ưu tiên của catalog; các hàng định tuyến cùng hạng được sắp theo provider/model. Thứ tự picker đã lưu có thể thay đổi cách hiển thị; công tắc hiển thị lọc các hàng xuất hiện. Client có thể giữ catalog cũ cho đến lần tải tiếp theo.`,"models.custom":`Tuỳ chỉnh…`,"models.customApply":`Áp dụng`,"models.customPlaceholder":`Tokens (ví dụ: 420000)`,"models.customAdd":`Thêm model tuỳ chỉnh`,"models.customAddTitle":`Thêm model tuỳ chỉnh — {provider}`,"models.customEditTitle":`Chỉnh sửa model tuỳ chỉnh — {provider}`,"pws.manageModelVisibility":`Quản lý hiển thị trong Models`,"pws.modelOwnershipLoading":`Đang kiểm tra định nghĩa model…`,"pws.modelOwnershipFailed":`Không thể tải định nghĩa model. Hãy thử lại trước khi thay đổi.`,"pws.modelSelectionPending":`Hoàn tất việc chọn model trong Models trước khi thay đổi.`,"pws.modelSaved":`Định nghĩa model tuỳ chỉnh đã được lưu.`,"pws.modelSavedHidden":`Đã lưu định nghĩa. Model này đang bị ẩn; hãy quản lý hiển thị trong Models.`,"pws.modelSavedRefreshPending":`Đã lưu định nghĩa, nhưng không thể làm mới danh mục model (model catalog). Hãy thử làm mới lại; đừng thêm lại model đó.`,"pws.modelMutationUnconfirmed":`Không thể xác nhận thay đổi. Hãy làm mới danh sách model trước khi thử lại.`,"pws.modelRemovedRefreshPending":`Thay đổi đã được lưu, nhưng không thể làm mới danh mục model. Hãy thử làm mới lại.`,"pws.modelHidden":`Model đã ẩn. Khôi phục hiển thị trong Models.`,"pws.modelDefinitionDeleted":`Định nghĩa tuỳ chỉnh đã bị xoá. Một model cơ sở (underlying model) vẫn có thể xuất hiện.`,"pws.modelKnown":`Model này đã được nhận diện. Quản lý hiển thị của nó trong Models.`,"models.customAdded":`Đã thêm model tuỳ chỉnh`,"models.customUpdated":`Đã cập nhật model tuỳ chỉnh`,"models.customDeleted":`Đã xoá model tuỳ chỉnh`,"models.customSaveFailed":`Lỗi lưu model tuỳ chỉnh`,"models.customSaving":`Đang lưu…`,"models.customAddBtn":`Thêm`,"models.customEditBtn":`Cập nhật`,"models.customEdit":`Chỉnh sửa`,"models.customDelete":`Xóa`,"models.customDeleteConfirm":`Xoá định nghĩa tuỳ chỉnh cho {name}? Một model gốc hoặc được khám phá tự động có thể xuất hiện trở lại.`,"models.hide":`Ẩn`,"models.hideConfirm":`Ẩn {name} khỏi danh mục model? Điều này không xoá định nghĩa của nó hay thay đổi chính sách định tuyến trực tiếp.`,"models.customBadge":`Tùy chỉnh`,"models.customSummary":`{count} tuỳ chỉnh`,"models.customFieldModelId":`Model ID (endpoint slug)`,"models.customFieldModelIdPlaceholder":`ví dụ: qwen4-max-preview`,"models.customFieldDisplayName":`Tên hiển thị (không bắt buộc)`,"models.customFieldDisplayNamePlaceholder":`ví dụ: Qwen 4 Max Preview`,"models.customFieldContext":`Cửa sổ ngữ cảnh (Context window)`,"models.customFieldModalities":`Đầu vào (Input modalities)`,"models.customFieldReasoning":`Nỗ lực suy luận (Reasoning effort)`,"models.customFieldReasoningOverride":`Ghi đè nỗ lực suy luận (Override reasoning effort)`,"models.reasoningEffort.none":`Không có`,"models.reasoningEffort.minimal":`Tối thiểu (Minimal)`,"models.reasoningEffort.low":`Thấp (Low)`,"models.reasoningEffort.medium":`Trung bình (Medium)`,"models.reasoningEffort.high":`Cao (High)`,"models.reasoningEffort.xhigh":`Rất cao (Extra high)`,"models.reasoningEffort.max":`Tối đa (Maximum)`,"models.reasoningEffort.ultra":`Tối thượng (Ultra)`,"models.tipProvider":`Nhà cung cấp`,"models.tipContext":`Ngữ cảnh`,"models.tipModalities":`Đầu vào (Modalities)`,"models.tipStatus":`Trạng thái`,"models.tipActive":`Đang hoạt động`,"models.tipDisabled":`Đã tắt`,"models.applied":`Đã lưu trên hub. Việc client tải catalog và kích hoạt trong thời gian chạy là hai trạng thái riêng biệt.`,"models.integrationRefreshWarning":`Đã lưu lựa chọn model. Một số danh mục client không thể được làm mới. Hãy kiểm tra Integrations trước khi bắt đầu phiên mới.`,"models.saveFailed":`Lưu thất bại`,"models.networkError":`Lỗi mạng — proxy có đang chạy không?`,"models.loadFail":`Lỗi tải danh sách model — proxy có đang chạy không?`,"models.noRouted":`Không có model được định tuyến`,"models.noRoutedHint":`Vui lòng đăng nhập vào một provider hoặc thêm một model trước.`,"models.emptyDiscovery":`Không tìm thấy model nào. Hãy kiểm tra endpoint của provider hoặc thêm model tĩnh/tuỳ chỉnh.`,"models.emptyDiscoveryDisabled":`Tính năng khám phá model trực tiếp đang tắt và không có model tĩnh nào được cấu hình.`,"models.discoveryFailedBadge":`Khám phá thất bại`,"models.discoveryFailedHttp":`Khám phá model thất bại (HTTP {status}).`,"models.discoveryFailedBlocked":`Khám phá model bị chặn bởi chính sách đích.`,"models.discoveryFailedInvalidResponse":`Khám phá model trả về phản hồi không hợp lệ.`,"models.discoveryFailedNetwork":`Khám phá model thất bại do lỗi mạng.`,"models.discoveryFailedProvider":`Provider báo lỗi khám phá model.`,"models.discoveryFailedGeneric":`Khám phá model thất bại.`,"models.openProviderSettings":`Mở cài đặt provider`,"models.inactiveNoCredit":`Hết credit`,"models.inactiveNoCreditHint":`Mọi provider phía sau mục này hiện đều đã hết credit, do đó yêu cầu sẽ thất bại. Nó vẫn hiển thị trong danh sách và có thể sử dụng lại khi credit được đặt lại hoặc nạp thêm.`,"models.discoveryFailedDependency":`Tính năng khám phá model đang bật cho provider này. Trong khi tính năng này liên tục thất bại, hãy tắt “{control}” trong cài đặt provider để sử dụng các model được thêm thủ công hoặc model tĩnh để thay thế.`,"models.loading":`Đang tải…`,"models.search":`Tìm kiếm model…`,"models.showMore":`Hiển thị thêm {n}`,"models.freeOnly":`Chỉ miễn phí`,"models.noFreeMatch":`Không có model miễn phí ở đây. Tắt Chỉ miễn phí để xem phần còn lại.`,"models.allowlistLabel":`Chỉ các mục đã chọn`,"models.allowlistHint":`Chỉ các model được chọn mới gửi đến danh mục (để trống = tất cả). Hữu ích cho các provider cung cấp hàng nghìn model.`,"models.selectedCount":`Đã chọn {n}`,"sub.subtitle":`{cmd} của Codex chỉ quảng bá 5 model đầu tiên (theo mức độ ưu tiên) làm ghi đè (overrides). Chọn tối đa 5 model ở đây — native gpt hoặc routed — và opencodex sẽ đặt mức độ ưu tiên trong catalog của chúng để những model này dẫn đầu. Bất kỳ model nào khác vẫn có thể được gọi bằng đúng tên của nó; cài đặt này chỉ kiểm soát những gì được hiển thị.`,"sub.featured":`Nổi bật (Featured)`,"sub.advanced":`Nâng cao (Advanced)`,"sub.orderHintAria":`Cách thứ tự này được sử dụng`,"sub.orderHint":`Thứ tự hiển thị ở đây thiết lập các vị trí 1–5 ở đầu picker model của Codex và các model mặc định cho {cmd}.`,"sub.noneSelected":`Chưa chọn — hãy chọn từ danh sách bên dưới.`,"sub.models":`Models`,"sub.search":`Tìm kiếm model (native gpt + routed)…`,"sub.settings":`Cài đặt`,"sub.sections":`Các phần agent con (Subagent sections)`,"sub.delegation.model":`Model sẽ gọi đầu tiên`,"sub.delegation.modelHint":`Model mà Codex gọi đầu tiên khi bàn giao (hands off) công việc. Nổi bật bên trên là danh sách model nó có thể gọi; đây là model nó gọi đầu tiên.`,"sub.noModels":`Không có model — vui lòng đăng nhập vào provider hoặc thêm model trước.`,"sub.saved":`Đã lưu {n} model. Hãy bắt đầu phiên Codex mới (hoặc chạy {cmd}) để thấy chúng dưới dạng ghi đè spawn_agent.`,"sub.saveFailed":`Lưu thất bại`,"sub.networkError":`Lỗi mạng — proxy có đang chạy không?`,"sub.loadFail":`Lỗi tải model — proxy có đang chạy không?`,"sub.loading":`Đang tải…`,"sub.moveUp":`Di chuyển {m} lên`,"sub.moveDown":`Di chuyển {m} xuống`,"sub.removeAria":`Xoá {m}`,"sub.workspace.addToFeatured":`Thêm {m} vào phần Nổi bật`,"sub.workspace.allModels":`Tất cả model`,"sub.workspace.featuredFull":`Danh sách Nổi bật đã đầy (tối đa 5)`,"sub.workspace.mainAria":`Chi tiết model của agent con`,"sub.workspace.notFeatured":`Không nổi bật`,"sub.workspace.priority":`Ưu tiên`,"sub.ultraMode":`Luôn uỷ quyền chủ động`,"sub.ultraModeHint":`Bật chính sách uỷ quyền đa agent chủ động (Proactive multi-agent delegation) cho mọi model và nỗ lực suy luận (không làm thay đổi bản thân nỗ lực suy luận). Ghi thiết lập vào features.multi_agent_v2.multi_agent_mode_hint_text trong config.toml.`,"sub.ultraModeV2Required":`Yêu cầu giao diện đa agent v2 (v2 multi-agent surface) — bật multi_agent_v2 và chọn v2 trong trình điều khiển Chế độ agent con (Sub-agent mode) trước.`,"sub.ultraModeText":`Văn bản uỷ quyền chủ động`,"sub.ultraModePreset":`Khôi phục preset`,"sub.ultraModeLoadFail":`Lỗi tải cài đặt uỷ quyền chủ động — proxy có đang chạy không?`,"sub.ultraModeSaveFail":`Lỗi lưu cài đặt uỷ quyền chủ động`,"sub.ultraModeSaved":`Đã lưu uỷ quyền chủ động. Áp dụng cho các phiên Codex mới.`,"sub.workspace.removeFromFeatured":`Xoá {m} khỏi phần Nổi bật`,"sub.workspace.selectModel":`Chọn một model`,"sub.workspace.selectModelDesc":`Chọn một model từ danh sách để xem chi tiết và đưa nó vào danh sách nổi bật cho spawn_agent.`,"sub.workspace.selector":`Bộ chọn công khai (Public selector)`,"sub.fallbackLabel":`Chuỗi dự phòng của agent con`,"sub.fallbackHint":`Các model có thứ tự được thử nghiệm khi model agent con không khả dụng hoặc bị lỗi.`,"sub.fallbackAdd":`Thêm model dự phòng…`,"sub.fallbackPoll":`Khoảng thời gian kiểm tra khả dụng (Availability check interval)`,"sub.fallbackSaved":`Đã lưu cài đặt dự phòng của agent con.`,"sub.fallbackSaveFailed":`Lỗi lưu cài đặt dự phòng`,"sub.fallbackUnavailable":`Hiện không được quảng bá; vẫn được giữ trong chuỗi dự phòng.`,"sub.fallbackPollInvalid":`Vui lòng nhập một số nguyên từ 5000 đến 600000 ms.`,"sub.v2Compatibility.title":`Khả năng tương thích V2 của Native-parent`,"sub.v2Compatibility.risk":`Nếu model cha ChatGPT-native uỷ quyền cho model định tuyến (routed model) này bằng V2, task của nó có thể bị mã hoá và thất bại trước khi thực thi. Các task có thể đọc được từ model cha định tuyến không bị ảnh hưởng.`,"sub.v2Compatibility.recoveryUnknown":`Trạng thái bật phục hồi/đủ điều kiện không được tiết lộ bởi máy chủ này. Hãy dùng V1/uỷ quyền tương thích văn bản thuần (plaintext-compatible delegation), hoặc chỉ bật khôi phục V2 thử nghiệm (experimental V2 recovery) nếu đủ điều kiện. Khôi phục sẽ tăng thêm tiêu tốn quota, độ trễ, phụ thuộc backend và có khả năng làm giảm độ chính xác; nó không sửa được giao thức upstream.`,"sub.v2Compatibility.details":`Chi tiết tương thích`,"logs.title":`Nhật ký yêu cầu`,"logs.tabLogs":`Nhật ký`,"logs.tabDebug":`Gỡ lỗi`,"logs.subtitle":`Các request gần đây được định tuyến qua local opencodex proxy, mới nhất ở trên cùng.`,"logs.autoRefresh":`Tự động làm mới`,"logs.noRequests":`Chưa có request nào.`,"logs.loadError":`Không thể tải logs request.`,"logs.filter.surface.label":`Giao diện (Surface)`,"logs.filter.model.all":`Tất cả model`,"logs.filter.provider.label":`Nhà cung cấp`,"logs.filter.provider.all":`Tất cả provider`,"logs.filter.status.label":`Trạng thái`,"logs.filter.status.all":`Tất cả trạng thái`,"logs.filter.status.success":`Thành công (2xx)`,"logs.filter.status.errors":`Lỗi (4xx/5xx)`,"logs.filter.time.label":`Thời gian`,"logs.filter.time.all":`Tất cả thời gian`,"logs.filter.time.15m":`15 phút qua`,"logs.filter.time.1h":`1 giờ qua`,"logs.filter.time.24h":`1 ngày qua`,"logs.filter.speed.label":`Tốc độ`,"logs.filter.speed.all":`Tất cả tốc độ`,"logs.filter.speed.slow":`< 15 tok/s`,"logs.filter.speed.medium":`15–< 50 tok/s`,"logs.filter.speed.fast":`≥ 50 tok/s`,"logs.filter.reset":`Đặt lại bộ lọc`,"logs.filter.showingCount":`Đang hiển thị {count} / {total}`,"logs.noMatchingRequests":`Không có request nào phù hợp.`,"logs.filter.surface.all":`Tất cả`,"logs.filter.surface.claude":`Claude`,"logs.filter.surface.codex":`Codex`,"logs.filter.surface.grok":`Grok`,"logs.filter.interceptedHelpersOnly":`Chỉ helper bị chặn lại (Intercepted helpers only)`,"logs.badge.interceptedHelper":`I · {model}`,"logs.badge.interceptedHelperTitle":`Yêu cầu phụ trợ bị chặn`,"logs.filter.conversation.label":`Cuộc hội thoại`,"logs.filter.conversation.placeholder":`Dán id cuộc hội thoại`,"logs.filter.model.label":`Model`,"logs.filter.model.placeholder":`Lọc theo model hoặc provider`,"logs.filter.conversation.apply":`Lọc logs`,"logs.conversation.totals":`{requests} yêu cầu · {tokens} token · {cost}`,"logs.conversation.scope":`Tổng số liệu chỉ áp dụng cho bộ đệm Logs đang được tải.`,"logs.conversation.excluded":`(đã loại trừ {unpriced} không có giá, {unmetered} không đo lường khỏi khoản ước tính ~$)`,"logs.cost.approximate":`{amount}`,"logs.cost.lowerBound":`≥{amount}`,"logs.cost.unavailable":`—`,"logs.detail.conversation":`Cuộc hội thoại`,"logs.badge.claude":`Claude`,"logs.badge.grok":`Grok`,"logs.col.time":`Thời gian`,"logs.col.request":`Yêu cầu`,"logs.col.model":`Model`,"logs.col.effort":`Nỗ lực (Effort)`,"logs.col.provider":`Nhà cung cấp`,"logs.col.status":`Trạng thái`,"logs.col.tokens":`Tokens`,"logs.col.tokPerSec":`tok/s`,"logs.col.estimatedCost":`~$`,"logs.metric.tokPerSecTitle":`Số output token mỗi giây trên toàn bộ thời lượng request`,"logs.metric.estimatedCostTitle":`Mức tương đương giá niêm yết của API, không phải là mức phí thực tế; không khả dụng với giá không khớp`,"usage.cost.total":`Tương đương giá niêm yết API (phạm vi này)`,"usage.cost.disclaimer":`Đây không phải biên lai thanh toán. Mức sử dụng thuê bao hoặc credit của provider có thể được áp dụng thay thế.`,"usage.cost.unpricedNote":`Đã loại trừ {count} requests (không có giá hoặc mức sử dụng)`,"usage.cost.excluded":`({count} yêu cầu bị loại trừ)`,"usage.cost.excludedOne":`({count} yêu cầu bị loại trừ)`,"logs.detail.section.basic":`Thông tin cơ bản`,"logs.detail.route.section":`Quyết định định tuyến (Route decision)`,"logs.detail.route.kind":`Loại định tuyến (Route kind)`,"logs.detail.route.profile":`Profile`,"logs.detail.route.selected":`Đã chọn`,"logs.detail.route.candidates":`Ứng viên (Candidates)`,"logs.detail.route.unknown":`Không có dấu vết định tuyến (route trace) nào được ghi lại cho request này (pre-trace row).`,"logs.detail.section.performance":`Hiệu suất (Performance)`,"logs.detail.section.cost":`Mức tương đương giá niêm yết API`,"logs.detail.section.attempts":`Lượt thử kết hợp (Combo attempts)`,"logs.detail.section.usage":`Mức sử dụng thô (Raw usage)`,"logs.detail.ttft":`TTFT`,"logs.detail.decodeTokPerSec":`Tốc độ decode (ước tính)`,"logs.detail.reason.ttft_missing":`Không ghi nhận thời gian đến token đầu tiên (time-to-first-token) cho request này, nên không có cửa sổ decode nào để đo lường.`,"logs.detail.reason.decode_window_too_short":`Cửa sổ sau token đầu tiên nhỏ hơn một giây, quá ngắn để ước tính tốc độ decode.`,"logs.detail.costTotal":`Tương đương giá niêm yết`,"logs.detail.totalTokens":`Tổng số tokens`,"logs.detail.matchedKey":`Khoá giá trùng khớp (Matched price key)`,"logs.detail.priceSource":`Nguồn giá (Price source)`,"logs.detail.unavailableReason":`Lý do không khả dụng`,"logs.detail.copyRequestId":`Sao chép ID request`,"logs.detail.copied":`Đã sao chép`,"logs.detail.source.jawcode":`Danh mục jawcode`,"logs.detail.source.expected":`Giá niêm yết mong đợi (Expected price overlay)`,"logs.detail.source.user":`Giá tuỳ chỉnh của provider (Provider-configured price overlay)`,"logs.detail.verification.verified":`Đã xác minh (Verified)`,"logs.detail.verification.derived":`Bắt nguồn từ model cơ sở (Derived from base model)`,"logs.detail.attempt.target":`Nhà cung cấp / model`,"logs.detail.attempt.reason":`Kết quả / lý do`,"logs.detail.attempt.completed":`Đã hoàn thành`,"logs.detail.attempt.e2eNote":`Chỉ số tok/s tổng thể (top-level) là tính từ đầu đến cuối (end-to-end); mỗi lần thử (attempt) sử dụng thời lượng riêng của nó.`,"logs.detail.attempt.recovery.transient5xx":`Lỗi tạm thời 5xx (Transient 5xx)`,"logs.detail.attempt.recovery.connectionReset":`Kết nối bị đặt lại (Connection reset)`,"logs.detail.attempt.recovery.oauth401":`Xác thực lại OAuth (OAuth re-authentication)`,"logs.detail.attempt.recovery.key429":`Khoá bị giới hạn tỷ lệ (Key rate-limited 429)`,"logs.detail.attempt.recovery.rateLimit429":`Bị giới hạn tỷ lệ (Rate-limited 429)`,"logs.detail.attempt.recovery.anthropicOauth429":`Xác thực Anthropic OAuth bị giới hạn tỷ lệ (429)`,"logs.detail.attempt.recovery.image413":`Kích thước hình ảnh quá lớn (413)`,"logs.detail.attempt.recovery.emptyCompletion":`Thử lại do hoàn thành rỗng (Empty completion retry)`,"logs.detail.attempt.recovery.consoleGoUpload":`Thử lại tải lên Console`,"logs.detail.attempt.recovery.key401":`Xác thực lại khóa API`,"logs.detail.attempt.recovery.oauthAccount429":`Tài khoản bị giới hạn tần suất (429)`,"logs.detail.attempt.recovery.opaqueBlobRejection":`Đã bỏ trạng thái mã hóa cũ`,"logs.detail.attempt.recovery.reasoningEffortDowngrade":`Đã giảm mức suy luận`,"logs.detail.outcome.label":`Kết quả`,"logs.detail.outcome.completed":`Hoàn tất`,"logs.detail.outcome.failed":`Thất bại`,"logs.detail.outcome.incomplete":`Chưa hoàn tất`,"logs.detail.outcome.aborted":`Đã hủy`,"logs.detail.sends.label":`Số lần gửi lên nhà cung cấp`,"logs.detail.sends.unresolved":`chưa xác định`,"logs.detail.attempt.recovery.unknown":`Lý do khôi phục không rõ`,"logs.detail.cause.label":`Nguyên nhân lỗi`,"logs.detail.stage.label":`đã đến`,"logs.detail.resend.label":`Gửi lại`,"logs.detail.cause.transportUnsent":`Chưa gửi lên thượng nguồn`,"logs.detail.cause.transportAmbiguous":`Mất kết nối, không rõ trạng thái thượng nguồn`,"logs.detail.cause.upstreamDeclined":`Thượng nguồn từ chối bắt đầu`,"logs.detail.cause.rateLimit":`Bị giới hạn tốc độ`,"logs.detail.cause.quotaExhausted":`Đã hết hạn mức`,"logs.detail.cause.credentialRejected":`Thông tin xác thực bị từ chối`,"logs.detail.cause.policyRefusal":`Bị chính sách nội dung từ chối`,"logs.detail.cause.parameterRejected":`Tham số yêu cầu bị từ chối`,"logs.detail.cause.ciphertextRefusal":`Trạng thái mã hoá bị từ chối`,"logs.detail.cause.payloadTooLarge":`Tải trọng quá lớn`,"logs.detail.cause.payloadRejected":`Tải trọng bị từ chối`,"logs.detail.cause.upstreamFault":`Lỗi thượng nguồn`,"logs.detail.cause.emptyOutput":`Không có đầu ra dùng được`,"logs.detail.cause.clientCancelled":`Ứng dụng khách đã huỷ`,"logs.detail.cause.localRefusal":`Proxy này từ chối`,"logs.detail.stage.preHeader":`không có đầu phản hồi`,"logs.detail.stage.headersOnly":`chỉ có tiêu đề`,"logs.detail.stage.protocolPrelude":`phần mở đầu giao thức`,"logs.detail.stage.semanticOutput":`đã gửi đầu ra`,"logs.detail.stage.sideEffect":`đã phát sinh tác dụng phụ`,"logs.detail.stage.terminal":`đã gửi câu trả lời`,"logs.detail.resend.permitted":`Có thể gửi lại`,"logs.detail.resend.permittedAfterRepair":`Có thể gửi lại sau khi sửa`,"logs.detail.resend.refusedAmbiguous":`Không gửi lại: không rõ trạng thái thượng nguồn`,"logs.detail.resend.refusedCommitted":`Không gửi lại: bên gọi đã thấy đầu ra`,"logs.detail.resend.refusedFutile":`Không gửi lại: yêu cầu tương tự vẫn sẽ lỗi`,"logs.detail.reason.usage_missing":`Mức sử dụng không được báo cáo.`,"logs.detail.reason.usage_unsupported":`Provider này không báo cáo mức sử dụng.`,"logs.detail.reason.output_missing":`Không có số lượng output token dương nào được báo cáo.`,"logs.detail.reason.invalid_duration":`Thời lượng request không hợp lệ.`,"logs.detail.reason.price_unmatched":`Không tìm thấy giá khớp.`,"logs.detail.reason.invalid_cache_breakdown":`Chi tiết cache token không khớp với tổng số input token.`,"logs.detail.reason.invalid_usage":`Mức sử dụng chứa giá trị token không hợp lệ.`,"logs.detail.reason.combo_attempt_unavailable":`Ít nhất một lượt thử kết hợp (combo attempt) không thể định giá.`,"logs.detail.estimate.usage_estimated":`Mức sử dụng của provider được ước tính.`,"logs.detail.estimate.cache_detail_missing":`Chi tiết cache không khả dụng; đầu vào là ước tính giới hạn trên.`,"logs.detail.estimate.expected_price_overlay":`Một giá niêm yết kỳ vọng (expected list price) đã xác minh được sử dụng.`,"logs.detail.estimate.provider_cost_overlay":`Sử dụng giá tuỳ chỉnh do provider cấu hình.`,"logs.detail.estimate.priority_lower_bound":`Giá Ưu tiên (Priority price) đã xác nhận không khả dụng; ước tính hiển thị là giới hạn dưới đã biết.`,"logs.col.error":`Lỗi`,"logs.col.upstreamReason":`Lý do upstream`,"logs.col.duration":`Thời lượng`,"logs.modelTooltip.model":`model`,"logs.modelTooltip.resolvedModel":`model đã giải quyết (resolved model)`,"logs.modelTooltip.requestedTier":`bậc (tier) được yêu cầu`,"logs.modelTooltip.configuredTier":`bậc (tier) cấu hình`,"logs.modelTooltip.responseTier":`bậc (tier) phản hồi`,"logs.modelTooltip.supportsTier":`hỗ trợ tier`,"logs.modelTooltip.tierOutcome.confirmed":`đã xác nhận`,"logs.modelTooltip.tierOutcome.assumed":`giả định`,"logs.modelTooltip.tierOutcome.downgraded":`đã hạ bậc`,"logs.modelTooltip.tierOutcome.unknown":`không rõ`,"logs.tokens.reported":`đã báo cáo`,"logs.tokens.unreported":`không báo cáo`,"logs.tokens.unsupported":`không hỗ trợ`,"logs.tokens.estimated":`ước tính`,"logs.tokens.input":`input`,"logs.tokens.output":`output`,"logs.tokens.cacheRead":`cache read (c)`,"logs.tokens.cacheWrite":`cache write (w)`,"logs.tokens.reasoning":`reasoning`,"logs.tokens.noCache":`không có dữ liệu cache`,"logs.tokens.contextTotal":`tổng ngữ cảnh hoạt động`,"logs.tokens.noCacheNote":`provider này không báo cáo số lượng cache tokens`,"logs.tokens.noCacheCursor":`Chi tiết bộ nhớ cache của Cursor không được báo cáo`,"logs.tokens.noCacheCursorNote":`Cursor không tiết lộ số lượng cache read/write token; thông tin này chưa được biết (unknown), không phải là xác nhận cache miss`,"logs.tokens.estimatedNote":`ước tính (provider không báo cáo mức sử dụng chính xác)`,"logs.details":`Chi tiết`,"logs.detailTitle":`Chi tiết request`,"logs.detailRaw":`Mục log thô`,"debug.title":`Gỡ lỗi`,"debug.subtitle":`Chuẩn đoán (Diagnostics) về trích xuất mức sử dụng và luồng truyền (transport) của provider tuỳ chọn. Các request lỗi và 502 vẫn ở tab Logs.`,"debug.debug":`Debug của provider`,"debug.usage":`Trích xuất mức sử dụng`,"debug.injection":`Log can thiệp (Injection log)`,"debug.claude":`Claude đầu vào (Claude inbound)`,"debug.claudeInbound.title":`Các request đầu vào từ Claude`,"debug.claudeInbound.sub":`Những gì Claude Code/Desktop thực sự gửi (thinking, effort, metadata) — không có nội dung text của prompt nào được lưu.`,"debug.claudeInbound.empty":`Chưa thu được request nào. Hãy gửi một tin nhắn từ Claude trong khi tính năng này được bật.`,"debug.claudeInbound.time":`Thời gian`,"debug.claudeInbound.endpoint":`Endpoint`,"debug.claudeInbound.model":`Model`,"debug.claudeInbound.none":`không có`,"debug.reset":`Xoá các thay đổi runtime (runtime overrides)`,"debug.refresh":`Làm mới`,"debug.follow":`Theo dõi (Follow)`,"debug.streamProvider":`Nhà cung cấp`,"debug.streamUsage":`Mức sử dụng`,"debug.streamInjection":`Sự can thiệp (Injection)`,"debug.loading":`Đang tải cài đặt debug…`,"debug.loadFailed":`Không thể tải cài đặt debug.`,"debug.emptyTitle":`Ghi log debug đang tắt`,"debug.empty":`Bật Provider debug hoặc Trích xuất mức sử dụng (Usage extraction) trong thẻ bên trên. Các dòng log sẽ xuất hiện ở đây sau khi bạn gửi một request qua proxy.`,"debug.noLinesTitle":`Đang chờ dòng (Waiting for lines)`,"debug.noLines.provider":`Tính năng Provider debug đang bật, nhưng nó chỉ ghi lại những bất thường trong quá trình truyền dữ liệu (dropped or malformed frames, và các sự kiện quay số/thử lại của Cursor). Một request không lỗi qua provider như Anthropic có thể không tạo ra dòng nào.`,"debug.noLines.usage":`Trích xuất mức sử dụng đang bật nhưng chưa thu thập được dữ liệu. Gửi một chat/request thông qua Codex và log sẽ hiện ra ở đây.`,"debug.noLines.injection":`Log can thiệp (Injection log) đang bật nhưng chưa thu thập được dữ liệu. Tính năng này ghi lại các can thiệp về hướng dẫn đa agent (multi-agent guidance injection) và quyết định nỗ lực trong các lượt cộng tác (collab) hoặc qua agent con.`,"usage.title":`Mức sử dụng`,"usage.subtitle":`Quản lý token cục bộ (local token accounting) từ proxy của bạn. Mức sử dụng bị thiếu sẽ không bao giờ hiển thị bằng 0 (zero).`,"usage.loading":`Đang tải dữ liệu sử dụng…`,"usage.empty":`Chưa có mức sử dụng nào được ghi lại. Gửi một request qua proxy để thấy hoạt động ở đây.`,"usage.loadError":`Không thể tải dữ liệu sử dụng.`,"usage.range.all":`Tất cả`,"usage.range.available":`Lịch sử khả dụng`,"usage.historyTruncated":`Số tổng chỉ bao gồm lịch sử có sẵn vì các dữ liệu sử dụng cũ hơn không được tải.`,"usage.historyTruncatedWindow":`Các hàng được tải có thời gian bắt đầu (request start times) từ {start} đến {end}. Các mục file cũ hơn đã bị bỏ qua bởi giới hạn đọc (read limit), do đó bất kỳ phạm vi đã chọn nào cũng có thể không đầy đủ.`,"usage.range.30d":`30 ngày`,"usage.range.7d":`7 ngày`,"usage.card.requests":`Yêu cầu`,"usage.card.measured":`Đã đo lường (Measured)`,"usage.card.reported":`Đã báo cáo (Reported)`,"usage.card.totalTokens":`Tổng số tokens`,"usage.card.cachedTokens":`Đọc cache (Cache reads)`,"usage.card.cachedTokensHint":`Prompt tokens được phục vụ từ cache của provider (cache reads). Cache writes sẽ hiển thị bên dưới nếu có.`,"usage.card.cacheWriteTokens":`ghi cache (cache writes)`,"usage.card.coverage":`Độ phủ (Coverage)`,"usage.card.activeDays":`Số ngày hoạt động`,"usage.section.heatmap":`Hoạt động hàng ngày`,"usage.section.overview":`Tổng quan`,"usage.section.models":`Models`,"usage.section.providers":`Nhà cung cấp`,"usage.section.coverage":`Chi tiết độ phủ (Coverage breakdown)`,"usage.section.companion":`Thanh menu và widget`,"usage.companion.title":`Thanh menu và widget`,"usage.companion.description":`Các cài đặt ở đây điều khiển ứng dụng máy tính/thanh menu OpenCodex và widget của ứng dụng.`,"usage.companion.installGuide":`Hướng dẫn cài đặt`,"usage.companion.loading":`Đang tải dòng thời gian…`,"usage.companion.timelineUnavailable":`Không có dòng thời gian`,"usage.companion.empty":`Không có lượt dùng trong {hours} giờ qua`,"usage.companion.chartLabel":`Dòng thời gian sử dụng`,"usage.companion.olderRecordsSkipped":`Đã bỏ qua các bản ghi cũ hơn`,"usage.companion.settingsUnavailable":`Không có cài đặt companion`,"usage.companion.corrupt":`Tệp cài đặt companion bị hỏng. Các điều khiển hiển thị giá trị mặc định; việc lưu bị tạm dừng cho đến khi bạn thay thế tệp.`,"usage.companion.corruptReset":`Thay thế bằng mặc định`,"usage.companion.saved":`Đã lưu · {time}`,"usage.companion.saveFailed":`Không thể lưu: {error}`,"usage.companion.reset":`Đặt lại mặc định`,"usage.companion.footer":`Widget hiển thị số yêu cầu, token và chi phí hôm nay cùng biểu đồ được cấu hình ở đây, rồi làm mới khi ứng dụng thăm dò.`,"usage.companion.menuBarShows":`Thanh menu hiển thị`,"usage.companion.menuRequests":`Yêu cầu`,"usage.companion.menuTokens":`Token`,"usage.companion.menuCost":`Chi phí`,"usage.companion.menuQuota":`Hạn mức`,"usage.companion.menuNone":`Chỉ biểu tượng`,"usage.companion.window":`Khoảng thời gian`,"usage.companion.window6":`6 giờ`,"usage.companion.window24":`24 giờ`,"usage.companion.window72":`3 ngày`,"usage.companion.window168":`7 ngày`,"usage.companion.style":`Kiểu`,"usage.companion.styleLine":`Đường`,"usage.companion.styleStacked":`Xếp chồng`,"usage.companion.metric":`Chỉ số`,"usage.companion.metricTotal":`Tổng`,"usage.companion.metricInput":`Đầu vào`,"usage.companion.metricOutput":`Đầu ra`,"usage.companion.metricCached":`Đã lưu đệm`,"usage.companion.groupBy":`Nhóm theo`,"usage.companion.groupModel":`Mô hình`,"usage.companion.groupAccount":`Mô hình + tài khoản`,"usage.companion.popoverSections":`Mục popover`,"usage.companion.sectionToday":`Hôm nay`,"usage.companion.sectionChart":`Biểu đồ`,"usage.companion.sectionModels":`Mô hình`,"usage.companion.sectionCost":`Chi phí`,"usage.companion.sectionAccounts":`Tài khoản`,"usage.companion.advanced":`Nâng cao`,"usage.companion.aggregation":`Tổng hợp`,"usage.companion.aggregationSum":`Tổng`,"usage.companion.aggregationAverage":`Trung bình`,"usage.companion.aggregationMax":`Tối đa`,"usage.companion.menuText":`Văn bản thanh menu`,"usage.companion.placeholders":`Trình giữ chỗ:`,"usage.companion.modelsOnChart":`Mô hình trên biểu đồ`,"usage.companion.connected":`Ứng dụng trên thanh menu đã kết nối · {age}`,"usage.companion.connectedDesktop":`Ứng dụng máy tính đã kết nối · {age}`,"usage.companion.installTitle":`Cài đặt ứng dụng máy tính`,"usage.companion.installOs":`Hệ điều hành`,"usage.companion.osMac":`macOS`,"usage.companion.osWindows":`Windows`,"usage.companion.osLinux":`Linux`,"usage.companion.runningInDesktop":`Bạn đang ở trong ứng dụng máy tính OpenCodex {version}`,"usage.companion.openInBrowser":`Mở trong trình duyệt`,"usage.companion.installMacStep1":`Tải OpenCodex-<version>-macos.dmg từ bản phát hành mới nhất và kéo OpenCodex.app vào Applications.`,"usage.companion.installMacStep2":`Lần đầu mở: nhấp chuột phải vào OpenCodex.app → Mở (Gatekeeper sẽ hỏi một lần cho đến khi ứng dụng được công chứng).`,"usage.companion.installMacStep3":`Ứng dụng tự tìm proxy này; widget xuất hiện trong thư viện widget sau khi ứng dụng chạy.`,"usage.companion.installWinStep1":`Tải OpenCodex-<version>-windows-x64.msi từ bản phát hành mới nhất và chạy trình cài đặt.`,"usage.companion.installWinStep2":`Nếu SmartScreen cảnh báo, chọn Thông tin thêm → Vẫn chạy (trình cài đặt chưa được ký mã).`,"usage.companion.installWinStep3":`OpenCodex xuất hiện trong khay hệ thống và kết nối proxy này, hoặc khởi chạy proxy đi kèm.`,"usage.companion.installLinuxStep1":`Tải OpenCodex-<version>-linux-x86_64.AppImage (hoặc .deb) từ bản phát hành mới nhất.`,"usage.companion.installLinuxStep2":`Chạy chmod +x cho AppImage rồi mở; biểu tượng khay cần môi trường desktop hỗ trợ AppIndicator.`,"usage.companion.installLinuxStep3":`Ứng dụng kết nối proxy này hoặc khởi chạy proxy đi kèm.`,"usage.companion.notConnected":`Chưa có ứng dụng trên thanh menu nào kết nối với proxy này.`,"usage.companion.lastSeen":`Lần kết nối gần nhất {age}`,"usage.companion.installAnother":`Cài đặt trên thiết bị khác`,"usage.companion.modelsCount":`{selected}/{total} trên biểu đồ`,"usage.companion.modelsShowAll":`Hiện tất cả`,"usage.companion.hideProviders":`Ẩn nhà cung cấp`,"usage.workspace.report":`Báo cáo sử dụng`,"usage.workspace.sections":`Các phần sử dụng`,"usage.coverage.measured":`Đã đo`,"usage.coverage.reported":`Provider báo cáo`,"usage.coverage.estimated":`Ước tính`,"usage.coverage.note":`Các mục đo lường (Measured) bao gồm số lượng token ước tính và được báo cáo bởi provider. Các requests không có báo cáo hoặc không được hỗ trợ vẫn được theo dõi nhưng không bao giờ bị biến thành 0 token.`,"usage.search.models":`Tìm kiếm models…`,"usage.col.requests":`Yêu cầu`,"usage.col.measured":`Đã đo`,"usage.col.reported":`Đã báo cáo`,"usage.col.inputTokens":`Token đầu vào`,"usage.col.outputTokens":`Token đầu ra`,"usage.col.cacheHits":`Lượt truy cập cache`,"usage.col.cacheWrites":`Lần ghi cache`,"usage.col.cacheHitRate":`Tỷ lệ truy cập cache`,"usage.cacheHitRate.partial":`Giá trị trung bình được tính dựa trên {measured} trong tổng số {total} token đầu vào; các yêu cầu còn lại không cung cấp thông tin chi tiết về cache.`,"usage.cacheHitRate.unmeasured":`Không có yêu cầu nào trong hàng này cung cấp thông tin chi tiết về cache, nên không thể tính tỷ lệ truy cập cache trung bình.`,"usage.unavailable":`—`,"usage.col.tokens":`Tokens`,"usage.col.apiListPrice":`Giá niêm yết API`,"usage.col.share":`Tỷ trọng`,"usage.heatmap.less":`Ít`,"usage.heatmap.more":`Nhiều`,"usage.dayMon":`T2`,"usage.dayWed":`T4`,"usage.dayFri":`T6`,"usage.heatmap.tooltipTokens":`{tokens} token`,"usage.chart.dayDetail":`{date}: {requests} yêu cầu, {tokens} token`,"usage.heatmap.keyboardLabel":`Dùng phím Lên và Xuống để di chuyển theo ngày; Trái và Phải để di chuyển theo tuần.`,"usage.heatmap.tooltipRequests":`{requests} yêu cầu`,"nav.storage":`Lưu trữ`,"storage.title":`Lưu trữ`,"storage.subtitle":`Xem những gì đang chiếm dụng dung lượng trong CODEX_HOME. Việc dọn dẹp sẽ không bao giờ đụng đến các phiên (sessions) đang hoạt động.`,"storage.loading":`Đang quét lưu trữ…`,"storage.empty":`CODEX_HOME trống hoặc bị thiếu — không có gì để báo cáo.`,"storage.error":`Quét lưu trữ thất bại. Vui lòng kiểm tra CODEX_HOME có trỏ đến một thư mục hợp lệ không.`,"storage.refresh":`Quét lại (Rescan)`,"storage.rescanned":`Quét hoàn tất.`,"storage.card.total":`Tổng kích thước`,"storage.card.files":`Tệp (Files)`,"storage.card.home":`CODEX_HOME`,"storage.snapshot.lastScan":`Lần quét trước`,"storage.snapshot.scanning":`Đang quét…`,"storage.snapshot.unavailable":`Chưa có lượt quét nào.`,"storage.cleanupCard.title":`Giải phóng không gian lưu trữ`,"storage.cleanupCard.tabs":`Tuỳ chọn dọn dẹp`,"storage.cleanupCard.tab.policy":`Chính sách (Policy)`,"storage.cleanupCard.tab.quarantine":`Cách ly (Quarantine)`,"storage.cleanup.noArchives":`Không có phiên lưu trữ (archived sessions) nào để dọn dẹp.`,"storage.section.buckets":`Buckets`,"storage.section.largest":`Các tệp lớn nhất`,"storage.workspace.overview":`Tổng quan`,"storage.workspace.selectBucket":`Chọn một bucket từ danh sách để xem chi tiết.`,"storage.col.bucket":`Bucket`,"storage.col.size":`Kích thước`,"storage.col.files":`Số tệp`,"storage.col.oldest":`Cũ nhất`,"storage.col.newest":`Mới nhất`,"storage.col.rows":`Hàng trong DB (DB rows)`,"storage.rows.unknown":`không rõ (đang bị khoá)`,"storage.bucket.sessions":`Các phiên hoạt động (Active sessions)`,"storage.bucket.archived_sessions":`Các phiên đã lưu trữ (Archived sessions)`,"storage.bucket.logs_db":`Cơ sở dữ liệu logs`,"storage.bucket.state_db":`Cơ sở dữ liệu state`,"storage.bucket.attachments":`Tệp đính kèm (Attachments)`,"storage.bucket.deletion_manifests":`Manifests xoá`,"storage.bucket.other":`Khác`,"storage.cleanup.title":`Dọn dẹp lưu trữ (Archived cleanup)`,"storage.cleanup.help":`Xoá các phiên đã lưu trữ cũ nhất theo tỷ lệ phần trăm. Các phiên hoạt động không bao giờ bị đụng tới. Cách ly là mặc định — các tệp sẽ chuyển vào CODEX_HOME/.trash.`,"storage.cleanup.slider":`Phần trăm cũ nhất của lưu trữ`,"storage.cleanup.percent":`{percent}%`,"storage.cleanup.preset":`{percent}`,"storage.cleanup.preview":`Xem trước`,"storage.cleanup.confirmTitle":`Xác nhận dọn dẹp lưu trữ`,"storage.cleanup.confirmBody":`Thao tác này sẽ xử lý {count} tệp lưu trữ (~{size}), chiếm {percent}% cũ nhất.`,"storage.cleanup.moreFiles":`…và {n} tệp khác`,"storage.cleanup.permanent":`Xoá vĩnh viễn (bỏ qua cách ly)`,"storage.cleanup.permanentWarn":`Thao tác xoá vĩnh viễn không thể hoàn tác.`,"storage.cleanup.quarantineNote":`Các tệp sẽ được di chuyển vào .trash thuộc CODEX_HOME. Bạn có thể khôi phục chúng từ tab Cách ly.`,"storage.cleanup.cancel":`Hủy`,"storage.cleanup.confirmQuarantine":`Cách ly`,"storage.cleanup.confirmPermanent":`Xoá vĩnh viễn`,"storage.cleanup.doneQuarantine":`Đã cách ly {count} tệp ({size}).`,"storage.cleanup.donePermanent":`Đã xoá vĩnh viễn {count} tệp ({size}).`,"storage.cleanup.skippedReferenced":`Đã bỏ qua {count} tệp đang được tham chiếu.`,"storage.cleanup.previewFailed":`Xem trước thất bại.`,"storage.cleanup.cleanupFailed":`Dọn dẹp thất bại.`,"storage.cleanup.err.codex_busy":`Codex đang sử dụng state.sqlite — hãy thử lại sau khi thoát Codex.`,"storage.cleanup.err.stale_preview":`Các tệp lưu trữ đã thay đổi kể từ khi xem trước — hãy chạy lại tính năng Xem trước (Preview).`,"storage.cleanup.err.restore_pending_overlap":`Các lưu trữ đã chọn bị trùng với tiến trình khôi phục rác chưa hoàn tất — hãy kết thúc hoặc thử khôi phục lại trước.`,"storage.cleanup.err.referenced_history":`Các lưu trữ đã chọn vẫn đang được tham chiếu bởi lịch sử phân nhánh (forked) hoặc phân trang (paginated).`,"storage.cleanup.err.invalid_digest":`Mã xác nhận xem trước (Preview digest) bị thiếu hoặc không hợp lệ.`,"storage.cleanup.err.invalid_mode":`Chế độ dọn dẹp phải là cách ly (quarantine) hoặc xoá vĩnh viễn (permanent).`,"storage.cleanup.err.fs_failed":`Dọn dẹp hệ thống tệp thất bại. Một số thay đổi có thể đã được áp dụng — kiểm tra CODEX_HOME/.trash và bất kỳ đường dẫn khôi phục nào được hiển thị.`,"storage.cleanup.err.fs_failed_trash":`Dọn dẹp hệ thống tệp thất bại. Một số thay đổi có thể đã được áp dụng — kiểm tra {trashDir} và manifest.json để xem tệp có thể khôi phục.`,"storage.cleanup.err.db_reconcile_failed":`Không thể cập nhật cơ sở dữ liệu state của Codex.`,"storage.cleanup.err.cleanup_failed":`Dọn dẹp thất bại.`,"storage.trash.title":`Cách ly (Quarantine)`,"storage.trash.help":`Các phiên đã lưu trữ (Archived sessions) được di chuyển vào CODEX_HOME/.trash. Quá trình Khôi phục sẽ đặt các tệp JSONL và dữ liệu hàng (thread rows) trở lại.`,"storage.trash.empty":`Không có mục cách ly nào.`,"storage.trash.loading":`Đang tải vùng cách ly…`,"storage.trash.col.when":`Thời gian cách ly`,"storage.trash.col.files":`Tệp`,"storage.trash.col.size":`Kích thước`,"storage.trash.col.mode":`Chế độ`,"storage.trash.col.id":`Mục (Entry)`,"storage.trash.restore":`Khôi phục`,"storage.trash.confirmTitle":`Khôi phục mục cách ly?`,"storage.trash.confirmBody":`Khôi phục {count} tệp (~{size}) từ {id} về lại các phiên đã lưu trữ (archived sessions).`,"storage.trash.cancel":`Hủy`,"storage.trash.confirmRestore":`Khôi phục`,"storage.trash.done":`Đã khôi phục {count} tệp ({size}).`,"storage.trash.restoreFailed":`Khôi phục thất bại.`,"storage.trash.listFailed":`Không thể lấy danh sách các mục cách ly.`,"storage.trash.mode.quarantine":`cách ly`,"storage.trash.mode.permanent":`xoá vĩnh viễn (chưa hoàn thành)`,"storage.trash.err.codex_busy":`Codex đang sử dụng state.sqlite — hãy thử lại sau khi thoát Codex.`,"storage.trash.err.invalid_trash":`Id của mục trong thùng rác bị thiếu hoặc không hợp lệ.`,"storage.trash.err.missing_trash":`Không tìm thấy mục thùng rác.`,"storage.trash.err.dest_exists":`Đích khôi phục đã tồn tại — hãy xoá hoặc đổi tên tệp lưu trữ và thử lại.`,"storage.trash.err.fs_failed":`Khôi phục hệ thống tệp thất bại. Một số tệp có thể đã được khôi phục — hãy kiểm tra archived_sessions và .trash.`,"storage.trash.err.db_reconcile_failed":`Không thể khôi phục hàng (rows) của cơ sở dữ liệu Codex state.`,"storage.trash.err.storage_mutation_busy":`Có một quá trình dọn dẹp hoặc khôi phục lưu trữ khác đang chạy — vui lòng thử lại sau.`,"storage.trash.err.restore_failed":`Khôi phục thất bại.`,"storage.trash.err.restore_worker_timeout":`Quá trình khôi phục diễn ra quá lâu (hơn 10 phút) và đã bị dừng lại.`,"storage.trash.err.restore_worker_aborted":`Quá trình khôi phục đã bị huỷ trong lúc tắt máy (shutdown).`,"storage.trash.err.restore_worker_failed":`Worker khôi phục bị treo hoặc bị lỗi ngoài dự kiến.`,"storage.policy.title":`Chính sách dọn dẹp tự động`,"storage.policy.help":`Làm sạch hàng loạt (batch cleanup) tuỳ chọn khi số phiên lưu trữ vượt quá ngưỡng nhất định. Mặc định là tắt — không bao giờ tự động bật.`,"storage.policy.loading":`Đang tải chính sách…`,"storage.policy.loadFailed":`Không thể tải chính sách dọn dẹp.`,"storage.policy.saveFailed":`Không thể lưu chính sách dọn dẹp.`,"storage.policy.runFailed":`Lỗi khi chạy chính sách (Policy run failed).`,"storage.policy.alreadyRunning":`Một lượt chạy chính sách dọn dẹp (cleanup policy run) đang được thực thi.`,"storage.policy.invalid":`Giá trị của chính sách không hợp lệ.`,"storage.policy.enabled":`Bật dọn dẹp tự động`,"storage.policy.enabledHint":`Mặc định đang tắt. Khi bật, nó chỉ chạy theo lịch mà bạn đã chọn (hoặc khi bấm Chạy ngay bây giờ).`,"storage.policy.threshold":`Khi kích thước lưu trữ vượt quá (GiB)`,"storage.policy.trigger":`Kích hoạt (Trigger)`,"storage.policy.target":`Mục tiêu dọn dẹp`,"storage.policy.targetPercent":`Xoá phần trăm cũ nhất của phần lưu trữ (%)`,"storage.policy.targetReduce":`Giảm dung lượng lưu trữ xuống (GiB)`,"storage.policy.thresholdInc":`Tăng ngưỡng`,"storage.policy.thresholdDec":`Giảm ngưỡng`,"storage.policy.percentInc":`Tăng tỷ lệ phần trăm`,"storage.policy.percentDec":`Giảm tỷ lệ phần trăm`,"storage.policy.reduceInc":`Tăng kích thước được giảm xuống`,"storage.policy.reduceDec":`Giảm kích thước được giảm xuống`,"storage.policy.schedule":`Lịch biểu (Schedule)`,"storage.policy.schedule.manual":`Chỉ thủ công (Manual only)`,"storage.policy.schedule.startup":`Khi khởi động proxy`,"storage.policy.schedule.daily":`Hàng ngày`,"storage.policy.schedule.weekly":`Hàng tuần`,"storage.policy.mode":`Chế độ xoá (Deletion mode)`,"storage.policy.mode.quarantine":`Cách ly (mặc định)`,"storage.policy.mode.permanent":`Xoá vĩnh viễn`,"storage.policy.permanentWarn":`Chế độ xoá vĩnh viễn không thể hoàn tác. Khuyến khích sử dụng chế độ cách ly trừ khi bạn chắc chắn.`,"storage.policy.lastRun":`Chạy lần cuối (Last run)`,"storage.policy.lastRunDetail":`Đã xoá {count} · đã giải phóng {size}`,"storage.policy.nextRun":`Chạy lần tiếp`,"storage.policy.never":`Không bao giờ`,"storage.policy.save":`Lưu`,"storage.policy.runNow":`Chạy ngay (Run now)`,"storage.policy.running":`Đang chạy…`,"storage.policy.saved":`Chính sách đã được lưu.`,"storage.policy.skippedDisabled":`Chính sách đang tắt — vui lòng bật nó lên trước.`,"storage.policy.skippedUnder":`Kích thước lưu trữ vẫn dưới ngưỡng — không cần phải làm gì.`,"storage.policy.skippedEmpty":`Không có ứng viên lưu trữ nào phù hợp với mục tiêu.`,"storage.policy.doneQuarantine":`Chính sách đã cách ly {count} tệp ({size}).`,"storage.policy.donePermanent":`Chính sách đã xoá vĩnh viễn {count} tệp ({size}).`,"storage.policy.metadataSaveWarning":`Phiên chạy chính sách đã kết thúc, nhưng metadata lập lịch của nó không thể lưu được.`,"modal.addNamed":`Thêm: {label}`,"modal.add":`Thêm provider`,"modal.search":`Tìm Provider…`,"modal.logInWith":`Đăng nhập bằng {label}`,"modal.waitingBrowser":`Đang đợi trình duyệt…`,"modal.providerName":`Tên provider`,"modal.adapter":`Adapter`,"modal.baseUrl":`Base URL`,"modal.endpoint":`Endpoint`,"modal.endpoint.tokenPlan":`Gói token`,"modal.endpoint.payAsYouGo":`Dùng bao nhiêu trả bấy nhiêu`,"modal.endpoint.custom":`Tùy chỉnh`,"modal.defaultModel":`Model mặc định (tuỳ chọn)`,"modal.allowPrivateNetwork":`Cho phép mạng nội bộ/cá nhân`,"modal.allowPrivateNetworkHint":`Chỉ bật cho các provider tự host có chủ đích. Các endpoint metadata vẫn bị chặn.`,"modal.nameRequired":`Bắt buộc phải có tên provider`,"modal.baseUrlRequired":`Bắt buộc phải có Base URL`,"modal.networkError":`Lỗi mạng — proxy có đang chạy không?`,"modal.loginFailStart":`Không thể bắt đầu đăng nhập`,"modal.waitingLogin":`Đang đợi đăng nhập trên trình duyệt…`,"modal.loggingIn":`Đang đăng nhập…`,"modal.loginTimeout":`Đăng nhập quá thời gian — vui lòng thử lại.`,"modal.back":`Quay lại`,"modal.badge.oauth":`OAuth`,"modal.customProvider":`Provider tuỳ chỉnh`,"modal.failedStatus":`Thất bại ({status})`,"modal.loginError":`Lỗi đăng nhập: {error}`,"modal.badge.codexLogin":`Đăng nhập Codex`,"modal.badge.local":`Cục bộ`,"modal.badge.apiKey":`API key`,"modal.badge.direct":`Trực tiếp`,"modal.badge.pool":`Pool`,"modal.badge.free":`Miễn phí`,"modal.badge.sponsor":`Tài trợ`,"pws.sponsor.orcaTitle":`Một model cho mọi prompt`,"pws.sponsor.orcaDescription":`Gateway tương thích OpenAI với tính năng định tuyến thích ứng và tự động chuyển đổi dự phòng.`,"pws.sponsor.packyTitle":`Claude Code, Codex và Gemini tại một nơi`,"pws.sponsor.packyDescription":`Relay API cho các công cụ AI lập trình của bạn. Bắt đầu với token nhóm Codex.`,"pws.sponsor.visit":`Khám phá {provider}`,"pws.sponsor.console":`Mở console`,"modal.invalidPreset":`Preset của provider tích hợp này bị thiếu. Hãy khởi động lại proxy và thử lại.`,"modal.freeTierTitle":`Gói miễn phí`,"modal.freeTierDefault":`Không cần API key. Có thể sử dụng ngay.`,"modal.tab.accounts":`Tài khoản`,"modal.tab.free":`Miễn phí`,"modal.tab.local":`Cục bộ`,"modal.tab.paid":`Trả phí`,"modal.noteMore":`Hiển thị mô tả đầy đủ`,"modal.searchResults":`{count} kết quả trong {tiers}`,"modal.accountsHint":`Đăng nhập vào tài khoản ChatGPT/Codex, các provider OAuth, và tài khoản API key tại đây. OpenAI đã được tích hợp sẵn — vui lòng đăng nhập thay vì thêm mới.`,"modal.accountsCodexAuthLink":`Xác thực Codex`,"modal.notListed":`Không tìm thấy provider? Thêm provider tuỳ chỉnh`,"modal.catalogLoading":`Đang tải danh mục…`,"modal.accountLogin":`Đăng nhập`,"modal.accountLogout":`Đăng xuất`,"modal.accountAdd":`Thêm tài khoản`,"modal.accountManage":`Quản lý`,"modal.accountCodexPool":`Pool tài khoản ChatGPT`,"modal.accountLoggedIn":`Đã đăng nhập`,"modal.accountLoggedOut":`Chưa đăng nhập`,"quota.ageMinutes":`{n} phút`,"quota.ageHours":`{n} giờ`,"quota.ageDays":`{n} ngày`,"quota.observedAgo":`Ghi nhận {age} trước`,"quota.observedHint":`Meta chỉ báo cáo mức sử dụng trong quá trình phản hồi stream, vì vậy đây là giá trị cuối cùng ghi nhận được, không phải số liệu thời gian thực.`,"quota.weeklyLimit":`Giới hạn hàng tuần`,"quota.monthlyLimit":`Giới hạn 30 ngày`,"quota.cursorFirstParty":`Các model first-party`,"quota.cursorApiUsage":`Mức sử dụng API`,"quota.totalSubscriptionCredits":`Tổng credit gói đăng ký`,"quota.creditsBalance":`Số dư credit`,"quota.creditsPeriodEnds":`Chu kỳ thanh toán kết thúc vào {date}`,"quota.usedPercent":`Đã dùng {pct}%`,"quota.limitReached":`Đã đạt giới hạn`,"quota.resetsToday":`Đặt lại hôm nay lúc {time}`,"quota.resetsTomorrow":`Đặt lại ngày mai lúc {time}`,"quota.resetsAt":`Đặt lại vào {when}`,"quota.resetsRelativeMinutes":`Đặt lại sau {n} phút`,"quota.resetsRelativeHours":`Đặt lại sau {n} giờ`,"pws.status.ready":`Sẵn sàng`,"pws.status.needsSetup":`Cần thiết lập`,"pws.status.needsAttention":`Cần chú ý`,"pws.auth.chatgptPassthrough":`ChatGPT passthrough`,"pws.auth.noKey":`Không cần key`,"pws.freeTitle":`Giá miễn phí (vẫn có thể yêu cầu key)`,"pws.localTitle":`Runtime cục bộ`,"pws.modelCountOne":`1 model`,"pws.modelCount":`{count} model`,"pws.rail.suffixDefault":` · mặc định`,"pws.rail.suffixLocal":` · cục bộ`,"pws.rail.suffixFree":` · miễn phí`,"pws.rail.selectAria":`Chọn {name} — {status}{suffix}`,"pws.searchPlaceholder":`Tìm Provider…`,"pws.filterAria":`Lọc các provider`,"pws.providerFiltersAria":`Bộ lọc provider`,"pws.filters":`Bộ lọc`,"pws.filterStatus":`Trạng thái`,"pws.pricing":`Định giá`,"pws.paid":`Trả phí`,"pws.filterType":`Loại`,"pws.type.cloud":`Cloud`,"pws.type.local":`Cục bộ`,"pws.type.selfHosted":`Tự host`,"pws.type.login":`Đăng nhập`,"pws.sort":`Sắp xếp`,"pws.sortProvidersAria":`Sắp xếp các provider`,"pws.sort.az":`A–Z`,"pws.sort.za":`Z–A`,"pws.sort.freePaid":`Miễn phí trước`,"pws.sort.paidFree":`Trả phí trước`,"pws.sort.accountsFirst":`Tài khoản trước`,"pws.resetAll":`Đặt lại tất cả`,"pws.providerList":`Danh sách provider`,"pws.providersAria":`Nhà cung cấp`,"pws.groupReady":`Sẵn sàng ({count})`,"pws.groupNeedsSetup":`Cần thiết lập ({count})`,"pws.groupDisabled":`Đã vô hiệu hoá ({count})`,"pws.noSearchResults":`Không có provider nào khớp với tìm kiếm của bạn.`,"pws.noMatchFilters":`Không có provider nào khớp với các bộ lọc.`,"pws.noProvidersConfigured":`Chưa có provider nào được cấu hình.`,"pws.workspaceMainAria":`Chi tiết provider`,"pws.detailComingSoon":`Chế độ xem chi tiết sắp ra mắt — sử dụng chế độ xem cổ điển để quản lý provider này.`,"pws.selectPrompt":`Chọn một provider từ danh sách.`,"pws.connectFirst":`Kết nối provider đầu tiên của bạn`,"pws.empty.browseFree":`Duyệt các provider miễn phí`,"pws.empty.browseFreeDesc":`Bắt đầu mà không cần gói đăng ký`,"pws.empty.connectAccount":`Kết nối một tài khoản`,"pws.empty.connectAccountDesc":`Sử dụng đăng nhập ChatGPT hoặc provider của bạn`,"pws.empty.addEndpoint":`Thêm một endpoint`,"pws.empty.addEndpointDesc":`Base URL và API key tuỳ chỉnh`,"pws.tab.overview":`Tổng quan`,"pws.tab.models":`Models`,"pws.tab.usage":`Mức sử dụng`,"pws.tab.accounts":`Tài khoản`,"pws.tab.settings":`Cài đặt`,"pws.connection":`Kết nối`,"pws.status.connected":`Đã kết nối`,"pws.attentionTitle":`Cần chú ý`,"pws.attention.reauth":`Tài khoản đang hoạt động cần xác thực lại`,"pws.attention.reauthForward":`Tài khoản Codex đang hoạt động cần xác thực lại — hãy mở mục Accounts để khắc phục`,"pws.attention.missingCredentials":`Thiếu thông tin xác thực`,"pws.cell.auth":`Xác thực`,"pws.cell.note":`Ghi chú`,"pws.cell.defaultModel":`Model mặc định`,"pws.statsAria":`Thống kê provider`,"pws.statsTitle":`Thống kê`,"pws.stats.totalRequests":`Yêu cầu (30 ngày)`,"pws.stats.totalTokens":`Token (30 ngày)`,"pws.stats.quotaUpdated":`Đã cập nhật hạn mức`,"pws.stats.quotaTracked":`Giới hạn tốc độ được theo dõi trong tab Usage.`,"pws.stats.source":`Nguồn`,"pws.usageLast30d":`Mức sử dụng (30 ngày qua)`,"pws.estimatedCost":`Chi phí ước tính`,"pws.costDisclaimer":`Ước tính theo giá niêm yết của API, không phải là mức phí thực tế.`,"pws.unresolvedRequestedModel":`Bao gồm cả mức sử dụng model được yêu cầu chưa giải quyết`,"pws.currentAccountUsage":`Mức sử dụng tài khoản hiện tại`,"pws.quotaUnsupported":`Tra cứu hạn mức không được hỗ trợ cho tài khoản này.`,"pws.quotaUnobserved":`Chưa có dữ liệu sử dụng nào được ghi nhận.`,"pws.quotaCheckCompleted":`Đã hoàn thành kiểm tra hạn mức`,"pws.modelBreakdown":`Chi tiết theo model`,"pws.col.model":`Model`,"pws.col.cost":`Chi phí ước tính`,"pws.col.tokens":`Tokens`,"pws.col.requests":`Yêu cầu`,"pws.col.share":`Tỷ lệ`,"pws.tokenInput":`Đầu vào`,"pws.tokenOutput":`Đầu ra`,"pws.metricRequests":`yêu cầu`,"pws.metricTokens":`tokens`,"pws.usageUnavailable":`Chưa có mức sử dụng nào được ghi nhận.`,"pws.rateLimits":`Giới hạn tốc độ`,"pws.quotaUnavailable":`Không có dữ liệu hạn mức cho provider này.`,"pws.accountQuotaUnavailable":`Dữ liệu giới hạn tốc độ tạm thời không khả dụng; đang hiển thị các giá trị cuối cùng được biết đến (nếu có).`,"pws.quotaFailure.account_unavailable":`Không có thông tin tài khoản cho lần kiểm tra hạn ngạch này.`,"pws.quotaFailure.access_denied":`Nhà cung cấp đã từ chối quyền truy cập dữ liệu hạn ngạch.`,"pws.quotaFailure.rate_limited":`Nhà cung cấp đã giới hạn tốc độ kiểm tra hạn ngạch.`,"pws.quotaFailure.upstream_error":`Nhà cung cấp không thể hoàn tất kiểm tra hạn ngạch.`,"pws.quotaFailure.redirect_blocked":`Endpoint hạn ngạch trả về một chuyển hướng bị chặn.`,"pws.quotaFailure.destination_blocked":`Đích hạn ngạch bị chính sách mạng chặn.`,"pws.quotaFailure.dns_failed":`Không thể phân giải hostname hạn ngạch.`,"pws.quotaFailure.timeout":`Yêu cầu hạn ngạch đã hết thời gian chờ.`,"pws.quotaFailure.transport_error":`Kết nối hạn ngạch thất bại.`,"pws.quotaFailure.response_unusable":`Nhà cung cấp trả về dữ liệu hạn ngạch không thể sử dụng.`,"pws.selected":`Đã chọn`,"pws.copyModelId":`Sao chép ID`,"pws.modelCopied":`Đã sao chép!`,"pws.modelsAvailable":`{count} model khả dụng`,"pws.modelSearchPlaceholder":`Lọc các model…`,"pws.modelsLoading":`Đang tải các model…`,"pws.modelsLoadFailed":`Không thể tải các model.`,"pws.modelsNeedsReauth":`Tài khoản cần đăng nhập lại trước khi tính năng khám phá model trực tiếp có thể hoạt động. Tạm thời hiển thị các model đã cấu hình.`,"pws.modelsConfiguredFallback":`Đang hiển thị các model đã cấu hình (tính năng khám phá trực tiếp không khả dụng).`,"pws.modelsTruncated":`Đang hiển thị {shown} model đầu tiên trong tổng số {total} model. Hãy sử dụng bộ lọc để thu hẹp danh sách.`,"pws.retry":`Thử lại`,"pws.noModels":`Không phát hiện model nào cho provider này.`,"pws.adapterBaseRequired":`Bắt buộc phải có Adapter và Base URL.`,"pws.addAccount":`Thêm tài khoản`,"pws.addKey":`Thêm API key`,"pws.apiKeys":`API Keys`,"pws.authMode":`Chế độ xác thực`,"pws.availableAccounts":`Các tài khoản khả dụng`,"pws.accountOrdinal":`Tài khoản {count}`,"pws.accountsLoading":`Đang tải các tài khoản…`,"pws.accountsLoadFailed":`Không thể tải các tài khoản.`,"pws.retryAccounts":`Thử lại`,"pws.noAccounts":`Chưa có tài khoản nào được kết nối.`,"pws.cockpitImportDescription":`Nhập tệp xuất Cockpit Tools Antigravity dạng JSON từ thiết bị này. Nội dung tệp sẽ không được hiển thị.`,"pws.cockpitImportFileLabel":`Tệp xuất JSON từ Cockpit Tools Antigravity`,"pws.cockpitImportChooseFile":`Chọn tệp JSON`,"pws.cockpitImporting":`Đang nhập…`,"pws.cockpitImportInvalid":`Tệp đã chọn không phải là tệp xuất JSON hợp lệ hoặc có kích thước quá lớn.`,"pws.cockpitImportFailed":`Không thể hoàn thành việc nhập tài khoản.`,"pws.cockpitImportComplete":`Đã nhập xong: {imported} được nhập, {updated} được cập nhật, {failed} thất bại, {unsupported} không được hỗ trợ.`,"pws.accountSwitching":`Đang chuyển…`,"pws.accountCurrent":`Tài khoản hiện tại`,"pws.defaultModelNone":`Không có (sử dụng mặc định của provider)`,"pws.discardSettings":`Huỷ bỏ`,"pws.jsonEditorDesc":`Chỉnh sửa config dạng JSON thô của provider. Các thay đổi sẽ được lưu ngay lập tức.`,"pws.jsonEditorTitle":`Trình chỉnh sửa JSON — {name}`,"pws.jsonRestore":`Khôi phục`,"pws.jsonSave":`Lưu`,"pws.loggedInTitle":`Đã đăng nhập`,"pws.notLoggedInTitle":`Chưa đăng nhập`,"pws.note":`Ghi chú`,"pws.allowPrivateNetwork":`Cho phép mạng nội bộ/cá nhân`,"pws.liveModels":`Khám phá các model từ provider`,"pws.liveModelsDesc":`Lấy danh mục model trực tiếp từ provider. Hãy tắt tuỳ chọn này nếu chỉ muốn sử dụng các model đã cấu hình/tĩnh.`,"pws.xaiChatOptIn":`Sử dụng Chat Completions cho Grok 4.5 và 4.6`,"pws.xaiChatOptInDesc":`Tắt để chọn Responses. Các yêu cầu OAuth Responses sử dụng tuỳ chọn này theo mặc định. Các model Grok khác và hành vi của gói không bị ảnh hưởng.`,"pws.xaiChatOptInMixed":`Chỉ có một model sử dụng Chat.`,"pws.cursorTransport":`Cursor transport`,"pws.cursorTransportHttp2":`HTTP/2 (mặc định)`,"pws.cursorTransportHttp1":`HTTP/1.1 (tương thích với proxy)`,"pws.cursorTransportDesc":`Sử dụng HTTP/1.1 khi proxy của bạn không thể truyền stream HTTP/2 của Cursor một cách đáng tin cậy.`,"pws.optionalPlaceholder":`Tuỳ chọn`,"pws.providerId":`ID provider`,"pws.reauth":`Cần xác thực lại`,"pws.reauthenticate":`Xác thực lại`,"pws.copyDoctor":`Sao chép ocx doctor`,"pws.doctorCopied":`Đã sao chép`,"pws.doctorCopyUnavailable":`Clipboard không khả dụng`,"pws.healthCooldownHint":`Đợi cho đến khi thời gian chờ kết thúc. Không thăm dò tài khoản này ngay bây giờ.`,"pws.healthLabel.rateLimited":`Bị giới hạn tốc độ`,"pws.healthLabel.quotaLimited":`Bị giới hạn hạn mức`,"pws.healthLabel.reauthRequired":`Yêu cầu xác thực lại`,"pws.healthLabel.refreshFailed":`Làm mới thất bại`,"pws.healthLabel.metadataMismatch":`Metadata không khớp`,"pws.healthLabel.validationPending":`Đang chờ xác thực`,"pws.healthSummary.validationPending":`{provider} {account}: được đăng ký trong khi bị giới hạn hạn mức. Sau khi hạn mức phục hồi, hãy làm mới hạn mức để chạy một yêu cầu xác thực nhỏ. Định tuyến sẽ bị vô hiệu hoá cho đến khi thành công.`,"pws.healthLabel.credentialConflict":`Xung đột thông tin xác thực`,"pws.healthSummary.rateLimited":`{provider} {account}: bị giới hạn tốc độ cho đến {until}. Quá trình định tuyến cho tài khoản này sẽ bị tạm dừng cho đến lúc đó.`,"pws.healthSummary.quotaLimited":`{provider} {account}: bị giới hạn hạn mức cho đến {until}. Quá trình định tuyến cho tài khoản này sẽ bị tạm dừng cho đến lúc đó.`,"pws.healthSummary.reauthRequired":`{provider} {account}: yêu cầu xác thực lại.`,"pws.healthSummary.credentialConflict":`{provider} {account}: có xung đột thông tin xác thực.`,"pws.healthSummary.metadataMismatch":`{provider} {account}: metadata không khớp.`,"pws.healthSummary.staleCredentials":`{provider} {account}: thông tin xác thực không đầy đủ.`,"pws.removeConfirm":`Xóa`,"pws.removeConfirmBody":`Xoá provider \\"{name}\\"? Hành động này không thể hoàn tác.`,"pws.removeDefaultConfirmBody":`Xoá provider mặc định \\"{name}\\"? \\"{defaultProvider}\\" sẽ trở thành provider mặc định. Hành động này không thể hoàn tác.`,"pws.removeConfirmTitle":`Xóa Provider`,"pws.saveSettings":`Lưu`,"pws.pacingTitle":`Pacing của yêu cầu`,"pws.pacingDesc":`Đồng đều trì hoãn thời điểm bắt đầu yêu cầu ra ngoài cho provider này. Các phản hồi stream có thể chồng chéo.`,"pws.pacingEnabled":`Đã bật`,"pws.pacingRpm":`Yêu cầu mỗi phút`,"pws.pacingRpmUnit":`RPM`,"pws.pacingDelay":`Khoảng thời gian tối thiểu (ms)`,"pws.pacingSlowerWins":`Giới hạn provider chậm hơn sẽ được ưu tiên. Ghi đè model chỉ có thể làm tăng thêm độ trễ.`,"pws.pacingQueued":`đã xếp hàng`,"pws.pacingNextSlot":`cho đến slot tiếp theo`,"pws.pacingLastModel":`model cuối cùng`,"pws.pacingNone":`Không có`,"pws.pacingModelOverrides":`Ghi đè model`,"pws.pacingModel":`Model`,"pws.pacingAdd":`Thêm ghi đè`,"pws.pacingRemove":`Xóa`,"pws.pacingRemoveModel":`Xoá ghi đè pacing yêu cầu cho {model}`,"pws.pacingRuleRequired":`Chỉ bật pacing yêu cầu sau khi đã thiết lập giới hạn provider hoặc một ghi đè model.`,"pws.saving":`Đang lưu…`,"pws.settingsSaved":`Đã lưu cài đặt.`,"pws.accountModeSaved":`Đã lưu chế độ tài khoản.`,"pws.accountModeFailed":`Không thể chuyển chế độ tài khoản.`,"pws.accountModeConfirm":`Chuyển chế độ tài khoản OpenAI? Các cuộc hội thoại đang chạy sẽ được gán lại cho bộ tài khoản của chế độ khác, và mức sử dụng hạn mức sẽ được theo dõi trên chế độ mới.`,"pws.settingsUnsavedBar":`Bạn có các thay đổi chưa lưu.`,"pws.unsavedLeaveBody":`Bạn có các thay đổi chưa lưu. Lưu chúng lại trước khi rời đi?`,"pws.unsavedLeaveTitle":`Thay đổi chưa lưu`,"pws.attentionRequired":`Cần sự chú ý`,"pws.attentionAria":`{name}: {reason}`,"pws.missingCredentials":`Thiếu thông tin xác thực`,"pws.editJsonDesc":`Chỉnh sửa config proxy thô dưới dạng JSON`,"pws.updatesUnavailable":`Các bản cập nhật của provider hiện không khả dụng.`,"pws.dashboard.title":`Tổng quan các provider`,"pws.dashboard.subtitle":`Quản lý tất cả các model provider của bạn tại một nơi.`,"pws.dashboard.rateLimits":`GIỚI HẠN TỐC ĐỘ`,"pws.capacity.estimate":`Ước tính pool theo trọng số đã định cấu hình`,"pws.capacity.currentAccount":`Tài khoản đang có hiệu lực hiện tại`,"pws.capacity.nextRecovery":`Lần phục hồi năng lực tiếp theo`,"pws.capacity.recoveryShare":`+{percent}% năng lực của pool`,"pws.capacity.incomplete":`Độ phủ không đầy đủ: Đã loại trừ {excluded} tài khoản`,"pws.capacity.uncalibratedPlan":`{count} tài khoản thuộc gói chưa được hiệu chuẩn sẽ được tính ở mức trọng số ghế tiêu chuẩn, do đó ước tính này có thể là bảo thủ`,"pws.capacity.partial":`Độ phủ window bán phần: {count} tài khoản không báo cáo mọi limit window được hiển thị`,"pws.capacity.windowPartial":`Bán phần`,"pws.capacity.windowPartialA11y":`{window}: độ phủ tài khoản không đầy đủ`,"pws.dashboard.recentlyUsed":`SỬ DỤNG GẦN ĐÂY`,"pws.dashboard.requests":`{count} yêu cầu`,"pws.dashboard.checkedAgo":`Đã kiểm tra {time}`,"pws.dashboard.noQuota":`Không có dữ liệu hạn mức`,"pws.dashboard.noUsage":`Chưa có dữ liệu sử dụng`,"pws.dashboard.noRateLimits":`Chưa có dữ liệu giới hạn tốc độ`,"pws.allProviders":`Tổng quan Provider`,"pws.enabledLabel":`Đã bật`,"pws.testConnection":`Kiểm tra kết nối`,"pws.testing":`Đang kiểm tra…`,"pws.connectionOk":`Kết nối OK`,"pws.connectionFailed":`Kết nối thất bại`,"pws.connectionNotApplicable":`Không áp dụng — provider này sử dụng danh mục model tĩnh.`,"pws.editSettings":`Chỉnh sửa cài đặt`,"pws.viewUsage":`Xem chi tiết mức sử dụng`,"pws.allSystemsOk":`Tất cả các hệ thống đều hoạt động`,"pws.apiKeyConfigured":`Đã cấu hình API key`,"pws.addApiKey":`Thêm API key`,"pws.loggedInAs":`Đã đăng nhập với tư cách {email}`,"pws.notLoggedIn":`Chưa đăng nhập`,"pws.passthrough":`Codex passthrough`,"pws.notes":`GHI CHÚ`,"pws.notePlaceholder":`Thêm ghi chú về provider này...`,"pws.noteSaved":`Đã lưu ghi chú`,"pws.authSummary":`XÁC THỰC`,"time.justNow":`Vừa xong`,"time.notChecked":`Chưa kiểm tra`,"time.minutesAgo":`{n} phút trước`,"time.hoursAgo":`{n} giờ trước`,"time.daysAgo":`{n} ngày trước`,"modal.noMatch":`Không khớp.`,"modal.oauthDefaultNote":`Đăng nhập bằng tài khoản của bạn — không cần API key.`,"modal.oauthComingSoon":`Đăng nhập OAuth cho {label} sẽ có trong bản cập nhật tới. Tạm thời hãy sử dụng API key.`,"modal.oauthComingSoonShort":`Đăng nhập OAuth cho provider này sẽ có trong bản cập nhật tới — tạm thời hãy sử dụng API key.`,"modal.useApiKeyInstead":`Thay vào đó hãy sử dụng API key`,"modal.setupGuide":`Hướng dẫn thiết lập`,"modal.setupStep1Prefix":`Truy cập`,"modal.setupDashboardLink":`bảng điều khiển {label}`,"modal.setupStep1Suffix":`và sao chép API key của bạn`,"modal.setupStep2":`Dán vào trường API key bên dưới`,"modal.setupStep3":`Nhấp vào Thêm provider — các model sẽ được tự động khám phá`,"modal.namePlaceholder":`vd: openrouter`,"modal.duplicateWarn":`Provider \\"{name}\\" đã tồn tại và sẽ bị ghi đè.`,"modal.forwardHintPrefix":`Không cần key — proxy sẽ chuyển tiếp`,"modal.forwardCredentials":`đăng nhập codex`,"modal.forwardHintSuffix":`thông tin xác thực của bạn đến provider này.`,"modal.localHint":`Không lưu trữ API key. Thao tác này sẽ thêm danh mục model công khai tĩnh của Cursor cho Codex, nhưng transport trực tiếp của Cursor và tính năng thực thi file/shell native vẫn bị vô hiệu hoá cho đến khi được kiểm toán.`,"modal.getApiKey":`Lấy API key {label} của bạn`,"modal.apiKey":`API key`,"modal.apiKeyTransport":`API key header`,"modal.apiKeyTransportNative":`x-api-key (Anthropic native)`,"modal.apiKeyTransportBearer":`Authorization: Bearer`,"modal.apiKeyPlaceholder":`sk-… (hoặc $ENV_VAR)`,"modal.defaultModelPlaceholder":`vd: gpt-5.5`,"modal.baseUrlPlaceholderError":`Base URL có chứa {placeholder} chưa được giải quyết. Thay thế bằng giá trị thực tế của bạn.`,"modal.baseUrlPlaceholderHint":`Hãy thay thế {placeholder} trong Base URL bằng Account ID thực tế của bạn trước khi thêm.`,"modal.adding":`Đang thêm…`,"modal.useOauthLogin":`← Sử dụng đăng nhập OAuth`,"nav.codexSet":`Cài đặt Codex`,"codexSet.tab.multiauth":`Đa xác thực`,"codexSet.tab.prompt":`Prompt`,"codexSet.prompt.title":`Prompt layer`,"codexSet.prompt.timing":`Áp dụng cho các phiên mới bắt đầu. Các phiên đang chạy sẽ giữ nguyên cài đặt prompt hiện tại của chúng.`,"codexSet.prompt.staleRevision":`Cấu hình đã thay đổi ở nơi khác. Danh sách đã được tải lại.`,"codexSet.prompt.repair":`Sửa chữa`,"codexSet.prompt.repairFailed":`Không thể hoàn thành việc sửa chữa.`,"codexSet.drift.journalPresent":`Một tác vụ ghi trước đó chưa hoàn thành. Quá trình phục hồi sẽ tự động chạy ở lần ghi tiếp theo.`,"codexSet.drift.projectionStale":`Các layer đã lưu và giá trị trong config.toml không khớp nhau. Sửa chữa sẽ ghi lại giá trị từ các layer của bạn.`,"codexSet.drift.storeMissing":`Tệp layer đã biến mất trong khi các chỉ thị vẫn còn trong config.toml. Sửa chữa sẽ giữ phần văn bản này như một layer và sẽ ghi một bản sao lưu trước.`,"codexSet.drift.ownedMalformed":`Dòng mã được sinh ra trong config.toml đã bị định dạng lại thủ công, nên không còn an toàn để ghi đè.`,"codexSet.custom.adoptUnsupported":`Giá trị tại {path} dòng {line} không phải là chuỗi một dòng, do đó không thể nhập. Di chuyển bằng tay để quản lý tại đây.`,"codexSet.prompt.unreadable":`Tệp config Codex tồn tại nhưng không thể đọc được, vì vậy các thay đổi sẽ bị từ chối.`,"codexSet.layer.permissions":`Quyền truy cập`,"codexSet.layer.collaboration":`Chế độ cộng tác`,"codexSet.layer.environment":`Bối cảnh môi trường`,"codexSet.layer.apps":`Ứng dụng`,"codexSet.group.transition":`Thông báo chuyển tiếp`,"codexSet.group.transitionDesc":`Các thông báo này thông báo về một sự thay đổi thay vì mô tả trạng thái, vì vậy chúng chỉ xuất hiện khi phiên chuyển sang trạng thái realtime hoặc chuyển model.`,"codexSet.custom.slotNote":`Các layer tuỳ chỉnh được nối thành một phần theo thứ tự này.`,"codexSet.row.onChange":`Kích hoạt khi thay đổi`,"codexSet.row.openFeatures":`Mở cài đặt`,"codexSet.dialog.setValue":`{value} (mặc định {fallback})`,"codexSet.custom.heading":`Layer tuỳ chỉnh`,"codexSet.custom.add":`+ Thêm layer`,"codexSet.custom.newTitle":`Layer mới`,"codexSet.custom.editTitle":`Chỉnh sửa layer`,"codexSet.custom.titleLabel":`Tiêu đề`,"codexSet.custom.bodyLabel":`Chỉ thị`,"codexSet.custom.bodySize":`{bytes} trên {max} byte`,"codexSet.custom.normalized":`Tab đã trở thành bốn dấu cách và kết thúc dòng đã trở thành LF.`,"codexSet.custom.titleRequired":`Hãy nhập tiêu đề.`,"codexSet.custom.titleTooLong":`Tiêu đề dài {count} ký tự; giới hạn là {max}.`,"codexSet.custom.titleMultiline":`Tiêu đề phải trên một dòng duy nhất.`,"codexSet.custom.bodyTooLarge":`Layer này có dung lượng {bytes} byte; giới hạn là {max}.`,"codexSet.custom.composedTooLarge":`Gộp chung, các layer được kích hoạt sẽ chiếm {bytes} byte, vượt quá giới hạn.`,"codexSet.custom.invalidCharacter":`Một ký tự điều khiển tại vị trí {position} không thể được lưu.`,"codexSet.custom.discardPrompt":`Huỷ bỏ các thay đổi của bạn?`,"codexSet.custom.keepEditing":`Tiếp tục chỉnh sửa`,"codexSet.custom.delete":`Xoá {title}`,"codexSet.custom.layerGone":`Layer đó đã bị xoá ở nơi khác, nên trình chỉnh sửa đã đóng.`,"codexSet.custom.deleteConfirmNamed":`Xoá “{title}”? Hành động này không thể hoàn tác.`,"codexSet.custom.prevLayer":`Layer trước`,"codexSet.custom.nextLayer":`Layer tiếp theo`,"codexSet.custom.navPosition":`{position} / {total}`,"codexSet.custom.moveDown":`Di chuyển {title} xuống`,"codexSet.custom.limitReached":`Bạn có thể giữ lại tối đa {max} layer tuỳ chỉnh.`,"codexSet.custom.notOwned":`developer_instructions được viết bên ngoài opencodex, vì vậy không thể chỉnh sửa nó từ đây. Hãy nhập nội dung đó để quản lý nó như một layer.`,"codexSet.custom.adopt":`Nhập các chỉ thị hiện có`,"codexSet.custom.adoptConfirm":`Nhập dưới dạng layer`,"codexSet.custom.adoptRefused":`Giá trị hiện có không thể được nhập.`,"codexSet.custom.baseReplaced":`model_instructions_file được đặt là {path}, có nghĩa là một yếu tố bên ngoài opencodex đã thay thế base prompt.`,"codexSet.lint.identity":`Cấu hình này tự nhận một danh tính khác với danh tính do Codex thiết lập.`,"codexSet.lint.foreignTool":`Các công cụ đến từ registry; việc chỉ đặt tên chúng ở đây không tự tạo ra công cụ.`,"codexSet.lint.placeholder":`Không có template engine nào xử lý các chỉ thị, do đó phần này sẽ được truyền đi đúng nguyên văn.`,"codexSet.lint.applyPatch":`apply_patch được định nghĩa bởi tool registry, không phải bởi các chỉ thị.`,"codexSet.lint.approvalVocab":`Codex tự chèn thêm từ vựng phê duyệt riêng; điều này có thể mâu thuẫn với nó.`,"codexSet.lint.environment":`Các sự kiện thực tế của môi trường được sinh ra sau đó và có thể gây mâu thuẫn với cấu hình này.`,"codexSet.preset.blank":`Layer trống`,"codexSet.preset.concise.name":`Phản hồi súc tích`,"codexSet.preset.concise.description":`Câu trả lời ngắn gọn, không có phần mở đầu, giảm thiểu định dạng.`,"codexSet.preset.concise.provenance":`Được điều chỉnh từ chỉ thị hướng đến sự ngắn gọn của Claude Code. Chúng tôi tự diễn đạt lại, không phải sao chép.`,"codexSet.preset.planFirst.name":`Lập kế hoạch trước khi chỉnh sửa`,"codexSet.preset.planFirst.description":`Trình bày kế hoạch trước, sau đó mới thực hiện thay đổi.`,"codexSet.preset.planFirst.provenance":`Được điều chỉnh từ phong thái lập kế hoạch của Claude Code. Chúng tôi tự diễn đạt lại, không phải sao chép.`,"codexSet.preset.explainWhy.name":`Giải thích lý do`,"codexSet.preset.explainWhy.description":`Cho biết tại sao lại thực hiện điều đó, thay vì chỉ mô tả những gì bạn đã làm.`,"codexSet.preset.explainWhy.provenance":`Được điều chỉnh từ phong cách xác nhận của Grok Build. Chúng tôi tự diễn đạt lại, không phải sao chép.`,"codexSet.preset.testFirst.name":`Viết test trước tiên`,"codexSet.preset.testFirst.description":`Viết fail test trước khi tiến hành sửa lỗi.`,"codexSet.preset.testFirst.provenance":`Được điều chỉnh từ quy trình thực hành thông thường của agent. Chúng tôi tự diễn đạt lại, không phải sao chép.`,"codexSet.preset.korean.name":`Phản hồi bằng tiếng Hàn`,"codexSet.preset.korean.description":`Luôn trả lời bằng tiếng Hàn cho dù yêu cầu sử dụng bất kỳ ngôn ngữ nào.`,"codexSet.preset.korean.provenance":`Được viết riêng cho opencodex dựa trên một tính năng chủ lực do người dùng yêu cầu. Chúng tôi tự diễn đạt lại, không phải sao chép.`,"codexSet.dialog.class":`Loại`,"codexSet.dialog.key":`Khoá cấu hình`,"codexSet.dialog.fileValue":`Giá trị trong tệp này`,"codexSet.dialog.absentDefault":`chưa thiết lập (mặc định là {value})`,"codexSet.dialog.sourceText":`Văn bản được gửi tới model`,"codexSet.dialog.sourceBytes":`{bytes} byte`,"codexSet.dialog.emptySource":`Tệp tại {path} tồn tại nhưng không có dữ liệu, vì vậy layer này không gửi đi nội dung nào cả.`,"codexSet.dialog.notExposed":`Base prompt di chuyển bên ngoài danh sách tin nhắn mà Codex có thể in ra, vì vậy không thể hiển thị ở đây. Tuy nhiên có thể thay thế nó thông qua model_instructions_file.`,"codexSet.dialog.unmapped":`Lớp này chưa có ánh xạ được xác nhận trong đầu ra prompt, vì vậy chưa thể hiển thị văn bản của nó ở đây.`,"codexSet.dialog.textUnavailable":`Không thể đọc prompt Codex trên máy này, do đó văn bản không khả dụng.`,"codexSet.class.base":`Base instructions`,"codexSet.class.config-toggle":`Có thể chuyển đổi tại đây`,"codexSet.class.feature-gated":`Tính năng bị giới hạn`,"codexSet.class.runtime-conditional":`Phụ thuộc vào runtime`,"codexSet.class.extension-unknown":`Layer mở rộng`,"codexSet.layer.base-instructions":`Base instructions`,"codexSet.layer.model-switch":`Thông báo chuyển đổi model`,"codexSet.layer.personality":`Tính cách`,"codexSet.layer.context-window-guidance":`Hướng dẫn context window`,"codexSet.layer.realtime":`Realtime`,"codexSet.layer.agents-md":`AGENTS.md`,"codexSet.layer.environments-instructions":`Môi trường`,"codexSet.layer.plugins":`Plugins`,"codexSet.layer.tools":`Công cụ`,"codexSet.layer.multi-agent-mode":`Chế độ multi-agent`,"codexSet.layer.git-attribution":`Attribution commit`,"codexSet.about.base-instructions":`Base instructions của riêng Codex. Chúng đi kèm với chính yêu cầu và không thể bị tắt.`,"codexSet.about.model-switch":`Được thêm vào khi phiên trò chuyện thay đổi model giữa cuộc hội thoại.`,"codexSet.about.personality":`Hướng dẫn về giọng điệu và phong cách, được điều khiển bởi một feature flag.`,"codexSet.about.context-window-guidance":`Lời khuyên về ngân sách context còn lại, được điều khiển bởi một feature flag.`,"codexSet.about.realtime":`Được thêm vào cho các phiên realtime.`,"codexSet.about.agents-md":`Tệp AGENTS.md cho dự án của bạn. Trang này chỉ báo cáo layer; nó không bao giờ chỉnh sửa tài liệu dự án của bạn.`,"codexSet.about.permissions":`Giải thích về sandbox và các cài đặt phê duyệt đang có hiệu lực.`,"codexSet.about.collaboration":`Giải thích chế độ cộng tác đang hoạt động.`,"codexSet.about.environment":`Thư mục làm việc, nền tảng, và các sự kiện môi trường thực tế khác.`,"codexSet.about.environments-instructions":`Hướng dẫn cho môi trường thực thi trì hoãn, được điều khiển bởi một feature flag.`,"codexSet.about.apps":`Cách sử dụng các ứng dụng đã kết nối.`,"codexSet.about.plugins":`Được thêm vào khi một plugin được chọn hoặc khi bất kỳ plugin nào quảng cáo về năng lực của mình.`,"codexSet.about.tools":`Mô tả công cụ trì hoãn, được điều khiển bởi một feature flag.`,"codexSet.about.skills":`Danh sách các kỹ năng (skills) khả dụng.`,"codexSet.about.multi-agent-mode":`Chỉ thị cho subagent, được điều khiển bởi một feature flag.`,"codexSet.about.git-attribution":`Yêu cầu model thêm trailer Co-authored-by: Codex vào các commit mà nó viết, và dòng Generated with Codex. vào các pull request mà nó mở. Codex phân giải điều này từ tài khoản của bạn, vì vậy không có cài đặt nào cho nó ở đây hay dưới phần [features]. Khi tài khoản của bạn tắt tính năng này, Codex sẽ gửi hướng dẫn ngược lại thay vì không gửi gì.`,"codexSet.condition.model-switch":`Chỉ được phát ra sau khi có sự thay đổi model giữa phiên làm việc.`,"codexSet.condition.realtime":`Chỉ được phát ra trong phiên realtime.`,"codexSet.condition.agents-md":`Được phát ra khi tìm thấy một tài liệu dự án cho thư mục làm việc.`,"codexSet.condition.plugins":`Được phát ra khi một plugin được chọn hoặc khi có bất kỳ plugin nào quảng cáo về năng lực của mình.`,"codexSet.condition.git-attribution":`Được cấu hình bởi chính sách attribution của tài khoản của bạn.`,"codexSet.base.title":`Base prompt`,"codexSet.base.prev":`Tuỳ chọn trước đó`,"codexSet.base.next":`Tuỳ chọn tiếp theo`,"codexSet.base.position":`{position} / {total}`,"codexSet.base.swipeHint":`Vuốt sang một bên, sử dụng các phím mũi tên hoặc nhấn vào các mũi tên để di chuyển qua lại giữa các tuỳ chọn. Chỉ áp dụng cho các phiên mới bắt đầu.`,"codexSet.base.defaultTitle":`Base prompt của riêng Codex`,"codexSet.base.defaultBody":`Mặc định không được lưu ở đây, vì vậy không có gì để chỉnh sửa hoặc xoá: việc chọn nó đơn giản là sẽ xoá model_instructions_file khỏi cấu hình của bạn, và Codex sử dụng prompt đi kèm với nó.`,"codexSet.base.variantTitle":`Tên`,"codexSet.base.variantBody":`Prompt`,"codexSet.base.replacesWarning":`Điều này SẼ THAY THẾ base prompt của chính Codex chứ không bổ sung thêm. Một prompt ngắn ở đây đồng nghĩa với một model có những chỉ thị ngắn.`,"codexSet.base.use":`Sử dụng cái này`,"codexSet.base.inUse":`Đang sử dụng`,"codexSet.base.externalBlocked":`model_instructions_file đã được trỏ tới {path}, tệp mà opencodex không hề viết. Hãy tự xoá tệp đó đi trước khi chọn một tuỳ chọn tại đây.`,"nav.api":`API`,"nav.integrations":`Tích hợp`,"nav.openMenu":`Mở menu`,"nav.closeMenu":`Đóng menu`,"nav.goHome":`Đi tới bảng điều khiển`,"pws.refreshAllQuotas":`Làm mới tất cả hạn mức`,"pws.quotaRefreshDone":`Đã kiểm tra hạn mức xong`,"integrations.subtitle":`Kết nối các client với opencodex, quản lý thông tin xác thực, và khôi phục cấu hình client.`,"integrations.tabsLabel":`Các bề mặt tích hợp`,"integrations.tab.overview":`Tổng quan`,"integrations.tab.keys":`API Keys`,"integrations.tab.codex":`Codex`,"integrations.tab.claude":`Claude`,"integrations.tab.grok":`Grok Build`,"integrations.tab.cursor":`Cursor`,"integrations.tab.opencode":`OpenCode`,"integrations.tab.pi":`Pi`,"integrations.tab.omp":`OMP`,"integrations.tab.hermes":`Hermes`,"integrations.tab.openclaw":`OpenClaw`,"integrations.tab.kimi":`Kimi Code`,"integrations.tab.gajae":`Gajae Code`,"integrations.tab.dsh":`DSH`,"integrations.tab.mcode":`MiniMax Code`,"integrations.tab.zcode":`ZCode`,"integrations.tab.prime":`Prime Agent`,"integrations.tab.aside":`Aside`,"integrations.tab.raycast":`Raycast`,"integrations.tab.omo":`omo`,"integrations.tab.cline":`Cline CLI`,"integrations.aside.profilesTitle":`Cấu hình Aside`,"integrations.aside.profilesHint":`Chọn profile nào sẽ nhận các model được chọn. Profile đang hoạt động của Aside sẽ được giữ nguyên.`,"integrations.aside.all":`Đồng bộ tất cả profile`,"integrations.aside.syncNow":`Đồng bộ ngay`,"integrations.aside.applied":`{count}/{total} profile đã được áp dụng`,"integrations.aside.current":`Profile hiện tại`,"integrations.aside.profile":`Profile {id}`,"integrations.aside.toggle":`Đồng bộ {name}`,"integrations.aside.details":`Quản lý {name}`,"integrations.aside.back":`Tất cả profile Aside`,"integrations.aside.empty":`Mở Aside và tạo một profile để kết nối nó.`,"integrations.aside.partial":`Một số profile cần chú ý. Các lựa chọn đồng bộ của bạn đã được lưu; hãy kiểm tra trạng thái của từng profile.`,"integrations.aside.pending":`Lựa chọn đồng bộ đã được lưu; đang chờ cập nhật file.`,"integrations.aside.retry":`Thử lại {name}`,"integrations.aside.loadError":`Không thể tải các profile Aside. Thử lại để kiểm tra trạng thái của chúng.`,"integrations.codex.title":`Codex CLI`,"integrations.codex.body":`Việc kết nối Codex do proxy service quản lý. Khởi động opencodex sẽ áp dụng nó; dừng service sẽ khôi phục lại định tuyến nguyên bản.`,"integrations.codex.openService":`Mở cài đặt service`,"integrations.state.notInstalled":`Chưa cài đặt`,"integrations.state.unknown":`Đang kiểm tra…`,"integrations.detail.codexRouted":`Các request của Codex đi qua proxy này`,"integrations.detail.codexAbsent":`Codex chưa được định tuyến qua proxy này`,"integrations.detail.keyCount":`{count} key đã được cấp`,"integrations.detail.keyNone":`Chưa có key nào được cấp`,"integrations.detail.keyChecking":`Đang kiểm tra…`,"integrations.detail.keyUnavailable":`Không có thông tin trạng thái key`,"integrations.detail.claudeOff":`Kết nối đang tắt`,"integrations.detail.desktopCurrent":`Desktop đang chạy profile này`,"integrations.detail.desktopStale":`File profile đã bị thay đổi sau khi được áp dụng`,"integrations.detail.desktopNotServed":`Profile có tồn tại, nhưng Desktop đang sử dụng một profile khác`,"integrations.detail.desktopAbsent":`Chưa có profile nào được áp dụng`,"integrations.detail.desktopDesiredOff":`Tích hợp Claude Desktop đang tắt`,"integrations.detail.desktopDesiredOffCleanupPending":`Claude Desktop vẫn đang sử dụng gateway; đang chờ dọn dẹp`,"integrations.detail.desktopDesiredOnNotApplied":`Tích hợp đang bật, nhưng Desktop không sử dụng profile gateway`,"integrations.detail.desktopSelectedElsewhere":`Desktop đang sử dụng một profile khác`,"integrations.detail.desktopProfileDrift":`Profile Desktop được chọn đã bị thay đổi`,"integrations.detail.desktopObservedUnsafe":`Không thể thay đổi profile Desktop được chọn một cách an toàn`,"integrations.detail.desktopNotInstalled":`Thư viện cấu hình Claude Desktop chưa được cài đặt`,"integrations.detail.grokModels":`{count} model đã được kết nối`,"integrations.detail.grokAbsent":`Không có block opencodex nào trong config`,"integrations.detail.cursorSeen":`Cursor đã gọi proxy này gần đây`,"integrations.detail.cursorNeverSeen":`Đã cài đặt Private Inference; chưa thấy request nào`,"integrations.detail.cursorAbsent":`Không tìm thấy Cursor Private Inference`,"integrations.cursor.title":`Cursor`,"integrations.cursor.intro":`Cursor Private Inference chạy agent của nó cục bộ và giao tiếp với opencodex trên loopback. Cursor bản thường không thể làm điều này: backend của nó gọi endpoint tùy chỉnh và cần một URL HTTPS công khai. Trang này không bao giờ ghi dữ liệu vào Cursor; bạn hãy tự dán các giá trị bên dưới vào Cursor.`,"integrations.cursor.loading":`Đang đọc trạng thái Cursor…`,"integrations.cursor.unavailable":`Không thể đọc trạng thái Cursor từ proxy.`,"integrations.cursor.detection":`Các bản cài đặt được phát hiện`,"integrations.cursor.privateInference":`Cursor Private Inference`,"integrations.cursor.regular":`Cursor (bản thường)`,"integrations.cursor.detected":`Đã phát hiện`,"integrations.cursor.notFound":`Không tìm thấy`,"integrations.cursor.regularOnly":`Chỉ tìm thấy Cursor bản thường. Nó định tuyến các custom endpoint qua server của Cursor, vì vậy proxy loopback không thể tiếp cận nếu không có public tunnel. Hãy xem hướng dẫn về bản Private Inference.`,"integrations.cursor.nothingFound":`Không tìm thấy bản cài đặt Cursor nào ở các vị trí thông thường. Nếu nó được cài đặt ở nơi khác, các giá trị bên dưới vẫn được áp dụng.`,"integrations.cursor.gateway":`Giá trị Gateway`,"integrations.cursor.gatewayHint":`Trong Cursor Private Inference, mở Settings > Models > Gateway, dán hai giá trị này, sau đó nhấn Refresh model list.`,"integrations.cursor.baseUrl":`Base URL`,"integrations.cursor.apiKey":`API Key`,"integrations.cursor.apiKeyCredential":`Một trong các API key opencodex của bạn (liên kết này yêu cầu credential)`,"integrations.cursor.copy":`Sao chép`,"integrations.cursor.copied":`Đã sao chép`,"integrations.cursor.connection":`Kết nối`,"integrations.cursor.seen":`Request cuối cùng từ Cursor: {time} ({ua})`,"integrations.cursor.neverSeen":`Chưa có request nào từ Cursor kể từ khi khởi động proxy. Sau khi lưu gateway, hãy nhấn Refresh model list trong Cursor.`,"integrations.cursor.models":`Những gì Cursor sẽ hiển thị`,"integrations.cursor.modelsHint":`Cursor lấy danh sách Reasoning từ bảng model của riêng nó, vì vậy opencodex chỉ có thể dự đoán. Context liệt kê mặc định và cửa sổ opt-in (Max Mode của Cursor).`,"integrations.cursor.ladderFromBundle":`Danh sách Reasoning đọc từ gói Cursor Private Inference {version} đã cài đặt. Cursor quyết định chúng; opencodex chỉ báo cáo bảng của nó.`,"integrations.cursor.ladderFromStatic":`Danh sách Reasoning là một bản sao tĩnh của Cursor 3.18.25 (không tìm thấy gói Private Inference nào có thể đọc được). Context liệt kê mặc định và cửa sổ opt-in.`,"integrations.cursor.unknownVersion":`không rõ phiên bản`,"integrations.cursor.noControl":`—`,"integrations.cursor.singleWindow":`cửa sổ đơn`,"integrations.cursor.noControlTitle":`ID này không có trong bảng effort tích hợp của Cursor, nên Cursor sẽ không hiển thị nút điều khiển Reasoning.`,"integrations.cursor.effortRowsOne":`1 dòng effort được công bố`,"integrations.cursor.effortRowsMany":`{n} dòng effort được công bố`,"integrations.cursor.effortRowsOff":`không có dòng effort`,"integrations.cursor.tableLessHint":`Các dòng được đánh dấu — sẽ không có nút điều khiển Reasoning trong Cursor. Bật cursorEffortRows để xuất ra một mục lựa chọn cho mỗi effort (id--effort), hoặc đặt modelDefaultReasoningEfforts trên provider để dùng mặc định cố định.`,"integrations.cursor.colModel":`Model`,"integrations.cursor.colReasoning":`Reasoning`,"integrations.cursor.colContext":`Context`,"integrations.cursor.guide":`Mở hướng dẫn Cursor Private Inference`,"integrations.dialog.codex.title":`Vô hiệu hóa tích hợp Codex?`,"integrations.dialog.codex.changes":`opencodex sẽ gỡ bỏ routing của nó khỏi {path}, gỡ bỏ profile nó tạo ra, khôi phục lại model catalog mặc định, và đổi thẻ các luồng có thể tiếp tục về native Codex.`,"integrations.dialog.codex.breakage":`Codex thuần sẽ kết nối trực tiếp đến OpenAI, và các model được định tuyến từ provider khác sẽ biến mất khỏi Codex. Proxy và /v1/responses vẫn tiếp tục chạy cho các client khác.`,"integrations.dialog.codex.undo":`Bật lại tính năng này sẽ xây dựng lại catalog được định tuyến từ các model hiện có và chèn Codex vào một lần nữa. Lịch sử cũ có thể dùng lại được cho hướng tương ứng, nhưng các file không được khôi phục chính xác từng byte.`,"integrations.dialog.codex.sideEffect":`Nếu bạn chọn một routed root model sau khi opencodex chèn cấu hình, việc vô hiệu hóa sẽ gỡ bỏ lựa chọn model đó và bật lại tích hợp sẽ không thể phục hồi nó; bạn hãy chọn lại model. Nếu một model_provider ngoài quản lý Codex, opencodex chỉ gỡ bỏ journal cũ của nó và giữ nguyên cấu hình, catalog và lịch sử.`,"integrations.dialog.codex.confirm":`Vô hiệu hóa`,"integrations.dialog.grok.title":`Vô hiệu hóa tích hợp Grok Build?`,"integrations.dialog.grok.changes":`Chỉ block được đánh dấu bởi opencodex sẽ bị gỡ bỏ khỏi {path}. Nội dung được ghi bên ngoài block sẽ giữ nguyên.`,"integrations.dialog.grok.breakage":`Việc vô hiệu hóa sẽ gỡ bỏ các bí danh model opencodex khỏi Grok Build. Các model được dùng với tài khoản xAI của bạn vẫn hoạt động.`,"integrations.dialog.grok.undo":`Nếu opencodex đang chạy trên địa chỉ loopback, việc bật lại tính năng này sẽ ghi một block mới từ các model hiện có.`,"integrations.dialog.grok.confirm":`Vô hiệu hóa`,"integrations.dialog.desktop.title":`Vô hiệu hóa tích hợp Claude Desktop?`,"integrations.dialog.desktop.changes":`Nếu {path} chứa một profile gateway do opencodex quản lý, Desktop sẽ chuyển về một profile tiêu chuẩn không cần credential, sau đó xóa profile cũ và bản sao lưu.`,"integrations.dialog.desktop.breakage":`Claude Desktop sẽ trở lại dùng Claude tiêu chuẩn thay vì các model định tuyến qua opencodex.`,"integrations.dialog.desktop.undo":`Bật lại tính năng này sẽ tạo lại profile opencodex từ các thiết lập model đã lưu của bạn.`,"integrations.dialog.desktop.restart":`Claude Desktop chỉ đọc cấu hình này khi khởi động. Hãy thoát hoàn toàn và mở lại để thay đổi có hiệu lực.`,"integrations.dialog.desktop.confirm":`Vô hiệu hóa`,"integrations.native.msg.nonLoopbackRemoved":`Grok Build chỉ có thể tự động đăng ký khi opencodex đang chạy trên một địa chỉ loopback. Block trước đó trỏ tới loopback đã bị xóa.`,"integrations.native.msg.nonLoopbackRemovedNoop":`Grok Build chỉ có thể tự động đăng ký khi opencodex đang chạy trên một địa chỉ loopback. Không có block trước đó nào để xóa.`,"integrations.native.msg.nonLoopbackSuperseded":`Grok Build chỉ có thể tự động đăng ký khi opencodex đang chạy trên một địa chỉ loopback. Một tiến trình khác đã ghi một block mới trong khi chờ, do đó block hiện tại trong file không phải do request này tạo ra.`,"integrations.native.error.orphanedMarker":`{path} có một điểm bắt đầu của opencodex nhưng không có điểm kết thúc. File không được thay đổi vì opencodex không thể xác định điểm cuối của block.`,"integrations.native.error.homeMismatch":`Thư mục cài đặt service không khớp với thư mục hiện tại, vì vậy file không được thay đổi.`,"integrations.native.error.notInstalled":`Grok Build chưa được cài đặt, nên không có gì để thay đổi.`,"integrations.native.error.configBusy":`Cấu hình đang được lưu ở nơi khác và không thể thay đổi. Hãy thử lại sau ít phút.`,"integrations.native.error.desktopUnsafeMetadata":`Metadata của Claude Desktop tại {path} không thể được đọc một cách an toàn, vì vậy thư viện của nó không được thay đổi.`,"integrations.native.error.desktopCleanupIncomplete":`Claude Desktop đang trỏ tới chế độ tiêu chuẩn, nhưng các file credential opencodex cũ vẫn còn tại: {paths}.`,"integrations.native.msg.desktopDisabled":`Tích hợp Claude Desktop đã bị vô hiệu hóa.`,"integrations.native.msg.desktopEnabled":`Tích hợp Claude Desktop đã được kích hoạt.`,"integrations.state.absent":`Chưa được áp dụng`,"integrations.state.current":`Đã được áp dụng`,"integrations.state.stale":`Cần cập nhật`,"integrations.state.conflict":`Xung đột`,"integrations.state.unsafe":`Không thể xác minh`,"integrations.summary.detected":`Các client được phát hiện`,"integrations.summary.applied":`Các client đã cấu hình`,"integrations.summary.stale":`Cần cập nhật`,"integrations.summary.lastChange":`Thay đổi cuối cùng`,"integrations.summary.disableAll":`Vô hiệu hóa tất cả…`,"integrations.onboarding":`Việc áp dụng sẽ ghi một provider block opencodex sau khi lưu một bản sao lưu. Việc vô hiệu hóa chỉ xóa block đó, và bản sao lưu đã giữ lại có thể được dùng để khôi phục.`,"integrations.empty.title":`Không tìm thấy client nào đã được cài đặt`,"integrations.empty.body":`Hãy cài đặt một client được hỗ trợ, sau đó quay lại đây để áp dụng opencodex.`,"integrations.action.apply":`Áp dụng`,"integrations.action.disable":`Vô hiệu hóa`,"integrations.action.refresh":`Cập nhật`,"integrations.action.settings":`Cài đặt`,"integrations.action.manageKeys":`Quản lý key`,"integrations.action.restore":`Khôi phục…`,"integrations.action.undo":`Hoàn tác`,"integrations.action.restorePoint":`Khôi phục điểm này…`,"integrations.action.snapshotExpired":`Bản sao lưu đã hết hạn`,"integrations.rollback.title":`Trung tâm hoàn tác`,"integrations.rollback.empty":`Chưa có lịch sử áp dụng`,"integrations.rollback.emptyBody":`Mỗi lần ghi thành công sẽ lưu một bản sao lưu trước khi ghi.`,"integrations.catalog.title":`Clients`,"integrations.rollback.older":`Các thao tác cũ hơn`,"integrations.rollback.showMore":`Hiển thị thêm {n} mục`,"integrations.rollback.failed":`Không thể tải lịch sử hoàn tác.`,"integrations.rollback.delete":`Xóa`,"integrations.rollback.deleteAria":`Xóa mục hoàn tác từ {at}`,"integrations.rollback.deleteNewest":`Mục gần đây nhất của client này được giữ lại để bạn vẫn có thể hoàn tác nó.`,"integrations.rollback.deleteGone":`Mục này đã bị xóa. Danh sách sẽ tự động làm mới.`,"integrations.dialog.deleteEntry.title":`Xóa mục hoàn tác này?`,"integrations.dialog.deleteEntry.changes":`Mục này sẽ biến mất khỏi danh sách hoàn tác, và bất kỳ bản sao lưu nào nó giữ cho {path} sẽ bị xóa khỏi đĩa.`,"integrations.dialog.deleteEntry.breakage":`Bạn sẽ không thể khôi phục file về thời điểm này nữa. Các mục mới hơn và bản thân file sẽ không bị ảnh hưởng.`,"integrations.dialog.deleteEntry.undo":`Thao tác này không thể hoàn tác. Mục gần đây nhất của mỗi client luôn được giữ lại và không thể xóa.`,"integrations.dialog.deleteEntry.confirm":`Xóa mục`,"integrations.restore.title":`Khôi phục bản sao lưu này?`,"integrations.restore.body":`File hiện tại sẽ được sao lưu trước, sau đó bản sao lưu đã chọn sẽ thay thế nó.`,"integrations.restore.driftTitle":`Đã phát hiện các thay đổi mới hơn`,"integrations.restore.driftBody":`Các thay đổi được thực hiện sau bản sao lưu này sẽ được sao lưu lại, sau đó file sẽ bị thay thế.`,"integrations.restore.confirm":`Khôi phục`,"integrations.restore.confirmDrift":`Sao lưu các thay đổi mới và khôi phục`,"integrations.restore.pending":`Đang khôi phục…`,"integrations.restore.manual":`Khôi phục tự động thất bại: {reason}. Hãy khôi phục thủ công từ {path}.`,"integrations.error.load":`Không thể tải trạng thái tích hợp.`,"integrations.error.stale":`Lần làm mới cuối cùng thất bại. Các giá trị bên dưới có thể đã cũ.`,"integrations.error.busy":`Một thay đổi khác cho client này vẫn đang chạy. Hãy thử lại sau ít phút.`,"integrations.error.conflict":`Cấu hình đã thay đổi sau khi opencodex ghi nó. Không có nội dung nào bị xóa.`,"integrations.error.unsafe":`Cấu hình không thể thay đổi một cách an toàn.`,"integrations.error.generic":`Việc thay đổi tích hợp thất bại. Trạng thái trước đó của bạn vẫn được giữ nguyên.`,"integrations.error.nonLoopback":`{client} chỉ có thể kết nối với proxy trên localhost — cấu hình của nó không có chỗ để đặt header admission mà một kết nối từ xa yêu cầu, vì vậy việc viết thủ công cũng không giúp ích. Thay vào đó, hãy cấp quyền truy cập loopback cho nó qua một tunnel hoặc local forwarder.`,"integrations.status.installed":`Đã cài đặt`,"integrations.status.notInstalled":`Chưa cài đặt`,"integrations.status.appliedAt":`Đã áp dụng`,"integrations.status.supersededStore":`Máy khách này hiện đọc danh sách nhà cung cấp từ {path}, tệp mà opencodex không ghi, nên bật ở đây sẽ không thay đổi những gì nó tải.`,"integrations.status.backup":`Sao lưu`,"integrations.status.lastRestore":`Lần khôi phục cuối`,"integrations.status.unknown":`Không xác định`,"integrations.bulk.title":`Vô hiệu hóa các tích hợp client đã áp dụng?`,"integrations.bulk.body":`Chỉ block thuộc về opencodex mới bị xóa. Một bản sao lưu trước khi ghi sẽ được giữ lại cho từng client.`,"integrations.bulk.partial":`Một số client không thể vô hiệu hóa: {clients}`,"integrations.bulk.success":`Các tích hợp client đã áp dụng đã bị vô hiệu hóa.`,"integrations.retention.degraded":`Việc dọn dẹp bản sao lưu bị chậm trễ; các bản sao lưu cũ hơn có thể vẫn còn trên đĩa.`,"integrations.error.residual":`File có thể đang ở trạng thái trung gian: {message} Hãy khôi phục nó từ {path}.`,"integrations.error.residualNoSnapshot":`{message} Quá trình khôi phục tự động chưa hoàn tất. Hãy kiểm tra cấu hình client trước khi thử lại.`,"integrations.error.recover":`{message} Một bản sao lưu nằm tại {path}.`,"integrations.kind.apply":`Đã áp dụng`,"integrations.kind.disable":`Đã tắt`,"integrations.kind.refresh":`Đã cập nhật`,"integrations.kind.restore":`Đã khôi phục`,"integrations.kind.overwrite":`Đã ghi đè`,"integrations.dialog.overwrite.title":`Thay thế block trong config này?`,"integrations.dialog.overwrite.changesUnowned":`Một block không do chúng ta ghi đã chiếm lấy các thiết lập mà opencodex cần trong {path}. Việc áp dụng sẽ thay thế nó bằng block mà opencodex sẽ ghi.`,"integrations.dialog.overwrite.changesForeign":`Thay đổi của bạn bên trong block opencodex ở {path} sẽ bị loại bỏ và thay thế bằng block mà opencodex sẽ ghi.`,"integrations.dialog.overwrite.breakage":`Bất cứ thứ gì mà block kia cấu hình sẽ ngừng hoạt động. Nội dung ở những chỗ khác trong file được giữ nguyên.`,"integrations.dialog.overwrite.undo":`Một bản sao lưu sẽ được lưu trước tiên, do đó thao tác này sẽ xuất hiện trong danh sách hoàn tác bên dưới và có thể được khôi phục.`,"integrations.dialog.overwrite.confirm":`Thay thế`,"integrations.action.overwrite":`Thay thế`,"integrations.preview.loading":`Đang tải kế hoạch thay đổi chính xác…`,"integrations.preview.failed":`Không thể tải kế hoạch thay đổi. Không có gì bị thay đổi.`,"integrations.preview.stale":`Tích hợp đã thay đổi trong lúc xác nhận. Hãy xem kế hoạch mới và xác nhận lại.`,"integrations.dialog.apply.title":`Áp dụng tích hợp này?`,"integrations.dialog.apply.changes":`opencodex sẽ thêm các cài đặt nhà cung cấp do nó quản lý vào cấu hình máy khách.`,"integrations.dialog.apply.breakage":`Máy khách sẽ dùng các mô hình hiện được phiên bản opencodex này cung cấp.`,"integrations.dialog.apply.undo":`Bản sao lưu được lưu trước và có thể hoàn tác thay đổi trong trung tâm khôi phục.`,"integrations.dialog.apply.confirm":`Áp dụng`,"integrations.dialog.disable.title":`Tắt tích hợp này?`,"integrations.dialog.disable.changes":`Chỉ các cài đặt thuộc opencodex sẽ bị xóa.`,"integrations.dialog.disable.breakage":`Máy khách sẽ ngừng dùng các mô hình được định tuyến qua phiên bản opencodex này.`,"integrations.dialog.disable.undo":`Bản sao lưu được lưu trước và có thể hoàn tác thay đổi trong trung tâm khôi phục.`,"integrations.dialog.disable.confirm":`Tắt`,"integrations.plan.heading":`Kế hoạch thay đổi từ máy chủ`,"integrations.plan.operation":`Thao tác: {operation}`,"integrations.plan.operation.apply":`Áp dụng`,"integrations.plan.operation.overwrite":`Thay thế`,"integrations.plan.operation.disable":`Tắt`,"integrations.plan.operation.restore":`Khôi phục`,"integrations.plan.change.add":`Thêm`,"integrations.plan.change.replace":`Thay thế`,"integrations.plan.change.remove":`Xóa`,"integrations.plan.change.snapshot":`Lưu bản sao`,"integrations.plan.change.ownership":`Cập nhật bản ghi quyền sở hữu`,"integrations.plan.change.journal":`Ghi mục khôi phục`,"integrations.plan.foreign.none":`Không phát hiện chỉnh sửa bên ngoài.`,"integrations.plan.foreign.unowned":`Một khối cài đặt không thuộc opencodex sẽ bị thay thế.`,"integrations.plan.foreign.foreignEdit":`Các chỉnh sửa trong khối do opencodex quản lý sẽ bị thay thế.`,"integrations.plan.foreign.drift":`Tệp đã thay đổi kể từ điểm khôi phục này.`,"integrations.plan.noop.applied":`Không cần thay đổi tài liệu máy khách được quản lý; cài đặt tích hợp đã có sẵn.`,"integrations.plan.noop.disabled":`Không cần thay đổi tài liệu máy khách được quản lý; cài đặt tích hợp đã không còn.`,"integrations.plan.noop.profilePreference":`Tùy chọn đồng bộ hồ sơ vẫn sẽ được lưu khi bạn xác nhận.`,"integrations.plan.refused":`Máy chủ không thể áp dụng kế hoạch này một cách an toàn.`,"integrations.plan.refusal.notInstalled":`Máy khách chưa được cài đặt. Hãy cài đặt, làm mới trang và xem trước thay đổi lần nữa.`,"integrations.plan.refusal.conflict":`Cài đặt được quản lý xung đột với tệp hiện tại. Hãy xem lại tệp hoặc dùng Thay thế khi có thể.`,"integrations.plan.refusal.unsafe":`Không thể thay đổi cấu hình máy khách một cách an toàn. Hãy sửa hoặc thay tệp trước khi thử lại.`,"integrations.plan.refusal.nonLoopback":`Máy khách này cần địa chỉ proxy loopback. Hãy dùng localhost, đường hầm hoặc chuyển tiếp cục bộ.`,"integrations.plan.refusal.supersededStore":`Máy khách này đọc danh sách nhà cung cấp từ một tệp mà opencodex không ghi, nên thao tác này sẽ không thay đổi những gì nó tải.`,"integrations.plan.refusal.driftRequiresConfirm":`Tệp đã thay đổi sau điểm khôi phục này. Hãy xem kế hoạch có tính đến thay đổi trước khi khôi phục.`,"integrations.plan.refusal.snapshotExpired":`Bản sao lưu cho điểm khôi phục này đã hết hạn nên không thể khôi phục nữa.`,"integrations.plan.refusal.writeFailed":`Máy chủ không thể chuẩn bị thao tác ghi an toàn. Hãy làm mới trạng thái tích hợp trước khi thử lại.`,"integrations.mutation.pending":`Đang áp dụng thay đổi đã xác nhận…`,"integrations.bulk.breakage":`Mỗi máy khách sẽ ngừng dùng các mô hình được định tuyến qua phiên bản opencodex này.`,"integrations.bulk.undo":`Mỗi máy khách giữ bản sao lưu và mục khôi phục riêng.`,"integrations.bulk.confirm":`Tắt tất cả`,"integrations.semantics.opencode":`Chỉ khởi chạy trực tiếp trên đĩa; việc inject môi trường ocx opencode sẽ được ưu tiên.`,"integrations.semantics.pi":`Áp dụng cho các session mới.`,"integrations.semantics.omp":`Khởi động lại OMP để tải catalog.`,"integrations.semantics.hermes":`Áp dụng cho các session mới.`,"integrations.semantics.openclaw":`Áp dụng ngay cho gateway đang chạy.`,"integrations.semantics.kimi":`Khởi động lại hoặc chạy /reload để áp dụng (v2 theo dõi file).`,"integrations.semantics.gajae":`Áp dụng cho session mới hoặc khi mở /model.`,"integrations.semantics.dsh":`OpenCodex chỉ quản lý llm-pi-ai.providers.opencodex trong $DSH_HOME/settings.yaml. DSH sẽ hot reload provider này; model mặc định của bạn và deepseek-official không thay đổi. Hiện chỉ hỗ trợ loopback; không ghi credential thật nào.`,"integrations.semantics.mcode":`Chỉ quản lý custom_provider.opencodex. Model mặc định của bạn và đăng nhập MiniMax không thay đổi.`,"integrations.semantics.zcode":`Chỉ quản lý provider.opencodex trong ~/.zcode/v2/config.json. Đăng nhập Z.ai của bạn và các provider khác không thay đổi. Khởi động lại ZCode sau khi thay đổi.`,"integrations.semantics.prime":`Chỉ quản lý providers.opencodex trong models.json của Prime Agent — ~/.prime/agent trừ khi PRIME_AGENT_CODING_AGENT_DIR điều hướng nó. Các provider khác và ngoại lệ model của bạn không thay đổi. Áp dụng cho các session mới.`,"integrations.semantics.aside":`Chỉ quản lý providers.opencodex trong ~/.aside/u/<id>/models.json của profile này. Các provider khác của bạn không thay đổi. Hãy thoát hoàn toàn và mở lại Aside sau khi áp dụng.`,"integrations.semantics.raycast":`Thêm một provider OpenCodex vào providers.yaml của Raycast để mọi model được định tuyến xuất hiện trong bộ chọn model AI của Raycast. Yêu cầu Raycast Pro.`,"integrations.semantics.omo":`Chỉ quản lý providers.opencodex trong models.json của omo — ~/.omo/agent, trừ khi OMO_CODING_AGENT_DIR, SENPI_CODING_AGENT_DIR hoặc PI_CODING_AGENT_DIR chuyển hướng. Các nhà cung cấp khác của bạn không thay đổi. Áp dụng cho phiên mới.`,"integrations.semantics.cline":`Quản lý OpenCodex trong providers.json và models.json của Cline CLI. Hãy dừng Cline trước khi thay đổi hoặc đồng bộ các tệp này, rồi khởi động lại. Hoàn tác sẽ khôi phục cả hai bản gốc. Nhà cung cấp mặc định của bạn không thay đổi; hãy chọn OpenCodex trong Cline.`,"integrations.raycast.proRequired":`Custom Providers là một tính năng của Raycast Pro. File sẽ được ghi, nhưng Raycast sẽ bỏ qua nó cho đến khi đăng ký Pro được kích hoạt.`,"integrations.raycast.planUnknown":`Không thể xác định xem Raycast Pro có đang hoạt động hay không; Custom Providers yêu cầu Raycast Pro.`,"integrations.raycast.revealConfig":`Mở Raycast → Settings → AI và nhấp vào Reveal Providers Config một lần để thư mục providers được tạo.`,"codexAuth.mainAccount":`Tài khoản chính`,"codexAuth.logLabel":`Nhãn log`,"codexAuth.codexApp":`Codex App`,"codexAuth.moreActions":`Hiển thị thêm hành động`,"codexAuth.copyId":`Sao chép Account ID`,"codexAuth.appLogin":`Đăng nhập App`,"codexAuth.accountPool":`Pool tài khoản`,"codexAuth.accountModeTitle":`Chế độ tài khoản OpenAI`,"codexAuth.accountModePool":`Chế độ Pool`,"codexAuth.accountModePoolDesc":`Tài khoản đăng nhập chính và các tài khoản đủ điều kiện được thêm vào sẽ luân phiên ở đây.`,"codexAuth.accountModeDirect":`Chế độ Direct`,"codexAuth.accountModeDirectDesc":`Các request chỉ sử dụng tài khoản đăng nhập chính; các tài khoản được thêm vào vẫn được lưu để dùng cho chế độ Pool.`,"codexAuth.openaiMissing":`Provider OpenAI mặc định chưa được cấu hình.`,"codexAuth.openaiDisabled":`Provider OpenAI mặc định đang bị vô hiệu hóa.`,"codexAuth.openaiUnavailableDesc":`Các tài khoản OpenAI của bạn vẫn khả dụng. Hãy bật provider để định tuyến các request của Codex.`,"codexAuth.enableOpenai":`Bật OpenAI`,"codexAuth.enablingOpenai":`Đang bật...`,"codexAuth.enableOpenaiFailed":`Không thể bật provider OpenAI.`,"codexAuth.openaiPresetLoadFailed":`Không thể tải preset của provider OpenAI.`,"codexAuth.openaiPresetUnavailable":`Preset của provider OpenAI không khả dụng.`,"codexAuth.openProviders":`Mở Providers`,"codexAuth.add":`Thêm`,"codexAuth.refreshQuota":`Làm mới quota`,"codexAuth.ultraFastTitle":`Dịch vụ cấp độ Ultra Fast`,"codexAuth.mainHardLockTitle":`Khóa tài khoản chính ở mức 99%`,"codexAuth.mainHardLockDesc":`Sử dụng mức 5h nếu có, nếu không thì dùng hàng tuần (hoặc hàng tháng đối với tài khoản chỉ có hàng tháng). Một kết quả đọc 0% mới sẽ tự động mở khóa; bảo vệ vẫn tiếp tục bật.`,"codexAuth.mainHardLockConfirmTitle":`Bật khóa 99% tài khoản chính?`,"codexAuth.mainHardLockConfirmBody":`Khi bị khóa, tài khoản chính không thể sử dụng Luna Reserve. Giữ lượng dùng dưới mức cạn kiệt có thể ngăn việc kích hoạt Reserve. Các tài khoản được thêm vào và provider khác vẫn khả dụng. Các request đang chạy, credential chưa khớp, và lưu lượng ngoài proxy này không được bảo vệ.`,"codexAuth.mainHardLockConfirm":`Bật bảo vệ`,"codexAuth.mainHardLockEnabled":`Bảo vệ 99% đang bật.`,"codexAuth.mainHardLockDisabled":`Bảo vệ 99% đang tắt. Các giới hạn tài khoản khác vẫn được áp dụng.`,"codexAuth.mainHardLockLoadFailed":`Không thể tải cài đặt này. Hãy thử lại để kiểm tra trạng thái hiện tại của nó.`,"codexAuth.mainHardLockSaveFailed":`Không thể xác nhận việc lưu. Tải lại cài đặt trước khi thử lại.`,"codexAuth.mainHardLockRefreshFailed":`Cài đặt đã được lưu, nhưng không thể làm mới trạng thái tài khoản. Vui lòng thử lại.`,"codexAuth.mainHardLockBlocked":`Bị khóa bởi bảo vệ 99%`,"codexAuth.mainHardLockUnknown":`Bảo vệ đang bật · lượng sử dụng chưa rõ`,"codexAuth.mainHardLockMonitoring":`Bảo vệ đang bật · đang theo dõi`,"codexAuth.mainHardLockManage":`Xem thiết lập bảo vệ`,"codexAuth.ultraFastDesc":`Ngăn không cho dịch vụ cấp độ Ultra Fast mà bạn đã thiết lập bị loại bỏ khi catalog được tạo lại, và đưa tên nó vào các request log. Nó không thêm Ultra Fast vào bộ chọn model: upstream chỉ quảng cáo Fast, do đó mục chọn sẽ đưa ra tốc độ mà đường truyền không thể đáp ứng.`,"codexAuth.ultraFastLoadFailed":`Không thể đọc thiết lập Ultra Fast.`,"codexAuth.ultraFastEnabled":`Cấp độ Ultra Fast đã bật`,"codexAuth.ultraFastDisabled":`Cấp độ Ultra Fast đã tắt`,"codexAuth.ultraFastFailed":`Không thể thay đổi thiết lập Ultra Fast`,"codexAuth.refreshingQuota":`Đang làm mới...`,"codexAuth.quotaRefreshed":`Đã làm mới quota`,"codexAuth.quotaRefreshFailed":`Làm mới quota thất bại`,"codexAuth.pauseExhausted":`Tạm ngưng tài khoản cạn kiệt`,"codexAuth.pausingExhausted":`Đang kiểm tra quota...`,"codexAuth.pauseExhaustedSucceeded":`Đã ngưng các tài khoản cạn kiệt: {count}`,"codexAuth.pauseExhaustedNone":`Không có tài khoản nào được xác nhận đã sử dụng 100%.`,"codexAuth.pauseExhaustedFailed":`Kiểm tra và ngưng các tài khoản cạn kiệt thất bại.`,"codexAuth.noPool":`Chưa có tài khoản pool nào được thêm vào.`,"codexAuth.pause":`Tạm dừng`,"codexAuth.resume":`Tiếp tục`,"codexAuth.paused":`ĐÃ TẠM NGƯNG`,"codexAuth.planExcluded":`Không được tự động chọn`,"codexAuth.planExcludedHint":`Gói {plan} bị loại khỏi lựa chọn tự động. Các tuyến tài khoản chỉ định vẫn khả dụng.`,"codexAuth.pauseSucceeded":`{email} đã bị tạm ngưng`,"codexAuth.resumeSucceeded":`{email} đã có mặt lại trong pool`,"codexAuth.pauseFailed":`Không thể ngưng {email}. Không có thay đổi nào.`,"codexAuth.resumeFailed":`Không thể tiếp tục {email}. Không có thay đổi nào.`,"codexAuth.pausedHint":`Được loại trừ khỏi luân phiên tự động, thử lại, hồi phục sau thời gian chờ, và lựa chọn thủ công cho đến khi tiếp tục.`,"codexAuth.pinned":`ĐÃ GHIM`,"codexAuth.pinnedHint":`Bạn đã chọn tài khoản này bằng tay, nên một thứ tự ưu tiên cao hơn sẽ không bỏ qua nó. Việc ghim kéo dài đến khi tài khoản này bị cạn kiệt, bạn chọn một tài khoản khác, hoặc bạn thay đổi bất kỳ thứ tự lựa chọn nào.`,"codexAuth.fiveHour":`5h`,"codexAuth.weekly":`Tuần`,"codexAuth.quotaAutoRefresh":`Tự động kích hoạt cửa sổ`,"codexAuth.quotaAutoRefreshHint":`Gửi một request warm-up Codex tối thiểu, không lưu trữ khi cửa sổ quota này reset.`,"codexAuth.quotaAutoRefreshUpdated":`Tự động kích hoạt cửa sổ đã được cập nhật.`,"codexAuth.quotaAutoRefreshFailed":`Không thể cập nhật tự động kích hoạt cửa sổ.`,"codexAuth.monthly":`30 ngày`,"codexAuth.resets":`làm mới`,"codexAuth.today":`Hôm nay`,"codexAuth.current":`HIỆN TẠI`,"codexAuth.nextSession":`ĐÃ CHỌN`,"codexAuth.poolPrepared":`ĐÃ CHUẨN BỊ CHO POOL`,"codexAuth.preparePoolTitle":`Chuẩn bị tài khoản này cho chế độ Pool?`,"codexAuth.preparePoolDesc":`Các request dạng Direct tiếp tục sử dụng đăng nhập chính. Tài khoản này trở thành lựa chọn được chuẩn bị của Pool khi chế độ Pool được bật.`,"codexAuth.prepareForPool":`Chuẩn bị cho Pool`,"codexAuth.poolPreparedToast":`{email} đã sẵn sàng cho chế độ Pool`,"codexAuth.switchTitle":`Chuyển tài khoản đang hoạt động?`,"codexAuth.switchDesc":`Có hiệu lực ngay lập tức. Các luồng gắn kết với tài khoản đã có và các request đang thực thi sẽ tiếp tục sử dụng tài khoản cũ; các request mới hoặc chưa gán sẽ dùng theo mức ưu tiên của tài khoản mới được chọn, và các tài khoản ở cùng mức độ ưu tiên vẫn sẽ luân phiên.`,"codexAuth.cacheWarning":`Prompt cache sẽ reset khi chuyển tài khoản. Session mới bắt đầu với cache rỗng.`,"codexAuth.setAsNext":`Dùng tài khoản này tiếp theo`,"codexAuth.cancel":`Hủy`,"codexAuth.switchBack":`Chuyển lại sang Main?`,"codexAuth.switchBackDesc":`Có hiệu lực ngay lập tức. Các luồng gắn kết với tài khoản đã có và các request đang thực thi sẽ tiếp tục sử dụng tài khoản cũ; các request mới hoặc chưa gán sẽ sử dụng mức ưu tiên của tài khoản đăng nhập App, và các tài khoản ở cùng mức độ ưu tiên vẫn sẽ luân phiên.`,"codexAuth.autoSwitch":`Luân phiên chủ động theo mức độ sử dụng`,"codexAuth.autoSwitchQuotaDesc":`Quota: ở mức {threshold}% hoặc cao hơn, request tiếp theo có thể chuyển sang một tài khoản khác đủ điều kiện có mức dùng thấp hơn, bao gồm cả một task đang liên kết; Go/Free chỉ dùng khung 30 ngày.`,"codexAuth.autoSwitchQuotaOffDesc":`Chuyển tài khoản chủ động dựa trên mức sử dụng đang tắt. Các gán ghép cho tác vụ mới/chưa gắn kết và hồi phục sự cố vẫn hoạt động.`,"codexAuth.autoSwitchRoundRobinDesc":`Phân bổ luân phiên (Round-robin) không sử dụng ngưỡng này; nó tiếp tục xoay vòng các task mới/chưa gắn kết.`,"codexAuth.autoSwitchFillFirstDesc":`Ưu tiên làm đầy trước (Fill-first): {threshold}% là điểm chuyển hướng cho các task mới/chưa gắn kết; các task đang liên kết hợp lệ vẫn giữ nguyên tài khoản của chúng.`,"codexAuth.autoSwitchFillFirstOffDesc":`Ưu tiên làm đầy trước (Fill-first) không có điểm chuyển hướng mức sử dụng cho các task mới/chưa gắn kết; việc hồi chiêu, tái xác thực, và hồi phục sự cố vẫn có thể thay đổi định tuyến.`,"codexAuth.failureRecoveryNote":`Hồi phục sự cố là một quy trình riêng: một request bị từ chối trước khi có output với 429/402, cooldown, reauthentication, bị loại trừ, hoặc cấu hình chuyển hướng lỗi tạm thời có thể chọn một tài khoản đủ điều kiện khác.`,"codexAuth.autoSwitchThreshold":`Ngưỡng sử dụng`,"codexAuth.autoSwitchThresholdAria":`Ngưỡng sử dụng, phần trăm`,"codexAuth.autoSwitchThresholdInc":`Tăng ngưỡng sử dụng`,"codexAuth.autoSwitchThresholdDec":`Giảm ngưỡng sử dụng`,"codexAuth.autoSwitchLoadFailed":`Không thể tải cài đặt chuyển đổi theo mức sử dụng.`,"codexAuth.autoSwitchThresholdInvalid":`Nhập một số nguyên từ 1 đến 100`,"codexAuth.autoSwitchUpdated":`Cập nhật chuyển đổi chủ động theo mức độ sử dụng thành công`,"codexAuth.autoSwitchUpdateFailed":`Không thể xác nhận bản cập nhật chuyển đổi theo mức sử dụng. Đang hiển thị giá trị được xác nhận gần nhất.`,"codexAuth.requestUserInput":`Yêu cầu người dùng nhập ở chế độ Default`,"codexAuth.requestUserInputDesc":`Cho phép Codex tạm ngưng một session Default-mode và đặt câu hỏi cho bạn bằng tool request_user_input.`,"codexAuth.requestUserInputUpdated":`Tính năng đã được cập nhật - áp dụng cho các session mới.`,"codexAuth.requestUserInputUpdatedRestart":`Tính năng đã được cập nhật - áp dụng cho các session mới. Khởi động lại Codex app để áp dụng.`,"codexAuth.requestUserInputUpdateFailed":`Không thể cập nhật tính năng. Không có thay đổi nào.`,"codexAuth.requestUserInputLoadFailed":`Không thể đọc tính năng từ config.toml.`,"codexAuth.accountPickerTitle":`Chỉ định một tài khoản Codex cụ thể từ bộ chọn model`,"codexAuth.accountPickerOffDesc":`Khi được bật, các mục chọn model GPT thông thường được thay thế bằng một lựa chọn cho mỗi tài khoản, vì vậy bạn có thể chọn chính xác một tài khoản cho cuộc hội thoại mà không cần đăng xuất. Việc tắt đi không xóa bất kỳ tài khoản nào.`,"codexAuth.accountPickerOnDesc":`Mỗi bộ chọn là một nhãn công khai cho một tài khoản đã lưu. Chọn nó sẽ khóa cuộc hội thoại đó với tài khoản được gán: nó không bao giờ luân phiên hoặc fallback, và nó không thay đổi tài khoản Pool đang hoạt động.`,"codexAuth.accountPickerCompatibility":`Tài khoản đăng nhập Codex App tích hợp sẵn có bộ chọn riêng; các liên kết tự tạo thường gọi nó là main và sử dụng hậu tố chống trùng lặp như main-2 khi cần. Các tài khoản được thêm nhận các nhãn an toàn riêng tư, còn các nhãn bộ chọn tùy chỉnh không bị thay đổi. Các cuộc hội thoại hiện có và model đã lưu tiếp tục được định tuyến. Việc tắt tùy chọn này ẩn đi các mục được tạo nhưng vẫn giữ các bộ chọn và các định tuyến chính xác. Các model ID GPT thuần giữ nguyên hành vi Pool hoặc Direct của chúng.`,"codexAuth.accountPickerUpdated":`Việc nhắm mục tiêu tài khoản đã được cập nhật.`,"codexAuth.accountPickerUpdateFailed":`Không thể cập nhật việc nhắm mục tiêu tài khoản. Cài đặt được xác nhận gần nhất đang được hiển thị.`,"codexAuth.accountPickerLoadFailed":`Không thể tải cài đặt nhắm mục tiêu tài khoản.`,"codexAuth.accountPickerRefreshFailed":`Không thể làm mới cài đặt này. Giá trị được xác nhận gần nhất vẫn đang được hiển thị.`,"codexAuth.advancedSettings":`Cài đặt nâng cao`,"codexAuth.advancedSettingsAria":`Hiển thị hoặc ẩn cài đặt xác thực Codex nâng cao`,"codexAuth.catalogRefreshPending":`Thay đổi đã được lưu, nhưng việc làm mới model catalog của Codex vẫn đang chờ xử lý. Hãy chạy ocx sync để thử lại.`,"anthropicPool.title":`Claude account pool (thử nghiệm)`,"anthropicPool.enabledDesc":`Sticky sessions, và các session mới ưu tiên mức sử dụng dưới {threshold}% ({window}).`,"anthropicPool.enabledNoProactiveDesc":`Sticky sessions. Việc chuyển đổi chủ động dựa trên mức sử dụng đang bị vô hiệu hóa với ngưỡng 0, nhưng việc lựa chọn session mới vẫn sử dụng cửa sổ {window}.`,"anthropicPool.disabledDesc":`Mỗi session một tài khoản. Lỗi 429 vẫn sẽ chuyển sang một tài khoản khác đã đăng nhập — điều này không thể bị tắt.`,"anthropicPool.experimentalWarning":`Thử nghiệm và chưa được kiểm chứng đầy đủ. Anthropic có thể giới hạn các tài khoản có vẻ như luân phiên nhiều tài khoản tự động. Cùng một tổ chức có thể chia sẻ quota — gom nhóm các tài khoản đó sẽ không có tác dụng. Vui lòng giữ ở trạng thái tắt trừ khi bạn hiểu rõ rủi ro.`,"anthropicPool.needTwoAccounts":`Thêm ít nhất hai tài khoản Claude OAuth trước khi kích hoạt pool.`,"anthropicPool.threshold":`Ngưỡng sử dụng cho session mới`,"anthropicPool.thresholdAria":`Ngưỡng sử dụng cho session mới, phần trăm`,"anthropicPool.thresholdHelp":`0 sẽ tắt tính năng lựa chọn dựa trên quota (chỉ giữ ái lực + tài khoản đang hoạt động). Mặc định là 80.`,"anthropicPool.thresholdInvalid":`Nhập một số nguyên từ 0 đến 100`,"anthropicPool.loadFailed":`Không thể tải cài đặt Claude pool.`,"anthropicPool.saveFailed":`Không thể lưu cài đặt Claude pool.`,"anthropicPool.on":`Bật`,"anthropicPool.off":`Tắt`,"accountPool.strategy":`Chiến lược xoay vòng`,"accountPool.strategyDesc":`Cách OpenCodex chỉ định tài khoản cho một task mới/chưa gắn kết.`,"accountPool.strategyResetFirst":`Ưu tiên lần đặt lại sớm nhất`,"accountPool.strategyHintResetFirst":`Ưu tiên lần đặt lại 5 giờ hoặc hàng tuần gần nhất trong tương lai giữa các tài khoản dưới ngưỡng sử dụng. Tác vụ đã liên kết tuân theo chính sách affinity đã cấu hình. Hạn ngạch model độc lập dùng thứ tự hạn ngạch.`,"accountPool.strategyQuota":`Quota`,"accountPool.strategyRoundRobin":`Luân phiên`,"accountPool.strategyFillFirst":`Làm đầy trước`,"accountPool.switchAtThreshold":`chuyển ở {threshold}%`,"accountPool.drainAtThreshold":`dùng cạn ở {threshold}%`,"accountPool.resetBelowThreshold":`lần đặt lại gần nhất dưới {threshold}%`,"accountPool.thresholdNotUsed":`không dùng ngưỡng`,"accountPool.proactiveSwitchingOff":`tắt chuyển đổi chủ động`,"accountPool.strategyHintQuota":`Quota cũng có thể liên kết lại một task đang chạy ở request tiếp theo của nó sau khi vượt qua ngưỡng sử dụng.`,"accountPool.strategyHintRoundRobin":`Luân phiên (Round-robin) chỉ chuyển đổi các task không có liên kết hiện tại; ngưỡng sử dụng không làm thay đổi việc luân phiên bình thường.`,"accountPool.strategyHintFillFirst":`Làm đầy trước (Fill-first) sử dụng ngưỡng như là một điểm xả cho các task chưa gắn kết; các task đang liên kết hợp lệ vẫn giữ ái lực.`,"accountPool.unboundDefinition":`Task mới/chưa gắn kết (new/unbound) nghĩa là một request không có liên kết tài khoản nào hiện tại; một task có thể nhìn thấy có thể trở nên chưa gắn kết sau khi proxy hoặc ái lực bị đặt lại.`,"accountPool.stickyLimit":`Các tác vụ mới/chưa gắn kết sẽ giữ nguyên trước khi quay vòng`,"accountPool.stickyLimitAria":`Số lần gán tác vụ mới/chưa gắn kết trước khi xoay vòng`,"accountPool.stickyLimitInc":`Tăng giới hạn dính`,"accountPool.stickyLimitDec":`Giảm giới hạn dính`,"accountPool.stickyLimitHelp":`Giữ tài khoản đã chọn cho số lần gán tác vụ mới/chưa gắn kết này trước khi chuyển sang tài khoản khác; bộ đếm tăng lên khi tác vụ được gắn kết, chứ không phải sau khi upstream thành công.`,"accountPool.stickyLimitInvalid":`Nhập một số nguyên từ 1 đến 100`,"accountPool.strategyLoadFailed":`Không thể tải chiến lược luân phiên.`,"accountPool.strategyUpdateFailed":`Không thể lưu chiến lược luân phiên.`,"accountPool.quotaWindow":`Cửa sổ Quota`,"accountPool.quotaWindowDesc":`Thanh trạng thái sử dụng lưu trong cache nào kiểm soát việc chọn session mới dựa trên quota, kiểm tra ngưỡng fill-first, và các bản thay thế 429 đủ điều kiện.`,"accountPool.quotaWindowFiveHour":`Khung 5 giờ`,"accountPool.quotaWindowWeekly":`Khung hàng tuần`,"accountPool.quotaWindowMaxUtilization":`Khung sử dụng cao hơn`,"accountPool.quotaWindowHint":`Hàng tuần sẽ bỏ qua các tài khoản đã hết mức giới hạn 5 giờ nếu còn tài khoản khác hợp lệ, nhưng sẽ quay về chúng nếu không còn ai khác. Nếu hòa hàng tuần, tài khoản có mức 5 giờ thấp hơn sẽ được ưu tiên; mức hàng tuần cho mỗi tài khoản chỉ được biết sau khi trang Providers đã lấy dữ liệu.`,"accountPool.quotaWindowInert":`Chỉ chiến lược Quota — hoặc Fill-first khi lớn hơn ngưỡng 0 — mới lấy điểm đánh giá mức sử dụng, nên cài đặt này không có tác dụng đối với chiến lược luân phiên hiện tại.`,"accountPool.priority":`Thứ tự chọn`,"accountPool.priorityAria":`Thứ tự ưu tiên cho tài khoản này`,"accountPool.priorityHint":`Số càng cao càng được sử dụng trước. Pool chuyển xuống một số ưu tiên thấp hơn chỉ khi tất cả các tài khoản ở mức trên bị cạn kiệt hoặc không khả dụng.`,"accountPool.priorityFirst":`Đầu tiên`,"accountPool.priorityEarlier":`Sớm hơn`,"accountPool.priorityNormal":`Thông thường`,"accountPool.priorityLater":`Muộn hơn`,"accountPool.priorityLast":`Cuối cùng`,"accountPool.priorityOption":`{name} ({value})`,"accountPool.priorityCustom":`Tùy chỉnh`,"accountPool.priorityUpdated":`Đã cập nhật thứ tự ưu tiên cho {email}`,"accountPool.priorityUpdateFailed":`Không thể lưu thứ tự lựa chọn cho {email}. Giá trị được xác nhận gần nhất đang được hiển thị.`,"codexAuth.switched":`Tài khoản được chọn cho request tiếp theo là {email}`,"codexAuth.loadFailed":`Không thể tải cài đặt tài khoản Codex.`,"codexAuth.accountsRefreshFailed":`Lần làm mới tài khoản gần nhất thất bại. Dưới đây là các tài khoản được xác nhận gần nhất.`,"codexAuth.switchExceedsThresholdWarning":`Mức sử dụng của tài khoản này đã đạt hoặc vượt ngưỡng chuyển đổi ({threshold}%). Lựa chọn đã ghim sẽ được giải phóng nếu không còn hạn ngạch khả dụng.`,"codexAuth.switchFailed":`Không thể chuyển đổi tài khoản. Tùy chọn trước đó của bạn vẫn được giữ nguyên.`,"codexAuth.removeConfirm":`Gỡ bỏ {id}?`,"codexAuth.removeFailed":`Không thể gỡ bỏ tài khoản. Không có thay đổi nào.`,"codexAuth.addTitle":`Thêm tài khoản Codex`,"codexAuth.addIdLabel":`ID tài khoản (slug)`,"codexAuth.addIdPlaceholder":`codex-work, codex-alt, team...`,"codexAuth.resetCreditsAria":`{count} credit reset`,"codexAuth.addJsonLabel":`Nội dung auth.json`,"codexAuth.addHelp":`Sao chép từ ~/.codex/auth.json trên một máy khác, hoặc sử dụng codex-auth export.`,"codexAuth.importBtn":`Nhập (Import)`,"codexAuth.importInvalidJson":`JSON không hợp lệ`,"codexAuth.importMissingTokens":`Thiếu access_token hoặc refresh_token trong JSON`,"codexAuth.importMissingId":`Account ID là bắt buộc`,"codexAuth.accountAdded":`Tài khoản đã được thêm vào pool`,"codexAuth.addPickDesc":`Đăng nhập bằng một tài khoản ChatGPT khác để thêm nó vào pool.`,"codexAuth.oauthLogin":`Đăng nhập bằng OAuth`,"codexAuth.oauthDesc":`Mở trang đăng nhập ChatGPT trong trình duyệt`,"codexAuth.deviceLogin":`Đăng nhập qua device code`,"codexAuth.deviceDesc":`Dành cho máy chủ headless hoặc proxy từ xa: nhập mã ngắn này trên một thiết bị khác`,"codexAuth.importAuthJson":`Nhập auth.json`,"codexAuth.importAuthJsonDesc":`Từ một bản Codex khác hoặc thông qua export codex-auth`,"codexAuth.back":`Quay lại`,"codexAuth.oauthAlreadyInProgress":`Đang tiến hành đăng nhập. Vui lòng hoàn tất quá trình này trong trình duyệt của bạn.`,"codexAuth.oauthWaiting":`Đang đợi quá trình đăng nhập ChatGPT hoàn tất trên trình duyệt...`,"codexAuth.oauthSubmittingCode":`Đang gửi mã…`,"codexAuth.oauthCodeSubmitted":`Đã gửi mã — đang đợi đăng nhập hoàn tất…`,"codexAuth.oauthStatusRetrying":`Lỗi mạng hoặc proxy trong khi kiểm tra trạng thái đăng nhập — đang thử lại…`,"codexAuth.oauthCancelled":`Quá trình đăng nhập đã bị hủy.`,"codexAuth.loginFailed":`Đăng nhập thất bại`,"codexAuth.needsReauth":`Đăng nhập lại`,"codexAuth.reauthenticate":`Xác thực lại`,"codexAuth.tokenExpired":`Token hết hạn — hãy xác thực lại tài khoản này`,"codexAuth.mainTokenExpired":`Token hết hạn — vui lòng đăng nhập lại thông qua Codex App login`,"codexAuth.mainReauthSucceeded":`Đã đăng nhập`,"codexAuth.mainReauthFailed":`Đăng nhập lại thất bại`,"codexAuth.mainReauthCancel":`Hủy`,"codexAuth.mainReauthCode":`Mã`,"codexAuth.mainReauthOpen":`Mở`,"codexAuth.mainReauthPending":`Đang chờ đăng nhập…`,"codexAuth.mainReauthDevice":`Đăng nhập lại bằng mã thiết bị`,"codexAuth.emailCollision":`Tài khoản này trùng với lần đăng nhập Codex chính của bạn. Vui lòng dùng tài khoản khác.`,"codexAuth.resetCreditsTitle":`Đặt lại Credits`,"codexAuth.resetCreditsAvailable":`Bạn đang có sẵn {count} credit reset.`,"codexAuth.resetCreditsDesc":`Mỗi credit reset ngay lập tức các giới hạn sử dụng hàng giờ và hàng tuần hiện tại của bạn.`,"codexAuth.noResetCredits":`Bạn không có credit reset nào.`,"codexAuth.earnCreditsHint":`Credit được thưởng hàng tháng và qua chương trình giới thiệu (referral program).`,"codexAuth.creditsExpireNote":`Credit hết hạn sau 30 ngày kể từ khi kiếm được.`,"codexAuth.useOneCredit":`Sử dụng 1 Credit`,"codexAuth.confirmResetTitle":`Sử dụng Reset Credit?`,"codexAuth.confirmResetDesc":`Thao tác này sẽ reset ngay lập tức các giới hạn tỉ lệ hiện tại của bạn. Bạn còn lại {count} credit.`,"codexAuth.irreversible":`Hành động này không thể hoàn tác.`,"codexAuth.useCredit":`Dùng Credit`,"codexAuth.redeeming":`Đang reset...`,"codexAuth.resetSuccess":`Đã reset các giới hạn sử dụng! Bạn còn lại {remaining} credit.`,"codexAuth.resetSuccessGeneric":`Đã reset các giới hạn sử dụng!`,"codexAuth.resetAlreadyRedeemed":`Credit này đã được sử dụng. Số lượng credit không thay đổi.`,"codexAuth.resetNothingToReset":`Hiện không có cửa sổ hạn mức nào cần reset.`,"codexAuth.resetNoCredit":`Không có reset credit nào.`,"codexAuth.resetError":`Không thể đổi reset credit. Vui lòng thử lại.`,"codexAuth.fifoNote":`Credit cũ nhất sẽ được dùng trước.`,"codexAuth.confirmWhichCredit":`Credit từ ngày {date} sẽ được sử dụng.`,"codexAuth.creditNext":`Sắp dùng tới`,"codexAuth.creditLabel":`Credit #{n}`,"codexAuth.creditNextBadge":`NEXT`,"codexAuth.creditGranted":`Được cấp vào {date}`,"codexAuth.creditExpires":`Hết hạn vào {date} (còn lại {days} ngày)`,"grokCoupon.badgeAria":`{count} phiếu đặt lại Grok`,"grokCoupon.badgeErrorAria":`Không thể đọc phiếu đặt lại Grok`,"grokCoupon.title":`Phiếu đặt lại Grok`,"grokCoupon.available":`Tài khoản này có {count} phiếu đặt lại.`,"grokCoupon.desc":`Một phiếu sẽ đặt lại ngay cửa sổ sử dụng Grok của tài khoản này.`,"grokCoupon.none":`Tài khoản này không có phiếu đặt lại.`,"grokCoupon.loadFailed":`Không thể đọc phiếu đặt lại của tài khoản này.`,"grokCoupon.loadFailedAuth":`Hãy đăng nhập lại tài khoản xAI này để đọc phiếu.`,"grokCoupon.retry":`Thử lại`,"grokCoupon.couponLabel":`Phiếu #{n}`,"grokCoupon.couponNext":`Sẽ dùng tiếp theo`,"grokCoupon.couponNextBadge":`TIẾP THEO`,"grokCoupon.validFrom":`Có hiệu lực từ {date}`,"grokCoupon.expires":`Hết hạn {date} (còn {days} ngày)`,"grokCoupon.useOne":`Dùng 1 phiếu`,"grokCoupon.fifoNote":`Phiếu gần hết hạn nhất được dùng trước.`,"grokCoupon.confirmTitle":`Dùng phiếu đặt lại?`,"grokCoupon.confirmDesc":`Việc này sẽ đặt lại ngay cửa sổ sử dụng Grok của tài khoản. Bạn có {count} phiếu.`,"grokCoupon.confirmWhich":`Phiếu hết hạn vào {date} sẽ được sử dụng.`,"grokCoupon.irreversible":`Không thể hoàn tác hành động này.`,"grokCoupon.redeem":`Dùng phiếu`,"grokCoupon.redeeming":`Đang đổi phiếu…`,"grokCoupon.redeemSuccess":`Đã đổi phiếu. Còn {count} phiếu.`,"grokCoupon.redeemReplayed":`Lần đổi phiếu này đã hoàn tất trước đó. Không có gì bị tiêu thụ thêm.`,"grokCoupon.redeemFailed":`Đổi phiếu thất bại. Hãy kiểm tra danh sách phiếu trước khi thử lại.`,"grokCoupon.authFailed":`Hãy đăng nhập lại tài khoản xAI này để dùng phiếu.`,"grokCoupon.noAccount":`Không có tài khoản xAI nào cho lần đổi phiếu này.`,"grokCoupon.noneAvailable":`Không có phiếu đặt lại nào để đổi.`,"grokCoupon.identityMismatch":`Lần đổi phiếu đó thuộc tài khoản khác. Hãy đóng hộp thoại này và bắt đầu lại.`,"grokCoupon.networkError":`Không thể kết nối tới proxy.`,"grokCoupon.capacity":`Nhật ký đổi phiếu hiện đã đầy. Hãy thử lại sau giây lát.`,"grokCoupon.noOperationId":`Trình duyệt này không thể tạo ID đổi phiếu, nên tính năng đổi phiếu bị tắt tại đây.`,"grokCoupon.unknownOutcome":`Lần đổi phiếu không phản hồi kịp thời nên chưa rõ kết quả. Hãy đọc lại tài khoản để xem phiếu đã được dùng hay chưa.`,"grokCoupon.checkResult":`Đọc lại tài khoản`,"grokCoupon.checking":`Đang đọc lại…`,"grokCoupon.consumedElsewhere":`Phiếu không còn trong tài khoản này, nên việc đổi phiếu đã thành công.`,"grokCoupon.unresolved":`Phiếu vẫn còn trong danh sách. Việc đổi có thể vẫn đang chạy ở upstream — hãy đọc lại sau một phút trước khi dùng phiếu khác.`,"api.title":`Truy cập API`,"api.subtitle":`Sử dụng các API key được tạo để truy cập proxy opencodex từ các ứng dụng bên ngoài. API key được xác thực qua header {authHeader}; xem bảng bên dưới để biết mỗi endpoint hỗ trợ những gì.`,"api.baseUrl":`Base URL`,"api.responsesEndpoint":`Responses API`,"api.chatCompletionsEndpoint":`Chat Completions API`,"api.messagesEndpoint":`Messages API`,"api.modelsEndpoint":`Models API`,"api.endpointNote":`Dùng URL cơ sở cho các ứng dụng hỗ trợ OpenAI tương thích. Responses và Chat Completions được đặt ở /v1.`,"api.endpointsTitle":`Endpoints`,"api.authTitle":`Xác thực (Authentication)`,"api.authLoopback":`Kết nối Loopback (127.0.0.1 hoặc ::1) bỏ qua xác thực. Các kết nối từ xa yêu cầu một API key tạo sẵn bằng tiền tố ocx_ hoặc OPENCODEX_API_AUTH_TOKEN.`,"api.authBaseUrlNote":`Cấu hình client bằng URL cơ sở, sau đó chọn một endpoint cụ thể theo giao thức ở bên dưới.`,"api.newKeyTitle":`Đã tạo key mới`,"api.newKeyNote":`Sao chép key này ngay bây giờ — nó sẽ không hiển thị lại nữa.`,"api.copy":`Sao chép`,"api.copied":`Đã sao chép`,"api.dismiss":`Bỏ qua`,"api.generateTitle":`Tạo key`,"api.keyNamePlaceholder":`Tên key (tùy chọn)`,"api.generate":`Tạo`,"api.generating":`Đang tạo…`,"api.activeKeys":`Các key đang kích hoạt ({count})`,"api.activeKeysLoading":`Các key đang kích hoạt`,"api.noKeys":`Chưa có API key nào. Hãy tạo một key ở trên.`,"api.workspace.sections":`Các phân hệ API`,"api.section.keys":`Keys`,"api.section.connect":`Kết nối`,"api.section.endpoints":`Endpoints`,"api.section.models":`Models`,"api.section.examples":`Ví dụ`,"api.workspace.details":`Chi tiết API key`,"api.workspace.keyDetails":`Chi tiết Key`,"api.workspace.keyPrefix":`Tiền tố key`,"api.workspace.deleteKey":`Xóa key`,"api.workspace.deleteConfirm":`Bạn có chắc chắn muốn xóa key này? Hành động này không thể hoàn tác.`,"api.workspace.usageExamples":`Ví dụ cách dùng`,"api.copyUrlHint":`Nhấp để chép URL`,"api.urlCopied":`Đã chép URL`,"api.copyExampleHint":`Nhấp để chép ví dụ`,"api.exampleCopied":`Đã chép ví dụ`,"api.colName":`Tên`,"api.colKey":`Key`,"api.colCreated":`Tạo ngày`,"api.confirm":`Xác nhận`,"api.deleteAria":`Xóa API key`,"api.modelsTitle":`Danh mục model bên ngoài`,"api.modelsCount":`{count} có thể gọi được`,"api.modelsLoading":`Đang tải các model…`,"api.modelsSearch":`Tìm model`,"api.modelsSubtitle":`Dùng chính xác các ID model này với /v1/models và giao thức đầu vào bạn đã chọn.`,"api.modelsEmpty":`Chưa có model bên ngoài nào khả dụng để gọi.`,"api.modelsNoMatch":`Không có model nào khớp với “{query}”.`,"api.modelsLoadFailed":`Không thể tải danh sách model bên ngoài.`,"api.colModel":`Model`,"api.colSource":`Nguồn (Source)`,"api.colProtocols":`Giao thức`,"api.sourceNative":`ChatGPT pool`,"api.sourceCombo":`Định tuyến hỗn hợp`,"api.sourceCustom":`Tùy chỉnh`,"api.protocolResponses":`Responses`,"api.protocolChatCompletions":`Chat Completions`,"api.protocolMessages":`Messages`,"api.copyModelId":`Sao chép ID`,"api.modelCopied":`Đã sao chép`,"api.testModel":`Kiểm tra`,"api.testingModel":`Đang kiểm tra…`,"api.testSucceeded":`OK`,"api.testFailed":`Thất bại`,"api.usageChatTitle":`Ví dụ Chat Completions`,"api.usageResponsesTitle":`Ví dụ Responses`,"api.usageMessagesTitle":`Ví dụ Messages`,"api.usageSampleInput":`Xin chào, thế giới!`,"api.clientConfig.title":`Cấu hình Client`,"api.clientConfig.rowsLabel":`Kết nối một client`,"api.clientConfig.details":`Chi tiết`,"api.clientConfig.detailsAria":`Chi tiết cấu hình {client}`,"api.clientConfig.copyAria":`Sao chép cấu hình {client}`,"api.clientConfig.downloadAria":`Tải cấu hình {client}`,"api.clientConfig.rowMeta":`{destination} · {count} model`,"api.clientConfig.rowError":`Không thể xây dựng cấu hình {client}.`,"api.clientConfig.copiedAnnounceClient":`Cấu hình {client} đã được chép vào clipboard.`,"api.clientConfig.clientOpencode":`OpenCode`,"api.clientConfig.clientPi":`Pi`,"api.clientConfig.clientOmp":`OMP`,"api.clientConfig.clientHermes":`Hermes`,"api.clientConfig.clientOpenclaw":`OpenClaw`,"api.clientConfig.clientKimi":`Kimi Code`,"api.clientConfig.clientGajae":`Gajae Code`,"api.clientConfig.clientDsh":`DeepSeek Harness (DSH)`,"api.clientConfig.clientMcode":`MiniMax Code`,"api.clientConfig.clientZcode":`ZCode`,"api.clientConfig.clientPrime":`Prime Agent`,"api.clientConfig.clientAside":`Aside`,"api.clientConfig.clientRaycast":`Raycast`,"api.clientConfig.clientOmo":`omo`,"api.clientConfig.clientCline":`Cline CLI`,"api.clientConfig.clineBundle":`Đây là gói gồm hai tệp, không phải tệp cài đặt Cline. Hãy hợp nhất cài đặt vào providers.json và catalog vào models.json cùng cấp. Dùng công tắc tích hợp để ghi kèm bản sao lưu.`,"api.clientConfig.clineDownloaded":`Đã tải xuống {filename}. Chưa có gì thay đổi; cài đặt và catalog thuộc hai tệp Cline riêng biệt.`,"api.clientConfig.copy":`Sao chép cấu hình`,"api.clientConfig.download":`Tải xuống`,"api.clientConfig.loading":`Đang xây dựng cấu hình client…`,"api.clientConfig.jsonLabel":`Cấu hình {client}`,"api.clientConfig.destination":`Tệp đích`,"api.clientConfig.envHint":`Thiết lập khóa trước khi khởi chạy`,"api.clientConfig.mergeWarning":`Gộp nội dung này vào tệp đích. Nếu ghi đè hoàn toàn, bạn sẽ mất các cài đặt MCP và provider khác.`,"api.clientConfig.modelCount":`Đã xuất {count} model`,"api.clientConfig.missingLimits":`{count} trong số {total} model được phân phối không có giới hạn ngữ cảnh (context limit); client sẽ áp dụng các giá trị mặc định của riêng nó.`,"api.clientConfig.noKeyYet":`{env} hiện chưa có khóa. Hãy tạo một khóa ở trên trước khi sử dụng cấu hình này bên ngoài loopback.`,"api.clientConfig.loadFailed":`Không thể đọc danh sách model, do đó không có cấu hình client nào được tạo ra.`,"api.clientConfig.copiedAnnounce":`Cấu hình client đã được sao chép vào khay nhớ tạm.`,"api.clientConfig.copyFailed":`Không thể sao chép cấu hình client.`,"api.clientConfig.downloadedAnnounce":`Đã tải xuống {filename}. Chưa có thay đổi nào được áp dụng — hãy tự gộp nó vào {destination}.`,"api.clientConfig.whereDisclosure":`Tệp này được lưu ở đâu`,"api.clientConfig.whereBody":`Đích đến ở trên là đường dẫn toàn cục (global path). Một tệp cấu hình project-local trong thư mục làm việc sẽ được ưu tiên cao hơn, và client sẽ đọc khóa từ biến môi trường (environment variable) được chỉ định trong cấu hình — chứ không bao giờ đọc từ tệp này.`,"api.keysLoadFailed":`Không thể tải các khóa API.`,"api.createFailed":`Không thể tạo khóa API.`,"api.deleteFailed":`Không thể xóa khóa API.`,"api.auth.endpoint":`Endpoint`,"api.auth.required":`Bắt buộc`,"api.auth.accepted":`Được chấp nhận`,"api.auth.rejected":`Không được chấp nhận`,"api.auth.testProtocol":`Kiểm tra {protocol}`,"api.auth.testNeedsFreshKey":`Tạo một khóa và giữ giá trị hiển thị một lần của nó trên màn hình để chạy một bài kiểm tra xác thực (authenticated test).`,"api.key.name":`Tên khóa`,"api.key.rename":`Đổi tên`,"api.key.saveName":`Lưu tên`,"api.key.renaming":`Đang lưu…`,"api.key.renameFailed":`Không thể đổi tên khóa. Bản nháp của bạn đã được giữ lại.`,"api.key.deleting":`Đang xóa…`,"api.rotation.title":`Luân chuyển khóa`,"api.rotation.description":`Cấp phát một khóa thay thế trong khi khóa hiện tại vẫn giữ hiệu lực trong một khoảng thời gian gối đầu ngắn.`,"api.rotation.start":`Bắt đầu luân chuyển`,"api.rotation.starting":`Đang bắt đầu…`,"api.rotation.pending":`Quá trình luân chuyển đang chờ xử lý. Hãy cập nhật và xác minh client trước khi xác nhận (commit).`,"api.rotation.expires":`Thời gian gối đầu (overlap) hết hạn lúc:`,"api.rotation.secretOnce":`Khóa thay thế — chỉ hiển thị một lần. Hãy sao chép nó trước khi đóng thông báo này.`,"api.rotation.commit":`Xác nhận luân chuyển`,"api.rotation.abort":`Hủy luân chuyển`,"api.rotation.failed":`Hành động luân chuyển không thể hoàn tất. Hãy làm mới trước khi thử lại.`,"api.rotation.startFailed":`Không thể bắt đầu luân chuyển khóa.`,"api.key.copyFailed":`Không thể sao chép khóa. Hãy chọn và sao chép thủ công trước khi đóng bảng này.`,"api.attribution.title":`Mức sử dụng được quy kết`,"api.attribution.requests7d":`Số requests, 7 ngày qua`,"api.attribution.totalRequests":`Tổng số requests được quy kết`,"api.attribution.totalRequestsAvailable":`Số requests trong lịch sử hiện có`,"api.attribution.sinceAvailable":`Dữ liệu quy kết có sẵn từ`,"api.attribution.lastUsed":`Lần sử dụng cuối`,"api.attribution.since":`Dữ liệu quy kết có sẵn từ`,"api.attribution.neverUsed":`Chưa được sử dụng kể từ khi bắt đầu quy kết`,"api.attribution.unavailable":`Không có dữ liệu sử dụng`,"api.attribution.unavailableDetail":`Chưa có mức sử dụng nào được quy kết. Các requests được ghi nhận trước khi tính năng quy kết bắt đầu sẽ không thể được gán hồi tố.`,"api.attribution.ambiguous":`Có hai khóa dùng chung ID này, do đó không thể quy kết mức sử dụng cho một trong số chúng. Hãy cung cấp cho mỗi khóa một ID duy nhất trong tệp cấu hình.`,"api.attribution.railAmbiguous":`trùng ID`,"claude.subtitle":`Sử dụng GPT, Gemini và các model khác bên trong Claude Code.`,"claude.pageTitle":`Claude Code`,"claude.workspace.settings":`Cài đặt`,"claude.enabledLabel":`Kết nối Claude`,"claude.enabledHint":`Khi tắt, Claude Code không thể sử dụng proxy này.`,"claude.authMode":`Chế độ xác thực`,"claude.authModeHint":`Chế độ Subscription yêu cầu tài khoản Claude, chế độ Proxy hoạt động mà không cần tài khoản Anthropic`,"claude.authModeSubscription":`Subscription (Tài khoản Claude)`,"claude.authModeProxy":`Proxy (Không cần tài khoản)`,"claude.authModeAuto":`Auto (Tự động phát hiện xác thực Claude)`,"claude.effectiveMode.label":`Sẽ có hiệu lực ở lần khởi chạy tiếp theo`,"claude.effectiveMode.manual":`Thủ công: {mode}`,"claude.effectiveMode.autoPresent":`Tự động: subscription — tìm thấy xác thực Claude thông qua {source}`,"claude.effectiveMode.autoAbsent":`Tự động: chế độ proxy — không tìm thấy xác thực Claude`,"claude.effectiveMode.autoUnknown":`Tự động: subscription — không thể xác minh xác thực`,"claude.effectiveMode.admissionKey":`Khóa API của proxy này vẫn được gửi đi.`,"claude.authSource.claude-json-oauth":`tài khoản Claude`,"claude.authSource.claude-credentials-file":`tệp credentials`,"claude.authSource.macos-keychain":`macOS Keychain`,"claude.authSource.exported-env":`biến môi trường (environment variable)`,"claude.authSource.unknown":`một credential được phát hiện`,"claude.systemEnv":`Tự động kết nối`,"claude.systemEnvDesc":`Khi bật, việc chạy claude trong bất kỳ terminal nào cũng sẽ tự động đi qua proxy.`,"claude.systemEnvUnsupported":`Tự động kết nối chỉ khả dụng trên macOS. Trên hệ thống này, hãy khởi chạy Claude bằng {cmd}.`,"claude.systemEnvWarn":`⚠ Bạn phải thoát hoàn toàn và mở lại ứng dụng terminal để thay đổi này có hiệu lực. Không khuyến khích.`,"claude.fastMode":`Chế độ Fast (OpenAI)`,"claude.fastModeDesc":`Kiểm soát service_tier cho các model OpenAI. ON = priority (nhanh hơn). OFF = default. Auto = passthrough (client tự quyết định).`,"claude.fastAuto":`Tự động`,"claude.fastOn":`BẬT`,"claude.fastOff":`TẮT`,"claude.autoContext":`Tự động sử dụng ngữ cảnh lớn (big context)`,"claude.autoContextDesc":`Kiểm soát phạm vi áp dụng nhãn 1M. ON: bất kỳ model nào có cửa sổ (window) đủ lớn để chứa ngưỡng nén (compaction threshold) đều sẽ có hàng big-context. OFF: chỉ những model thực sự đạt 1M mới có.`,"claude.autoContextInert":`Bị vô hiệu hóa vì giá trị kích thước ngữ cảnh (maxContextTokens) cũ vẫn tồn tại trong tệp cấu hình. Hãy xóa nó ở đó để kích hoạt lại.`,"claude.autoCompactWindow":`Điểm tự động tóm tắt`,"claude.autoCompactDefault":`{value} (mặc định)`,"claude.autoCompactWindowDesc":`Các tin nhắn cũ hơn sẽ được tóm tắt khi cuộc trò chuyện đạt đến điểm này. Nó không bao giờ vượt qua giới hạn riêng của từng model, do đó các model 200k sẽ không bị ảnh hưởng.`,"claude.autoCompactWindowWarn":`Việc thay đổi điều này có thể làm hỏng các model GPT — nếu đặt cao hơn giới hạn thực của model, các cuộc trò chuyện sẽ gặp lỗi trước khi quá trình tóm tắt bắt đầu.`,"claude.injectAgents":`Tự động đăng ký các subagent`,"claude.injectAgentsDesc":`Đăng ký các model được chọn trên thẻ Subagents (cộng với model mặc định hiện tại) làm các agent Claude Code có thể điều phối (ocx-*). Có hiệu lực từ phiên làm việc tiếp theo.`,"claude.webSearchSidecar":`Ghi đè sidecar tìm kiếm web`,"claude.webSearchSidecarHint":`Ghi đè sidecar tìm kiếm web chính đối với các yêu cầu từ Claude Code.`,"claude.visionSidecar":`Ghi đè sidecar thị giác (vision sidecar)`,"claude.visionSidecarHint":`Ghi đè sidecar thị giác chính đối với các yêu cầu từ Claude Code.`,"claude.useMainSetting":`Sử dụng thiết lập chính`,"claude.sidecarModelPlaceholder":`Model thiết lập chính`,"claude.quickstart":`Bắt đầu`,"claude.quickstartHint":`{cmd} sẽ mở Claude Code thông qua proxy. Phiên đăng nhập claude.ai của bạn vẫn được giữ nguyên.`,"claude.manualEnv":`Thiết lập thủ công (nâng cao)`,"claude.smallFastModel":`Model hỗ trợ nền (Background helper model)`,"claude.smallFastModelHint":`Model mà Claude Code sử dụng cho các tác vụ nền như tóm tắt trò chuyện và phát hiện chủ đề. Bí danh (alias) của subagent haiku cũng sử dụng nó. Bỏ trống = Mặc định của Claude (Haiku).`,"claude.smallFastModelAccurateHint":`Model mà Claude Code sử dụng cho các tác vụ nền như tóm tắt trò chuyện và phát hiện chủ đề. Bí danh của subagent haiku cũng sử dụng nó.`,"claude.smallFastModelUnsetOption":`Để Claude Code tự chọn (native model)`,"claude.smallFastModelNativeWarning":`Khi bỏ trống, OpenCodex sẽ không ghi đè model hỗ trợ (helper-model). Claude Code có thể sử dụng model Sonnet gốc của nó, điều này có thể phát sinh chi phí từ provider gốc của bạn.`,"claude.slotUnset":`Sử dụng mặc định của Claude`,"claude.modelMap":`Đánh chặn model (Model interception)`,"claude.modelMapHint":`Đánh chặn các yêu cầu đến một model cụ thể và định tuyến lại sang model bạn chọn. Mặc định là trống — sẽ không có gì xảy ra cho đến khi bạn thêm một quy tắc (rule).`,"claude.mapFrom":`Model gốc (ví dụ: claude-sonnet-4-5)`,"claude.mapTo":`Chuyển đổi thành (ví dụ: gemini/gemini-3-pro)`,"claude.addMapping":`Thêm quy tắc`,"claude.removeMapping":`Xóa quy tắc`,"claude.aliases":`Các model có sẵn`,"claude.aliasesHint":`Các model xuất hiện trong menu /model của Claude Code.`,"claude.aliasProviderOther":`Khác`,"claude.loading":`Đang tải…`,"claude.loadFail":`Không thể tải cài đặt Claude`,"claude.saved":`Đã lưu.`,"claude.saveFailed":`Lưu thất bại`,"claude.networkError":`Lỗi mạng — proxy có đang chạy không?`,"claude.toggleAria":`Bật/tắt kết nối Claude`,"claude.none":`Không có`,"cws.loading":`Đang tải các combo…`,"cws.loadFailed":`Không thể tải các combo.`,"cws.saveFailed":`Không thể lưu combo.`,"cws.removeFailed":`Không thể xóa combo.`,"cws.saved":`Đã lưu combo.`,"cws.created":`Đã tạo {model}.`,"cws.removed":`Đã xóa combo/{id}.`,"cws.renamed":`Đã đổi tên {from} thành {to}.`,"cws.add":`Thêm combo`,"cws.addTitle":`Thêm combo`,"cws.addSubtitle":`Tạo một model ảo (virtual model) xuyên suốt các provider và chọn chính xác tên model mà các client sẽ gọi.`,"cws.create":`Tạo combo`,"cws.railAria":`Danh sách combo`,"cws.searchPlaceholder":`Tìm kiếm combo hoặc mục tiêu (target)…`,"cws.noSearchResults":`Không có combo nào khớp với tìm kiếm của bạn.`,"cws.group.failover":`Failover`,"cws.group.roundRobin":`Round-robin`,"cws.group.other":`Các chiến lược khác`,"cws.targetCount":`{count} mục tiêu`,"cws.targetCountOne":`1 mục tiêu`,"cws.overviewTitle":`Combos`,"cws.overviewBlurb":`Các model ảo thực hiện định tuyến qua các mục tiêu provider/model với các cơ chế như failover, round-robin, weighted random (ngẫu nhiên có trọng số), least-used (ít được sử dụng nhất), hoặc soonest quota reset (đặt lại hạn ngạch sớm nhất).`,"cws.count.total":`Tổng cộng`,"cws.count.failover":`Failover`,"cws.count.roundRobin":`Round-robin`,"cws.count.other":`Khác`,"cws.howTitle":`Cách thức hoạt động`,"cws.howBody":`Hỏi Codex về tên model công khai (public model name) của combo. Nếu không có, mặc định sẽ là combo/<id>. OpenCodex sẽ chọn một mục tiêu và chỉ chuyển sang mục tiêu khác (hop) khi gặp các lỗi từ upstream có thể thử lại. Nếu không còn mục tiêu nào khả dụng, yêu cầu sẽ bị từ chối (fails closed) thay vì sử dụng provider mặc định toàn cục.`,"cws.attentionTitle":`Cần chú ý`,"cws.attention.empty":`Chưa có mục tiêu nào được cấu hình`,"cws.attention.few":`Chỉ có một mục tiêu — tính năng failover sẽ không có nơi nào để chuyển tiếp (hop)`,"cws.attention.catalogOmitted":`Bị thiếu khỏi danh mục model (model catalog) — các khả năng của thành viên bị thiếu hoặc không tương thích (thiếu cửa sổ ngữ cảnh / metadata, hoặc giao điểm phương thức bị rỗng). Tính năng định tuyến qua bí danh (alias) vẫn hoạt động`,"cws.attention.allTargetsExhausted":`Tất cả các mục tiêu được bật đều đã hết hạn ngạch (quota)`,"cws.emptyTitle":`Tạo combo đầu tiên của bạn`,"cws.empty.createDesc":`Đặt tên cho một model ảo và liên kết hai hoặc nhiều backend với nhau.`,"cws.backToAll":`Quay lại tất cả combo`,"cws.allCombos":`Tất cả combo`,"cws.copyModel":`Sao chép id`,"cws.copied":`Đã sao chép`,"cws.tabsLabel":`Các phần chi tiết của combo`,"cws.tab.config":`Cấu hình`,"cws.tab.about":`Thông tin`,"cws.strategy":`Chiến lược`,"cws.strategy.failover":`Failover`,"cws.strategy.roundRobin":`Round-robin`,"cws.strategy.random":`Ngẫu nhiên`,"cws.strategy.leastUsed":`Ít được sử dụng nhất (Least-used)`,"cws.strategy.resetWindow":`Reset-window`,"cws.strategy.failoverHint":`Thử các mục tiêu theo thứ tự. Nếu mục tiêu đầu tiên gặp lỗi có thể thử lại (rate limit, mất kết nối, chặn subscription), sẽ chuyển tiếp (hop) sang mục tiêu tiếp theo.`,"cws.strategy.roundRobinHint":`Cân bằng lưu lượng một cách tất định (deterministically) theo trọng số. Giữ nguyên mục tiêu được chọn cho một loạt các yêu cầu thành công, sau đó chuyển sang mục tiêu tiếp theo.`,"cws.strategy.randomHint":`Rút ngẫu nhiên một mục tiêu đủ điều kiện cho mỗi yêu cầu, với tỷ lệ thuận theo trọng số. Không giữ nguyên trạng thái (stickiness) giữa các yêu cầu.`,"cws.strategy.leastUsedHint":`Định tuyến từng yêu cầu đến mục tiêu đủ điều kiện có số lượng thành công được ghi nhận ít nhất. Số đếm sẽ khởi động lại cùng với proxy.`,"cws.strategy.resetWindowHint":`Ưu tiên mục tiêu đủ điều kiện có thời gian đặt lại hạn ngạch (quota window) sớm nhất. Sẽ chuyển về thứ tự cấu hình khi dữ liệu hạn ngạch bị thiếu.`,"cws.field.id":`Id của combo`,"cws.field.idHint":`Các client sẽ gửi yêu cầu tới {model}`,"cws.field.idInternalHint":`Id nội bộ của combo. Bạn có thể thay đổi nó sau khi tạo.`,"cws.field.idHintEdit":`Việc đổi tên sẽ chuyển combo sang một id mới. Các client sẽ gửi yêu cầu tới {model}.`,"cws.field.alias":`Tên model công khai (Public model name)`,"cws.field.aliasPlaceholder":`deepseek-v4-flash hoặc vendor/model`,"cws.field.aliasHint":`Tùy chọn. Sử dụng một tên trần (bare name) không có tiền tố, một tiền tố tùy chỉnh như vendor/model, hoặc để trống để sử dụng combo/<id>.`,"cws.field.nativeAlias":`Bí danh OpenAI gốc (Native OpenAI alias)`,"cws.field.nativeAliasHint":`Cho phép combo này sở hữu một id model OpenAI gốc (unqualified) được hỗ trợ. Các định tuyến OpenAI được chỉ định qua tài khoản và provider sẽ được giữ tách biệt.`,"cws.field.displayName":`Tên hiển thị`,"cws.field.displayNameHint":`Nhãn hiển thị trên bộ chọn (picker) cho combo này. Bắt buộc khi tính năng Bí danh OpenAI gốc (Native OpenAI alias) được bật.`,"cws.field.stickyLimit":`Số lần thành công giữ nguyên trước khi xoay vòng (rotate)`,"cws.field.stickyLimitHint":`Giữ nguyên mục tiêu được chọn cho từng này yêu cầu thành công trước khi bộ chọn theo trọng số (weighted selector) chuyển tiếp.`,"cws.field.defaultEffort":`Suy luận (reasoning) mặc định`,"cws.field.defaultEffortNone":`Không (mặc định của mục tiêu)`,"cws.field.defaultEffortHint":`Chỉ sử dụng khi client không chỉ định mức độ suy luận (reasoning effort). Các tùy chọn là giao điểm của các mức độ được công bố từ các mục tiêu đã chọn; những mục tiêu không có metadata về mức độ suy luận trong danh mục sẽ không cung cấp tùy chọn này.`,"cws.capability.imageInputUnavailable":`Không khả dụng cho đến khi mọi mục tiêu được chọn đều hỗ trợ đầu vào hình ảnh (image input).`,"cws.capability.imageInputHint":`Được bật theo mặc định khi mọi mục tiêu đều hỗ trợ hình ảnh. Tắt để chỉ chấp nhận văn bản.`,"cws.capability.imageInput":`Hình ảnh / đa phương thức (multimodal)`,"cws.capability.adaptiveEffort":`Thang suy luận thích ứng (Adaptive reasoning ladder)`,"cws.capability.adaptiveEffortHint":`Tắt: một mục tiêu không có kiểm soát suy luận sẽ ẩn đi bộ chọn mức độ (effort picker) cho toàn bộ combo. Bật: những mục tiêu đó vẫn có thể sử dụng và bộ chọn sẽ giữ lại các cấp độ mà các mục tiêu còn lại dùng chung.`,"cws.capabilities":`Khả năng (Capabilities)`,"cws.field.defaultEffortUnsupported":`Mức độ (effort) này không nằm trong thang dùng chung của các mục tiêu — nó sẽ bị bỏ qua hoặc tự điều chỉnh vào thời điểm gửi yêu cầu.`,"cws.field.defaultEffortUnsupportedOption":`không nằm trong giao điểm`,"cws.targets":`Mục tiêu (Targets)`,"cws.targets.failoverHint":`Thứ tự rất quan trọng — mục tiêu đầu tiên là ưu tiên chính (primary).`,"cws.targets.roundRobinHint":`Trọng số kiểm soát việc lựa chọn tương đối một cách tất định; thứ tự sẽ phá vỡ thế cân bằng (tie-breaker) trong vòng xoay (rotation ring).`,"cws.targets.randomHint":`Trọng số kiểm soát tỷ lệ cược của mỗi lần rút (draw); thứ tự không quan trọng.`,"cws.targets.leastUsedHint":`Thứ tự chỉ dùng để phá vỡ thế cân bằng giữa các mục tiêu được sử dụng với tần suất như nhau.`,"cws.targets.resetWindowHint":`Thứ tự được áp dụng khi dữ liệu hạn ngạch bị thiếu hoặc ngang bằng nhau.`,"cws.target.provider":`Nhà cung cấp`,"cws.target.model":`Model`,"cws.target.weight":`Trọng số (Weight)`,"cws.target.pickProvider":`Chọn provider…`,"cws.target.pickProviderFirst":`Hãy chọn một provider trước…`,"cws.target.pickModel":`Chọn model…`,"cws.target.noModels":`Không có model nào cho provider này`,"cws.target.modelPlaceholder":`id của model`,"cws.target.add":`Thêm mục tiêu`,"cws.target.drag":`Kéo để sắp xếp lại`,"cws.target.moveUp":`Di chuyển lên`,"cws.target.moveDown":`Di chuyển xuống`,"cws.quota.available":`Khả dụng`,"cws.quota.exhausted":`Hết hạn ngạch`,"cws.quota.unknown":`Không xác định hạn ngạch`,"cws.quota.allExhausted":`Tất cả các mục tiêu được bật đều đã hết hạn ngạch. Hãy chọn một mục tiêu khác hoặc chờ hạn ngạch được phục hồi.`,"cws.aboutTitle":`Thời gian chạy (Runtime)`,"cws.aboutBody":`Các mục tiêu gặp lỗi sẽ được làm mát (cool down) trong một khoảng thời gian ngắn, tuân theo Retry-After. Các lỗi ngữ cảnh (context error) hoặc không hợp lệ sẽ không bị chuyển tiếp (hop). Mỗi mục tiêu sẽ thích ứng mức độ suy luận (effort) theo khả năng riêng của nó; các combo đã cạn kiệt sẽ bị từ chối (fail closed). Nhật ký (Logs) và Mức sử dụng (Usage) sẽ giữ nguyên thứ tự các lần thử vật lý và mức sử dụng trên từng lần thử.`,"cws.removeConfirmTitle":`Xóa {model}?`,"cws.removeConfirmDesc":`Hành động này sẽ xóa model ảo khỏi cấu hình và danh mục Codex. Nó không xóa bất kỳ provider nào.`,"cws.unsavedTitle":`Các thay đổi chưa được lưu`,"cws.unsavedDesc":`Loại bỏ các chỉnh sửa đối với combo này và tiếp tục?`,"cws.keepEditing":`Tiếp tục chỉnh sửa`,"cws.err.missingId":`Bắt buộc phải có Id của combo.`,"cws.err.invalidId":`Id phải bắt đầu bằng một chữ cái hoặc số và chỉ sử dụng các chữ cái, số, dấu chấm, dấu gạch dưới hoặc dấu gạch ngang (tối đa 64 ký tự).`,"cws.err.duplicateId":`Đã tồn tại một combo với id này.`,"cws.err.invalidAlias":`Bí danh (alias) phải sử dụng các chữ cái, số, dấu chấm, dấu gạch dưới hoặc dấu gạch ngang, với tối đa một phân đoạn "/".`,"cws.err.aliasReservedNamespace":`Bí danh không được sử dụng namespace dành riêng "combo/".`,"cws.err.aliasNativeFamily":`Không được phép sử dụng các bí danh trần (bare aliases) thuộc bộ OpenAI gốc (gpt-*, o1-*, o3-*, o4-*, codex-*).`,"cws.err.unsupportedNativeAlias":`Bí danh gốc (native alias) phải là một id model OpenAI trần (bare OpenAI model id) hiện đang được hỗ trợ.`,"cws.err.missingNativeAliasDisplayName":`Bắt buộc phải có tên hiển thị đối với các bí danh gốc.`,"cws.err.invalidDisplayName":`Tên hiển thị phải có tối đa 128 ký tự và không chứa các ký tự điều khiển (control characters).`,"cws.err.duplicateAlias":`Một combo khác đã sử dụng bí danh này.`,"cws.err.noTargets":`Hãy thêm ít nhất một mục tiêu.`,"cws.err.incompleteTarget":`Mỗi mục tiêu cần một provider và model.`,"cws.target.disabled":`{name} (bị vô hiệu hóa)`,"cws.err.reservedNamespace":`Một provider vật lý có tên là combo phải được đổi tên trước khi tạo các combo.`,"cws.err.providerCollision":`ID của combo bị xung đột với một tên provider đã được cấu hình.`,"cws.err.unknownProvider":`Mỗi mục tiêu phải sử dụng một provider đã được cấu hình.`,"cws.err.duplicateTarget":`Cùng một mục tiêu provider/model chỉ có thể xuất hiện một lần.`,"cws.err.invalidStickyLimit":`Số lần thành công giữ nguyên (sticky successes) phải là một số nguyên từ 1 đến 100.`,"cws.err.invalidWeight":`Mỗi trọng số round-robin phải là một số nguyên từ 1 đến 10000.`,"cws.err.noEnabledTarget":`Ít nhất một mục tiêu phải sử dụng một provider đã được bật.`,"claude.tabsLabel":`Client Claude`,"claude.tabCode":`Code`,"claude.tabDesktop":`Desktop`,"claudeDesktop.title":`Claude Desktop`,"claudeDesktop.subtitle":`Định tuyến từng họ model (model family) Claude thông qua một model khả dụng trên cổng {port}.`,"claudeDesktop.importJson":`Nhập JSON`,"claudeDesktop.exportJson":`Xuất JSON`,"claudeDesktop.loading":`Đang tải hồ sơ Claude Desktop…`,"claudeDesktop.loadFail":`Không thể tải hồ sơ Claude Desktop.`,"claudeDesktop.retry":`Thử lại`,"claudeDesktop.saveFailed":`Không thể lưu hồ sơ Claude Desktop.`,"claudeDesktop.applyFailed":`Hồ sơ đã được lưu, nhưng không thể áp dụng.`,"claudeDesktop.updateFailed":`Cập nhật Claude Desktop thất bại.`,"claudeDesktop.savedApplied":`Hồ sơ đã được lưu và áp dụng cho Claude Desktop.`,"claudeDesktop.appliedMarkerUnsaved":`Đã được áp dụng cho Claude Desktop, nhưng dấu (marker) áp dụng chưa được lưu — trạng thái đã lưu-so với-đã áp dụng bên dưới có thể hiển thị dữ liệu cũ cho đến khi bạn áp dụng lại.`,"claudeDesktop.savedAppliedAnnounce":`Hồ sơ Claude Desktop đã được lưu và áp dụng.`,"claudeDesktop.saved":`Hồ sơ đã được lưu.`,"claudeDesktop.savedAnnounce":`Hồ sơ Claude Desktop đã được lưu.`,"claudeDesktop.exported":`Hồ sơ đã được xuất dưới dạng JSON.`,"claudeDesktop.importExpected":`Cần có một hồ sơ Claude Desktop phiên bản 1.`,"claudeDesktop.importReady":`Đã nhập JSON. Hãy xem lại bản nháp, sau đó lưu và áp dụng.`,"claudeDesktop.importedAnnounce":`Đã nhập JSON hồ sơ. Các thay đổi chưa được lưu đã sẵn sàng để xem xét.`,"claudeDesktop.importInvalid":`Tệp đã chọn không phải là một hồ sơ hợp lệ.`,"claudeDesktop.importFailed":`Nhập thất bại. {error}`,"claudeDesktop.moved":`{route} đã được chuyển đến {family}.`,"claudeDesktop.unsaved":`Các thay đổi chưa được lưu`,"claudeDesktop.upToDate":`Hồ sơ đã được cập nhật`,"claudeDesktop.saving":`Đang lưu…`,"claudeDesktop.applying":`Đang áp dụng…`,"claudeDesktop.saveApply":`Lưu & áp dụng`,"claudeDesktop.emptyTitle":`Không có model nào khả dụng`,"claudeDesktop.emptyHint":`Hãy thêm hoặc bật một provider, sau đó quay lại để chỉ định các định tuyến cho Claude Desktop.`,"claudeDesktop.assignmentsLabel":`Các chỉ định họ model Claude`,"claudeDesktop.family.opus":`Opus`,"claudeDesktop.family.fable":`Fable`,"claudeDesktop.family.sonnet":`Sonnet`,"claudeDesktop.family.haiku":`Haiku`,"claudeDesktop.modelCountOne":`{count} model`,"claudeDesktop.modelCountMany":`{count} model`,"claudeDesktop.chooseDefault":`Chọn một model mặc định`,"claudeDesktop.temporaryDefault":`Mặc định tạm thời`,"claudeDesktop.laneEmpty":`Thả một model vào đây hoặc sử dụng bộ điều khiển Di chuyển (Move) của nó.`,"claudeDesktop.laneNoMatch":`Không có model nào trong họ này khớp với tìm kiếm của bạn.`,"nav.grok":`Grok`,"grok.title":`Grok Build`,"grok.subtitle":`Các model mà opencodex đã đăng ký trong cấu hình Grok của bạn.`,"grok.loading":`Đang tải trạng thái Grok…`,"grok.loadFail":`Không thể đọc cấu hình Grok.`,"grok.notConfiguredTitle":`Grok Build chưa được kết nối`,"grok.notConfiguredHint":`Hãy khởi động hoặc khởi động lại proxy với Grok đã được cài đặt và opencodex sẽ ghi một khối được quản lý (managed block) vào:`,"grok.endpoint":`Endpoint`,"grok.colModel":`Model`,"grok.colAlias":`Bí danh Grok`,"grok.colContext":`Ngữ cảnh (Context)`,"grok.groupNative":`Các model gốc (Native models)`,"grok.groupRouted":`Các model được định tuyến (Routed models)`,"grok.enabledCount":`Đã đăng ký {on} trong tổng số {total}`,"grok.saved":`Đã lưu lựa chọn.`,"grok.savedApplied":`Lựa chọn đã được lưu và được ghi vào cấu hình Grok của bạn.`,"grok.saveFailed":`Không thể lưu lựa chọn Grok.`,"grok.applyFailed":`Lựa chọn đã được lưu, nhưng cấu hình Grok không thể được cập nhật.`,"grok.applySkipped":`Lựa chọn đã được lưu. Cấu hình Grok không thay đổi.`,"grok.saveApply":`Lưu & áp dụng`,"grok.saving":`Đang lưu…`,"grok.applying":`Đang áp dụng…`,"grok.unsaved":`Các thay đổi chưa được lưu`,"grok.upToDate":`Lựa chọn đã được cập nhật`,"grok.toggleModel":`Đăng ký {id} với Grok`,"claudeDesktop.available":`Khả dụng`,"claudeDesktop.defaultBadge":`Mặc định`,"claudeDesktop.supports1m":`1M`,"claudeDesktop.unavailable":`Không khả dụng`,"claudeDesktop.contextM":`ngữ cảnh {n}M`,"claudeDesktop.contextK":`ngữ cảnh {n}k`,"claudeDesktop.contextUnknown":`không xác định ngữ cảnh`,"claudeDesktop.alias":`Bí danh`,"claudeDesktop.useAsDefault":`Sử dụng làm mặc định cho {family}`,"claudeDesktop.moveTo":`Chuyển đến`,"claudeDesktop.move":`Di chuyển`,"claudeDesktop.status.applied":`Đã áp dụng cho Desktop`,"claudeDesktop.status.stale":`Cấu hình đã cũ — hãy áp dụng lại`,"claudeDesktop.status.notApplied":`Chưa được áp dụng`,"claudeDesktop.status.notActiveProfile":`Desktop đang phục vụ một hồ sơ khác — hãy áp dụng lại`,"claudeDesktop.status.disabled":`Tiện ích tích hợp Claude Desktop đang tắt. Hãy thoát hoàn toàn và mở lại Desktop sau khi bật nó.`,"claudeDesktop.enableApply":`Bật và áp dụng`,"claudeDesktop.switchModeApply":`Đổi chế độ & áp dụng`,"claudeDesktop.status.appliedFirstParty":`First-party: tab Code đi qua proxy cục bộ`,"claudeDesktop.mode.legend":`Chế độ kết nối`,"claudeDesktop.mode.firstParty":`First-party`,"claudeDesktop.mode.gateway":`Gateway (bên thứ ba)`,"claudeDesktop.mode.defaultBadge":`mặc định`,"claudeDesktop.mode.current":`hiện tại`,"claudeDesktop.mode.firstPartyHint":`Desktop vẫn đăng nhập claude.ai (chat, connector, điều khiển từ xa). Chỉ tab Code, các subagent và Claude Code CLI đi qua OpenCodex.`,"claudeDesktop.mode.gatewayHint":`Toàn bộ ứng dụng chuyển sang dùng OpenCodex làm gateway. Chat chạy cục bộ; các tính năng claude.ai không khả dụng.`,"claudeDesktop.mode.switchNote":`Chuyển chế độ sẽ xóa cấu hình của chế độ kia. Sau đó hãy thoát hẳn Desktop rồi mở lại.`,"claudeDesktop.firstParty.proxyRunning":`Proxy cục bộ tại 127.0.0.1:{port}`,"claudeDesktop.firstParty.proxyStopped":`Proxy cục bộ 127.0.0.1:{port} không chạy — khởi động lại OpenCodex`,"claudeDesktop.firstParty.interceptDisabled":`Proxy chặn bắt đã bị tắt trong cấu hình (claudeCode.intercept.enabled)`,"claudeDesktop.health.lastRequest":`Yêu cầu cuối cùng (Last request)`,"claudeDesktop.health.stats":`{count} req / {errors} err`,"claudeDesktop.effort.supported":`suy luận (effort)`,"claudeDesktop.effort.displayOnly":`suy luận (chỉ hiển thị)`,"lab.title":`Phòng thí nghiệm tương thích`,"lab.subtitle":`Ma trận phán quyết tính tương thích (compatibility verdict matrix) chỉ đọc từ các bằng chứng dự báo của lab.`,"lab.loadFailed":`Không thể tải dữ liệu compatibility lab`,"lab.projectionUnavailable":`Dự báo của lab không có sẵn. Hãy chạy các bài kiểm tra conformance (tính tuân thủ) hoặc live probes (thăm dò trực tiếp) trước.`,"lab.projectionIncompatible":`Lược đồ dự báo của lab không tương thích. Hãy xây dựng lại dự báo (projection).`,"lab.statusTitle":`Trạng thái dự báo`,"lab.matrixTitle":`Ma trận tương thích`,"lab.verdictsTitle":`Các bản ghi phán quyết (Verdict records)`,"lab.filter.layer":`Lớp bằng chứng (Evidence layer)`,"lab.filter.verdict":`Phán quyết (Verdict)`,"lab.filter.subject":`ID đối tượng (Subject ID)`,"lab.filter.all":`Tất cả`,"lab.col.subject":`Đối tượng (Subject)`,"lab.col.layer":`Lớp (Layer)`,"lab.col.suite":`Bộ kiểm thử (Suite)`,"lab.col.verdict":`Phán quyết`,"lab.col.asOf":`Tính đến`,"lab.col.protocol":`Tuân thủ giao thức (Protocol conformance)`,"lab.col.live":`Tính tương thích của định tuyến trực tiếp (Live route compatibility)`,"lab.col.task":`Hiệu quả tác vụ (Task effectiveness)`,"lab.empty":`Chưa có phán quyết tương thích nào trong dự báo.`,"lab.subjectKind":`Loại (Kind)`,"lab.observationCount":`Quan sát (Observations)`,"lab.eventCount":`Sự kiện (Events)`,"lab.verdictCount":`Phán quyết (Verdicts)`,"lab.subjectCount":`Đối tượng (Subjects)`,"lab.builtAt":`Đã xây dựng`,"lab.loading":`Đang tải bằng chứng tương thích…`,"lab.loadMore":`Tải thêm`,"lab.detailTitle":`Chi tiết phán quyết`,"lab.detailClose":`Đóng`,"lab.detailSubject":`Đối tượng`,"lab.detailObservations":`Quan sát`,"lab.detailEvents":`Các sự kiện đóng góp (Contributing events)`,"lab.detailArtifacts":`Siêu dữ liệu artifact (Artifact metadata)`,"lab.production.title":`Lưu lượng truy cập production được quan sát`,"lab.production.notVerification":`Không phải quy trình xác minh Lab (Lab verification)`,"lab.production.attempts":`Số lần thử (Attempts)`,"lab.production.successes":`Thành công (Successes)`,"lab.production.routeErrors":`Lỗi định tuyến (Route errors)`,"lab.production.lastObserved":`Quan sát lần cuối`,"lab.detailLoadFailed":`Không thể tải chi tiết phán quyết`,"lab.refresh":`Làm mới`,"lab.verdict.UNKNOWN":`Không xác định`,"lab.verdict.CLAIMED":`Đã xác nhận (Claimed)`,"lab.verdict.PROBED":`Đã thăm dò (Probed)`,"lab.verdict.VERIFIED":`Đã xác minh (Verified)`,"lab.verdict.DEGRADED":`Đã xuống cấp (Degraded)`,"lab.verdict.BLOCKED":`Đã bị chặn (Blocked)`,"lab.verdict.UNSUPPORTED":`Không được hỗ trợ (Unsupported)`,"lab.layer.protocol_conformance":`Tuân thủ giao thức (Protocol conformance)`,"lab.layer.live_route_compatibility":`Tính tương thích của định tuyến trực tiếp (Live route compatibility)`,"lab.layer.task_effectiveness":`Hiệu quả tác vụ (Task effectiveness)`,"models.aliases":`Bí danh (Aliases)`,"models.aliasesTable":`Bảng bí danh (Alias table)`,"models.aliasPrompt":`Bí danh provider (để trống để xóa)`,"models.modelAliasPrompt":`Bí danh model (để trống để xóa)`,"models.aliasSaved":`Đã lưu bí danh`,"models.aliasConflict":`Bí danh đó xung đột với một tên đã tồn tại`,"models.editProviderAlias":`Chỉnh sửa bí danh provider`,"models.editModelAlias":`Chỉnh sửa bí danh model`,"models.useDefaultAliases":`Sử dụng các bí danh mặc định`,"models.useDefaultAliasesGlobal":`Sử dụng các bí danh mặc định toàn cục`,"models.aliasAuto":`tự động (auto)`,"models.aliasUser":`người dùng (user)`,"models.aliasStale":`cũ (stale)`,"connection.discovering":`Đang khám phá các mục tiêu cục bộ (local) và được chia sẻ…`,"connection.machineUnavailable":`Mặt phẳng máy cục bộ (local machine plane) không khả dụng. Các yêu cầu chia sẻ đã không được chuyển hướng cục bộ.`,"connection.disconnect":`Ngắt kết nối khỏi hub`,"connection.disconnectConfirm":`Ngắt kết nối máy này khỏi hub và khởi động lại ở chế độ độc lập (standalone mode)?`,"connection.pairing.hub":`Hub`,"connection.pairing.getCode":`Chạy lệnh này trên hub cho trình duyệt này:`,"connection.pairing.askOperator":`Nếu người khác vận hành hub, hãy gửi lệnh này cho họ và yêu cầu mã ghép nối dùng một lần.`,"connection.pairing.notApiKey":`Dán mã ghép nối dùng một lần vào đây. Khóa API dữ liệu và admin token không thuộc trường này.`,"connection.pairing.networkError":`Không thể kết nối tới hub. Hãy kiểm tra kết nối và thử lại; mã của bạn vẫn còn ở đây.`,"connection.pairing.requestError":`Hub không thể hoàn tất yêu cầu ghép nối. Hãy kiểm tra trạng thái và thử lại.`,"connection.pairing.responseError":`Hub không trả về phiên trình duyệt hợp lệ. Hãy cập nhật hub hoặc nhờ người vận hành rồi thử lại.`,"dash.authRequired":`Cần xác thực trình duyệt để xem bảng điều khiển này.`,"dash.permissionDenied":`Trình duyệt này không được phép đọc bảng điều khiển. Hãy kiểm tra cài đặt truy cập với người vận hành máy chủ.`,"dash.dataUnavailable":`Không thể tải dữ liệu bảng điều khiển. Hãy kiểm tra kết nối và thử lại.`,"dash.staleData":`Đang hiển thị dữ liệu nhận được gần nhất; dữ liệu có thể đã cũ.`,"connection.pairing.title":`Kết nối dashboard này với hub`,"connection.pairing.body":`Dán mã ghép nối một lần (one-time pairing code) được tạo trên hub.`,"connection.pairing.relayWarning":`Mã này được trao đổi thông qua hub relay cố định. Không thể chuyển hướng relay sang một máy chủ khác.`,"connection.pairing.code":`Mã ghép nối một lần`,"connection.pairing.submit":`Kết nối`,"connection.pairing.submitting":`Đang kết nối…`,"connection.pairing.error":`Mã ghép nối đã bị từ chối hoặc hết hạn. Mã vẫn được giữ nguyên để bạn có thể kiểm tra.`,"connection.machine.title":`Máy này`,"connection.machine.shimHealthy":`Codex shim đang hoạt động bình thường.`,"connection.machine.shimNeedsAttention":`Codex shim cần được chú ý.`,"connection.machine.repairShim":`Sửa chữa shim`,"connection.machine.removeShim":`Xóa shim`,"connection.clients.title":`Các client đã kết nối`,"connection.clients.none":`Không có trạng thái client nào khả dụng`,"connection.clients.sync":`Đồng bộ ngay`,"connection.clients.syncing":`Đang đồng bộ…`,"connection.sessionLogout":`Đăng xuất phiên từ xa`,"connection.sessionLoggingOut":`Đang đăng xuất phiên từ xa…`,"connection.sessionLogoutFailed":`Không thể đăng xuất phiên từ xa. Phiên hiện tại vẫn được giữ nguyên.`,"usage.source.connected":`Nguồn: mức sử dụng hub`,"usage.source.local":`Nguồn: usage.jsonl cục bộ`,"usage.scope.label":`Phạm vi sử dụng`,"usage.scope.machine":`Máy này`,"usage.scope.hub":`Toàn bộ hub`,"usage.hubOffline":`Mức sử dụng hub không khả dụng. Mức sử dụng cục bộ đã không được dùng thay thế.`,"models.displayNameSavedRefreshFailed":`Thay đổi đã được lưu, nhưng không thể làm mới danh sách model. Hãy thử lại để làm mới nó.`,"models.displayNameOutcomeUnknown":`Yêu cầu chưa hoàn tất. Thay đổi có thể đã được lưu. Hãy thử lại để kiểm tra tên hiện tại trước khi thực hiện thay đổi khác.`,"models.displayNameCurrentUnavailable":`Tên hiện tại không khả dụng cho đến khi làm mới`,"models.displayNameReloaded":`Đã làm mới danh sách model`,"models.displayNameAction":`Tên`,"models.displayNameActionLabel":`Chỉnh sửa tên thân thiện (friendly name) cho {model}`,"models.displayNameTitle":`Tên thân thiện`,"models.displayNameModelId":`Model ID`,"models.displayNameCurrent":`Tên hiện tại`,"models.displayNameSourceOperator":`Tên của bạn`,"models.displayNameSourceProvider":`Tên provider`,"models.displayNameSourceFallback":`Dự phòng Model ID (Model ID fallback)`,"models.displayNameField":`Tên thân thiện`,"models.displayNamePlaceholder":`ví dụ: Grok 4.6`,"models.displayNameHelp":`Chỉ thay đổi cách hiển thị. Việc định tuyến vẫn là {model}.`,"models.displayNameReset":`Đặt lại tên`,"models.displayNameSaved":`Đã lưu tên hiển thị`,"models.displayNameResetDone":`Đã đặt lại tên hiển thị`,"models.displayNameSaveFailed":`Không thể lưu tên hiển thị`,"models.displayNameRequired":`Hãy nhập tên thân thiện, hoặc sử dụng Đặt lại tên.`,"models.displayNameTooLong":`Tên thân thiện phải có độ dài từ 128 ký tự trở xuống.`,"models.displayNameNoSlash":`Tên thân thiện không được chứa ký tự /.`,"models.displayNameNoControl":`Tên thân thiện không được chứa các ký tự điều khiển (control characters).`,"pricing.override.action":`Giá`,"pricing.override.actionLabel":`Chỉnh sửa giá cho {model}`,"pricing.override.badge":`Giá thủ công`,"pricing.override.title":`Giá model`,"pricing.override.modelId":`Model ID`,"pricing.override.help":`USD cho mỗi 1M token. Nhập mức giá đầu vào (input) và đầu ra (output); mức giá cache nếu để trống sẽ tính là 0. Đặt cả bốn mức giá bằng 0 nghĩa là miễn phí.`,"pricing.override.input":`Đầu vào (Input)`,"pricing.override.output":`Đầu ra (Output)`,"pricing.override.cacheRead":`Đọc bộ nhớ đệm (Cache read)`,"pricing.override.cacheWrite":`Ghi bộ nhớ đệm (Cache write)`,"pricing.override.loading":`Đang tải giá đã lưu…`,"pricing.override.loadFailed":`Không thể tải giá đã lưu. Hãy tải lại để thử lại.`,"pricing.override.outcomeUnknown":`Yêu cầu không hoàn tất một cách đáng tin cậy. Giá có thể đã thay đổi. Hãy tải lại giá đã lưu trước khi chỉnh sửa tiếp.`,"pricing.override.recoveryFailed":`Không thể khôi phục giá đã lưu. Chức năng chỉnh sửa vẫn bị khóa; hãy tải lại để thử lại.`,"pricing.override.recovered":`Đã tải giá được lưu mới nhất. Yêu cầu trước đó hoặc một client khác vẫn có thể thay đổi nó.`,"pricing.override.refreshFailed":`Giá đã được lưu, nhưng không thể làm mới danh sách model. Hãy thử làm mới lại danh sách.`,"pricing.override.invalid":`Hãy nhập mức giá đầu vào và đầu ra. Mỗi mức giá phải là một số hữu hạn từ 0 đến 1,000,000.`,"pricing.override.reset":`Đặt lại thành tự động`,"pricing.override.save":`Lưu`,"pricing.override.saving":`Đang lưu…`,"pricing.override.reload":`Tải lại giá`,"pricing.override.refresh":`Làm mới danh sách`,"pricing.override.cancel":`Hủy`,"pricing.override.close":`Đóng`,"usage.range.custom":`Phạm vi ngày tùy chỉnh`,"usage.range.start":`Bắt đầu (giờ địa phương)`,"usage.range.end":`Kết thúc (giờ địa phương)`,"usage.range.apply":`Áp dụng`,"usage.range.clear":`Xóa`,"usage.range.help":`Giờ địa phương. Bao gồm toàn bộ phút kết thúc.`,"usage.range.required":`Hãy nhập cả ngày và giờ bắt đầu cũng như kết thúc.`,"usage.range.invalid":`Hãy nhập ngày và giờ địa phương hợp lệ, từ ngày 1970-01-01 UTC trở đi.`,"usage.range.reversed":`Thời điểm kết thúc phải bằng hoặc sau thời điểm bắt đầu.`,"usage.range.applied":`Khoảng thời gian đã chọn: {start} – {end} (bao gồm cả hai).`,"models.pickerOrder.editorHint":`Sắp xếp lại các model được định tuyến, sau đó lưu bản nháp của bạn. Các hàng nổi bật (featured) được cố định; các model gốc (native) không được hiển thị.`,"models.pickerOrder.nativeLocked":`Thứ tự đã lưu này bao gồm các model gốc. Hãy áp dụng một cài đặt sẵn (preset) định tuyến hoặc Mặc định (Default) trước khi chỉnh sửa Tùy chỉnh (Custom).`,"models.pickerOrder.unknownChosen":`Các lựa chọn nổi bật không xác định. Hãy tải lại trước khi chỉnh sửa.`,"models.pickerOrder.changed":`Cài đặt bộ chọn (picker) đã thay đổi. Bản nháp của bạn vẫn được giữ lại; hãy tải lại để loại bỏ nó và sử dụng cài đặt hiện tại.`,"models.pickerOrder.savedReload":`Đã lưu thứ tự. Hãy tải lại cài đặt hiện tại trước khi chỉnh sửa lại.`,"models.pickerOrder.requestFailed":`Yêu cầu thất bại. Bản nháp của bạn vẫn được giữ lại; hãy thử lại hoặc tải lại.`,"models.pickerOrder.empty":`Không có model được định tuyến nào khả dụng.`,"models.pickerOrder.dragModel":`Kéo {model}`,"models.pickerOrder.featured":`Nổi bật (Featured)`,"models.pickerOrder.upModel":`Di chuyển {model} lên`,"models.pickerOrder.downModel":`Di chuyển {model} xuống`,"models.pickerOrder.position":`{model}: vị trí {position} trong số {total}`,"models.pickerOrder.saveDraft":`Lưu bản nháp`,"models.pickerOrder.reloadDraft":`Tải lại và bỏ bản nháp`,"models.pickerOrder.catalogRequired":`Danh tính của các model bị thiếu hoặc không rõ ràng. Hãy tải lại trang Models để làm mới danh mục của nó trước khi chỉnh sửa Tùy chỉnh (Custom).`,"nav.remote":`Không gian làm việc từ xa`,"remote.title":`Không gian làm việc từ xa`,"remote.subtitle":`Chạy Codex, Claude Code hoặc Pi từ Hub này trong khi tệp, lệnh, kiểm thử và bản dựng vẫn ở trên máy tính bạn chọn.`,"remote.loading":`Đang tải không gian làm việc từ xa…`,"remote.loadFailed":`Không thể tải không gian làm việc từ xa.`,"remote.hubRequired":`Hãy dùng chế độ Hub và khởi động Hub với OCX_REMOTE_WORKSPACE_ENABLED=1 để bật không gian làm việc từ xa.`,"remote.refresh":`Làm mới`,"remote.addComputer":`Thêm máy tính`,"remote.addComputerHint":`Phê duyệt một hoặc nhiều thư mục cục bộ, sau đó giữ executor chỉ dành cho OCX kết nối với Hub này.`,"remote.createPairing":`Tạo mã ghép nối`,"remote.pairingCode":`Mã ghép nối dùng một lần`,"remote.pairingExpires":`Hết hạn lúc {time}`,"remote.pairingCommand":`Chạy trên máy tính bạn đang thêm`,"remote.pairingCommandPosix":`Terminal Linux / macOS`,"remote.pairingCommandWindows":`Windows PowerShell`,"remote.copyCommand":`Sao chép lệnh`,"remote.copied":`Đã sao chép`,"remote.devices":`Máy tính`,"remote.noDevices":`Chưa có máy tính nào được ghép nối.`,"remote.online":`Trực tuyến`,"remote.offline":`Ngoại tuyến`,"remote.revoke":`Thu hồi máy tính`,"remote.revokeConfirm":`Thu hồi {name}? Các phiên đang hoạt động trên máy tính này sẽ dừng.`,"remote.newSession":`Phiên từ xa mới`,"remote.device":`Máy tính`,"remote.folder":`Thư mục không gian làm việc`,"remote.runtime":`Coding agent`,"remote.access":`Quyền truy cập không gian làm việc`,"remote.access.readOnly":`Chỉ đọc`,"remote.access.workspace":`Chỉnh sửa tệp và chạy lệnh`,"remote.access.workspaceFilesOnly":`Chỉ chỉnh sửa tệp`,"remote.unavailable":`Không khả dụng`,"remote.capability.full":`Tệp + lệnh trong sandbox`,"remote.capability.files":`Chỉ công cụ tệp`,"remote.runsOnHub":`Model và thông tin đăng nhập vẫn ở trên Hub này`,"remote.runsReadOnly":`Chỉ có thể đọc tệp trên máy tính này`,"remote.runsFilesCommands":`Tệp, bản dựng và lệnh chạy tại đây`,"remote.runsFilesOnly":`Công cụ tệp chạy tại đây; sandbox lệnh không khả dụng`,"remote.execUnavailable":`Máy tính này có thể chỉnh sửa tệp, nhưng bản dựng và lệnh terminal bị tắt vì không có sandbox hệ điều hành được hỗ trợ.`,"remote.notResumable":`Phiên này đã dừng trước khi coding agent tạo lịch sử bền vững. Hãy bắt đầu phiên từ xa mới.`,"remote.startSession":`Bắt đầu phiên từ xa`,"remote.sessionStarted":`Phiên từ xa đã sẵn sàng.`,"remote.sessions":`Phiên`,"remote.noSessions":`Hãy chọn máy tính trực tuyến, thư mục và coding agent để bắt đầu.`,"remote.events":`Hoạt động phiên từ xa`,"remote.noEvents":`Chưa có hoạt động.`,"remote.prompt":`Tin nhắn`,"remote.promptPlaceholder":`Yêu cầu agent trên Hub làm việc trong thư mục từ xa đã chọn…`,"remote.send":`Gửi`,"remote.stop":`Dừng phiên`,"remote.requestFailed":`Yêu cầu không gian làm việc từ xa thất bại.`,"remote.submissionUnknown":`Chưa rõ trạng thái gửi. Hãy kiểm tra phiên trước khi gửi lại.`,"remote.status.starting":`Đang khởi động`,"remote.status.ready":`Sẵn sàng`,"remote.status.running":`Đang chạy`,"remote.status.waiting":`Executor ngoại tuyến`,"remote.status.failed":`Thất bại`,"remote.status.stopped":`Đã dừng`,"remote.event.status":`Trạng thái`,"remote.event.tool":`Công cụ từ xa`,"remote.event.error":`Lỗi`,"models.newPolicyGlobal":`Model mới mặc định bị tắt`,"models.newPolicyProvider":`Chính sách model mới`,"models.newPolicy_inherit":`Kế thừa`,"models.newPolicy_off":`Tắt`,"models.newPolicy_on":`Bật`,"models.newBadge":`MỚI`,"models.newCount":`{count} model mới, đang tắt`,"codexSet.custom.deleteConfirm":`Xóa lớp này? Không thể hoàn tác.`,"codexSet.custom.moveUp":`Di chuyển {title} lên`,"codexSet.dialog.copyKey":`Sao chép khóa`,"codexSet.dialog.noRenderedText":`Codex không cung cấp nội dung đã ghép của một lớp tích hợp sẵn, nên hộp thoại này mô tả lớp và nêu tên khóa thay vì hiển thị nội dung của nó.`,"codexSet.dialog.notRendered":`Lớp này không gửi gì trong lượt đã đọc. Các phần chỉ được gửi lại khi thay đổi, nên một lớp không đổi sẽ vắng mặt trong một mẫu đơn lẻ.`,"codexSet.dialog.unknownLayer":`Bản dựng này không có mô tả cho lớp đó. Nó đến từ một runtime Codex mới hơn bảng điều khiển.`,"codexSet.layer.skills":`Skills`,"codexSet.lint.size":`Lớp này vượt quá 8 KB. Vẫn lưu được, nhưng sẽ tốn token trong mọi yêu cầu.`,"codexSet.prompt.extensionsUnknown":`Tiện ích mở rộng có thể thêm lớp riêng. Codex không cung cấp chúng, nên không thể liệt kê ở đây.`,"codexSet.prompt.loadFailed":`Không thể tải các lớp prompt.`,"codexSet.prompt.writeFailed":`Không thể lưu thay đổi.`,"codexSet.row.alwaysOn":`Luôn bật`,"codexSet.row.featureGated":`Được cấu hình trong [features]`,"common.discard":`Hủy bỏ`,"logs.filter.conversation.clear":`Xóa`,"modal.baseUrlPlaceholder":`https://...`,"nav.codexAuth":`Codex Auth`,"pws.noModelMatch":`Không có model nào khớp bộ lọc.`,"quota.fiveHourLimit":`Giới hạn 5 giờ`,"models.fastRows.title":`Hiển thị hàng model Fast`,"models.fastRows.desc":`Thêm các bộ chọn “Model Fast” đủ điều kiện vào trình chọn model của client bên ngoài. Việc này không thay đổi tùy chọn reasoning-effort của model gốc. Khi lưu, các tích hợp đang kết nối sẽ được làm mới nếu có thể; nếu không, hãy làm mới tích hợp hoặc catalog của client.`,"models.fastRows.refreshHint":`Đã lưu. Đang chờ làm mới catalog.`,"models.fastRows.enabled":`Đã bật hàng model Fast.`,"models.fastRows.disabled":`Đã tắt hàng model Fast.`,"models.fastRows.loadFailed":`Không thể tải cài đặt hàng Fast.`,"models.fastRows.updateFailed":`Không thể cập nhật cài đặt hàng Fast.`},ae={en:{"lab.title":`Compatibility Lab`,"lab.subtitle":`Read-only compatibility verdict matrix from lab projection evidence.`,"lab.loadFailed":`Could not load compatibility lab data`,"lab.projectionUnavailable":`Lab projection is not available. Run conformance or live probes first.`,"lab.projectionIncompatible":`Lab projection schema is incompatible. Rebuild the projection.`,"lab.statusTitle":`Projection status`,"lab.matrixTitle":`Compatibility matrix`,"lab.verdictsTitle":`Verdict records`,"lab.filter.layer":`Evidence layer`,"lab.filter.verdict":`Verdict`,"lab.filter.subject":`Subject ID`,"lab.filter.all":`All`,"lab.col.subject":`Subject`,"lab.col.layer":`Layer`,"lab.col.suite":`Suite`,"lab.col.verdict":`Verdict`,"lab.col.asOf":`As of`,"lab.col.protocol":`Protocol conformance`,"lab.col.live":`Live route compatibility`,"lab.col.task":`Task effectiveness`,"lab.empty":`No compatibility verdicts in the projection yet.`,"lab.subjectKind":`Kind`,"lab.observationCount":`Observations`,"lab.eventCount":`Events`,"lab.verdictCount":`Verdicts`,"lab.subjectCount":`Subjects`,"lab.builtAt":`Built`,"lab.loading":`Loading compatibility evidence…`,"lab.loadMore":`Load more`,"lab.detailTitle":`Verdict detail`,"lab.detailClose":`Close`,"lab.detailSubject":`Subject`,"lab.detailObservations":`Observations`,"lab.detailEvents":`Evidence events`,"lab.detailArtifacts":`Artifact metadata`,"lab.detailLoadFailed":`Could not load verdict detail`,"lab.refresh":`Refresh`,"lab.verdict.UNKNOWN":`Unknown`,"lab.verdict.CLAIMED":`Claimed`,"lab.verdict.PROBED":`Probed`,"lab.verdict.VERIFIED":`Verified`,"lab.verdict.DEGRADED":`Degraded`,"lab.verdict.BLOCKED":`Blocked`,"lab.verdict.UNSUPPORTED":`Unsupported`,"lab.layer.protocol_conformance":`Protocol conformance`,"lab.layer.live_route_compatibility":`Live route compatibility`,"lab.layer.task_effectiveness":`Task effectiveness`},de:{"lab.title":`Kompatibilitäts-Labor`,"lab.subtitle":`Schreibgeschützte Kompatibilitätsmatrix aus den Evidenzen der Lab-Projektion.`,"lab.loadFailed":`Kompatibilitätsdaten konnten nicht geladen werden`,"lab.projectionUnavailable":`Die Lab-Projektion ist nicht verfügbar. Führe zuerst Konformitäts- oder Live-Probes aus.`,"lab.projectionIncompatible":`Das Schema der Lab-Projektion ist inkompatibel. Baue die Projektion neu auf.`,"lab.statusTitle":`Projektionsstatus`,"lab.matrixTitle":`Kompatibilitätsmatrix`,"lab.verdictsTitle":`Urteilsdatensätze`,"lab.filter.layer":`Evidenzschicht`,"lab.filter.verdict":`Urteil`,"lab.filter.subject":`Subjekt-ID`,"lab.filter.all":`Alle`,"lab.col.subject":`Subjekt`,"lab.col.layer":`Schicht`,"lab.col.suite":`Suite`,"lab.col.verdict":`Urteil`,"lab.col.asOf":`Stand`,"lab.col.protocol":`Protokollkonformität`,"lab.col.live":`Live-Route-Kompatibilität`,"lab.col.task":`Aufgabenwirksamkeit`,"lab.empty":`In der Projektion gibt es noch keine Kompatibilitätsurteile.`,"lab.subjectKind":`Art`,"lab.observationCount":`Beobachtungen`,"lab.eventCount":`Ereignisse`,"lab.verdictCount":`Urteile`,"lab.subjectCount":`Subjekte`,"lab.builtAt":`Erstellt`,"lab.loading":`Kompatibilitätsevidenz wird geladen…`,"lab.loadMore":`Mehr laden`,"lab.detailTitle":`Urteilsdetails`,"lab.detailClose":`Schließen`,"lab.detailSubject":`Subjekt`,"lab.detailObservations":`Beobachtungen`,"lab.detailEvents":`Evidenzereignisse`,"lab.detailArtifacts":`Artefakt-Metadaten`,"lab.detailLoadFailed":`Urteilsdetails konnten nicht geladen werden`,"lab.refresh":`Aktualisieren`,"lab.verdict.UNKNOWN":`Unbekannt`,"lab.verdict.CLAIMED":`Behauptet`,"lab.verdict.PROBED":`Geprüft`,"lab.verdict.VERIFIED":`Verifiziert`,"lab.verdict.DEGRADED":`Eingeschränkt`,"lab.verdict.BLOCKED":`Blockiert`,"lab.verdict.UNSUPPORTED":`Nicht unterstützt`,"lab.layer.protocol_conformance":`Protokollkonformität`,"lab.layer.live_route_compatibility":`Live-Route-Kompatibilität`,"lab.layer.task_effectiveness":`Aufgabenwirksamkeit`},fr:{"lab.title":`Laboratoire de compatibilité`,"lab.subtitle":`Matrice en lecture seule des verdicts de compatibilité fondée sur les preuves de la projection du laboratoire.`,"lab.loadFailed":`Impossible de charger les données du laboratoire de compatibilité`,"lab.projectionUnavailable":`La projection du laboratoire n’est pas disponible. Exécutez d’abord les sondes de conformité ou en conditions réelles.`,"lab.projectionIncompatible":`Le schéma de la projection du laboratoire est incompatible. Reconstruisez la projection.`,"lab.statusTitle":`État de la projection`,"lab.matrixTitle":`Matrice de compatibilité`,"lab.verdictsTitle":`Enregistrements des verdicts`,"lab.filter.layer":`Couche de preuves`,"lab.filter.verdict":`Verdict`,"lab.filter.subject":`ID du sujet`,"lab.filter.all":`Tous`,"lab.col.subject":`Sujet`,"lab.col.layer":`Couche`,"lab.col.suite":`Suite`,"lab.col.verdict":`Verdict`,"lab.col.asOf":`Établi le`,"lab.col.protocol":`Conformité au protocole`,"lab.col.live":`Compatibilité du routage en conditions réelles`,"lab.col.task":`Efficacité des tâches`,"lab.empty":`La projection ne contient encore aucun verdict de compatibilité.`,"lab.subjectKind":`Type`,"lab.observationCount":`Observations`,"lab.eventCount":`Événements`,"lab.verdictCount":`Verdicts`,"lab.subjectCount":`Sujets`,"lab.builtAt":`Générée le`,"lab.loading":`Chargement des preuves de compatibilité…`,"lab.loadMore":`Charger plus`,"lab.detailTitle":`Détails du verdict`,"lab.detailClose":`Fermer`,"lab.detailSubject":`Sujet`,"lab.detailObservations":`Observations`,"lab.detailEvents":`Événements probants`,"lab.detailArtifacts":`Métadonnées des artefacts`,"lab.detailLoadFailed":`Impossible de charger les détails du verdict`,"lab.refresh":`Actualiser`,"lab.verdict.UNKNOWN":`Inconnu`,"lab.verdict.CLAIMED":`Déclaré`,"lab.verdict.PROBED":`Sondé`,"lab.verdict.VERIFIED":`Vérifié`,"lab.verdict.DEGRADED":`Dégradé`,"lab.verdict.BLOCKED":`Bloqué`,"lab.verdict.UNSUPPORTED":`Non pris en charge`,"lab.layer.protocol_conformance":`Conformité au protocole`,"lab.layer.live_route_compatibility":`Compatibilité du routage en conditions réelles`,"lab.layer.task_effectiveness":`Efficacité des tâches`},ko:{"lab.title":`호환성 랩`,"lab.subtitle":`랩 프로젝션 증거를 기반으로 한 읽기 전용 호환성 판정 매트릭스입니다.`,"lab.loadFailed":`호환성 랩 데이터를 불러오지 못했습니다`,"lab.projectionUnavailable":`랩 프로젝션을 사용할 수 없습니다. 먼저 적합성 또는 라이브 프로브를 실행하세요.`,"lab.projectionIncompatible":`랩 프로젝션 스키마가 호환되지 않습니다. 프로젝션을 다시 빌드하세요.`,"lab.statusTitle":`프로젝션 상태`,"lab.matrixTitle":`호환성 매트릭스`,"lab.verdictsTitle":`판정 레코드`,"lab.filter.layer":`증거 레이어`,"lab.filter.verdict":`판정`,"lab.filter.subject":`대상 ID`,"lab.filter.all":`전체`,"lab.col.subject":`대상`,"lab.col.layer":`레이어`,"lab.col.suite":`스위트`,"lab.col.verdict":`판정`,"lab.col.asOf":`기준 시각`,"lab.col.protocol":`프로토콜 적합성`,"lab.col.live":`라이브 경로 호환성`,"lab.col.task":`작업 효과성`,"lab.empty":`프로젝션에 아직 호환성 판정이 없습니다.`,"lab.subjectKind":`종류`,"lab.observationCount":`관측`,"lab.eventCount":`이벤트`,"lab.verdictCount":`판정`,"lab.subjectCount":`대상`,"lab.builtAt":`빌드 시각`,"lab.loading":`호환성 증거를 불러오는 중…`,"lab.loadMore":`더 불러오기`,"lab.detailTitle":`판정 상세`,"lab.detailClose":`닫기`,"lab.detailSubject":`대상`,"lab.detailObservations":`관측`,"lab.detailEvents":`증거 이벤트`,"lab.detailArtifacts":`아티팩트 메타데이터`,"lab.detailLoadFailed":`판정 상세를 불러오지 못했습니다`,"lab.refresh":`새로고침`,"lab.verdict.UNKNOWN":`알 수 없음`,"lab.verdict.CLAIMED":`주장됨`,"lab.verdict.PROBED":`프로브됨`,"lab.verdict.VERIFIED":`검증됨`,"lab.verdict.DEGRADED":`저하됨`,"lab.verdict.BLOCKED":`차단됨`,"lab.verdict.UNSUPPORTED":`지원되지 않음`,"lab.layer.protocol_conformance":`프로토콜 적합성`,"lab.layer.live_route_compatibility":`라이브 경로 호환성`,"lab.layer.task_effectiveness":`작업 효과성`},zh:{"lab.title":`兼容性实验室`,"lab.subtitle":`基于实验室投影证据的只读兼容性判定矩阵。`,"lab.loadFailed":`无法加载兼容性实验室数据`,"lab.projectionUnavailable":`实验室投影不可用。请先运行一致性探测或实时探测。`,"lab.projectionIncompatible":`实验室投影架构不兼容。请重新构建投影。`,"lab.statusTitle":`投影状态`,"lab.matrixTitle":`兼容性矩阵`,"lab.verdictsTitle":`判定记录`,"lab.filter.layer":`证据层`,"lab.filter.verdict":`判定`,"lab.filter.subject":`主体 ID`,"lab.filter.all":`全部`,"lab.col.subject":`主体`,"lab.col.layer":`层`,"lab.col.suite":`测试套件`,"lab.col.verdict":`判定`,"lab.col.asOf":`截至`,"lab.col.protocol":`协议一致性`,"lab.col.live":`实时路由兼容性`,"lab.col.task":`任务有效性`,"lab.empty":`投影中还没有兼容性判定。`,"lab.subjectKind":`类型`,"lab.observationCount":`观测`,"lab.eventCount":`事件`,"lab.verdictCount":`判定`,"lab.subjectCount":`主体`,"lab.builtAt":`构建时间`,"lab.loading":`正在加载兼容性证据…`,"lab.loadMore":`加载更多`,"lab.detailTitle":`判定详情`,"lab.detailClose":`关闭`,"lab.detailSubject":`主体`,"lab.detailObservations":`观测`,"lab.detailEvents":`证据事件`,"lab.detailArtifacts":`制品元数据`,"lab.detailLoadFailed":`无法加载判定详情`,"lab.refresh":`刷新`,"lab.verdict.UNKNOWN":`未知`,"lab.verdict.CLAIMED":`已声明`,"lab.verdict.PROBED":`已探测`,"lab.verdict.VERIFIED":`已验证`,"lab.verdict.DEGRADED":`降级`,"lab.verdict.BLOCKED":`已阻止`,"lab.verdict.UNSUPPORTED":`不支持`,"lab.layer.protocol_conformance":`协议一致性`,"lab.layer.live_route_compatibility":`实时路由兼容性`,"lab.layer.task_effectiveness":`任务有效性`},"zh-TW":{"lab.title":`相容性實驗室`,"lab.subtitle":`基於實驗室投影證據的唯讀相容性判定矩陣。`,"lab.loadFailed":`無法載入相容性實驗室資料`,"lab.projectionUnavailable":`實驗室投影不可用。請先執行一致性探測或即時探測。`,"lab.projectionIncompatible":`實驗室投影架構不相容。請重新建置投影。`,"lab.statusTitle":`投影狀態`,"lab.matrixTitle":`相容性矩陣`,"lab.verdictsTitle":`判定記錄`,"lab.filter.layer":`證據層`,"lab.filter.verdict":`判定`,"lab.filter.subject":`主體 ID`,"lab.filter.all":`全部`,"lab.col.subject":`主體`,"lab.col.layer":`層`,"lab.col.suite":`測試套件`,"lab.col.verdict":`判定`,"lab.col.asOf":`截至`,"lab.col.protocol":`協定一致性`,"lab.col.live":`即時路由相容性`,"lab.col.task":`任務有效性`,"lab.empty":`投影中還沒有相容性判定。`,"lab.subjectKind":`類型`,"lab.observationCount":`觀測`,"lab.eventCount":`事件`,"lab.verdictCount":`判定`,"lab.subjectCount":`主體`,"lab.builtAt":`建置時間`,"lab.loading":`正在載入相容性證據…`,"lab.loadMore":`載入更多`,"lab.detailTitle":`判定詳情`,"lab.detailClose":`關閉`,"lab.detailSubject":`主體`,"lab.detailObservations":`觀測`,"lab.detailEvents":`證據事件`,"lab.detailArtifacts":`產物中繼資料`,"lab.detailLoadFailed":`無法載入判定詳情`,"lab.refresh":`重新整理`,"lab.verdict.UNKNOWN":`未知`,"lab.verdict.CLAIMED":`已聲明`,"lab.verdict.PROBED":`已探測`,"lab.verdict.VERIFIED":`已驗證`,"lab.verdict.DEGRADED":`降級`,"lab.verdict.BLOCKED":`已封鎖`,"lab.verdict.UNSUPPORTED":`不支援`,"lab.layer.protocol_conformance":`協定一致性`,"lab.layer.live_route_compatibility":`即時路由相容性`,"lab.layer.task_effectiveness":`任務有效性`},ru:{"lab.title":`Лаборатория совместимости`,"lab.subtitle":`Матрица вердиктов совместимости только для чтения на основе данных проекции лаборатории.`,"lab.loadFailed":`Не удалось загрузить данные лаборатории совместимости`,"lab.projectionUnavailable":`Проекция лаборатории недоступна. Сначала выполните проверки соответствия или live-проверки.`,"lab.projectionIncompatible":`Схема проекции лаборатории несовместима. Перестройте проекцию.`,"lab.statusTitle":`Состояние проекции`,"lab.matrixTitle":`Матрица совместимости`,"lab.verdictsTitle":`Записи вердиктов`,"lab.filter.layer":`Слой доказательств`,"lab.filter.verdict":`Вердикт`,"lab.filter.subject":`ID субъекта`,"lab.filter.all":`Все`,"lab.col.subject":`Субъект`,"lab.col.layer":`Слой`,"lab.col.suite":`Набор`,"lab.col.verdict":`Вердикт`,"lab.col.asOf":`По состоянию на`,"lab.col.protocol":`Соответствие протоколу`,"lab.col.live":`Совместимость live-маршрута`,"lab.col.task":`Эффективность задач`,"lab.empty":`В проекции пока нет вердиктов совместимости.`,"lab.subjectKind":`Тип`,"lab.observationCount":`Наблюдения`,"lab.eventCount":`События`,"lab.verdictCount":`Вердикты`,"lab.subjectCount":`Субъекты`,"lab.builtAt":`Собрано`,"lab.loading":`Загрузка доказательств совместимости…`,"lab.loadMore":`Загрузить ещё`,"lab.detailTitle":`Детали вердикта`,"lab.detailClose":`Закрыть`,"lab.detailSubject":`Субъект`,"lab.detailObservations":`Наблюдения`,"lab.detailEvents":`События доказательств`,"lab.detailArtifacts":`Метаданные артефактов`,"lab.detailLoadFailed":`Не удалось загрузить детали вердикта`,"lab.refresh":`Обновить`,"lab.verdict.UNKNOWN":`Неизвестно`,"lab.verdict.CLAIMED":`Заявлено`,"lab.verdict.PROBED":`Проверено пробой`,"lab.verdict.VERIFIED":`Подтверждено`,"lab.verdict.DEGRADED":`Ограничено`,"lab.verdict.BLOCKED":`Заблокировано`,"lab.verdict.UNSUPPORTED":`Не поддерживается`,"lab.layer.protocol_conformance":`Соответствие протоколу`,"lab.layer.live_route_compatibility":`Совместимость live-маршрута`,"lab.layer.task_effectiveness":`Эффективность задач`},ja:{"lab.title":`互換性ラボ`,"lab.subtitle":`ラボ投影の証拠に基づく読み取り専用の互換性判定マトリクスです。`,"lab.loadFailed":`互換性ラボのデータを読み込めませんでした`,"lab.projectionUnavailable":`ラボ投影を利用できません。先に適合性プローブまたはライブプローブを実行してください。`,"lab.projectionIncompatible":`ラボ投影のスキーマに互換性がありません。投影を再構築してください。`,"lab.statusTitle":`投影ステータス`,"lab.matrixTitle":`互換性マトリクス`,"lab.verdictsTitle":`判定レコード`,"lab.filter.layer":`証拠レイヤー`,"lab.filter.verdict":`判定`,"lab.filter.subject":`サブジェクト ID`,"lab.filter.all":`すべて`,"lab.col.subject":`サブジェクト`,"lab.col.layer":`レイヤー`,"lab.col.suite":`スイート`,"lab.col.verdict":`判定`,"lab.col.asOf":`時点`,"lab.col.protocol":`プロトコル適合性`,"lab.col.live":`ライブ経路互換性`,"lab.col.task":`タスク有効性`,"lab.empty":`投影にはまだ互換性判定がありません。`,"lab.subjectKind":`種類`,"lab.observationCount":`観測`,"lab.eventCount":`イベント`,"lab.verdictCount":`判定`,"lab.subjectCount":`サブジェクト`,"lab.builtAt":`構築日時`,"lab.loading":`互換性の証拠を読み込み中…`,"lab.loadMore":`さらに読み込む`,"lab.detailTitle":`判定の詳細`,"lab.detailClose":`閉じる`,"lab.detailSubject":`サブジェクト`,"lab.detailObservations":`観測`,"lab.detailEvents":`証拠イベント`,"lab.detailArtifacts":`アーティファクトのメタデータ`,"lab.detailLoadFailed":`判定の詳細を読み込めませんでした`,"lab.refresh":`更新`,"lab.verdict.UNKNOWN":`不明`,"lab.verdict.CLAIMED":`申告済み`,"lab.verdict.PROBED":`プローブ済み`,"lab.verdict.VERIFIED":`検証済み`,"lab.verdict.DEGRADED":`低下`,"lab.verdict.BLOCKED":`ブロック`,"lab.verdict.UNSUPPORTED":`未対応`,"lab.layer.protocol_conformance":`プロトコル適合性`,"lab.layer.live_route_compatibility":`ライブ経路互換性`,"lab.layer.task_effectiveness":`タスク有効性`},tr:{"lab.title":`Uyumluluk Laboratuvarı`,"lab.subtitle":`Laboratuvar projeksiyonu kanıtlarından oluşturulan salt okunur uyumluluk karar matrisi.`,"lab.loadFailed":`Uyumluluk laboratuvarı verileri yüklenemedi`,"lab.projectionUnavailable":`Laboratuvar projeksiyonu kullanılamıyor. Önce uygunluk veya canlı probları çalıştırın.`,"lab.projectionIncompatible":`Laboratuvar projeksiyonu şeması uyumsuz. Projeksiyonu yeniden oluşturun.`,"lab.statusTitle":`Projeksiyon durumu`,"lab.matrixTitle":`Uyumluluk matrisi`,"lab.verdictsTitle":`Karar kayıtları`,"lab.filter.layer":`Kanıt katmanı`,"lab.filter.verdict":`Karar`,"lab.filter.subject":`Özne kimliği`,"lab.filter.all":`Tümü`,"lab.col.subject":`Özne`,"lab.col.layer":`Katman`,"lab.col.suite":`Paket`,"lab.col.verdict":`Karar`,"lab.col.asOf":`Tarih`,"lab.col.protocol":`Protokol uygunluğu`,"lab.col.live":`Canlı rota uyumluluğu`,"lab.col.task":`Görev etkinliği`,"lab.empty":`Projeksiyonda henüz uyumluluk kararı yok.`,"lab.subjectKind":`Tür`,"lab.observationCount":`Gözlemler`,"lab.eventCount":`Olaylar`,"lab.verdictCount":`Kararlar`,"lab.subjectCount":`Özneler`,"lab.builtAt":`Oluşturulma`,"lab.loading":`Uyumluluk kanıtları yükleniyor…`,"lab.loadMore":`Daha fazla yükle`,"lab.detailTitle":`Karar ayrıntısı`,"lab.detailClose":`Kapat`,"lab.detailSubject":`Özne`,"lab.detailObservations":`Gözlemler`,"lab.detailEvents":`Kanıt olayları`,"lab.detailArtifacts":`Artefakt meta verileri`,"lab.detailLoadFailed":`Karar ayrıntısı yüklenemedi`,"lab.refresh":`Yenile`,"lab.verdict.UNKNOWN":`Bilinmiyor`,"lab.verdict.CLAIMED":`İddia edildi`,"lab.verdict.PROBED":`Problandı`,"lab.verdict.VERIFIED":`Doğrulandı`,"lab.verdict.DEGRADED":`Kısıtlı`,"lab.verdict.BLOCKED":`Engellendi`,"lab.verdict.UNSUPPORTED":`Desteklenmiyor`,"lab.layer.protocol_conformance":`Protokol uygunluğu`,"lab.layer.live_route_compatibility":`Canlı rota uyumluluğu`,"lab.layer.task_effectiveness":`Görev etkinliği`},vi:{"lab.title":`Phòng thí nghiệm tương thích`,"lab.subtitle":`Ma trận kết quả tương thích chỉ đọc từ bằng chứng phép chiếu của phòng thí nghiệm.`,"lab.loadFailed":`Không thể tải dữ liệu phòng thí nghiệm tương thích`,"lab.projectionUnavailable":`Phép chiếu của phòng thí nghiệm không khả dụng. Hãy chạy kiểm tra tuân thủ hoặc đầu dò trực tiếp trước.`,"lab.projectionIncompatible":`Lược đồ phép chiếu của phòng thí nghiệm không tương thích. Hãy xây dựng lại phép chiếu.`,"lab.statusTitle":`Trạng thái phép chiếu`,"lab.matrixTitle":`Ma trận tương thích`,"lab.verdictsTitle":`Bản ghi kết quả`,"lab.filter.layer":`Lớp bằng chứng`,"lab.filter.verdict":`Kết quả`,"lab.filter.subject":`ID Chủ đề`,"lab.filter.all":`Tất cả`,"lab.col.subject":`Chủ đề`,"lab.col.layer":`Lớp`,"lab.col.suite":`Bộ kiểm thử`,"lab.col.verdict":`Kết quả`,"lab.col.asOf":`Tính đến`,"lab.col.protocol":`Tuân thủ giao thức`,"lab.col.live":`Tương thích tuyến trực tiếp`,"lab.col.task":`Hiệu quả tác vụ`,"lab.empty":`Chưa có kết quả tương thích nào trong phép chiếu.`,"lab.subjectKind":`Loại`,"lab.observationCount":`Số quan sát`,"lab.eventCount":`Số sự kiện`,"lab.verdictCount":`Số kết quả`,"lab.subjectCount":`Số đối tượng`,"lab.builtAt":`Thời điểm xây dựng`,"lab.loading":`Đang tải bằng chứng tương thích…`,"lab.loadMore":`Tải thêm`,"lab.detailTitle":`Chi tiết kết quả`,"lab.detailClose":`Đóng`,"lab.detailSubject":`Chủ đề`,"lab.detailObservations":`Các quan sát`,"lab.detailEvents":`Sự kiện bằng chứng`,"lab.detailArtifacts":`Metadata của artifact`,"lab.detailLoadFailed":`Không thể tải chi tiết kết quả`,"lab.refresh":`Làm mới`,"lab.verdict.UNKNOWN":`Không xác định`,"lab.verdict.CLAIMED":`Đã khai báo`,"lab.verdict.PROBED":`Đã thăm dò`,"lab.verdict.VERIFIED":`Đã xác minh`,"lab.verdict.DEGRADED":`Suy giảm`,"lab.verdict.BLOCKED":`Bị chặn`,"lab.verdict.UNSUPPORTED":`Không được hỗ trợ`,"lab.layer.protocol_conformance":`Tuân thủ giao thức`,"lab.layer.live_route_compatibility":`Tương thích tuyến trực tiếp`,"lab.layer.task_effectiveness":`Hiệu quả tác vụ`}},oe={en:{subjectKindUnknown:`Unknown`,"artifact.present":`Present`,"artifact.corrupt":`Corrupt`,"artifact.purged_unavailable":`Purged / unavailable`,selectVerdict:`View verdict for {subject}`,"community.title":`Community evidence`,"community.notLocalVerdict":`Untrusted read-only context. Not included in this local verdict.`,"community.bundles":`Bundles`,"community.activeRecords":`Active records`,"community.revokedRecords":`Revoked records`},de:{subjectKindUnknown:`Unbekannt`,"artifact.present":`Vorhanden`,"artifact.corrupt":`Beschädigt`,"artifact.purged_unavailable":`Gelöscht / nicht verfügbar`,selectVerdict:`Urteil für {subject} anzeigen`,"community.title":`Community-Evidenz`,"community.notLocalVerdict":`Nicht vertrauenswürdiger Nur-Lese-Kontext. Nicht Teil dieses lokalen Urteils.`,"community.bundles":`Pakete`,"community.activeRecords":`Aktive Einträge`,"community.revokedRecords":`Widerrufene Einträge`},fr:{subjectKindUnknown:`Inconnu`,"artifact.present":`Présent`,"artifact.corrupt":`Corrompu`,"artifact.purged_unavailable":`Purgé / indisponible`,selectVerdict:`Afficher le verdict pour {subject}`,"community.title":`Données de la communauté`,"community.notLocalVerdict":`Contexte non fiable en lecture seule. Non inclus dans ce verdict local.`,"community.bundles":`Lots`,"community.activeRecords":`Enregistrements actifs`,"community.revokedRecords":`Enregistrements révoqués`},ko:{subjectKindUnknown:`알 수 없음`,"artifact.present":`있음`,"artifact.corrupt":`손상됨`,"artifact.purged_unavailable":`삭제됨 / 사용할 수 없음`,selectVerdict:`{subject}의 판정 보기`,"community.title":`커뮤니티 증거`,"community.notLocalVerdict":`신뢰되지 않는 읽기 전용 컨텍스트입니다. 이 로컬 판정에는 포함되지 않습니다.`,"community.bundles":`번들`,"community.activeRecords":`활성 레코드`,"community.revokedRecords":`폐기된 레코드`},zh:{subjectKindUnknown:`未知`,"artifact.present":`存在`,"artifact.corrupt":`已损坏`,"artifact.purged_unavailable":`已清除 / 不可用`,selectVerdict:`查看 {subject} 的判定`,"community.title":`社区证据`,"community.notLocalVerdict":`不受信任的只读上下文。不计入此本地判定。`,"community.bundles":`证据包`,"community.activeRecords":`有效记录`,"community.revokedRecords":`已撤销记录`},"zh-TW":{subjectKindUnknown:`未知`,"artifact.present":`存在`,"artifact.corrupt":`已損壞`,"artifact.purged_unavailable":`已清除 / 不可用`,selectVerdict:`查看 {subject} 的判定`,"community.title":`社群證據`,"community.notLocalVerdict":`不受信任的唯讀脈絡。不計入此本地判定。`,"community.bundles":`證據包`,"community.activeRecords":`有效記錄`,"community.revokedRecords":`已撤銷記錄`},ru:{subjectKindUnknown:`Неизвестно`,"artifact.present":`Доступен`,"artifact.corrupt":`Повреждён`,"artifact.purged_unavailable":`Удалён / недоступен`,selectVerdict:`Открыть вердикт для {subject}`,"community.title":`Данные сообщества`,"community.notLocalVerdict":`Недоверенный контекст только для чтения. Не входит в этот локальный вердикт.`,"community.bundles":`Пакеты`,"community.activeRecords":`Активные записи`,"community.revokedRecords":`Отозванные записи`},ja:{subjectKindUnknown:`不明`,"artifact.present":`存在`,"artifact.corrupt":`破損`,"artifact.purged_unavailable":`削除済み / 利用不可`,selectVerdict:`{subject} の判定を表示`,"community.title":`コミュニティ証拠`,"community.notLocalVerdict":`信頼されていない読み取り専用コンテキストです。このローカル判定には含まれません。`,"community.bundles":`バンドル`,"community.activeRecords":`有効なレコード`,"community.revokedRecords":`取り消されたレコード`},tr:{subjectKindUnknown:`Bilinmiyor`,"artifact.present":`Mevcut`,"artifact.corrupt":`Bozuk`,"artifact.purged_unavailable":`Temizlenmiş / kullanılamıyor`,selectVerdict:`{subject} için kararı görüntüle`,"community.title":`Topluluk kanıtı`,"community.notLocalVerdict":`Güvenilmeyen salt okunur bağlam. Bu yerel karara dahil değildir.`,"community.bundles":`Paketler`,"community.activeRecords":`Etkin kayıtlar`,"community.revokedRecords":`Geri çekilen kayıtlar`},vi:{subjectKindUnknown:`Không xác định`,"artifact.present":`Có sẵn`,"artifact.corrupt":`Hỏng`,"artifact.purged_unavailable":`Đã xóa / không khả dụng`,selectVerdict:`Xem kết quả cho {subject}`,"community.title":`Bằng chứng cộng đồng`,"community.notLocalVerdict":`Ngữ cảnh chỉ đọc không đáng tin cậy. Không được đưa vào kết quả cục bộ này.`,"community.bundles":`Gói bằng chứng`,"community.activeRecords":`Bản ghi đang hoạt động`,"community.revokedRecords":`Bản ghi đã thu hồi`}};function se(e,t,n){let r=oe[e][t];if(n)for(let[e,t]of Object.entries(n))r=r.split(`{${e}}`).join(String(t));return r}function ce(e,t){return{...t,...ae[e]}}var le={en:ce(`en`,y),de:ce(`de`,b),fr:ce(`fr`,x),ko:ce(`ko`,ee),zh:ce(`zh`,S),"zh-TW":ce(`zh-TW`,C),ru:ce(`ru`,te),ja:ce(`ja`,ne),tr:ce(`tr`,re),vi:ce(`vi`,ie)};function ue(e){return le[e][`lang.nativeName`]}function de(e,t){return le[e][t]}var w=[{code:`en`,htmlLang:`en`},{code:`de`,htmlLang:`de`},{code:`fr`,htmlLang:`fr`},{code:`ko`,htmlLang:`ko`},{code:`zh`,htmlLang:`zh-CN`},{code:`zh-TW`,htmlLang:`zh-TW`},{code:`ru`,htmlLang:`ru`},{code:`ja`,htmlLang:`ja`},{code:`tr`,htmlLang:`tr`},{code:`vi`,htmlLang:`vi`}],T=`ocx-lang`,fe=null;function pe(){try{let e=localStorage.getItem(T);if(e===`en`||e===`de`||e===`fr`||e===`ko`||e===`zh`||e===`zh-TW`||e===`ru`||e===`ja`||e===`tr`||e===`vi`)return e}catch{}let e=typeof navigator<`u`&&navigator?.language?navigator.language.toLowerCase():`en`;return e.startsWith(`de`)?`de`:e.startsWith(`fr`)?`fr`:e.startsWith(`ko`)?`ko`:e.startsWith(`zh`)?e.includes(`tw`)||e.includes(`hk`)||e.includes(`mo`)||e.includes(`hant`)?`zh-TW`:`zh`:e.startsWith(`ru`)?`ru`:e.startsWith(`ja`)?`ja`:e.startsWith(`tr`)?`tr`:e.startsWith(`vi`)?`vi`:`en`}function me(){return fe??pe()}function he(e){fe=e}var E=(0,_.createContext)(null);function D(e,t){if(!t)return e;let n=e;for(let e of Object.keys(t))n=n.split(`{${e}}`).join(String(t[e]));return n}function ge(){let e=(0,_.useContext)(E);if(!e)throw Error(`useI18n must be used within LanguageProvider`);return e}function _e(){return ge().t}var ve=`opencodex-admin-token-dialog`,ye=`OpenCodex`,be=`https://opencodex.me/guides/web-dashboard/#finding-the-admin-token`;function xe(e,t=me()){let n=le[t],r=n[`auth.adminTokenTitle`];return new Promise(t=>{let i=document.activeElement instanceof HTMLElement?document.activeElement:null,a=!1,o=document.createElement(`dialog`);o.id=ve,o.className=`modal-overlay`,o.setAttribute(`aria-labelledby`,`${ve}-title`);let s=document.createElement(`form`);s.className=`modal-card`,s.method=`post`,s.action=window.location.href,s.autocomplete=`on`;let c=document.createElement(`div`);c.className=`modal-head`;let l=document.createElement(`h3`);l.id=`${ve}-title`,l.textContent=r,c.append(l);let u=document.createElement(`div`),d=document.createElement(`label`);d.className=`field-label`,d.htmlFor=`${ve}-username`,d.textContent=n[`auth.adminAccountLabel`];let f=document.createElement(`input`);f.id=d.htmlFor,f.className=`input`,f.type=`text`,f.name=`username`,f.autocomplete=`username`,f.value=ye,f.readOnly=!0,u.append(d,f);let p=document.createElement(`div`);p.style.marginTop=`var(--space-4)`;let m=document.createElement(`label`);m.className=`field-label`,m.htmlFor=`${ve}-password`,m.textContent=n[`auth.adminTokenFieldLabel`];let h=document.createElement(`input`);h.id=m.htmlFor,h.className=`input`,h.type=`password`,h.name=`password`,h.autocomplete=`current-password`,h.required=!0,h.spellcheck=!1,h.autocapitalize=`none`,p.append(m,h);let g=document.createElement(`p`);g.className=`hint`,g.style.marginTop=`var(--space-2)`,g.textContent=n[`auth.adminTokenHelp`];let _=document.createElement(`a`);_.className=`text-control`,_.href=be,_.target=`_blank`,_.rel=`noreferrer`,_.style.color=`var(--accent)`,_.textContent=n[`auth.adminTokenDocsLink`],g.append(` `,_),p.append(g);let v=document.createElement(`div`);v.className=`notice notice-err`,v.setAttribute(`role`,`alert`),v.hidden=!0;let y=document.createElement(`div`);y.className=`modal-actions`;let b=document.createElement(`button`);b.type=`button`,b.className=`btn btn-ghost`,b.textContent=n[`common.cancel`];let x=document.createElement(`button`);x.type=`submit`,x.className=`btn btn-primary`,x.textContent=n[`common.ok`],y.append(b,x),s.append(c,u,p,v,y),o.append(s);let ee=e=>{v.textContent=e??``,v.hidden=e===null},S=e=>{a||(a=!0,o.open&&o.close(),o.remove(),i?.focus(),t(e))};s.addEventListener(`submit`,t=>{t.preventDefault();let r=h.value.trim();if(!r){h.value=``,h.reportValidity();return}h.disabled=!0,x.disabled=!0,ee(null),e(r).then(e=>{if(!a){if(e===`accepted`){S(r);return}h.value=``,h.disabled=!1,x.disabled=!1,ee(e===`rejected`?n[`auth.adminTokenRejected`]:n[`auth.adminTokenUnavailable`]),h.focus()}}).catch(()=>{a||(h.value=``,h.disabled=!1,x.disabled=!1,ee(n[`auth.adminTokenUnavailable`]),h.focus())})}),b.addEventListener(`click`,()=>S(null)),o.addEventListener(`cancel`,e=>{e.preventDefault(),S(null)}),document.body.append(o),typeof o.showModal==`function`?o.showModal():o.setAttribute(`open`,``),queueMicrotask(()=>h.focus())})}function Se(e){let t=new AbortController;if(typeof AbortSignal<`u`&&typeof AbortSignal.any==`function`&&typeof AbortSignal.timeout==`function`)return{controller:t,signal:AbortSignal.any([t.signal,AbortSignal.timeout(e)]),clear:()=>void 0};let n=setTimeout(()=>t.abort(),e);return{controller:t,signal:t.signal,clear:()=>clearTimeout(n)}}function Ce(){return typeof document>`u`?null:document.querySelector(`meta[name="opencodex-runtime-role"]`)?.getAttribute(`content`)?.trim()||null}function we(){return Ce()===`client`}function Te(){if(typeof document<`u`){let e=document.querySelector(`meta[name="opencodex-management-auth-required"]`)?.getAttribute(`content`)?.trim();if(e===`1`)return!0;if(e===`0`)return!1}return Ce()===`hub`}function Ee(e){return e.replace(/\/+$/,``)}function De(e){return new URL(e||`/`,window.location.href)}function Oe(e){try{let t=new URL(e);return t.protocol!==`http:`&&t.protocol!==`https:`||t.username||t.password||t.pathname!==`/`||t.search||t.hash?null:t.origin}catch{return null}}function ke(e,t,n,r){let i=Ee(t);return{id:e,baseUrl:i,serverOrigin:n,bootstrapPath:`${i}/opencodex-session`,transport:r}}function Ae(e){let t=De(e),n=Ee(e);return{connected:!1,machine:ke(`machine`,n,t.origin,`same-origin`),shared:ke(`shared`,n,t.origin,`same-origin`)}}function je(e){if(!e||typeof e!=`object`||Array.isArray(e))return!1;let t=e;return t.mode===`client`&&t.connected===!0&&t.protocolVersion===1&&(t.managementTransport===`direct`||t.managementTransport===`relay`)&&typeof t.machineBase==`string`&&typeof t.sharedBase==`string`&&typeof t.sharedServerOrigin==`string`&&typeof t.apiKeyId==`string`&&t.apiKeyId.trim().length>0&&typeof t.connectedAt==`string`&&(t.catalogSyncedAt===void 0||typeof t.catalogSyncedAt==`string`)}function Me(e,t){if(!je(t))throw TypeError(`machine status response is invalid`);let n=Ae(e),r=Oe(t.machineBase),i=Oe(t.sharedServerOrigin);if(!r||r!==n.machine.serverOrigin||!i)throw TypeError(`machine status target origins are invalid`);let a;try{a=new URL(t.sharedBase)}catch{throw TypeError(`machine status shared target is invalid`)}if(a.username||a.password||a.search||a.hash)throw TypeError(`machine status shared target is invalid`);if(t.managementTransport===`direct`){if(a.origin!==i||a.pathname!==`/`)throw TypeError(`machine status direct target is inconsistent`)}else if(a.origin!==r||a.pathname!==`/api/machine/hub-relay`)throw TypeError(`machine status relay target is inconsistent`);return{connected:!0,machine:ke(`machine`,Ee(e),r,`same-origin`),shared:t.managementTransport===`relay`?ke(`shared`,`${Ee(e)}/api/machine/hub-relay`,i,`relay`):ke(`shared`,i,i,`direct`),apiKeyId:t.apiKeyId,catalogSyncedAt:t.catalogSyncedAt}}function Ne(e,t){return t[e].baseUrl}async function Pe(e,t){let n=Ae(e);if(Ce()!==`client`)return n;let r;try{r=await fetch(`${n.machine.baseUrl}/api/machine/status`,{signal:t,cache:`no-store`})}catch(e){throw Error(`local machine plane unavailable`,{cause:e})}if(r.status===404)return n;if(!r.ok)throw Error(`local machine plane refused discovery (${r.status})`);let i=await r.json().catch(()=>null);if(!je(i))throw Error(`local machine plane returned invalid status`);return Me(e,i)}var Fe=`opencodex:session-unavailable`,Ie=`opencodex-api-token`,Le=`/api/settings`,Re=1e4,ze=15e3,Be=`X-OpenCodex-Machine-Session`,Ve=`X-OpenCodex-Machine-GUI-Origin`,He=`X-OpenCodex-Machine-CSRF-Token`,Ue=!1,We=null,Ge=null,Ke=xe,qe=Re,Je=ze,Ye=new Map;function Xe(e){if(typeof window>`u`)return;let t=window.CustomEvent??(typeof CustomEvent==`function`?CustomEvent:null);if(t)try{window.dispatchEvent(new t(Fe,{detail:{plane:e}}))}catch{}}function Ze(){return{token:null,csrfToken:null,browserOrigin:null,serverOrigin:null}}function Qe(){return Ge||et(Ae(``)),Ge}function $e(e,t){return e.baseUrl===t.baseUrl&&e.serverOrigin===t.serverOrigin&&e.transport===t.transport}function et(e){Ge=e;for(let t of[`machine`,`shared`]){let n=Ye.get(t);Ye.set(t,n&&$e(n.target,e[t])?{...n,target:e[t]}:{target:e[t],session:Ze(),resolutionInFlight:null,promptCancelled:!1})}}function O(e){return Qe(),Ye.get(e)}function tt(e,t){let n=O(e);t!==null&&n.session.token===t&&(n.session=Ze())}function nt(e,t,n,r,i){let a=O(e);return!t?.startsWith(`ocx_session_`)||!n||r!==window.location.origin||i!==a.target.serverOrigin?(a.session=Ze(),!1):(a.session={token:t,csrfToken:n,browserOrigin:r,serverOrigin:i},a.promptCancelled=!1,!0)}function rt(e){return!!O(e).session.token?.startsWith(`ocx_session_`)}async function it(e){let t=O(e);if(!t.session.token?.startsWith(`ocx_session_`))return!1;let n=Se(Re);try{return(await window.fetch(`${t.target.baseUrl}/api/session/logout`,{method:`POST`,signal:n.signal})).ok?(t.session=Ze(),t.promptCancelled=!1,!0):!1}catch{return!1}finally{n.clear()}}function at(e){let t=document.querySelector(`meta[name="${e}"]`),n=t?.content.trim()||null;return t?.remove(),n}function ot(){let e={token:at(`opencodex-session-token`),csrf:at(`opencodex-session-csrf`),browser:at(`opencodex-session-origin`),server:at(`opencodex-session-server-origin`)};for(let t of[`machine`,`shared`])O(t).target.serverOrigin===e.server&&nt(t,e.token,e.csrf,e.browser,e.server)}function st(e,t){for(let n of e.match(/<meta\b[^>]*>/gi)??[])if(n.match(/\bname=["']([^"']+)["']/i)?.[1]===t)return n.match(/\bcontent=["']([^"']*)["']/i)?.[1]?.trim()||null;return null}function ct(e,t){return nt(e,st(t,`opencodex-session-token`),st(t,`opencodex-session-csrf`),st(t,`opencodex-session-origin`),st(t,`opencodex-session-server-origin`))}function lt(){try{sessionStorage.removeItem(Ie)}catch{}}function ut(e){return new URL(e.baseUrl||`/`,window.location.href)}function dt(e,t){let n=ut(e);if(t.origin!==n.origin)return!1;let r=n.pathname.replace(/\/$/,``);return r===``||t.pathname===r||t.pathname.startsWith(`${r}/`)}function ft(e,t){if(!dt(e,t))return null;let n=ut(e).pathname.replace(/\/$/,``);return t.pathname.slice(n.length)||`/`}function pt(e){let t;try{t=new URL(e instanceof Request?e.url:String(e),window.location.href)}catch{return null}let n=Qe();return t.href===new URL(n.shared.bootstrapPath,window.location.href).href?{plane:`shared`,bootstrap:!0}:n.shared.transport===`relay`&&dt(n.shared,t)?{plane:`shared`,bootstrap:!1}:ft(n.machine,t)?.startsWith(`/api/machine/`)?{plane:`machine`,bootstrap:!1}:ft(n.shared,t)?.startsWith(`/api/`)?{plane:`shared`,bootstrap:!1}:t.href===new URL(n.machine.bootstrapPath,window.location.href).href?{plane:`machine`,bootstrap:!0}:null}function mt(e,t,n,r){let i=O(e),a=new Headers(n?.headers??(t instanceof Request?t.headers:void 0)),o=r===void 0?i.session.token:r,s=(n?.method??(t instanceof Request?t.method:`GET`)).toUpperCase();if(o&&a.set(`X-OpenCodex-API-Key`,o),o?.startsWith(`ocx_session_`)&&i.session.browserOrigin&&i.session.csrfToken&&(a.set(`X-OpenCodex-GUI-Origin`,i.session.browserOrigin),s!==`GET`&&s!==`HEAD`&&a.set(`X-OpenCodex-CSRF-Token`,i.session.csrfToken)),e===`shared`&&i.target.transport===`relay`){let e=O(`machine`).session;e.token&&a.set(Be,e.token),e.browserOrigin&&a.set(Ve,e.browserOrigin),s!==`GET`&&s!==`HEAD`&&e.csrfToken&&a.set(He,e.csrfToken)}return a}function ht(e,t,n,r){let i=mt(e,t,n,r);return t instanceof Request?[new Request(t,{headers:i}),n?{...n,headers:i}:void 0]:[t,{...n,headers:i}]}async function gt(e){if(!We)return{kind:`failed`};let t=O(e),n=Se(qe);try{let[r,i]=ht(e,t.target.bootstrapPath,{cache:`no-store`,signal:n.signal},null),a=await We(r,i);return a.ok?ct(e,await a.text())?{kind:`minted`,token:O(e).session.token}:{kind:`unavailable`}:a.status>=400&&a.status<500?{kind:`unavailable`}:{kind:`failed`}}catch{return{kind:`failed`}}finally{n.clear()}}async function _t(e,t){if(!We)return`unavailable`;try{let[n,r]=ht(e,`${O(e).target.baseUrl}${Le}`,{cache:`no-store`},t),i=await We(n,r);return i.status===401?`rejected`:i.ok?`accepted`:`unavailable`}catch{return`unavailable`}}async function vt(e,t,n){let r=O(e);if(r.promptCancelled||n?.aborted)return null;if(!r.resolutionInFlight){let n=(async()=>{let n=r.session.token;if(n&&n!==t)return n;let i,a=await Promise.race([gt(e),new Promise(e=>{i=setTimeout(()=>e({kind:`failed`}),Je)})]).finally(()=>clearTimeout(i));if(a.kind===`minted`)return a.token;if(a.kind===`failed`)return null;if(!Te())return r.promptCancelled=!0,null;let o=await Ke(t=>_t(e,t));return o?(r.session={token:o,csrfToken:null,browserOrigin:null,serverOrigin:r.target.serverOrigin},o):(r.promptCancelled=!0,null)})().finally(()=>{r.resolutionInFlight===n&&(r.resolutionInFlight=null)});r.resolutionInFlight=n}if(!n)return r.resolutionInFlight;let i,a=new Promise(e=>{i=()=>e(null),n.addEventListener(`abort`,i,{once:!0})});return Promise.race([r.resolutionInFlight,a]).finally(()=>{i&&n.removeEventListener(`abort`,i)})}function yt(){if(Ue)return;Ue=!0,lt(),Qe(),ot();let e=window.fetch.bind(window);We=e,window.fetch=async(t,n)=>{let r=pt(t);if(!r)return e(t,n);let i=O(r.plane),a=i.session.token,[o,s]=ht(r.plane,t,n),c=await e(o,s);if(r.bootstrap||c.status!==401)return c;let l=i.session.token;if(l&&l!==a){let[i,a]=ht(r.plane,t,n),o=await e(i,a);if(o.status!==401)return o;tt(r.plane,l)}else tt(r.plane,a);let u=n?.signal??(t instanceof Request?t.signal:void 0),d=await vt(r.plane,a,u??void 0);if(!d)return!u?.aborted&&!rt(r.plane)&&Xe(r.plane),c;let[f,p]=ht(r.plane,t,n,d),m=await e(f,p);return m.status===401&&(tt(r.plane,d),!u?.aborted&&!rt(r.plane)&&Xe(r.plane)),m}}function bt(e,t){let n=new URL(e);return![`http:`,`https:`].includes(n.protocol)||n.pathname!==`/v1/audio/transcriptions`||n.username||n.password||n.search||n.hash||t.method!==`POST`?Promise.reject(Error(`Invalid audio upload destination`)):(We??fetch)(n.href,{...t,credentials:`omit`,redirect:`error`})}var xt=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})),St=o(((e,t)=>{t.exports=xt()})),Ct=St();function wt({children:e}){let[t,n]=(0,_.useState)(()=>{let e=pe();return he(e),e}),r=(0,_.useCallback)(e=>{he(e),n(e)},[]);(0,_.useEffect)(()=>{let e=w.find(e=>e.code===t)??w[0];document.documentElement.lang=e.htmlLang;try{localStorage.setItem(`ocx-lang`,t)}catch{}},[t]);let i=(0,_.useCallback)((e,n)=>D(le[t][e]??y[e]??e,n),[t]),a=(0,_.useMemo)(()=>({locale:t,setLocale:r,t:i}),[t,i]);return(0,Ct.jsx)(E.Provider,{value:a,children:e})}function Tt({k:e,cmd:t,vars:n}){let{t:r}=ge(),[i,a=``]=r(e,n).split(`{cmd}`);return(0,Ct.jsxs)(Ct.Fragment,{children:[i,(0,Ct.jsx)(`code`,{className:`chip`,children:t}),a]})}var Et=`modulepreload`,Dt=function(e){return`/`+e},Ot={},k=function(e,t,n){let r=Promise.resolve();if(t&&t.length>0){let e=document.getElementsByTagName(`link`),i=document.querySelector(`meta[property=csp-nonce]`),a=i?.nonce||i?.getAttribute(`nonce`);function o(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}function s(e){return import.meta.resolve?import.meta.resolve(e):new URL(e,import.meta.url).href}r=o(t.map(t=>{if(t=Dt(t,n),t=s(t),t in Ot)return;Ot[t]=!0;let r=t.endsWith(`.css`);for(let n=e.length-1;n>=0;n--){let i=e[n];if(i.href===t&&(!r||i.rel===`stylesheet`))return}let i=document.createElement(`link`);if(i.rel=r?`stylesheet`:Et,r||(i.as=`script`),i.crossOrigin=``,i.href=t,a&&i.setAttribute(`nonce`,a),document.head.appendChild(i),r)return new Promise((e,n)=>{i.addEventListener(`load`,e),i.addEventListener(`error`,()=>n(Error(`Unable to preload CSS for ${t}`)))})}))}function i(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return r.then(t=>{for(let e of t||[])e.status===`rejected`&&i(e.reason);return e().catch(i)})},kt=window.location.hash.split(`?`)[0]===`#/tray`,At=(0,_.lazy)(()=>k(kt?()=>import(`./Tray-CLZh48fM.js`):()=>import(`./App-CH6C5H7x.js`),__vite__mapDeps([0,1])));kt&&yt(),v.createRoot(document.getElementById(`root`)).render((0,Ct.jsx)(_.StrictMode,{children:(0,Ct.jsx)(wt,{children:(0,Ct.jsx)(_.Suspense,{fallback:null,children:(0,Ct.jsx)(At,{})})})}));export{m as C,se as S,c as T,ge as _,bt as a,de as b,ct as c,Pe as d,we as f,me as g,w as h,et as i,it as l,Se as m,St as n,rt as o,Ae as p,Fe as r,yt as s,Tt as t,Ne as u,_e as v,u as w,ue as x,le as y};
86
+ Các thay đổi sẽ áp dụng cho các phiên (sessions) mới.`,"dash.multiAgent":`Agent con (Sub-agent)`,"dash.codexDesktopAuthless":`Mở Codex không cần đăng nhập`,"dash.codexDesktopAuthlessHint":`Mặc định tắt. Bỏ qua bước đăng nhập Desktop riêng cho các kết nối cục bộ hợp lệ. Vẫn cần thông tin xác thực upstream. Khởi động lại Codex sau khi thay đổi cài đặt này. Các tính năng Desktop yêu cầu tài khoản có thể không khả dụng.`,"dash.codexClientCompaction":`Sử dụng tính năng thu gọn phía client (client-side compaction)`,"dash.codexClientCompactionHint":`Mặc định tắt; chỉ dành cho authenticated loopback. Các compactions trong tương lai sẽ lưu trữ các bản tóm tắt văn bản thuần trong khi OpenCodeX và V2 provider routing vẫn hoạt động; provider được cấu hình có thể xử lý chúng và tiêu tốn quota. Lịch sử được giữ nguyên, và các luồng (threads) hiện tại tiếp tục định tuyến qua proxy thông qua ghi đè openai_base_url mà OpenCodeX quản lý; nếu bạn tự thiết lập dòng đó, nó sẽ được giữ lại và các luồng đó sẽ tuân theo đích đến của bạn thay thế. Lịch sử ocx1 hiện tại vẫn có thể khôi phục được; chỉ khôi phục một luồng riêng biệt trước khi phát lại (replay) trong Codex native. Khởi động lại Codex sau khi thay đổi cài đặt này.`,"models.v2Conflict":`[agents] max_threads đã được thiết lập — codex sẽ từ chối khởi động; hãy xoá nó khỏi config.toml`,"models.v2Applied":`Chế độ agent con đã được cập nhật — áp dụng cho các phiên mới (khởi động lại ứng dụng Codex để làm mới picker)`,"models.v2ThreadsLabel":`Luồng tối đa (Max threads)`,"models.v2ThreadsDefault":`mặc định (4)`,"models.v2ThreadsApplied":`Giới hạn luồng đã được cập nhật — áp dụng cho các phiên mới`,"models.v2ThreadsInvalid":`Giới hạn luồng phải là số nguyên >= 1`,"models.v2ThreadsApply":`Áp dụng`,"models.capValue":`Mặc định {value}`,"models.contextSettings":`Cửa sổ tuỳ chỉnh (Custom windows)`,"models.contextSettingsTitle":`Cửa sổ tuỳ chỉnh — {provider}`,"models.contextDefault":`Mặc định của provider`,"models.contextModel":`Model`,"models.contextModelOverride":`Ghi đè model`,"models.contextHint":`Ghi cửa sổ (window) Codex thực tế vào đây khi bạn đã biết nó. Việc này điền vào một cửa sổ upstream bị thiếu và chỉ làm giảm bớt nếu cửa sổ được báo cáo lớn hơn. Để trống để sử dụng cửa sổ/giới hạn Mặc định của provider, hoặc 128k nếu giới hạn đó đã bị tắt.`,"models.contextAutomatic":`Khám phá tự động (Automatic discovery)`,"models.contextSaved":`Cửa sổ ngữ cảnh (Context windows) đã được cập nhật — có hiệu lực ở lượt Codex tiếp theo.`,"models.contextUnchanged":`Không có thay đổi nào về cửa sổ ngữ cảnh để lưu.`,"models.contextSaveFailed":`Lỗi lưu cửa sổ ngữ cảnh`,"models.contextInvalid":`Cửa sổ ngữ cảnh phải là số nguyên dương`,"models.contextCappedValue":`giới hạn {value}`,"models.setAll":`Thiết lập tất cả`,"models.setAllHint":`Bật cửa sổ mặc định {value} cho mọi provider được định tuyến. Các relay bỏ qua context_window / context_length sẽ nhận giá trị này làm cửa sổ Codex thực tế. Sử dụng Cửa sổ tuỳ chỉnh trên một hàng provider để thiết lập một model bằng tay. Các native provider không bị ảnh hưởng.`,"models.collapseAll":`Thu gọn tất cả`,"models.expandAll":`Mở rộng tất cả`,"models.orderHint":`Thứ tự mặc định tuân theo các lựa chọn nổi bật và độ ưu tiên của catalog; các hàng định tuyến cùng hạng được sắp theo provider/model. Thứ tự picker đã lưu có thể thay đổi cách hiển thị; công tắc hiển thị lọc các hàng xuất hiện. Client có thể giữ catalog cũ cho đến lần tải tiếp theo.`,"models.custom":`Tuỳ chỉnh…`,"models.customApply":`Áp dụng`,"models.customPlaceholder":`Tokens (ví dụ: 420000)`,"models.customAdd":`Thêm model tuỳ chỉnh`,"models.customAddTitle":`Thêm model tuỳ chỉnh — {provider}`,"models.customEditTitle":`Chỉnh sửa model tuỳ chỉnh — {provider}`,"pws.manageModelVisibility":`Quản lý hiển thị trong Models`,"pws.modelOwnershipLoading":`Đang kiểm tra định nghĩa model…`,"pws.modelOwnershipFailed":`Không thể tải định nghĩa model. Hãy thử lại trước khi thay đổi.`,"pws.modelSelectionPending":`Hoàn tất việc chọn model trong Models trước khi thay đổi.`,"pws.modelSaved":`Định nghĩa model tuỳ chỉnh đã được lưu.`,"pws.modelSavedHidden":`Đã lưu định nghĩa. Model này đang bị ẩn; hãy quản lý hiển thị trong Models.`,"pws.modelSavedRefreshPending":`Đã lưu định nghĩa, nhưng không thể làm mới danh mục model (model catalog). Hãy thử làm mới lại; đừng thêm lại model đó.`,"pws.modelMutationUnconfirmed":`Không thể xác nhận thay đổi. Hãy làm mới danh sách model trước khi thử lại.`,"pws.modelRemovedRefreshPending":`Thay đổi đã được lưu, nhưng không thể làm mới danh mục model. Hãy thử làm mới lại.`,"pws.modelHidden":`Model đã ẩn. Khôi phục hiển thị trong Models.`,"pws.modelDefinitionDeleted":`Định nghĩa tuỳ chỉnh đã bị xoá. Một model cơ sở (underlying model) vẫn có thể xuất hiện.`,"pws.modelKnown":`Model này đã được nhận diện. Quản lý hiển thị của nó trong Models.`,"models.customAdded":`Đã thêm model tuỳ chỉnh`,"models.customUpdated":`Đã cập nhật model tuỳ chỉnh`,"models.customDeleted":`Đã xoá model tuỳ chỉnh`,"models.customSaveFailed":`Lỗi lưu model tuỳ chỉnh`,"models.customSaving":`Đang lưu…`,"models.customAddBtn":`Thêm`,"models.customEditBtn":`Cập nhật`,"models.customEdit":`Chỉnh sửa`,"models.customDelete":`Xóa`,"models.customDeleteConfirm":`Xoá định nghĩa tuỳ chỉnh cho {name}? Một model gốc hoặc được khám phá tự động có thể xuất hiện trở lại.`,"models.hide":`Ẩn`,"models.hideConfirm":`Ẩn {name} khỏi danh mục model? Điều này không xoá định nghĩa của nó hay thay đổi chính sách định tuyến trực tiếp.`,"models.customBadge":`Tùy chỉnh`,"models.customSummary":`{count} tuỳ chỉnh`,"models.customFieldModelId":`Model ID (endpoint slug)`,"models.customFieldModelIdPlaceholder":`ví dụ: qwen4-max-preview`,"models.customFieldDisplayName":`Tên hiển thị (không bắt buộc)`,"models.customFieldDisplayNamePlaceholder":`ví dụ: Qwen 4 Max Preview`,"models.customFieldContext":`Cửa sổ ngữ cảnh (Context window)`,"models.customFieldModalities":`Đầu vào (Input modalities)`,"models.customFieldReasoning":`Nỗ lực suy luận (Reasoning effort)`,"models.customFieldReasoningOverride":`Ghi đè nỗ lực suy luận (Override reasoning effort)`,"models.reasoningEffort.none":`Không có`,"models.reasoningEffort.minimal":`Tối thiểu (Minimal)`,"models.reasoningEffort.low":`Thấp (Low)`,"models.reasoningEffort.medium":`Trung bình (Medium)`,"models.reasoningEffort.high":`Cao (High)`,"models.reasoningEffort.xhigh":`Rất cao (Extra high)`,"models.reasoningEffort.max":`Tối đa (Maximum)`,"models.reasoningEffort.ultra":`Tối thượng (Ultra)`,"models.tipProvider":`Nhà cung cấp`,"models.tipContext":`Ngữ cảnh`,"models.tipModalities":`Đầu vào (Modalities)`,"models.tipStatus":`Trạng thái`,"models.tipActive":`Đang hoạt động`,"models.tipDisabled":`Đã tắt`,"models.applied":`Đã lưu trên hub. Việc client tải catalog và kích hoạt trong thời gian chạy là hai trạng thái riêng biệt.`,"models.integrationRefreshWarning":`Đã lưu lựa chọn model. Một số danh mục client không thể được làm mới. Hãy kiểm tra Integrations trước khi bắt đầu phiên mới.`,"models.saveFailed":`Lưu thất bại`,"models.networkError":`Lỗi mạng — proxy có đang chạy không?`,"models.loadFail":`Lỗi tải danh sách model — proxy có đang chạy không?`,"models.noRouted":`Không có model được định tuyến`,"models.noRoutedHint":`Vui lòng đăng nhập vào một provider hoặc thêm một model trước.`,"models.emptyDiscovery":`Không tìm thấy model nào. Hãy kiểm tra endpoint của provider hoặc thêm model tĩnh/tuỳ chỉnh.`,"models.emptyDiscoveryDisabled":`Tính năng khám phá model trực tiếp đang tắt và không có model tĩnh nào được cấu hình.`,"models.discoveryFailedBadge":`Khám phá thất bại`,"models.discoveryFailedHttp":`Khám phá model thất bại (HTTP {status}).`,"models.discoveryFailedBlocked":`Khám phá model bị chặn bởi chính sách đích.`,"models.discoveryFailedInvalidResponse":`Khám phá model trả về phản hồi không hợp lệ.`,"models.discoveryFailedNetwork":`Khám phá model thất bại do lỗi mạng.`,"models.discoveryFailedProvider":`Provider báo lỗi khám phá model.`,"models.discoveryFailedGeneric":`Khám phá model thất bại.`,"models.openProviderSettings":`Mở cài đặt provider`,"models.inactiveNoCredit":`Hết credit`,"models.inactiveNoCreditHint":`Mọi provider phía sau mục này hiện đều đã hết credit, do đó yêu cầu sẽ thất bại. Nó vẫn hiển thị trong danh sách và có thể sử dụng lại khi credit được đặt lại hoặc nạp thêm.`,"models.discoveryFailedDependency":`Tính năng khám phá model đang bật cho provider này. Trong khi tính năng này liên tục thất bại, hãy tắt “{control}” trong cài đặt provider để sử dụng các model được thêm thủ công hoặc model tĩnh để thay thế.`,"models.loading":`Đang tải…`,"models.search":`Tìm kiếm model…`,"models.showMore":`Hiển thị thêm {n}`,"models.freeOnly":`Chỉ miễn phí`,"models.noFreeMatch":`Không có model miễn phí ở đây. Tắt Chỉ miễn phí để xem phần còn lại.`,"models.allowlistLabel":`Chỉ các mục đã chọn`,"models.allowlistHint":`Chỉ các model được chọn mới gửi đến danh mục (để trống = tất cả). Hữu ích cho các provider cung cấp hàng nghìn model.`,"models.selectedCount":`Đã chọn {n}`,"sub.subtitle":`{cmd} của Codex chỉ quảng bá 5 model đầu tiên (theo mức độ ưu tiên) làm ghi đè (overrides). Chọn tối đa 5 model ở đây — native gpt hoặc routed — và opencodex sẽ đặt mức độ ưu tiên trong catalog của chúng để những model này dẫn đầu. Bất kỳ model nào khác vẫn có thể được gọi bằng đúng tên của nó; cài đặt này chỉ kiểm soát những gì được hiển thị.`,"sub.featured":`Nổi bật (Featured)`,"sub.advanced":`Nâng cao (Advanced)`,"sub.orderHintAria":`Cách thứ tự này được sử dụng`,"sub.orderHint":`Thứ tự hiển thị ở đây thiết lập các vị trí 1–5 ở đầu picker model của Codex và các model mặc định cho {cmd}.`,"sub.noneSelected":`Chưa chọn — hãy chọn từ danh sách bên dưới.`,"sub.models":`Models`,"sub.search":`Tìm kiếm model (native gpt + routed)…`,"sub.settings":`Cài đặt`,"sub.sections":`Các phần agent con (Subagent sections)`,"sub.delegation.model":`Model sẽ gọi đầu tiên`,"sub.delegation.modelHint":`Model mà Codex gọi đầu tiên khi bàn giao (hands off) công việc. Nổi bật bên trên là danh sách model nó có thể gọi; đây là model nó gọi đầu tiên.`,"sub.noModels":`Không có model — vui lòng đăng nhập vào provider hoặc thêm model trước.`,"sub.saved":`Đã lưu {n} model. Hãy bắt đầu phiên Codex mới (hoặc chạy {cmd}) để thấy chúng dưới dạng ghi đè spawn_agent.`,"sub.saveFailed":`Lưu thất bại`,"sub.networkError":`Lỗi mạng — proxy có đang chạy không?`,"sub.loadFail":`Lỗi tải model — proxy có đang chạy không?`,"sub.loading":`Đang tải…`,"sub.moveUp":`Di chuyển {m} lên`,"sub.moveDown":`Di chuyển {m} xuống`,"sub.removeAria":`Xoá {m}`,"sub.workspace.addToFeatured":`Thêm {m} vào phần Nổi bật`,"sub.workspace.allModels":`Tất cả model`,"sub.workspace.featuredFull":`Danh sách Nổi bật đã đầy (tối đa 5)`,"sub.workspace.mainAria":`Chi tiết model của agent con`,"sub.workspace.notFeatured":`Không nổi bật`,"sub.workspace.priority":`Ưu tiên`,"sub.ultraMode":`Luôn uỷ quyền chủ động`,"sub.ultraModeHint":`Bật chính sách uỷ quyền đa agent chủ động (Proactive multi-agent delegation) cho mọi model và nỗ lực suy luận (không làm thay đổi bản thân nỗ lực suy luận). Ghi thiết lập vào features.multi_agent_v2.multi_agent_mode_hint_text trong config.toml.`,"sub.ultraModeV2Required":`Yêu cầu giao diện đa agent v2 (v2 multi-agent surface) — bật multi_agent_v2 và chọn v2 trong trình điều khiển Chế độ agent con (Sub-agent mode) trước.`,"sub.ultraModeText":`Văn bản uỷ quyền chủ động`,"sub.ultraModePreset":`Khôi phục preset`,"sub.ultraModeLoadFail":`Lỗi tải cài đặt uỷ quyền chủ động — proxy có đang chạy không?`,"sub.ultraModeSaveFail":`Lỗi lưu cài đặt uỷ quyền chủ động`,"sub.ultraModeSaved":`Đã lưu uỷ quyền chủ động. Áp dụng cho các phiên Codex mới.`,"sub.workspace.removeFromFeatured":`Xoá {m} khỏi phần Nổi bật`,"sub.workspace.selectModel":`Chọn một model`,"sub.workspace.selectModelDesc":`Chọn một model từ danh sách để xem chi tiết và đưa nó vào danh sách nổi bật cho spawn_agent.`,"sub.workspace.selector":`Bộ chọn công khai (Public selector)`,"sub.fallbackLabel":`Chuỗi dự phòng của agent con`,"sub.fallbackHint":`Các model có thứ tự được thử nghiệm khi model agent con không khả dụng hoặc bị lỗi.`,"sub.fallbackAdd":`Thêm model dự phòng…`,"sub.fallbackPoll":`Khoảng thời gian kiểm tra khả dụng (Availability check interval)`,"sub.fallbackSaved":`Đã lưu cài đặt dự phòng của agent con.`,"sub.fallbackSaveFailed":`Lỗi lưu cài đặt dự phòng`,"sub.fallbackUnavailable":`Hiện không được quảng bá; vẫn được giữ trong chuỗi dự phòng.`,"sub.fallbackPollInvalid":`Vui lòng nhập một số nguyên từ 5000 đến 600000 ms.`,"sub.v2Compatibility.title":`Khả năng tương thích V2 của Native-parent`,"sub.v2Compatibility.risk":`Nếu model cha ChatGPT-native uỷ quyền cho model định tuyến (routed model) này bằng V2, task của nó có thể bị mã hoá và thất bại trước khi thực thi. Các task có thể đọc được từ model cha định tuyến không bị ảnh hưởng.`,"sub.v2Compatibility.recoveryUnknown":`Trạng thái bật phục hồi/đủ điều kiện không được tiết lộ bởi máy chủ này. Hãy dùng V1/uỷ quyền tương thích văn bản thuần (plaintext-compatible delegation), hoặc chỉ bật khôi phục V2 thử nghiệm (experimental V2 recovery) nếu đủ điều kiện. Khôi phục sẽ tăng thêm tiêu tốn quota, độ trễ, phụ thuộc backend và có khả năng làm giảm độ chính xác; nó không sửa được giao thức upstream.`,"sub.v2Compatibility.details":`Chi tiết tương thích`,"logs.title":`Nhật ký yêu cầu`,"logs.tabLogs":`Nhật ký`,"logs.tabDebug":`Gỡ lỗi`,"logs.subtitle":`Các request gần đây được định tuyến qua local opencodex proxy, mới nhất ở trên cùng.`,"logs.autoRefresh":`Tự động làm mới`,"logs.noRequests":`Chưa có request nào.`,"logs.loadError":`Không thể tải logs request.`,"logs.filter.surface.label":`Giao diện (Surface)`,"logs.filter.model.all":`Tất cả model`,"logs.filter.provider.label":`Nhà cung cấp`,"logs.filter.provider.all":`Tất cả provider`,"logs.filter.status.label":`Trạng thái`,"logs.filter.status.all":`Tất cả trạng thái`,"logs.filter.status.success":`Thành công (2xx)`,"logs.filter.status.errors":`Lỗi (4xx/5xx)`,"logs.filter.time.label":`Thời gian`,"logs.filter.time.all":`Tất cả thời gian`,"logs.filter.time.15m":`15 phút qua`,"logs.filter.time.1h":`1 giờ qua`,"logs.filter.time.24h":`1 ngày qua`,"logs.filter.speed.label":`Tốc độ`,"logs.filter.speed.all":`Tất cả tốc độ`,"logs.filter.speed.slow":`< 15 tok/s`,"logs.filter.speed.medium":`15–< 50 tok/s`,"logs.filter.speed.fast":`≥ 50 tok/s`,"logs.filter.reset":`Đặt lại bộ lọc`,"logs.filter.showingCount":`Đang hiển thị {count} / {total}`,"logs.noMatchingRequests":`Không có request nào phù hợp.`,"logs.filter.surface.all":`Tất cả`,"logs.filter.surface.claude":`Claude`,"logs.filter.surface.codex":`Codex`,"logs.filter.surface.grok":`Grok`,"logs.filter.interceptedHelpersOnly":`Chỉ helper bị chặn lại (Intercepted helpers only)`,"logs.badge.interceptedHelper":`I · {model}`,"logs.badge.interceptedHelperTitle":`Yêu cầu phụ trợ bị chặn`,"logs.filter.conversation.label":`Cuộc hội thoại`,"logs.filter.conversation.placeholder":`Dán id cuộc hội thoại`,"logs.filter.model.label":`Model`,"logs.filter.model.placeholder":`Lọc theo model hoặc provider`,"logs.filter.conversation.apply":`Lọc logs`,"logs.conversation.totals":`{requests} yêu cầu · {tokens} token · {cost}`,"logs.conversation.scope":`Tổng số liệu chỉ áp dụng cho bộ đệm Logs đang được tải.`,"logs.conversation.excluded":`(đã loại trừ {unpriced} không có giá, {unmetered} không đo lường khỏi khoản ước tính ~$)`,"logs.cost.approximate":`{amount}`,"logs.cost.lowerBound":`≥{amount}`,"logs.cost.unavailable":`—`,"logs.detail.conversation":`Cuộc hội thoại`,"logs.badge.claude":`Claude`,"logs.badge.grok":`Grok`,"logs.col.time":`Thời gian`,"logs.col.request":`Yêu cầu`,"logs.col.model":`Model`,"logs.col.effort":`Nỗ lực (Effort)`,"logs.col.provider":`Nhà cung cấp`,"logs.col.status":`Trạng thái`,"logs.col.tokens":`Tokens`,"logs.col.tokPerSec":`tok/s`,"logs.col.estimatedCost":`~$`,"logs.metric.tokPerSecTitle":`Số output token mỗi giây trên toàn bộ thời lượng request`,"logs.metric.estimatedCostTitle":`Mức tương đương giá niêm yết của API, không phải là mức phí thực tế; không khả dụng với giá không khớp`,"usage.cost.total":`Tương đương giá niêm yết API (phạm vi này)`,"usage.cost.disclaimer":`Đây không phải biên lai thanh toán. Mức sử dụng thuê bao hoặc credit của provider có thể được áp dụng thay thế.`,"usage.cost.unpricedNote":`Đã loại trừ {count} requests (không có giá hoặc mức sử dụng)`,"usage.cost.excluded":`({count} yêu cầu bị loại trừ)`,"usage.cost.excludedOne":`({count} yêu cầu bị loại trừ)`,"logs.detail.section.basic":`Thông tin cơ bản`,"logs.detail.route.section":`Quyết định định tuyến (Route decision)`,"logs.detail.route.kind":`Loại định tuyến (Route kind)`,"logs.detail.route.profile":`Profile`,"logs.detail.route.selected":`Đã chọn`,"logs.detail.route.candidates":`Ứng viên (Candidates)`,"logs.detail.route.unknown":`Không có dấu vết định tuyến (route trace) nào được ghi lại cho request này (pre-trace row).`,"logs.detail.section.performance":`Hiệu suất (Performance)`,"logs.detail.section.cost":`Mức tương đương giá niêm yết API`,"logs.detail.section.attempts":`Lượt thử kết hợp (Combo attempts)`,"logs.detail.section.usage":`Mức sử dụng thô (Raw usage)`,"logs.detail.ttft":`TTFT`,"logs.detail.decodeTokPerSec":`Tốc độ decode (ước tính)`,"logs.detail.reason.ttft_missing":`Không ghi nhận thời gian đến token đầu tiên (time-to-first-token) cho request này, nên không có cửa sổ decode nào để đo lường.`,"logs.detail.reason.decode_window_too_short":`Cửa sổ sau token đầu tiên nhỏ hơn một giây, quá ngắn để ước tính tốc độ decode.`,"logs.detail.costTotal":`Tương đương giá niêm yết`,"logs.detail.totalTokens":`Tổng số tokens`,"logs.detail.matchedKey":`Khoá giá trùng khớp (Matched price key)`,"logs.detail.priceSource":`Nguồn giá (Price source)`,"logs.detail.unavailableReason":`Lý do không khả dụng`,"logs.detail.copyRequestId":`Sao chép ID request`,"logs.detail.copied":`Đã sao chép`,"logs.detail.source.jawcode":`Danh mục jawcode`,"logs.detail.source.expected":`Giá niêm yết mong đợi (Expected price overlay)`,"logs.detail.source.user":`Giá tuỳ chỉnh của provider (Provider-configured price overlay)`,"logs.detail.verification.verified":`Đã xác minh (Verified)`,"logs.detail.verification.derived":`Bắt nguồn từ model cơ sở (Derived from base model)`,"logs.detail.attempt.target":`Nhà cung cấp / model`,"logs.detail.attempt.reason":`Kết quả / lý do`,"logs.detail.attempt.completed":`Đã hoàn thành`,"logs.detail.attempt.e2eNote":`Chỉ số tok/s tổng thể (top-level) là tính từ đầu đến cuối (end-to-end); mỗi lần thử (attempt) sử dụng thời lượng riêng của nó.`,"logs.detail.attempt.recovery.transient5xx":`Lỗi tạm thời 5xx (Transient 5xx)`,"logs.detail.attempt.recovery.connectionReset":`Kết nối bị đặt lại (Connection reset)`,"logs.detail.attempt.recovery.oauth401":`Xác thực lại OAuth (OAuth re-authentication)`,"logs.detail.attempt.recovery.key429":`Khoá bị giới hạn tỷ lệ (Key rate-limited 429)`,"logs.detail.attempt.recovery.rateLimit429":`Bị giới hạn tỷ lệ (Rate-limited 429)`,"logs.detail.attempt.recovery.anthropicOauth429":`Xác thực Anthropic OAuth bị giới hạn tỷ lệ (429)`,"logs.detail.attempt.recovery.image413":`Kích thước hình ảnh quá lớn (413)`,"logs.detail.attempt.recovery.emptyCompletion":`Thử lại do hoàn thành rỗng (Empty completion retry)`,"logs.detail.attempt.recovery.consoleGoUpload":`Thử lại tải lên Console`,"logs.detail.attempt.recovery.key401":`Xác thực lại khóa API`,"logs.detail.attempt.recovery.oauthAccount429":`Tài khoản bị giới hạn tần suất (429)`,"logs.detail.attempt.recovery.opaqueBlobRejection":`Đã bỏ trạng thái mã hóa cũ`,"logs.detail.attempt.recovery.reasoningEffortDowngrade":`Đã giảm mức suy luận`,"logs.detail.outcome.label":`Kết quả`,"logs.detail.outcome.completed":`Hoàn tất`,"logs.detail.outcome.failed":`Thất bại`,"logs.detail.outcome.incomplete":`Chưa hoàn tất`,"logs.detail.outcome.aborted":`Đã hủy`,"logs.detail.sends.label":`Số lần gửi lên nhà cung cấp`,"logs.detail.sends.unresolved":`chưa xác định`,"logs.detail.attempt.recovery.unknown":`Lý do khôi phục không rõ`,"logs.detail.cause.label":`Nguyên nhân lỗi`,"logs.detail.stage.label":`đã đến`,"logs.detail.resend.label":`Gửi lại`,"logs.detail.cause.transportUnsent":`Chưa gửi lên thượng nguồn`,"logs.detail.cause.transportAmbiguous":`Mất kết nối, không rõ trạng thái thượng nguồn`,"logs.detail.cause.upstreamDeclined":`Thượng nguồn từ chối bắt đầu`,"logs.detail.cause.rateLimit":`Bị giới hạn tốc độ`,"logs.detail.cause.quotaExhausted":`Đã hết hạn mức`,"logs.detail.cause.credentialRejected":`Thông tin xác thực bị từ chối`,"logs.detail.cause.policyRefusal":`Bị chính sách nội dung từ chối`,"logs.detail.cause.parameterRejected":`Tham số yêu cầu bị từ chối`,"logs.detail.cause.ciphertextRefusal":`Trạng thái mã hoá bị từ chối`,"logs.detail.cause.payloadTooLarge":`Tải trọng quá lớn`,"logs.detail.cause.payloadRejected":`Tải trọng bị từ chối`,"logs.detail.cause.upstreamFault":`Lỗi thượng nguồn`,"logs.detail.cause.emptyOutput":`Không có đầu ra dùng được`,"logs.detail.cause.clientCancelled":`Ứng dụng khách đã huỷ`,"logs.detail.cause.localRefusal":`Proxy này từ chối`,"logs.detail.stage.preHeader":`không có đầu phản hồi`,"logs.detail.stage.headersOnly":`chỉ có tiêu đề`,"logs.detail.stage.protocolPrelude":`phần mở đầu giao thức`,"logs.detail.stage.semanticOutput":`đã gửi đầu ra`,"logs.detail.stage.sideEffect":`đã phát sinh tác dụng phụ`,"logs.detail.stage.terminal":`đã gửi câu trả lời`,"logs.detail.resend.permitted":`Có thể gửi lại`,"logs.detail.resend.permittedAfterRepair":`Có thể gửi lại sau khi sửa`,"logs.detail.resend.refusedAmbiguous":`Không gửi lại: không rõ trạng thái thượng nguồn`,"logs.detail.resend.refusedCommitted":`Không gửi lại: bên gọi đã thấy đầu ra`,"logs.detail.resend.refusedFutile":`Không gửi lại: yêu cầu tương tự vẫn sẽ lỗi`,"logs.detail.reason.usage_missing":`Mức sử dụng không được báo cáo.`,"logs.detail.reason.usage_unsupported":`Provider này không báo cáo mức sử dụng.`,"logs.detail.reason.output_missing":`Không có số lượng output token dương nào được báo cáo.`,"logs.detail.reason.invalid_duration":`Thời lượng request không hợp lệ.`,"logs.detail.reason.price_unmatched":`Không tìm thấy giá khớp.`,"logs.detail.reason.invalid_cache_breakdown":`Chi tiết cache token không khớp với tổng số input token.`,"logs.detail.reason.invalid_usage":`Mức sử dụng chứa giá trị token không hợp lệ.`,"logs.detail.reason.combo_attempt_unavailable":`Ít nhất một lượt thử kết hợp (combo attempt) không thể định giá.`,"logs.detail.estimate.usage_estimated":`Mức sử dụng của provider được ước tính.`,"logs.detail.estimate.cache_detail_missing":`Chi tiết cache không khả dụng; đầu vào là ước tính giới hạn trên.`,"logs.detail.estimate.expected_price_overlay":`Một giá niêm yết kỳ vọng (expected list price) đã xác minh được sử dụng.`,"logs.detail.estimate.provider_cost_overlay":`Sử dụng giá tuỳ chỉnh do provider cấu hình.`,"logs.detail.estimate.priority_lower_bound":`Giá Ưu tiên (Priority price) đã xác nhận không khả dụng; ước tính hiển thị là giới hạn dưới đã biết.`,"logs.col.error":`Lỗi`,"logs.col.upstreamReason":`Lý do upstream`,"logs.col.duration":`Thời lượng`,"logs.modelTooltip.model":`model`,"logs.modelTooltip.resolvedModel":`model đã giải quyết (resolved model)`,"logs.modelTooltip.requestedTier":`bậc (tier) được yêu cầu`,"logs.modelTooltip.configuredTier":`bậc (tier) cấu hình`,"logs.modelTooltip.responseTier":`bậc (tier) phản hồi`,"logs.modelTooltip.supportsTier":`hỗ trợ tier`,"logs.modelTooltip.tierOutcome.confirmed":`đã xác nhận`,"logs.modelTooltip.tierOutcome.assumed":`giả định`,"logs.modelTooltip.tierOutcome.downgraded":`đã hạ bậc`,"logs.modelTooltip.tierOutcome.unknown":`không rõ`,"logs.tokens.reported":`đã báo cáo`,"logs.tokens.unreported":`không báo cáo`,"logs.tokens.unsupported":`không hỗ trợ`,"logs.tokens.estimated":`ước tính`,"logs.tokens.input":`input`,"logs.tokens.output":`output`,"logs.tokens.cacheRead":`cache read (c)`,"logs.tokens.cacheWrite":`cache write (w)`,"logs.tokens.reasoning":`reasoning`,"logs.tokens.noCache":`không có dữ liệu cache`,"logs.tokens.contextTotal":`tổng ngữ cảnh hoạt động`,"logs.tokens.noCacheNote":`provider này không báo cáo số lượng cache tokens`,"logs.tokens.noCacheCursor":`Chi tiết bộ nhớ cache của Cursor không được báo cáo`,"logs.tokens.noCacheCursorNote":`Cursor không tiết lộ số lượng cache read/write token; thông tin này chưa được biết (unknown), không phải là xác nhận cache miss`,"logs.tokens.estimatedNote":`ước tính (provider không báo cáo mức sử dụng chính xác)`,"logs.details":`Chi tiết`,"logs.detailTitle":`Chi tiết request`,"logs.detailRaw":`Mục log thô`,"debug.title":`Gỡ lỗi`,"debug.subtitle":`Chuẩn đoán (Diagnostics) về trích xuất mức sử dụng và luồng truyền (transport) của provider tuỳ chọn. Các request lỗi và 502 vẫn ở tab Logs.`,"debug.debug":`Debug của provider`,"debug.usage":`Trích xuất mức sử dụng`,"debug.injection":`Log can thiệp (Injection log)`,"debug.claude":`Claude đầu vào (Claude inbound)`,"debug.claudeInbound.title":`Các request đầu vào từ Claude`,"debug.claudeInbound.sub":`Những gì Claude Code/Desktop thực sự gửi (thinking, effort, metadata) — không có nội dung text của prompt nào được lưu.`,"debug.claudeInbound.empty":`Chưa thu được request nào. Hãy gửi một tin nhắn từ Claude trong khi tính năng này được bật.`,"debug.claudeInbound.time":`Thời gian`,"debug.claudeInbound.endpoint":`Endpoint`,"debug.claudeInbound.model":`Model`,"debug.claudeInbound.none":`không có`,"debug.reset":`Xoá các thay đổi runtime (runtime overrides)`,"debug.refresh":`Làm mới`,"debug.follow":`Theo dõi (Follow)`,"debug.streamProvider":`Nhà cung cấp`,"debug.streamUsage":`Mức sử dụng`,"debug.streamInjection":`Sự can thiệp (Injection)`,"debug.loading":`Đang tải cài đặt debug…`,"debug.loadFailed":`Không thể tải cài đặt debug.`,"debug.emptyTitle":`Ghi log debug đang tắt`,"debug.empty":`Bật Provider debug hoặc Trích xuất mức sử dụng (Usage extraction) trong thẻ bên trên. Các dòng log sẽ xuất hiện ở đây sau khi bạn gửi một request qua proxy.`,"debug.noLinesTitle":`Đang chờ dòng (Waiting for lines)`,"debug.noLines.provider":`Tính năng Provider debug đang bật, nhưng nó chỉ ghi lại những bất thường trong quá trình truyền dữ liệu (dropped or malformed frames, và các sự kiện quay số/thử lại của Cursor). Một request không lỗi qua provider như Anthropic có thể không tạo ra dòng nào.`,"debug.noLines.usage":`Trích xuất mức sử dụng đang bật nhưng chưa thu thập được dữ liệu. Gửi một chat/request thông qua Codex và log sẽ hiện ra ở đây.`,"debug.noLines.injection":`Log can thiệp (Injection log) đang bật nhưng chưa thu thập được dữ liệu. Tính năng này ghi lại các can thiệp về hướng dẫn đa agent (multi-agent guidance injection) và quyết định nỗ lực trong các lượt cộng tác (collab) hoặc qua agent con.`,"usage.title":`Mức sử dụng`,"usage.subtitle":`Quản lý token cục bộ (local token accounting) từ proxy của bạn. Mức sử dụng bị thiếu sẽ không bao giờ hiển thị bằng 0 (zero).`,"usage.loading":`Đang tải dữ liệu sử dụng…`,"usage.empty":`Chưa có mức sử dụng nào được ghi lại. Gửi một request qua proxy để thấy hoạt động ở đây.`,"usage.loadError":`Không thể tải dữ liệu sử dụng.`,"usage.range.all":`Tất cả`,"usage.range.available":`Lịch sử khả dụng`,"usage.historyTruncated":`Số tổng chỉ bao gồm lịch sử có sẵn vì các dữ liệu sử dụng cũ hơn không được tải.`,"usage.historyTruncatedWindow":`Các hàng được tải có thời gian bắt đầu (request start times) từ {start} đến {end}. Các mục file cũ hơn đã bị bỏ qua bởi giới hạn đọc (read limit), do đó bất kỳ phạm vi đã chọn nào cũng có thể không đầy đủ.`,"usage.range.30d":`30 ngày`,"usage.range.7d":`7 ngày`,"usage.card.requests":`Yêu cầu`,"usage.card.measured":`Đã đo lường (Measured)`,"usage.card.reported":`Đã báo cáo (Reported)`,"usage.card.totalTokens":`Tổng số tokens`,"usage.card.cachedTokens":`Đọc cache (Cache reads)`,"usage.card.cachedTokensHint":`Prompt tokens được phục vụ từ cache của provider (cache reads). Cache writes sẽ hiển thị bên dưới nếu có.`,"usage.card.cacheWriteTokens":`ghi cache (cache writes)`,"usage.card.coverage":`Độ phủ (Coverage)`,"usage.card.activeDays":`Số ngày hoạt động`,"usage.section.heatmap":`Hoạt động hàng ngày`,"usage.section.overview":`Tổng quan`,"usage.section.models":`Models`,"usage.section.providers":`Nhà cung cấp`,"usage.section.coverage":`Chi tiết độ phủ (Coverage breakdown)`,"usage.section.companion":`Thanh menu và widget`,"usage.companion.title":`Thanh menu và widget`,"usage.companion.description":`Các cài đặt ở đây điều khiển ứng dụng máy tính/thanh menu OpenCodex và widget của ứng dụng.`,"usage.companion.installGuide":`Hướng dẫn cài đặt`,"usage.companion.loading":`Đang tải dòng thời gian…`,"usage.companion.timelineUnavailable":`Không có dòng thời gian`,"usage.companion.empty":`Không có lượt dùng trong {hours} giờ qua`,"usage.companion.chartLabel":`Dòng thời gian sử dụng`,"usage.companion.olderRecordsSkipped":`Đã bỏ qua các bản ghi cũ hơn`,"usage.companion.settingsUnavailable":`Không có cài đặt companion`,"usage.companion.corrupt":`Tệp cài đặt companion bị hỏng. Các điều khiển hiển thị giá trị mặc định; việc lưu bị tạm dừng cho đến khi bạn thay thế tệp.`,"usage.companion.corruptReset":`Thay thế bằng mặc định`,"usage.companion.saved":`Đã lưu · {time}`,"usage.companion.saveFailed":`Không thể lưu: {error}`,"usage.companion.reset":`Đặt lại mặc định`,"usage.companion.footer":`Widget hiển thị số yêu cầu, token và chi phí hôm nay cùng biểu đồ được cấu hình ở đây, rồi làm mới khi ứng dụng thăm dò.`,"usage.companion.menuBarShows":`Thanh menu hiển thị`,"usage.companion.menuRequests":`Yêu cầu`,"usage.companion.menuTokens":`Token`,"usage.companion.menuCost":`Chi phí`,"usage.companion.menuQuota":`Hạn mức`,"usage.companion.menuNone":`Chỉ biểu tượng`,"usage.companion.window":`Khoảng thời gian`,"usage.companion.window6":`6 giờ`,"usage.companion.window24":`24 giờ`,"usage.companion.window72":`3 ngày`,"usage.companion.window168":`7 ngày`,"usage.companion.style":`Kiểu`,"usage.companion.styleLine":`Đường`,"usage.companion.styleStacked":`Xếp chồng`,"usage.companion.metric":`Chỉ số`,"usage.companion.metricTotal":`Tổng`,"usage.companion.metricInput":`Đầu vào`,"usage.companion.metricOutput":`Đầu ra`,"usage.companion.metricCached":`Đã lưu đệm`,"usage.companion.groupBy":`Nhóm theo`,"usage.companion.groupModel":`Mô hình`,"usage.companion.groupAccount":`Mô hình + tài khoản`,"usage.companion.popoverSections":`Mục popover`,"usage.companion.sectionToday":`Hôm nay`,"usage.companion.sectionChart":`Biểu đồ`,"usage.companion.sectionModels":`Mô hình`,"usage.companion.sectionCost":`Chi phí`,"usage.companion.sectionAccounts":`Tài khoản`,"usage.companion.advanced":`Nâng cao`,"usage.companion.aggregation":`Tổng hợp`,"usage.companion.aggregationSum":`Tổng`,"usage.companion.aggregationAverage":`Trung bình`,"usage.companion.aggregationMax":`Tối đa`,"usage.companion.menuText":`Văn bản thanh menu`,"usage.companion.placeholders":`Trình giữ chỗ:`,"usage.companion.modelsOnChart":`Mô hình trên biểu đồ`,"usage.companion.connected":`Ứng dụng trên thanh menu đã kết nối · {age}`,"usage.companion.connectedDesktop":`Ứng dụng máy tính đã kết nối · {age}`,"usage.companion.installTitle":`Cài đặt ứng dụng máy tính`,"usage.companion.installOs":`Hệ điều hành`,"usage.companion.osMac":`macOS`,"usage.companion.osWindows":`Windows`,"usage.companion.osLinux":`Linux`,"usage.companion.runningInDesktop":`Bạn đang ở trong ứng dụng máy tính OpenCodex {version}`,"usage.companion.openInBrowser":`Mở trong trình duyệt`,"usage.companion.installMacStep1":`Tải OpenCodex-<version>-macos.dmg từ bản phát hành mới nhất và kéo OpenCodex.app vào Applications.`,"usage.companion.installMacStep2":`Lần đầu mở: nhấp chuột phải vào OpenCodex.app → Mở (Gatekeeper sẽ hỏi một lần cho đến khi ứng dụng được công chứng).`,"usage.companion.installMacStep3":`Ứng dụng tự tìm proxy này; widget xuất hiện trong thư viện widget sau khi ứng dụng chạy.`,"usage.companion.installWinStep1":`Tải OpenCodex-<version>-windows-x64.msi từ bản phát hành mới nhất và chạy trình cài đặt.`,"usage.companion.installWinStep2":`Nếu SmartScreen cảnh báo, chọn Thông tin thêm → Vẫn chạy (trình cài đặt chưa được ký mã).`,"usage.companion.installWinStep3":`OpenCodex xuất hiện trong khay hệ thống và kết nối proxy này, hoặc khởi chạy proxy đi kèm.`,"usage.companion.installLinuxStep1":`Tải OpenCodex-<version>-linux-x86_64.AppImage (hoặc .deb) từ bản phát hành mới nhất.`,"usage.companion.installLinuxStep2":`Chạy chmod +x cho AppImage rồi mở; biểu tượng khay cần môi trường desktop hỗ trợ AppIndicator.`,"usage.companion.installLinuxStep3":`Ứng dụng kết nối proxy này hoặc khởi chạy proxy đi kèm.`,"usage.companion.notConnected":`Chưa có ứng dụng trên thanh menu nào kết nối với proxy này.`,"usage.companion.lastSeen":`Lần kết nối gần nhất {age}`,"usage.companion.installAnother":`Cài đặt trên thiết bị khác`,"usage.companion.modelsCount":`{selected}/{total} trên biểu đồ`,"usage.companion.modelsShowAll":`Hiện tất cả`,"usage.companion.hideProviders":`Ẩn nhà cung cấp`,"usage.workspace.report":`Báo cáo sử dụng`,"usage.workspace.sections":`Các phần sử dụng`,"usage.coverage.measured":`Đã đo`,"usage.coverage.reported":`Provider báo cáo`,"usage.coverage.estimated":`Ước tính`,"usage.coverage.note":`Các mục đo lường (Measured) bao gồm số lượng token ước tính và được báo cáo bởi provider. Các requests không có báo cáo hoặc không được hỗ trợ vẫn được theo dõi nhưng không bao giờ bị biến thành 0 token.`,"usage.search.models":`Tìm kiếm models…`,"usage.col.requests":`Yêu cầu`,"usage.col.measured":`Đã đo`,"usage.col.reported":`Đã báo cáo`,"usage.col.inputTokens":`Token đầu vào`,"usage.col.outputTokens":`Token đầu ra`,"usage.col.cacheHits":`Lượt truy cập cache`,"usage.col.cacheWrites":`Lần ghi cache`,"usage.col.cacheHitRate":`Tỷ lệ truy cập cache`,"usage.cacheHitRate.partial":`Giá trị trung bình được tính dựa trên {measured} trong tổng số {total} token đầu vào; các yêu cầu còn lại không cung cấp thông tin chi tiết về cache.`,"usage.cacheHitRate.unmeasured":`Không có yêu cầu nào trong hàng này cung cấp thông tin chi tiết về cache, nên không thể tính tỷ lệ truy cập cache trung bình.`,"usage.unavailable":`—`,"usage.col.tokens":`Tokens`,"usage.col.apiListPrice":`Giá niêm yết API`,"usage.col.share":`Tỷ trọng`,"usage.heatmap.less":`Ít`,"usage.heatmap.more":`Nhiều`,"usage.dayMon":`T2`,"usage.dayWed":`T4`,"usage.dayFri":`T6`,"usage.heatmap.tooltipTokens":`{tokens} token`,"usage.chart.dayDetail":`{date}: {requests} yêu cầu, {tokens} token`,"usage.heatmap.keyboardLabel":`Dùng phím Lên và Xuống để di chuyển theo ngày; Trái và Phải để di chuyển theo tuần.`,"usage.heatmap.tooltipRequests":`{requests} yêu cầu`,"nav.storage":`Lưu trữ`,"storage.title":`Lưu trữ`,"storage.subtitle":`Xem những gì đang chiếm dụng dung lượng trong CODEX_HOME. Việc dọn dẹp sẽ không bao giờ đụng đến các phiên (sessions) đang hoạt động.`,"storage.loading":`Đang quét lưu trữ…`,"storage.empty":`CODEX_HOME trống hoặc bị thiếu — không có gì để báo cáo.`,"storage.error":`Quét lưu trữ thất bại. Vui lòng kiểm tra CODEX_HOME có trỏ đến một thư mục hợp lệ không.`,"storage.refresh":`Quét lại (Rescan)`,"storage.rescanned":`Quét hoàn tất.`,"storage.card.total":`Tổng kích thước`,"storage.card.files":`Tệp (Files)`,"storage.card.home":`CODEX_HOME`,"storage.snapshot.lastScan":`Lần quét trước`,"storage.snapshot.scanning":`Đang quét…`,"storage.snapshot.unavailable":`Chưa có lượt quét nào.`,"storage.cleanupCard.title":`Giải phóng không gian lưu trữ`,"storage.cleanupCard.tabs":`Tuỳ chọn dọn dẹp`,"storage.cleanupCard.tab.policy":`Chính sách (Policy)`,"storage.cleanupCard.tab.quarantine":`Cách ly (Quarantine)`,"storage.cleanup.noArchives":`Không có phiên lưu trữ (archived sessions) nào để dọn dẹp.`,"storage.section.buckets":`Buckets`,"storage.section.largest":`Các tệp lớn nhất`,"storage.workspace.overview":`Tổng quan`,"storage.workspace.selectBucket":`Chọn một bucket từ danh sách để xem chi tiết.`,"storage.col.bucket":`Bucket`,"storage.col.size":`Kích thước`,"storage.col.files":`Số tệp`,"storage.col.oldest":`Cũ nhất`,"storage.col.newest":`Mới nhất`,"storage.col.rows":`Hàng trong DB (DB rows)`,"storage.rows.unknown":`không rõ (đang bị khoá)`,"storage.bucket.sessions":`Các phiên hoạt động (Active sessions)`,"storage.bucket.archived_sessions":`Các phiên đã lưu trữ (Archived sessions)`,"storage.bucket.logs_db":`Cơ sở dữ liệu logs`,"storage.bucket.state_db":`Cơ sở dữ liệu state`,"storage.bucket.attachments":`Tệp đính kèm (Attachments)`,"storage.bucket.deletion_manifests":`Manifests xoá`,"storage.bucket.other":`Khác`,"storage.cleanup.title":`Dọn dẹp lưu trữ (Archived cleanup)`,"storage.cleanup.help":`Xoá các phiên đã lưu trữ cũ nhất theo tỷ lệ phần trăm. Các phiên hoạt động không bao giờ bị đụng tới. Cách ly là mặc định — các tệp sẽ chuyển vào CODEX_HOME/.trash.`,"storage.cleanup.slider":`Phần trăm cũ nhất của lưu trữ`,"storage.cleanup.percent":`{percent}%`,"storage.cleanup.preset":`{percent}`,"storage.cleanup.preview":`Xem trước`,"storage.cleanup.confirmTitle":`Xác nhận dọn dẹp lưu trữ`,"storage.cleanup.confirmBody":`Thao tác này sẽ xử lý {count} tệp lưu trữ (~{size}), chiếm {percent}% cũ nhất.`,"storage.cleanup.moreFiles":`…và {n} tệp khác`,"storage.cleanup.permanent":`Xoá vĩnh viễn (bỏ qua cách ly)`,"storage.cleanup.permanentWarn":`Thao tác xoá vĩnh viễn không thể hoàn tác.`,"storage.cleanup.quarantineNote":`Các tệp sẽ được di chuyển vào .trash thuộc CODEX_HOME. Bạn có thể khôi phục chúng từ tab Cách ly.`,"storage.cleanup.cancel":`Hủy`,"storage.cleanup.confirmQuarantine":`Cách ly`,"storage.cleanup.confirmPermanent":`Xoá vĩnh viễn`,"storage.cleanup.doneQuarantine":`Đã cách ly {count} tệp ({size}).`,"storage.cleanup.donePermanent":`Đã xoá vĩnh viễn {count} tệp ({size}).`,"storage.cleanup.skippedReferenced":`Đã bỏ qua {count} tệp đang được tham chiếu.`,"storage.cleanup.previewFailed":`Xem trước thất bại.`,"storage.cleanup.cleanupFailed":`Dọn dẹp thất bại.`,"storage.cleanup.err.codex_busy":`Codex đang sử dụng state.sqlite — hãy thử lại sau khi thoát Codex.`,"storage.cleanup.err.stale_preview":`Các tệp lưu trữ đã thay đổi kể từ khi xem trước — hãy chạy lại tính năng Xem trước (Preview).`,"storage.cleanup.err.restore_pending_overlap":`Các lưu trữ đã chọn bị trùng với tiến trình khôi phục rác chưa hoàn tất — hãy kết thúc hoặc thử khôi phục lại trước.`,"storage.cleanup.err.referenced_history":`Các lưu trữ đã chọn vẫn đang được tham chiếu bởi lịch sử phân nhánh (forked) hoặc phân trang (paginated).`,"storage.cleanup.err.invalid_digest":`Mã xác nhận xem trước (Preview digest) bị thiếu hoặc không hợp lệ.`,"storage.cleanup.err.invalid_mode":`Chế độ dọn dẹp phải là cách ly (quarantine) hoặc xoá vĩnh viễn (permanent).`,"storage.cleanup.err.fs_failed":`Dọn dẹp hệ thống tệp thất bại. Một số thay đổi có thể đã được áp dụng — kiểm tra CODEX_HOME/.trash và bất kỳ đường dẫn khôi phục nào được hiển thị.`,"storage.cleanup.err.fs_failed_trash":`Dọn dẹp hệ thống tệp thất bại. Một số thay đổi có thể đã được áp dụng — kiểm tra {trashDir} và manifest.json để xem tệp có thể khôi phục.`,"storage.cleanup.err.db_reconcile_failed":`Không thể cập nhật cơ sở dữ liệu state của Codex.`,"storage.cleanup.err.cleanup_failed":`Dọn dẹp thất bại.`,"storage.trash.title":`Cách ly (Quarantine)`,"storage.trash.help":`Các phiên đã lưu trữ (Archived sessions) được di chuyển vào CODEX_HOME/.trash. Quá trình Khôi phục sẽ đặt các tệp JSONL và dữ liệu hàng (thread rows) trở lại.`,"storage.trash.empty":`Không có mục cách ly nào.`,"storage.trash.loading":`Đang tải vùng cách ly…`,"storage.trash.col.when":`Thời gian cách ly`,"storage.trash.col.files":`Tệp`,"storage.trash.col.size":`Kích thước`,"storage.trash.col.mode":`Chế độ`,"storage.trash.col.id":`Mục (Entry)`,"storage.trash.restore":`Khôi phục`,"storage.trash.confirmTitle":`Khôi phục mục cách ly?`,"storage.trash.confirmBody":`Khôi phục {count} tệp (~{size}) từ {id} về lại các phiên đã lưu trữ (archived sessions).`,"storage.trash.cancel":`Hủy`,"storage.trash.confirmRestore":`Khôi phục`,"storage.trash.done":`Đã khôi phục {count} tệp ({size}).`,"storage.trash.restoreFailed":`Khôi phục thất bại.`,"storage.trash.listFailed":`Không thể lấy danh sách các mục cách ly.`,"storage.trash.mode.quarantine":`cách ly`,"storage.trash.mode.permanent":`xoá vĩnh viễn (chưa hoàn thành)`,"storage.trash.err.codex_busy":`Codex đang sử dụng state.sqlite — hãy thử lại sau khi thoát Codex.`,"storage.trash.err.invalid_trash":`Id của mục trong thùng rác bị thiếu hoặc không hợp lệ.`,"storage.trash.err.missing_trash":`Không tìm thấy mục thùng rác.`,"storage.trash.err.dest_exists":`Đích khôi phục đã tồn tại — hãy xoá hoặc đổi tên tệp lưu trữ và thử lại.`,"storage.trash.err.fs_failed":`Khôi phục hệ thống tệp thất bại. Một số tệp có thể đã được khôi phục — hãy kiểm tra archived_sessions và .trash.`,"storage.trash.err.db_reconcile_failed":`Không thể khôi phục hàng (rows) của cơ sở dữ liệu Codex state.`,"storage.trash.err.storage_mutation_busy":`Có một quá trình dọn dẹp hoặc khôi phục lưu trữ khác đang chạy — vui lòng thử lại sau.`,"storage.trash.err.restore_failed":`Khôi phục thất bại.`,"storage.trash.err.restore_worker_timeout":`Quá trình khôi phục diễn ra quá lâu (hơn 10 phút) và đã bị dừng lại.`,"storage.trash.err.restore_worker_aborted":`Quá trình khôi phục đã bị huỷ trong lúc tắt máy (shutdown).`,"storage.trash.err.restore_worker_failed":`Worker khôi phục bị treo hoặc bị lỗi ngoài dự kiến.`,"storage.policy.title":`Chính sách dọn dẹp tự động`,"storage.policy.help":`Làm sạch hàng loạt (batch cleanup) tuỳ chọn khi số phiên lưu trữ vượt quá ngưỡng nhất định. Mặc định là tắt — không bao giờ tự động bật.`,"storage.policy.loading":`Đang tải chính sách…`,"storage.policy.loadFailed":`Không thể tải chính sách dọn dẹp.`,"storage.policy.saveFailed":`Không thể lưu chính sách dọn dẹp.`,"storage.policy.runFailed":`Lỗi khi chạy chính sách (Policy run failed).`,"storage.policy.alreadyRunning":`Một lượt chạy chính sách dọn dẹp (cleanup policy run) đang được thực thi.`,"storage.policy.invalid":`Giá trị của chính sách không hợp lệ.`,"storage.policy.enabled":`Bật dọn dẹp tự động`,"storage.policy.enabledHint":`Mặc định đang tắt. Khi bật, nó chỉ chạy theo lịch mà bạn đã chọn (hoặc khi bấm Chạy ngay bây giờ).`,"storage.policy.threshold":`Khi kích thước lưu trữ vượt quá (GiB)`,"storage.policy.trigger":`Kích hoạt (Trigger)`,"storage.policy.target":`Mục tiêu dọn dẹp`,"storage.policy.targetPercent":`Xoá phần trăm cũ nhất của phần lưu trữ (%)`,"storage.policy.targetReduce":`Giảm dung lượng lưu trữ xuống (GiB)`,"storage.policy.thresholdInc":`Tăng ngưỡng`,"storage.policy.thresholdDec":`Giảm ngưỡng`,"storage.policy.percentInc":`Tăng tỷ lệ phần trăm`,"storage.policy.percentDec":`Giảm tỷ lệ phần trăm`,"storage.policy.reduceInc":`Tăng kích thước được giảm xuống`,"storage.policy.reduceDec":`Giảm kích thước được giảm xuống`,"storage.policy.schedule":`Lịch biểu (Schedule)`,"storage.policy.schedule.manual":`Chỉ thủ công (Manual only)`,"storage.policy.schedule.startup":`Khi khởi động proxy`,"storage.policy.schedule.daily":`Hàng ngày`,"storage.policy.schedule.weekly":`Hàng tuần`,"storage.policy.mode":`Chế độ xoá (Deletion mode)`,"storage.policy.mode.quarantine":`Cách ly (mặc định)`,"storage.policy.mode.permanent":`Xoá vĩnh viễn`,"storage.policy.permanentWarn":`Chế độ xoá vĩnh viễn không thể hoàn tác. Khuyến khích sử dụng chế độ cách ly trừ khi bạn chắc chắn.`,"storage.policy.lastRun":`Chạy lần cuối (Last run)`,"storage.policy.lastRunDetail":`Đã xoá {count} · đã giải phóng {size}`,"storage.policy.nextRun":`Chạy lần tiếp`,"storage.policy.never":`Không bao giờ`,"storage.policy.save":`Lưu`,"storage.policy.runNow":`Chạy ngay (Run now)`,"storage.policy.running":`Đang chạy…`,"storage.policy.saved":`Chính sách đã được lưu.`,"storage.policy.skippedDisabled":`Chính sách đang tắt — vui lòng bật nó lên trước.`,"storage.policy.skippedUnder":`Kích thước lưu trữ vẫn dưới ngưỡng — không cần phải làm gì.`,"storage.policy.skippedEmpty":`Không có ứng viên lưu trữ nào phù hợp với mục tiêu.`,"storage.policy.doneQuarantine":`Chính sách đã cách ly {count} tệp ({size}).`,"storage.policy.donePermanent":`Chính sách đã xoá vĩnh viễn {count} tệp ({size}).`,"storage.policy.metadataSaveWarning":`Phiên chạy chính sách đã kết thúc, nhưng metadata lập lịch của nó không thể lưu được.`,"modal.addNamed":`Thêm: {label}`,"modal.add":`Thêm provider`,"modal.search":`Tìm Provider…`,"modal.logInWith":`Đăng nhập bằng {label}`,"modal.waitingBrowser":`Đang đợi trình duyệt…`,"modal.providerName":`Tên provider`,"modal.adapter":`Adapter`,"modal.baseUrl":`Base URL`,"modal.endpoint":`Endpoint`,"modal.endpoint.tokenPlan":`Gói token`,"modal.endpoint.payAsYouGo":`Dùng bao nhiêu trả bấy nhiêu`,"modal.endpoint.custom":`Tùy chỉnh`,"modal.defaultModel":`Model mặc định (tuỳ chọn)`,"modal.allowPrivateNetwork":`Cho phép mạng nội bộ/cá nhân`,"modal.allowPrivateNetworkHint":`Chỉ bật cho các provider tự host có chủ đích. Các endpoint metadata vẫn bị chặn.`,"modal.nameRequired":`Bắt buộc phải có tên provider`,"modal.baseUrlRequired":`Bắt buộc phải có Base URL`,"modal.networkError":`Lỗi mạng — proxy có đang chạy không?`,"modal.loginFailStart":`Không thể bắt đầu đăng nhập`,"modal.waitingLogin":`Đang đợi đăng nhập trên trình duyệt…`,"modal.loggingIn":`Đang đăng nhập…`,"modal.loginTimeout":`Đăng nhập quá thời gian — vui lòng thử lại.`,"modal.back":`Quay lại`,"modal.badge.oauth":`OAuth`,"modal.customProvider":`Provider tuỳ chỉnh`,"modal.failedStatus":`Thất bại ({status})`,"modal.loginError":`Lỗi đăng nhập: {error}`,"modal.badge.codexLogin":`Đăng nhập Codex`,"modal.badge.local":`Cục bộ`,"modal.badge.apiKey":`API key`,"modal.badge.direct":`Trực tiếp`,"modal.badge.pool":`Pool`,"modal.badge.free":`Miễn phí`,"modal.badge.sponsor":`Tài trợ`,"pws.sponsor.orcaTitle":`Một model cho mọi prompt`,"pws.sponsor.orcaDescription":`Gateway tương thích OpenAI với tính năng định tuyến thích ứng và tự động chuyển đổi dự phòng.`,"pws.sponsor.packyTitle":`Claude Code, Codex và Gemini tại một nơi`,"pws.sponsor.packyDescription":`Relay API cho các công cụ AI lập trình của bạn. Bắt đầu với token nhóm Codex.`,"pws.sponsor.visit":`Khám phá {provider}`,"pws.sponsor.console":`Mở console`,"modal.invalidPreset":`Preset của provider tích hợp này bị thiếu. Hãy khởi động lại proxy và thử lại.`,"modal.freeTierTitle":`Gói miễn phí`,"modal.freeTierDefault":`Không cần API key. Có thể sử dụng ngay.`,"modal.tab.accounts":`Tài khoản`,"modal.tab.free":`Miễn phí`,"modal.tab.local":`Cục bộ`,"modal.tab.paid":`Trả phí`,"modal.noteMore":`Hiển thị mô tả đầy đủ`,"modal.searchResults":`{count} kết quả trong {tiers}`,"modal.accountsHint":`Đăng nhập vào tài khoản ChatGPT/Codex, các provider OAuth, và tài khoản API key tại đây. OpenAI đã được tích hợp sẵn — vui lòng đăng nhập thay vì thêm mới.`,"modal.accountsCodexAuthLink":`Xác thực Codex`,"modal.notListed":`Không tìm thấy provider? Thêm provider tuỳ chỉnh`,"modal.catalogLoading":`Đang tải danh mục…`,"modal.accountLogin":`Đăng nhập`,"modal.accountLogout":`Đăng xuất`,"modal.accountAdd":`Thêm tài khoản`,"modal.accountManage":`Quản lý`,"modal.accountCodexPool":`Pool tài khoản ChatGPT`,"modal.accountLoggedIn":`Đã đăng nhập`,"modal.accountLoggedOut":`Chưa đăng nhập`,"quota.ageMinutes":`{n} phút`,"quota.ageHours":`{n} giờ`,"quota.ageDays":`{n} ngày`,"quota.observedAgo":`Ghi nhận {age} trước`,"quota.observedHint":`Meta chỉ báo cáo mức sử dụng trong quá trình phản hồi stream, vì vậy đây là giá trị cuối cùng ghi nhận được, không phải số liệu thời gian thực.`,"quota.weeklyLimit":`Giới hạn hàng tuần`,"quota.monthlyLimit":`Giới hạn 30 ngày`,"quota.cursorFirstParty":`Các model first-party`,"quota.cursorApiUsage":`Mức sử dụng API`,"quota.totalSubscriptionCredits":`Tổng credit gói đăng ký`,"quota.creditsBalance":`Số dư credit`,"quota.creditsPeriodEnds":`Chu kỳ thanh toán kết thúc vào {date}`,"quota.usedPercent":`Đã dùng {pct}%`,"quota.limitReached":`Đã đạt giới hạn`,"quota.resetsToday":`Đặt lại hôm nay lúc {time}`,"quota.resetsTomorrow":`Đặt lại ngày mai lúc {time}`,"quota.resetsAt":`Đặt lại vào {when}`,"quota.resetsRelativeMinutes":`Đặt lại sau {n} phút`,"quota.resetsRelativeHours":`Đặt lại sau {n} giờ`,"pws.status.ready":`Sẵn sàng`,"pws.status.needsSetup":`Cần thiết lập`,"pws.status.needsAttention":`Cần chú ý`,"pws.auth.chatgptPassthrough":`ChatGPT passthrough`,"pws.auth.noKey":`Không cần key`,"pws.freeTitle":`Giá miễn phí (vẫn có thể yêu cầu key)`,"pws.localTitle":`Runtime cục bộ`,"pws.modelCountOne":`1 model`,"pws.modelCount":`{count} model`,"pws.rail.suffixDefault":` · mặc định`,"pws.rail.suffixLocal":` · cục bộ`,"pws.rail.suffixFree":` · miễn phí`,"pws.rail.selectAria":`Chọn {name} — {status}{suffix}`,"pws.searchPlaceholder":`Tìm Provider…`,"pws.filterAria":`Lọc các provider`,"pws.providerFiltersAria":`Bộ lọc provider`,"pws.filters":`Bộ lọc`,"pws.filterStatus":`Trạng thái`,"pws.pricing":`Định giá`,"pws.paid":`Trả phí`,"pws.filterType":`Loại`,"pws.type.cloud":`Cloud`,"pws.type.local":`Cục bộ`,"pws.type.selfHosted":`Tự host`,"pws.type.login":`Đăng nhập`,"pws.sort":`Sắp xếp`,"pws.sortProvidersAria":`Sắp xếp các provider`,"pws.sort.az":`A–Z`,"pws.sort.za":`Z–A`,"pws.sort.freePaid":`Miễn phí trước`,"pws.sort.paidFree":`Trả phí trước`,"pws.sort.accountsFirst":`Tài khoản trước`,"pws.resetAll":`Đặt lại tất cả`,"pws.providerList":`Danh sách provider`,"pws.providersAria":`Nhà cung cấp`,"pws.groupReady":`Sẵn sàng ({count})`,"pws.groupNeedsSetup":`Cần thiết lập ({count})`,"pws.groupDisabled":`Đã vô hiệu hoá ({count})`,"pws.noSearchResults":`Không có provider nào khớp với tìm kiếm của bạn.`,"pws.noMatchFilters":`Không có provider nào khớp với các bộ lọc.`,"pws.noProvidersConfigured":`Chưa có provider nào được cấu hình.`,"pws.workspaceMainAria":`Chi tiết provider`,"pws.detailComingSoon":`Chế độ xem chi tiết sắp ra mắt — sử dụng chế độ xem cổ điển để quản lý provider này.`,"pws.selectPrompt":`Chọn một provider từ danh sách.`,"pws.connectFirst":`Kết nối provider đầu tiên của bạn`,"pws.empty.browseFree":`Duyệt các provider miễn phí`,"pws.empty.browseFreeDesc":`Bắt đầu mà không cần gói đăng ký`,"pws.empty.connectAccount":`Kết nối một tài khoản`,"pws.empty.connectAccountDesc":`Sử dụng đăng nhập ChatGPT hoặc provider của bạn`,"pws.empty.addEndpoint":`Thêm một endpoint`,"pws.empty.addEndpointDesc":`Base URL và API key tuỳ chỉnh`,"pws.tab.overview":`Tổng quan`,"pws.tab.models":`Models`,"pws.tab.usage":`Mức sử dụng`,"pws.tab.accounts":`Tài khoản`,"pws.tab.settings":`Cài đặt`,"pws.connection":`Kết nối`,"pws.status.connected":`Đã kết nối`,"pws.attentionTitle":`Cần chú ý`,"pws.attention.reauth":`Tài khoản đang hoạt động cần xác thực lại`,"pws.attention.reauthForward":`Tài khoản Codex đang hoạt động cần xác thực lại — hãy mở mục Accounts để khắc phục`,"pws.attention.missingCredentials":`Thiếu thông tin xác thực`,"pws.cell.auth":`Xác thực`,"pws.cell.note":`Ghi chú`,"pws.cell.defaultModel":`Model mặc định`,"pws.statsAria":`Thống kê provider`,"pws.statsTitle":`Thống kê`,"pws.stats.totalRequests":`Yêu cầu (30 ngày)`,"pws.stats.totalTokens":`Token (30 ngày)`,"pws.stats.quotaUpdated":`Đã cập nhật hạn mức`,"pws.stats.quotaTracked":`Giới hạn tốc độ được theo dõi trong tab Usage.`,"pws.stats.source":`Nguồn`,"pws.usageLast30d":`Mức sử dụng (30 ngày qua)`,"pws.estimatedCost":`Chi phí ước tính`,"pws.costDisclaimer":`Ước tính theo giá niêm yết của API, không phải là mức phí thực tế.`,"pws.unresolvedRequestedModel":`Bao gồm cả mức sử dụng model được yêu cầu chưa giải quyết`,"pws.currentAccountUsage":`Mức sử dụng tài khoản hiện tại`,"pws.quotaUnsupported":`Tra cứu hạn mức không được hỗ trợ cho tài khoản này.`,"pws.quotaUnobserved":`Chưa có dữ liệu sử dụng nào được ghi nhận.`,"pws.quotaCheckCompleted":`Đã hoàn thành kiểm tra hạn mức`,"pws.modelBreakdown":`Chi tiết theo model`,"pws.col.model":`Model`,"pws.col.cost":`Chi phí ước tính`,"pws.col.tokens":`Tokens`,"pws.col.requests":`Yêu cầu`,"pws.col.share":`Tỷ lệ`,"pws.tokenInput":`Đầu vào`,"pws.tokenOutput":`Đầu ra`,"pws.metricRequests":`yêu cầu`,"pws.metricTokens":`tokens`,"pws.usageUnavailable":`Chưa có mức sử dụng nào được ghi nhận.`,"pws.rateLimits":`Giới hạn tốc độ`,"pws.quotaUnavailable":`Không có dữ liệu hạn mức cho provider này.`,"pws.accountQuotaUnavailable":`Dữ liệu giới hạn tốc độ tạm thời không khả dụng; đang hiển thị các giá trị cuối cùng được biết đến (nếu có).`,"pws.quotaFailure.account_unavailable":`Không có thông tin tài khoản cho lần kiểm tra hạn ngạch này.`,"pws.quotaFailure.access_denied":`Nhà cung cấp đã từ chối quyền truy cập dữ liệu hạn ngạch.`,"pws.quotaFailure.rate_limited":`Nhà cung cấp đã giới hạn tốc độ kiểm tra hạn ngạch.`,"pws.quotaFailure.upstream_error":`Nhà cung cấp không thể hoàn tất kiểm tra hạn ngạch.`,"pws.quotaFailure.redirect_blocked":`Endpoint hạn ngạch trả về một chuyển hướng bị chặn.`,"pws.quotaFailure.destination_blocked":`Đích hạn ngạch bị chính sách mạng chặn.`,"pws.quotaFailure.dns_failed":`Không thể phân giải hostname hạn ngạch.`,"pws.quotaFailure.timeout":`Yêu cầu hạn ngạch đã hết thời gian chờ.`,"pws.quotaFailure.transport_error":`Kết nối hạn ngạch thất bại.`,"pws.quotaFailure.response_unusable":`Nhà cung cấp trả về dữ liệu hạn ngạch không thể sử dụng.`,"pws.selected":`Đã chọn`,"pws.copyModelId":`Sao chép ID`,"pws.modelCopied":`Đã sao chép!`,"pws.modelsAvailable":`{count} model khả dụng`,"pws.modelSearchPlaceholder":`Lọc các model…`,"pws.modelsLoading":`Đang tải các model…`,"pws.modelsLoadFailed":`Không thể tải các model.`,"pws.modelsNeedsReauth":`Tài khoản cần đăng nhập lại trước khi tính năng khám phá model trực tiếp có thể hoạt động. Tạm thời hiển thị các model đã cấu hình.`,"pws.modelsConfiguredFallback":`Đang hiển thị các model đã cấu hình (tính năng khám phá trực tiếp không khả dụng).`,"pws.modelsTruncated":`Đang hiển thị {shown} model đầu tiên trong tổng số {total} model. Hãy sử dụng bộ lọc để thu hẹp danh sách.`,"pws.retry":`Thử lại`,"pws.noModels":`Không phát hiện model nào cho provider này.`,"pws.adapterBaseRequired":`Bắt buộc phải có Adapter và Base URL.`,"pws.addAccount":`Thêm tài khoản`,"pws.addKey":`Thêm API key`,"pws.apiKeys":`API Keys`,"pws.authMode":`Chế độ xác thực`,"pws.availableAccounts":`Các tài khoản khả dụng`,"pws.accountOrdinal":`Tài khoản {count}`,"pws.accountsLoading":`Đang tải các tài khoản…`,"pws.accountsLoadFailed":`Không thể tải các tài khoản.`,"pws.retryAccounts":`Thử lại`,"pws.noAccounts":`Chưa có tài khoản nào được kết nối.`,"pws.cockpitImportDescription":`Nhập tệp xuất Cockpit Tools Antigravity dạng JSON từ thiết bị này. Nội dung tệp sẽ không được hiển thị.`,"pws.cockpitImportFileLabel":`Tệp xuất JSON từ Cockpit Tools Antigravity`,"pws.cockpitImportChooseFile":`Chọn tệp JSON`,"pws.cockpitImporting":`Đang nhập…`,"pws.cockpitImportInvalid":`Tệp đã chọn không phải là tệp xuất JSON hợp lệ hoặc có kích thước quá lớn.`,"pws.cockpitImportFailed":`Không thể hoàn thành việc nhập tài khoản.`,"pws.cockpitImportComplete":`Đã nhập xong: {imported} được nhập, {updated} được cập nhật, {failed} thất bại, {unsupported} không được hỗ trợ.`,"pws.accountSwitching":`Đang chuyển…`,"pws.accountCurrent":`Tài khoản hiện tại`,"pws.defaultModelNone":`Không có (sử dụng mặc định của provider)`,"pws.discardSettings":`Huỷ bỏ`,"pws.jsonEditorDesc":`Chỉnh sửa config dạng JSON thô của provider. Các thay đổi sẽ được lưu ngay lập tức.`,"pws.jsonEditorTitle":`Trình chỉnh sửa JSON — {name}`,"pws.jsonRestore":`Khôi phục`,"pws.jsonSave":`Lưu`,"pws.loggedInTitle":`Đã đăng nhập`,"pws.notLoggedInTitle":`Chưa đăng nhập`,"pws.note":`Ghi chú`,"pws.allowPrivateNetwork":`Cho phép mạng nội bộ/cá nhân`,"pws.liveModels":`Khám phá các model từ provider`,"pws.liveModelsDesc":`Lấy danh mục model trực tiếp từ provider. Hãy tắt tuỳ chọn này nếu chỉ muốn sử dụng các model đã cấu hình/tĩnh.`,"pws.xaiChatOptIn":`Sử dụng Chat Completions cho Grok 4.5 và 4.6`,"pws.xaiChatOptInDesc":`Tắt để chọn Responses. Các yêu cầu OAuth Responses sử dụng tuỳ chọn này theo mặc định. Các model Grok khác và hành vi của gói không bị ảnh hưởng.`,"pws.xaiChatOptInMixed":`Chỉ có một model sử dụng Chat.`,"pws.cursorTransport":`Cursor transport`,"pws.cursorTransportHttp2":`HTTP/2 (mặc định)`,"pws.cursorTransportHttp1":`HTTP/1.1 (tương thích với proxy)`,"pws.cursorTransportDesc":`Sử dụng HTTP/1.1 khi proxy của bạn không thể truyền stream HTTP/2 của Cursor một cách đáng tin cậy.`,"pws.optionalPlaceholder":`Tuỳ chọn`,"pws.providerId":`ID provider`,"pws.reauth":`Cần xác thực lại`,"pws.reauthenticate":`Xác thực lại`,"pws.copyDoctor":`Sao chép ocx doctor`,"pws.doctorCopied":`Đã sao chép`,"pws.doctorCopyUnavailable":`Clipboard không khả dụng`,"pws.healthCooldownHint":`Đợi cho đến khi thời gian chờ kết thúc. Không thăm dò tài khoản này ngay bây giờ.`,"pws.healthLabel.rateLimited":`Bị giới hạn tốc độ`,"pws.healthLabel.quotaLimited":`Bị giới hạn hạn mức`,"pws.healthLabel.reauthRequired":`Yêu cầu xác thực lại`,"pws.healthLabel.refreshFailed":`Làm mới thất bại`,"pws.healthLabel.metadataMismatch":`Metadata không khớp`,"pws.healthLabel.validationPending":`Đang chờ xác thực`,"pws.healthSummary.validationPending":`{provider} {account}: được đăng ký trong khi bị giới hạn hạn mức. Sau khi hạn mức phục hồi, hãy làm mới hạn mức để chạy một yêu cầu xác thực nhỏ. Định tuyến sẽ bị vô hiệu hoá cho đến khi thành công.`,"pws.healthLabel.credentialConflict":`Xung đột thông tin xác thực`,"pws.healthSummary.rateLimited":`{provider} {account}: bị giới hạn tốc độ cho đến {until}. Quá trình định tuyến cho tài khoản này sẽ bị tạm dừng cho đến lúc đó.`,"pws.healthSummary.quotaLimited":`{provider} {account}: bị giới hạn hạn mức cho đến {until}. Quá trình định tuyến cho tài khoản này sẽ bị tạm dừng cho đến lúc đó.`,"pws.healthSummary.reauthRequired":`{provider} {account}: yêu cầu xác thực lại.`,"pws.healthSummary.credentialConflict":`{provider} {account}: có xung đột thông tin xác thực.`,"pws.healthSummary.metadataMismatch":`{provider} {account}: metadata không khớp.`,"pws.healthSummary.staleCredentials":`{provider} {account}: thông tin xác thực không đầy đủ.`,"pws.removeConfirm":`Xóa`,"pws.removeConfirmBody":`Xoá provider \\"{name}\\"? Hành động này không thể hoàn tác.`,"pws.removeDefaultConfirmBody":`Xoá provider mặc định \\"{name}\\"? \\"{defaultProvider}\\" sẽ trở thành provider mặc định. Hành động này không thể hoàn tác.`,"pws.removeConfirmTitle":`Xóa Provider`,"pws.saveSettings":`Lưu`,"pws.pacingTitle":`Pacing của yêu cầu`,"pws.pacingDesc":`Đồng đều trì hoãn thời điểm bắt đầu yêu cầu ra ngoài cho provider này. Các phản hồi stream có thể chồng chéo.`,"pws.pacingEnabled":`Đã bật`,"pws.pacingRpm":`Yêu cầu mỗi phút`,"pws.pacingRpmUnit":`RPM`,"pws.pacingDelay":`Khoảng thời gian tối thiểu (ms)`,"pws.pacingSlowerWins":`Giới hạn provider chậm hơn sẽ được ưu tiên. Ghi đè model chỉ có thể làm tăng thêm độ trễ.`,"pws.pacingQueued":`đã xếp hàng`,"pws.pacingNextSlot":`cho đến slot tiếp theo`,"pws.pacingLastModel":`model cuối cùng`,"pws.pacingNone":`Không có`,"pws.pacingModelOverrides":`Ghi đè model`,"pws.pacingModel":`Model`,"pws.pacingAdd":`Thêm ghi đè`,"pws.pacingRemove":`Xóa`,"pws.pacingRemoveModel":`Xoá ghi đè pacing yêu cầu cho {model}`,"pws.pacingRuleRequired":`Chỉ bật pacing yêu cầu sau khi đã thiết lập giới hạn provider hoặc một ghi đè model.`,"pws.saving":`Đang lưu…`,"pws.settingsSaved":`Đã lưu cài đặt.`,"pws.accountModeSaved":`Đã lưu chế độ tài khoản.`,"pws.accountModeFailed":`Không thể chuyển chế độ tài khoản.`,"pws.accountModeConfirm":`Chuyển chế độ tài khoản OpenAI? Các cuộc hội thoại đang chạy sẽ được gán lại cho bộ tài khoản của chế độ khác, và mức sử dụng hạn mức sẽ được theo dõi trên chế độ mới.`,"pws.settingsUnsavedBar":`Bạn có các thay đổi chưa lưu.`,"pws.unsavedLeaveBody":`Bạn có các thay đổi chưa lưu. Lưu chúng lại trước khi rời đi?`,"pws.unsavedLeaveTitle":`Thay đổi chưa lưu`,"pws.attentionRequired":`Cần sự chú ý`,"pws.attentionAria":`{name}: {reason}`,"pws.missingCredentials":`Thiếu thông tin xác thực`,"pws.editJsonDesc":`Chỉnh sửa config proxy thô dưới dạng JSON`,"pws.updatesUnavailable":`Các bản cập nhật của provider hiện không khả dụng.`,"pws.dashboard.title":`Tổng quan các provider`,"pws.dashboard.subtitle":`Quản lý tất cả các model provider của bạn tại một nơi.`,"pws.dashboard.rateLimits":`GIỚI HẠN TỐC ĐỘ`,"pws.capacity.estimate":`Ước tính pool theo trọng số đã định cấu hình`,"pws.capacity.currentAccount":`Tài khoản đang có hiệu lực hiện tại`,"pws.capacity.nextRecovery":`Lần phục hồi năng lực tiếp theo`,"pws.capacity.recoveryShare":`+{percent}% năng lực của pool`,"pws.capacity.incomplete":`Độ phủ không đầy đủ: Đã loại trừ {excluded} tài khoản`,"pws.capacity.uncalibratedPlan":`{count} tài khoản thuộc gói chưa được hiệu chuẩn sẽ được tính ở mức trọng số ghế tiêu chuẩn, do đó ước tính này có thể là bảo thủ`,"pws.capacity.partial":`Độ phủ window bán phần: {count} tài khoản không báo cáo mọi limit window được hiển thị`,"pws.capacity.windowPartial":`Bán phần`,"pws.capacity.windowPartialA11y":`{window}: độ phủ tài khoản không đầy đủ`,"pws.dashboard.recentlyUsed":`SỬ DỤNG GẦN ĐÂY`,"pws.dashboard.requests":`{count} yêu cầu`,"pws.dashboard.checkedAgo":`Đã kiểm tra {time}`,"pws.dashboard.noQuota":`Không có dữ liệu hạn mức`,"pws.dashboard.noUsage":`Chưa có dữ liệu sử dụng`,"pws.dashboard.noRateLimits":`Chưa có dữ liệu giới hạn tốc độ`,"pws.allProviders":`Tổng quan Provider`,"pws.enabledLabel":`Đã bật`,"pws.testConnection":`Kiểm tra kết nối`,"pws.testing":`Đang kiểm tra…`,"pws.connectionOk":`Kết nối OK`,"pws.connectionFailed":`Kết nối thất bại`,"pws.connectionNotApplicable":`Không áp dụng — provider này sử dụng danh mục model tĩnh.`,"pws.editSettings":`Chỉnh sửa cài đặt`,"pws.viewUsage":`Xem chi tiết mức sử dụng`,"pws.allSystemsOk":`Tất cả các hệ thống đều hoạt động`,"pws.apiKeyConfigured":`Đã cấu hình API key`,"pws.addApiKey":`Thêm API key`,"pws.loggedInAs":`Đã đăng nhập với tư cách {email}`,"pws.notLoggedIn":`Chưa đăng nhập`,"pws.passthrough":`Codex passthrough`,"pws.notes":`GHI CHÚ`,"pws.notePlaceholder":`Thêm ghi chú về provider này...`,"pws.noteSaved":`Đã lưu ghi chú`,"pws.authSummary":`XÁC THỰC`,"time.justNow":`Vừa xong`,"time.notChecked":`Chưa kiểm tra`,"time.minutesAgo":`{n} phút trước`,"time.hoursAgo":`{n} giờ trước`,"time.daysAgo":`{n} ngày trước`,"modal.noMatch":`Không khớp.`,"modal.oauthDefaultNote":`Đăng nhập bằng tài khoản của bạn — không cần API key.`,"modal.oauthComingSoon":`Đăng nhập OAuth cho {label} sẽ có trong bản cập nhật tới. Tạm thời hãy sử dụng API key.`,"modal.oauthComingSoonShort":`Đăng nhập OAuth cho provider này sẽ có trong bản cập nhật tới — tạm thời hãy sử dụng API key.`,"modal.useApiKeyInstead":`Thay vào đó hãy sử dụng API key`,"modal.setupGuide":`Hướng dẫn thiết lập`,"modal.setupStep1Prefix":`Truy cập`,"modal.setupDashboardLink":`bảng điều khiển {label}`,"modal.setupStep1Suffix":`và sao chép API key của bạn`,"modal.setupStep2":`Dán vào trường API key bên dưới`,"modal.setupStep3":`Nhấp vào Thêm provider — các model sẽ được tự động khám phá`,"modal.namePlaceholder":`vd: openrouter`,"modal.duplicateWarn":`Provider \\"{name}\\" đã tồn tại và sẽ bị ghi đè.`,"modal.forwardHintPrefix":`Không cần key — proxy sẽ chuyển tiếp`,"modal.forwardCredentials":`đăng nhập codex`,"modal.forwardHintSuffix":`thông tin xác thực của bạn đến provider này.`,"modal.localHint":`Không lưu trữ API key. Thao tác này sẽ thêm danh mục model công khai tĩnh của Cursor cho Codex, nhưng transport trực tiếp của Cursor và tính năng thực thi file/shell native vẫn bị vô hiệu hoá cho đến khi được kiểm toán.`,"modal.getApiKey":`Lấy API key {label} của bạn`,"modal.apiKey":`API key`,"modal.apiKeyTransport":`API key header`,"modal.apiKeyTransportNative":`x-api-key (Anthropic native)`,"modal.apiKeyTransportBearer":`Authorization: Bearer`,"modal.apiKeyPlaceholder":`sk-… (hoặc $ENV_VAR)`,"modal.defaultModelPlaceholder":`vd: gpt-5.5`,"modal.baseUrlPlaceholderError":`Base URL có chứa {placeholder} chưa được giải quyết. Thay thế bằng giá trị thực tế của bạn.`,"modal.baseUrlPlaceholderHint":`Hãy thay thế {placeholder} trong Base URL bằng Account ID thực tế của bạn trước khi thêm.`,"modal.adding":`Đang thêm…`,"modal.useOauthLogin":`← Sử dụng đăng nhập OAuth`,"nav.codexSet":`Cài đặt Codex`,"codexSet.tab.multiauth":`Đa xác thực`,"codexSet.tab.prompt":`Prompt`,"codexSet.prompt.title":`Prompt layer`,"codexSet.prompt.timing":`Áp dụng cho các phiên mới bắt đầu. Các phiên đang chạy sẽ giữ nguyên cài đặt prompt hiện tại của chúng.`,"codexSet.prompt.staleRevision":`Cấu hình đã thay đổi ở nơi khác. Danh sách đã được tải lại.`,"codexSet.prompt.repair":`Sửa chữa`,"codexSet.prompt.repairFailed":`Không thể hoàn thành việc sửa chữa.`,"codexSet.drift.journalPresent":`Một tác vụ ghi trước đó chưa hoàn thành. Quá trình phục hồi sẽ tự động chạy ở lần ghi tiếp theo.`,"codexSet.drift.projectionStale":`Các layer đã lưu và giá trị trong config.toml không khớp nhau. Sửa chữa sẽ ghi lại giá trị từ các layer của bạn.`,"codexSet.drift.storeMissing":`Tệp layer đã biến mất trong khi các chỉ thị vẫn còn trong config.toml. Sửa chữa sẽ giữ phần văn bản này như một layer và sẽ ghi một bản sao lưu trước.`,"codexSet.drift.ownedMalformed":`Dòng mã được sinh ra trong config.toml đã bị định dạng lại thủ công, nên không còn an toàn để ghi đè.`,"codexSet.custom.adoptUnsupported":`Giá trị tại {path} dòng {line} không phải là chuỗi một dòng, do đó không thể nhập. Di chuyển bằng tay để quản lý tại đây.`,"codexSet.prompt.unreadable":`Tệp config Codex tồn tại nhưng không thể đọc được, vì vậy các thay đổi sẽ bị từ chối.`,"codexSet.layer.permissions":`Quyền truy cập`,"codexSet.layer.collaboration":`Chế độ cộng tác`,"codexSet.layer.environment":`Bối cảnh môi trường`,"codexSet.layer.apps":`Ứng dụng`,"codexSet.group.transition":`Thông báo chuyển tiếp`,"codexSet.group.transitionDesc":`Các thông báo này thông báo về một sự thay đổi thay vì mô tả trạng thái, vì vậy chúng chỉ xuất hiện khi phiên chuyển sang trạng thái realtime hoặc chuyển model.`,"codexSet.custom.slotNote":`Các layer tuỳ chỉnh được nối thành một phần theo thứ tự này.`,"codexSet.row.onChange":`Kích hoạt khi thay đổi`,"codexSet.row.openFeatures":`Mở cài đặt`,"codexSet.dialog.setValue":`{value} (mặc định {fallback})`,"codexSet.custom.heading":`Layer tuỳ chỉnh`,"codexSet.custom.add":`+ Thêm layer`,"codexSet.custom.newTitle":`Layer mới`,"codexSet.custom.editTitle":`Chỉnh sửa layer`,"codexSet.custom.titleLabel":`Tiêu đề`,"codexSet.custom.bodyLabel":`Chỉ thị`,"codexSet.custom.bodySize":`{bytes} trên {max} byte`,"codexSet.custom.normalized":`Tab đã trở thành bốn dấu cách và kết thúc dòng đã trở thành LF.`,"codexSet.custom.titleRequired":`Hãy nhập tiêu đề.`,"codexSet.custom.titleTooLong":`Tiêu đề dài {count} ký tự; giới hạn là {max}.`,"codexSet.custom.titleMultiline":`Tiêu đề phải trên một dòng duy nhất.`,"codexSet.custom.bodyTooLarge":`Layer này có dung lượng {bytes} byte; giới hạn là {max}.`,"codexSet.custom.composedTooLarge":`Gộp chung, các layer được kích hoạt sẽ chiếm {bytes} byte, vượt quá giới hạn.`,"codexSet.custom.invalidCharacter":`Một ký tự điều khiển tại vị trí {position} không thể được lưu.`,"codexSet.custom.discardPrompt":`Huỷ bỏ các thay đổi của bạn?`,"codexSet.custom.keepEditing":`Tiếp tục chỉnh sửa`,"codexSet.custom.delete":`Xoá {title}`,"codexSet.custom.layerGone":`Layer đó đã bị xoá ở nơi khác, nên trình chỉnh sửa đã đóng.`,"codexSet.custom.deleteConfirmNamed":`Xoá “{title}”? Hành động này không thể hoàn tác.`,"codexSet.custom.prevLayer":`Layer trước`,"codexSet.custom.nextLayer":`Layer tiếp theo`,"codexSet.custom.navPosition":`{position} / {total}`,"codexSet.custom.moveDown":`Di chuyển {title} xuống`,"codexSet.custom.limitReached":`Bạn có thể giữ lại tối đa {max} layer tuỳ chỉnh.`,"codexSet.custom.notOwned":`developer_instructions được viết bên ngoài opencodex, vì vậy không thể chỉnh sửa nó từ đây. Hãy nhập nội dung đó để quản lý nó như một layer.`,"codexSet.custom.adopt":`Nhập các chỉ thị hiện có`,"codexSet.custom.adoptConfirm":`Nhập dưới dạng layer`,"codexSet.custom.adoptRefused":`Giá trị hiện có không thể được nhập.`,"codexSet.custom.baseReplaced":`model_instructions_file được đặt là {path}, có nghĩa là một yếu tố bên ngoài opencodex đã thay thế base prompt.`,"codexSet.lint.identity":`Cấu hình này tự nhận một danh tính khác với danh tính do Codex thiết lập.`,"codexSet.lint.foreignTool":`Các công cụ đến từ registry; việc chỉ đặt tên chúng ở đây không tự tạo ra công cụ.`,"codexSet.lint.placeholder":`Không có template engine nào xử lý các chỉ thị, do đó phần này sẽ được truyền đi đúng nguyên văn.`,"codexSet.lint.applyPatch":`apply_patch được định nghĩa bởi tool registry, không phải bởi các chỉ thị.`,"codexSet.lint.approvalVocab":`Codex tự chèn thêm từ vựng phê duyệt riêng; điều này có thể mâu thuẫn với nó.`,"codexSet.lint.environment":`Các sự kiện thực tế của môi trường được sinh ra sau đó và có thể gây mâu thuẫn với cấu hình này.`,"codexSet.preset.blank":`Layer trống`,"codexSet.preset.concise.name":`Phản hồi súc tích`,"codexSet.preset.concise.description":`Câu trả lời ngắn gọn, không có phần mở đầu, giảm thiểu định dạng.`,"codexSet.preset.concise.provenance":`Được điều chỉnh từ chỉ thị hướng đến sự ngắn gọn của Claude Code. Chúng tôi tự diễn đạt lại, không phải sao chép.`,"codexSet.preset.planFirst.name":`Lập kế hoạch trước khi chỉnh sửa`,"codexSet.preset.planFirst.description":`Trình bày kế hoạch trước, sau đó mới thực hiện thay đổi.`,"codexSet.preset.planFirst.provenance":`Được điều chỉnh từ phong thái lập kế hoạch của Claude Code. Chúng tôi tự diễn đạt lại, không phải sao chép.`,"codexSet.preset.explainWhy.name":`Giải thích lý do`,"codexSet.preset.explainWhy.description":`Cho biết tại sao lại thực hiện điều đó, thay vì chỉ mô tả những gì bạn đã làm.`,"codexSet.preset.explainWhy.provenance":`Được điều chỉnh từ phong cách xác nhận của Grok Build. Chúng tôi tự diễn đạt lại, không phải sao chép.`,"codexSet.preset.testFirst.name":`Viết test trước tiên`,"codexSet.preset.testFirst.description":`Viết fail test trước khi tiến hành sửa lỗi.`,"codexSet.preset.testFirst.provenance":`Được điều chỉnh từ quy trình thực hành thông thường của agent. Chúng tôi tự diễn đạt lại, không phải sao chép.`,"codexSet.preset.korean.name":`Phản hồi bằng tiếng Hàn`,"codexSet.preset.korean.description":`Luôn trả lời bằng tiếng Hàn cho dù yêu cầu sử dụng bất kỳ ngôn ngữ nào.`,"codexSet.preset.korean.provenance":`Được viết riêng cho opencodex dựa trên một tính năng chủ lực do người dùng yêu cầu. Chúng tôi tự diễn đạt lại, không phải sao chép.`,"codexSet.dialog.class":`Loại`,"codexSet.dialog.key":`Khoá cấu hình`,"codexSet.dialog.fileValue":`Giá trị trong tệp này`,"codexSet.dialog.absentDefault":`chưa thiết lập (mặc định là {value})`,"codexSet.dialog.sourceText":`Văn bản được gửi tới model`,"codexSet.dialog.sourceBytes":`{bytes} byte`,"codexSet.dialog.emptySource":`Tệp tại {path} tồn tại nhưng không có dữ liệu, vì vậy layer này không gửi đi nội dung nào cả.`,"codexSet.dialog.notExposed":`Base prompt di chuyển bên ngoài danh sách tin nhắn mà Codex có thể in ra, vì vậy không thể hiển thị ở đây. Tuy nhiên có thể thay thế nó thông qua model_instructions_file.`,"codexSet.dialog.unmapped":`Lớp này chưa có ánh xạ được xác nhận trong đầu ra prompt, vì vậy chưa thể hiển thị văn bản của nó ở đây.`,"codexSet.dialog.textUnavailable":`Không thể đọc prompt Codex trên máy này, do đó văn bản không khả dụng.`,"codexSet.class.base":`Base instructions`,"codexSet.class.config-toggle":`Có thể chuyển đổi tại đây`,"codexSet.class.feature-gated":`Tính năng bị giới hạn`,"codexSet.class.runtime-conditional":`Phụ thuộc vào runtime`,"codexSet.class.extension-unknown":`Layer mở rộng`,"codexSet.layer.base-instructions":`Base instructions`,"codexSet.layer.model-switch":`Thông báo chuyển đổi model`,"codexSet.layer.personality":`Tính cách`,"codexSet.layer.context-window-guidance":`Hướng dẫn context window`,"codexSet.layer.realtime":`Realtime`,"codexSet.layer.agents-md":`AGENTS.md`,"codexSet.layer.environments-instructions":`Môi trường`,"codexSet.layer.plugins":`Plugins`,"codexSet.layer.tools":`Công cụ`,"codexSet.layer.multi-agent-mode":`Chế độ multi-agent`,"codexSet.layer.git-attribution":`Attribution commit`,"codexSet.about.base-instructions":`Base instructions của riêng Codex. Chúng đi kèm với chính yêu cầu và không thể bị tắt.`,"codexSet.about.model-switch":`Được thêm vào khi phiên trò chuyện thay đổi model giữa cuộc hội thoại.`,"codexSet.about.personality":`Hướng dẫn về giọng điệu và phong cách, được điều khiển bởi một feature flag.`,"codexSet.about.context-window-guidance":`Lời khuyên về ngân sách context còn lại, được điều khiển bởi một feature flag.`,"codexSet.about.realtime":`Được thêm vào cho các phiên realtime.`,"codexSet.about.agents-md":`Tệp AGENTS.md cho dự án của bạn. Trang này chỉ báo cáo layer; nó không bao giờ chỉnh sửa tài liệu dự án của bạn.`,"codexSet.about.permissions":`Giải thích về sandbox và các cài đặt phê duyệt đang có hiệu lực.`,"codexSet.about.collaboration":`Giải thích chế độ cộng tác đang hoạt động.`,"codexSet.about.environment":`Thư mục làm việc, nền tảng, và các sự kiện môi trường thực tế khác.`,"codexSet.about.environments-instructions":`Hướng dẫn cho môi trường thực thi trì hoãn, được điều khiển bởi một feature flag.`,"codexSet.about.apps":`Cách sử dụng các ứng dụng đã kết nối.`,"codexSet.about.plugins":`Được thêm vào khi một plugin được chọn hoặc khi bất kỳ plugin nào quảng cáo về năng lực của mình.`,"codexSet.about.tools":`Mô tả công cụ trì hoãn, được điều khiển bởi một feature flag.`,"codexSet.about.skills":`Danh sách các kỹ năng (skills) khả dụng.`,"codexSet.about.multi-agent-mode":`Chỉ thị cho subagent, được điều khiển bởi một feature flag.`,"codexSet.about.git-attribution":`Yêu cầu model thêm trailer Co-authored-by: Codex vào các commit mà nó viết, và dòng Generated with Codex. vào các pull request mà nó mở. Codex phân giải điều này từ tài khoản của bạn, vì vậy không có cài đặt nào cho nó ở đây hay dưới phần [features]. Khi tài khoản của bạn tắt tính năng này, Codex sẽ gửi hướng dẫn ngược lại thay vì không gửi gì.`,"codexSet.condition.model-switch":`Chỉ được phát ra sau khi có sự thay đổi model giữa phiên làm việc.`,"codexSet.condition.realtime":`Chỉ được phát ra trong phiên realtime.`,"codexSet.condition.agents-md":`Được phát ra khi tìm thấy một tài liệu dự án cho thư mục làm việc.`,"codexSet.condition.plugins":`Được phát ra khi một plugin được chọn hoặc khi có bất kỳ plugin nào quảng cáo về năng lực của mình.`,"codexSet.condition.git-attribution":`Được cấu hình bởi chính sách attribution của tài khoản của bạn.`,"codexSet.base.title":`Base prompt`,"codexSet.base.prev":`Tuỳ chọn trước đó`,"codexSet.base.next":`Tuỳ chọn tiếp theo`,"codexSet.base.position":`{position} / {total}`,"codexSet.base.swipeHint":`Vuốt sang một bên, sử dụng các phím mũi tên hoặc nhấn vào các mũi tên để di chuyển qua lại giữa các tuỳ chọn. Chỉ áp dụng cho các phiên mới bắt đầu.`,"codexSet.base.defaultTitle":`Base prompt của riêng Codex`,"codexSet.base.defaultBody":`Mặc định không được lưu ở đây, vì vậy không có gì để chỉnh sửa hoặc xoá: việc chọn nó đơn giản là sẽ xoá model_instructions_file khỏi cấu hình của bạn, và Codex sử dụng prompt đi kèm với nó.`,"codexSet.base.variantTitle":`Tên`,"codexSet.base.variantBody":`Prompt`,"codexSet.base.replacesWarning":`Điều này SẼ THAY THẾ base prompt của chính Codex chứ không bổ sung thêm. Một prompt ngắn ở đây đồng nghĩa với một model có những chỉ thị ngắn.`,"codexSet.base.use":`Sử dụng cái này`,"codexSet.base.inUse":`Đang sử dụng`,"codexSet.base.externalBlocked":`model_instructions_file đã được trỏ tới {path}, tệp mà opencodex không hề viết. Hãy tự xoá tệp đó đi trước khi chọn một tuỳ chọn tại đây.`,"nav.api":`API`,"nav.integrations":`Tích hợp`,"nav.openMenu":`Mở menu`,"nav.closeMenu":`Đóng menu`,"nav.goHome":`Đi tới bảng điều khiển`,"pws.refreshAllQuotas":`Làm mới tất cả hạn mức`,"pws.quotaRefreshDone":`Đã kiểm tra hạn mức xong`,"integrations.subtitle":`Kết nối các client với opencodex, quản lý thông tin xác thực, và khôi phục cấu hình client.`,"integrations.tabsLabel":`Các bề mặt tích hợp`,"integrations.tab.overview":`Tổng quan`,"integrations.tab.keys":`API Keys`,"integrations.tab.codex":`Codex`,"integrations.tab.claude":`Claude`,"integrations.tab.grok":`Grok Build`,"integrations.tab.cursor":`Cursor`,"integrations.tab.opencode":`OpenCode`,"integrations.tab.pi":`Pi`,"integrations.tab.omp":`OMP`,"integrations.tab.hermes":`Hermes`,"integrations.tab.openclaw":`OpenClaw`,"integrations.tab.kimi":`Kimi Code`,"integrations.tab.gajae":`Gajae Code`,"integrations.tab.dsh":`DSH`,"integrations.tab.mcode":`MiniMax Code`,"integrations.tab.zcode":`ZCode`,"integrations.tab.prime":`Prime Agent`,"integrations.tab.aside":`Aside`,"integrations.tab.raycast":`Raycast`,"integrations.tab.omo":`omo`,"integrations.tab.cline":`Cline CLI`,"integrations.aside.profilesTitle":`Cấu hình Aside`,"integrations.aside.profilesHint":`Chọn profile nào sẽ nhận các model được chọn. Profile đang hoạt động của Aside sẽ được giữ nguyên.`,"integrations.aside.all":`Đồng bộ tất cả profile`,"integrations.aside.syncNow":`Đồng bộ ngay`,"integrations.aside.applied":`{count}/{total} profile đã được áp dụng`,"integrations.aside.current":`Profile hiện tại`,"integrations.aside.profile":`Profile {id}`,"integrations.aside.toggle":`Đồng bộ {name}`,"integrations.aside.details":`Quản lý {name}`,"integrations.aside.back":`Tất cả profile Aside`,"integrations.aside.empty":`Mở Aside và tạo một profile để kết nối nó.`,"integrations.aside.partial":`Một số profile cần chú ý. Các lựa chọn đồng bộ của bạn đã được lưu; hãy kiểm tra trạng thái của từng profile.`,"integrations.aside.pending":`Lựa chọn đồng bộ đã được lưu; đang chờ cập nhật file.`,"integrations.aside.retry":`Thử lại {name}`,"integrations.aside.loadError":`Không thể tải các profile Aside. Thử lại để kiểm tra trạng thái của chúng.`,"integrations.codex.title":`Codex CLI`,"integrations.codex.body":`Việc kết nối Codex do proxy service quản lý. Khởi động opencodex sẽ áp dụng nó; dừng service sẽ khôi phục lại định tuyến nguyên bản.`,"integrations.codex.openService":`Mở cài đặt service`,"integrations.state.notInstalled":`Chưa cài đặt`,"integrations.state.unknown":`Đang kiểm tra…`,"integrations.detail.codexRouted":`Các request của Codex đi qua proxy này`,"integrations.detail.codexAbsent":`Codex chưa được định tuyến qua proxy này`,"integrations.detail.keyCount":`{count} key đã được cấp`,"integrations.detail.keyNone":`Chưa có key nào được cấp`,"integrations.detail.keyChecking":`Đang kiểm tra…`,"integrations.detail.keyUnavailable":`Không có thông tin trạng thái key`,"integrations.detail.claudeOff":`Kết nối đang tắt`,"integrations.detail.desktopCurrent":`Desktop đang chạy profile này`,"integrations.detail.desktopStale":`File profile đã bị thay đổi sau khi được áp dụng`,"integrations.detail.desktopNotServed":`Profile có tồn tại, nhưng Desktop đang sử dụng một profile khác`,"integrations.detail.desktopAbsent":`Chưa có profile nào được áp dụng`,"integrations.detail.desktopDesiredOff":`Tích hợp Claude Desktop đang tắt`,"integrations.detail.desktopDesiredOffCleanupPending":`Claude Desktop vẫn đang sử dụng gateway; đang chờ dọn dẹp`,"integrations.detail.desktopDesiredOnNotApplied":`Tích hợp đang bật, nhưng Desktop không sử dụng profile gateway`,"integrations.detail.desktopSelectedElsewhere":`Desktop đang sử dụng một profile khác`,"integrations.detail.desktopProfileDrift":`Profile Desktop được chọn đã bị thay đổi`,"integrations.detail.desktopObservedUnsafe":`Không thể thay đổi profile Desktop được chọn một cách an toàn`,"integrations.detail.desktopNotInstalled":`Thư viện cấu hình Claude Desktop chưa được cài đặt`,"integrations.detail.grokModels":`{count} model đã được kết nối`,"integrations.detail.grokAbsent":`Không có block opencodex nào trong config`,"integrations.detail.cursorSeen":`Cursor đã gọi proxy này gần đây`,"integrations.detail.cursorNeverSeen":`Đã cài đặt Private Inference; chưa thấy request nào`,"integrations.detail.cursorAbsent":`Không tìm thấy Cursor Private Inference`,"integrations.cursor.title":`Cursor`,"integrations.cursor.intro":`Cursor Private Inference chạy agent của nó cục bộ và giao tiếp với opencodex trên loopback. Cursor bản thường không thể làm điều này: backend của nó gọi endpoint tùy chỉnh và cần một URL HTTPS công khai. Trang này không bao giờ ghi dữ liệu vào Cursor; bạn hãy tự dán các giá trị bên dưới vào Cursor.`,"integrations.cursor.loading":`Đang đọc trạng thái Cursor…`,"integrations.cursor.unavailable":`Không thể đọc trạng thái Cursor từ proxy.`,"integrations.cursor.detection":`Các bản cài đặt được phát hiện`,"integrations.cursor.privateInference":`Cursor Private Inference`,"integrations.cursor.regular":`Cursor (bản thường)`,"integrations.cursor.detected":`Đã phát hiện`,"integrations.cursor.notFound":`Không tìm thấy`,"integrations.cursor.regularOnly":`Chỉ tìm thấy Cursor bản thường. Nó định tuyến các custom endpoint qua server của Cursor, vì vậy proxy loopback không thể tiếp cận nếu không có public tunnel. Hãy xem hướng dẫn về bản Private Inference.`,"integrations.cursor.nothingFound":`Không tìm thấy bản cài đặt Cursor nào ở các vị trí thông thường. Nếu nó được cài đặt ở nơi khác, các giá trị bên dưới vẫn được áp dụng.`,"integrations.cursor.gateway":`Giá trị Gateway`,"integrations.cursor.gatewayHint":`Trong Cursor Private Inference, mở Settings > Models > Gateway, dán hai giá trị này, sau đó nhấn Refresh model list.`,"integrations.cursor.baseUrl":`Base URL`,"integrations.cursor.apiKey":`API Key`,"integrations.cursor.apiKeyCredential":`Một trong các API key opencodex của bạn (liên kết này yêu cầu credential)`,"integrations.cursor.copy":`Sao chép`,"integrations.cursor.copied":`Đã sao chép`,"integrations.cursor.connection":`Kết nối`,"integrations.cursor.seen":`Request cuối cùng từ Cursor: {time} ({ua})`,"integrations.cursor.neverSeen":`Chưa có request nào từ Cursor kể từ khi khởi động proxy. Sau khi lưu gateway, hãy nhấn Refresh model list trong Cursor.`,"integrations.cursor.models":`Những gì Cursor sẽ hiển thị`,"integrations.cursor.modelsHint":`Cursor lấy danh sách Reasoning từ bảng model của riêng nó, vì vậy opencodex chỉ có thể dự đoán. Context liệt kê mặc định và cửa sổ opt-in (Max Mode của Cursor).`,"integrations.cursor.ladderFromBundle":`Danh sách Reasoning đọc từ gói Cursor Private Inference {version} đã cài đặt. Cursor quyết định chúng; opencodex chỉ báo cáo bảng của nó.`,"integrations.cursor.ladderFromStatic":`Danh sách Reasoning là một bản sao tĩnh của Cursor 3.18.25 (không tìm thấy gói Private Inference nào có thể đọc được). Context liệt kê mặc định và cửa sổ opt-in.`,"integrations.cursor.unknownVersion":`không rõ phiên bản`,"integrations.cursor.noControl":`—`,"integrations.cursor.singleWindow":`cửa sổ đơn`,"integrations.cursor.noControlTitle":`ID này không có trong bảng effort tích hợp của Cursor, nên Cursor sẽ không hiển thị nút điều khiển Reasoning.`,"integrations.cursor.effortRowsOne":`1 dòng effort được công bố`,"integrations.cursor.effortRowsMany":`{n} dòng effort được công bố`,"integrations.cursor.effortRowsOff":`không có dòng effort`,"integrations.cursor.tableLessHint":`Các dòng được đánh dấu — sẽ không có nút điều khiển Reasoning trong Cursor. Bật cursorEffortRows để xuất ra một mục lựa chọn cho mỗi effort (id--effort), hoặc đặt modelDefaultReasoningEfforts trên provider để dùng mặc định cố định.`,"integrations.cursor.colModel":`Model`,"integrations.cursor.colReasoning":`Reasoning`,"integrations.cursor.colContext":`Context`,"integrations.cursor.guide":`Mở hướng dẫn Cursor Private Inference`,"integrations.dialog.codex.title":`Vô hiệu hóa tích hợp Codex?`,"integrations.dialog.codex.changes":`opencodex sẽ gỡ bỏ routing của nó khỏi {path}, gỡ bỏ profile nó tạo ra, khôi phục lại model catalog mặc định, và đổi thẻ các luồng có thể tiếp tục về native Codex.`,"integrations.dialog.codex.breakage":`Codex thuần sẽ kết nối trực tiếp đến OpenAI, và các model được định tuyến từ provider khác sẽ biến mất khỏi Codex. Proxy và /v1/responses vẫn tiếp tục chạy cho các client khác.`,"integrations.dialog.codex.undo":`Bật lại tính năng này sẽ xây dựng lại catalog được định tuyến từ các model hiện có và chèn Codex vào một lần nữa. Lịch sử cũ có thể dùng lại được cho hướng tương ứng, nhưng các file không được khôi phục chính xác từng byte.`,"integrations.dialog.codex.sideEffect":`Nếu bạn chọn một routed root model sau khi opencodex chèn cấu hình, việc vô hiệu hóa sẽ gỡ bỏ lựa chọn model đó và bật lại tích hợp sẽ không thể phục hồi nó; bạn hãy chọn lại model. Nếu một model_provider ngoài quản lý Codex, opencodex chỉ gỡ bỏ journal cũ của nó và giữ nguyên cấu hình, catalog và lịch sử.`,"integrations.dialog.codex.confirm":`Vô hiệu hóa`,"integrations.dialog.grok.title":`Vô hiệu hóa tích hợp Grok Build?`,"integrations.dialog.grok.changes":`Chỉ block được đánh dấu bởi opencodex sẽ bị gỡ bỏ khỏi {path}. Nội dung được ghi bên ngoài block sẽ giữ nguyên.`,"integrations.dialog.grok.breakage":`Việc vô hiệu hóa sẽ gỡ bỏ các bí danh model opencodex khỏi Grok Build. Các model được dùng với tài khoản xAI của bạn vẫn hoạt động.`,"integrations.dialog.grok.undo":`Nếu opencodex đang chạy trên địa chỉ loopback, việc bật lại tính năng này sẽ ghi một block mới từ các model hiện có.`,"integrations.dialog.grok.confirm":`Vô hiệu hóa`,"integrations.dialog.desktop.title":`Vô hiệu hóa tích hợp Claude Desktop?`,"integrations.dialog.desktop.changes":`Nếu {path} chứa một profile gateway do opencodex quản lý, Desktop sẽ chuyển về một profile tiêu chuẩn không cần credential, sau đó xóa profile cũ và bản sao lưu.`,"integrations.dialog.desktop.breakage":`Claude Desktop sẽ trở lại dùng Claude tiêu chuẩn thay vì các model định tuyến qua opencodex.`,"integrations.dialog.desktop.undo":`Bật lại tính năng này sẽ tạo lại profile opencodex từ các thiết lập model đã lưu của bạn.`,"integrations.dialog.desktop.restart":`Claude Desktop chỉ đọc cấu hình này khi khởi động. Hãy thoát hoàn toàn và mở lại để thay đổi có hiệu lực.`,"integrations.dialog.desktop.confirm":`Vô hiệu hóa`,"integrations.native.msg.nonLoopbackRemoved":`Grok Build chỉ có thể tự động đăng ký khi opencodex đang chạy trên một địa chỉ loopback. Block trước đó trỏ tới loopback đã bị xóa.`,"integrations.native.msg.nonLoopbackRemovedNoop":`Grok Build chỉ có thể tự động đăng ký khi opencodex đang chạy trên một địa chỉ loopback. Không có block trước đó nào để xóa.`,"integrations.native.msg.nonLoopbackSuperseded":`Grok Build chỉ có thể tự động đăng ký khi opencodex đang chạy trên một địa chỉ loopback. Một tiến trình khác đã ghi một block mới trong khi chờ, do đó block hiện tại trong file không phải do request này tạo ra.`,"integrations.native.error.orphanedMarker":`{path} có một điểm bắt đầu của opencodex nhưng không có điểm kết thúc. File không được thay đổi vì opencodex không thể xác định điểm cuối của block.`,"integrations.native.error.homeMismatch":`Thư mục cài đặt service không khớp với thư mục hiện tại, vì vậy file không được thay đổi.`,"integrations.native.error.notInstalled":`Grok Build chưa được cài đặt, nên không có gì để thay đổi.`,"integrations.native.error.configBusy":`Cấu hình đang được lưu ở nơi khác và không thể thay đổi. Hãy thử lại sau ít phút.`,"integrations.native.error.desktopUnsafeMetadata":`Metadata của Claude Desktop tại {path} không thể được đọc một cách an toàn, vì vậy thư viện của nó không được thay đổi.`,"integrations.native.error.desktopCleanupIncomplete":`Claude Desktop đang trỏ tới chế độ tiêu chuẩn, nhưng các file credential opencodex cũ vẫn còn tại: {paths}.`,"integrations.native.msg.desktopDisabled":`Tích hợp Claude Desktop đã bị vô hiệu hóa.`,"integrations.native.msg.desktopEnabled":`Tích hợp Claude Desktop đã được kích hoạt.`,"integrations.state.absent":`Chưa được áp dụng`,"integrations.state.current":`Đã được áp dụng`,"integrations.state.stale":`Cần cập nhật`,"integrations.state.conflict":`Xung đột`,"integrations.state.unsafe":`Không thể xác minh`,"integrations.summary.detected":`Các client được phát hiện`,"integrations.summary.applied":`Các client đã cấu hình`,"integrations.summary.stale":`Cần cập nhật`,"integrations.summary.lastChange":`Thay đổi cuối cùng`,"integrations.summary.disableAll":`Vô hiệu hóa tất cả…`,"integrations.onboarding":`Việc áp dụng sẽ ghi một provider block opencodex sau khi lưu một bản sao lưu. Việc vô hiệu hóa chỉ xóa block đó, và bản sao lưu đã giữ lại có thể được dùng để khôi phục.`,"integrations.empty.title":`Không tìm thấy client nào đã được cài đặt`,"integrations.empty.body":`Hãy cài đặt một client được hỗ trợ, sau đó quay lại đây để áp dụng opencodex.`,"integrations.action.apply":`Áp dụng`,"integrations.action.disable":`Vô hiệu hóa`,"integrations.action.refresh":`Cập nhật`,"integrations.action.settings":`Cài đặt`,"integrations.action.manageKeys":`Quản lý key`,"integrations.action.restore":`Khôi phục…`,"integrations.action.undo":`Hoàn tác`,"integrations.action.restorePoint":`Khôi phục điểm này…`,"integrations.action.snapshotExpired":`Bản sao lưu đã hết hạn`,"integrations.rollback.title":`Trung tâm hoàn tác`,"integrations.rollback.empty":`Chưa có lịch sử áp dụng`,"integrations.rollback.emptyBody":`Mỗi lần ghi thành công sẽ lưu một bản sao lưu trước khi ghi.`,"integrations.catalog.title":`Clients`,"integrations.rollback.older":`Các thao tác cũ hơn`,"integrations.rollback.showMore":`Hiển thị thêm {n} mục`,"integrations.rollback.failed":`Không thể tải lịch sử hoàn tác.`,"integrations.rollback.delete":`Xóa`,"integrations.rollback.deleteAria":`Xóa mục hoàn tác từ {at}`,"integrations.rollback.deleteNewest":`Mục gần đây nhất của client này được giữ lại để bạn vẫn có thể hoàn tác nó.`,"integrations.rollback.deleteGone":`Mục này đã bị xóa. Danh sách sẽ tự động làm mới.`,"integrations.dialog.deleteEntry.title":`Xóa mục hoàn tác này?`,"integrations.dialog.deleteEntry.changes":`Mục này sẽ biến mất khỏi danh sách hoàn tác, và bất kỳ bản sao lưu nào nó giữ cho {path} sẽ bị xóa khỏi đĩa.`,"integrations.dialog.deleteEntry.breakage":`Bạn sẽ không thể khôi phục file về thời điểm này nữa. Các mục mới hơn và bản thân file sẽ không bị ảnh hưởng.`,"integrations.dialog.deleteEntry.undo":`Thao tác này không thể hoàn tác. Mục gần đây nhất của mỗi client luôn được giữ lại và không thể xóa.`,"integrations.dialog.deleteEntry.confirm":`Xóa mục`,"integrations.restore.title":`Khôi phục bản sao lưu này?`,"integrations.restore.body":`File hiện tại sẽ được sao lưu trước, sau đó bản sao lưu đã chọn sẽ thay thế nó.`,"integrations.restore.driftTitle":`Đã phát hiện các thay đổi mới hơn`,"integrations.restore.driftBody":`Các thay đổi được thực hiện sau bản sao lưu này sẽ được sao lưu lại, sau đó file sẽ bị thay thế.`,"integrations.restore.confirm":`Khôi phục`,"integrations.restore.confirmDrift":`Sao lưu các thay đổi mới và khôi phục`,"integrations.restore.pending":`Đang khôi phục…`,"integrations.restore.manual":`Khôi phục tự động thất bại: {reason}. Hãy khôi phục thủ công từ {path}.`,"integrations.error.load":`Không thể tải trạng thái tích hợp.`,"integrations.error.stale":`Lần làm mới cuối cùng thất bại. Các giá trị bên dưới có thể đã cũ.`,"integrations.error.busy":`Một thay đổi khác cho client này vẫn đang chạy. Hãy thử lại sau ít phút.`,"integrations.error.conflict":`Cấu hình đã thay đổi sau khi opencodex ghi nó. Không có nội dung nào bị xóa.`,"integrations.error.unsafe":`Cấu hình không thể thay đổi một cách an toàn.`,"integrations.error.generic":`Việc thay đổi tích hợp thất bại. Trạng thái trước đó của bạn vẫn được giữ nguyên.`,"integrations.error.nonLoopback":`{client} chỉ có thể kết nối với proxy trên localhost — cấu hình của nó không có chỗ để đặt header admission mà một kết nối từ xa yêu cầu, vì vậy việc viết thủ công cũng không giúp ích. Thay vào đó, hãy cấp quyền truy cập loopback cho nó qua một tunnel hoặc local forwarder.`,"integrations.status.installed":`Đã cài đặt`,"integrations.status.notInstalled":`Chưa cài đặt`,"integrations.status.appliedAt":`Đã áp dụng`,"integrations.status.supersededStore":`Máy khách này hiện đọc danh sách nhà cung cấp từ {path}, tệp mà opencodex không ghi, nên bật ở đây sẽ không thay đổi những gì nó tải.`,"integrations.status.backup":`Sao lưu`,"integrations.status.lastRestore":`Lần khôi phục cuối`,"integrations.status.unknown":`Không xác định`,"integrations.bulk.title":`Vô hiệu hóa các tích hợp client đã áp dụng?`,"integrations.bulk.body":`Chỉ block thuộc về opencodex mới bị xóa. Một bản sao lưu trước khi ghi sẽ được giữ lại cho từng client.`,"integrations.bulk.partial":`Một số client không thể vô hiệu hóa: {clients}`,"integrations.bulk.success":`Các tích hợp client đã áp dụng đã bị vô hiệu hóa.`,"integrations.retention.degraded":`Việc dọn dẹp bản sao lưu bị chậm trễ; các bản sao lưu cũ hơn có thể vẫn còn trên đĩa.`,"integrations.error.residual":`File có thể đang ở trạng thái trung gian: {message} Hãy khôi phục nó từ {path}.`,"integrations.error.residualNoSnapshot":`{message} Quá trình khôi phục tự động chưa hoàn tất. Hãy kiểm tra cấu hình client trước khi thử lại.`,"integrations.error.recover":`{message} Một bản sao lưu nằm tại {path}.`,"integrations.kind.apply":`Đã áp dụng`,"integrations.kind.disable":`Đã tắt`,"integrations.kind.refresh":`Đã cập nhật`,"integrations.kind.restore":`Đã khôi phục`,"integrations.kind.overwrite":`Đã ghi đè`,"integrations.dialog.overwrite.title":`Thay thế block trong config này?`,"integrations.dialog.overwrite.changesUnowned":`Một block không do chúng ta ghi đã chiếm lấy các thiết lập mà opencodex cần trong {path}. Việc áp dụng sẽ thay thế nó bằng block mà opencodex sẽ ghi.`,"integrations.dialog.overwrite.changesForeign":`Thay đổi của bạn bên trong block opencodex ở {path} sẽ bị loại bỏ và thay thế bằng block mà opencodex sẽ ghi.`,"integrations.dialog.overwrite.breakage":`Bất cứ thứ gì mà block kia cấu hình sẽ ngừng hoạt động. Nội dung ở những chỗ khác trong file được giữ nguyên.`,"integrations.dialog.overwrite.undo":`Một bản sao lưu sẽ được lưu trước tiên, do đó thao tác này sẽ xuất hiện trong danh sách hoàn tác bên dưới và có thể được khôi phục.`,"integrations.dialog.overwrite.confirm":`Thay thế`,"integrations.action.overwrite":`Thay thế`,"integrations.preview.loading":`Đang tải kế hoạch thay đổi chính xác…`,"integrations.preview.failed":`Không thể tải kế hoạch thay đổi. Không có gì bị thay đổi.`,"integrations.preview.stale":`Tích hợp đã thay đổi trong lúc xác nhận. Hãy xem kế hoạch mới và xác nhận lại.`,"integrations.dialog.apply.title":`Áp dụng tích hợp này?`,"integrations.dialog.apply.changes":`opencodex sẽ thêm các cài đặt nhà cung cấp do nó quản lý vào cấu hình máy khách.`,"integrations.dialog.apply.breakage":`Máy khách sẽ dùng các mô hình hiện được phiên bản opencodex này cung cấp.`,"integrations.dialog.apply.undo":`Bản sao lưu được lưu trước và có thể hoàn tác thay đổi trong trung tâm khôi phục.`,"integrations.dialog.apply.confirm":`Áp dụng`,"integrations.dialog.disable.title":`Tắt tích hợp này?`,"integrations.dialog.disable.changes":`Chỉ các cài đặt thuộc opencodex sẽ bị xóa.`,"integrations.dialog.disable.breakage":`Máy khách sẽ ngừng dùng các mô hình được định tuyến qua phiên bản opencodex này.`,"integrations.dialog.disable.undo":`Bản sao lưu được lưu trước và có thể hoàn tác thay đổi trong trung tâm khôi phục.`,"integrations.dialog.disable.confirm":`Tắt`,"integrations.plan.heading":`Kế hoạch thay đổi từ máy chủ`,"integrations.plan.operation":`Thao tác: {operation}`,"integrations.plan.operation.apply":`Áp dụng`,"integrations.plan.operation.overwrite":`Thay thế`,"integrations.plan.operation.disable":`Tắt`,"integrations.plan.operation.restore":`Khôi phục`,"integrations.plan.change.add":`Thêm`,"integrations.plan.change.replace":`Thay thế`,"integrations.plan.change.remove":`Xóa`,"integrations.plan.change.snapshot":`Lưu bản sao`,"integrations.plan.change.ownership":`Cập nhật bản ghi quyền sở hữu`,"integrations.plan.change.journal":`Ghi mục khôi phục`,"integrations.plan.foreign.none":`Không phát hiện chỉnh sửa bên ngoài.`,"integrations.plan.foreign.unowned":`Một khối cài đặt không thuộc opencodex sẽ bị thay thế.`,"integrations.plan.foreign.foreignEdit":`Các chỉnh sửa trong khối do opencodex quản lý sẽ bị thay thế.`,"integrations.plan.foreign.drift":`Tệp đã thay đổi kể từ điểm khôi phục này.`,"integrations.plan.noop.applied":`Không cần thay đổi tài liệu máy khách được quản lý; cài đặt tích hợp đã có sẵn.`,"integrations.plan.noop.disabled":`Không cần thay đổi tài liệu máy khách được quản lý; cài đặt tích hợp đã không còn.`,"integrations.plan.noop.profilePreference":`Tùy chọn đồng bộ hồ sơ vẫn sẽ được lưu khi bạn xác nhận.`,"integrations.plan.refused":`Máy chủ không thể áp dụng kế hoạch này một cách an toàn.`,"integrations.plan.refusal.notInstalled":`Máy khách chưa được cài đặt. Hãy cài đặt, làm mới trang và xem trước thay đổi lần nữa.`,"integrations.plan.refusal.conflict":`Cài đặt được quản lý xung đột với tệp hiện tại. Hãy xem lại tệp hoặc dùng Thay thế khi có thể.`,"integrations.plan.refusal.unsafe":`Không thể thay đổi cấu hình máy khách một cách an toàn. Hãy sửa hoặc thay tệp trước khi thử lại.`,"integrations.plan.refusal.nonLoopback":`Máy khách này cần địa chỉ proxy loopback. Hãy dùng localhost, đường hầm hoặc chuyển tiếp cục bộ.`,"integrations.plan.refusal.supersededStore":`Máy khách này đọc danh sách nhà cung cấp từ một tệp mà opencodex không ghi, nên thao tác này sẽ không thay đổi những gì nó tải.`,"integrations.plan.refusal.driftRequiresConfirm":`Tệp đã thay đổi sau điểm khôi phục này. Hãy xem kế hoạch có tính đến thay đổi trước khi khôi phục.`,"integrations.plan.refusal.snapshotExpired":`Bản sao lưu cho điểm khôi phục này đã hết hạn nên không thể khôi phục nữa.`,"integrations.plan.refusal.writeFailed":`Máy chủ không thể chuẩn bị thao tác ghi an toàn. Hãy làm mới trạng thái tích hợp trước khi thử lại.`,"integrations.mutation.pending":`Đang áp dụng thay đổi đã xác nhận…`,"integrations.bulk.breakage":`Mỗi máy khách sẽ ngừng dùng các mô hình được định tuyến qua phiên bản opencodex này.`,"integrations.bulk.undo":`Mỗi máy khách giữ bản sao lưu và mục khôi phục riêng.`,"integrations.bulk.confirm":`Tắt tất cả`,"integrations.semantics.opencode":`Chỉ khởi chạy trực tiếp trên đĩa; việc inject môi trường ocx opencode sẽ được ưu tiên.`,"integrations.semantics.pi":`Áp dụng cho các session mới.`,"integrations.semantics.omp":`Khởi động lại OMP để tải catalog.`,"integrations.semantics.hermes":`Áp dụng cho các session mới.`,"integrations.semantics.openclaw":`Áp dụng ngay cho gateway đang chạy.`,"integrations.semantics.kimi":`Khởi động lại hoặc chạy /reload để áp dụng (v2 theo dõi file).`,"integrations.semantics.gajae":`Áp dụng cho session mới hoặc khi mở /model.`,"integrations.semantics.dsh":`OpenCodex chỉ quản lý llm-pi-ai.providers.opencodex trong $DSH_HOME/settings.yaml. DSH sẽ hot reload provider này; model mặc định của bạn và deepseek-official không thay đổi. Hiện chỉ hỗ trợ loopback; không ghi credential thật nào.`,"integrations.semantics.mcode":`Chỉ quản lý custom_provider.opencodex. Model mặc định của bạn và đăng nhập MiniMax không thay đổi.`,"integrations.semantics.zcode":`Chỉ quản lý provider.opencodex trong ~/.zcode/v2/config.json. Đăng nhập Z.ai của bạn và các provider khác không thay đổi. Khởi động lại ZCode sau khi thay đổi.`,"integrations.semantics.prime":`Chỉ quản lý providers.opencodex trong models.json của Prime Agent — ~/.prime/agent trừ khi PRIME_AGENT_CODING_AGENT_DIR điều hướng nó. Các provider khác và ngoại lệ model của bạn không thay đổi. Áp dụng cho các session mới.`,"integrations.semantics.aside":`Chỉ quản lý providers.opencodex trong ~/.aside/u/<id>/models.json của profile này. Các provider khác của bạn không thay đổi. Hãy thoát hoàn toàn và mở lại Aside sau khi áp dụng.`,"integrations.semantics.raycast":`Thêm một provider OpenCodex vào providers.yaml của Raycast để mọi model được định tuyến xuất hiện trong bộ chọn model AI của Raycast. Yêu cầu Raycast Pro.`,"integrations.semantics.omo":`Chỉ quản lý providers.opencodex trong models.json của omo — ~/.omo/agent, trừ khi OMO_CODING_AGENT_DIR, SENPI_CODING_AGENT_DIR hoặc PI_CODING_AGENT_DIR chuyển hướng. Các nhà cung cấp khác của bạn không thay đổi. Áp dụng cho phiên mới.`,"integrations.semantics.cline":`Quản lý OpenCodex trong providers.json và models.json của Cline CLI. Hãy dừng Cline trước khi thay đổi hoặc đồng bộ các tệp này, rồi khởi động lại. Hoàn tác sẽ khôi phục cả hai bản gốc. Nhà cung cấp mặc định của bạn không thay đổi; hãy chọn OpenCodex trong Cline.`,"integrations.raycast.proRequired":`Custom Providers là một tính năng của Raycast Pro. File sẽ được ghi, nhưng Raycast sẽ bỏ qua nó cho đến khi đăng ký Pro được kích hoạt.`,"integrations.raycast.planUnknown":`Không thể xác định xem Raycast Pro có đang hoạt động hay không; Custom Providers yêu cầu Raycast Pro.`,"integrations.raycast.revealConfig":`Mở Raycast → Settings → AI và nhấp vào Reveal Providers Config một lần để thư mục providers được tạo.`,"codexAuth.mainAccount":`Tài khoản chính`,"codexAuth.logLabel":`Nhãn log`,"codexAuth.codexApp":`Codex App`,"codexAuth.moreActions":`Hiển thị thêm hành động`,"codexAuth.copyId":`Sao chép Account ID`,"codexAuth.appLogin":`Đăng nhập App`,"codexAuth.accountPool":`Pool tài khoản`,"codexAuth.accountModeTitle":`Chế độ tài khoản OpenAI`,"codexAuth.accountModePool":`Chế độ Pool`,"codexAuth.accountModePoolDesc":`Tài khoản đăng nhập chính và các tài khoản đủ điều kiện được thêm vào sẽ luân phiên ở đây.`,"codexAuth.accountModeDirect":`Chế độ Direct`,"codexAuth.accountModeDirectDesc":`Các request chỉ sử dụng tài khoản đăng nhập chính; các tài khoản được thêm vào vẫn được lưu để dùng cho chế độ Pool.`,"codexAuth.openaiMissing":`Provider OpenAI mặc định chưa được cấu hình.`,"codexAuth.openaiDisabled":`Provider OpenAI mặc định đang bị vô hiệu hóa.`,"codexAuth.openaiUnavailableDesc":`Các tài khoản OpenAI của bạn vẫn khả dụng. Hãy bật provider để định tuyến các request của Codex.`,"codexAuth.enableOpenai":`Bật OpenAI`,"codexAuth.enablingOpenai":`Đang bật...`,"codexAuth.enableOpenaiFailed":`Không thể bật provider OpenAI.`,"codexAuth.openaiPresetLoadFailed":`Không thể tải preset của provider OpenAI.`,"codexAuth.openaiPresetUnavailable":`Preset của provider OpenAI không khả dụng.`,"codexAuth.openProviders":`Mở Providers`,"codexAuth.add":`Thêm`,"codexAuth.refreshQuota":`Làm mới quota`,"codexAuth.ultraFastTitle":`Dịch vụ cấp độ Ultra Fast`,"codexAuth.mainHardLockTitle":`Khóa tài khoản chính ở mức 99%`,"codexAuth.mainHardLockDesc":`Sử dụng mức 5h nếu có, nếu không thì dùng hàng tuần (hoặc hàng tháng đối với tài khoản chỉ có hàng tháng). Một kết quả đọc 0% mới sẽ tự động mở khóa; bảo vệ vẫn tiếp tục bật.`,"codexAuth.mainHardLockConfirmTitle":`Bật khóa 99% tài khoản chính?`,"codexAuth.mainHardLockConfirmBody":`Khi bị khóa, tài khoản chính không thể sử dụng Luna Reserve. Giữ lượng dùng dưới mức cạn kiệt có thể ngăn việc kích hoạt Reserve. Các tài khoản được thêm vào và provider khác vẫn khả dụng. Các request đang chạy, credential chưa khớp, và lưu lượng ngoài proxy này không được bảo vệ.`,"codexAuth.mainHardLockConfirm":`Bật bảo vệ`,"codexAuth.mainHardLockEnabled":`Bảo vệ 99% đang bật.`,"codexAuth.mainHardLockDisabled":`Bảo vệ 99% đang tắt. Các giới hạn tài khoản khác vẫn được áp dụng.`,"codexAuth.mainHardLockLoadFailed":`Không thể tải cài đặt này. Hãy thử lại để kiểm tra trạng thái hiện tại của nó.`,"codexAuth.mainHardLockSaveFailed":`Không thể xác nhận việc lưu. Tải lại cài đặt trước khi thử lại.`,"codexAuth.mainHardLockRefreshFailed":`Cài đặt đã được lưu, nhưng không thể làm mới trạng thái tài khoản. Vui lòng thử lại.`,"codexAuth.mainHardLockBlocked":`Bị khóa bởi bảo vệ 99%`,"codexAuth.mainHardLockUnknown":`Bảo vệ đang bật · lượng sử dụng chưa rõ`,"codexAuth.mainHardLockMonitoring":`Bảo vệ đang bật · đang theo dõi`,"codexAuth.mainHardLockManage":`Xem thiết lập bảo vệ`,"codexAuth.ultraFastDesc":`Ngăn không cho dịch vụ cấp độ Ultra Fast mà bạn đã thiết lập bị loại bỏ khi catalog được tạo lại, và đưa tên nó vào các request log. Nó không thêm Ultra Fast vào bộ chọn model: upstream chỉ quảng cáo Fast, do đó mục chọn sẽ đưa ra tốc độ mà đường truyền không thể đáp ứng.`,"codexAuth.ultraFastLoadFailed":`Không thể đọc thiết lập Ultra Fast.`,"codexAuth.ultraFastEnabled":`Cấp độ Ultra Fast đã bật`,"codexAuth.ultraFastDisabled":`Cấp độ Ultra Fast đã tắt`,"codexAuth.ultraFastFailed":`Không thể thay đổi thiết lập Ultra Fast`,"codexAuth.refreshingQuota":`Đang làm mới...`,"codexAuth.quotaRefreshed":`Đã làm mới quota`,"codexAuth.quotaRefreshFailed":`Làm mới quota thất bại`,"codexAuth.pauseExhausted":`Tạm ngưng tài khoản cạn kiệt`,"codexAuth.pausingExhausted":`Đang kiểm tra quota...`,"codexAuth.pauseExhaustedSucceeded":`Đã ngưng các tài khoản cạn kiệt: {count}`,"codexAuth.pauseExhaustedNone":`Không có tài khoản nào được xác nhận đã sử dụng 100%.`,"codexAuth.pauseExhaustedFailed":`Kiểm tra và ngưng các tài khoản cạn kiệt thất bại.`,"codexAuth.noPool":`Chưa có tài khoản pool nào được thêm vào.`,"codexAuth.pause":`Tạm dừng`,"codexAuth.resume":`Tiếp tục`,"codexAuth.paused":`ĐÃ TẠM NGƯNG`,"codexAuth.planExcluded":`Không được tự động chọn`,"codexAuth.planExcludedHint":`Gói {plan} bị loại khỏi lựa chọn tự động. Các tuyến tài khoản chỉ định vẫn khả dụng.`,"codexAuth.pauseSucceeded":`{email} đã bị tạm ngưng`,"codexAuth.resumeSucceeded":`{email} đã có mặt lại trong pool`,"codexAuth.pauseFailed":`Không thể ngưng {email}. Không có thay đổi nào.`,"codexAuth.resumeFailed":`Không thể tiếp tục {email}. Không có thay đổi nào.`,"codexAuth.pausedHint":`Được loại trừ khỏi luân phiên tự động, thử lại, hồi phục sau thời gian chờ, và lựa chọn thủ công cho đến khi tiếp tục.`,"codexAuth.pinned":`ĐÃ GHIM`,"codexAuth.pinnedHint":`Bạn đã chọn tài khoản này bằng tay, nên một thứ tự ưu tiên cao hơn sẽ không bỏ qua nó. Việc ghim kéo dài đến khi tài khoản này bị cạn kiệt, bạn chọn một tài khoản khác, hoặc bạn thay đổi bất kỳ thứ tự lựa chọn nào.`,"codexAuth.fiveHour":`5h`,"codexAuth.weekly":`Tuần`,"codexAuth.quotaAutoRefresh":`Tự động kích hoạt cửa sổ`,"codexAuth.quotaAutoRefreshHint":`Gửi một request warm-up Codex tối thiểu, không lưu trữ khi cửa sổ quota này reset.`,"codexAuth.quotaAutoRefreshUpdated":`Tự động kích hoạt cửa sổ đã được cập nhật.`,"codexAuth.quotaAutoRefreshFailed":`Không thể cập nhật tự động kích hoạt cửa sổ.`,"codexAuth.monthly":`30 ngày`,"codexAuth.resets":`làm mới`,"codexAuth.today":`Hôm nay`,"codexAuth.current":`HIỆN TẠI`,"codexAuth.nextSession":`ĐÃ CHỌN`,"codexAuth.poolPrepared":`ĐÃ CHUẨN BỊ CHO POOL`,"codexAuth.preparePoolTitle":`Chuẩn bị tài khoản này cho chế độ Pool?`,"codexAuth.preparePoolDesc":`Các request dạng Direct tiếp tục sử dụng đăng nhập chính. Tài khoản này trở thành lựa chọn được chuẩn bị của Pool khi chế độ Pool được bật.`,"codexAuth.prepareForPool":`Chuẩn bị cho Pool`,"codexAuth.poolPreparedToast":`{email} đã sẵn sàng cho chế độ Pool`,"codexAuth.switchTitle":`Chuyển tài khoản đang hoạt động?`,"codexAuth.switchDesc":`Có hiệu lực ngay lập tức. Các luồng gắn kết với tài khoản đã có và các request đang thực thi sẽ tiếp tục sử dụng tài khoản cũ; các request mới hoặc chưa gán sẽ dùng theo mức ưu tiên của tài khoản mới được chọn, và các tài khoản ở cùng mức độ ưu tiên vẫn sẽ luân phiên.`,"codexAuth.cacheWarning":`Prompt cache sẽ reset khi chuyển tài khoản. Session mới bắt đầu với cache rỗng.`,"codexAuth.setAsNext":`Dùng tài khoản này tiếp theo`,"codexAuth.cancel":`Hủy`,"codexAuth.switchBack":`Chuyển lại sang Main?`,"codexAuth.switchBackDesc":`Có hiệu lực ngay lập tức. Các luồng gắn kết với tài khoản đã có và các request đang thực thi sẽ tiếp tục sử dụng tài khoản cũ; các request mới hoặc chưa gán sẽ sử dụng mức ưu tiên của tài khoản đăng nhập App, và các tài khoản ở cùng mức độ ưu tiên vẫn sẽ luân phiên.`,"codexAuth.autoSwitch":`Luân phiên chủ động theo mức độ sử dụng`,"codexAuth.autoSwitchQuotaDesc":`Quota: ở mức {threshold}% hoặc cao hơn, request tiếp theo có thể chuyển sang một tài khoản khác đủ điều kiện có mức dùng thấp hơn, bao gồm cả một task đang liên kết; Go/Free chỉ dùng khung 30 ngày.`,"codexAuth.autoSwitchQuotaOffDesc":`Chuyển tài khoản chủ động dựa trên mức sử dụng đang tắt. Các gán ghép cho tác vụ mới/chưa gắn kết và hồi phục sự cố vẫn hoạt động.`,"codexAuth.autoSwitchRoundRobinDesc":`Phân bổ luân phiên (Round-robin) không sử dụng ngưỡng này; nó tiếp tục xoay vòng các task mới/chưa gắn kết.`,"codexAuth.autoSwitchFillFirstDesc":`Ưu tiên làm đầy trước (Fill-first): {threshold}% là điểm chuyển hướng cho các task mới/chưa gắn kết; các task đang liên kết hợp lệ vẫn giữ nguyên tài khoản của chúng.`,"codexAuth.autoSwitchFillFirstOffDesc":`Ưu tiên làm đầy trước (Fill-first) không có điểm chuyển hướng mức sử dụng cho các task mới/chưa gắn kết; việc hồi chiêu, tái xác thực, và hồi phục sự cố vẫn có thể thay đổi định tuyến.`,"codexAuth.failureRecoveryNote":`Hồi phục sự cố là một quy trình riêng: một request bị từ chối trước khi có output với 429/402, cooldown, reauthentication, bị loại trừ, hoặc cấu hình chuyển hướng lỗi tạm thời có thể chọn một tài khoản đủ điều kiện khác.`,"codexAuth.autoSwitchThreshold":`Ngưỡng sử dụng`,"codexAuth.autoSwitchThresholdAria":`Ngưỡng sử dụng, phần trăm`,"codexAuth.autoSwitchThresholdInc":`Tăng ngưỡng sử dụng`,"codexAuth.autoSwitchThresholdDec":`Giảm ngưỡng sử dụng`,"codexAuth.autoSwitchLoadFailed":`Không thể tải cài đặt chuyển đổi theo mức sử dụng.`,"codexAuth.autoSwitchThresholdInvalid":`Nhập một số nguyên từ 1 đến 100`,"codexAuth.autoSwitchUpdated":`Cập nhật chuyển đổi chủ động theo mức độ sử dụng thành công`,"codexAuth.autoSwitchUpdateFailed":`Không thể xác nhận bản cập nhật chuyển đổi theo mức sử dụng. Đang hiển thị giá trị được xác nhận gần nhất.`,"codexAuth.requestUserInput":`Yêu cầu người dùng nhập ở chế độ Default`,"codexAuth.requestUserInputDesc":`Cho phép Codex tạm ngưng một session Default-mode và đặt câu hỏi cho bạn bằng tool request_user_input.`,"codexAuth.requestUserInputUpdated":`Tính năng đã được cập nhật - áp dụng cho các session mới.`,"codexAuth.requestUserInputUpdatedRestart":`Tính năng đã được cập nhật - áp dụng cho các session mới. Khởi động lại Codex app để áp dụng.`,"codexAuth.requestUserInputUpdateFailed":`Không thể cập nhật tính năng. Không có thay đổi nào.`,"codexAuth.requestUserInputLoadFailed":`Không thể đọc tính năng từ config.toml.`,"codexAuth.accountPickerTitle":`Chỉ định một tài khoản Codex cụ thể từ bộ chọn model`,"codexAuth.accountPickerOffDesc":`Khi được bật, các mục chọn model GPT thông thường được thay thế bằng một lựa chọn cho mỗi tài khoản, vì vậy bạn có thể chọn chính xác một tài khoản cho cuộc hội thoại mà không cần đăng xuất. Việc tắt đi không xóa bất kỳ tài khoản nào.`,"codexAuth.accountPickerOnDesc":`Mỗi bộ chọn là một nhãn công khai cho một tài khoản đã lưu. Chọn nó sẽ khóa cuộc hội thoại đó với tài khoản được gán: nó không bao giờ luân phiên hoặc fallback, và nó không thay đổi tài khoản Pool đang hoạt động.`,"codexAuth.accountPickerCompatibility":`Tài khoản đăng nhập Codex App tích hợp sẵn có bộ chọn riêng; các liên kết tự tạo thường gọi nó là main và sử dụng hậu tố chống trùng lặp như main-2 khi cần. Các tài khoản được thêm nhận các nhãn an toàn riêng tư, còn các nhãn bộ chọn tùy chỉnh không bị thay đổi. Các cuộc hội thoại hiện có và model đã lưu tiếp tục được định tuyến. Việc tắt tùy chọn này ẩn đi các mục được tạo nhưng vẫn giữ các bộ chọn và các định tuyến chính xác. Các model ID GPT thuần giữ nguyên hành vi Pool hoặc Direct của chúng.`,"codexAuth.accountPickerUpdated":`Việc nhắm mục tiêu tài khoản đã được cập nhật.`,"codexAuth.accountPickerUpdateFailed":`Không thể cập nhật việc nhắm mục tiêu tài khoản. Cài đặt được xác nhận gần nhất đang được hiển thị.`,"codexAuth.accountPickerLoadFailed":`Không thể tải cài đặt nhắm mục tiêu tài khoản.`,"codexAuth.accountPickerRefreshFailed":`Không thể làm mới cài đặt này. Giá trị được xác nhận gần nhất vẫn đang được hiển thị.`,"codexAuth.advancedSettings":`Cài đặt nâng cao`,"codexAuth.advancedSettingsAria":`Hiển thị hoặc ẩn cài đặt xác thực Codex nâng cao`,"codexAuth.catalogRefreshPending":`Thay đổi đã được lưu, nhưng việc làm mới model catalog của Codex vẫn đang chờ xử lý. Hãy chạy ocx sync để thử lại.`,"anthropicPool.title":`Claude account pool (thử nghiệm)`,"anthropicPool.enabledDesc":`Sticky sessions, và các session mới ưu tiên mức sử dụng dưới {threshold}% ({window}).`,"anthropicPool.enabledNoProactiveDesc":`Sticky sessions. Việc chuyển đổi chủ động dựa trên mức sử dụng đang bị vô hiệu hóa với ngưỡng 0, nhưng việc lựa chọn session mới vẫn sử dụng cửa sổ {window}.`,"anthropicPool.disabledDesc":`Mỗi session một tài khoản. Lỗi 429 vẫn sẽ chuyển sang một tài khoản khác đã đăng nhập — điều này không thể bị tắt.`,"anthropicPool.experimentalWarning":`Thử nghiệm và chưa được kiểm chứng đầy đủ. Anthropic có thể giới hạn các tài khoản có vẻ như luân phiên nhiều tài khoản tự động. Cùng một tổ chức có thể chia sẻ quota — gom nhóm các tài khoản đó sẽ không có tác dụng. Vui lòng giữ ở trạng thái tắt trừ khi bạn hiểu rõ rủi ro.`,"anthropicPool.needTwoAccounts":`Thêm ít nhất hai tài khoản Claude OAuth trước khi kích hoạt pool.`,"anthropicPool.threshold":`Ngưỡng sử dụng cho session mới`,"anthropicPool.thresholdAria":`Ngưỡng sử dụng cho session mới, phần trăm`,"anthropicPool.thresholdHelp":`0 sẽ tắt tính năng lựa chọn dựa trên quota (chỉ giữ ái lực + tài khoản đang hoạt động). Mặc định là 80.`,"anthropicPool.thresholdInvalid":`Nhập một số nguyên từ 0 đến 100`,"anthropicPool.loadFailed":`Không thể tải cài đặt Claude pool.`,"anthropicPool.saveFailed":`Không thể lưu cài đặt Claude pool.`,"anthropicPool.on":`Bật`,"anthropicPool.off":`Tắt`,"accountPool.strategy":`Chiến lược xoay vòng`,"accountPool.strategyDesc":`Cách OpenCodex chỉ định tài khoản cho một task mới/chưa gắn kết.`,"accountPool.strategyResetFirst":`Ưu tiên lần đặt lại sớm nhất`,"accountPool.strategyHintResetFirst":`Ưu tiên lần đặt lại 5 giờ hoặc hàng tuần gần nhất trong tương lai giữa các tài khoản dưới ngưỡng sử dụng. Tác vụ đã liên kết tuân theo chính sách affinity đã cấu hình. Hạn ngạch model độc lập dùng thứ tự hạn ngạch.`,"accountPool.strategyQuota":`Quota`,"accountPool.strategyRoundRobin":`Luân phiên`,"accountPool.strategyFillFirst":`Làm đầy trước`,"accountPool.switchAtThreshold":`chuyển ở {threshold}%`,"accountPool.drainAtThreshold":`dùng cạn ở {threshold}%`,"accountPool.resetBelowThreshold":`lần đặt lại gần nhất dưới {threshold}%`,"accountPool.thresholdNotUsed":`không dùng ngưỡng`,"accountPool.proactiveSwitchingOff":`tắt chuyển đổi chủ động`,"accountPool.strategyHintQuota":`Quota cũng có thể liên kết lại một task đang chạy ở request tiếp theo của nó sau khi vượt qua ngưỡng sử dụng.`,"accountPool.strategyHintRoundRobin":`Luân phiên (Round-robin) chỉ chuyển đổi các task không có liên kết hiện tại; ngưỡng sử dụng không làm thay đổi việc luân phiên bình thường.`,"accountPool.strategyHintFillFirst":`Làm đầy trước (Fill-first) sử dụng ngưỡng như là một điểm xả cho các task chưa gắn kết; các task đang liên kết hợp lệ vẫn giữ ái lực.`,"accountPool.unboundDefinition":`Task mới/chưa gắn kết (new/unbound) nghĩa là một request không có liên kết tài khoản nào hiện tại; một task có thể nhìn thấy có thể trở nên chưa gắn kết sau khi proxy hoặc ái lực bị đặt lại.`,"accountPool.stickyLimit":`Các tác vụ mới/chưa gắn kết sẽ giữ nguyên trước khi quay vòng`,"accountPool.stickyLimitAria":`Số lần gán tác vụ mới/chưa gắn kết trước khi xoay vòng`,"accountPool.stickyLimitInc":`Tăng giới hạn dính`,"accountPool.stickyLimitDec":`Giảm giới hạn dính`,"accountPool.stickyLimitHelp":`Giữ tài khoản đã chọn cho số lần gán tác vụ mới/chưa gắn kết này trước khi chuyển sang tài khoản khác; bộ đếm tăng lên khi tác vụ được gắn kết, chứ không phải sau khi upstream thành công.`,"accountPool.stickyLimitInvalid":`Nhập một số nguyên từ 1 đến 100`,"accountPool.strategyLoadFailed":`Không thể tải chiến lược luân phiên.`,"accountPool.strategyUpdateFailed":`Không thể lưu chiến lược luân phiên.`,"accountPool.quotaWindow":`Cửa sổ Quota`,"accountPool.quotaWindowDesc":`Thanh trạng thái sử dụng lưu trong cache nào kiểm soát việc chọn session mới dựa trên quota, kiểm tra ngưỡng fill-first, và các bản thay thế 429 đủ điều kiện.`,"accountPool.quotaWindowFiveHour":`Khung 5 giờ`,"accountPool.quotaWindowWeekly":`Khung hàng tuần`,"accountPool.quotaWindowMaxUtilization":`Khung sử dụng cao hơn`,"accountPool.quotaWindowHint":`Hàng tuần sẽ bỏ qua các tài khoản đã hết mức giới hạn 5 giờ nếu còn tài khoản khác hợp lệ, nhưng sẽ quay về chúng nếu không còn ai khác. Nếu hòa hàng tuần, tài khoản có mức 5 giờ thấp hơn sẽ được ưu tiên; mức hàng tuần cho mỗi tài khoản chỉ được biết sau khi trang Providers đã lấy dữ liệu.`,"accountPool.quotaWindowInert":`Chỉ chiến lược Quota — hoặc Fill-first khi lớn hơn ngưỡng 0 — mới lấy điểm đánh giá mức sử dụng, nên cài đặt này không có tác dụng đối với chiến lược luân phiên hiện tại.`,"accountPool.priority":`Thứ tự chọn`,"accountPool.priorityAria":`Thứ tự ưu tiên cho tài khoản này`,"accountPool.priorityHint":`Số càng cao càng được sử dụng trước. Pool chuyển xuống một số ưu tiên thấp hơn chỉ khi tất cả các tài khoản ở mức trên bị cạn kiệt hoặc không khả dụng.`,"accountPool.priorityFirst":`Đầu tiên`,"accountPool.priorityEarlier":`Sớm hơn`,"accountPool.priorityNormal":`Thông thường`,"accountPool.priorityLater":`Muộn hơn`,"accountPool.priorityLast":`Cuối cùng`,"accountPool.priorityOption":`{name} ({value})`,"accountPool.priorityCustom":`Tùy chỉnh`,"accountPool.priorityUpdated":`Đã cập nhật thứ tự ưu tiên cho {email}`,"accountPool.priorityUpdateFailed":`Không thể lưu thứ tự lựa chọn cho {email}. Giá trị được xác nhận gần nhất đang được hiển thị.`,"codexAuth.switched":`Tài khoản được chọn cho request tiếp theo là {email}`,"codexAuth.loadFailed":`Không thể tải cài đặt tài khoản Codex.`,"codexAuth.accountsRefreshFailed":`Lần làm mới tài khoản gần nhất thất bại. Dưới đây là các tài khoản được xác nhận gần nhất.`,"codexAuth.switchExceedsThresholdWarning":`Mức sử dụng của tài khoản này đã đạt hoặc vượt ngưỡng chuyển đổi ({threshold}%). Lựa chọn đã ghim sẽ được giải phóng nếu không còn hạn ngạch khả dụng.`,"codexAuth.switchFailed":`Không thể chuyển đổi tài khoản. Tùy chọn trước đó của bạn vẫn được giữ nguyên.`,"codexAuth.removeConfirm":`Gỡ bỏ {id}?`,"codexAuth.removeFailed":`Không thể gỡ bỏ tài khoản. Không có thay đổi nào.`,"codexAuth.addTitle":`Thêm tài khoản Codex`,"codexAuth.addIdLabel":`ID tài khoản (slug)`,"codexAuth.addIdPlaceholder":`codex-work, codex-alt, team...`,"codexAuth.resetCreditsAria":`{count} credit reset`,"codexAuth.addJsonLabel":`Nội dung auth.json`,"codexAuth.addHelp":`Sao chép từ ~/.codex/auth.json trên một máy khác, hoặc sử dụng codex-auth export.`,"codexAuth.importBtn":`Nhập (Import)`,"codexAuth.importInvalidJson":`JSON không hợp lệ`,"codexAuth.importMissingTokens":`Thiếu access_token hoặc refresh_token trong JSON`,"codexAuth.importMissingId":`Account ID là bắt buộc`,"codexAuth.accountAdded":`Tài khoản đã được thêm vào pool`,"codexAuth.addPickDesc":`Đăng nhập bằng một tài khoản ChatGPT khác để thêm nó vào pool.`,"codexAuth.oauthLogin":`Đăng nhập bằng OAuth`,"codexAuth.oauthDesc":`Mở trang đăng nhập ChatGPT trong trình duyệt`,"codexAuth.deviceLogin":`Đăng nhập qua device code`,"codexAuth.deviceDesc":`Dành cho máy chủ headless hoặc proxy từ xa: nhập mã ngắn này trên một thiết bị khác`,"codexAuth.importAuthJson":`Nhập auth.json`,"codexAuth.importAuthJsonDesc":`Từ một bản Codex khác hoặc thông qua export codex-auth`,"codexAuth.back":`Quay lại`,"codexAuth.oauthAlreadyInProgress":`Đang tiến hành đăng nhập. Vui lòng hoàn tất quá trình này trong trình duyệt của bạn.`,"codexAuth.oauthWaiting":`Đang đợi quá trình đăng nhập ChatGPT hoàn tất trên trình duyệt...`,"codexAuth.oauthSubmittingCode":`Đang gửi mã…`,"codexAuth.oauthCodeSubmitted":`Đã gửi mã — đang đợi đăng nhập hoàn tất…`,"codexAuth.oauthStatusRetrying":`Lỗi mạng hoặc proxy trong khi kiểm tra trạng thái đăng nhập — đang thử lại…`,"codexAuth.oauthCancelled":`Quá trình đăng nhập đã bị hủy.`,"codexAuth.loginFailed":`Đăng nhập thất bại`,"codexAuth.needsReauth":`Đăng nhập lại`,"codexAuth.reauthenticate":`Xác thực lại`,"codexAuth.tokenExpired":`Token hết hạn — hãy xác thực lại tài khoản này`,"codexAuth.mainTokenExpired":`Token hết hạn — vui lòng đăng nhập lại thông qua Codex App login`,"codexAuth.mainReauthSucceeded":`Đã đăng nhập`,"codexAuth.mainReauthFailed":`Đăng nhập lại thất bại`,"codexAuth.mainReauthCancel":`Hủy`,"codexAuth.mainReauthCode":`Mã`,"codexAuth.mainReauthOpen":`Mở`,"codexAuth.mainReauthPending":`Đang chờ đăng nhập…`,"codexAuth.mainReauthDevice":`Đăng nhập lại bằng mã thiết bị`,"codexAuth.emailCollision":`Tài khoản này trùng với lần đăng nhập Codex chính của bạn. Vui lòng dùng tài khoản khác.`,"codexAuth.resetCreditsTitle":`Đặt lại Credits`,"codexAuth.resetCreditsAvailable":`Bạn đang có sẵn {count} credit reset.`,"codexAuth.resetCreditsDesc":`Mỗi credit reset ngay lập tức các giới hạn sử dụng hàng giờ và hàng tuần hiện tại của bạn.`,"codexAuth.noResetCredits":`Bạn không có credit reset nào.`,"codexAuth.earnCreditsHint":`Credit được thưởng hàng tháng và qua chương trình giới thiệu (referral program).`,"codexAuth.creditsExpireNote":`Credit hết hạn sau 30 ngày kể từ khi kiếm được.`,"codexAuth.useOneCredit":`Sử dụng 1 Credit`,"codexAuth.confirmResetTitle":`Sử dụng Reset Credit?`,"codexAuth.confirmResetDesc":`Thao tác này sẽ reset ngay lập tức các giới hạn tỉ lệ hiện tại của bạn. Bạn còn lại {count} credit.`,"codexAuth.irreversible":`Hành động này không thể hoàn tác.`,"codexAuth.useCredit":`Dùng Credit`,"codexAuth.redeeming":`Đang reset...`,"codexAuth.resetSuccess":`Đã reset các giới hạn sử dụng! Bạn còn lại {remaining} credit.`,"codexAuth.resetSuccessGeneric":`Đã reset các giới hạn sử dụng!`,"codexAuth.resetAlreadyRedeemed":`Credit này đã được sử dụng. Số lượng credit không thay đổi.`,"codexAuth.resetNothingToReset":`Hiện không có cửa sổ hạn mức nào cần reset.`,"codexAuth.resetNoCredit":`Không có reset credit nào.`,"codexAuth.resetError":`Không thể đổi reset credit. Vui lòng thử lại.`,"codexAuth.fifoNote":`Credit cũ nhất sẽ được dùng trước.`,"codexAuth.confirmWhichCredit":`Credit từ ngày {date} sẽ được sử dụng.`,"codexAuth.creditNext":`Sắp dùng tới`,"codexAuth.creditLabel":`Credit #{n}`,"codexAuth.creditNextBadge":`NEXT`,"codexAuth.creditGranted":`Được cấp vào {date}`,"codexAuth.creditExpires":`Hết hạn vào {date} (còn lại {days} ngày)`,"grokCoupon.badgeAria":`{count} phiếu đặt lại Grok`,"grokCoupon.badgeErrorAria":`Không thể đọc phiếu đặt lại Grok`,"grokCoupon.title":`Phiếu đặt lại Grok`,"grokCoupon.available":`Tài khoản này có {count} phiếu đặt lại.`,"grokCoupon.desc":`Một phiếu sẽ đặt lại ngay cửa sổ sử dụng Grok của tài khoản này.`,"grokCoupon.none":`Tài khoản này không có phiếu đặt lại.`,"grokCoupon.loadFailed":`Không thể đọc phiếu đặt lại của tài khoản này.`,"grokCoupon.loadFailedAuth":`Hãy đăng nhập lại tài khoản xAI này để đọc phiếu.`,"grokCoupon.retry":`Thử lại`,"grokCoupon.couponLabel":`Phiếu #{n}`,"grokCoupon.couponNext":`Sẽ dùng tiếp theo`,"grokCoupon.couponNextBadge":`TIẾP THEO`,"grokCoupon.validFrom":`Có hiệu lực từ {date}`,"grokCoupon.expires":`Hết hạn {date} (còn {days} ngày)`,"grokCoupon.useOne":`Dùng 1 phiếu`,"grokCoupon.fifoNote":`Phiếu gần hết hạn nhất được dùng trước.`,"grokCoupon.confirmTitle":`Dùng phiếu đặt lại?`,"grokCoupon.confirmDesc":`Việc này sẽ đặt lại ngay cửa sổ sử dụng Grok của tài khoản. Bạn có {count} phiếu.`,"grokCoupon.confirmWhich":`Phiếu hết hạn vào {date} sẽ được sử dụng.`,"grokCoupon.irreversible":`Không thể hoàn tác hành động này.`,"grokCoupon.redeem":`Dùng phiếu`,"grokCoupon.redeeming":`Đang đổi phiếu…`,"grokCoupon.redeemSuccess":`Đã đổi phiếu. Còn {count} phiếu.`,"grokCoupon.redeemReplayed":`Lần đổi phiếu này đã hoàn tất trước đó. Không có gì bị tiêu thụ thêm.`,"grokCoupon.redeemFailed":`Đổi phiếu thất bại. Hãy kiểm tra danh sách phiếu trước khi thử lại.`,"grokCoupon.authFailed":`Hãy đăng nhập lại tài khoản xAI này để dùng phiếu.`,"grokCoupon.noAccount":`Không có tài khoản xAI nào cho lần đổi phiếu này.`,"grokCoupon.noneAvailable":`Không có phiếu đặt lại nào để đổi.`,"grokCoupon.identityMismatch":`Lần đổi phiếu đó thuộc tài khoản khác. Hãy đóng hộp thoại này và bắt đầu lại.`,"grokCoupon.networkError":`Không thể kết nối tới proxy.`,"grokCoupon.capacity":`Nhật ký đổi phiếu hiện đã đầy. Hãy thử lại sau giây lát.`,"grokCoupon.noOperationId":`Trình duyệt này không thể tạo ID đổi phiếu, nên tính năng đổi phiếu bị tắt tại đây.`,"grokCoupon.unknownOutcome":`Lần đổi phiếu không phản hồi kịp thời nên chưa rõ kết quả. Hãy đọc lại tài khoản để xem phiếu đã được dùng hay chưa.`,"grokCoupon.checkResult":`Đọc lại tài khoản`,"grokCoupon.checking":`Đang đọc lại…`,"grokCoupon.consumedElsewhere":`Phiếu không còn trong tài khoản này, nên việc đổi phiếu đã thành công.`,"grokCoupon.unresolved":`Phiếu vẫn còn trong danh sách. Việc đổi có thể vẫn đang chạy ở upstream — hãy đọc lại sau một phút trước khi dùng phiếu khác.`,"api.title":`Truy cập API`,"api.subtitle":`Sử dụng các API key được tạo để truy cập proxy opencodex từ các ứng dụng bên ngoài. API key được xác thực qua header {authHeader}; xem bảng bên dưới để biết mỗi endpoint hỗ trợ những gì.`,"api.baseUrl":`Base URL`,"api.responsesEndpoint":`Responses API`,"api.chatCompletionsEndpoint":`Chat Completions API`,"api.messagesEndpoint":`Messages API`,"api.modelsEndpoint":`Models API`,"api.endpointNote":`Dùng URL cơ sở cho các ứng dụng hỗ trợ OpenAI tương thích. Responses và Chat Completions được đặt ở /v1.`,"api.endpointsTitle":`Endpoints`,"api.authTitle":`Xác thực (Authentication)`,"api.authLoopback":`Kết nối Loopback (127.0.0.1 hoặc ::1) bỏ qua xác thực. Các kết nối từ xa yêu cầu một API key tạo sẵn bằng tiền tố ocx_ hoặc OPENCODEX_API_AUTH_TOKEN.`,"api.authBaseUrlNote":`Cấu hình client bằng URL cơ sở, sau đó chọn một endpoint cụ thể theo giao thức ở bên dưới.`,"api.newKeyTitle":`Đã tạo key mới`,"api.newKeyNote":`Sao chép key này ngay bây giờ — nó sẽ không hiển thị lại nữa.`,"api.copy":`Sao chép`,"api.copied":`Đã sao chép`,"api.dismiss":`Bỏ qua`,"api.generateTitle":`Tạo key`,"api.keyNamePlaceholder":`Tên key (tùy chọn)`,"api.generate":`Tạo`,"api.generating":`Đang tạo…`,"api.activeKeys":`Các key đang kích hoạt ({count})`,"api.activeKeysLoading":`Các key đang kích hoạt`,"api.noKeys":`Chưa có API key nào. Hãy tạo một key ở trên.`,"api.workspace.sections":`Các phân hệ API`,"api.section.keys":`Keys`,"api.section.connect":`Kết nối`,"api.section.endpoints":`Endpoints`,"api.section.models":`Models`,"api.section.examples":`Ví dụ`,"api.workspace.details":`Chi tiết API key`,"api.workspace.keyDetails":`Chi tiết Key`,"api.workspace.keyPrefix":`Tiền tố key`,"api.workspace.deleteKey":`Xóa key`,"api.workspace.deleteConfirm":`Bạn có chắc chắn muốn xóa key này? Hành động này không thể hoàn tác.`,"api.workspace.usageExamples":`Ví dụ cách dùng`,"api.copyUrlHint":`Nhấp để chép URL`,"api.urlCopied":`Đã chép URL`,"api.copyExampleHint":`Nhấp để chép ví dụ`,"api.exampleCopied":`Đã chép ví dụ`,"api.colName":`Tên`,"api.colKey":`Key`,"api.colCreated":`Tạo ngày`,"api.confirm":`Xác nhận`,"api.deleteAria":`Xóa API key`,"api.modelsTitle":`Danh mục model bên ngoài`,"api.modelsCount":`{count} có thể gọi được`,"api.modelsLoading":`Đang tải các model…`,"api.modelsSearch":`Tìm model`,"api.modelsSubtitle":`Dùng chính xác các ID model này với /v1/models và giao thức đầu vào bạn đã chọn.`,"api.modelsEmpty":`Chưa có model bên ngoài nào khả dụng để gọi.`,"api.modelsNoMatch":`Không có model nào khớp với “{query}”.`,"api.modelsLoadFailed":`Không thể tải danh sách model bên ngoài.`,"api.colModel":`Model`,"api.colSource":`Nguồn (Source)`,"api.colProtocols":`Giao thức`,"api.sourceNative":`ChatGPT pool`,"api.sourceCombo":`Định tuyến hỗn hợp`,"api.sourceCustom":`Tùy chỉnh`,"api.protocolResponses":`Responses`,"api.protocolChatCompletions":`Chat Completions`,"api.protocolMessages":`Messages`,"api.copyModelId":`Sao chép ID`,"api.modelCopied":`Đã sao chép`,"api.testModel":`Kiểm tra`,"api.testingModel":`Đang kiểm tra…`,"api.testSucceeded":`OK`,"api.testFailed":`Thất bại`,"api.usageChatTitle":`Ví dụ Chat Completions`,"api.usageResponsesTitle":`Ví dụ Responses`,"api.usageMessagesTitle":`Ví dụ Messages`,"api.usageSampleInput":`Xin chào, thế giới!`,"api.clientConfig.title":`Cấu hình Client`,"api.clientConfig.rowsLabel":`Kết nối một client`,"api.clientConfig.details":`Chi tiết`,"api.clientConfig.detailsAria":`Chi tiết cấu hình {client}`,"api.clientConfig.copyAria":`Sao chép cấu hình {client}`,"api.clientConfig.downloadAria":`Tải cấu hình {client}`,"api.clientConfig.rowMeta":`{destination} · {count} model`,"api.clientConfig.rowError":`Không thể xây dựng cấu hình {client}.`,"api.clientConfig.copiedAnnounceClient":`Cấu hình {client} đã được chép vào clipboard.`,"api.clientConfig.clientOpencode":`OpenCode`,"api.clientConfig.clientPi":`Pi`,"api.clientConfig.clientOmp":`OMP`,"api.clientConfig.clientHermes":`Hermes`,"api.clientConfig.clientOpenclaw":`OpenClaw`,"api.clientConfig.clientKimi":`Kimi Code`,"api.clientConfig.clientGajae":`Gajae Code`,"api.clientConfig.clientDsh":`DeepSeek Harness (DSH)`,"api.clientConfig.clientMcode":`MiniMax Code`,"api.clientConfig.clientZcode":`ZCode`,"api.clientConfig.clientPrime":`Prime Agent`,"api.clientConfig.clientAside":`Aside`,"api.clientConfig.clientRaycast":`Raycast`,"api.clientConfig.clientOmo":`omo`,"api.clientConfig.clientCline":`Cline CLI`,"api.clientConfig.clineBundle":`Đây là gói gồm hai tệp, không phải tệp cài đặt Cline. Hãy hợp nhất cài đặt vào providers.json và catalog vào models.json cùng cấp. Dùng công tắc tích hợp để ghi kèm bản sao lưu.`,"api.clientConfig.clineDownloaded":`Đã tải xuống {filename}. Chưa có gì thay đổi; cài đặt và catalog thuộc hai tệp Cline riêng biệt.`,"api.clientConfig.copy":`Sao chép cấu hình`,"api.clientConfig.download":`Tải xuống`,"api.clientConfig.loading":`Đang xây dựng cấu hình client…`,"api.clientConfig.jsonLabel":`Cấu hình {client}`,"api.clientConfig.destination":`Tệp đích`,"api.clientConfig.envHint":`Thiết lập khóa trước khi khởi chạy`,"api.clientConfig.mergeWarning":`Gộp nội dung này vào tệp đích. Nếu ghi đè hoàn toàn, bạn sẽ mất các cài đặt MCP và provider khác.`,"api.clientConfig.modelCount":`Đã xuất {count} model`,"api.clientConfig.missingLimits":`{count} trong số {total} model được phân phối không có giới hạn ngữ cảnh (context limit); client sẽ áp dụng các giá trị mặc định của riêng nó.`,"api.clientConfig.noKeyYet":`{env} hiện chưa có khóa. Hãy tạo một khóa ở trên trước khi sử dụng cấu hình này bên ngoài loopback.`,"api.clientConfig.loadFailed":`Không thể đọc danh sách model, do đó không có cấu hình client nào được tạo ra.`,"api.clientConfig.copiedAnnounce":`Cấu hình client đã được sao chép vào khay nhớ tạm.`,"api.clientConfig.copyFailed":`Không thể sao chép cấu hình client.`,"api.clientConfig.downloadedAnnounce":`Đã tải xuống {filename}. Chưa có thay đổi nào được áp dụng — hãy tự gộp nó vào {destination}.`,"api.clientConfig.whereDisclosure":`Tệp này được lưu ở đâu`,"api.clientConfig.whereBody":`Đích đến ở trên là đường dẫn toàn cục (global path). Một tệp cấu hình project-local trong thư mục làm việc sẽ được ưu tiên cao hơn, và client sẽ đọc khóa từ biến môi trường (environment variable) được chỉ định trong cấu hình — chứ không bao giờ đọc từ tệp này.`,"api.keysLoadFailed":`Không thể tải các khóa API.`,"api.createFailed":`Không thể tạo khóa API.`,"api.deleteFailed":`Không thể xóa khóa API.`,"api.auth.endpoint":`Endpoint`,"api.auth.required":`Bắt buộc`,"api.auth.accepted":`Được chấp nhận`,"api.auth.rejected":`Không được chấp nhận`,"api.auth.testProtocol":`Kiểm tra {protocol}`,"api.auth.testNeedsFreshKey":`Tạo một khóa và giữ giá trị hiển thị một lần của nó trên màn hình để chạy một bài kiểm tra xác thực (authenticated test).`,"api.key.name":`Tên khóa`,"api.key.rename":`Đổi tên`,"api.key.saveName":`Lưu tên`,"api.key.renaming":`Đang lưu…`,"api.key.renameFailed":`Không thể đổi tên khóa. Bản nháp của bạn đã được giữ lại.`,"api.key.deleting":`Đang xóa…`,"api.rotation.title":`Luân chuyển khóa`,"api.rotation.description":`Cấp phát một khóa thay thế trong khi khóa hiện tại vẫn giữ hiệu lực trong một khoảng thời gian gối đầu ngắn.`,"api.rotation.start":`Bắt đầu luân chuyển`,"api.rotation.starting":`Đang bắt đầu…`,"api.rotation.pending":`Quá trình luân chuyển đang chờ xử lý. Hãy cập nhật và xác minh client trước khi xác nhận (commit).`,"api.rotation.expires":`Thời gian gối đầu (overlap) hết hạn lúc:`,"api.rotation.secretOnce":`Khóa thay thế — chỉ hiển thị một lần. Hãy sao chép nó trước khi đóng thông báo này.`,"api.rotation.commit":`Xác nhận luân chuyển`,"api.rotation.abort":`Hủy luân chuyển`,"api.rotation.failed":`Hành động luân chuyển không thể hoàn tất. Hãy làm mới trước khi thử lại.`,"api.rotation.startFailed":`Không thể bắt đầu luân chuyển khóa.`,"api.key.copyFailed":`Không thể sao chép khóa. Hãy chọn và sao chép thủ công trước khi đóng bảng này.`,"api.attribution.title":`Mức sử dụng được quy kết`,"api.attribution.requests7d":`Số requests, 7 ngày qua`,"api.attribution.totalRequests":`Tổng số requests được quy kết`,"api.attribution.totalRequestsAvailable":`Số requests trong lịch sử hiện có`,"api.attribution.sinceAvailable":`Dữ liệu quy kết có sẵn từ`,"api.attribution.lastUsed":`Lần sử dụng cuối`,"api.attribution.since":`Dữ liệu quy kết có sẵn từ`,"api.attribution.neverUsed":`Chưa được sử dụng kể từ khi bắt đầu quy kết`,"api.attribution.unavailable":`Không có dữ liệu sử dụng`,"api.attribution.unavailableDetail":`Chưa có mức sử dụng nào được quy kết. Các requests được ghi nhận trước khi tính năng quy kết bắt đầu sẽ không thể được gán hồi tố.`,"api.attribution.ambiguous":`Có hai khóa dùng chung ID này, do đó không thể quy kết mức sử dụng cho một trong số chúng. Hãy cung cấp cho mỗi khóa một ID duy nhất trong tệp cấu hình.`,"api.attribution.railAmbiguous":`trùng ID`,"claude.subtitle":`Sử dụng GPT, Gemini và các model khác bên trong Claude Code.`,"claude.pageTitle":`Claude Code`,"claude.workspace.settings":`Cài đặt`,"claude.enabledLabel":`Kết nối Claude`,"claude.enabledHint":`Khi tắt, Claude Code không thể sử dụng proxy này.`,"claude.authMode":`Chế độ xác thực`,"claude.authModeHint":`Chế độ Subscription yêu cầu tài khoản Claude, chế độ Proxy hoạt động mà không cần tài khoản Anthropic`,"claude.authModeSubscription":`Subscription (Tài khoản Claude)`,"claude.authModeProxy":`Proxy (Không cần tài khoản)`,"claude.authModeAuto":`Auto (Tự động phát hiện xác thực Claude)`,"claude.effectiveMode.label":`Sẽ có hiệu lực ở lần khởi chạy tiếp theo`,"claude.effectiveMode.manual":`Thủ công: {mode}`,"claude.effectiveMode.autoPresent":`Tự động: subscription — tìm thấy xác thực Claude thông qua {source}`,"claude.effectiveMode.autoAbsent":`Tự động: chế độ proxy — không tìm thấy xác thực Claude`,"claude.effectiveMode.autoUnknown":`Tự động: subscription — không thể xác minh xác thực`,"claude.effectiveMode.admissionKey":`Khóa API của proxy này vẫn được gửi đi.`,"claude.authSource.claude-json-oauth":`tài khoản Claude`,"claude.authSource.claude-credentials-file":`tệp credentials`,"claude.authSource.macos-keychain":`macOS Keychain`,"claude.authSource.exported-env":`biến môi trường (environment variable)`,"claude.authSource.unknown":`một credential được phát hiện`,"claude.systemEnv":`Tự động kết nối`,"claude.systemEnvDesc":`Khi bật, việc chạy claude trong bất kỳ terminal nào cũng sẽ tự động đi qua proxy.`,"claude.systemEnvUnsupported":`Tự động kết nối chỉ khả dụng trên macOS. Trên hệ thống này, hãy khởi chạy Claude bằng {cmd}.`,"claude.systemEnvWarn":`⚠ Bạn phải thoát hoàn toàn và mở lại ứng dụng terminal để thay đổi này có hiệu lực. Không khuyến khích.`,"claude.fastMode":`Chế độ Fast (OpenAI)`,"claude.fastModeDesc":`Kiểm soát service_tier cho các model OpenAI. ON = priority (nhanh hơn). OFF = default. Auto = passthrough (client tự quyết định).`,"claude.fastAuto":`Tự động`,"claude.fastOn":`BẬT`,"claude.fastOff":`TẮT`,"claude.autoContext":`Tự động sử dụng ngữ cảnh lớn (big context)`,"claude.autoContextDesc":`Kiểm soát phạm vi áp dụng nhãn 1M. ON: bất kỳ model nào có cửa sổ (window) đủ lớn để chứa ngưỡng nén (compaction threshold) đều sẽ có hàng big-context. OFF: chỉ những model thực sự đạt 1M mới có.`,"claude.autoContextInert":`Bị vô hiệu hóa vì giá trị kích thước ngữ cảnh (maxContextTokens) cũ vẫn tồn tại trong tệp cấu hình. Hãy xóa nó ở đó để kích hoạt lại.`,"claude.autoCompactWindow":`Điểm tự động tóm tắt`,"claude.autoCompactDefault":`{value} (mặc định)`,"claude.autoCompactWindowDesc":`Các tin nhắn cũ hơn sẽ được tóm tắt khi cuộc trò chuyện đạt đến điểm này. Nó không bao giờ vượt qua giới hạn riêng của từng model, do đó các model 200k sẽ không bị ảnh hưởng.`,"claude.autoCompactWindowWarn":`Việc thay đổi điều này có thể làm hỏng các model GPT — nếu đặt cao hơn giới hạn thực của model, các cuộc trò chuyện sẽ gặp lỗi trước khi quá trình tóm tắt bắt đầu.`,"claude.injectAgents":`Tự động đăng ký các subagent`,"claude.injectAgentsDesc":`Đăng ký các model được chọn trên thẻ Subagents (cộng với model mặc định hiện tại) làm các agent Claude Code có thể điều phối (ocx-*). Có hiệu lực từ phiên làm việc tiếp theo.`,"claude.webSearchSidecar":`Ghi đè sidecar tìm kiếm web`,"claude.webSearchSidecarHint":`Ghi đè sidecar tìm kiếm web chính đối với các yêu cầu từ Claude Code.`,"claude.visionSidecar":`Ghi đè sidecar thị giác (vision sidecar)`,"claude.visionSidecarHint":`Ghi đè sidecar thị giác chính đối với các yêu cầu từ Claude Code.`,"claude.useMainSetting":`Sử dụng thiết lập chính`,"claude.sidecarModelPlaceholder":`Model thiết lập chính`,"claude.quickstart":`Bắt đầu`,"claude.quickstartHint":`{cmd} sẽ mở Claude Code thông qua proxy. Phiên đăng nhập claude.ai của bạn vẫn được giữ nguyên.`,"claude.manualEnv":`Thiết lập thủ công (nâng cao)`,"claude.smallFastModel":`Model hỗ trợ nền (Background helper model)`,"claude.smallFastModelHint":`Model mà Claude Code sử dụng cho các tác vụ nền như tóm tắt trò chuyện và phát hiện chủ đề. Bí danh (alias) của subagent haiku cũng sử dụng nó. Bỏ trống = Mặc định của Claude (Haiku).`,"claude.smallFastModelAccurateHint":`Model mà Claude Code sử dụng cho các tác vụ nền như tóm tắt trò chuyện và phát hiện chủ đề. Bí danh của subagent haiku cũng sử dụng nó.`,"claude.smallFastModelUnsetOption":`Để Claude Code tự chọn (native model)`,"claude.smallFastModelNativeWarning":`Khi bỏ trống, OpenCodex sẽ không ghi đè model hỗ trợ (helper-model). Claude Code có thể sử dụng model Sonnet gốc của nó, điều này có thể phát sinh chi phí từ provider gốc của bạn.`,"claude.slotUnset":`Sử dụng mặc định của Claude`,"claude.modelMap":`Đánh chặn model (Model interception)`,"claude.modelMapHint":`Đánh chặn các yêu cầu đến một model cụ thể và định tuyến lại sang model bạn chọn. Mặc định là trống — sẽ không có gì xảy ra cho đến khi bạn thêm một quy tắc (rule).`,"claude.mapFrom":`Model gốc (ví dụ: claude-sonnet-4-5)`,"claude.mapTo":`Chuyển đổi thành (ví dụ: gemini/gemini-3-pro)`,"claude.addMapping":`Thêm quy tắc`,"claude.removeMapping":`Xóa quy tắc`,"claude.aliases":`Các model có sẵn`,"claude.aliasesHint":`Các model xuất hiện trong menu /model của Claude Code.`,"claude.aliasProviderOther":`Khác`,"claude.loading":`Đang tải…`,"claude.loadFail":`Không thể tải cài đặt Claude`,"claude.saved":`Đã lưu.`,"claude.saveFailed":`Lưu thất bại`,"claude.networkError":`Lỗi mạng — proxy có đang chạy không?`,"claude.toggleAria":`Bật/tắt kết nối Claude`,"claude.none":`Không có`,"cws.loading":`Đang tải các combo…`,"cws.loadFailed":`Không thể tải các combo.`,"cws.saveFailed":`Không thể lưu combo.`,"cws.removeFailed":`Không thể xóa combo.`,"cws.saved":`Đã lưu combo.`,"cws.created":`Đã tạo {model}.`,"cws.removed":`Đã xóa combo/{id}.`,"cws.renamed":`Đã đổi tên {from} thành {to}.`,"cws.add":`Thêm combo`,"cws.addTitle":`Thêm combo`,"cws.addSubtitle":`Tạo một model ảo (virtual model) xuyên suốt các provider và chọn chính xác tên model mà các client sẽ gọi.`,"cws.create":`Tạo combo`,"cws.railAria":`Danh sách combo`,"cws.searchPlaceholder":`Tìm kiếm combo hoặc mục tiêu (target)…`,"cws.noSearchResults":`Không có combo nào khớp với tìm kiếm của bạn.`,"cws.group.failover":`Failover`,"cws.group.roundRobin":`Round-robin`,"cws.group.other":`Các chiến lược khác`,"cws.targetCount":`{count} mục tiêu`,"cws.targetCountOne":`1 mục tiêu`,"cws.overviewTitle":`Combos`,"cws.overviewBlurb":`Các model ảo thực hiện định tuyến qua các mục tiêu provider/model với các cơ chế như failover, round-robin, weighted random (ngẫu nhiên có trọng số), least-used (ít được sử dụng nhất), hoặc soonest quota reset (đặt lại hạn ngạch sớm nhất).`,"cws.count.total":`Tổng cộng`,"cws.count.failover":`Failover`,"cws.count.roundRobin":`Round-robin`,"cws.count.other":`Khác`,"cws.howTitle":`Cách thức hoạt động`,"cws.howBody":`Hỏi Codex về tên model công khai (public model name) của combo. Nếu không có, mặc định sẽ là combo/<id>. OpenCodex sẽ chọn một mục tiêu và chỉ chuyển sang mục tiêu khác (hop) khi gặp các lỗi từ upstream có thể thử lại. Nếu không còn mục tiêu nào khả dụng, yêu cầu sẽ bị từ chối (fails closed) thay vì sử dụng provider mặc định toàn cục.`,"cws.attentionTitle":`Cần chú ý`,"cws.attention.empty":`Chưa có mục tiêu nào được cấu hình`,"cws.attention.few":`Chỉ có một mục tiêu — tính năng failover sẽ không có nơi nào để chuyển tiếp (hop)`,"cws.attention.catalogOmitted":`Bị thiếu khỏi danh mục model (model catalog) — các khả năng của thành viên bị thiếu hoặc không tương thích (thiếu cửa sổ ngữ cảnh / metadata, hoặc giao điểm phương thức bị rỗng). Tính năng định tuyến qua bí danh (alias) vẫn hoạt động`,"cws.attention.allTargetsExhausted":`Tất cả các mục tiêu được bật đều đã hết hạn ngạch (quota)`,"cws.emptyTitle":`Tạo combo đầu tiên của bạn`,"cws.empty.createDesc":`Đặt tên cho một model ảo và liên kết hai hoặc nhiều backend với nhau.`,"cws.backToAll":`Quay lại tất cả combo`,"cws.allCombos":`Tất cả combo`,"cws.copyModel":`Sao chép id`,"cws.copied":`Đã sao chép`,"cws.tabsLabel":`Các phần chi tiết của combo`,"cws.tab.config":`Cấu hình`,"cws.tab.about":`Thông tin`,"cws.strategy":`Chiến lược`,"cws.strategy.failover":`Failover`,"cws.strategy.roundRobin":`Round-robin`,"cws.strategy.random":`Ngẫu nhiên`,"cws.strategy.leastUsed":`Ít được sử dụng nhất (Least-used)`,"cws.strategy.resetWindow":`Reset-window`,"cws.strategy.failoverHint":`Thử các mục tiêu theo thứ tự. Nếu mục tiêu đầu tiên gặp lỗi có thể thử lại (rate limit, mất kết nối, chặn subscription), sẽ chuyển tiếp (hop) sang mục tiêu tiếp theo.`,"cws.strategy.roundRobinHint":`Cân bằng lưu lượng một cách tất định (deterministically) theo trọng số. Giữ nguyên mục tiêu được chọn cho một loạt các yêu cầu thành công, sau đó chuyển sang mục tiêu tiếp theo.`,"cws.strategy.randomHint":`Rút ngẫu nhiên một mục tiêu đủ điều kiện cho mỗi yêu cầu, với tỷ lệ thuận theo trọng số. Không giữ nguyên trạng thái (stickiness) giữa các yêu cầu.`,"cws.strategy.leastUsedHint":`Định tuyến từng yêu cầu đến mục tiêu đủ điều kiện có số lượng thành công được ghi nhận ít nhất. Số đếm sẽ khởi động lại cùng với proxy.`,"cws.strategy.resetWindowHint":`Ưu tiên mục tiêu đủ điều kiện có thời gian đặt lại hạn ngạch (quota window) sớm nhất. Sẽ chuyển về thứ tự cấu hình khi dữ liệu hạn ngạch bị thiếu.`,"cws.field.id":`Id của combo`,"cws.field.idHint":`Các client sẽ gửi yêu cầu tới {model}`,"cws.field.idInternalHint":`Id nội bộ của combo. Bạn có thể thay đổi nó sau khi tạo.`,"cws.field.idHintEdit":`Việc đổi tên sẽ chuyển combo sang một id mới. Các client sẽ gửi yêu cầu tới {model}.`,"cws.field.alias":`Tên model công khai (Public model name)`,"cws.field.aliasPlaceholder":`deepseek-v4-flash hoặc vendor/model`,"cws.field.aliasHint":`Tùy chọn. Sử dụng một tên trần (bare name) không có tiền tố, một tiền tố tùy chỉnh như vendor/model, hoặc để trống để sử dụng combo/<id>.`,"cws.field.nativeAlias":`Bí danh OpenAI gốc (Native OpenAI alias)`,"cws.field.nativeAliasHint":`Cho phép combo này sở hữu một id model OpenAI gốc (unqualified) được hỗ trợ. Các định tuyến OpenAI được chỉ định qua tài khoản và provider sẽ được giữ tách biệt.`,"cws.field.displayName":`Tên hiển thị`,"cws.field.displayNameHint":`Nhãn hiển thị trên bộ chọn (picker) cho combo này. Bắt buộc khi tính năng Bí danh OpenAI gốc (Native OpenAI alias) được bật.`,"cws.field.stickyLimit":`Số lần thành công giữ nguyên trước khi xoay vòng (rotate)`,"cws.field.stickyLimitHint":`Giữ nguyên mục tiêu được chọn cho từng này yêu cầu thành công trước khi bộ chọn theo trọng số (weighted selector) chuyển tiếp.`,"cws.field.defaultEffort":`Suy luận (reasoning) mặc định`,"cws.field.defaultEffortNone":`Không (mặc định của mục tiêu)`,"cws.field.defaultEffortHint":`Chỉ sử dụng khi client không chỉ định mức độ suy luận (reasoning effort). Các tùy chọn là giao điểm của các mức độ được công bố từ các mục tiêu đã chọn; những mục tiêu không có metadata về mức độ suy luận trong danh mục sẽ không cung cấp tùy chọn này.`,"cws.capability.imageInputUnavailable":`Không khả dụng cho đến khi mọi mục tiêu được chọn đều hỗ trợ đầu vào hình ảnh (image input).`,"cws.capability.imageInputHint":`Được bật theo mặc định khi mọi mục tiêu đều hỗ trợ hình ảnh. Tắt để chỉ chấp nhận văn bản.`,"cws.capability.imageInput":`Hình ảnh / đa phương thức (multimodal)`,"cws.capability.adaptiveEffort":`Thang suy luận thích ứng (Adaptive reasoning ladder)`,"cws.capability.adaptiveEffortHint":`Tắt: một mục tiêu không có kiểm soát suy luận sẽ ẩn đi bộ chọn mức độ (effort picker) cho toàn bộ combo. Bật: những mục tiêu đó vẫn có thể sử dụng và bộ chọn sẽ giữ lại các cấp độ mà các mục tiêu còn lại dùng chung.`,"cws.capabilities":`Khả năng (Capabilities)`,"cws.field.defaultEffortUnsupported":`Mức độ (effort) này không nằm trong thang dùng chung của các mục tiêu — nó sẽ bị bỏ qua hoặc tự điều chỉnh vào thời điểm gửi yêu cầu.`,"cws.field.defaultEffortUnsupportedOption":`không nằm trong giao điểm`,"cws.targets":`Mục tiêu (Targets)`,"cws.targets.failoverHint":`Thứ tự rất quan trọng — mục tiêu đầu tiên là ưu tiên chính (primary).`,"cws.targets.roundRobinHint":`Trọng số kiểm soát việc lựa chọn tương đối một cách tất định; thứ tự sẽ phá vỡ thế cân bằng (tie-breaker) trong vòng xoay (rotation ring).`,"cws.targets.randomHint":`Trọng số kiểm soát tỷ lệ cược của mỗi lần rút (draw); thứ tự không quan trọng.`,"cws.targets.leastUsedHint":`Thứ tự chỉ dùng để phá vỡ thế cân bằng giữa các mục tiêu được sử dụng với tần suất như nhau.`,"cws.targets.resetWindowHint":`Thứ tự được áp dụng khi dữ liệu hạn ngạch bị thiếu hoặc ngang bằng nhau.`,"cws.target.provider":`Nhà cung cấp`,"cws.target.model":`Model`,"cws.target.weight":`Trọng số (Weight)`,"cws.target.pickProvider":`Chọn provider…`,"cws.target.pickProviderFirst":`Hãy chọn một provider trước…`,"cws.target.pickModel":`Chọn model…`,"cws.target.noModels":`Không có model nào cho provider này`,"cws.target.modelPlaceholder":`id của model`,"cws.target.add":`Thêm mục tiêu`,"cws.target.drag":`Kéo để sắp xếp lại`,"cws.target.moveUp":`Di chuyển lên`,"cws.target.moveDown":`Di chuyển xuống`,"cws.quota.available":`Khả dụng`,"cws.quota.exhausted":`Hết hạn ngạch`,"cws.quota.unknown":`Không xác định hạn ngạch`,"cws.quota.allExhausted":`Tất cả các mục tiêu được bật đều đã hết hạn ngạch. Hãy chọn một mục tiêu khác hoặc chờ hạn ngạch được phục hồi.`,"cws.aboutTitle":`Thời gian chạy (Runtime)`,"cws.aboutBody":`Các mục tiêu gặp lỗi sẽ được làm mát (cool down) trong một khoảng thời gian ngắn, tuân theo Retry-After. Các lỗi ngữ cảnh (context error) hoặc không hợp lệ sẽ không bị chuyển tiếp (hop). Mỗi mục tiêu sẽ thích ứng mức độ suy luận (effort) theo khả năng riêng của nó; các combo đã cạn kiệt sẽ bị từ chối (fail closed). Nhật ký (Logs) và Mức sử dụng (Usage) sẽ giữ nguyên thứ tự các lần thử vật lý và mức sử dụng trên từng lần thử.`,"cws.removeConfirmTitle":`Xóa {model}?`,"cws.removeConfirmDesc":`Hành động này sẽ xóa model ảo khỏi cấu hình và danh mục Codex. Nó không xóa bất kỳ provider nào.`,"cws.unsavedTitle":`Các thay đổi chưa được lưu`,"cws.unsavedDesc":`Loại bỏ các chỉnh sửa đối với combo này và tiếp tục?`,"cws.keepEditing":`Tiếp tục chỉnh sửa`,"cws.err.missingId":`Bắt buộc phải có Id của combo.`,"cws.err.invalidId":`Id phải bắt đầu bằng một chữ cái hoặc số và chỉ sử dụng các chữ cái, số, dấu chấm, dấu gạch dưới hoặc dấu gạch ngang (tối đa 64 ký tự).`,"cws.err.duplicateId":`Đã tồn tại một combo với id này.`,"cws.err.invalidAlias":`Bí danh (alias) phải sử dụng các chữ cái, số, dấu chấm, dấu gạch dưới hoặc dấu gạch ngang, với tối đa một phân đoạn "/".`,"cws.err.aliasReservedNamespace":`Bí danh không được sử dụng namespace dành riêng "combo/".`,"cws.err.aliasNativeFamily":`Không được phép sử dụng các bí danh trần (bare aliases) thuộc bộ OpenAI gốc (gpt-*, o1-*, o3-*, o4-*, codex-*).`,"cws.err.unsupportedNativeAlias":`Bí danh gốc (native alias) phải là một id model OpenAI trần (bare OpenAI model id) hiện đang được hỗ trợ.`,"cws.err.missingNativeAliasDisplayName":`Bắt buộc phải có tên hiển thị đối với các bí danh gốc.`,"cws.err.invalidDisplayName":`Tên hiển thị phải có tối đa 128 ký tự và không chứa các ký tự điều khiển (control characters).`,"cws.err.duplicateAlias":`Một combo khác đã sử dụng bí danh này.`,"cws.err.noTargets":`Hãy thêm ít nhất một mục tiêu.`,"cws.err.incompleteTarget":`Mỗi mục tiêu cần một provider và model.`,"cws.target.disabled":`{name} (bị vô hiệu hóa)`,"cws.err.reservedNamespace":`Một provider vật lý có tên là combo phải được đổi tên trước khi tạo các combo.`,"cws.err.providerCollision":`ID của combo bị xung đột với một tên provider đã được cấu hình.`,"cws.err.unknownProvider":`Mỗi mục tiêu phải sử dụng một provider đã được cấu hình.`,"cws.err.duplicateTarget":`Cùng một mục tiêu provider/model chỉ có thể xuất hiện một lần.`,"cws.err.invalidStickyLimit":`Số lần thành công giữ nguyên (sticky successes) phải là một số nguyên từ 1 đến 100.`,"cws.err.invalidWeight":`Mỗi trọng số round-robin phải là một số nguyên từ 1 đến 10000.`,"cws.err.noEnabledTarget":`Ít nhất một mục tiêu phải sử dụng một provider đã được bật.`,"claude.tabsLabel":`Client Claude`,"claude.tabCode":`Code`,"claude.tabDesktop":`Desktop`,"claudeDesktop.title":`Claude Desktop`,"claudeDesktop.subtitle":`Định tuyến từng họ model (model family) Claude thông qua một model khả dụng trên cổng {port}.`,"claudeDesktop.importJson":`Nhập JSON`,"claudeDesktop.exportJson":`Xuất JSON`,"claudeDesktop.loading":`Đang tải hồ sơ Claude Desktop…`,"claudeDesktop.loadFail":`Không thể tải hồ sơ Claude Desktop.`,"claudeDesktop.retry":`Thử lại`,"claudeDesktop.saveFailed":`Không thể lưu hồ sơ Claude Desktop.`,"claudeDesktop.applyFailed":`Hồ sơ đã được lưu, nhưng không thể áp dụng.`,"claudeDesktop.updateFailed":`Cập nhật Claude Desktop thất bại.`,"claudeDesktop.savedApplied":`Hồ sơ đã được lưu và áp dụng cho Claude Desktop.`,"claudeDesktop.appliedMarkerUnsaved":`Đã được áp dụng cho Claude Desktop, nhưng dấu (marker) áp dụng chưa được lưu — trạng thái đã lưu-so với-đã áp dụng bên dưới có thể hiển thị dữ liệu cũ cho đến khi bạn áp dụng lại.`,"claudeDesktop.savedAppliedAnnounce":`Hồ sơ Claude Desktop đã được lưu và áp dụng.`,"claudeDesktop.saved":`Hồ sơ đã được lưu.`,"claudeDesktop.savedAnnounce":`Hồ sơ Claude Desktop đã được lưu.`,"claudeDesktop.exported":`Hồ sơ đã được xuất dưới dạng JSON.`,"claudeDesktop.importExpected":`Cần có một hồ sơ Claude Desktop phiên bản 1.`,"claudeDesktop.importReady":`Đã nhập JSON. Hãy xem lại bản nháp, sau đó lưu và áp dụng.`,"claudeDesktop.importedAnnounce":`Đã nhập JSON hồ sơ. Các thay đổi chưa được lưu đã sẵn sàng để xem xét.`,"claudeDesktop.importInvalid":`Tệp đã chọn không phải là một hồ sơ hợp lệ.`,"claudeDesktop.importFailed":`Nhập thất bại. {error}`,"claudeDesktop.moved":`{route} đã được chuyển đến {family}.`,"claudeDesktop.unsaved":`Các thay đổi chưa được lưu`,"claudeDesktop.upToDate":`Hồ sơ đã được cập nhật`,"claudeDesktop.saving":`Đang lưu…`,"claudeDesktop.applying":`Đang áp dụng…`,"claudeDesktop.saveApply":`Lưu & áp dụng`,"claudeDesktop.emptyTitle":`Không có model nào khả dụng`,"claudeDesktop.emptyHint":`Hãy thêm hoặc bật một provider, sau đó quay lại để chỉ định các định tuyến cho Claude Desktop.`,"claudeDesktop.assignmentsLabel":`Các chỉ định họ model Claude`,"claudeDesktop.family.opus":`Opus`,"claudeDesktop.family.fable":`Fable`,"claudeDesktop.family.sonnet":`Sonnet`,"claudeDesktop.family.haiku":`Haiku`,"claudeDesktop.modelCountOne":`{count} model`,"claudeDesktop.modelCountMany":`{count} model`,"claudeDesktop.chooseDefault":`Chọn một model mặc định`,"claudeDesktop.temporaryDefault":`Mặc định tạm thời`,"claudeDesktop.laneEmpty":`Thả một model vào đây hoặc sử dụng bộ điều khiển Di chuyển (Move) của nó.`,"claudeDesktop.laneNoMatch":`Không có model nào trong họ này khớp với tìm kiếm của bạn.`,"nav.grok":`Grok`,"grok.title":`Grok Build`,"grok.subtitle":`Các model mà opencodex đã đăng ký trong cấu hình Grok của bạn.`,"grok.loading":`Đang tải trạng thái Grok…`,"grok.loadFail":`Không thể đọc cấu hình Grok.`,"grok.notConfiguredTitle":`Grok Build chưa được kết nối`,"grok.notConfiguredHint":`Hãy khởi động hoặc khởi động lại proxy với Grok đã được cài đặt và opencodex sẽ ghi một khối được quản lý (managed block) vào:`,"grok.endpoint":`Endpoint`,"grok.colModel":`Model`,"grok.colAlias":`Bí danh Grok`,"grok.colContext":`Ngữ cảnh (Context)`,"grok.groupNative":`Các model gốc (Native models)`,"grok.groupRouted":`Các model được định tuyến (Routed models)`,"grok.enabledCount":`Đã đăng ký {on} trong tổng số {total}`,"grok.saved":`Đã lưu lựa chọn.`,"grok.savedApplied":`Lựa chọn đã được lưu và được ghi vào cấu hình Grok của bạn.`,"grok.saveFailed":`Không thể lưu lựa chọn Grok.`,"grok.applyFailed":`Lựa chọn đã được lưu, nhưng cấu hình Grok không thể được cập nhật.`,"grok.applySkipped":`Lựa chọn đã được lưu. Cấu hình Grok không thay đổi.`,"grok.saveApply":`Lưu & áp dụng`,"grok.saving":`Đang lưu…`,"grok.applying":`Đang áp dụng…`,"grok.unsaved":`Các thay đổi chưa được lưu`,"grok.upToDate":`Lựa chọn đã được cập nhật`,"grok.toggleModel":`Đăng ký {id} với Grok`,"claudeDesktop.available":`Khả dụng`,"claudeDesktop.defaultBadge":`Mặc định`,"claudeDesktop.supports1m":`1M`,"claudeDesktop.unavailable":`Không khả dụng`,"claudeDesktop.contextM":`ngữ cảnh {n}M`,"claudeDesktop.contextK":`ngữ cảnh {n}k`,"claudeDesktop.contextUnknown":`không xác định ngữ cảnh`,"claudeDesktop.alias":`Bí danh`,"claudeDesktop.useAsDefault":`Sử dụng làm mặc định cho {family}`,"claudeDesktop.moveTo":`Chuyển đến`,"claudeDesktop.move":`Di chuyển`,"claudeDesktop.status.applied":`Đã áp dụng cho Desktop`,"claudeDesktop.status.stale":`Cấu hình đã cũ — hãy áp dụng lại`,"claudeDesktop.status.notApplied":`Chưa được áp dụng`,"claudeDesktop.status.notActiveProfile":`Desktop đang phục vụ một hồ sơ khác — hãy áp dụng lại`,"claudeDesktop.status.disabled":`Tiện ích tích hợp Claude Desktop đang tắt. Hãy thoát hoàn toàn và mở lại Desktop sau khi bật nó.`,"claudeDesktop.enableApply":`Bật và áp dụng`,"claudeDesktop.switchModeApply":`Đổi chế độ & áp dụng`,"claudeDesktop.status.appliedFirstParty":`First-party: tab Code đi qua proxy cục bộ`,"claudeDesktop.mode.legend":`Chế độ kết nối`,"claudeDesktop.mode.firstParty":`First-party`,"claudeDesktop.mode.gateway":`Gateway (bên thứ ba)`,"claudeDesktop.mode.defaultBadge":`mặc định`,"claudeDesktop.mode.current":`hiện tại`,"claudeDesktop.mode.firstPartyHint":`Desktop vẫn đăng nhập claude.ai (chat, connector, điều khiển từ xa). Chỉ tab Code, các subagent và Claude Code CLI đi qua OpenCodex.`,"claudeDesktop.mode.gatewayHint":`Toàn bộ ứng dụng chuyển sang dùng OpenCodex làm gateway. Chat chạy cục bộ; các tính năng claude.ai không khả dụng.`,"claudeDesktop.mode.switchNote":`Chuyển chế độ sẽ xóa cấu hình của chế độ kia. Sau đó hãy thoát hẳn Desktop rồi mở lại.`,"claudeDesktop.firstParty.proxyRunning":`Proxy cục bộ tại 127.0.0.1:{port}`,"claudeDesktop.firstParty.proxyStopped":`Proxy cục bộ 127.0.0.1:{port} không chạy — khởi động lại OpenCodex`,"claudeDesktop.firstParty.interceptDisabled":`Proxy chặn bắt đã bị tắt trong cấu hình (claudeCode.intercept.enabled)`,"claudeDesktop.health.lastRequest":`Yêu cầu cuối cùng (Last request)`,"claudeDesktop.health.stats":`{count} req / {errors} err`,"claudeDesktop.effort.supported":`suy luận (effort)`,"claudeDesktop.effort.displayOnly":`suy luận (chỉ hiển thị)`,"lab.title":`Phòng thí nghiệm tương thích`,"lab.subtitle":`Ma trận phán quyết tính tương thích (compatibility verdict matrix) chỉ đọc từ các bằng chứng dự báo của lab.`,"lab.loadFailed":`Không thể tải dữ liệu compatibility lab`,"lab.projectionUnavailable":`Dự báo của lab không có sẵn. Hãy chạy các bài kiểm tra conformance (tính tuân thủ) hoặc live probes (thăm dò trực tiếp) trước.`,"lab.projectionIncompatible":`Lược đồ dự báo của lab không tương thích. Hãy xây dựng lại dự báo (projection).`,"lab.statusTitle":`Trạng thái dự báo`,"lab.matrixTitle":`Ma trận tương thích`,"lab.verdictsTitle":`Các bản ghi phán quyết (Verdict records)`,"lab.filter.layer":`Lớp bằng chứng (Evidence layer)`,"lab.filter.verdict":`Phán quyết (Verdict)`,"lab.filter.subject":`ID đối tượng (Subject ID)`,"lab.filter.all":`Tất cả`,"lab.col.subject":`Đối tượng (Subject)`,"lab.col.layer":`Lớp (Layer)`,"lab.col.suite":`Bộ kiểm thử (Suite)`,"lab.col.verdict":`Phán quyết`,"lab.col.asOf":`Tính đến`,"lab.col.protocol":`Tuân thủ giao thức (Protocol conformance)`,"lab.col.live":`Tính tương thích của định tuyến trực tiếp (Live route compatibility)`,"lab.col.task":`Hiệu quả tác vụ (Task effectiveness)`,"lab.empty":`Chưa có phán quyết tương thích nào trong dự báo.`,"lab.subjectKind":`Loại (Kind)`,"lab.observationCount":`Quan sát (Observations)`,"lab.eventCount":`Sự kiện (Events)`,"lab.verdictCount":`Phán quyết (Verdicts)`,"lab.subjectCount":`Đối tượng (Subjects)`,"lab.builtAt":`Đã xây dựng`,"lab.loading":`Đang tải bằng chứng tương thích…`,"lab.loadMore":`Tải thêm`,"lab.detailTitle":`Chi tiết phán quyết`,"lab.detailClose":`Đóng`,"lab.detailSubject":`Đối tượng`,"lab.detailObservations":`Quan sát`,"lab.detailEvents":`Các sự kiện đóng góp (Contributing events)`,"lab.detailArtifacts":`Siêu dữ liệu artifact (Artifact metadata)`,"lab.production.title":`Lưu lượng truy cập production được quan sát`,"lab.production.notVerification":`Không phải quy trình xác minh Lab (Lab verification)`,"lab.production.attempts":`Số lần thử (Attempts)`,"lab.production.successes":`Thành công (Successes)`,"lab.production.routeErrors":`Lỗi định tuyến (Route errors)`,"lab.production.lastObserved":`Quan sát lần cuối`,"lab.detailLoadFailed":`Không thể tải chi tiết phán quyết`,"lab.refresh":`Làm mới`,"lab.verdict.UNKNOWN":`Không xác định`,"lab.verdict.CLAIMED":`Đã xác nhận (Claimed)`,"lab.verdict.PROBED":`Đã thăm dò (Probed)`,"lab.verdict.VERIFIED":`Đã xác minh (Verified)`,"lab.verdict.DEGRADED":`Đã xuống cấp (Degraded)`,"lab.verdict.BLOCKED":`Đã bị chặn (Blocked)`,"lab.verdict.UNSUPPORTED":`Không được hỗ trợ (Unsupported)`,"lab.layer.protocol_conformance":`Tuân thủ giao thức (Protocol conformance)`,"lab.layer.live_route_compatibility":`Tính tương thích của định tuyến trực tiếp (Live route compatibility)`,"lab.layer.task_effectiveness":`Hiệu quả tác vụ (Task effectiveness)`,"models.aliases":`Bí danh (Aliases)`,"models.aliasesTable":`Bảng bí danh (Alias table)`,"models.aliasPrompt":`Bí danh provider (để trống để xóa)`,"models.modelAliasPrompt":`Bí danh model (để trống để xóa)`,"models.aliasSaved":`Đã lưu bí danh`,"models.aliasConflict":`Bí danh đó xung đột với một tên đã tồn tại`,"models.editProviderAlias":`Chỉnh sửa bí danh provider`,"models.editModelAlias":`Chỉnh sửa bí danh model`,"models.useDefaultAliases":`Sử dụng các bí danh mặc định`,"models.useDefaultAliasesGlobal":`Sử dụng các bí danh mặc định toàn cục`,"models.aliasAuto":`tự động (auto)`,"models.aliasUser":`người dùng (user)`,"models.aliasStale":`cũ (stale)`,"connection.discovering":`Đang khám phá các mục tiêu cục bộ (local) và được chia sẻ…`,"connection.machineUnavailable":`Mặt phẳng máy cục bộ (local machine plane) không khả dụng. Các yêu cầu chia sẻ đã không được chuyển hướng cục bộ.`,"connection.disconnect":`Ngắt kết nối khỏi hub`,"connection.disconnectConfirm":`Ngắt kết nối máy này khỏi hub và khởi động lại ở chế độ độc lập (standalone mode)?`,"connection.pairing.hub":`Hub`,"connection.pairing.getCode":`Chạy lệnh này trên hub cho trình duyệt này:`,"connection.pairing.askOperator":`Nếu người khác vận hành hub, hãy gửi lệnh này cho họ và yêu cầu mã ghép nối dùng một lần.`,"connection.pairing.notApiKey":`Dán mã ghép nối dùng một lần vào đây. Khóa API dữ liệu và admin token không thuộc trường này.`,"connection.pairing.networkError":`Không thể kết nối tới hub. Hãy kiểm tra kết nối và thử lại; mã của bạn vẫn còn ở đây.`,"connection.pairing.requestError":`Hub không thể hoàn tất yêu cầu ghép nối. Hãy kiểm tra trạng thái và thử lại.`,"connection.pairing.responseError":`Hub không trả về phiên trình duyệt hợp lệ. Hãy cập nhật hub hoặc nhờ người vận hành rồi thử lại.`,"dash.authRequired":`Cần xác thực trình duyệt để xem bảng điều khiển này.`,"dash.permissionDenied":`Trình duyệt này không được phép đọc bảng điều khiển. Hãy kiểm tra cài đặt truy cập với người vận hành máy chủ.`,"dash.dataUnavailable":`Không thể tải dữ liệu bảng điều khiển. Hãy kiểm tra kết nối và thử lại.`,"dash.staleData":`Đang hiển thị dữ liệu nhận được gần nhất; dữ liệu có thể đã cũ.`,"connection.pairing.title":`Kết nối dashboard này với hub`,"connection.pairing.body":`Dán mã ghép nối một lần (one-time pairing code) được tạo trên hub.`,"connection.pairing.relayWarning":`Mã này được trao đổi thông qua hub relay cố định. Không thể chuyển hướng relay sang một máy chủ khác.`,"connection.pairing.code":`Mã ghép nối một lần`,"connection.pairing.submit":`Kết nối`,"connection.pairing.submitting":`Đang kết nối…`,"connection.pairing.error":`Mã ghép nối đã bị từ chối hoặc hết hạn. Mã vẫn được giữ nguyên để bạn có thể kiểm tra.`,"connection.machine.title":`Máy này`,"connection.machine.shimHealthy":`Codex shim đang hoạt động bình thường.`,"connection.machine.shimNeedsAttention":`Codex shim cần được chú ý.`,"connection.machine.repairShim":`Sửa chữa shim`,"connection.machine.removeShim":`Xóa shim`,"connection.clients.title":`Các client đã kết nối`,"connection.clients.none":`Không có trạng thái client nào khả dụng`,"connection.clients.sync":`Đồng bộ ngay`,"connection.clients.syncing":`Đang đồng bộ…`,"connection.sessionLogout":`Đăng xuất phiên từ xa`,"connection.sessionLoggingOut":`Đang đăng xuất phiên từ xa…`,"connection.sessionLogoutFailed":`Không thể đăng xuất phiên từ xa. Phiên hiện tại vẫn được giữ nguyên.`,"usage.source.connected":`Nguồn: mức sử dụng hub`,"usage.source.local":`Nguồn: usage.jsonl cục bộ`,"usage.scope.label":`Phạm vi sử dụng`,"usage.scope.machine":`Máy này`,"usage.scope.hub":`Toàn bộ hub`,"usage.hubOffline":`Mức sử dụng hub không khả dụng. Mức sử dụng cục bộ đã không được dùng thay thế.`,"models.displayNameSavedRefreshFailed":`Thay đổi đã được lưu, nhưng không thể làm mới danh sách model. Hãy thử lại để làm mới nó.`,"models.displayNameOutcomeUnknown":`Yêu cầu chưa hoàn tất. Thay đổi có thể đã được lưu. Hãy thử lại để kiểm tra tên hiện tại trước khi thực hiện thay đổi khác.`,"models.displayNameCurrentUnavailable":`Tên hiện tại không khả dụng cho đến khi làm mới`,"models.displayNameReloaded":`Đã làm mới danh sách model`,"models.displayNameAction":`Tên`,"models.displayNameActionLabel":`Chỉnh sửa tên thân thiện (friendly name) cho {model}`,"models.displayNameTitle":`Tên thân thiện`,"models.displayNameModelId":`Model ID`,"models.displayNameCurrent":`Tên hiện tại`,"models.displayNameSourceOperator":`Tên của bạn`,"models.displayNameSourceProvider":`Tên provider`,"models.displayNameSourceFallback":`Dự phòng Model ID (Model ID fallback)`,"models.displayNameField":`Tên thân thiện`,"models.displayNamePlaceholder":`ví dụ: Grok 4.6`,"models.displayNameHelp":`Chỉ thay đổi cách hiển thị. Việc định tuyến vẫn là {model}.`,"models.displayNameReset":`Đặt lại tên`,"models.displayNameSaved":`Đã lưu tên hiển thị`,"models.displayNameResetDone":`Đã đặt lại tên hiển thị`,"models.displayNameSaveFailed":`Không thể lưu tên hiển thị`,"models.displayNameRequired":`Hãy nhập tên thân thiện, hoặc sử dụng Đặt lại tên.`,"models.displayNameTooLong":`Tên thân thiện phải có độ dài từ 128 ký tự trở xuống.`,"models.displayNameNoSlash":`Tên thân thiện không được chứa ký tự /.`,"models.displayNameNoControl":`Tên thân thiện không được chứa các ký tự điều khiển (control characters).`,"pricing.override.action":`Giá`,"pricing.override.actionLabel":`Chỉnh sửa giá cho {model}`,"pricing.override.badge":`Giá thủ công`,"pricing.override.title":`Giá model`,"pricing.override.modelId":`Model ID`,"pricing.override.help":`USD cho mỗi 1M token. Nhập mức giá đầu vào (input) và đầu ra (output); mức giá cache nếu để trống sẽ tính là 0. Đặt cả bốn mức giá bằng 0 nghĩa là miễn phí.`,"pricing.override.input":`Đầu vào (Input)`,"pricing.override.output":`Đầu ra (Output)`,"pricing.override.cacheRead":`Đọc bộ nhớ đệm (Cache read)`,"pricing.override.cacheWrite":`Ghi bộ nhớ đệm (Cache write)`,"pricing.override.loading":`Đang tải giá đã lưu…`,"pricing.override.loadFailed":`Không thể tải giá đã lưu. Hãy tải lại để thử lại.`,"pricing.override.outcomeUnknown":`Yêu cầu không hoàn tất một cách đáng tin cậy. Giá có thể đã thay đổi. Hãy tải lại giá đã lưu trước khi chỉnh sửa tiếp.`,"pricing.override.recoveryFailed":`Không thể khôi phục giá đã lưu. Chức năng chỉnh sửa vẫn bị khóa; hãy tải lại để thử lại.`,"pricing.override.recovered":`Đã tải giá được lưu mới nhất. Yêu cầu trước đó hoặc một client khác vẫn có thể thay đổi nó.`,"pricing.override.refreshFailed":`Giá đã được lưu, nhưng không thể làm mới danh sách model. Hãy thử làm mới lại danh sách.`,"pricing.override.invalid":`Hãy nhập mức giá đầu vào và đầu ra. Mỗi mức giá phải là một số hữu hạn từ 0 đến 1,000,000.`,"pricing.override.reset":`Đặt lại thành tự động`,"pricing.override.save":`Lưu`,"pricing.override.saving":`Đang lưu…`,"pricing.override.reload":`Tải lại giá`,"pricing.override.refresh":`Làm mới danh sách`,"pricing.override.cancel":`Hủy`,"pricing.override.close":`Đóng`,"usage.range.custom":`Phạm vi ngày tùy chỉnh`,"usage.range.start":`Bắt đầu (giờ địa phương)`,"usage.range.end":`Kết thúc (giờ địa phương)`,"usage.range.apply":`Áp dụng`,"usage.range.clear":`Xóa`,"usage.range.help":`Giờ địa phương. Bao gồm toàn bộ phút kết thúc.`,"usage.range.required":`Hãy nhập cả ngày và giờ bắt đầu cũng như kết thúc.`,"usage.range.invalid":`Hãy nhập ngày và giờ địa phương hợp lệ, từ ngày 1970-01-01 UTC trở đi.`,"usage.range.reversed":`Thời điểm kết thúc phải bằng hoặc sau thời điểm bắt đầu.`,"usage.range.applied":`Khoảng thời gian đã chọn: {start} – {end} (bao gồm cả hai).`,"models.pickerOrder.editorHint":`Sắp xếp lại các model được định tuyến, sau đó lưu bản nháp của bạn. Các hàng nổi bật (featured) được cố định; các model gốc (native) không được hiển thị.`,"models.pickerOrder.nativeLocked":`Thứ tự đã lưu này bao gồm các model gốc. Hãy áp dụng một cài đặt sẵn (preset) định tuyến hoặc Mặc định (Default) trước khi chỉnh sửa Tùy chỉnh (Custom).`,"models.pickerOrder.unknownChosen":`Các lựa chọn nổi bật không xác định. Hãy tải lại trước khi chỉnh sửa.`,"models.pickerOrder.changed":`Cài đặt bộ chọn (picker) đã thay đổi. Bản nháp của bạn vẫn được giữ lại; hãy tải lại để loại bỏ nó và sử dụng cài đặt hiện tại.`,"models.pickerOrder.savedReload":`Đã lưu thứ tự. Hãy tải lại cài đặt hiện tại trước khi chỉnh sửa lại.`,"models.pickerOrder.requestFailed":`Yêu cầu thất bại. Bản nháp của bạn vẫn được giữ lại; hãy thử lại hoặc tải lại.`,"models.pickerOrder.empty":`Không có model được định tuyến nào khả dụng.`,"models.pickerOrder.dragModel":`Kéo {model}`,"models.pickerOrder.featured":`Nổi bật (Featured)`,"models.pickerOrder.upModel":`Di chuyển {model} lên`,"models.pickerOrder.downModel":`Di chuyển {model} xuống`,"models.pickerOrder.position":`{model}: vị trí {position} trong số {total}`,"models.pickerOrder.saveDraft":`Lưu bản nháp`,"models.pickerOrder.reloadDraft":`Tải lại và bỏ bản nháp`,"models.pickerOrder.catalogRequired":`Danh tính của các model bị thiếu hoặc không rõ ràng. Hãy tải lại trang Models để làm mới danh mục của nó trước khi chỉnh sửa Tùy chỉnh (Custom).`,"nav.remote":`Không gian làm việc từ xa`,"remote.title":`Không gian làm việc từ xa`,"remote.subtitle":`Chạy Codex, Claude Code hoặc Pi từ Hub này trong khi tệp, lệnh, kiểm thử và bản dựng vẫn ở trên máy tính bạn chọn.`,"remote.loading":`Đang tải không gian làm việc từ xa…`,"remote.loadFailed":`Không thể tải không gian làm việc từ xa.`,"remote.hubRequired":`Hãy dùng chế độ Hub và khởi động Hub với OCX_REMOTE_WORKSPACE_ENABLED=1 để bật không gian làm việc từ xa.`,"remote.refresh":`Làm mới`,"remote.addComputer":`Thêm máy tính`,"remote.addComputerHint":`Phê duyệt một hoặc nhiều thư mục cục bộ, sau đó giữ executor chỉ dành cho OCX kết nối với Hub này.`,"remote.createPairing":`Tạo mã ghép nối`,"remote.pairingCode":`Mã ghép nối dùng một lần`,"remote.pairingExpires":`Hết hạn lúc {time}`,"remote.pairingCommand":`Chạy trên máy tính bạn đang thêm`,"remote.pairingCommandPosix":`Terminal Linux / macOS`,"remote.pairingCommandWindows":`Windows PowerShell`,"remote.copyCommand":`Sao chép lệnh`,"remote.copied":`Đã sao chép`,"remote.devices":`Máy tính`,"remote.noDevices":`Chưa có máy tính nào được ghép nối.`,"remote.online":`Trực tuyến`,"remote.offline":`Ngoại tuyến`,"remote.revoke":`Thu hồi máy tính`,"remote.revokeConfirm":`Thu hồi {name}? Các phiên đang hoạt động trên máy tính này sẽ dừng.`,"remote.newSession":`Phiên từ xa mới`,"remote.device":`Máy tính`,"remote.folder":`Thư mục không gian làm việc`,"remote.runtime":`Coding agent`,"remote.access":`Quyền truy cập không gian làm việc`,"remote.access.readOnly":`Chỉ đọc`,"remote.access.workspace":`Chỉnh sửa tệp và chạy lệnh`,"remote.access.workspaceFilesOnly":`Chỉ chỉnh sửa tệp`,"remote.unavailable":`Không khả dụng`,"remote.capability.full":`Tệp + lệnh trong sandbox`,"remote.capability.files":`Chỉ công cụ tệp`,"remote.runsOnHub":`Model và thông tin đăng nhập vẫn ở trên Hub này`,"remote.runsReadOnly":`Chỉ có thể đọc tệp trên máy tính này`,"remote.runsFilesCommands":`Tệp, bản dựng và lệnh chạy tại đây`,"remote.runsFilesOnly":`Công cụ tệp chạy tại đây; sandbox lệnh không khả dụng`,"remote.execUnavailable":`Máy tính này có thể chỉnh sửa tệp, nhưng bản dựng và lệnh terminal bị tắt vì không có sandbox hệ điều hành được hỗ trợ.`,"remote.notResumable":`Phiên này đã dừng trước khi coding agent tạo lịch sử bền vững. Hãy bắt đầu phiên từ xa mới.`,"remote.startSession":`Bắt đầu phiên từ xa`,"remote.sessionStarted":`Phiên từ xa đã sẵn sàng.`,"remote.sessions":`Phiên`,"remote.noSessions":`Hãy chọn máy tính trực tuyến, thư mục và coding agent để bắt đầu.`,"remote.events":`Hoạt động phiên từ xa`,"remote.noEvents":`Chưa có hoạt động.`,"remote.prompt":`Tin nhắn`,"remote.promptPlaceholder":`Yêu cầu agent trên Hub làm việc trong thư mục từ xa đã chọn…`,"remote.send":`Gửi`,"remote.stop":`Dừng phiên`,"remote.requestFailed":`Yêu cầu không gian làm việc từ xa thất bại.`,"remote.submissionUnknown":`Chưa rõ trạng thái gửi. Hãy kiểm tra phiên trước khi gửi lại.`,"remote.status.starting":`Đang khởi động`,"remote.status.ready":`Sẵn sàng`,"remote.status.running":`Đang chạy`,"remote.status.waiting":`Executor ngoại tuyến`,"remote.status.failed":`Thất bại`,"remote.status.stopped":`Đã dừng`,"remote.event.status":`Trạng thái`,"remote.event.tool":`Công cụ từ xa`,"remote.event.error":`Lỗi`,"models.newPolicyGlobal":`Model mới mặc định bị tắt`,"models.newPolicyProvider":`Chính sách model mới`,"models.newPolicy_inherit":`Kế thừa`,"models.newPolicy_off":`Tắt`,"models.newPolicy_on":`Bật`,"models.newBadge":`MỚI`,"models.newCount":`{count} model mới, đang tắt`,"codexSet.custom.deleteConfirm":`Xóa lớp này? Không thể hoàn tác.`,"codexSet.custom.moveUp":`Di chuyển {title} lên`,"codexSet.dialog.copyKey":`Sao chép khóa`,"codexSet.dialog.noRenderedText":`Codex không cung cấp nội dung đã ghép của một lớp tích hợp sẵn, nên hộp thoại này mô tả lớp và nêu tên khóa thay vì hiển thị nội dung của nó.`,"codexSet.dialog.notRendered":`Lớp này không gửi gì trong lượt đã đọc. Các phần chỉ được gửi lại khi thay đổi, nên một lớp không đổi sẽ vắng mặt trong một mẫu đơn lẻ.`,"codexSet.dialog.unknownLayer":`Bản dựng này không có mô tả cho lớp đó. Nó đến từ một runtime Codex mới hơn bảng điều khiển.`,"codexSet.layer.skills":`Skills`,"codexSet.lint.size":`Lớp này vượt quá 8 KB. Vẫn lưu được, nhưng sẽ tốn token trong mọi yêu cầu.`,"codexSet.prompt.extensionsUnknown":`Tiện ích mở rộng có thể thêm lớp riêng. Codex không cung cấp chúng, nên không thể liệt kê ở đây.`,"codexSet.prompt.loadFailed":`Không thể tải các lớp prompt.`,"codexSet.prompt.writeFailed":`Không thể lưu thay đổi.`,"codexSet.row.alwaysOn":`Luôn bật`,"codexSet.row.featureGated":`Được cấu hình trong [features]`,"common.discard":`Hủy bỏ`,"logs.filter.conversation.clear":`Xóa`,"modal.baseUrlPlaceholder":`https://...`,"nav.codexAuth":`Codex Auth`,"pws.noModelMatch":`Không có model nào khớp bộ lọc.`,"quota.fiveHourLimit":`Giới hạn 5 giờ`,"models.fastRows.title":`Hiển thị hàng model Fast`,"models.fastRows.desc":`Thêm các bộ chọn “Model Fast” đủ điều kiện vào trình chọn model của client bên ngoài. Việc này không thay đổi tùy chọn reasoning-effort của model gốc. Khi lưu, các tích hợp đang kết nối sẽ được làm mới nếu có thể; nếu không, hãy làm mới tích hợp hoặc catalog của client.`,"models.fastRows.refreshHint":`Đã lưu. Đang chờ làm mới catalog.`,"models.fastRows.enabled":`Đã bật hàng model Fast.`,"models.fastRows.disabled":`Đã tắt hàng model Fast.`,"models.fastRows.loadFailed":`Không thể tải cài đặt hàng Fast.`,"models.fastRows.updateFailed":`Không thể cập nhật cài đặt hàng Fast.`},ae={en:{"lab.title":`Compatibility Lab`,"lab.subtitle":`Read-only compatibility verdict matrix from lab projection evidence.`,"lab.loadFailed":`Could not load compatibility lab data`,"lab.projectionUnavailable":`Lab projection is not available. Run conformance or live probes first.`,"lab.projectionIncompatible":`Lab projection schema is incompatible. Rebuild the projection.`,"lab.statusTitle":`Projection status`,"lab.matrixTitle":`Compatibility matrix`,"lab.verdictsTitle":`Verdict records`,"lab.filter.layer":`Evidence layer`,"lab.filter.verdict":`Verdict`,"lab.filter.subject":`Subject ID`,"lab.filter.all":`All`,"lab.col.subject":`Subject`,"lab.col.layer":`Layer`,"lab.col.suite":`Suite`,"lab.col.verdict":`Verdict`,"lab.col.asOf":`As of`,"lab.col.protocol":`Protocol conformance`,"lab.col.live":`Live route compatibility`,"lab.col.task":`Task effectiveness`,"lab.empty":`No compatibility verdicts in the projection yet.`,"lab.subjectKind":`Kind`,"lab.observationCount":`Observations`,"lab.eventCount":`Events`,"lab.verdictCount":`Verdicts`,"lab.subjectCount":`Subjects`,"lab.builtAt":`Built`,"lab.loading":`Loading compatibility evidence…`,"lab.loadMore":`Load more`,"lab.detailTitle":`Verdict detail`,"lab.detailClose":`Close`,"lab.detailSubject":`Subject`,"lab.detailObservations":`Observations`,"lab.detailEvents":`Evidence events`,"lab.detailArtifacts":`Artifact metadata`,"lab.detailLoadFailed":`Could not load verdict detail`,"lab.refresh":`Refresh`,"lab.verdict.UNKNOWN":`Unknown`,"lab.verdict.CLAIMED":`Claimed`,"lab.verdict.PROBED":`Probed`,"lab.verdict.VERIFIED":`Verified`,"lab.verdict.DEGRADED":`Degraded`,"lab.verdict.BLOCKED":`Blocked`,"lab.verdict.UNSUPPORTED":`Unsupported`,"lab.layer.protocol_conformance":`Protocol conformance`,"lab.layer.live_route_compatibility":`Live route compatibility`,"lab.layer.task_effectiveness":`Task effectiveness`},de:{"lab.title":`Kompatibilitäts-Labor`,"lab.subtitle":`Schreibgeschützte Kompatibilitätsmatrix aus den Evidenzen der Lab-Projektion.`,"lab.loadFailed":`Kompatibilitätsdaten konnten nicht geladen werden`,"lab.projectionUnavailable":`Die Lab-Projektion ist nicht verfügbar. Führe zuerst Konformitäts- oder Live-Probes aus.`,"lab.projectionIncompatible":`Das Schema der Lab-Projektion ist inkompatibel. Baue die Projektion neu auf.`,"lab.statusTitle":`Projektionsstatus`,"lab.matrixTitle":`Kompatibilitätsmatrix`,"lab.verdictsTitle":`Urteilsdatensätze`,"lab.filter.layer":`Evidenzschicht`,"lab.filter.verdict":`Urteil`,"lab.filter.subject":`Subjekt-ID`,"lab.filter.all":`Alle`,"lab.col.subject":`Subjekt`,"lab.col.layer":`Schicht`,"lab.col.suite":`Suite`,"lab.col.verdict":`Urteil`,"lab.col.asOf":`Stand`,"lab.col.protocol":`Protokollkonformität`,"lab.col.live":`Live-Route-Kompatibilität`,"lab.col.task":`Aufgabenwirksamkeit`,"lab.empty":`In der Projektion gibt es noch keine Kompatibilitätsurteile.`,"lab.subjectKind":`Art`,"lab.observationCount":`Beobachtungen`,"lab.eventCount":`Ereignisse`,"lab.verdictCount":`Urteile`,"lab.subjectCount":`Subjekte`,"lab.builtAt":`Erstellt`,"lab.loading":`Kompatibilitätsevidenz wird geladen…`,"lab.loadMore":`Mehr laden`,"lab.detailTitle":`Urteilsdetails`,"lab.detailClose":`Schließen`,"lab.detailSubject":`Subjekt`,"lab.detailObservations":`Beobachtungen`,"lab.detailEvents":`Evidenzereignisse`,"lab.detailArtifacts":`Artefakt-Metadaten`,"lab.detailLoadFailed":`Urteilsdetails konnten nicht geladen werden`,"lab.refresh":`Aktualisieren`,"lab.verdict.UNKNOWN":`Unbekannt`,"lab.verdict.CLAIMED":`Behauptet`,"lab.verdict.PROBED":`Geprüft`,"lab.verdict.VERIFIED":`Verifiziert`,"lab.verdict.DEGRADED":`Eingeschränkt`,"lab.verdict.BLOCKED":`Blockiert`,"lab.verdict.UNSUPPORTED":`Nicht unterstützt`,"lab.layer.protocol_conformance":`Protokollkonformität`,"lab.layer.live_route_compatibility":`Live-Route-Kompatibilität`,"lab.layer.task_effectiveness":`Aufgabenwirksamkeit`},fr:{"lab.title":`Laboratoire de compatibilité`,"lab.subtitle":`Matrice en lecture seule des verdicts de compatibilité fondée sur les preuves de la projection du laboratoire.`,"lab.loadFailed":`Impossible de charger les données du laboratoire de compatibilité`,"lab.projectionUnavailable":`La projection du laboratoire n’est pas disponible. Exécutez d’abord les sondes de conformité ou en conditions réelles.`,"lab.projectionIncompatible":`Le schéma de la projection du laboratoire est incompatible. Reconstruisez la projection.`,"lab.statusTitle":`État de la projection`,"lab.matrixTitle":`Matrice de compatibilité`,"lab.verdictsTitle":`Enregistrements des verdicts`,"lab.filter.layer":`Couche de preuves`,"lab.filter.verdict":`Verdict`,"lab.filter.subject":`ID du sujet`,"lab.filter.all":`Tous`,"lab.col.subject":`Sujet`,"lab.col.layer":`Couche`,"lab.col.suite":`Suite`,"lab.col.verdict":`Verdict`,"lab.col.asOf":`Établi le`,"lab.col.protocol":`Conformité au protocole`,"lab.col.live":`Compatibilité du routage en conditions réelles`,"lab.col.task":`Efficacité des tâches`,"lab.empty":`La projection ne contient encore aucun verdict de compatibilité.`,"lab.subjectKind":`Type`,"lab.observationCount":`Observations`,"lab.eventCount":`Événements`,"lab.verdictCount":`Verdicts`,"lab.subjectCount":`Sujets`,"lab.builtAt":`Générée le`,"lab.loading":`Chargement des preuves de compatibilité…`,"lab.loadMore":`Charger plus`,"lab.detailTitle":`Détails du verdict`,"lab.detailClose":`Fermer`,"lab.detailSubject":`Sujet`,"lab.detailObservations":`Observations`,"lab.detailEvents":`Événements probants`,"lab.detailArtifacts":`Métadonnées des artefacts`,"lab.detailLoadFailed":`Impossible de charger les détails du verdict`,"lab.refresh":`Actualiser`,"lab.verdict.UNKNOWN":`Inconnu`,"lab.verdict.CLAIMED":`Déclaré`,"lab.verdict.PROBED":`Sondé`,"lab.verdict.VERIFIED":`Vérifié`,"lab.verdict.DEGRADED":`Dégradé`,"lab.verdict.BLOCKED":`Bloqué`,"lab.verdict.UNSUPPORTED":`Non pris en charge`,"lab.layer.protocol_conformance":`Conformité au protocole`,"lab.layer.live_route_compatibility":`Compatibilité du routage en conditions réelles`,"lab.layer.task_effectiveness":`Efficacité des tâches`},ko:{"lab.title":`호환성 랩`,"lab.subtitle":`랩 프로젝션 증거를 기반으로 한 읽기 전용 호환성 판정 매트릭스입니다.`,"lab.loadFailed":`호환성 랩 데이터를 불러오지 못했습니다`,"lab.projectionUnavailable":`랩 프로젝션을 사용할 수 없습니다. 먼저 적합성 또는 라이브 프로브를 실행하세요.`,"lab.projectionIncompatible":`랩 프로젝션 스키마가 호환되지 않습니다. 프로젝션을 다시 빌드하세요.`,"lab.statusTitle":`프로젝션 상태`,"lab.matrixTitle":`호환성 매트릭스`,"lab.verdictsTitle":`판정 레코드`,"lab.filter.layer":`증거 레이어`,"lab.filter.verdict":`판정`,"lab.filter.subject":`대상 ID`,"lab.filter.all":`전체`,"lab.col.subject":`대상`,"lab.col.layer":`레이어`,"lab.col.suite":`스위트`,"lab.col.verdict":`판정`,"lab.col.asOf":`기준 시각`,"lab.col.protocol":`프로토콜 적합성`,"lab.col.live":`라이브 경로 호환성`,"lab.col.task":`작업 효과성`,"lab.empty":`프로젝션에 아직 호환성 판정이 없습니다.`,"lab.subjectKind":`종류`,"lab.observationCount":`관측`,"lab.eventCount":`이벤트`,"lab.verdictCount":`판정`,"lab.subjectCount":`대상`,"lab.builtAt":`빌드 시각`,"lab.loading":`호환성 증거를 불러오는 중…`,"lab.loadMore":`더 불러오기`,"lab.detailTitle":`판정 상세`,"lab.detailClose":`닫기`,"lab.detailSubject":`대상`,"lab.detailObservations":`관측`,"lab.detailEvents":`증거 이벤트`,"lab.detailArtifacts":`아티팩트 메타데이터`,"lab.detailLoadFailed":`판정 상세를 불러오지 못했습니다`,"lab.refresh":`새로고침`,"lab.verdict.UNKNOWN":`알 수 없음`,"lab.verdict.CLAIMED":`주장됨`,"lab.verdict.PROBED":`프로브됨`,"lab.verdict.VERIFIED":`검증됨`,"lab.verdict.DEGRADED":`저하됨`,"lab.verdict.BLOCKED":`차단됨`,"lab.verdict.UNSUPPORTED":`지원되지 않음`,"lab.layer.protocol_conformance":`프로토콜 적합성`,"lab.layer.live_route_compatibility":`라이브 경로 호환성`,"lab.layer.task_effectiveness":`작업 효과성`},zh:{"lab.title":`兼容性实验室`,"lab.subtitle":`基于实验室投影证据的只读兼容性判定矩阵。`,"lab.loadFailed":`无法加载兼容性实验室数据`,"lab.projectionUnavailable":`实验室投影不可用。请先运行一致性探测或实时探测。`,"lab.projectionIncompatible":`实验室投影架构不兼容。请重新构建投影。`,"lab.statusTitle":`投影状态`,"lab.matrixTitle":`兼容性矩阵`,"lab.verdictsTitle":`判定记录`,"lab.filter.layer":`证据层`,"lab.filter.verdict":`判定`,"lab.filter.subject":`主体 ID`,"lab.filter.all":`全部`,"lab.col.subject":`主体`,"lab.col.layer":`层`,"lab.col.suite":`测试套件`,"lab.col.verdict":`判定`,"lab.col.asOf":`截至`,"lab.col.protocol":`协议一致性`,"lab.col.live":`实时路由兼容性`,"lab.col.task":`任务有效性`,"lab.empty":`投影中还没有兼容性判定。`,"lab.subjectKind":`类型`,"lab.observationCount":`观测`,"lab.eventCount":`事件`,"lab.verdictCount":`判定`,"lab.subjectCount":`主体`,"lab.builtAt":`构建时间`,"lab.loading":`正在加载兼容性证据…`,"lab.loadMore":`加载更多`,"lab.detailTitle":`判定详情`,"lab.detailClose":`关闭`,"lab.detailSubject":`主体`,"lab.detailObservations":`观测`,"lab.detailEvents":`证据事件`,"lab.detailArtifacts":`制品元数据`,"lab.detailLoadFailed":`无法加载判定详情`,"lab.refresh":`刷新`,"lab.verdict.UNKNOWN":`未知`,"lab.verdict.CLAIMED":`已声明`,"lab.verdict.PROBED":`已探测`,"lab.verdict.VERIFIED":`已验证`,"lab.verdict.DEGRADED":`降级`,"lab.verdict.BLOCKED":`已阻止`,"lab.verdict.UNSUPPORTED":`不支持`,"lab.layer.protocol_conformance":`协议一致性`,"lab.layer.live_route_compatibility":`实时路由兼容性`,"lab.layer.task_effectiveness":`任务有效性`},"zh-TW":{"lab.title":`相容性實驗室`,"lab.subtitle":`基於實驗室投影證據的唯讀相容性判定矩陣。`,"lab.loadFailed":`無法載入相容性實驗室資料`,"lab.projectionUnavailable":`實驗室投影不可用。請先執行一致性探測或即時探測。`,"lab.projectionIncompatible":`實驗室投影架構不相容。請重新建置投影。`,"lab.statusTitle":`投影狀態`,"lab.matrixTitle":`相容性矩陣`,"lab.verdictsTitle":`判定記錄`,"lab.filter.layer":`證據層`,"lab.filter.verdict":`判定`,"lab.filter.subject":`主體 ID`,"lab.filter.all":`全部`,"lab.col.subject":`主體`,"lab.col.layer":`層`,"lab.col.suite":`測試套件`,"lab.col.verdict":`判定`,"lab.col.asOf":`截至`,"lab.col.protocol":`協定一致性`,"lab.col.live":`即時路由相容性`,"lab.col.task":`任務有效性`,"lab.empty":`投影中還沒有相容性判定。`,"lab.subjectKind":`類型`,"lab.observationCount":`觀測`,"lab.eventCount":`事件`,"lab.verdictCount":`判定`,"lab.subjectCount":`主體`,"lab.builtAt":`建置時間`,"lab.loading":`正在載入相容性證據…`,"lab.loadMore":`載入更多`,"lab.detailTitle":`判定詳情`,"lab.detailClose":`關閉`,"lab.detailSubject":`主體`,"lab.detailObservations":`觀測`,"lab.detailEvents":`證據事件`,"lab.detailArtifacts":`產物中繼資料`,"lab.detailLoadFailed":`無法載入判定詳情`,"lab.refresh":`重新整理`,"lab.verdict.UNKNOWN":`未知`,"lab.verdict.CLAIMED":`已聲明`,"lab.verdict.PROBED":`已探測`,"lab.verdict.VERIFIED":`已驗證`,"lab.verdict.DEGRADED":`降級`,"lab.verdict.BLOCKED":`已封鎖`,"lab.verdict.UNSUPPORTED":`不支援`,"lab.layer.protocol_conformance":`協定一致性`,"lab.layer.live_route_compatibility":`即時路由相容性`,"lab.layer.task_effectiveness":`任務有效性`},ru:{"lab.title":`Лаборатория совместимости`,"lab.subtitle":`Матрица вердиктов совместимости только для чтения на основе данных проекции лаборатории.`,"lab.loadFailed":`Не удалось загрузить данные лаборатории совместимости`,"lab.projectionUnavailable":`Проекция лаборатории недоступна. Сначала выполните проверки соответствия или live-проверки.`,"lab.projectionIncompatible":`Схема проекции лаборатории несовместима. Перестройте проекцию.`,"lab.statusTitle":`Состояние проекции`,"lab.matrixTitle":`Матрица совместимости`,"lab.verdictsTitle":`Записи вердиктов`,"lab.filter.layer":`Слой доказательств`,"lab.filter.verdict":`Вердикт`,"lab.filter.subject":`ID субъекта`,"lab.filter.all":`Все`,"lab.col.subject":`Субъект`,"lab.col.layer":`Слой`,"lab.col.suite":`Набор`,"lab.col.verdict":`Вердикт`,"lab.col.asOf":`По состоянию на`,"lab.col.protocol":`Соответствие протоколу`,"lab.col.live":`Совместимость live-маршрута`,"lab.col.task":`Эффективность задач`,"lab.empty":`В проекции пока нет вердиктов совместимости.`,"lab.subjectKind":`Тип`,"lab.observationCount":`Наблюдения`,"lab.eventCount":`События`,"lab.verdictCount":`Вердикты`,"lab.subjectCount":`Субъекты`,"lab.builtAt":`Собрано`,"lab.loading":`Загрузка доказательств совместимости…`,"lab.loadMore":`Загрузить ещё`,"lab.detailTitle":`Детали вердикта`,"lab.detailClose":`Закрыть`,"lab.detailSubject":`Субъект`,"lab.detailObservations":`Наблюдения`,"lab.detailEvents":`События доказательств`,"lab.detailArtifacts":`Метаданные артефактов`,"lab.detailLoadFailed":`Не удалось загрузить детали вердикта`,"lab.refresh":`Обновить`,"lab.verdict.UNKNOWN":`Неизвестно`,"lab.verdict.CLAIMED":`Заявлено`,"lab.verdict.PROBED":`Проверено пробой`,"lab.verdict.VERIFIED":`Подтверждено`,"lab.verdict.DEGRADED":`Ограничено`,"lab.verdict.BLOCKED":`Заблокировано`,"lab.verdict.UNSUPPORTED":`Не поддерживается`,"lab.layer.protocol_conformance":`Соответствие протоколу`,"lab.layer.live_route_compatibility":`Совместимость live-маршрута`,"lab.layer.task_effectiveness":`Эффективность задач`},ja:{"lab.title":`互換性ラボ`,"lab.subtitle":`ラボ投影の証拠に基づく読み取り専用の互換性判定マトリクスです。`,"lab.loadFailed":`互換性ラボのデータを読み込めませんでした`,"lab.projectionUnavailable":`ラボ投影を利用できません。先に適合性プローブまたはライブプローブを実行してください。`,"lab.projectionIncompatible":`ラボ投影のスキーマに互換性がありません。投影を再構築してください。`,"lab.statusTitle":`投影ステータス`,"lab.matrixTitle":`互換性マトリクス`,"lab.verdictsTitle":`判定レコード`,"lab.filter.layer":`証拠レイヤー`,"lab.filter.verdict":`判定`,"lab.filter.subject":`サブジェクト ID`,"lab.filter.all":`すべて`,"lab.col.subject":`サブジェクト`,"lab.col.layer":`レイヤー`,"lab.col.suite":`スイート`,"lab.col.verdict":`判定`,"lab.col.asOf":`時点`,"lab.col.protocol":`プロトコル適合性`,"lab.col.live":`ライブ経路互換性`,"lab.col.task":`タスク有効性`,"lab.empty":`投影にはまだ互換性判定がありません。`,"lab.subjectKind":`種類`,"lab.observationCount":`観測`,"lab.eventCount":`イベント`,"lab.verdictCount":`判定`,"lab.subjectCount":`サブジェクト`,"lab.builtAt":`構築日時`,"lab.loading":`互換性の証拠を読み込み中…`,"lab.loadMore":`さらに読み込む`,"lab.detailTitle":`判定の詳細`,"lab.detailClose":`閉じる`,"lab.detailSubject":`サブジェクト`,"lab.detailObservations":`観測`,"lab.detailEvents":`証拠イベント`,"lab.detailArtifacts":`アーティファクトのメタデータ`,"lab.detailLoadFailed":`判定の詳細を読み込めませんでした`,"lab.refresh":`更新`,"lab.verdict.UNKNOWN":`不明`,"lab.verdict.CLAIMED":`申告済み`,"lab.verdict.PROBED":`プローブ済み`,"lab.verdict.VERIFIED":`検証済み`,"lab.verdict.DEGRADED":`低下`,"lab.verdict.BLOCKED":`ブロック`,"lab.verdict.UNSUPPORTED":`未対応`,"lab.layer.protocol_conformance":`プロトコル適合性`,"lab.layer.live_route_compatibility":`ライブ経路互換性`,"lab.layer.task_effectiveness":`タスク有効性`},tr:{"lab.title":`Uyumluluk Laboratuvarı`,"lab.subtitle":`Laboratuvar projeksiyonu kanıtlarından oluşturulan salt okunur uyumluluk karar matrisi.`,"lab.loadFailed":`Uyumluluk laboratuvarı verileri yüklenemedi`,"lab.projectionUnavailable":`Laboratuvar projeksiyonu kullanılamıyor. Önce uygunluk veya canlı probları çalıştırın.`,"lab.projectionIncompatible":`Laboratuvar projeksiyonu şeması uyumsuz. Projeksiyonu yeniden oluşturun.`,"lab.statusTitle":`Projeksiyon durumu`,"lab.matrixTitle":`Uyumluluk matrisi`,"lab.verdictsTitle":`Karar kayıtları`,"lab.filter.layer":`Kanıt katmanı`,"lab.filter.verdict":`Karar`,"lab.filter.subject":`Özne kimliği`,"lab.filter.all":`Tümü`,"lab.col.subject":`Özne`,"lab.col.layer":`Katman`,"lab.col.suite":`Paket`,"lab.col.verdict":`Karar`,"lab.col.asOf":`Tarih`,"lab.col.protocol":`Protokol uygunluğu`,"lab.col.live":`Canlı rota uyumluluğu`,"lab.col.task":`Görev etkinliği`,"lab.empty":`Projeksiyonda henüz uyumluluk kararı yok.`,"lab.subjectKind":`Tür`,"lab.observationCount":`Gözlemler`,"lab.eventCount":`Olaylar`,"lab.verdictCount":`Kararlar`,"lab.subjectCount":`Özneler`,"lab.builtAt":`Oluşturulma`,"lab.loading":`Uyumluluk kanıtları yükleniyor…`,"lab.loadMore":`Daha fazla yükle`,"lab.detailTitle":`Karar ayrıntısı`,"lab.detailClose":`Kapat`,"lab.detailSubject":`Özne`,"lab.detailObservations":`Gözlemler`,"lab.detailEvents":`Kanıt olayları`,"lab.detailArtifacts":`Artefakt meta verileri`,"lab.detailLoadFailed":`Karar ayrıntısı yüklenemedi`,"lab.refresh":`Yenile`,"lab.verdict.UNKNOWN":`Bilinmiyor`,"lab.verdict.CLAIMED":`İddia edildi`,"lab.verdict.PROBED":`Problandı`,"lab.verdict.VERIFIED":`Doğrulandı`,"lab.verdict.DEGRADED":`Kısıtlı`,"lab.verdict.BLOCKED":`Engellendi`,"lab.verdict.UNSUPPORTED":`Desteklenmiyor`,"lab.layer.protocol_conformance":`Protokol uygunluğu`,"lab.layer.live_route_compatibility":`Canlı rota uyumluluğu`,"lab.layer.task_effectiveness":`Görev etkinliği`},vi:{"lab.title":`Phòng thí nghiệm tương thích`,"lab.subtitle":`Ma trận kết quả tương thích chỉ đọc từ bằng chứng phép chiếu của phòng thí nghiệm.`,"lab.loadFailed":`Không thể tải dữ liệu phòng thí nghiệm tương thích`,"lab.projectionUnavailable":`Phép chiếu của phòng thí nghiệm không khả dụng. Hãy chạy kiểm tra tuân thủ hoặc đầu dò trực tiếp trước.`,"lab.projectionIncompatible":`Lược đồ phép chiếu của phòng thí nghiệm không tương thích. Hãy xây dựng lại phép chiếu.`,"lab.statusTitle":`Trạng thái phép chiếu`,"lab.matrixTitle":`Ma trận tương thích`,"lab.verdictsTitle":`Bản ghi kết quả`,"lab.filter.layer":`Lớp bằng chứng`,"lab.filter.verdict":`Kết quả`,"lab.filter.subject":`ID Chủ đề`,"lab.filter.all":`Tất cả`,"lab.col.subject":`Chủ đề`,"lab.col.layer":`Lớp`,"lab.col.suite":`Bộ kiểm thử`,"lab.col.verdict":`Kết quả`,"lab.col.asOf":`Tính đến`,"lab.col.protocol":`Tuân thủ giao thức`,"lab.col.live":`Tương thích tuyến trực tiếp`,"lab.col.task":`Hiệu quả tác vụ`,"lab.empty":`Chưa có kết quả tương thích nào trong phép chiếu.`,"lab.subjectKind":`Loại`,"lab.observationCount":`Số quan sát`,"lab.eventCount":`Số sự kiện`,"lab.verdictCount":`Số kết quả`,"lab.subjectCount":`Số đối tượng`,"lab.builtAt":`Thời điểm xây dựng`,"lab.loading":`Đang tải bằng chứng tương thích…`,"lab.loadMore":`Tải thêm`,"lab.detailTitle":`Chi tiết kết quả`,"lab.detailClose":`Đóng`,"lab.detailSubject":`Chủ đề`,"lab.detailObservations":`Các quan sát`,"lab.detailEvents":`Sự kiện bằng chứng`,"lab.detailArtifacts":`Metadata của artifact`,"lab.detailLoadFailed":`Không thể tải chi tiết kết quả`,"lab.refresh":`Làm mới`,"lab.verdict.UNKNOWN":`Không xác định`,"lab.verdict.CLAIMED":`Đã khai báo`,"lab.verdict.PROBED":`Đã thăm dò`,"lab.verdict.VERIFIED":`Đã xác minh`,"lab.verdict.DEGRADED":`Suy giảm`,"lab.verdict.BLOCKED":`Bị chặn`,"lab.verdict.UNSUPPORTED":`Không được hỗ trợ`,"lab.layer.protocol_conformance":`Tuân thủ giao thức`,"lab.layer.live_route_compatibility":`Tương thích tuyến trực tiếp`,"lab.layer.task_effectiveness":`Hiệu quả tác vụ`}},oe={en:{subjectKindUnknown:`Unknown`,"artifact.present":`Present`,"artifact.corrupt":`Corrupt`,"artifact.purged_unavailable":`Purged / unavailable`,selectVerdict:`View verdict for {subject}`,"community.title":`Community evidence`,"community.notLocalVerdict":`Untrusted read-only context. Not included in this local verdict.`,"community.bundles":`Bundles`,"community.activeRecords":`Active records`,"community.revokedRecords":`Revoked records`},de:{subjectKindUnknown:`Unbekannt`,"artifact.present":`Vorhanden`,"artifact.corrupt":`Beschädigt`,"artifact.purged_unavailable":`Gelöscht / nicht verfügbar`,selectVerdict:`Urteil für {subject} anzeigen`,"community.title":`Community-Evidenz`,"community.notLocalVerdict":`Nicht vertrauenswürdiger Nur-Lese-Kontext. Nicht Teil dieses lokalen Urteils.`,"community.bundles":`Pakete`,"community.activeRecords":`Aktive Einträge`,"community.revokedRecords":`Widerrufene Einträge`},fr:{subjectKindUnknown:`Inconnu`,"artifact.present":`Présent`,"artifact.corrupt":`Corrompu`,"artifact.purged_unavailable":`Purgé / indisponible`,selectVerdict:`Afficher le verdict pour {subject}`,"community.title":`Données de la communauté`,"community.notLocalVerdict":`Contexte non fiable en lecture seule. Non inclus dans ce verdict local.`,"community.bundles":`Lots`,"community.activeRecords":`Enregistrements actifs`,"community.revokedRecords":`Enregistrements révoqués`},ko:{subjectKindUnknown:`알 수 없음`,"artifact.present":`있음`,"artifact.corrupt":`손상됨`,"artifact.purged_unavailable":`삭제됨 / 사용할 수 없음`,selectVerdict:`{subject}의 판정 보기`,"community.title":`커뮤니티 증거`,"community.notLocalVerdict":`신뢰되지 않는 읽기 전용 컨텍스트입니다. 이 로컬 판정에는 포함되지 않습니다.`,"community.bundles":`번들`,"community.activeRecords":`활성 레코드`,"community.revokedRecords":`폐기된 레코드`},zh:{subjectKindUnknown:`未知`,"artifact.present":`存在`,"artifact.corrupt":`已损坏`,"artifact.purged_unavailable":`已清除 / 不可用`,selectVerdict:`查看 {subject} 的判定`,"community.title":`社区证据`,"community.notLocalVerdict":`不受信任的只读上下文。不计入此本地判定。`,"community.bundles":`证据包`,"community.activeRecords":`有效记录`,"community.revokedRecords":`已撤销记录`},"zh-TW":{subjectKindUnknown:`未知`,"artifact.present":`存在`,"artifact.corrupt":`已損壞`,"artifact.purged_unavailable":`已清除 / 不可用`,selectVerdict:`查看 {subject} 的判定`,"community.title":`社群證據`,"community.notLocalVerdict":`不受信任的唯讀脈絡。不計入此本地判定。`,"community.bundles":`證據包`,"community.activeRecords":`有效記錄`,"community.revokedRecords":`已撤銷記錄`},ru:{subjectKindUnknown:`Неизвестно`,"artifact.present":`Доступен`,"artifact.corrupt":`Повреждён`,"artifact.purged_unavailable":`Удалён / недоступен`,selectVerdict:`Открыть вердикт для {subject}`,"community.title":`Данные сообщества`,"community.notLocalVerdict":`Недоверенный контекст только для чтения. Не входит в этот локальный вердикт.`,"community.bundles":`Пакеты`,"community.activeRecords":`Активные записи`,"community.revokedRecords":`Отозванные записи`},ja:{subjectKindUnknown:`不明`,"artifact.present":`存在`,"artifact.corrupt":`破損`,"artifact.purged_unavailable":`削除済み / 利用不可`,selectVerdict:`{subject} の判定を表示`,"community.title":`コミュニティ証拠`,"community.notLocalVerdict":`信頼されていない読み取り専用コンテキストです。このローカル判定には含まれません。`,"community.bundles":`バンドル`,"community.activeRecords":`有効なレコード`,"community.revokedRecords":`取り消されたレコード`},tr:{subjectKindUnknown:`Bilinmiyor`,"artifact.present":`Mevcut`,"artifact.corrupt":`Bozuk`,"artifact.purged_unavailable":`Temizlenmiş / kullanılamıyor`,selectVerdict:`{subject} için kararı görüntüle`,"community.title":`Topluluk kanıtı`,"community.notLocalVerdict":`Güvenilmeyen salt okunur bağlam. Bu yerel karara dahil değildir.`,"community.bundles":`Paketler`,"community.activeRecords":`Etkin kayıtlar`,"community.revokedRecords":`Geri çekilen kayıtlar`},vi:{subjectKindUnknown:`Không xác định`,"artifact.present":`Có sẵn`,"artifact.corrupt":`Hỏng`,"artifact.purged_unavailable":`Đã xóa / không khả dụng`,selectVerdict:`Xem kết quả cho {subject}`,"community.title":`Bằng chứng cộng đồng`,"community.notLocalVerdict":`Ngữ cảnh chỉ đọc không đáng tin cậy. Không được đưa vào kết quả cục bộ này.`,"community.bundles":`Gói bằng chứng`,"community.activeRecords":`Bản ghi đang hoạt động`,"community.revokedRecords":`Bản ghi đã thu hồi`}};function se(e,t,n){let r=oe[e][t];if(n)for(let[e,t]of Object.entries(n))r=r.split(`{${e}}`).join(String(t));return r}function ce(e,t){return{...t,...ae[e]}}var le={en:ce(`en`,y),de:ce(`de`,b),fr:ce(`fr`,x),ko:ce(`ko`,ee),zh:ce(`zh`,S),"zh-TW":ce(`zh-TW`,C),ru:ce(`ru`,te),ja:ce(`ja`,ne),tr:ce(`tr`,re),vi:ce(`vi`,ie)};function ue(e){return le[e][`lang.nativeName`]}function de(e,t){return le[e][t]}var w=[{code:`en`,htmlLang:`en`},{code:`de`,htmlLang:`de`},{code:`fr`,htmlLang:`fr`},{code:`ko`,htmlLang:`ko`},{code:`zh`,htmlLang:`zh-CN`},{code:`zh-TW`,htmlLang:`zh-TW`},{code:`ru`,htmlLang:`ru`},{code:`ja`,htmlLang:`ja`},{code:`tr`,htmlLang:`tr`},{code:`vi`,htmlLang:`vi`}],T=`ocx-lang`,fe=null;function pe(){try{let e=localStorage.getItem(T);if(e===`en`||e===`de`||e===`fr`||e===`ko`||e===`zh`||e===`zh-TW`||e===`ru`||e===`ja`||e===`tr`||e===`vi`)return e}catch{}let e=typeof navigator<`u`&&navigator?.language?navigator.language.toLowerCase():`en`;return e.startsWith(`de`)?`de`:e.startsWith(`fr`)?`fr`:e.startsWith(`ko`)?`ko`:e.startsWith(`zh`)?e.includes(`tw`)||e.includes(`hk`)||e.includes(`mo`)||e.includes(`hant`)?`zh-TW`:`zh`:e.startsWith(`ru`)?`ru`:e.startsWith(`ja`)?`ja`:e.startsWith(`tr`)?`tr`:e.startsWith(`vi`)?`vi`:`en`}function me(){return fe??pe()}function he(e){fe=e}var E=(0,_.createContext)(null);function D(e,t){if(!t)return e;let n=e;for(let e of Object.keys(t))n=n.split(`{${e}}`).join(String(t[e]));return n}function ge(){let e=(0,_.useContext)(E);if(!e)throw Error(`useI18n must be used within LanguageProvider`);return e}function _e(){return ge().t}var ve=`opencodex-admin-token-dialog`,ye=`OpenCodex`,be=`https://opencodex.me/guides/web-dashboard/#finding-the-admin-token`;function xe(e,t=me()){let n=le[t],r=n[`auth.adminTokenTitle`];return new Promise(t=>{let i=document.activeElement instanceof HTMLElement?document.activeElement:null,a=!1,o=document.createElement(`dialog`);o.id=ve,o.className=`modal-overlay`,o.setAttribute(`aria-labelledby`,`${ve}-title`);let s=document.createElement(`form`);s.className=`modal-card`,s.method=`post`,s.action=window.location.href,s.autocomplete=`on`;let c=document.createElement(`div`);c.className=`modal-head`;let l=document.createElement(`h3`);l.id=`${ve}-title`,l.textContent=r,c.append(l);let u=document.createElement(`div`),d=document.createElement(`label`);d.className=`field-label`,d.htmlFor=`${ve}-username`,d.textContent=n[`auth.adminAccountLabel`];let f=document.createElement(`input`);f.id=d.htmlFor,f.className=`input`,f.type=`text`,f.name=`username`,f.autocomplete=`username`,f.value=ye,f.readOnly=!0,u.append(d,f);let p=document.createElement(`div`);p.style.marginTop=`var(--space-4)`;let m=document.createElement(`label`);m.className=`field-label`,m.htmlFor=`${ve}-password`,m.textContent=n[`auth.adminTokenFieldLabel`];let h=document.createElement(`input`);h.id=m.htmlFor,h.className=`input`,h.type=`password`,h.name=`password`,h.autocomplete=`current-password`,h.required=!0,h.spellcheck=!1,h.autocapitalize=`none`,p.append(m,h);let g=document.createElement(`p`);g.className=`hint`,g.style.marginTop=`var(--space-2)`,g.textContent=n[`auth.adminTokenHelp`];let _=document.createElement(`a`);_.className=`text-control`,_.href=be,_.target=`_blank`,_.rel=`noreferrer`,_.style.color=`var(--accent)`,_.textContent=n[`auth.adminTokenDocsLink`],g.append(` `,_),p.append(g);let v=document.createElement(`div`);v.className=`notice notice-err`,v.setAttribute(`role`,`alert`),v.hidden=!0;let y=document.createElement(`div`);y.className=`modal-actions`;let b=document.createElement(`button`);b.type=`button`,b.className=`btn btn-ghost`,b.textContent=n[`common.cancel`];let x=document.createElement(`button`);x.type=`submit`,x.className=`btn btn-primary`,x.textContent=n[`common.ok`],y.append(b,x),s.append(c,u,p,v,y),o.append(s);let ee=e=>{v.textContent=e??``,v.hidden=e===null},S=e=>{a||(a=!0,o.open&&o.close(),o.remove(),i?.focus(),t(e))};s.addEventListener(`submit`,t=>{t.preventDefault();let r=h.value.trim();if(!r){h.value=``,h.reportValidity();return}h.disabled=!0,x.disabled=!0,ee(null),e(r).then(e=>{if(!a){if(e===`accepted`){S(r);return}h.value=``,h.disabled=!1,x.disabled=!1,ee(e===`rejected`?n[`auth.adminTokenRejected`]:n[`auth.adminTokenUnavailable`]),h.focus()}}).catch(()=>{a||(h.value=``,h.disabled=!1,x.disabled=!1,ee(n[`auth.adminTokenUnavailable`]),h.focus())})}),b.addEventListener(`click`,()=>S(null)),o.addEventListener(`cancel`,e=>{e.preventDefault(),S(null)}),document.body.append(o),typeof o.showModal==`function`?o.showModal():o.setAttribute(`open`,``),queueMicrotask(()=>h.focus())})}function Se(e){let t=new AbortController;if(typeof AbortSignal<`u`&&typeof AbortSignal.any==`function`&&typeof AbortSignal.timeout==`function`)return{controller:t,signal:AbortSignal.any([t.signal,AbortSignal.timeout(e)]),clear:()=>void 0};let n=setTimeout(()=>t.abort(),e);return{controller:t,signal:t.signal,clear:()=>clearTimeout(n)}}function Ce(){return typeof document>`u`?null:document.querySelector(`meta[name="opencodex-runtime-role"]`)?.getAttribute(`content`)?.trim()||null}function we(){return Ce()===`client`}function Te(){if(typeof document<`u`){let e=document.querySelector(`meta[name="opencodex-management-auth-required"]`)?.getAttribute(`content`)?.trim();if(e===`1`)return!0;if(e===`0`)return!1}return Ce()===`hub`}function Ee(e){return e.replace(/\/+$/,``)}function De(e){return new URL(e||`/`,window.location.href)}function Oe(e){try{let t=new URL(e);return t.protocol!==`http:`&&t.protocol!==`https:`||t.username||t.password||t.pathname!==`/`||t.search||t.hash?null:t.origin}catch{return null}}function ke(e,t,n,r){let i=Ee(t);return{id:e,baseUrl:i,serverOrigin:n,bootstrapPath:`${i}/opencodex-session`,transport:r}}function Ae(e){let t=De(e),n=Ee(e);return{connected:!1,machine:ke(`machine`,n,t.origin,`same-origin`),shared:ke(`shared`,n,t.origin,`same-origin`)}}function je(e){if(!e||typeof e!=`object`||Array.isArray(e))return!1;let t=e;return t.mode===`client`&&t.connected===!0&&t.protocolVersion===1&&(t.managementTransport===`direct`||t.managementTransport===`relay`)&&typeof t.machineBase==`string`&&typeof t.sharedBase==`string`&&typeof t.sharedServerOrigin==`string`&&typeof t.apiKeyId==`string`&&t.apiKeyId.trim().length>0&&typeof t.connectedAt==`string`&&(t.catalogSyncedAt===void 0||typeof t.catalogSyncedAt==`string`)}function Me(e,t){if(!je(t))throw TypeError(`machine status response is invalid`);let n=Ae(e),r=Oe(t.machineBase),i=Oe(t.sharedServerOrigin);if(!r||r!==n.machine.serverOrigin||!i)throw TypeError(`machine status target origins are invalid`);let a;try{a=new URL(t.sharedBase)}catch{throw TypeError(`machine status shared target is invalid`)}if(a.username||a.password||a.search||a.hash)throw TypeError(`machine status shared target is invalid`);if(t.managementTransport===`direct`){if(a.origin!==i||a.pathname!==`/`)throw TypeError(`machine status direct target is inconsistent`)}else if(a.origin!==r||a.pathname!==`/api/machine/hub-relay`)throw TypeError(`machine status relay target is inconsistent`);return{connected:!0,machine:ke(`machine`,Ee(e),r,`same-origin`),shared:t.managementTransport===`relay`?ke(`shared`,`${Ee(e)}/api/machine/hub-relay`,i,`relay`):ke(`shared`,i,i,`direct`),apiKeyId:t.apiKeyId,catalogSyncedAt:t.catalogSyncedAt}}function Ne(e,t){return t[e].baseUrl}async function Pe(e,t){let n=Ae(e);if(Ce()!==`client`)return n;let r;try{r=await fetch(`${n.machine.baseUrl}/api/machine/status`,{signal:t,cache:`no-store`})}catch(e){throw Error(`local machine plane unavailable`,{cause:e})}if(r.status===404)return n;if(!r.ok)throw Error(`local machine plane refused discovery (${r.status})`);let i=await r.json().catch(()=>null);if(!je(i))throw Error(`local machine plane returned invalid status`);return Me(e,i)}var Fe=`opencodex:session-unavailable`,Ie=`opencodex-api-token`,Le=`/api/settings`,Re=1e4,ze=15e3,Be=`X-OpenCodex-Machine-Session`,Ve=`X-OpenCodex-Machine-GUI-Origin`,He=`X-OpenCodex-Machine-CSRF-Token`,Ue=!1,We=null,Ge=null,Ke=xe,qe=Re,Je=ze,Ye=new Map;function Xe(e){if(typeof window>`u`)return;let t=window.CustomEvent??(typeof CustomEvent==`function`?CustomEvent:null);if(t)try{window.dispatchEvent(new t(Fe,{detail:{plane:e}}))}catch{}}function Ze(){return{token:null,csrfToken:null,browserOrigin:null,serverOrigin:null}}function Qe(){return Ge||et(Ae(``)),Ge}function $e(e,t){return e.baseUrl===t.baseUrl&&e.serverOrigin===t.serverOrigin&&e.transport===t.transport}function et(e){Ge=e;for(let t of[`machine`,`shared`]){let n=Ye.get(t);Ye.set(t,n&&$e(n.target,e[t])?{...n,target:e[t]}:{target:e[t],session:Ze(),resolutionInFlight:null,promptCancelled:!1})}}function O(e){return Qe(),Ye.get(e)}function tt(e,t){let n=O(e);t!==null&&n.session.token===t&&(n.session=Ze())}function nt(e,t,n,r,i){let a=O(e);return!t?.startsWith(`ocx_session_`)||!n||r!==window.location.origin||i!==a.target.serverOrigin?(a.session=Ze(),!1):(a.session={token:t,csrfToken:n,browserOrigin:r,serverOrigin:i},a.promptCancelled=!1,!0)}function rt(e){return!!O(e).session.token?.startsWith(`ocx_session_`)}async function it(e){let t=O(e);if(!t.session.token?.startsWith(`ocx_session_`))return!1;let n=Se(Re);try{return(await window.fetch(`${t.target.baseUrl}/api/session/logout`,{method:`POST`,signal:n.signal})).ok?(t.session=Ze(),t.promptCancelled=!1,!0):!1}catch{return!1}finally{n.clear()}}function at(e){let t=document.querySelector(`meta[name="${e}"]`),n=t?.content.trim()||null;return t?.remove(),n}function ot(){let e={token:at(`opencodex-session-token`),csrf:at(`opencodex-session-csrf`),browser:at(`opencodex-session-origin`),server:at(`opencodex-session-server-origin`)};for(let t of[`machine`,`shared`])O(t).target.serverOrigin===e.server&&nt(t,e.token,e.csrf,e.browser,e.server)}function st(e,t){for(let n of e.match(/<meta\b[^>]*>/gi)??[])if(n.match(/\bname=["']([^"']+)["']/i)?.[1]===t)return n.match(/\bcontent=["']([^"']*)["']/i)?.[1]?.trim()||null;return null}function ct(e,t){return nt(e,st(t,`opencodex-session-token`),st(t,`opencodex-session-csrf`),st(t,`opencodex-session-origin`),st(t,`opencodex-session-server-origin`))}function lt(){try{sessionStorage.removeItem(Ie)}catch{}}function ut(e){return new URL(e.baseUrl||`/`,window.location.href)}function dt(e,t){let n=ut(e);if(t.origin!==n.origin)return!1;let r=n.pathname.replace(/\/$/,``);return r===``||t.pathname===r||t.pathname.startsWith(`${r}/`)}function ft(e,t){if(!dt(e,t))return null;let n=ut(e).pathname.replace(/\/$/,``);return t.pathname.slice(n.length)||`/`}function pt(e){let t;try{t=new URL(e instanceof Request?e.url:String(e),window.location.href)}catch{return null}let n=Qe();return t.href===new URL(n.shared.bootstrapPath,window.location.href).href?{plane:`shared`,bootstrap:!0}:n.shared.transport===`relay`&&dt(n.shared,t)?{plane:`shared`,bootstrap:!1}:ft(n.machine,t)?.startsWith(`/api/machine/`)?{plane:`machine`,bootstrap:!1}:ft(n.shared,t)?.startsWith(`/api/`)?{plane:`shared`,bootstrap:!1}:t.href===new URL(n.machine.bootstrapPath,window.location.href).href?{plane:`machine`,bootstrap:!0}:null}function mt(e,t,n,r){let i=O(e),a=new Headers(n?.headers??(t instanceof Request?t.headers:void 0)),o=r===void 0?i.session.token:r,s=(n?.method??(t instanceof Request?t.method:`GET`)).toUpperCase();if(o&&a.set(`X-OpenCodex-API-Key`,o),o?.startsWith(`ocx_session_`)&&i.session.browserOrigin&&i.session.csrfToken&&(a.set(`X-OpenCodex-GUI-Origin`,i.session.browserOrigin),s!==`GET`&&s!==`HEAD`&&a.set(`X-OpenCodex-CSRF-Token`,i.session.csrfToken)),e===`shared`&&i.target.transport===`relay`){let e=O(`machine`).session;e.token&&a.set(Be,e.token),e.browserOrigin&&a.set(Ve,e.browserOrigin),s!==`GET`&&s!==`HEAD`&&e.csrfToken&&a.set(He,e.csrfToken)}return a}function ht(e,t,n,r){let i=mt(e,t,n,r);return t instanceof Request?[new Request(t,{headers:i}),n?{...n,headers:i}:void 0]:[t,{...n,headers:i}]}async function gt(e){if(!We)return{kind:`failed`};let t=O(e),n=Se(qe);try{let[r,i]=ht(e,t.target.bootstrapPath,{cache:`no-store`,signal:n.signal},null),a=await We(r,i);return a.ok?ct(e,await a.text())?{kind:`minted`,token:O(e).session.token}:{kind:`unavailable`}:a.status>=400&&a.status<500?{kind:`unavailable`}:{kind:`failed`}}catch{return{kind:`failed`}}finally{n.clear()}}async function _t(e,t){if(!We)return`unavailable`;try{let[n,r]=ht(e,`${O(e).target.baseUrl}${Le}`,{cache:`no-store`},t),i=await We(n,r);return i.status===401?`rejected`:i.ok?`accepted`:`unavailable`}catch{return`unavailable`}}async function vt(e,t,n){let r=O(e);if(r.promptCancelled||n?.aborted)return null;if(!r.resolutionInFlight){let n=(async()=>{let n=r.session.token;if(n&&n!==t)return n;let i,a=await Promise.race([gt(e),new Promise(e=>{i=setTimeout(()=>e({kind:`failed`}),Je)})]).finally(()=>clearTimeout(i));if(a.kind===`minted`)return a.token;if(a.kind===`failed`)return null;if(!Te())return r.promptCancelled=!0,null;let o=await Ke(t=>_t(e,t));return o?(r.session={token:o,csrfToken:null,browserOrigin:null,serverOrigin:r.target.serverOrigin},o):(r.promptCancelled=!0,null)})().finally(()=>{r.resolutionInFlight===n&&(r.resolutionInFlight=null)});r.resolutionInFlight=n}if(!n)return r.resolutionInFlight;let i,a=new Promise(e=>{i=()=>e(null),n.addEventListener(`abort`,i,{once:!0})});return Promise.race([r.resolutionInFlight,a]).finally(()=>{i&&n.removeEventListener(`abort`,i)})}function yt(){if(Ue)return;Ue=!0,lt(),Qe(),ot();let e=window.fetch.bind(window);We=e,window.fetch=async(t,n)=>{let r=pt(t);if(!r)return e(t,n);let i=O(r.plane),a=i.session.token,[o,s]=ht(r.plane,t,n),c=await e(o,s);if(r.bootstrap||c.status!==401)return c;let l=i.session.token;if(l&&l!==a){let[i,a]=ht(r.plane,t,n),o=await e(i,a);if(o.status!==401)return o;tt(r.plane,l)}else tt(r.plane,a);let u=n?.signal??(t instanceof Request?t.signal:void 0),d=await vt(r.plane,a,u??void 0);if(!d)return!u?.aborted&&!rt(r.plane)&&Xe(r.plane),c;let[f,p]=ht(r.plane,t,n,d),m=await e(f,p);return m.status===401&&(tt(r.plane,d),!u?.aborted&&!rt(r.plane)&&Xe(r.plane)),m}}function bt(e,t){let n=new URL(e);return![`http:`,`https:`].includes(n.protocol)||n.pathname!==`/v1/audio/transcriptions`||n.username||n.password||n.search||n.hash||t.method!==`POST`?Promise.reject(Error(`Invalid audio upload destination`)):(We??fetch)(n.href,{...t,credentials:`omit`,redirect:`error`})}var xt=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})),St=o(((e,t)=>{t.exports=xt()})),Ct=St();function wt({children:e}){let[t,n]=(0,_.useState)(()=>{let e=pe();return he(e),e}),r=(0,_.useCallback)(e=>{he(e),n(e)},[]);(0,_.useEffect)(()=>{let e=w.find(e=>e.code===t)??w[0];document.documentElement.lang=e.htmlLang;try{localStorage.setItem(`ocx-lang`,t)}catch{}},[t]);let i=(0,_.useCallback)((e,n)=>D(le[t][e]??y[e]??e,n),[t]),a=(0,_.useMemo)(()=>({locale:t,setLocale:r,t:i}),[t,i]);return(0,Ct.jsx)(E.Provider,{value:a,children:e})}function Tt({k:e,cmd:t,vars:n}){let{t:r}=ge(),[i,a=``]=r(e,n).split(`{cmd}`);return(0,Ct.jsxs)(Ct.Fragment,{children:[i,(0,Ct.jsx)(`code`,{className:`chip`,children:t}),a]})}var Et=`modulepreload`,Dt=function(e){return`/`+e},Ot={},k=function(e,t,n){let r=Promise.resolve();if(t&&t.length>0){let e=document.getElementsByTagName(`link`),i=document.querySelector(`meta[property=csp-nonce]`),a=i?.nonce||i?.getAttribute(`nonce`);function o(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}function s(e){return import.meta.resolve?import.meta.resolve(e):new URL(e,import.meta.url).href}r=o(t.map(t=>{if(t=Dt(t,n),t=s(t),t in Ot)return;Ot[t]=!0;let r=t.endsWith(`.css`);for(let n=e.length-1;n>=0;n--){let i=e[n];if(i.href===t&&(!r||i.rel===`stylesheet`))return}let i=document.createElement(`link`);if(i.rel=r?`stylesheet`:Et,r||(i.as=`script`),i.crossOrigin=``,i.href=t,a&&i.setAttribute(`nonce`,a),document.head.appendChild(i),r)return new Promise((e,n)=>{i.addEventListener(`load`,e),i.addEventListener(`error`,()=>n(Error(`Unable to preload CSS for ${t}`)))})}))}function i(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return r.then(t=>{for(let e of t||[])e.status===`rejected`&&i(e.reason);return e().catch(i)})},kt=window.location.hash.split(`?`)[0]===`#/tray`,At=(0,_.lazy)(()=>k(kt?()=>import(`./Tray-DdvPBVLi.js`):()=>import(`./App-CANWata-.js`),__vite__mapDeps([0,1])));kt&&yt(),v.createRoot(document.getElementById(`root`)).render((0,Ct.jsx)(_.StrictMode,{children:(0,Ct.jsx)(wt,{children:(0,Ct.jsx)(_.Suspense,{fallback:null,children:(0,Ct.jsx)(At,{})})})}));export{m as C,se as S,c as T,ge as _,bt as a,de as b,ct as c,Pe as d,we as f,me as g,w as h,et as i,it as l,Se as m,St as n,rt as o,Ae as p,Fe as r,yt as s,Tt as t,Ne as u,_e as v,u as w,ue as x,le as y};