From 3c34b708b9e407561c18a379058b40008f23ecce Mon Sep 17 00:00:00 2001 From: tajniak81 <13187254+tajniak81@users.noreply.github.com> Date: Sat, 5 Sep 2026 12:54:30 +0200 Subject: [PATCH] A mode that does not work stops being on the menu MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The control-mode picker offered all five paths to everyone, always. When one of them is broken in a deployment — OCPP is, right now — there was nothing to do about it: the superadmin could pick a different mode for the global layer, but the option stayed in every organization's and every user's dropdown, waiting to be chosen. The cascade could impose a mode. It could not withdraw one. So each layer now carries a second, separate thing: a list of the modes it hides from the layers below it. controlModesDisabled sits beside controlMode, on the global layer as a plugin config field and on an organization as part of the same pluginSettings blob its credentials already live in. A superadmin ticking Own CSMS and Proxy CSMS takes both OCPP paths out of every picker underneath; an org admin ticking Modbus takes it out of their own users'. Three decisions are worth naming. A hide-list governs the layers below, not the layer holding it. The superadmin can keep running Proxy globally while hiding it from everyone else, which is what you want while a mode is being repaired rather than retired: the operator testing the fix is the one person who still needs to select it. The alternative, a list that also invalidates its own layer's choice, would have made the panel contradict itself — a mode chosen in one field and switched off in the one below it. But a hidden mode really is hidden, not merely absent from a dropdown. A user who had picked Proxy last month stops resolving to Proxy the moment the superadmin hides it, and falls back to monitoring only. Filtering the picker alone would have left every existing charger on the broken path and quietly disagreed with the list the operator had just filled in. Resolution now walks the layers accumulating what each hides from the next, so a stored value only takes effect if the layers above it still permit it. And off is never hideable. It is what a charger falls back to and what an empty cascade resolves to, so a layer that could take it away could leave the layer below with a picker holding no valid choice at all. It is not among the checkboxes in any of the three clients, and the parser drops it if it arrives anyway. The panel needed a field shape it did not have — several options, any number chosen — so ConfigField grows a "multiselect" type, stored as the comma-separated string that fits the flat map every other field already uses. That is generic: any plugin can declare one now, and the PUT body is unchanged. The phone's field specs grew the same way, a scopeOptions hook that narrows a declared option list to what the server still offers, rather than teaching the integration card about control modes specifically. Both clients clamp a stored mode that has since been hidden back to off before drawing the picker, so the box shows what will actually happen rather than a choice that would be dropped on save. Verified: Go tests pass, both frontends build, flutter analyze is clean, and the panel's new checkbox field was rendered against the real stylesheet. The end-to-end path — superadmin hides a mode, an org admin and then a user reload and find it gone — has not been walked on a live stack; the panel is embedded in the Go binary, so the remote deployment needs a rebuild before any of this is visible there. Co-Authored-By: Claude Opus 5 --- .../api/dist/assets/index-BBZfstAT.js | 17 --- .../api/dist/assets/index-CUgU2Fxs.js | 17 +++ ...{index-_8IdQ1wh.css => index-Cd85xDqG.css} | 2 +- API Server/internal/api/dist/index.html | 4 +- .../internal/api/integrations_ankersolix.go | 135 +++++++++++++++- .../api/integrations_ankersolix_test.go | 80 ++++++++++ .../plugins/builtin/ankersolix/ankersolix.go | 13 ++ .../builtin/ankersolix/ankersolix_test.go | 25 +++ API Server/internal/plugins/plugin.go | 7 +- .../panel/src/components/PluginsCard.vue | 45 +++++- API Server/panel/src/style.css | 14 ++ Phone App/assets/i18n/da.json | 2 + Phone App/assets/i18n/en.json | 2 + Phone App/assets/i18n/pl.json | 2 + Phone App/lib/models.dart | 18 ++- Phone App/lib/screens/settings_screen.dart | 144 ++++++++++++++++-- Web App/web/src/i18n/da.json | 2 + Web App/web/src/i18n/en.json | 2 + Web App/web/src/i18n/pl.json | 2 + Web App/web/src/style.css | 15 ++ Web App/web/src/views/Settings.vue | 83 +++++++++- 21 files changed, 582 insertions(+), 49 deletions(-) delete mode 100644 API Server/internal/api/dist/assets/index-BBZfstAT.js create mode 100644 API Server/internal/api/dist/assets/index-CUgU2Fxs.js rename API Server/internal/api/dist/assets/{index-_8IdQ1wh.css => index-Cd85xDqG.css} (50%) diff --git a/API Server/internal/api/dist/assets/index-BBZfstAT.js b/API Server/internal/api/dist/assets/index-BBZfstAT.js deleted file mode 100644 index f7e7246..0000000 --- a/API Server/internal/api/dist/assets/index-BBZfstAT.js +++ /dev/null @@ -1,17 +0,0 @@ -(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const i of document.querySelectorAll('link[rel="modulepreload"]'))n(i);new MutationObserver(i=>{for(const o of i)if(o.type==="childList")for(const r of o.addedNodes)r.tagName==="LINK"&&r.rel==="modulepreload"&&n(r)}).observe(document,{childList:!0,subtree:!0});function s(i){const o={};return i.integrity&&(o.integrity=i.integrity),i.referrerPolicy&&(o.referrerPolicy=i.referrerPolicy),i.crossOrigin==="use-credentials"?o.credentials="include":i.crossOrigin==="anonymous"?o.credentials="omit":o.credentials="same-origin",o}function n(i){if(i.ep)return;i.ep=!0;const o=s(i);fetch(i.href,o)}})();/** -* @vue/shared v3.5.39 -* (c) 2018-present Yuxi (Evan) You and Vue contributors -* @license MIT -**/function cn(e){const t=Object.create(null);for(const s of e.split(","))t[s]=1;return s=>s in t}const ne={},Tt=[],Ze=()=>{},mi=()=>!1,Ss=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),Es=e=>e.startsWith("onUpdate:"),_e=Object.assign,un=(e,t)=>{const s=e.indexOf(t);s>-1&&e.splice(s,1)},$o=Object.prototype.hasOwnProperty,X=(e,t)=>$o.call(e,t),L=Array.isArray,St=e=>ts(e)==="[object Map]",zt=e=>ts(e)==="[object Set]",zn=e=>ts(e)==="[object Date]",W=e=>typeof e=="function",ue=e=>typeof e=="string",Je=e=>typeof e=="symbol",te=e=>e!==null&&typeof e=="object",bi=e=>(te(e)||W(e))&&W(e.then)&&W(e.catch),vi=Object.prototype.toString,ts=e=>vi.call(e),Oo=e=>ts(e).slice(8,-1),yi=e=>ts(e)==="[object Object]",dn=e=>ue(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,Bt=cn(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),Ps=e=>{const t=Object.create(null);return(s=>t[s]||(t[s]=e(s)))},Do=/-\w/g,je=Ps(e=>e.replace(Do,t=>t.slice(1).toUpperCase())),Ro=/\B([A-Z])/g,ft=Ps(e=>e.replace(Ro,"-$1").toLowerCase()),_i=Ps(e=>e.charAt(0).toUpperCase()+e.slice(1)),Ns=Ps(e=>e?`on${_i(e)}`:""),qe=(e,t)=>!Object.is(e,t),ps=(e,...t)=>{for(let s=0;s{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:n,value:s})},Cs=e=>{const t=parseFloat(e);return isNaN(t)?e:t};let In;const As=()=>In||(In=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function pn(e){if(L(e)){const t={};for(let s=0;s{if(s){const n=s.split(Io);n.length>1&&(t[n[0].trim()]=n[1].trim())}}),t}function Ee(e){let t="";if(ue(e))t=e;else if(L(e))for(let s=0;sut(s,t))}const ki=e=>!!(e&&e.__v_isRef===!0),m=e=>ue(e)?e:e==null?"":L(e)||te(e)&&(e.toString===vi||!W(e.toString))?ki(e)?m(e.value):JSON.stringify(e,Ti,2):String(e),Ti=(e,t)=>ki(t)?Ti(e,t.value):St(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((s,[n,i],o)=>(s[Ms(n,o)+" =>"]=i,s),{})}:zt(t)?{[`Set(${t.size})`]:[...t.values()].map(s=>Ms(s))}:Je(t)?Ms(t):te(t)&&!L(t)&&!yi(t)?String(t):t,Ms=(e,t="")=>{var s;return Je(e)?`Symbol(${(s=e.description)!=null?s:t})`:e};/** -* @vue/reactivity v3.5.39 -* (c) 2018-present Yuxi (Evan) You and Vue contributors -* @license MIT -**/let me;class Fo{constructor(t=!1){this.detached=t,this._active=!0,this._on=0,this.effects=[],this.cleanups=[],this._isPaused=!1,this._warnOnRun=!0,this.__v_skip=!0,!t&&me&&(me.active?(this.parent=me,this.index=(me.scopes||(me.scopes=[])).push(this)-1):(this._active=!1,this._warnOnRun=!1))}get active(){return this._active}pause(){if(this._active){this._isPaused=!0;let t,s;if(this.scopes)for(t=0,s=this.scopes.length;t0&&--this._on===0){if(me===this)me=this.prevScope;else{let t=me;for(;t;){if(t.prevScope===this){t.prevScope=this.prevScope;break}t=t.prevScope}}this.prevScope=void 0}}stop(t){if(this._active){this._active=!1;let s,n;for(s=0,n=this.effects.length;s0)return;if(Vt){let t=Vt;for(Vt=void 0;t;){const s=t.next;t.next=void 0,t.flags&=-9,t=s}}let e;for(;Ht;){let t=Ht;for(Ht=void 0;t;){const s=t.next;if(t.next=void 0,t.flags&=-9,t.flags&1)try{t.trigger()}catch(n){e||(e=n)}t=s}}if(e)throw e}function Ci(e){for(let t=e.deps;t;t=t.nextDep)t.version=-1,t.prevActiveLink=t.dep.activeLink,t.dep.activeLink=t}function Ai(e){let t,s=e.depsTail,n=s;for(;n;){const i=n.prevDep;n.version===-1?(n===s&&(s=i),mn(n),Ho(n)):t=n,n.dep.activeLink=n.prevActiveLink,n.prevActiveLink=void 0,n=i}e.deps=t,e.depsTail=s}function Js(e){for(let t=e.deps;t;t=t.nextDep)if(t.dep.version!==t.version||t.dep.computed&&($i(t.dep.computed)||t.dep.version!==t.version))return!0;return!!e._dirty}function $i(e){if(e.flags&4&&!(e.flags&16)||(e.flags&=-17,e.globalVersion===Zt)||(e.globalVersion=Zt,!e.isSSR&&e.flags&128&&(!e.deps&&!e._dirty||!Js(e))))return;e.flags|=2;const t=e.dep,s=oe,n=Ue;oe=e,Ue=!0;try{Ci(e);const i=e.fn(e._value);(t.version===0||qe(i,e._value))&&(e.flags|=128,e._value=i,t.version++)}catch(i){throw t.version++,i}finally{oe=s,Ue=n,Ai(e),e.flags&=-3}}function mn(e,t=!1){const{dep:s,prevSub:n,nextSub:i}=e;if(n&&(n.nextSub=i,e.prevSub=void 0),i&&(i.prevSub=n,e.nextSub=void 0),s.subs===e&&(s.subs=n,!n&&s.computed)){s.computed.flags&=-5;for(let o=s.computed.deps;o;o=o.nextDep)mn(o,!0)}!t&&!--s.sc&&s.map&&s.map.delete(s.key)}function Ho(e){const{prevDep:t,nextDep:s}=e;t&&(t.nextDep=s,e.prevDep=void 0),s&&(s.prevDep=t,e.nextDep=void 0)}let Ue=!0;const Oi=[];function Ye(){Oi.push(Ue),Ue=!1}function Xe(){const e=Oi.pop();Ue=e===void 0?!0:e}function jn(e){const{cleanup:t}=e;if(e.cleanup=void 0,t){const s=oe;oe=void 0;try{t()}finally{oe=s}}}let Zt=0;class Vo{constructor(t,s){this.sub=t,this.dep=s,this.version=s.version,this.nextDep=this.prevDep=this.nextSub=this.prevSub=this.prevActiveLink=void 0}}class bn{constructor(t){this.computed=t,this.version=0,this.activeLink=void 0,this.subs=void 0,this.map=void 0,this.key=void 0,this.sc=0,this.__v_skip=!0}track(t){if(!oe||!Ue||oe===this.computed)return;let s=this.activeLink;if(s===void 0||s.sub!==oe)s=this.activeLink=new Vo(oe,this),oe.deps?(s.prevDep=oe.depsTail,oe.depsTail.nextDep=s,oe.depsTail=s):oe.deps=oe.depsTail=s,Di(s);else if(s.version===-1&&(s.version=this.version,s.nextDep)){const n=s.nextDep;n.prevDep=s.prevDep,s.prevDep&&(s.prevDep.nextDep=n),s.prevDep=oe.depsTail,s.nextDep=void 0,oe.depsTail.nextDep=s,oe.depsTail=s,oe.deps===s&&(oe.deps=n)}return s}trigger(t){this.version++,Zt++,this.notify(t)}notify(t){hn();try{for(let s=this.subs;s;s=s.prevSub)s.sub.notify()&&s.sub.dep.notify()}finally{gn()}}}function Di(e){if(e.dep.sc++,e.sub.flags&4){const t=e.dep.computed;if(t&&!e.dep.subs){t.flags|=20;for(let n=t.deps;n;n=n.nextDep)Di(n)}const s=e.dep.subs;s!==e&&(e.prevSub=s,s&&(s.nextSub=e)),e.dep.subs=e}}const Ys=new WeakMap,yt=Symbol(""),Xs=Symbol(""),Jt=Symbol("");function ve(e,t,s){if(Ue&&oe){let n=Ys.get(e);n||Ys.set(e,n=new Map);let i=n.get(s);i||(n.set(s,i=new bn),i.map=n,i.key=s),i.track()}}function nt(e,t,s,n,i,o){const r=Ys.get(e);if(!r){Zt++;return}const a=l=>{l&&l.trigger()};if(hn(),t==="clear")r.forEach(a);else{const l=L(e),g=l&&dn(s);if(l&&s==="length"){const d=Number(n);r.forEach((b,E)=>{(E==="length"||E===Jt||!Je(E)&&E>=d)&&a(b)})}else switch((s!==void 0||r.has(void 0))&&a(r.get(s)),g&&a(r.get(Jt)),t){case"add":l?g&&a(r.get("length")):(a(r.get(yt)),St(e)&&a(r.get(Xs)));break;case"delete":l||(a(r.get(yt)),St(e)&&a(r.get(Xs)));break;case"set":St(e)&&a(r.get(yt));break}}gn()}function xt(e){const t=Y(e);return t===e?t:(ve(t,"iterate",Jt),ze(e)?t:t.map(Ne))}function $s(e){return ve(e=Y(e),"iterate",Jt),e}function Ke(e,t){return rt(e)?At(_t(e)?Ne(t):t):Ne(t)}const Go={__proto__:null,[Symbol.iterator](){return Fs(this,Symbol.iterator,e=>Ke(this,e))},concat(...e){return xt(this).concat(...e.map(t=>L(t)?xt(t):t))},entries(){return Fs(this,"entries",e=>(e[1]=Ke(this,e[1]),e))},every(e,t){return Qe(this,"every",e,t,void 0,arguments)},filter(e,t){return Qe(this,"filter",e,t,s=>s.map(n=>Ke(this,n)),arguments)},find(e,t){return Qe(this,"find",e,t,s=>Ke(this,s),arguments)},findIndex(e,t){return Qe(this,"findIndex",e,t,void 0,arguments)},findLast(e,t){return Qe(this,"findLast",e,t,s=>Ke(this,s),arguments)},findLastIndex(e,t){return Qe(this,"findLastIndex",e,t,void 0,arguments)},forEach(e,t){return Qe(this,"forEach",e,t,void 0,arguments)},includes(...e){return Bs(this,"includes",e)},indexOf(...e){return Bs(this,"indexOf",e)},join(e){return xt(this).join(e)},lastIndexOf(...e){return Bs(this,"lastIndexOf",e)},map(e,t){return Qe(this,"map",e,t,void 0,arguments)},pop(){return Nt(this,"pop")},push(...e){return Nt(this,"push",e)},reduce(e,...t){return Un(this,"reduce",e,t)},reduceRight(e,...t){return Un(this,"reduceRight",e,t)},shift(){return Nt(this,"shift")},some(e,t){return Qe(this,"some",e,t,void 0,arguments)},splice(...e){return Nt(this,"splice",e)},toReversed(){return xt(this).toReversed()},toSorted(e){return xt(this).toSorted(e)},toSpliced(...e){return xt(this).toSpliced(...e)},unshift(...e){return Nt(this,"unshift",e)},values(){return Fs(this,"values",e=>Ke(this,e))}};function Fs(e,t,s){const n=$s(e),i=n[t]();return n!==e&&!ze(e)&&(i._next=i.next,i.next=()=>{const o=i._next();return o.done||(o.value=s(o.value)),o}),i}const Ko=Array.prototype;function Qe(e,t,s,n,i,o){const r=$s(e),a=r!==e&&!ze(e),l=r[t];if(l!==Ko[t]){const b=l.apply(e,o);return a?Ne(b):b}let g=s;r!==e&&(a?g=function(b,E){return s.call(this,Ke(e,b),E,e)}:s.length>2&&(g=function(b,E){return s.call(this,b,E,e)}));const d=l.call(r,g,n);return a&&i?i(d):d}function Un(e,t,s,n){const i=$s(e),o=i!==e&&!ze(e);let r=s,a=!1;i!==e&&(o?(a=n.length===0,r=function(g,d,b){return a&&(a=!1,g=Ke(e,g)),s.call(this,g,Ke(e,d),b,e)}):s.length>3&&(r=function(g,d,b){return s.call(this,g,d,b,e)}));const l=i[t](r,...n);return a?Ke(e,l):l}function Bs(e,t,s){const n=Y(e);ve(n,"iterate",Jt);const i=n[t](...s);return(i===-1||i===!1)&&_n(s[0])?(s[0]=Y(s[0]),n[t](...s)):i}function Nt(e,t,s=[]){Ye(),hn();const n=Y(e)[t].apply(e,s);return gn(),Xe(),n}const Wo=cn("__proto__,__v_isRef,__isVue"),Ri=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(Je));function qo(e){Je(e)||(e=String(e));const t=Y(this);return ve(t,"has",e),t.hasOwnProperty(e)}class zi{constructor(t=!1,s=!1){this._isReadonly=t,this._isShallow=s}get(t,s,n){if(s==="__v_skip")return t.__v_skip;const i=this._isReadonly,o=this._isShallow;if(s==="__v_isReactive")return!i;if(s==="__v_isReadonly")return i;if(s==="__v_isShallow")return o;if(s==="__v_raw")return n===(i?o?ir:Ni:o?Ui:ji).get(t)||Object.getPrototypeOf(t)===Object.getPrototypeOf(n)?t:void 0;const r=L(t);if(!i){let l;if(r&&(l=Go[s]))return l;if(s==="hasOwnProperty")return qo}const a=Reflect.get(t,s,ye(t)?t:n);if((Je(s)?Ri.has(s):Wo(s))||(i||ve(t,"get",s),o))return a;if(ye(a)){const l=r&&dn(s)?a:a.value;return i&&te(l)?en(l):l}return te(a)?i?en(a):Yt(a):a}}class Ii extends zi{constructor(t=!1){super(!1,t)}set(t,s,n,i){let o=t[s];const r=L(t)&&dn(s);if(!this._isShallow){const g=rt(o);if(!ze(n)&&!rt(n)&&(o=Y(o),n=Y(n)),!r&&ye(o)&&!ye(n))return g||(o.value=n),!0}const a=r?Number(s)e,ls=e=>Reflect.getPrototypeOf(e);function Qo(e,t,s){return function(...n){const i=this.__v_raw,o=Y(i),r=St(o),a=e==="entries"||e===Symbol.iterator&&r,l=e==="keys"&&r,g=i[e](...n),d=s?Qs:t?At:Ne;return!t&&ve(o,"iterate",l?Xs:yt),_e(Object.create(g),{next(){const{value:b,done:E}=g.next();return E?{value:b,done:E}:{value:a?[d(b[0]),d(b[1])]:d(b),done:E}}})}}function cs(e){return function(...t){return e==="delete"?!1:e==="clear"?void 0:this}}function er(e,t){const s={get(i){const o=this.__v_raw,r=Y(o),a=Y(i);e||(qe(i,a)&&ve(r,"get",i),ve(r,"get",a));const{has:l}=ls(r),g=t?Qs:e?At:Ne;if(l.call(r,i))return g(o.get(i));if(l.call(r,a))return g(o.get(a));o!==r&&o.get(i)},get size(){const i=this.__v_raw;return!e&&ve(Y(i),"iterate",yt),i.size},has(i){const o=this.__v_raw,r=Y(o),a=Y(i);return e||(qe(i,a)&&ve(r,"has",i),ve(r,"has",a)),i===a?o.has(i):o.has(i)||o.has(a)},forEach(i,o){const r=this,a=r.__v_raw,l=Y(a),g=t?Qs:e?At:Ne;return!e&&ve(l,"iterate",yt),a.forEach((d,b)=>i.call(o,g(d),g(b),r))}};return _e(s,e?{add:cs("add"),set:cs("set"),delete:cs("delete"),clear:cs("clear")}:{add(i){const o=Y(this),r=ls(o),a=Y(i),l=!t&&!ze(i)&&!rt(i)?a:i;return r.has.call(o,l)||qe(i,l)&&r.has.call(o,i)||qe(a,l)&&r.has.call(o,a)||(o.add(l),nt(o,"add",l,l)),this},set(i,o){!t&&!ze(o)&&!rt(o)&&(o=Y(o));const r=Y(this),{has:a,get:l}=ls(r);let g=a.call(r,i);g||(i=Y(i),g=a.call(r,i));const d=l.call(r,i);return r.set(i,o),g?qe(o,d)&&nt(r,"set",i,o):nt(r,"add",i,o),this},delete(i){const o=Y(this),{has:r,get:a}=ls(o);let l=r.call(o,i);l||(i=Y(i),l=r.call(o,i)),a&&a.call(o,i);const g=o.delete(i);return l&&nt(o,"delete",i,void 0),g},clear(){const i=Y(this),o=i.size!==0,r=i.clear();return o&&nt(i,"clear",void 0,void 0),r}}),["keys","values","entries",Symbol.iterator].forEach(i=>{s[i]=Qo(i,e,t)}),s}function vn(e,t){const s=er(e,t);return(n,i,o)=>i==="__v_isReactive"?!e:i==="__v_isReadonly"?e:i==="__v_raw"?n:Reflect.get(X(s,i)&&i in n?s:n,i,o)}const tr={get:vn(!1,!1)},sr={get:vn(!1,!0)},nr={get:vn(!0,!1)};const ji=new WeakMap,Ui=new WeakMap,Ni=new WeakMap,ir=new WeakMap;function or(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function Yt(e){return rt(e)?e:yn(e,!1,Jo,tr,ji)}function rr(e){return yn(e,!1,Xo,sr,Ui)}function en(e){return yn(e,!0,Yo,nr,Ni)}function yn(e,t,s,n,i){if(!te(e)||e.__v_raw&&!(t&&e.__v_isReactive)||e.__v_skip||!Object.isExtensible(e))return e;const o=i.get(e);if(o)return o;const r=or(Oo(e));if(r===0)return e;const a=new Proxy(e,r===2?n:s);return i.set(e,a),a}function _t(e){return rt(e)?_t(e.__v_raw):!!(e&&e.__v_isReactive)}function rt(e){return!!(e&&e.__v_isReadonly)}function ze(e){return!!(e&&e.__v_isShallow)}function _n(e){return e?!!e.__v_raw:!1}function Y(e){const t=e&&e.__v_raw;return t?Y(t):e}function ar(e){return!X(e,"__v_skip")&&Object.isExtensible(e)&&wi(e,"__v_skip",!0),e}const Ne=e=>te(e)?Yt(e):e,At=e=>te(e)?en(e):e;function ye(e){return e?e.__v_isRef===!0:!1}function H(e){return lr(e,!1)}function lr(e,t){return ye(e)?e:new cr(e,t)}class cr{constructor(t,s){this.dep=new bn,this.__v_isRef=!0,this.__v_isShallow=!1,this._rawValue=s?t:Y(t),this._value=s?t:Ne(t),this.__v_isShallow=s}get value(){return this.dep.track(),this._value}set value(t){const s=this._rawValue,n=this.__v_isShallow||ze(t)||rt(t);t=n?t:Y(t),qe(t,s)&&(this._rawValue=t,this._value=n?t:Ne(t),this.dep.trigger())}}function h(e){return ye(e)?e.value:e}const ur={get:(e,t,s)=>t==="__v_raw"?e:h(Reflect.get(e,t,s)),set:(e,t,s,n)=>{const i=e[t];return ye(i)&&!ye(s)?(i.value=s,!0):Reflect.set(e,t,s,n)}};function Mi(e){return _t(e)?e:new Proxy(e,ur)}class dr{constructor(t,s,n){this.fn=t,this.setter=s,this._value=void 0,this.dep=new bn(this),this.__v_isRef=!0,this.deps=void 0,this.depsTail=void 0,this.flags=16,this.globalVersion=Zt-1,this.next=void 0,this.effect=this,this.__v_isReadonly=!s,this.isSSR=n}notify(){if(this.flags|=16,!(this.flags&8)&&oe!==this)return Pi(this,!0),!0}get value(){const t=this.dep.track();return $i(this),t&&(t.version=this.dep.version),this._value}set value(t){this.setter&&this.setter(t)}}function pr(e,t,s=!1){let n,i;return W(e)?n=e:(n=e.get,i=e.set),new dr(n,i,s)}const us={},ms=new WeakMap;let vt;function fr(e,t=!1,s=vt){if(s){let n=ms.get(s);n||ms.set(s,n=[]),n.push(e)}}function hr(e,t,s=ne){const{immediate:n,deep:i,once:o,scheduler:r,augmentJob:a,call:l}=s,g=U=>i?U:ze(U)||i===!1||i===0?it(U,1):it(U);let d,b,E,A,V=!1,x=!1;if(ye(e)?(b=()=>e.value,V=ze(e)):_t(e)?(b=()=>g(e),V=!0):L(e)?(x=!0,V=e.some(U=>_t(U)||ze(U)),b=()=>e.map(U=>{if(ye(U))return U.value;if(_t(U))return g(U);if(W(U))return l?l(U,2):U()})):W(e)?t?b=l?()=>l(e,2):e:b=()=>{if(E){Ye();try{E()}finally{Xe()}}const U=vt;vt=d;try{return l?l(e,3,[A]):e(A)}finally{vt=U}}:b=Ze,t&&i){const U=b,le=i===!0?1/0:i;b=()=>it(U(),le)}const N=Bo(),R=()=>{d.stop(),N&&N.active&&un(N.effects,d)};if(o&&t){const U=t;t=(...le)=>{const z=U(...le);return R(),z}}let G=x?new Array(e.length).fill(us):us;const Z=U=>{if(!(!(d.flags&1)||!d.dirty&&!U))if(t){const le=d.run();if(U||i||V||(x?le.some((z,K)=>qe(z,G[K])):qe(le,G))){E&&E();const z=vt;vt=d;try{const K=[le,G===us?void 0:x&&G[0]===us?[]:G,A];G=le,l?l(t,3,K):t(...K)}finally{vt=z}}}else d.run()};return a&&a(Z),d=new Si(b),d.scheduler=r?()=>r(Z,!1):Z,A=U=>fr(U,!1,d),E=d.onStop=()=>{const U=ms.get(d);if(U){if(l)l(U,4);else for(const le of U)le();ms.delete(d)}},t?n?Z(!0):G=d.run():r?r(Z.bind(null,!0),!0):d.run(),R.pause=d.pause.bind(d),R.resume=d.resume.bind(d),R.stop=R,R}function it(e,t=1/0,s){if(t<=0||!te(e)||e.__v_skip||(s=s||new Map,(s.get(e)||0)>=t))return e;if(s.set(e,t),t--,ye(e))it(e.value,t,s);else if(L(e))for(let n=0;n{it(n,t,s)});else if(yi(e)){for(const n in e)it(e[n],t,s);for(const n of Object.getOwnPropertySymbols(e))Object.prototype.propertyIsEnumerable.call(e,n)&&it(e[n],t,s)}return e}/** -* @vue/runtime-core v3.5.39 -* (c) 2018-present Yuxi (Evan) You and Vue contributors -* @license MIT -**/function ss(e,t,s,n){try{return n?e(...n):e()}catch(i){Os(i,t,s)}}function Me(e,t,s,n){if(W(e)){const i=ss(e,t,s,n);return i&&bi(i)&&i.catch(o=>{Os(o,t,s)}),i}if(L(e)){const i=[];for(let o=0;o>>1,i=ke[n],o=Xt(i);o=Xt(s)?ke.push(e):ke.splice(mr(t),0,e),e.flags|=1,Bi()}}function Bi(){bs||(bs=Li.then(Vi))}function br(e){L(e)?Et.push(...e):ct&&e.id===-1?ct.splice(kt+1,0,e):e.flags&1||(Et.push(e),e.flags|=1),Bi()}function Nn(e,t,s=Ge+1){for(;sXt(s)-Xt(n));if(Et.length=0,ct){ct.push(...t);return}for(ct=t,kt=0;kte.id==null?e.flags&2?-1:1/0:e.id;function Vi(e){try{for(Ge=0;Ge{n._d&&Zn(-1);const o=vs(t);let r;try{r=e(...i)}finally{vs(o),n._d&&Zn(1)}return r};return n._n=!0,n._c=!0,n._d=!0,n}function pe(e,t){if(Re===null)return e;const s=Is(Re),n=e.dirs||(e.dirs=[]);for(let i=0;i1)return s&&W(t)?t.call(n&&n.proxy):t}}const _r=Symbol.for("v-scx"),wr=()=>fs(_r);function Hs(e,t,s){return Ki(e,t,s)}function Ki(e,t,s=ne){const{immediate:n,deep:i,flush:o,once:r}=s,a=_e({},s),l=t&&n||!t&&o!=="post";let g;if(es){if(o==="sync"){const A=wr();g=A.__watcherHandles||(A.__watcherHandles=[])}else if(!l){const A=()=>{};return A.stop=Ze,A.resume=Ze,A.pause=Ze,A}}const d=Te;a.call=(A,V,x)=>Me(A,d,V,x);let b=!1;o==="post"?a.scheduler=A=>{Se(A,d&&d.suspense)}:o!=="sync"&&(b=!0,a.scheduler=(A,V)=>{V?A():wn(A)}),a.augmentJob=A=>{t&&(A.flags|=4),b&&(A.flags|=2,d&&(A.id=d.uid,A.i=d))};const E=hr(e,t,a);return es&&(g?g.push(E):l&&E()),E}function xr(e,t,s){const n=this.proxy,i=ue(e)?e.includes(".")?Wi(n,e):()=>n[e]:e.bind(n,n);let o;W(t)?o=t:(o=t.handler,s=t);const r=ns(this),a=Ki(i,o.bind(n),s);return r(),a}function Wi(e,t){const s=t.split(".");return()=>{let n=e;for(let i=0;ie.__isTeleport,Vs=Symbol("_leaveCb");function xn(e,t){e.shapeFlag&6&&e.component?(e.transition=t,xn(e.component.subTree,t)):e.shapeFlag&128?(e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback)):e.transition=t}function qi(e){e.ids=[e.ids[0]+e.ids[2]+++"-",0,0]}function Mn(e,t){let s;return!!((s=Object.getOwnPropertyDescriptor(e,t))&&!s.configurable)}const ys=new WeakMap;function Gt(e,t,s,n,i=!1){if(L(e)){e.forEach((x,N)=>Gt(x,t&&(L(t)?t[N]:t),s,n,i));return}if(Kt(n)&&!i){n.shapeFlag&512&&n.type.__asyncResolved&&n.component.subTree.component&&Gt(e,t,s,n.component.subTree);return}const o=n.shapeFlag&4?Is(n.component):n.el,r=i?null:o,{i:a,r:l}=e,g=t&&t.r,d=a.refs===ne?a.refs={}:a.refs,b=a.setupState,E=Y(b),A=b===ne?mi:x=>Mn(d,x)?!1:X(E,x),V=(x,N)=>!(N&&Mn(d,N));if(g!=null&&g!==l){if(Ln(t),ue(g))d[g]=null,A(g)&&(b[g]=null);else if(ye(g)){const x=t;V(g,x.k)&&(g.value=null),x.k&&(d[x.k]=null)}}if(W(l)){Ye();try{ss(l,a,12,[r,d])}finally{Xe()}}else{const x=ue(l),N=ye(l);if(x||N){const R=()=>{if(e.f){const G=x?A(l)?b[l]:d[l]:V()||!e.k?l.value:d[e.k];if(i)L(G)&&un(G,o);else if(L(G))G.includes(o)||G.push(o);else if(x)d[l]=[o],A(l)&&(b[l]=d[l]);else{const Z=[o];V(l,e.k)&&(l.value=Z),e.k&&(d[e.k]=Z)}}else x?(d[l]=r,A(l)&&(b[l]=r)):N&&(V(l,e.k)&&(l.value=r),e.k&&(d[e.k]=r))};if(r){const G=()=>{R(),ys.delete(e)};G.id=-1,ys.set(e,G),Se(G,s)}else Ln(e),R()}}}function Ln(e){const t=ys.get(e);t&&(t.flags|=8,ys.delete(e))}As().requestIdleCallback;As().cancelIdleCallback;const Kt=e=>!!e.type.__asyncLoader,Zi=e=>e.type.__isKeepAlive;function Sr(e,t){Ji(e,"a",t)}function Er(e,t){Ji(e,"da",t)}function Ji(e,t,s=Te){const n=e.__wdc||(e.__wdc=()=>{let i=s;for(;i;){if(i.isDeactivated)return;i=i.parent}return e()});if(Ds(t,n,s),s){let i=s.parent;for(;i&&i.parent;)Zi(i.parent.vnode)&&Pr(n,t,s,i),i=i.parent}}function Pr(e,t,s,n){const i=Ds(t,e,n,!0);kn(()=>{un(n[t],i)},s)}function Ds(e,t,s=Te,n=!1){if(s){const i=s[e]||(s[e]=[]),o=t.__weh||(t.__weh=(...r)=>{Ye();const a=ns(s),l=Me(t,s,e,r);return a(),Xe(),l});return n?i.unshift(o):i.push(o),o}}const at=e=>(t,s=Te)=>{(!es||e==="sp")&&Ds(e,(...n)=>t(...n),s)},Cr=at("bm"),lt=at("m"),Ar=at("bu"),$r=at("u"),Or=at("bum"),kn=at("um"),Dr=at("sp"),Rr=at("rtg"),zr=at("rtc");function Ir(e,t=Te){Ds("ec",e,t)}const jr=Symbol.for("v-ndc");function Ce(e,t,s,n){let i;const o=s,r=L(e);if(r||ue(e)){const a=r&&_t(e);let l=!1,g=!1;a&&(l=!ze(e),g=rt(e),e=$s(e)),i=new Array(e.length);for(let d=0,b=e.length;dt(a,l,void 0,o));else{const a=Object.keys(e);i=new Array(a.length);for(let l=0,g=a.length;le?vo(e)?Is(e):tn(e.parent):null,Wt=_e(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>tn(e.parent),$root:e=>tn(e.root),$host:e=>e.ce,$emit:e=>e.emit,$options:e=>Xi(e),$forceUpdate:e=>e.f||(e.f=()=>{wn(e.update)}),$nextTick:e=>e.n||(e.n=Fi.bind(e.proxy)),$watch:e=>xr.bind(e)}),Gs=(e,t)=>e!==ne&&!e.__isScriptSetup&&X(e,t),Ur={get({_:e},t){if(t==="__v_skip")return!0;const{ctx:s,setupState:n,data:i,props:o,accessCache:r,type:a,appContext:l}=e;if(t[0]!=="$"){const E=r[t];if(E!==void 0)switch(E){case 1:return n[t];case 2:return i[t];case 4:return s[t];case 3:return o[t]}else{if(Gs(n,t))return r[t]=1,n[t];if(i!==ne&&X(i,t))return r[t]=2,i[t];if(X(o,t))return r[t]=3,o[t];if(s!==ne&&X(s,t))return r[t]=4,s[t];sn&&(r[t]=0)}}const g=Wt[t];let d,b;if(g)return t==="$attrs"&&ve(e.attrs,"get",""),g(e);if((d=a.__cssModules)&&(d=d[t]))return d;if(s!==ne&&X(s,t))return r[t]=4,s[t];if(b=l.config.globalProperties,X(b,t))return b[t]},set({_:e},t,s){const{data:n,setupState:i,ctx:o}=e;return Gs(i,t)?(i[t]=s,!0):n!==ne&&X(n,t)?(n[t]=s,!0):X(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(o[t]=s,!0)},has({_:{data:e,setupState:t,accessCache:s,ctx:n,appContext:i,props:o,type:r}},a){let l;return!!(s[a]||e!==ne&&a[0]!=="$"&&X(e,a)||Gs(t,a)||X(o,a)||X(n,a)||X(Wt,a)||X(i.config.globalProperties,a)||(l=r.__cssModules)&&l[a])},defineProperty(e,t,s){return s.get!=null?e._.accessCache[t]=0:X(s,"value")&&this.set(e,t,s.value,null),Reflect.defineProperty(e,t,s)}};function Fn(e){return L(e)?e.reduce((t,s)=>(t[s]=null,t),{}):e}let sn=!0;function Nr(e){const t=Xi(e),s=e.proxy,n=e.ctx;sn=!1,t.beforeCreate&&Bn(t.beforeCreate,e,"bc");const{data:i,computed:o,methods:r,watch:a,provide:l,inject:g,created:d,beforeMount:b,mounted:E,beforeUpdate:A,updated:V,activated:x,deactivated:N,beforeDestroy:R,beforeUnmount:G,destroyed:Z,unmounted:U,render:le,renderTracked:z,renderTriggered:K,errorCaptured:P,serverPrefetch:I,expose:J,inheritAttrs:wt,components:is,directives:os,filters:js}=t;if(g&&Mr(g,n,null),r)for(const ce in r){const ie=r[ce];W(ie)&&(n[ce]=ie.bind(s))}if(i){const ce=i.call(s,s);te(ce)&&(e.data=Yt(ce))}if(sn=!0,o)for(const ce in o){const ie=o[ce],ht=W(ie)?ie.bind(s,s):W(ie.get)?ie.get.bind(s,s):Ze,rs=!W(ie)&&W(ie.set)?ie.set.bind(s):Ze,gt=Oe({get:ht,set:rs});Object.defineProperty(n,ce,{enumerable:!0,configurable:!0,get:()=>gt.value,set:Le=>gt.value=Le})}if(a)for(const ce in a)Yi(a[ce],n,s,ce);if(l){const ce=W(l)?l.call(s):l;Reflect.ownKeys(ce).forEach(ie=>{yr(ie,ce[ie])})}d&&Bn(d,e,"c");function we(ce,ie){L(ie)?ie.forEach(ht=>ce(ht.bind(s))):ie&&ce(ie.bind(s))}if(we(Cr,b),we(lt,E),we(Ar,A),we($r,V),we(Sr,x),we(Er,N),we(Ir,P),we(zr,z),we(Rr,K),we(Or,G),we(kn,U),we(Dr,I),L(J))if(J.length){const ce=e.exposed||(e.exposed={});J.forEach(ie=>{Object.defineProperty(ce,ie,{get:()=>s[ie],set:ht=>s[ie]=ht,enumerable:!0})})}else e.exposed||(e.exposed={});le&&e.render===Ze&&(e.render=le),wt!=null&&(e.inheritAttrs=wt),is&&(e.components=is),os&&(e.directives=os),I&&qi(e)}function Mr(e,t,s=Ze){L(e)&&(e=nn(e));for(const n in e){const i=e[n];let o;te(i)?"default"in i?o=fs(i.from||n,i.default,!0):o=fs(i.from||n):o=fs(i),ye(o)?Object.defineProperty(t,n,{enumerable:!0,configurable:!0,get:()=>o.value,set:r=>o.value=r}):t[n]=o}}function Bn(e,t,s){Me(L(e)?e.map(n=>n.bind(t.proxy)):e.bind(t.proxy),t,s)}function Yi(e,t,s,n){let i=n.includes(".")?Wi(s,n):()=>s[n];if(ue(e)){const o=t[e];W(o)&&Hs(i,o)}else if(W(e))Hs(i,e.bind(s));else if(te(e))if(L(e))e.forEach(o=>Yi(o,t,s,n));else{const o=W(e.handler)?e.handler.bind(s):t[e.handler];W(o)&&Hs(i,o,e)}}function Xi(e){const t=e.type,{mixins:s,extends:n}=t,{mixins:i,optionsCache:o,config:{optionMergeStrategies:r}}=e.appContext,a=o.get(t);let l;return a?l=a:!i.length&&!s&&!n?l=t:(l={},i.length&&i.forEach(g=>_s(l,g,r,!0)),_s(l,t,r)),te(t)&&o.set(t,l),l}function _s(e,t,s,n=!1){const{mixins:i,extends:o}=t;o&&_s(e,o,s,!0),i&&i.forEach(r=>_s(e,r,s,!0));for(const r in t)if(!(n&&r==="expose")){const a=Lr[r]||s&&s[r];e[r]=a?a(e[r],t[r]):t[r]}return e}const Lr={data:Hn,props:Vn,emits:Vn,methods:Lt,computed:Lt,beforeCreate:xe,created:xe,beforeMount:xe,mounted:xe,beforeUpdate:xe,updated:xe,beforeDestroy:xe,beforeUnmount:xe,destroyed:xe,unmounted:xe,activated:xe,deactivated:xe,errorCaptured:xe,serverPrefetch:xe,components:Lt,directives:Lt,watch:Br,provide:Hn,inject:Fr};function Hn(e,t){return t?e?function(){return _e(W(e)?e.call(this,this):e,W(t)?t.call(this,this):t)}:t:e}function Fr(e,t){return Lt(nn(e),nn(t))}function nn(e){if(L(e)){const t={};for(let s=0;st==="modelValue"||t==="model-value"?e.modelModifiers:e[`${t}Modifiers`]||e[`${je(t)}Modifiers`]||e[`${ft(t)}Modifiers`];function Kr(e,t,...s){if(e.isUnmounted)return;const n=e.vnode.props||ne;let i=s;const o=t.startsWith("update:"),r=o&&Gr(n,t.slice(7));r&&(r.trim&&(i=s.map(d=>ue(d)?d.trim():d)),r.number&&(i=s.map(Cs)));let a,l=n[a=Ns(t)]||n[a=Ns(je(t))];!l&&o&&(l=n[a=Ns(ft(t))]),l&&Me(l,e,6,i);const g=n[a+"Once"];if(g){if(!e.emitted)e.emitted={};else if(e.emitted[a])return;e.emitted[a]=!0,Me(g,e,6,i)}}const Wr=new WeakMap;function eo(e,t,s=!1){const n=s?Wr:t.emitsCache,i=n.get(e);if(i!==void 0)return i;const o=e.emits;let r={},a=!1;if(!W(e)){const l=g=>{const d=eo(g,t,!0);d&&(a=!0,_e(r,d))};!s&&t.mixins.length&&t.mixins.forEach(l),e.extends&&l(e.extends),e.mixins&&e.mixins.forEach(l)}return!o&&!a?(te(e)&&n.set(e,null),null):(L(o)?o.forEach(l=>r[l]=null):_e(r,o),te(e)&&n.set(e,r),r)}function Rs(e,t){return!e||!Ss(t)?!1:(t=t.slice(2),t=t==="Once"?t:t.replace(/Once$/,""),X(e,t[0].toLowerCase()+t.slice(1))||X(e,ft(t))||X(e,t))}function Gn(e){const{type:t,vnode:s,proxy:n,withProxy:i,propsOptions:[o],slots:r,attrs:a,emit:l,render:g,renderCache:d,props:b,data:E,setupState:A,ctx:V,inheritAttrs:x}=e,N=vs(e);let R,G;try{if(s.shapeFlag&4){const U=i||n,le=U;R=We(g.call(le,U,d,b,A,E,V)),G=a}else{const U=t;R=We(U.length>1?U(b,{attrs:a,slots:r,emit:l}):U(b,null)),G=t.props?a:qr(a)}}catch(U){qt.length=0,Os(U,e,1),R=ee(dt)}let Z=R;if(G&&x!==!1){const U=Object.keys(G),{shapeFlag:le}=Z;U.length&&le&7&&(o&&U.some(Es)&&(G=Zr(G,o)),Z=$t(Z,G,!1,!0))}return s.dirs&&(Z=$t(Z,null,!1,!0),Z.dirs=Z.dirs?Z.dirs.concat(s.dirs):s.dirs),s.transition&&xn(Z,s.transition),R=Z,vs(N),R}const qr=e=>{let t;for(const s in e)(s==="class"||s==="style"||Ss(s))&&((t||(t={}))[s]=e[s]);return t},Zr=(e,t)=>{const s={};for(const n in e)(!Es(n)||!(n.slice(9)in t))&&(s[n]=e[n]);return s};function Jr(e,t,s){const{props:n,children:i,component:o}=e,{props:r,children:a,patchFlag:l}=t,g=o.emitsOptions;if(t.dirs||t.transition)return!0;if(s&&l>=0){if(l&1024)return!0;if(l&16)return n?Kn(n,r,g):!!r;if(l&8){const d=t.dynamicProps;for(let b=0;bObject.create(so),io=e=>Object.getPrototypeOf(e)===so;function Xr(e,t,s,n=!1){const i={},o=no();e.propsDefaults=Object.create(null),oo(e,t,i,o);for(const r in e.propsOptions[0])r in i||(i[r]=void 0);s?e.props=n?i:rr(i):e.type.props?e.props=i:e.props=o,e.attrs=o}function Qr(e,t,s,n){const{props:i,attrs:o,vnode:{patchFlag:r}}=e,a=Y(i),[l]=e.propsOptions;let g=!1;if((n||r>0)&&!(r&16)){if(r&8){const d=e.vnode.dynamicProps;for(let b=0;b{l=!0;const[E,A]=ro(b,t,!0);_e(r,E),A&&a.push(...A)};!s&&t.mixins.length&&t.mixins.forEach(d),e.extends&&d(e.extends),e.mixins&&e.mixins.forEach(d)}if(!o&&!l)return te(e)&&n.set(e,Tt),Tt;if(L(o))for(let d=0;de==="_"||e==="_ctx"||e==="$stable",Sn=e=>L(e)?e.map(We):[We(e)],ta=(e,t,s)=>{if(t._n)return t;const n=vr((...i)=>Sn(t(...i)),s);return n._c=!1,n},ao=(e,t,s)=>{const n=e._ctx;for(const i in e){if(Tn(i))continue;const o=e[i];if(W(o))t[i]=ta(i,o,n);else if(o!=null){const r=Sn(o);t[i]=()=>r}}},lo=(e,t)=>{const s=Sn(t);e.slots.default=()=>s},co=(e,t,s)=>{for(const n in t)(s||!Tn(n))&&(e[n]=t[n])},sa=(e,t,s)=>{const n=e.slots=no();if(e.vnode.shapeFlag&32){const i=t._;i?(co(n,t,s),s&&wi(n,"_",i,!0)):ao(t,n)}else t&&lo(e,t)},na=(e,t,s)=>{const{vnode:n,slots:i}=e;let o=!0,r=ne;if(n.shapeFlag&32){const a=t._;a?s&&a===1?o=!1:co(i,t,s):(o=!t.$stable,ao(t,i)),r=t}else t&&(lo(e,t),r={default:1});if(o)for(const a in i)!Tn(a)&&r[a]==null&&delete i[a]},Se=la;function ia(e){return oa(e)}function oa(e,t){const s=As();s.__VUE__=!0;const{insert:n,remove:i,patchProp:o,createElement:r,createText:a,createComment:l,setText:g,setElementText:d,parentNode:b,nextSibling:E,setScopeId:A=Ze,insertStaticContent:V}=e,x=(c,p,v,S=null,k=null,_=null,O=void 0,$=null,C=!!p.dynamicChildren)=>{if(c===p)return;c&&!Mt(c,p)&&(S=as(c),Le(c,k,_,!0),c=null),p.patchFlag===-2&&(C=!1,p.dynamicChildren=null);const{type:w,ref:M,shapeFlag:D}=p;switch(w){case zs:N(c,p,v,S);break;case dt:R(c,p,v,S);break;case Ws:c==null&&G(p,v,S,O);break;case re:is(c,p,v,S,k,_,O,$,C);break;default:D&1?le(c,p,v,S,k,_,O,$,C):D&6?os(c,p,v,S,k,_,O,$,C):(D&64||D&128)&&w.process(c,p,v,S,k,_,O,$,C,jt)}M!=null&&k?Gt(M,c&&c.ref,_,p||c,!p):M==null&&c&&c.ref!=null&&Gt(c.ref,null,_,c,!0)},N=(c,p,v,S)=>{if(c==null)n(p.el=a(p.children),v,S);else{const k=p.el=c.el;p.children!==c.children&&g(k,p.children)}},R=(c,p,v,S)=>{c==null?n(p.el=l(p.children||""),v,S):p.el=c.el},G=(c,p,v,S)=>{[c.el,c.anchor]=V(c.children,p,v,S,c.el,c.anchor)},Z=({el:c,anchor:p},v,S)=>{let k;for(;c&&c!==p;)k=E(c),n(c,v,S),c=k;n(p,v,S)},U=({el:c,anchor:p})=>{let v;for(;c&&c!==p;)v=E(c),i(c),c=v;i(p)},le=(c,p,v,S,k,_,O,$,C)=>{if(p.type==="svg"?O="svg":p.type==="math"&&(O="mathml"),c==null)z(p,v,S,k,_,O,$,C);else{const w=c.el&&c.el._isVueCE?c.el:null;try{w&&w._beginPatch(),I(c,p,k,_,O,$,C)}finally{w&&w._endPatch()}}},z=(c,p,v,S,k,_,O,$)=>{let C,w;const{props:M,shapeFlag:D,transition:j,dirs:B}=c;if(C=c.el=r(c.type,_,M&&M.is,M),D&8?d(C,c.children):D&16&&P(c.children,C,null,S,k,Ks(c,_),O,$),B&&mt(c,null,S,"created"),K(C,c,c.scopeId,O,S),M){for(const se in M)se!=="value"&&!Bt(se)&&o(C,se,null,M[se],_,S);"value"in M&&o(C,"value",null,M.value,_),(w=M.onVnodeBeforeMount)&&Ve(w,S,c)}B&&mt(c,null,S,"beforeMount");const q=ra(k,j);q&&j.beforeEnter(C),n(C,p,v),((w=M&&M.onVnodeMounted)||q||B)&&Se(()=>{try{w&&Ve(w,S,c),q&&j.enter(C),B&&mt(c,null,S,"mounted")}finally{}},k)},K=(c,p,v,S,k)=>{if(v&&A(c,v),S)for(let _=0;_{for(let w=C;w{const $=p.el=c.el;let{patchFlag:C,dynamicChildren:w,dirs:M}=p;C|=c.patchFlag&16;const D=c.props||ne,j=p.props||ne;let B;if(v&&bt(v,!1),(B=j.onVnodeBeforeUpdate)&&Ve(B,v,p,c),M&&mt(p,c,v,"beforeUpdate"),v&&bt(v,!0),w&&(!c.dynamicChildren||c.dynamicChildren.length!==w.length)&&(C=0,O=!1,w=null),(D.innerHTML&&j.innerHTML==null||D.textContent&&j.textContent==null)&&d($,""),w?J(c.dynamicChildren,w,$,v,S,Ks(p,k),_):O||ie(c,p,$,null,v,S,Ks(p,k),_,!1),C>0){if(C&16)wt($,D,j,v,k);else if(C&2&&D.class!==j.class&&o($,"class",null,j.class,k),C&4&&o($,"style",D.style,j.style,k),C&8){const q=p.dynamicProps;for(let se=0;se{B&&Ve(B,v,p,c),M&&mt(p,c,v,"updated")},S)},J=(c,p,v,S,k,_,O)=>{for(let $=0;${if(p!==v){if(p!==ne)for(const _ in p)!Bt(_)&&!(_ in v)&&o(c,_,p[_],null,k,S);for(const _ in v){if(Bt(_))continue;const O=v[_],$=p[_];O!==$&&_!=="value"&&o(c,_,$,O,k,S)}"value"in v&&o(c,"value",p.value,v.value,k)}},is=(c,p,v,S,k,_,O,$,C)=>{const w=p.el=c?c.el:a(""),M=p.anchor=c?c.anchor:a("");let{patchFlag:D,dynamicChildren:j,slotScopeIds:B}=p;B&&($=$?$.concat(B):B),c==null?(n(w,v,S),n(M,v,S),P(p.children||[],v,M,k,_,O,$,C)):D>0&&D&64&&j&&c.dynamicChildren&&c.dynamicChildren.length===j.length?(J(c.dynamicChildren,j,v,k,_,O,$),(p.key!=null||k&&p===k.subTree)&&uo(c,p,!0)):ie(c,p,v,M,k,_,O,$,C)},os=(c,p,v,S,k,_,O,$,C)=>{p.slotScopeIds=$,c==null?p.shapeFlag&512?k.ctx.activate(p,v,S,O,C):js(p,v,S,k,_,O,C):Cn(c,p,C)},js=(c,p,v,S,k,_,O)=>{const $=c.component=ga(c,S,k);if(Zi(c)&&($.ctx.renderer=jt),ba($,!1,O),$.asyncDep){if(k&&k.registerDep($,we,O),!c.el){const C=$.subTree=ee(dt);R(null,C,p,v),c.placeholder=C.el}}else we($,c,p,v,k,_,O)},Cn=(c,p,v)=>{const S=p.component=c.component;if(Jr(c,p,v))if(S.asyncDep&&!S.asyncResolved){ce(S,p,v);return}else S.next=p,S.update();else p.el=c.el,S.vnode=p},we=(c,p,v,S,k,_,O)=>{const $=()=>{if(c.isMounted){let{next:D,bu:j,u:B,parent:q,vnode:se}=c;{const Be=po(c);if(Be){D&&(D.el=se.el,ce(c,D,O)),Be.asyncDep.then(()=>{Se(()=>{c.isUnmounted||w()},k)});return}}let Q=D,de;bt(c,!1),D?(D.el=se.el,ce(c,D,O)):D=se,j&&ps(j),(de=D.props&&D.props.onVnodeBeforeUpdate)&&Ve(de,q,D,se),bt(c,!0);const ge=Gn(c),Fe=c.subTree;c.subTree=ge,x(Fe,ge,b(Fe.el),as(Fe),c,k,_),D.el=ge.el,Q===null&&Yr(c,ge.el),B&&Se(B,k),(de=D.props&&D.props.onVnodeUpdated)&&Se(()=>Ve(de,q,D,se),k)}else{let D;const{el:j,props:B}=p,{bm:q,m:se,parent:Q,root:de,type:ge}=c,Fe=Kt(p);bt(c,!1),q&&ps(q),!Fe&&(D=B&&B.onVnodeBeforeMount)&&Ve(D,Q,p),bt(c,!0);{de.ce&&de.ce._hasShadowRoot()&&de.ce._injectChildStyle(ge,c.parent?c.parent.type:void 0);const Be=c.subTree=Gn(c);x(null,Be,v,S,c,k,_),p.el=Be.el}if(se&&Se(se,k),!Fe&&(D=B&&B.onVnodeMounted)){const Be=p;Se(()=>Ve(D,Q,Be),k)}(p.shapeFlag&256||Q&&Kt(Q.vnode)&&Q.vnode.shapeFlag&256)&&c.a&&Se(c.a,k),c.isMounted=!0,p=v=S=null}};c.scope.on();const C=c.effect=new Si($);c.scope.off();const w=c.update=C.run.bind(C),M=c.job=C.runIfDirty.bind(C);M.i=c,M.id=c.uid,C.scheduler=()=>wn(M),bt(c,!0),w()},ce=(c,p,v)=>{p.component=c;const S=c.vnode.props;c.vnode=p,c.next=null,Qr(c,p.props,S,v),na(c,p.children,v),Ye(),Nn(c),Xe()},ie=(c,p,v,S,k,_,O,$,C=!1)=>{const w=c&&c.children,M=c?c.shapeFlag:0,D=p.children,{patchFlag:j,shapeFlag:B}=p;if(j>0){if(j&128){rs(w,D,v,S,k,_,O,$,C);return}else if(j&256){ht(w,D,v,S,k,_,O,$,C);return}}B&8?(M&16&&It(w,k,_),D!==w&&d(v,D)):M&16?B&16?rs(w,D,v,S,k,_,O,$,C):It(w,k,_,!0):(M&8&&d(v,""),B&16&&P(D,v,S,k,_,O,$,C))},ht=(c,p,v,S,k,_,O,$,C)=>{c=c||Tt,p=p||Tt;const w=c.length,M=p.length,D=Math.min(w,M);let j;for(j=0;jM?It(c,k,_,!0,!1,D):P(p,v,S,k,_,O,$,C,D)},rs=(c,p,v,S,k,_,O,$,C)=>{let w=0;const M=p.length;let D=c.length-1,j=M-1;for(;w<=D&&w<=j;){const B=c[w],q=p[w]=C?st(p[w]):We(p[w]);if(Mt(B,q))x(B,q,v,null,k,_,O,$,C);else break;w++}for(;w<=D&&w<=j;){const B=c[D],q=p[j]=C?st(p[j]):We(p[j]);if(Mt(B,q))x(B,q,v,null,k,_,O,$,C);else break;D--,j--}if(w>D){if(w<=j){const B=j+1,q=Bj)for(;w<=D;)Le(c[w],k,_,!0),w++;else{const B=w,q=w,se=new Map;for(w=q;w<=j;w++){const Pe=p[w]=C?st(p[w]):We(p[w]);Pe.key!=null&&se.set(Pe.key,w)}let Q,de=0;const ge=j-q+1;let Fe=!1,Be=0;const Ut=new Array(ge);for(w=0;w=ge){Le(Pe,k,_,!0);continue}let He;if(Pe.key!=null)He=se.get(Pe.key);else for(Q=q;Q<=j;Q++)if(Ut[Q-q]===0&&Mt(Pe,p[Q])){He=Q;break}He===void 0?Le(Pe,k,_,!0):(Ut[He-q]=w+1,He>=Be?Be=He:Fe=!0,x(Pe,p[He],v,null,k,_,O,$,C),de++)}const On=Fe?aa(Ut):Tt;for(Q=On.length-1,w=ge-1;w>=0;w--){const Pe=q+w,He=p[Pe],Dn=p[Pe+1],Rn=Pe+1{const{el:_,type:O,transition:$,children:C,shapeFlag:w}=c;if(w&6){gt(c.component.subTree,p,v,S);return}if(w&128){c.suspense.move(p,v,S);return}if(w&64){O.move(c,p,v,jt);return}if(O===re){n(_,p,v);for(let D=0;D$.enter(_),k));else{const{leave:D,delayLeave:j,afterLeave:B}=$,q=()=>{c.ctx.isUnmounted?i(_):n(_,p,v)},se=()=>{const Q=_._isLeaving||!!_[Vs];_._isLeaving&&_[Vs](!0),$.persisted&&!Q?q():D(_,()=>{q(),B&&B()})};j?j(_,q,se):se()}else n(_,p,v)},Le=(c,p,v,S=!1,k=!1)=>{const{type:_,props:O,ref:$,children:C,dynamicChildren:w,shapeFlag:M,patchFlag:D,dirs:j,cacheIndex:B,memo:q}=c;if(D===-2&&(k=!1),$!=null&&(Ye(),Gt($,null,v,c,!0),Xe()),B!=null&&(p.renderCache[B]=void 0),M&256){p.ctx.deactivate(c);return}const se=M&1&&j,Q=!Kt(c);let de;if(Q&&(de=O&&O.onVnodeBeforeUnmount)&&Ve(de,p,c),M&6)Ao(c.component,v,S);else{if(M&128){c.suspense.unmount(v,S);return}se&&mt(c,null,p,"beforeUnmount"),M&64?c.type.remove(c,p,v,jt,S):w&&!w.hasOnce&&(_!==re||D>0&&D&64)?It(w,p,v,!1,!0):(_===re&&D&384||!k&&M&16)&&It(C,p,v),S&&An(c)}const ge=q!=null&&B==null;(Q&&(de=O&&O.onVnodeUnmounted)||se||ge)&&Se(()=>{de&&Ve(de,p,c),se&&mt(c,null,p,"unmounted"),ge&&(c.el=null)},v)},An=c=>{const{type:p,el:v,anchor:S,transition:k}=c;if(p===re){Co(v,S);return}if(p===Ws){U(c);return}const _=()=>{i(v),k&&!k.persisted&&k.afterLeave&&k.afterLeave()};if(c.shapeFlag&1&&k&&!k.persisted){const{leave:O,delayLeave:$}=k,C=()=>O(v,_);$?$(c.el,_,C):C()}else _()},Co=(c,p)=>{let v;for(;c!==p;)v=E(c),i(c),c=v;i(p)},Ao=(c,p,v)=>{const{bum:S,scope:k,job:_,subTree:O,um:$,m:C,a:w}=c;qn(C),qn(w),S&&ps(S),k.stop(),_&&(_.flags|=8,Le(O,c,p,v)),$&&Se($,p),Se(()=>{c.isUnmounted=!0},p)},It=(c,p,v,S=!1,k=!1,_=0)=>{for(let O=_;O{if(c.shapeFlag&6)return as(c.component.subTree);if(c.shapeFlag&128)return c.suspense.next();const p=E(c.anchor||c.el),v=p&&p[kr];return v?E(v):p};let Us=!1;const $n=(c,p,v)=>{let S;c==null?p._vnode&&(Le(p._vnode,null,null,!0),S=p._vnode.component):x(p._vnode||null,c,p,null,null,null,v),p._vnode=c,Us||(Us=!0,Nn(S),Hi(),Us=!1)},jt={p:x,um:Le,m:gt,r:An,mt:js,mc:P,pc:ie,pbc:J,n:as,o:e};return{render:$n,hydrate:void 0,createApp:Vr($n)}}function Ks({type:e,props:t},s){return s==="svg"&&e==="foreignObject"||s==="mathml"&&e==="annotation-xml"&&t&&t.encoding&&t.encoding.includes("html")?void 0:s}function bt({effect:e,job:t},s){s?(e.flags|=32,t.flags|=4):(e.flags&=-33,t.flags&=-5)}function ra(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}function uo(e,t,s=!1){const n=e.children,i=t.children;if(L(n)&&L(i))for(let o=0;o>1,e[s[a]]0&&(t[n]=s[o-1]),s[o]=n)}}for(o=s.length,r=s[o-1];o-- >0;)s[o]=r,r=t[r];return s}function po(e){const t=e.subTree.component;if(t)return t.asyncDep&&!t.asyncResolved?t:po(t)}function qn(e){if(e)for(let t=0;te.__isSuspense;function la(e,t){t&&t.pendingBranch?L(e)?t.effects.push(...e):t.effects.push(e):br(e)}const re=Symbol.for("v-fgt"),zs=Symbol.for("v-txt"),dt=Symbol.for("v-cmt"),Ws=Symbol.for("v-stc"),qt=[];let Ae=null;function y(e=!1){qt.push(Ae=e?null:[])}function ca(){qt.pop(),Ae=qt[qt.length-1]||null}let Qt=1;function Zn(e,t=!1){Qt+=e,e<0&&Ae&&t&&(Ae.hasOnce=!0)}function go(e){return e.dynamicChildren=Qt>0?Ae||Tt:null,ca(),Qt>0&&Ae&&Ae.push(e),e}function T(e,t,s,n,i,o){return go(u(e,t,s,n,i,o,!0))}function et(e,t,s,n,i){return go(ee(e,t,s,n,i,!0))}function mo(e){return e?e.__v_isVNode===!0:!1}function Mt(e,t){return e.type===t.type&&e.key===t.key}const bo=({key:e})=>e??null,hs=({ref:e,ref_key:t,ref_for:s})=>(typeof e=="number"&&(e=""+e),e!=null?ue(e)||ye(e)||W(e)?{i:Re,r:e,k:t,f:!!s}:e:null);function u(e,t=null,s=null,n=0,i=null,o=e===re?0:1,r=!1,a=!1){const l={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&bo(t),ref:t&&hs(t),scopeId:Gi,slotScopeIds:null,children:s,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetStart:null,targetAnchor:null,staticCount:0,shapeFlag:o,patchFlag:n,dynamicProps:i,dynamicChildren:null,appContext:null,ctx:Re};return a?(ws(l,s),o&128&&e.normalize(l)):s&&(l.shapeFlag|=ue(s)?8:16),Qt>0&&!r&&Ae&&(l.patchFlag>0||o&6)&&l.patchFlag!==32&&Ae.push(l),l}const ee=ua;function ua(e,t=null,s=null,n=0,i=null,o=!1){if((!e||e===jr)&&(e=dt),mo(e)){const a=$t(e,t,!0);return s&&ws(a,s),Qt>0&&!o&&Ae&&(a.shapeFlag&6?Ae[Ae.indexOf(e)]=a:Ae.push(a)),a.patchFlag=-2,a}if(wa(e)&&(e=e.__vccOpts),t){t=da(t);let{class:a,style:l}=t;a&&!ue(a)&&(t.class=Ee(a)),te(l)&&(_n(l)&&!L(l)&&(l=_e({},l)),t.style=pn(l))}const r=ue(e)?1:ho(e)?128:Tr(e)?64:te(e)?4:W(e)?2:0;return u(e,t,s,n,i,r,o,!0)}function da(e){return e?_n(e)||io(e)?_e({},e):e:null}function $t(e,t,s=!1,n=!1){const{props:i,ref:o,patchFlag:r,children:a,transition:l}=e,g=t?pa(i||{},t):i,d={__v_isVNode:!0,__v_skip:!0,type:e.type,props:g,key:g&&bo(g),ref:t&&t.ref?s&&o?L(o)?o.concat(hs(t)):[o,hs(t)]:hs(t):o,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:a,target:e.target,targetStart:e.targetStart,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==re?r===-1?16:r|16:r,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:l,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&$t(e.ssContent),ssFallback:e.ssFallback&&$t(e.ssFallback),placeholder:e.placeholder,el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce};return l&&n&&xn(d,l.clone(d)),d}function $e(e=" ",t=0){return ee(zs,null,e,t)}function F(e="",t=!1){return t?(y(),et(dt,null,e)):ee(dt,null,e)}function We(e){return e==null||typeof e=="boolean"?ee(dt):L(e)?ee(re,null,e.slice()):mo(e)?st(e):ee(zs,null,String(e))}function st(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:$t(e)}function ws(e,t){let s=0;const{shapeFlag:n}=e;if(t==null)t=null;else if(L(t))s=16;else if(typeof t=="object")if(n&65){const i=t.default;i&&(i._c&&(i._d=!1),ws(e,i()),i._c&&(i._d=!0));return}else{s=32;const i=t._;!i&&!io(t)?t._ctx=Re:i===3&&Re&&(Re.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else if(W(t)){if(n&65){ws(e,{default:t});return}t={default:t,_ctx:Re},s=32}else t=String(t),n&64?(s=16,t=[$e(t)]):s=8;e.children=t,e.shapeFlag|=s}function pa(...e){const t={};for(let s=0;sTe||Re;let xs,rn;{const e=As(),t=(s,n)=>{let i;return(i=e[s])||(i=e[s]=[]),i.push(n),o=>{i.length>1?i.forEach(r=>r(o)):i[0](o)}};xs=t("__VUE_INSTANCE_SETTERS__",s=>Te=s),rn=t("__VUE_SSR_SETTERS__",s=>es=s)}const ns=e=>{const t=Te;return xs(e),e.scope.on(),()=>{e.scope.off(),xs(t)}},Jn=()=>{Te&&Te.scope.off(),xs(null)};function vo(e){return e.vnode.shapeFlag&4}let es=!1;function ba(e,t=!1,s=!1){t&&rn(t);const{props:n,children:i}=e.vnode,o=vo(e);Xr(e,n,o,t),sa(e,i,s||t);const r=o?va(e,t):void 0;return t&&rn(!1),r}function va(e,t){const s=e.type;e.accessCache=Object.create(null),e.proxy=new Proxy(e.ctx,Ur);const{setup:n}=s;if(n){Ye();const i=e.setupContext=n.length>1?_a(e):null,o=ns(e),r=ss(n,e,0,[e.props,i]),a=bi(r);if(Xe(),o(),(a||e.sp)&&!Kt(e)&&qi(e),a){if(r.then(Jn,Jn),t)return r.then(l=>{Yn(e,l)}).catch(l=>{Os(l,e,0)});e.asyncDep=r}else Yn(e,r)}else yo(e)}function Yn(e,t,s){W(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:te(t)&&(e.setupState=Mi(t)),yo(e)}function yo(e,t,s){const n=e.type;e.render||(e.render=n.render||Ze);{const i=ns(e);Ye();try{Nr(e)}finally{Xe(),i()}}}const ya={get(e,t){return ve(e,"get",""),e[t]}};function _a(e){const t=s=>{e.exposed=s||{}};return{attrs:new Proxy(e.attrs,ya),slots:e.slots,emit:e.emit,expose:t}}function Is(e){return e.exposed?e.exposeProxy||(e.exposeProxy=new Proxy(Mi(ar(e.exposed)),{get(t,s){if(s in t)return t[s];if(s in Wt)return Wt[s](e)},has(t,s){return s in t||s in Wt}})):e.proxy}function wa(e){return W(e)&&"__vccOpts"in e}const Oe=(e,t)=>pr(e,t,es),xa="3.5.39";/** -* @vue/runtime-dom v3.5.39 -* (c) 2018-present Yuxi (Evan) You and Vue contributors -* @license MIT -**/let an;const Xn=typeof window<"u"&&window.trustedTypes;if(Xn)try{an=Xn.createPolicy("vue",{createHTML:e=>e})}catch{}const _o=an?e=>an.createHTML(e):e=>e,ka="http://www.w3.org/2000/svg",Ta="http://www.w3.org/1998/Math/MathML",tt=typeof document<"u"?document:null,Qn=tt&&tt.createElement("template"),Sa={insert:(e,t,s)=>{t.insertBefore(e,s||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,s,n)=>{const i=t==="svg"?tt.createElementNS(ka,e):t==="mathml"?tt.createElementNS(Ta,e):s?tt.createElement(e,{is:s}):tt.createElement(e);return e==="select"&&n&&n.multiple!=null&&i.setAttribute("multiple",n.multiple),i},createText:e=>tt.createTextNode(e),createComment:e=>tt.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>tt.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,s,n,i,o){const r=s?s.previousSibling:t.lastChild;if(i&&(i===o||i.nextSibling))for(;t.insertBefore(i.cloneNode(!0),s),!(i===o||!(i=i.nextSibling)););else{Qn.innerHTML=_o(n==="svg"?`${e}`:n==="mathml"?`${e}`:e);const a=Qn.content;if(n==="svg"||n==="mathml"){const l=a.firstChild;for(;l.firstChild;)a.appendChild(l.firstChild);a.removeChild(l)}t.insertBefore(a,s)}return[r?r.nextSibling:t.firstChild,s?s.previousSibling:t.lastChild]}},Ea=Symbol("_vtc");function Pa(e,t,s){const n=e[Ea];n&&(t=(t?[t,...n]:[...n]).join(" ")),t==null?e.removeAttribute("class"):s?e.setAttribute("class",t):e.className=t}const ei=Symbol("_vod"),Ca=Symbol("_vsh"),Aa=Symbol(""),$a=/(?:^|;)\s*display\s*:/;function Oa(e,t,s){const n=e.style,i=ue(s);let o=!1;if(s&&!i){if(t)if(ue(t))for(const r of t.split(";")){const a=r.slice(0,r.indexOf(":")).trim();s[a]==null&&Ft(n,a,"")}else for(const r in t)s[r]==null&&Ft(n,r,"");for(const r in s){r==="display"&&(o=!0);const a=s[r];a!=null?Ra(e,r,!ue(t)&&t?t[r]:void 0,a)||Ft(n,r,a):Ft(n,r,"")}}else if(i){if(t!==s){const r=n[Aa];r&&(s+=";"+r),n.cssText=s,o=$a.test(s)}}else t&&e.removeAttribute("style");ei in e&&(e[ei]=o?n.display:"",e[Ca]&&(n.display="none"))}const ti=/\s*!important$/;function Ft(e,t,s){if(L(s))s.forEach(n=>Ft(e,t,n));else if(s==null&&(s=""),t.startsWith("--"))e.setProperty(t,s);else{const n=Da(e,t);ti.test(s)?e.setProperty(ft(n),s.replace(ti,""),"important"):e[n]=s}}const si=["Webkit","Moz","ms"],qs={};function Da(e,t){const s=qs[t];if(s)return s;let n=je(t);if(n!=="filter"&&n in e)return qs[t]=n;n=_i(n);for(let i=0;iZs||(Ma.then(()=>Zs=0),Zs=Date.now());function Fa(e,t){const s=n=>{if(!n._vts)n._vts=Date.now();else if(n._vts<=s.attached)return;const i=s.value;if(L(i)){const o=n.stopImmediatePropagation;n.stopImmediatePropagation=()=>{o.call(n),n._stopped=!0};const r=i.slice(),a=[n];for(let l=0;le.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,Ba=(e,t,s,n,i,o)=>{const r=i==="svg";t==="class"?Pa(e,n,r):t==="style"?Oa(e,s,n):Ss(t)?Es(t)||Ia(e,t,s,n,o):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):Ha(e,t,n,r))?(oi(e,t,n),!e.tagName.includes("-")&&(t==="value"||t==="checked"||t==="selected")&&ii(e,t,n,r,o,t!=="value")):e._isVueCE&&(Va(e,t)||e._def.__asyncLoader&&(/[A-Z]/.test(t)||!ue(n)))?oi(e,je(t),n,o,t):(t==="true-value"?e._trueValue=n:t==="false-value"&&(e._falseValue=n),ii(e,t,n,r))};function Ha(e,t,s,n){if(n)return!!(t==="innerHTML"||t==="textContent"||t in e&&ai(t)&&W(s));if(t==="spellcheck"||t==="draggable"||t==="translate"||t==="autocorrect"||t==="sandbox"&&e.tagName==="IFRAME"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA")return!1;if(t==="width"||t==="height"){const i=e.tagName;if(i==="IMG"||i==="VIDEO"||i==="CANVAS"||i==="SOURCE")return!1}return ai(t)&&ue(s)?!1:t in e}function Va(e,t){const s=e._def.props;if(!s)return!1;const n=je(t);return Array.isArray(s)?s.some(i=>je(i)===n):Object.keys(s).some(i=>je(i)===n)}const pt=e=>{const t=e.props["onUpdate:modelValue"]||!1;return L(t)?s=>ps(t,s):t};function Ga(e){e.target.composing=!0}function li(e){const t=e.target;t.composing&&(t.composing=!1,t.dispatchEvent(new Event("input")))}const Ie=Symbol("_assign");function ci(e,t,s){return t&&(e=e.trim()),s&&(e=Cs(e)),e}const be={created(e,{modifiers:{lazy:t,trim:s,number:n}},i){e[Ie]=pt(i);const o=n||i.props&&i.props.type==="number";ot(e,t?"change":"input",r=>{r.target.composing||e[Ie](ci(e.value,s,o))}),(s||o)&&ot(e,"change",()=>{e.value=ci(e.value,s,o)}),t||(ot(e,"compositionstart",Ga),ot(e,"compositionend",li),ot(e,"change",li))},mounted(e,{value:t}){e.value=t??""},beforeUpdate(e,{value:t,oldValue:s,modifiers:{lazy:n,trim:i,number:o}},r){if(e[Ie]=pt(r),e.composing)return;const a=(o||e.type==="number")&&!/^0\d/.test(e.value)?Cs(e.value):e.value,l=t??"";if(a===l)return;const g=e.getRootNode();(g instanceof Document||g instanceof ShadowRoot)&&g.activeElement===e&&e.type!=="range"&&(n&&t===s||i&&e.value.trim()===l)||(e.value=l)}},Ka={deep:!0,created(e,t,s){e[Ie]=pt(s),ot(e,"change",()=>{const n=e._modelValue,i=Ot(e),o=e.checked,r=e[Ie];if(L(n)){const a=fn(n,i),l=a!==-1;if(o&&!l)r(n.concat(i));else if(!o&&l){const g=[...n];g.splice(a,1),r(g)}}else if(zt(n)){const a=new Set(n);o?a.add(i):a.delete(i),r(a)}else r(wo(e,o))})},mounted:ui,beforeUpdate(e,t,s){e[Ie]=pt(s),ui(e,t,s)}};function ui(e,{value:t,oldValue:s},n){e._modelValue=t;let i;if(L(t))i=fn(t,n.props.value)>-1;else if(zt(t))i=t.has(n.props.value);else{if(t===s)return;i=ut(t,wo(e,!0))}e.checked!==i&&(e.checked=i)}const Wa={created(e,{value:t},s){e.checked=ut(t,s.props.value),e[Ie]=pt(s),ot(e,"change",()=>{e[Ie](Ot(e))})},beforeUpdate(e,{value:t,oldValue:s},n){e[Ie]=pt(n),t!==s&&(e.checked=ut(t,n.props.value))}},ks={deep:!0,created(e,{value:t,modifiers:{number:s}},n){const i=zt(t);ot(e,"change",()=>{const o=Array.prototype.filter.call(e.options,r=>r.selected).map(r=>s?Cs(Ot(r)):Ot(r));e[Ie](e.multiple?i?new Set(o):o:o[0]),e._assigning=!0,Fi(()=>{e._assigning=!1})}),e[Ie]=pt(n)},mounted(e,{value:t}){di(e,t)},beforeUpdate(e,t,s){e[Ie]=pt(s)},updated(e,{value:t}){e._assigning||di(e,t)}};function di(e,t){const s=e.multiple,n=L(t);if(!(s&&!n&&!zt(t))){for(let i=0,o=e.options.length;iString(g)===String(a)):r.selected=fn(t,a)>-1}else r.selected=t.has(a);else if(ut(Ot(r),t)){e.selectedIndex!==i&&(e.selectedIndex=i);return}}!s&&e.selectedIndex!==-1&&(e.selectedIndex=-1)}}function Ot(e){return"_value"in e?e._value:e.value}function wo(e,t){const s=t?"_trueValue":"_falseValue";return s in e?e[s]:t}const qa={created(e,t,s){ds(e,t,s,null,"created")},mounted(e,t,s){ds(e,t,s,null,"mounted")},beforeUpdate(e,t,s,n){ds(e,t,s,n,"beforeUpdate")},updated(e,t,s,n){ds(e,t,s,n,"updated")}};function Za(e,t){switch(e){case"SELECT":return ks;case"TEXTAREA":return be;default:switch(t){case"checkbox":return Ka;case"radio":return Wa;default:return be}}}function ds(e,t,s,n,i){const r=Za(e.tagName,s.props&&s.props.type)[i];r&&r(e,t,s,n)}const Ja=["ctrl","shift","alt","meta"],Ya={stop:e=>e.stopPropagation(),prevent:e=>e.preventDefault(),self:e=>e.target!==e.currentTarget,ctrl:e=>!e.ctrlKey,shift:e=>!e.shiftKey,alt:e=>!e.altKey,meta:e=>!e.metaKey,left:e=>"button"in e&&e.button!==0,middle:e=>"button"in e&&e.button!==1,right:e=>"button"in e&&e.button!==2,exact:(e,t)=>Ja.some(s=>e[`${s}Key`]&&!t.includes(s))},Xa=(e,t)=>{if(!e)return e;const s=e._withMods||(e._withMods={}),n=t.join(".");return s[n]||(s[n]=((i,...o)=>{for(let r=0;r{const s=e._withKeys||(e._withKeys={}),n=t.join(".");return s[n]||(s[n]=(i=>{if(!("key"in i))return;const o=ft(i.key);if(t.some(r=>r===o||Qa[r]===o))return e(i)}))},el=_e({patchProp:Ba},Sa);let pi;function tl(){return pi||(pi=ia(el))}const sl=((...e)=>{const t=tl().createApp(...e),{mount:s}=t;return t.mount=n=>{const i=il(n);if(!i)return;const o=t._component;!W(o)&&!o.render&&!o.template&&(o.template=i.innerHTML),i.nodeType===1&&(i.textContent="");const r=s(i,!1,nl(i));return i instanceof Element&&(i.removeAttribute("v-cloak"),i.setAttribute("data-v-app","")),r},t});function nl(e){if(e instanceof SVGElement)return"svg";if(typeof MathMLElement=="function"&&e instanceof MathMLElement)return"mathml"}function il(e){return ue(e)?document.querySelector(e):e}const ko="dh-panel-theme";function ol(){var e;try{const t=localStorage.getItem(ko);if(t==="dark"||t==="light")return t}catch{}return(e=window.matchMedia)!=null&&e.call(window,"(prefers-color-scheme: dark)").matches?"dark":"light"}const Ct=H(ol());function To(e){Ct.value=e,document.documentElement.classList.toggle("dark",e==="dark");try{localStorage.setItem(ko,e)}catch{}}function fi(){To(Ct.value==="dark"?"light":"dark")}To(Ct.value);const rl={apiServer:"API server",switchToLight:"Switch to light theme",switchToDark:"Switch to dark theme",theme:"Theme",signOut:"Sign out",loading:"Loading…",standardUserNote:"Signed in as a standard user — management sections need an admin role",footer:"DriverVault — car maintenance & service tracker."},al={overview:"Overview",users:"Users",orgs:"Organizations",server:"API Server",pocketbase:"PocketBase",webapp:"Web App",plugins:"Plugins",api:"API"},ll={title:"Sign in",subtitle:"Superadmin console for the DriverVault API Server.",email:"Email",password:"Password",submit:"Sign in",submitting:"Signing in…",invalid:"Invalid email or password.",failed:"Could not sign in.",authNote:"Authenticates against PocketBase through this server"},cl={title:"Status",unreachable:"unreachable",checking:"Checking…",apiServer:"API Server",pocketBase:"PocketBase",webApp:"Web App",thisProcess:"this process"},ul={create:"Create",save:"Save",cancel:"Cancel",edit:"Edit",delete:"Delete",rename:"Rename",empty:"—",name:"Name",email:"Email",role:"Role",organization:"Organization"},dl={title:"Users",allOrgs:"All organizations",yourOrg:"Your organization",newUser:"New user",password:"Password",passwordUnchanged:"Password (blank = unchanged)",passwordPlaceholder:"min 8 characters",orgNone:"— none —",you:"you",empty:"No users.",confirmDelete:"Delete {email}? This cannot be undone."},pl={title:"Organizations",subtitle:"Tenants users belong to",subtitleOwn:"Your organization",subtitleNone:"Create one to manage your own team",newOrg:"New organization",namePlaceholder:"Acme Fleet",empty:"No organizations yet.",createHint:"You have no organization yet. Create one to become its admin.",colId:"ID",confirmDelete:'Delete the organization "{name}"?',confirmDeleteOwn:'Delete your organization "{name}"? You will be removed from it and become a regular user.'},fl={title:"API Server",subtitle:"How this server identifies itself to the clients that connect to it",name:"Server name",nameHint:"Shown by clients that can be pointed at more than one DriverVault, such as the Web App's server switcher. Reported by /api/health.",saveApply:"Save & apply",persistedEnv:"persisted to .env",savedNotice:"Saved. The new name applies to the next request."},hl={title:"PocketBase",subtitle:"Database connection used by every endpoint",connected:"connected",noSuperuser:"no superuser",unreachable:"unreachable",baseUrl:"Base URL",superuserEmail:"Superuser email",superuserPassword:"Superuser password",passwordUnchanged:"unchanged",passwordNotSet:"not set",saveApply:"Save & apply",testConnection:"Test connection",persistedEnv:"persisted to .env",testOk:"Connection OK — superuser authenticated.",testReachableNoAuth:"PocketBase is reachable, but the service account did not authenticate.",testUnreachable:"PocketBase is not reachable at that address.",savedNotice:"Saved. The server is now using this PocketBase."},gl={title:"Web App",subtitle:"Address probed by the status check, and who may call this API from a browser",reachable:"reachable",unreachable:"unreachable",baseUrl:"Base URL",allowedOrigins:"Allowed origins",originsHint:"Comma separated, or {star} for any. Native mobile apps are not subject to CORS.",saveApply:"Save & apply",testConnection:"Test connection",persistedEnv:"persisted to .env",testOk:"Web App is reachable.",testFailed:"Web App did not answer its health check at that address.",savedNotice:"Saved. New origins apply to the next request."},ml={title:"Plugins",subtitle:"Third-party service integrations",categories:{vehicles:"Car manufacturers",chargers:"EV chargers",notifications:"Notifications","apis-external":"Other APIs","drives-external":"Remote drives","drives-local":"Local drives"},registerExternal:"Register external",cancelRegister:"Cancel",name:"Name",baseUrl:"Base URL",provider:"Provider",register:"Register",empty:"No plugins yet. Register an external one above, or compile a built-in connector.",builtin:"builtin",enabled:"enabled",disabled:"disabled",health:"Health",configure:"Configure",close:"Close",noConfig:"This plugin takes no configuration.",notSet:"Not set — let organizations and users choose",capabilities:"Capabilities",saved:"Saved.",checking:"Checking…",save:"Save",saveEnable:"Save & enable",disable:"Disable",remove:"Remove",builtinNote:"Built-in plugins can be disabled but not removed",confirmRemove:'Remove the external plugin "{name}"? Its saved config is deleted.'},bl={colEndpoint:"Endpoint",colDescription:"Description",authNone:"No auth",authBearer:"Bearer token",authManager:"Admin / superadmin",authSuperadmin:"Superadmin",authCharger:"Charger credentials",groupPublic:"Public",groupIdentity:"Identity",groupCars:"Cars",groupService:"Service records",groupTechnical:"Technical checks",groupParts:"Parts",groupFuel:"Fuel",groupCharging:"Charging",groupMaintenance:"Maintenance",groupDocuments:"Documents",groupReminders:"Reminders",groupAttachments:"Attachments",groupProviders:"Vehicle providers",groupIntegrations:"Integrations",groupOcpp:"OCPP",groupAccount:"Account",groupManagement:"Management",groupSuperadmin:"Superadmin"},vl={app:rl,sections:al,login:ll,status:cl,common:ul,users:dl,orgs:pl,server:fl,pocketbase:hl,webapp:gl,plugins:ml,api:bl},yl={apiServer:"Serwer API",switchToLight:"Przełącz na motyw jasny",switchToDark:"Przełącz na motyw ciemny",theme:"Motyw",signOut:"Wyloguj się",loading:"Ładowanie…",standardUserNote:"Zalogowano jako zwykły użytkownik — sekcje zarządzania wymagają roli administratora",footer:"DriverVault — rejestr serwisu i konserwacji samochodu."},_l={overview:"Przegląd",users:"Użytkownicy",orgs:"Organizacje",server:"Serwer API",pocketbase:"PocketBase",webapp:"Aplikacja webowa",plugins:"Wtyczki",api:"API"},wl={title:"Zaloguj się",subtitle:"Konsola superadministratora serwera API DriverVault.",email:"E-mail",password:"Hasło",submit:"Zaloguj się",submitting:"Logowanie…",invalid:"Nieprawidłowy e-mail lub hasło.",failed:"Nie udało się zalogować.",authNote:"Uwierzytelnia w PocketBase za pośrednictwem tego serwera"},xl={title:"Status",unreachable:"niedostępny",checking:"Sprawdzanie…",apiServer:"Serwer API",pocketBase:"PocketBase",webApp:"Aplikacja webowa",thisProcess:"ten proces"},kl={create:"Utwórz",save:"Zapisz",cancel:"Anuluj",edit:"Edytuj",delete:"Usuń",rename:"Zmień nazwę",empty:"—",name:"Nazwa",email:"E-mail",role:"Rola",organization:"Organizacja"},Tl={title:"Użytkownicy",allOrgs:"Wszystkie organizacje",yourOrg:"Twoja organizacja",newUser:"Nowy użytkownik",password:"Hasło",passwordUnchanged:"Hasło (puste = bez zmian)",passwordPlaceholder:"min. 8 znaków",orgNone:"— brak —",you:"Ty",empty:"Brak użytkowników.",confirmDelete:"Usunąć {email}? Tej operacji nie można cofnąć."},Sl={title:"Organizacje",subtitle:"Podmioty, do których należą użytkownicy",subtitleOwn:"Twoja organizacja",subtitleNone:"Utwórz ją, aby zarządzać własnym zespołem",newOrg:"Nowa organizacja",namePlaceholder:"Acme Fleet",empty:"Brak organizacji.",createHint:"Nie masz jeszcze organizacji. Utwórz ją, aby zostać jej administratorem.",colId:"ID",confirmDelete:"Usunąć organizację „{name}”?",confirmDeleteOwn:"Usunąć Twoją organizację „{name}”? Zostaniesz z niej usunięty i staniesz się zwykłym użytkownikiem."},El={title:"Serwer API",subtitle:"Jak ten serwer przedstawia się klientom, które się z nim łączą",name:"Nazwa serwera",nameHint:"Widoczna w klientach, które można skierować na więcej niż jeden DriverVault, na przykład w przełączniku serwerów aplikacji webowej. Zwracana przez /api/health.",saveApply:"Zapisz i zastosuj",persistedEnv:"zapisano w .env",savedNotice:"Zapisano. Nowa nazwa obowiązuje od następnego żądania."},Pl={title:"PocketBase",subtitle:"Połączenie z bazą danych używane przez każdy punkt końcowy",connected:"połączono",noSuperuser:"brak superużytkownika",unreachable:"niedostępny",baseUrl:"Adres bazowy",superuserEmail:"E-mail superużytkownika",superuserPassword:"Hasło superużytkownika",passwordUnchanged:"bez zmian",passwordNotSet:"nie ustawiono",saveApply:"Zapisz i zastosuj",testConnection:"Testuj połączenie",persistedEnv:"zapisano w .env",testOk:"Połączenie OK — superużytkownik uwierzytelniony.",testReachableNoAuth:"PocketBase jest dostępny, ale konto usługowe nie zostało uwierzytelnione.",testUnreachable:"PocketBase jest niedostępny pod tym adresem.",savedNotice:"Zapisano. Serwer korzysta teraz z tego PocketBase."},Cl={title:"Aplikacja webowa",subtitle:"Adres sprawdzany podczas kontroli statusu oraz kto może wywoływać to API z przeglądarki",reachable:"dostępna",unreachable:"niedostępna",baseUrl:"Adres bazowy",allowedOrigins:"Dozwolone źródła",originsHint:"Oddzielone przecinkami lub {star} dla dowolnego. Natywne aplikacje mobilne nie podlegają CORS.",saveApply:"Zapisz i zastosuj",testConnection:"Testuj połączenie",persistedEnv:"zapisano w .env",testOk:"Aplikacja webowa jest dostępna.",testFailed:"Aplikacja webowa nie odpowiedziała na kontrolę stanu pod tym adresem.",savedNotice:"Zapisano. Nowe źródła obowiązują od następnego żądania."},Al={title:"Wtyczki",subtitle:"Integracje z usługami zewnętrznymi",categories:{vehicles:"Producenci samochodów",chargers:"Ładowarki EV",notifications:"Powiadomienia","apis-external":"Pozostałe API","drives-external":"Dyski zdalne","drives-local":"Dyski lokalne"},registerExternal:"Zarejestruj zewnętrzną",cancelRegister:"Anuluj",name:"Nazwa",baseUrl:"Adres bazowy",provider:"Dostawca",register:"Zarejestruj",empty:"Brak wtyczek. Zarejestruj zewnętrzną powyżej lub skompiluj wbudowany łącznik.",builtin:"wbudowana",enabled:"włączona",disabled:"wyłączona",health:"Stan",configure:"Konfiguruj",close:"Zamknij",noConfig:"Ta wtyczka nie wymaga konfiguracji.",notSet:"Nie ustawiono — pozwól organizacjom i użytkownikom wybrać",capabilities:"Możliwości",saved:"Zapisano.",checking:"Sprawdzanie…",save:"Zapisz",saveEnable:"Zapisz i włącz",disable:"Wyłącz",remove:"Usuń",builtinNote:"Wtyczki wbudowane można wyłączyć, ale nie usunąć",confirmRemove:"Usunąć zewnętrzną wtyczkę „{name}”? Jej zapisana konfiguracja zostanie usunięta."},$l={colEndpoint:"Punkt końcowy",colDescription:"Opis",authNone:"Bez uwierzytelniania",authBearer:"Token Bearer",authManager:"Administrator / superadministrator",authSuperadmin:"Superadministrator",authCharger:"Dane logowania ładowarki",groupPublic:"Publiczne",groupIdentity:"Tożsamość",groupCars:"Samochody",groupService:"Wpisy serwisowe",groupTechnical:"Przeglądy techniczne",groupParts:"Części",groupFuel:"Paliwo",groupCharging:"Ładowanie",groupMaintenance:"Naprawy",groupDocuments:"Dokumenty",groupReminders:"Przypomnienia",groupAttachments:"Załączniki",groupProviders:"Dostawcy pojazdów",groupIntegrations:"Integracje",groupOcpp:"OCPP",groupAccount:"Konto",groupManagement:"Zarządzanie",groupSuperadmin:"Superadministrator"},Ol={app:yl,sections:_l,login:wl,status:xl,common:kl,users:Tl,orgs:Sl,server:El,pocketbase:Pl,webapp:Cl,plugins:Al,api:$l},Dl={apiServer:"API-server",switchToLight:"Skift til lyst tema",switchToDark:"Skift til mørkt tema",theme:"Tema",signOut:"Log ud",loading:"Indlæser…",standardUserNote:"Logget ind som almindelig bruger — administrationssektioner kræver en administratorrolle",footer:"DriverVault — bilservice- og vedligeholdelsesregister."},Rl={overview:"Oversigt",users:"Brugere",orgs:"Organisationer",server:"API-server",pocketbase:"PocketBase",webapp:"Webapp",plugins:"Plugins",api:"API"},zl={title:"Log ind",subtitle:"Superadmin-konsol til DriverVault API-serveren.",email:"E-mail",password:"Adgangskode",submit:"Log ind",submitting:"Logger ind…",invalid:"Ugyldig e-mail eller adgangskode.",failed:"Kunne ikke logge ind.",authNote:"Godkender mod PocketBase gennem denne server"},Il={title:"Status",unreachable:"utilgængelig",checking:"Tjekker…",apiServer:"API-server",pocketBase:"PocketBase",webApp:"Webapp",thisProcess:"denne proces"},jl={create:"Opret",save:"Gem",cancel:"Annuller",edit:"Rediger",delete:"Slet",rename:"Omdøb",empty:"—",name:"Navn",email:"E-mail",role:"Rolle",organization:"Organisation"},Ul={title:"Brugere",allOrgs:"Alle organisationer",yourOrg:"Din organisation",newUser:"Ny bruger",password:"Adgangskode",passwordUnchanged:"Adgangskode (tom = uændret)",passwordPlaceholder:"mindst 8 tegn",orgNone:"— ingen —",you:"dig",empty:"Ingen brugere.",confirmDelete:"Slet {email}? Dette kan ikke fortrydes."},Nl={title:"Organisationer",subtitle:"Enheder, som brugere tilhører",subtitleOwn:"Din organisation",subtitleNone:"Opret en for at administrere dit eget team",newOrg:"Ny organisation",namePlaceholder:"Acme Fleet",empty:"Ingen organisationer endnu.",createHint:"Du har endnu ingen organisation. Opret en for at blive dens administrator.",colId:"ID",confirmDelete:'Slet organisationen "{name}"?',confirmDeleteOwn:"Slet din organisation „{name}“? Du fjernes fra den og bliver en almindelig bruger."},Ml={title:"API-server",subtitle:"Hvordan denne server identificerer sig over for de klienter, der forbinder til den",name:"Servernavn",nameHint:"Vises af klienter, der kan pege på mere end én DriverVault, for eksempel webappens serverskifter. Returneres af /api/health.",saveApply:"Gem og anvend",persistedEnv:"gemt i .env",savedNotice:"Gemt. Det nye navn gælder fra næste anmodning."},Ll={title:"PocketBase",subtitle:"Databaseforbindelse brugt af hvert endpoint",connected:"forbundet",noSuperuser:"ingen superbruger",unreachable:"utilgængelig",baseUrl:"Basis-URL",superuserEmail:"Superbrugerens e-mail",superuserPassword:"Superbrugerens adgangskode",passwordUnchanged:"uændret",passwordNotSet:"ikke angivet",saveApply:"Gem og anvend",testConnection:"Test forbindelse",persistedEnv:"gemt i .env",testOk:"Forbindelse OK — superbruger godkendt.",testReachableNoAuth:"PocketBase er tilgængelig, men servicekontoen blev ikke godkendt.",testUnreachable:"PocketBase er ikke tilgængelig på den adresse.",savedNotice:"Gemt. Serveren bruger nu denne PocketBase."},Fl={title:"Webapp",subtitle:"Adressen, der tjekkes ved statuskontrol, og hvem der må kalde dette API fra en browser",reachable:"tilgængelig",unreachable:"utilgængelig",baseUrl:"Basis-URL",allowedOrigins:"Tilladte oprindelser",originsHint:"Kommasepareret, eller {star} for enhver. Native mobilapps er ikke underlagt CORS.",saveApply:"Gem og anvend",testConnection:"Test forbindelse",persistedEnv:"gemt i .env",testOk:"Webappen er tilgængelig.",testFailed:"Webappen svarede ikke på sit helbredstjek på den adresse.",savedNotice:"Gemt. Nye oprindelser gælder fra næste anmodning."},Bl={title:"Plugins",subtitle:"Integrationer med tredjepartstjenester",categories:{vehicles:"Bilproducenter",chargers:"EV-ladere",notifications:"Notifikationer","apis-external":"Øvrige API'er","drives-external":"Eksterne drev","drives-local":"Lokale drev"},registerExternal:"Registrér ekstern",cancelRegister:"Annuller",name:"Navn",baseUrl:"Basis-URL",provider:"Udbyder",register:"Registrér",empty:"Ingen plugins endnu. Registrér et eksternt ovenfor, eller kompilér et indbygget stik.",builtin:"indbygget",enabled:"aktiveret",disabled:"deaktiveret",health:"Helbred",configure:"Konfigurer",close:"Luk",noConfig:"Dette plugin kræver ingen konfiguration.",notSet:"Ikke angivet — lad organisationer og brugere vælge",capabilities:"Funktioner",saved:"Gemt.",checking:"Tjekker…",save:"Gem",saveEnable:"Gem og aktivér",disable:"Deaktiver",remove:"Fjern",builtinNote:"Indbyggede plugins kan deaktiveres, men ikke fjernes",confirmRemove:'Fjern det eksterne plugin "{name}"? Dets gemte konfiguration slettes.'},Hl={colEndpoint:"Endpoint",colDescription:"Beskrivelse",authNone:"Ingen godkendelse",authBearer:"Bearer-token",authManager:"Admin / superadmin",authSuperadmin:"Superadmin",authCharger:"Laderens loginoplysninger",groupPublic:"Offentlig",groupIdentity:"Identitet",groupCars:"Biler",groupService:"Serviceposter",groupTechnical:"Syn",groupParts:"Reservedele",groupFuel:"Brændstof",groupCharging:"Opladning",groupMaintenance:"Værksted",groupDocuments:"Dokumenter",groupReminders:"Påmindelser",groupAttachments:"Vedhæftede filer",groupProviders:"Køretøjsudbydere",groupIntegrations:"Integrationer",groupOcpp:"OCPP",groupAccount:"Konto",groupManagement:"Administration",groupSuperadmin:"Superadmin"},Vl={app:Dl,sections:Rl,login:zl,status:Il,common:jl,users:Ul,orgs:Nl,server:Ml,pocketbase:Ll,webapp:Fl,plugins:Bl,api:Hl},So="dh-panel-lang",Eo="en",Dt={en:vl,pl:Ol,da:Vl},Gl=Object.keys(Dt);function Kl(){try{const t=localStorage.getItem(So);if(t&&Dt[t])return t}catch{}const e=(navigator.language||"en").split("-")[0];return Dt[e]?e:Eo}const En=H(Kl());function Wl(e){if(Dt[e]){En.value=e;try{localStorage.setItem(So,e)}catch{}}}function hi(e,t){return t.split(".").reduce((s,n)=>s==null?void 0:s[n],e)}function ql(e,t){return t?e.replace(/\{(\w+)\}/g,(s,n)=>t[n]==null?s:String(t[n])):e}function Zl(e,t,s){let n="other";try{n=new Intl.PluralRules(s).select(t)}catch{n=t===1?"one":"other"}return e[n]??e.other??e.one}function f(e,t){const s=En.value;let n=hi(Dt[s],e);if(n==null&&(n=hi(Dt[Eo],e)),n==null)return e;if(typeof n=="object"){if((t==null?void 0:t.n)==null)return e;n=Zl(n,t.n,s)}return typeof n!="string"?e:ql(n,t)}function gi(e,t,s){const i=f(e,{...s,[t]:"\0"}),o=i.indexOf("\0");return o===-1?{before:i,after:""}:{before:i.slice(0,o),after:i.slice(o+1)}}const ln="dh-panel-token";function Jl(){try{return localStorage.getItem(ln)||""}catch{return""}}const Rt=H(Jl()),he=H(null),De=Oe(()=>{var e;return((e=he.value)==null?void 0:e.role)==="superadmin"}),gs=Oe(()=>{var e,t;return((e=he.value)==null?void 0:e.role)==="admin"||((t=he.value)==null?void 0:t.role)==="superadmin"});function Po(e){Rt.value=e;try{e?localStorage.setItem(ln,e):localStorage.removeItem(ln)}catch{}}class Yl extends Error{constructor(t,s,n){super(t),this.status=s,this.body=n}}function Xl(e,t){if(!e||typeof e!="object")return`HTTP ${t}`;if(e.error)return e.error;const s=Object.entries(e.data||{}).map(([n,i])=>`${n}: ${(i==null?void 0:i.message)||i}`).filter(Boolean);return s.length?s.join("; "):e.message||`HTTP ${t}`}async function ae(e,{method:t="GET",body:s,auth:n=!0}={}){const i={};s!==void 0&&(i["Content-Type"]="application/json"),n&&Rt.value&&(i.Authorization=Rt.value);const o=await fetch(e,{method:t,headers:i,body:s===void 0?void 0:JSON.stringify(s)}),r=await o.text();let a=null;try{a=r?JSON.parse(r):null}catch{a=null}if(!o.ok)throw o.status===401&&n&&Pn(),new Yl(Xl(a,o.status),o.status,a);return a}async function Ql(e,t){const s=await ae("/api/auth/login",{method:"POST",body:{email:e,password:t},auth:!1});return Po(s.token),await Ts(),he.value}async function Ts(){return he.value=await ae("/api/identity"),he.value}function Pn(){Po(""),he.value=null}async function ec(){if(!Rt.value)return null;try{return await Ts()}catch{return Pn(),null}}const tc={class:"inline-flex items-center gap-2.5 select-none"},sc={class:"h-full w-auto shrink-0",viewBox:"0 0 48 48",fill:"none","aria-hidden":"true"},nc={transform:"translate(7 0) skewX(-13)"},ic=["fill"],oc=["fill"],rc=["fill"],ac={key:0,class:"text-[1.35em] font-extrabold italic leading-none tracking-[-0.03em]"},lc={__name:"Logo",props:{iconOnly:{type:Boolean,default:!1},onDark:{type:Boolean,default:!1}},setup(e){return(t,s)=>(y(),T("span",tc,[(y(),T("svg",sc,[u("g",nc,[u("rect",{x:"9",y:"16",width:"6",height:"16",rx:"3",fill:e.onDark?"#60A5FA":"var(--brand-700)"},null,8,ic),u("rect",{x:"19",y:"12",width:"6",height:"24",rx:"3",fill:e.onDark?"#93C5FD":"var(--brand-500)"},null,8,oc),u("rect",{x:"29",y:"8",width:"6",height:"32",rx:"3",fill:e.onDark?"#ffffff":"var(--brand-400)"},null,8,rc)])])),e.iconOnly?F("",!0):(y(),T("span",ac,[u("span",{class:Ee(e.onDark?"text-white":"text-strong")},"Driver",2),u("span",{class:Ee(e.onDark?"text-brand-400":"text-brandtext")},"Vault",2)])),s[0]||(s[0]=u("span",{class:"sr-only"},"DriverVault",-1))]))}},cc={class:"mx-auto flex w-full max-w-sm flex-col gap-5 pt-24"},uc={class:"dh-card p-6"},dc={class:"text-lg font-bold tracking-[-0.02em] text-strong"},pc={class:"mt-1 mb-5 text-sm text-body"},fc={class:"dh-label",for:"login-email"},hc={class:"dh-label",for:"login-password"},gc={key:0,class:"rounded-control bg-danger-soft px-3 py-2 text-xs text-danger"},mc=["disabled"],bc={class:"eyebrow text-center"},vc={__name:"LoginView",emits:["authenticated"],setup(e,{emit:t}){const s=t,n=H(""),i=H(""),o=H(""),r=H(!1),a=Oe(()=>n.value.trim()!==""&&i.value!==""&&!r.value);async function l(){if(a.value){o.value="",r.value=!0;try{const g=await Ql(n.value.trim(),i.value);s("authenticated",g)}catch(g){o.value=g.status===400||g.status===404?f("login.invalid"):g.message||f("login.failed"),i.value=""}finally{r.value=!1}}}return(g,d)=>(y(),T("div",cc,[u("div",uc,[u("h1",dc,m(h(f)("login.title")),1),u("p",pc,m(h(f)("login.subtitle")),1),u("form",{class:"flex flex-col gap-4",onSubmit:Xa(l,["prevent"])},[u("div",null,[u("label",fc,m(h(f)("login.email")),1),pe(u("input",{id:"login-email","onUpdate:modelValue":d[0]||(d[0]=b=>n.value=b),class:"dh-input",type:"email",autocomplete:"username",autofocus:"",placeholder:"you@example.com"},null,512),[[be,n.value]])]),u("div",null,[u("label",hc,m(h(f)("login.password")),1),pe(u("input",{id:"login-password","onUpdate:modelValue":d[1]||(d[1]=b=>i.value=b),class:"dh-input",type:"password",autocomplete:"current-password",placeholder:"••••••••"},null,512),[[be,i.value]])]),o.value?(y(),T("p",gc,m(o.value),1)):F("",!0),u("button",{class:"dh-btn w-full",type:"submit",disabled:!a.value},m(r.value?h(f)("login.submitting"):h(f)("login.submit")),9,mc)],32)]),u("p",bc,m(h(f)("login.authNote")),1)]))}},yc={class:"dh-card overflow-hidden"},_c={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},wc={class:"text-base font-bold tracking-[-0.02em] text-strong"},xc={key:0,class:"dh-pill bg-danger-soft text-danger"},kc={key:0,class:"px-5 py-4 text-sm text-danger"},Tc={key:1,class:"w-full text-left text-sm"},Sc={class:"px-5 py-3 font-medium text-strong"},Ec={class:"data px-5 py-3 text-xs text-muted"},Pc={class:"data px-5 py-3 text-right text-xs text-muted"},Cc={class:"px-5 py-3 text-right"},Ac={key:2,class:"px-5 py-4 text-sm text-muted"},$c={__name:"StatusCard",setup(e){const t=H(null),s=H("");let n=null;async function i(){try{t.value=await ae("/api/status",{auth:!1}),s.value=""}catch(a){t.value=null,s.value=a.message||f("status.unreachable")}}const o=Oe(()=>{var a,l,g;return[{key:"apiServer",label:f("status.apiServer"),h:(a=t.value)==null?void 0:a.apiServer},{key:"pocketBase",label:f("status.pocketBase"),h:(l=t.value)==null?void 0:l.pocketBase},{key:"webApp",label:f("status.webApp"),h:(g=t.value)==null?void 0:g.webApp}]});lt(()=>{i(),n=setInterval(i,1e4)}),kn(()=>clearInterval(n));const r=a=>a==="ok"?"bg-success-soft text-success":"bg-danger-soft text-danger";return(a,l)=>(y(),T("div",yc,[u("div",_c,[u("div",wc,m(h(f)("status.title")),1),s.value?(y(),T("span",xc,[l[0]||(l[0]=u("span",{class:"h-1.5 w-1.5 rounded-full bg-current"},null,-1)),$e(m(h(f)("status.unreachable")),1)])):F("",!0)]),s.value?(y(),T("div",kc,m(s.value),1)):t.value?(y(),T("table",Tc,[u("tbody",null,[(y(!0),T(re,null,Ce(o.value,g=>(y(),T("tr",{key:g.key,class:"border-t border-subtle first:border-t-0"},[u("td",Sc,m(g.label),1),u("td",Ec,m(g.h.url||h(f)("status.thisProcess")),1),u("td",Pc,m(g.h.latencyMs!=null?g.h.latencyMs+"ms":h(f)("common.empty")),1),u("td",Cc,[u("span",{class:Ee(["dh-pill",r(g.h.status)])},[l[1]||(l[1]=u("span",{class:"h-1.5 w-1.5 rounded-full bg-current"},null,-1)),$e(m(g.h.status),1)],2)])]))),128))])])):(y(),T("div",Ac,m(h(f)("status.checking")),1))]))}},Oc={class:"dh-card overflow-hidden"},Dc={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},Rc={class:"text-base font-bold tracking-[-0.02em] text-strong"},zc={class:"mt-0.5 text-xs text-muted"},Ic={class:"flex flex-col gap-4 px-5 py-4"},jc={class:"dh-label",for:"pb-url"},Uc={class:"grid gap-4 sm:grid-cols-2"},Nc={class:"dh-label",for:"pb-email"},Mc={class:"dh-label",for:"pb-password"},Lc=["placeholder"],Fc={key:0,class:"data text-xs text-muted"},Bc={key:1,class:"rounded-control bg-info-soft px-3 py-2 text-xs text-info"},Hc={key:2,class:"rounded-control bg-danger-soft px-3 py-2 text-xs text-danger"},Vc={class:"flex items-center gap-2"},Gc=["disabled"],Kc=["disabled"],Wc={class:"eyebrow"},qc={__name:"PocketBaseCard",setup(e){const t=H(null),s=H({url:"",adminEmail:"",adminPassword:""}),n=H(null),i=H(""),o=H(""),r=H(!1);async function a(){try{t.value=await ae("/api/admin/pb-config"),s.value={url:t.value.url,adminEmail:t.value.adminEmail,adminPassword:""},n.value=t.value.probe}catch(d){i.value=d.message}}lt(a);async function l(){i.value="",o.value="",r.value=!0;try{n.value=await ae("/api/admin/pb-config/test",{method:"POST",body:s.value}),o.value=n.value.superuser?f("pocketbase.testOk"):n.value.reachable?f("pocketbase.testReachableNoAuth"):f("pocketbase.testUnreachable")}catch(d){i.value=d.message}finally{r.value=!1}}async function g(){i.value="",o.value="",r.value=!0;try{const d=await ae("/api/admin/pb-config",{method:"PUT",body:s.value});t.value=d.config,n.value=d.config.probe,s.value.adminPassword="",o.value=d.warning||f("pocketbase.savedNotice")}catch(d){i.value=d.message}finally{r.value=!1}}return(d,b)=>{var E,A;return y(),T("div",Oc,[u("div",Dc,[u("div",null,[u("div",Rc,m(h(f)("pocketbase.title")),1),u("p",zc,m(h(f)("pocketbase.subtitle")),1)]),n.value?(y(),T("span",{key:0,class:Ee(["dh-pill",n.value.superuser?"bg-success-soft text-success":n.value.reachable?"bg-warning-soft text-warning":"bg-danger-soft text-danger"])},[b[3]||(b[3]=u("span",{class:"h-1.5 w-1.5 rounded-full bg-current"},null,-1)),$e(" "+m(n.value.superuser?h(f)("pocketbase.connected"):n.value.reachable?h(f)("pocketbase.noSuperuser"):h(f)("pocketbase.unreachable")),1)],2)):F("",!0)]),u("div",Ic,[u("div",null,[u("label",jc,m(h(f)("pocketbase.baseUrl")),1),pe(u("input",{id:"pb-url","onUpdate:modelValue":b[0]||(b[0]=V=>s.value.url=V),class:"dh-input",placeholder:"http://10.2.1.10:8027"},null,512),[[be,s.value.url]])]),u("div",Uc,[u("div",null,[u("label",Nc,m(h(f)("pocketbase.superuserEmail")),1),pe(u("input",{id:"pb-email","onUpdate:modelValue":b[1]||(b[1]=V=>s.value.adminEmail=V),class:"dh-input",autocomplete:"off"},null,512),[[be,s.value.adminEmail]])]),u("div",null,[u("label",Mc,m(h(f)("pocketbase.superuserPassword")),1),pe(u("input",{id:"pb-password","onUpdate:modelValue":b[2]||(b[2]=V=>s.value.adminPassword=V),class:"dh-input",type:"password",autocomplete:"new-password",placeholder:(E=t.value)!=null&&E.adminConfigured?h(f)("pocketbase.passwordUnchanged"):h(f)("pocketbase.passwordNotSet")},null,8,Lc),[[be,s.value.adminPassword]])])]),(A=n.value)!=null&&A.detail?(y(),T("p",Fc,m(n.value.detail),1)):F("",!0),o.value?(y(),T("p",Bc,m(o.value),1)):F("",!0),i.value?(y(),T("p",Hc,m(i.value),1)):F("",!0),u("div",Vc,[u("button",{class:"dh-btn",disabled:r.value,onClick:g},m(h(f)("pocketbase.saveApply")),9,Gc),u("button",{class:"dh-btn-ghost",disabled:r.value,onClick:l},m(h(f)("pocketbase.testConnection")),9,Kc),b[4]||(b[4]=u("span",{class:"flex-1"},null,-1)),u("span",Wc,m(h(f)("pocketbase.persistedEnv")),1)])])])}}},Zc={class:"dh-card overflow-hidden"},Jc={class:"border-b border-subtle px-5 py-4"},Yc={class:"text-base font-bold tracking-[-0.02em] text-strong"},Xc={class:"mt-0.5 text-xs text-muted"},Qc={class:"flex flex-col gap-4 px-5 py-4"},eu={class:"dh-label",for:"server-name"},tu={class:"mt-1 text-xs text-muted"},su={key:0,class:"rounded-control bg-info-soft px-3 py-2 text-xs text-info"},nu={key:1,class:"rounded-control bg-danger-soft px-3 py-2 text-xs text-danger"},iu={class:"flex items-center gap-2"},ou=["disabled"],ru={class:"eyebrow"},au={__name:"ServerCard",setup(e){const t=H({name:""}),s=H(""),n=H(""),i=H(!1);async function o(){try{const a=await ae("/api/admin/server-config");t.value={name:a.name}}catch(a){s.value=a.message}}lt(o);async function r(){s.value="",n.value="",i.value=!0;try{const a=await ae("/api/admin/server-config",{method:"PUT",body:{name:t.value.name}});t.value={name:a.config.name},n.value=a.warning||f("server.savedNotice")}catch(a){s.value=a.message}finally{i.value=!1}}return(a,l)=>(y(),T("div",Zc,[u("div",Jc,[u("div",Yc,m(h(f)("server.title")),1),u("p",Xc,m(h(f)("server.subtitle")),1)]),u("div",Qc,[u("div",null,[u("label",eu,m(h(f)("server.name")),1),pe(u("input",{id:"server-name","onUpdate:modelValue":l[0]||(l[0]=g=>t.value.name=g),class:"dh-input",maxlength:"64",placeholder:"DriverVault API Server",onKeyup:xo(r,["enter"])},null,544),[[be,t.value.name]]),u("p",tu,m(h(f)("server.nameHint")),1)]),n.value?(y(),T("p",su,m(n.value),1)):F("",!0),s.value?(y(),T("p",nu,m(s.value),1)):F("",!0),u("div",iu,[u("button",{class:"dh-btn",disabled:i.value,onClick:r},m(h(f)("server.saveApply")),9,ou),l[1]||(l[1]=u("span",{class:"flex-1"},null,-1)),u("span",ru,m(h(f)("server.persistedEnv")),1)])])]))}},lu={class:"dh-card overflow-hidden"},cu={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},uu={class:"text-base font-bold tracking-[-0.02em] text-strong"},du={class:"mt-0.5 text-xs text-muted"},pu={class:"flex flex-col gap-4 px-5 py-4"},fu={class:"dh-label",for:"web-url"},hu={class:"dh-label",for:"web-origins"},gu={class:"mt-1 text-xs text-muted"},mu={key:0,class:"data text-xs text-muted"},bu={key:1,class:"rounded-control bg-info-soft px-3 py-2 text-xs text-info"},vu={key:2,class:"rounded-control bg-danger-soft px-3 py-2 text-xs text-danger"},yu={class:"flex items-center gap-2"},_u=["disabled"],wu=["disabled"],xu={class:"eyebrow"},ku={__name:"WebAppCard",setup(e){const t=H(null),s=H({url:"",origins:""}),n=H(null),i=H(""),o=H(""),r=H(!1),a=E=>E.split(",").map(A=>A.trim()).filter(Boolean);function l(E){t.value=E,s.value={url:E.url,origins:(E.allowOrigins||[]).join(", ")},n.value=E.probe}async function g(){try{l(await ae("/api/admin/webapp-config"))}catch(E){i.value=E.message}}lt(g);async function d(){i.value="",o.value="",r.value=!0;try{n.value=await ae("/api/admin/webapp-config/test",{method:"POST",body:{url:s.value.url}}),o.value=n.value.status==="ok"?f("webapp.testOk"):f("webapp.testFailed")}catch(E){i.value=E.message}finally{r.value=!1}}async function b(){i.value="",o.value="",r.value=!0;try{const E=await ae("/api/admin/webapp-config",{method:"PUT",body:{url:s.value.url,allowOrigins:a(s.value.origins)}});l(E.config),o.value=E.warning||f("webapp.savedNotice")}catch(E){i.value=E.message}finally{r.value=!1}}return(E,A)=>{var V;return y(),T("div",lu,[u("div",cu,[u("div",null,[u("div",uu,m(h(f)("webapp.title")),1),u("p",du,m(h(f)("webapp.subtitle")),1)]),n.value?(y(),T("span",{key:0,class:Ee(["dh-pill",n.value.status==="ok"?"bg-success-soft text-success":"bg-danger-soft text-danger"])},[A[2]||(A[2]=u("span",{class:"h-1.5 w-1.5 rounded-full bg-current"},null,-1)),$e(" "+m(n.value.status==="ok"?h(f)("webapp.reachable"):h(f)("webapp.unreachable")),1)],2)):F("",!0)]),u("div",pu,[u("div",null,[u("label",fu,m(h(f)("webapp.baseUrl")),1),pe(u("input",{id:"web-url","onUpdate:modelValue":A[0]||(A[0]=x=>s.value.url=x),class:"dh-input",placeholder:"http://localhost:8090"},null,512),[[be,s.value.url]])]),u("div",null,[u("label",hu,m(h(f)("webapp.allowedOrigins")),1),pe(u("input",{id:"web-origins","onUpdate:modelValue":A[1]||(A[1]=x=>s.value.origins=x),class:"dh-input",placeholder:"http://localhost:8090, https://app.example.com"},null,512),[[be,s.value.origins]]),u("p",gu,[$e(m(h(gi)("webapp.originsHint","star").before),1),A[3]||(A[3]=u("span",{class:"data"},"*",-1)),$e(m(h(gi)("webapp.originsHint","star").after),1)])]),(V=n.value)!=null&&V.error?(y(),T("p",mu,m(n.value.error),1)):F("",!0),o.value?(y(),T("p",bu,m(o.value),1)):F("",!0),i.value?(y(),T("p",vu,m(i.value),1)):F("",!0),u("div",yu,[u("button",{class:"dh-btn",disabled:r.value,onClick:b},m(h(f)("webapp.saveApply")),9,_u),u("button",{class:"dh-btn-ghost",disabled:r.value,onClick:d},m(h(f)("webapp.testConnection")),9,wu),A[4]||(A[4]=u("span",{class:"flex-1"},null,-1)),u("span",xu,m(h(f)("webapp.persistedEnv")),1)])])])}}},Tu={class:"dh-card overflow-hidden"},Su={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},Eu={class:"text-base font-bold tracking-[-0.02em] text-strong"},Pu={class:"mt-0.5 text-xs text-muted"},Cu={key:0,class:"border-b border-subtle bg-sunken px-5 py-4"},Au={class:"grid gap-3 sm:grid-cols-3"},$u={class:"dh-label"},Ou={class:"dh-label"},Du={class:"dh-label"},Ru=["disabled"],zu={key:1,class:"border-b border-subtle px-5 py-3 text-xs text-danger"},Iu={key:2,class:"px-5 py-6 text-center text-sm text-muted"},ju={key:3,class:"flex flex-wrap gap-1.5 border-b border-subtle px-5 py-3"},Uu=["onClick"],Nu={class:"dh-pill bg-sunken text-muted"},Mu={class:"flex items-center gap-3 px-5 py-3"},Lu=["onClick"],Fu={class:"font-semibold text-strong"},Bu={class:"dh-pill bg-sunken text-muted"},Hu={key:0,class:"text-xs text-muted"},Vu=["disabled","onClick"],Gu=["disabled","onClick"],Ku={key:0,class:"bg-sunken px-5 py-4"},Wu={key:0,class:"data mb-3 text-xs text-muted"},qu={key:1,class:"grid gap-3 sm:grid-cols-2"},Zu={class:"dh-label"},Ju={key:0,class:"text-danger"},Yu=["onUpdate:modelValue"],Xu={key:0,value:""},Qu=["value"],ed=["onUpdate:modelValue","type","placeholder"],td={key:2,class:"mt-1 text-xs text-muted"},sd={key:2,class:"text-xs text-muted"},nd={key:3,class:"mt-4"},id={class:"eyebrow mb-1.5"},od={class:"data flex flex-col gap-1 text-xs text-muted"},rd={class:"text-strong"},ad={key:0},ld={key:1},cd={key:4,class:"data mt-3 text-xs text-body"},ud={class:"mt-4 flex items-center gap-2"},dd=["disabled","onClick"],pd=["disabled","onClick"],fd=["disabled","onClick"],hd={key:5,class:"eyebrow mt-2"},gd={__name:"PluginsCard",setup(e){const t=H([]),s=H(""),n=H(!1),i=H(null),o=Yt({}),r=Yt({}),a=H(!1),l=H({name:"",baseURL:"",provider:""}),g=H(""),d=["vehicles","chargers","notifications","apis-external","drives-external","drives-local"],b=z=>d.includes(z.category)?z.category:"apis-external",E=Oe(()=>{var K;const z={};for(const P of t.value)(z[K=b(P)]||(z[K]=[])).push(P);return d.filter(P=>z[P]).map(P=>({id:P,label:f(`plugins.categories.${P}`),plugins:z[P]}))}),A=Oe(()=>E.value.find(z=>z.id===g.value)||E.value[0]),V=Oe(()=>{var z;return((z=A.value)==null?void 0:z.plugins)||[]});async function x(){try{const z=await ae("/api/admin/plugins");t.value=z.plugins||[],s.value=""}catch(z){s.value=z.message}}lt(x);function N(z){var P;if(i.value===z.name){i.value=null;return}const K={};for(const I of z.configFields||[])K[I.key]=((P=z.config)==null?void 0:P[I.key])??"";o[z.name]=K,i.value=z.name}async function R(z,K){n.value=!0,r[z.name]="";try{const P=await ae(`/api/admin/plugins/${encodeURIComponent(z.name)}`,{method:"PUT",body:{enabled:K,config:o[z.name]??{}}});r[z.name]=P.warning||f("plugins.saved"),await x()}catch(P){r[z.name]=P.message}finally{n.value=!1}}async function G(z){n.value=!0,r[z.name]=f("plugins.checking");try{const K=await ae(`/api/admin/plugins/${encodeURIComponent(z.name)}/health`,{method:"POST"});r[z.name]=`${K.health.status}${K.health.detail?" — "+K.health.detail:""}`,await x()}catch(K){r[z.name]=K.message}finally{n.value=!1}}async function Z(z){if(confirm(f("plugins.confirmRemove",{name:z.name}))){n.value=!0;try{await ae(`/api/admin/plugins/${encodeURIComponent(z.name)}`,{method:"DELETE"}),i.value===z.name&&(i.value=null),await x()}catch(K){r[z.name]=K.message}finally{n.value=!1}}}async function U(){n.value=!0,s.value="";try{await ae("/api/admin/plugins",{method:"POST",body:l.value}),l.value={name:"",baseURL:"",provider:""},a.value=!1,await x()}catch(z){s.value=z.message}finally{n.value=!1}}const le=z=>z==="ok"?"bg-success-soft text-success":z==="degraded"?"bg-warning-soft text-warning":"bg-danger-soft text-danger";return(z,K)=>(y(),T("div",Tu,[u("div",Su,[u("div",null,[u("div",Eu,m(h(f)("plugins.title")),1),u("p",Pu,m(h(f)("plugins.subtitle")),1)]),u("button",{class:"dh-btn-ghost",onClick:K[0]||(K[0]=P=>a.value=!a.value)},m(a.value?h(f)("plugins.cancelRegister"):h(f)("plugins.registerExternal")),1)]),a.value?(y(),T("div",Cu,[u("div",Au,[u("div",null,[u("label",$u,m(h(f)("plugins.name")),1),pe(u("input",{"onUpdate:modelValue":K[1]||(K[1]=P=>l.value.name=P),class:"dh-input",placeholder:"acme-parts"},null,512),[[be,l.value.name]])]),u("div",null,[u("label",Ou,m(h(f)("plugins.baseUrl")),1),pe(u("input",{"onUpdate:modelValue":K[2]||(K[2]=P=>l.value.baseURL=P),class:"dh-input",placeholder:"http://127.0.0.1:9100"},null,512),[[be,l.value.baseURL]])]),u("div",null,[u("label",Du,m(h(f)("plugins.provider")),1),pe(u("input",{"onUpdate:modelValue":K[3]||(K[3]=P=>l.value.provider=P),class:"dh-input",placeholder:"ACME Corp"},null,512),[[be,l.value.provider]])])]),u("button",{class:"dh-btn mt-3",disabled:n.value||!l.value.name||!l.value.baseURL,onClick:U},m(h(f)("plugins.register")),9,Ru)])):F("",!0),s.value?(y(),T("p",zu,m(s.value),1)):F("",!0),t.value.length?F("",!0):(y(),T("p",Iu,m(h(f)("plugins.empty")),1)),E.value.length>1?(y(),T("nav",ju,[(y(!0),T(re,null,Ce(E.value,P=>{var I;return y(),T("button",{key:P.id,class:Ee(["dh-btn-ghost",((I=A.value)==null?void 0:I.id)===P.id?"border-accent text-brandtext":""]),onClick:J=>g.value=P.id},[$e(m(P.label)+" ",1),u("span",Nu,m(P.plugins.length),1)],10,Uu)}),128))])):F("",!0),(y(!0),T(re,null,Ce(V.value,P=>(y(),T("div",{key:P.name,class:"border-t border-subtle first:border-t-0"},[u("div",Mu,[u("button",{class:"flex flex-1 items-center gap-3 text-left",onClick:I=>N(P)},[u("span",Fu,m(P.name),1),u("span",Bu,m(P.kind||h(f)("plugins.builtin")),1),P.provider?(y(),T("span",Hu,m(P.provider),1)):F("",!0),P.health?(y(),T("span",{key:1,class:Ee(["dh-pill",le(P.health.status)])},[K[4]||(K[4]=u("span",{class:"h-1.5 w-1.5 rounded-full bg-current"},null,-1)),$e(m(P.health.status),1)],2)):F("",!0)],8,Lu),u("span",{class:Ee(["dh-pill",P.enabled?"bg-success-soft text-success":"bg-sunken text-muted"])},m(P.enabled?h(f)("plugins.enabled"):h(f)("plugins.disabled")),3),u("button",{class:"dh-btn-ghost",disabled:n.value,onClick:I=>G(P)},m(h(f)("plugins.health")),9,Vu),u("button",{class:"dh-btn-ghost",disabled:n.value,onClick:I=>N(P)},m(i.value===P.name?h(f)("plugins.close"):h(f)("plugins.configure")),9,Gu)]),i.value===P.name?(y(),T("div",Ku,[P.baseURL?(y(),T("div",Wu,m(P.baseURL),1)):F("",!0),(P.configFields||[]).length?(y(),T("div",qu,[(y(!0),T(re,null,Ce(P.configFields,I=>(y(),T("div",{key:I.key},[u("label",Zu,[$e(m(I.label||I.key),1),I.required?(y(),T("span",Ju," *")):F("",!0)]),I.type==="select"?pe((y(),T("select",{key:0,"onUpdate:modelValue":J=>o[P.name][I.key]=J,class:"dh-select"},[I.required?F("",!0):(y(),T("option",Xu,m(h(f)("plugins.notSet")),1)),(y(!0),T(re,null,Ce(I.options||[],J=>(y(),T("option",{key:J.value,value:J.value},m(J.label||J.value),9,Qu))),128))],8,Yu)),[[ks,o[P.name][I.key]]]):pe((y(),T("input",{key:1,"onUpdate:modelValue":J=>o[P.name][I.key]=J,class:"dh-input",type:I.type==="password"?"password":I.type==="number"?"number":"text",placeholder:I.default||"",autocomplete:"off"},null,8,ed)),[[qa,o[P.name][I.key]]]),I.help?(y(),T("p",td,m(I.help),1)):F("",!0)]))),128))])):(y(),T("p",sd,m(h(f)("plugins.noConfig")),1)),(P.capabilities||[]).length?(y(),T("div",nd,[u("div",id,m(h(f)("plugins.capabilities")),1),u("ul",od,[(y(!0),T(re,null,Ce(P.capabilities,I=>(y(),T("li",{key:I.id},[u("span",rd,m(I.id),1),I.method||I.endpoint?(y(),T("span",ad," — "+m(I.method)+" "+m(I.endpoint),1)):F("",!0),I.description?(y(),T("span",ld," · "+m(I.description),1)):F("",!0)]))),128))])])):F("",!0),r[P.name]?(y(),T("p",cd,m(r[P.name]),1)):F("",!0),u("div",ud,[u("button",{class:"dh-btn",disabled:n.value,onClick:I=>R(P,!0)},m(P.enabled?h(f)("plugins.save"):h(f)("plugins.saveEnable")),9,dd),P.enabled?(y(),T("button",{key:0,class:"dh-btn-ghost",disabled:n.value,onClick:I=>R(P,!1)},m(h(f)("plugins.disable")),9,pd)):F("",!0),K[5]||(K[5]=u("span",{class:"flex-1"},null,-1)),P.kind==="external"?(y(),T("button",{key:1,class:"dh-btn-danger",disabled:n.value,onClick:I=>Z(P)},m(h(f)("plugins.remove")),9,fd)):F("",!0)]),P.kind!=="external"?(y(),T("p",hd,m(h(f)("plugins.builtinNote")),1)):F("",!0)])):F("",!0)]))),128))]))}},md={class:"dh-card overflow-hidden"},bd={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},vd={class:"text-base font-bold tracking-[-0.02em] text-strong"},yd={class:"mt-0.5 text-xs text-muted"},_d={key:0,class:"border-b border-subtle px-5 py-3 text-xs text-danger"},wd={key:1,class:"border-b border-subtle bg-sunken px-5 py-4"},xd={class:"grid gap-3 sm:grid-cols-2"},kd={class:"dh-label"},Td={class:"dh-label"},Sd={class:"dh-label"},Ed=["placeholder"],Pd={class:"dh-label"},Cd=["value"],Ad={key:0},$d={class:"dh-label"},Od={value:""},Dd=["value"],Rd={class:"mt-3 flex items-center gap-2"},zd=["disabled"],Id=["disabled"],jd={key:2,class:"px-5 py-6 text-center text-sm text-muted"},Ud={key:3,class:"w-full text-left text-sm"},Nd={class:"[&>th]:eyebrow [&>th]:px-5 [&>th]:py-2.5 [&>th]:font-medium"},Md={class:"data px-5 py-2.5 text-xs text-strong"},Ld={key:0,class:"eyebrow ml-1"},Fd={class:"px-5 py-2.5 text-body"},Bd={class:"px-5 py-2.5 text-body"},Hd={class:"px-5 py-2.5"},Vd={class:"px-5 py-2.5 text-right whitespace-nowrap"},Gd=["onClick"],Kd=["disabled","onClick"],Wd={__name:"UsersCard",setup(e){const t=H([]),s=H([]),n=H(""),i=H(!1),o=H(null),r=H({}),a=Oe(()=>De.value?["user","admin","superadmin"]:["user","admin"]);async function l(){try{const[x,N]=await Promise.all([ae("/api/users"),ae("/api/orgs")]);t.value=x.users||[],s.value=N.organizations||[],n.value=""}catch(x){n.value=x.message}}lt(l);function g(){var x;o.value="new",r.value={email:"",name:"",password:"",role:"user",organization:De.value?"":((x=he.value)==null?void 0:x.organization)||""}}function d(x){o.value=x.id,r.value={email:x.email,name:x.name||"",password:"",role:x.role,organization:x.organization||""}}function b(){o.value=null,n.value=""}async function E(){i.value=!0,n.value="";try{if(o.value==="new")await ae("/api/users",{method:"POST",body:r.value});else{const x={...r.value};x.password||delete x.password,await ae(`/api/users/${o.value}`,{method:"PATCH",body:x})}o.value=null,await l()}catch(x){n.value=x.message}finally{i.value=!1}}async function A(x){if(confirm(f("users.confirmDelete",{email:x.email}))){i.value=!0,n.value="";try{await ae(`/api/users/${x.id}`,{method:"DELETE"}),await l()}catch(N){n.value=N.message}finally{i.value=!1}}}const V=x=>x==="superadmin"?"bg-info-soft text-info":x==="admin"?"bg-warning-soft text-warning":"bg-sunken text-muted";return(x,N)=>(y(),T("div",md,[u("div",bd,[u("div",null,[u("div",vd,m(h(f)("users.title")),1),u("p",yd,m(h(De)?h(f)("users.allOrgs"):h(f)("users.yourOrg")),1)]),u("button",{class:"dh-btn",onClick:g},m(h(f)("users.newUser")),1)]),n.value?(y(),T("p",_d,m(n.value),1)):F("",!0),o.value?(y(),T("div",wd,[u("div",xd,[u("div",null,[u("label",kd,m(h(f)("common.email")),1),pe(u("input",{"onUpdate:modelValue":N[0]||(N[0]=R=>r.value.email=R),class:"dh-input",type:"email",autocomplete:"off"},null,512),[[be,r.value.email]])]),u("div",null,[u("label",Td,m(h(f)("common.name")),1),pe(u("input",{"onUpdate:modelValue":N[1]||(N[1]=R=>r.value.name=R),class:"dh-input",autocomplete:"off"},null,512),[[be,r.value.name]])]),u("div",null,[u("label",Sd,m(o.value==="new"?h(f)("users.password"):h(f)("users.passwordUnchanged")),1),pe(u("input",{"onUpdate:modelValue":N[2]||(N[2]=R=>r.value.password=R),class:"dh-input",type:"password",autocomplete:"new-password",placeholder:h(f)("users.passwordPlaceholder")},null,8,Ed),[[be,r.value.password]])]),u("div",null,[u("label",Pd,m(h(f)("common.role")),1),pe(u("select",{"onUpdate:modelValue":N[3]||(N[3]=R=>r.value.role=R),class:"dh-select"},[(y(!0),T(re,null,Ce(a.value,R=>(y(),T("option",{key:R,value:R},m(R),9,Cd))),128))],512),[[ks,r.value.role]])]),h(De)?(y(),T("div",Ad,[u("label",$d,m(h(f)("common.organization")),1),pe(u("select",{"onUpdate:modelValue":N[4]||(N[4]=R=>r.value.organization=R),class:"dh-select"},[u("option",Od,m(h(f)("users.orgNone")),1),(y(!0),T(re,null,Ce(s.value,R=>(y(),T("option",{key:R.id,value:R.id},m(R.name),9,Dd))),128))],512),[[ks,r.value.organization]])])):F("",!0)]),u("div",Rd,[u("button",{class:"dh-btn",disabled:i.value,onClick:E},m(o.value==="new"?h(f)("common.create"):h(f)("common.save")),9,zd),u("button",{class:"dh-btn-ghost",disabled:i.value,onClick:b},m(h(f)("common.cancel")),9,Id)])])):F("",!0),t.value.length?(y(),T("table",Ud,[u("thead",null,[u("tr",Nd,[u("th",null,m(h(f)("common.email")),1),u("th",null,m(h(f)("common.name")),1),u("th",null,m(h(f)("common.organization")),1),u("th",null,m(h(f)("common.role")),1),N[5]||(N[5]=u("th",null,null,-1))])]),u("tbody",null,[(y(!0),T(re,null,Ce(t.value,R=>{var G,Z;return y(),T("tr",{key:R.id,class:"border-t border-subtle transition-colors hover:bg-sunken"},[u("td",Md,[$e(m(R.email)+" ",1),R.id===((G=h(he))==null?void 0:G.id)?(y(),T("span",Ld,m(h(f)("users.you")),1)):F("",!0)]),u("td",Fd,m(R.name||h(f)("common.empty")),1),u("td",Bd,m(R.organizationName||h(f)("common.empty")),1),u("td",Hd,[u("span",{class:Ee(["dh-pill",V(R.role)])},m(R.role),3)]),u("td",Vd,[u("button",{class:"dh-btn-ghost",onClick:U=>d(R)},m(h(f)("common.edit")),9,Gd),R.id!==((Z=h(he))==null?void 0:Z.id)?(y(),T("button",{key:0,class:"dh-btn-danger ml-1.5",disabled:i.value,onClick:U=>A(R)},m(h(f)("common.delete")),9,Kd)):F("",!0)])])}),128))])])):(y(),T("p",jd,m(h(f)("users.empty")),1))]))}},qd={class:"dh-card overflow-hidden"},Zd={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},Jd={class:"text-base font-bold tracking-[-0.02em] text-strong"},Yd={class:"mt-0.5 text-xs text-muted"},Xd={key:0,class:"border-b border-subtle px-5 py-3 text-xs text-danger"},Qd={key:1,class:"border-b border-subtle bg-sunken px-5 py-4"},ep={class:"dh-label"},tp=["placeholder"],sp={class:"mt-3 flex items-center gap-2"},np=["disabled"],ip=["disabled"],op={key:2,class:"px-5 py-6 text-center text-sm text-muted"},rp={key:3,class:"w-full text-left text-sm"},ap={class:"[&>th]:eyebrow [&>th]:px-5 [&>th]:py-2.5 [&>th]:font-medium"},lp={class:"px-5 py-2.5 font-medium text-strong"},cp={class:"data px-5 py-2.5 text-xs text-muted"},up={class:"px-5 py-2.5 text-right whitespace-nowrap"},dp=["onClick"],pp=["disabled","onClick"],fp={__name:"OrgsCard",setup(e){const t=H([]),s=H(""),n=H(!1),i=H(null),o=H(""),r=Oe(()=>{var x;return((x=he.value)==null?void 0:x.organization)||""}),a=Oe(()=>De.value||!r.value);function l(x){return De.value||x.id===r.value}async function g(){if(!gs.value){t.value=[];return}try{const x=await ae("/api/orgs");t.value=x.organizations||[],s.value=""}catch(x){s.value=x.message}}lt(g);function d(){i.value="new",o.value=""}function b(x){i.value=x.id,o.value=x.name}function E(){i.value=null,s.value=""}async function A(){n.value=!0,s.value="";try{i.value==="new"?(await ae("/api/orgs",{method:"POST",body:{name:o.value}}),De.value||await Ts()):await ae(`/api/orgs/${i.value}`,{method:"PATCH",body:{name:o.value}}),i.value=null,await g()}catch(x){s.value=x.message}finally{n.value=!1}}async function V(x){const N=!De.value&&x.id===r.value;if(confirm(f(N?"orgs.confirmDeleteOwn":"orgs.confirmDelete",{name:x.name}))){n.value=!0,s.value="";try{await ae(`/api/orgs/${x.id}`,{method:"DELETE"}),N&&await Ts(),await g()}catch(G){s.value=G.message}finally{n.value=!1}}}return(x,N)=>(y(),T("div",qd,[u("div",Zd,[u("div",null,[u("div",Jd,m(h(De)?h(f)("orgs.title"):h(f)("common.organization")),1),u("p",Yd,m(h(De)?h(f)("orgs.subtitle"):r.value?h(f)("orgs.subtitleOwn"):h(f)("orgs.subtitleNone")),1)]),a.value?(y(),T("button",{key:0,class:"dh-btn",onClick:d},m(h(f)("orgs.newOrg")),1)):F("",!0)]),s.value?(y(),T("p",Xd,m(s.value),1)):F("",!0),i.value?(y(),T("div",Qd,[u("label",ep,m(h(f)("common.name")),1),pe(u("input",{"onUpdate:modelValue":N[0]||(N[0]=R=>o.value=R),class:"dh-input",placeholder:h(f)("orgs.namePlaceholder"),onKeyup:xo(A,["enter"])},null,40,tp),[[be,o.value]]),u("div",sp,[u("button",{class:"dh-btn",disabled:n.value||!o.value.trim(),onClick:A},m(i.value==="new"?h(f)("common.create"):h(f)("common.save")),9,np),u("button",{class:"dh-btn-ghost",disabled:n.value,onClick:E},m(h(f)("common.cancel")),9,ip)])])):F("",!0),t.value.length?(y(),T("table",rp,[u("thead",null,[u("tr",ap,[u("th",null,m(h(f)("common.name")),1),u("th",null,m(h(f)("orgs.colId")),1),N[1]||(N[1]=u("th",null,null,-1))])]),u("tbody",null,[(y(!0),T(re,null,Ce(t.value,R=>(y(),T("tr",{key:R.id,class:"border-t border-subtle transition-colors hover:bg-sunken"},[u("td",lp,m(R.name),1),u("td",cp,m(R.id),1),u("td",up,[l(R)?(y(),T(re,{key:0},[u("button",{class:"dh-btn-ghost",onClick:G=>b(R)},m(h(f)("common.rename")),9,dp),u("button",{class:"dh-btn-danger ml-1.5",disabled:n.value,onClick:G=>V(R)},m(h(f)("common.delete")),9,pp)],64)):F("",!0)])]))),128))])])):(y(),T("p",op,m(a.value&&!h(De)?h(f)("orgs.createHint"):h(f)("orgs.empty")),1))]))}},hp={class:"dh-card overflow-hidden"},gp={class:"border-b border-subtle px-5 py-4"},mp={class:"flex items-center justify-between"},bp={class:"text-base font-bold tracking-[-0.02em] text-strong"},vp={class:"eyebrow"},yp={key:0,class:"mt-1.5 text-xs text-muted"},_p={class:"overflow-x-auto"},wp={class:"w-full text-left text-sm"},xp={class:"[&>th]:eyebrow [&>th]:px-5 [&>th]:py-2.5 [&>th]:font-medium"},kp={class:"data border-t border-subtle px-5 py-2.5 text-xs whitespace-nowrap"},Tp={class:"text-strong"},Sp={class:"border-t border-subtle px-5 py-2.5 text-body"},fe={__name:"EndpointTable",props:{title:String,auth:String,endpoints:Array,note:String},setup(e){const t={GET:"text-success",POST:"text-brandtext",PUT:"text-info",PATCH:"text-warning",DELETE:"text-danger"};return(s,n)=>(y(),T("div",hp,[u("div",gp,[u("div",mp,[u("div",bp,m(e.title),1),u("span",vp,m(e.auth),1)]),e.note?(y(),T("p",yp,m(e.note),1)):F("",!0)]),u("div",_p,[u("table",wp,[u("thead",null,[u("tr",xp,[u("th",null,m(h(f)("api.colEndpoint")),1),u("th",null,m(h(f)("api.colDescription")),1)])]),u("tbody",null,[(y(!0),T(re,null,Ce(e.endpoints,i=>(y(),T("tr",{key:i.method+i.path,class:"transition-colors hover:bg-sunken"},[u("td",kp,[u("span",{class:Ee(["font-semibold",t[i.method]])},m(i.method),3),u("span",Tp,m(i.path),1)]),u("td",Sp,m(i.desc),1)]))),128))])])])]))}},Ep={class:"mx-auto flex max-w-[1368px] flex-col gap-6 px-6 pt-12 pb-16"},Pp={class:"flex items-center gap-3"},Cp={class:"eyebrow mt-1.5"},Ap={key:0,class:"data hidden text-xs text-muted sm:inline"},$p={key:0},Op={key:1,class:"dh-pill bg-info-soft text-info"},Dp=["value","aria-label"],Rp=["value"],zp=["title"],Ip={key:0,xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"1.75",class:"h-4 w-4"},jp={key:1,xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"1.75",class:"h-4 w-4"},Up={key:0,class:"eyebrow py-16 text-center"},Np={class:"flex flex-wrap gap-1.5"},Mp=["onClick"],Lp={key:8,class:"eyebrow text-center"},Fp={class:"eyebrow text-center"},Bp="{records} is any of service-records, technical-checks, maintenance, fuel-entries, charging-sessions, car-documents, parts.",Hp={__name:"App",setup(e){const t=H(!0),s=H("overview");lt(async()=>{await ec(),t.value=!1});const n=Oe(()=>{const P=[{id:"overview",label:f("sections.overview")}];return gs.value&&P.push({id:"users",label:f("sections.users")}),(gs.value||he.value)&&P.push({id:"orgs",label:f("sections.orgs")}),De.value&&P.push({id:"server",label:f("sections.server")},{id:"pocketbase",label:f("sections.pocketbase")},{id:"webapp",label:f("sections.webapp")},{id:"plugins",label:f("sections.plugins")}),P.push({id:"api",label:f("sections.api")}),P}),i=Oe(()=>Gl.map(P=>{let I=P;try{I=new Intl.DisplayNames([P],{type:"language"}).of(P)||P}catch{}return{code:P,label:I.charAt(0).toUpperCase()+I.slice(1)}}));function o(){Pn(),s.value="overview"}const r=[{method:"GET",path:"/api/health",desc:"Liveness probe (no auth)"},{method:"GET",path:"/healthz",desc:"The same probe under the conventional container path"},{method:"GET",path:"/api/status",desc:"Health of PocketBase + Web App"},{method:"POST",path:"/api/auth/login",desc:"Exchange email + password for a PocketBase token"},{method:"GET",path:"/api/auth/validate",desc:"Check whether a token is still valid"}],a=[{method:"GET",path:"/api/auth/me",desc:"Identity of the bearer token"},{method:"GET",path:"/api/identity",desc:"Identity incl. role + organization"}],l=[{method:"GET",path:"/api/cars",desc:"List owned + shared cars"},{method:"POST",path:"/api/cars",desc:"Create a car"},{method:"GET",path:"/api/cars/{id}",desc:"Fetch one car"},{method:"PATCH",path:"/api/cars/{id}",desc:"Update a car"},{method:"PUT",path:"/api/cars/{id}/view",desc:"Save the car's layout — hidden tabs/fields/columns and their order"},{method:"DELETE",path:"/api/cars/{id}",desc:"Delete a car (owner only)"},{method:"GET",path:"/api/cars/{id}/service-records",desc:"A car's service history"},{method:"GET",path:"/api/cars/{id}/technical-checks",desc:"A car's roadworthiness inspections"},{method:"GET",path:"/api/cars/{id}/parts",desc:"A car's parts catalog"},{method:"GET",path:"/api/cars/{id}/fuel-entries",desc:"A car's refuelings"},{method:"GET",path:"/api/cars/{id}/fuel-stats",desc:"Consumption + cost totals from the fuel log"},{method:"GET",path:"/api/cars/{id}/charging-sessions",desc:"A car's charging sessions"},{method:"GET",path:"/api/cars/{id}/charging-stats",desc:"Energy + cost totals from the charging log"},{method:"GET",path:"/api/cars/{id}/maintenance",desc:"A car's maintenance log"},{method:"GET",path:"/api/cars/{id}/documents",desc:"A car's documents"},{method:"GET",path:"/api/cars/{id}/reminders",desc:"A car's reminders"},{method:"GET",path:"/api/cars/{id}/provider",desc:"Live snapshot from the car's connected service"},{method:"POST",path:"/api/cars/{id}/provider",desc:"Link the car to a provider vehicle (an empty provider unlinks)"},{method:"POST",path:"/api/cars/{id}/provider/sync",desc:"Re-apply the provider's data to the car"},{method:"GET",path:"/api/cars/{id}/shares",desc:"Who a car is shared with (owner)"},{method:"POST",path:"/api/cars/{id}/shares",desc:"Share a car by email (owner)"},{method:"DELETE",path:"/api/cars/{id}/shares/{userId}",desc:"Revoke a share (owner)"}],g=[{method:"GET",path:"/api/service-records",desc:"List one car's service records (?car={id})"},{method:"POST",path:"/api/service-records",desc:"Log a service record"},{method:"GET",path:"/api/service-records/{id}",desc:"Fetch one record"},{method:"PATCH",path:"/api/service-records/{id}",desc:"Update a record"},{method:"DELETE",path:"/api/service-records/{id}",desc:"Delete a record"}],d=[{method:"GET",path:"/api/technical-checks",desc:"List one car's inspections (?car={id})"},{method:"POST",path:"/api/technical-checks",desc:"Log an inspection"},{method:"GET",path:"/api/technical-checks/{id}",desc:"Fetch one inspection"},{method:"PATCH",path:"/api/technical-checks/{id}",desc:"Update an inspection"},{method:"DELETE",path:"/api/technical-checks/{id}",desc:"Delete an inspection"}],b=[{method:"GET",path:"/api/parts",desc:"List one car's parts (?car={id})"},{method:"POST",path:"/api/parts",desc:"Add a part"},{method:"GET",path:"/api/parts/{id}",desc:"Fetch one part"},{method:"PATCH",path:"/api/parts/{id}",desc:"Update a part"},{method:"DELETE",path:"/api/parts/{id}",desc:"Delete a part"}],E=[{method:"GET",path:"/api/fuel-entries",desc:"List one car's refuelings (?car={id})"},{method:"POST",path:"/api/fuel-entries",desc:"Log a refueling"},{method:"GET",path:"/api/fuel-entries/{id}",desc:"Fetch one refueling"},{method:"PATCH",path:"/api/fuel-entries/{id}",desc:"Update a refueling"},{method:"DELETE",path:"/api/fuel-entries/{id}",desc:"Delete a refueling"}],A=[{method:"GET",path:"/api/charging-sessions",desc:"List one car's charging sessions (?car={id})"},{method:"POST",path:"/api/charging-sessions",desc:"Log a charging session"},{method:"GET",path:"/api/charging-sessions/{id}",desc:"Fetch one session"},{method:"PATCH",path:"/api/charging-sessions/{id}",desc:"Update a session"},{method:"DELETE",path:"/api/charging-sessions/{id}",desc:"Delete a session"}],V=[{method:"GET",path:"/api/maintenance",desc:"List one car's maintenance jobs (?car={id})"},{method:"POST",path:"/api/maintenance",desc:"Log a maintenance job"},{method:"GET",path:"/api/maintenance/{id}",desc:"Fetch one job"},{method:"PATCH",path:"/api/maintenance/{id}",desc:"Update a job"},{method:"DELETE",path:"/api/maintenance/{id}",desc:"Delete a job"}],x=[{method:"GET",path:"/api/car-documents",desc:"List one car's documents (?car={id})"},{method:"POST",path:"/api/car-documents",desc:"Add a document"},{method:"GET",path:"/api/car-documents/{id}",desc:"Fetch one document"},{method:"PATCH",path:"/api/car-documents/{id}",desc:"Update a document"},{method:"DELETE",path:"/api/car-documents/{id}",desc:"Delete a document"}],N=[{method:"GET",path:"/api/reminders",desc:"List one car's reminders (?car={id})"},{method:"POST",path:"/api/reminders",desc:"Create a reminder"},{method:"GET",path:"/api/reminders/{id}",desc:"Fetch one reminder"},{method:"PATCH",path:"/api/reminders/{id}",desc:"Update a reminder"},{method:"DELETE",path:"/api/reminders/{id}",desc:"Delete a reminder"},{method:"POST",path:"/api/reminders/{id}/complete",desc:"Mark done — a recurring reminder rolls forward from now"}],R=[{method:"POST",path:"/api/{records}/{id}/file",desc:"Attach a file, replacing any previous one (PDF or image, max 10 MB)"},{method:"GET",path:"/api/{records}/{id}/file",desc:"Download the attachment (car access re-checked on every request)"},{method:"DELETE",path:"/api/{records}/{id}/file",desc:"Detach and delete the file"}],G=[{method:"GET",path:"/api/vehicle-providers",desc:"Registered providers and whether the caller can use each one"},{method:"GET",path:"/api/vehicle-providers/{provider}/vehicles",desc:"Vehicles on the caller's provider account, as importable cars"},{method:"POST",path:"/api/vehicle-providers/{provider}/import",desc:"Create a car from a provider vehicle (409 if already imported)"}],Z=[{method:"GET",path:"/api/integrations/toyota",desc:"Resolved Toyota Connected settings (secrets masked)"},{method:"PUT",path:"/api/integrations/toyota",desc:"Save the caller's own layer (user or org scope)"},{method:"POST",path:"/api/integrations/toyota/health",desc:"Live probe with the resolved credentials"},{method:"GET",path:"/api/integrations/toyota/vehicles",desc:"Raw MyToyota vehicle payload"},{method:"GET",path:"/api/integrations/anker-solix",desc:"Resolved Anker Solix settings (secrets masked)"},{method:"PUT",path:"/api/integrations/anker-solix",desc:"Save the caller's own layer (user or org scope)"},{method:"POST",path:"/api/integrations/anker-solix/health",desc:"Live probe with the resolved credentials"},{method:"GET",path:"/api/integrations/anker-solix/chargers",desc:"EV chargers on the linked Anker account"},{method:"GET",path:"/api/integrations/anker-solix/chargers/{sn}/control",desc:"Control mode, token state and live CSMS session for one charger"},{method:"POST",path:"/api/integrations/anker-solix/chargers/{sn}/control/token",desc:"(Re)issue the charger's control token"},{method:"DELETE",path:"/api/integrations/anker-solix/chargers/{sn}/control/token",desc:"Revoke the control token"},{method:"POST",path:"/api/integrations/anker-solix/chargers/{sn}/{action}",desc:"One OCPP command: start, stop, limit, clear-limit, availability, reset, unlock, trigger, config"},{method:"GET",path:"/api/integrations/greencell",desc:"Resolved Greencell settings (secrets masked)"},{method:"PUT",path:"/api/integrations/greencell",desc:"Save the caller's own layer (user or org scope)"},{method:"POST",path:"/api/integrations/greencell/health",desc:"Live probe: connect to the broker and broadcast for devices"},{method:"GET",path:"/api/integrations/greencell/chargers",desc:"Greencell chargers answering on the configured MQTT broker"},{method:"GET",path:"/api/integrations/greencell/chargers/{sn}/state",desc:"Live EVSE state, access level, power and per-phase current/voltage"}],U=[{method:"GET",path:"/ocpp/{serial}",desc:"WebSocket the charger dials out to; OCPP Basic auth with the serial + its control token"}],le=[{method:"GET",path:"/api/me",desc:"Current user profile"},{method:"PATCH",path:"/api/me",desc:"Update profile"},{method:"POST",path:"/api/me/password",desc:"Change password"},{method:"POST",path:"/api/me/avatar",desc:"Upload avatar"},{method:"GET",path:"/api/me/avatar",desc:"Fetch avatar"},{method:"DELETE",path:"/api/me/avatar",desc:"Remove avatar"},{method:"POST",path:"/api/me/verify/request",desc:"Request email verification"},{method:"GET",path:"/api/me/export",desc:"Export your data"},{method:"POST",path:"/api/me/import",desc:"Import data"},{method:"POST",path:"/api/me/delete",desc:"Request account deletion"},{method:"POST",path:"/api/me/delete/cancel",desc:"Cancel deletion request"},{method:"DELETE",path:"/api/me",desc:"Finalize account deletion"}],z=[{method:"GET",path:"/api/users",desc:"List users (scoped by role)"},{method:"POST",path:"/api/users",desc:"Create a user"},{method:"PATCH",path:"/api/users/{id}",desc:"Update email / name / role / org / password"},{method:"DELETE",path:"/api/users/{id}",desc:"Delete a user"},{method:"GET",path:"/api/orgs",desc:"List organizations"},{method:"POST",path:"/api/orgs",desc:"Create an organization (any user without one; creator becomes admin)"},{method:"PATCH",path:"/api/orgs/{id}",desc:"Rename an organization (own org; any as superadmin)"},{method:"DELETE",path:"/api/orgs/{id}",desc:"Delete an organization (own org; any as superadmin)"}],K=[{method:"GET",path:"/api/admin/pb-config",desc:"PocketBase connection + live probe"},{method:"POST",path:"/api/admin/pb-config/test",desc:"Probe a candidate connection"},{method:"PUT",path:"/api/admin/pb-config",desc:"Apply + persist a connection"},{method:"GET",path:"/api/admin/server-config",desc:"This server's display name"},{method:"PUT",path:"/api/admin/server-config",desc:"Rename this server (applied + persisted)"},{method:"GET",path:"/api/admin/webapp-config",desc:"Web App URL + CORS origins, with a live probe"},{method:"POST",path:"/api/admin/webapp-config/test",desc:"Probe a candidate Web App address"},{method:"PUT",path:"/api/admin/webapp-config",desc:"Apply + persist Web App settings"},{method:"GET",path:"/api/admin/plugins",desc:"List plugins (secrets masked)"},{method:"POST",path:"/api/admin/plugins",desc:"Register an external plugin"},{method:"GET",path:"/api/admin/plugins/{name}",desc:"Fetch one plugin"},{method:"PUT",path:"/api/admin/plugins/{name}",desc:"Enable/disable + configure"},{method:"DELETE",path:"/api/admin/plugins/{name}",desc:"Remove an external plugin"},{method:"POST",path:"/api/admin/plugins/{name}/health",desc:"Run a health check now"}];return(P,I)=>(y(),T("div",Ep,[u("div",Pp,[ee(lc,{"on-dark":h(Ct)==="dark",class:"h-7"},null,8,["on-dark"]),u("span",Cp,m(h(f)("app.apiServer")),1),I[4]||(I[4]=u("div",{class:"flex-1"},null,-1)),h(he)?(y(),T("span",Ap,[$e(m(h(he).email),1),h(he).organizationName?(y(),T("span",$p," · "+m(h(he).organizationName),1)):F("",!0)])):F("",!0),h(he)?(y(),T("span",Op,m(h(he).role),1)):F("",!0),u("select",{class:"dh-select !w-auto !py-1 !text-xs",value:h(En),"aria-label":h(f)("sections.overview"),onChange:I[0]||(I[0]=J=>h(Wl)(J.target.value))},[(y(!0),T(re,null,Ce(i.value,J=>(y(),T("option",{key:J.code,value:J.code},m(J.label),9,Rp))),128))],40,Dp),u("button",{class:"dh-btn-ghost",title:h(Ct)==="dark"?h(f)("app.switchToLight"):h(f)("app.switchToDark"),onClick:I[1]||(I[1]=(...J)=>h(fi)&&h(fi)(...J))},[h(Ct)==="dark"?(y(),T("svg",Ip,[...I[2]||(I[2]=[u("circle",{cx:"12",cy:"12",r:"4"},null,-1),u("path",{"stroke-linecap":"round",d:"M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4"},null,-1)])])):(y(),T("svg",jp,[...I[3]||(I[3]=[u("path",{"stroke-linecap":"round","stroke-linejoin":"round",d:"M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8Z"},null,-1)])])),$e(" "+m(h(f)("app.theme")),1)],8,zp),h(Rt)?(y(),T("button",{key:2,class:"dh-btn-ghost",onClick:o},m(h(f)("app.signOut")),1)):F("",!0)]),t.value?(y(),T("p",Up,m(h(f)("app.loading")),1)):h(Rt)?(y(),T(re,{key:2},[u("nav",Np,[(y(!0),T(re,null,Ce(n.value,J=>(y(),T("button",{key:J.id,class:Ee(["dh-btn-ghost",s.value===J.id?"border-accent text-brandtext":""]),onClick:wt=>s.value=J.id},m(J.label),11,Mp))),128))]),s.value==="overview"?(y(),et($c,{key:0})):s.value==="users"?(y(),et(Wd,{key:1})):s.value==="orgs"?(y(),et(fp,{key:2})):s.value==="server"?(y(),et(au,{key:3})):s.value==="pocketbase"?(y(),et(qc,{key:4})):s.value==="webapp"?(y(),et(ku,{key:5})):s.value==="plugins"?(y(),et(gd,{key:6})):s.value==="api"?(y(),T(re,{key:7},[ee(fe,{title:h(f)("api.groupPublic"),auth:h(f)("api.authNone"),endpoints:r},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupIdentity"),auth:h(f)("api.authBearer"),endpoints:a},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupCars"),auth:h(f)("api.authBearer"),endpoints:l},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupService"),auth:h(f)("api.authBearer"),endpoints:g},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupTechnical"),auth:h(f)("api.authBearer"),endpoints:d},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupParts"),auth:h(f)("api.authBearer"),endpoints:b},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupFuel"),auth:h(f)("api.authBearer"),endpoints:E},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupCharging"),auth:h(f)("api.authBearer"),endpoints:A},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupMaintenance"),auth:h(f)("api.authBearer"),endpoints:V},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupDocuments"),auth:h(f)("api.authBearer"),endpoints:x},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupReminders"),auth:h(f)("api.authBearer"),endpoints:N},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupAttachments"),auth:h(f)("api.authBearer"),endpoints:R,note:Bp},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupProviders"),auth:h(f)("api.authBearer"),endpoints:G},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupIntegrations"),auth:h(f)("api.authBearer"),endpoints:Z},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupOcpp"),auth:h(f)("api.authCharger"),endpoints:U},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupAccount"),auth:h(f)("api.authBearer"),endpoints:le},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupManagement"),auth:h(f)("api.authManager"),endpoints:z},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupSuperadmin"),auth:h(f)("api.authSuperadmin"),endpoints:K},null,8,["title","auth"])],64)):F("",!0),!h(gs)&&s.value==="overview"?(y(),T("p",Lp,m(h(f)("app.standardUserNote")),1)):F("",!0)],64)):(y(),et(vc,{key:1})),u("p",Fp,m(h(f)("app.footer")),1)]))}};sl(Hp).mount("#app"); diff --git a/API Server/internal/api/dist/assets/index-CUgU2Fxs.js b/API Server/internal/api/dist/assets/index-CUgU2Fxs.js new file mode 100644 index 0000000..5573a80 --- /dev/null +++ b/API Server/internal/api/dist/assets/index-CUgU2Fxs.js @@ -0,0 +1,17 @@ +(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const i of document.querySelectorAll('link[rel="modulepreload"]'))n(i);new MutationObserver(i=>{for(const o of i)if(o.type==="childList")for(const r of o.addedNodes)r.tagName==="LINK"&&r.rel==="modulepreload"&&n(r)}).observe(document,{childList:!0,subtree:!0});function s(i){const o={};return i.integrity&&(o.integrity=i.integrity),i.referrerPolicy&&(o.referrerPolicy=i.referrerPolicy),i.crossOrigin==="use-credentials"?o.credentials="include":i.crossOrigin==="anonymous"?o.credentials="omit":o.credentials="same-origin",o}function n(i){if(i.ep)return;i.ep=!0;const o=s(i);fetch(i.href,o)}})();/** +* @vue/shared v3.5.39 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/function un(e){const t=Object.create(null);for(const s of e.split(","))t[s]=1;return s=>s in t}const ne={},Pt=[],Xe=()=>{},mi=()=>!1,Ps=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),Cs=e=>e.startsWith("onUpdate:"),xe=Object.assign,dn=(e,t)=>{const s=e.indexOf(t);s>-1&&e.splice(s,1)},$o=Object.prototype.hasOwnProperty,X=(e,t)=>$o.call(e,t),F=Array.isArray,Ct=e=>is(e)==="[object Map]",Ut=e=>is(e)==="[object Set]",zn=e=>is(e)==="[object Date]",W=e=>typeof e=="function",de=e=>typeof e=="string",Qe=e=>typeof e=="symbol",te=e=>e!==null&&typeof e=="object",bi=e=>(te(e)||W(e))&&W(e.then)&&W(e.catch),vi=Object.prototype.toString,is=e=>vi.call(e),Oo=e=>is(e).slice(8,-1),yi=e=>is(e)==="[object Object]",pn=e=>de(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,Gt=un(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),As=e=>{const t=Object.create(null);return(s=>t[s]||(t[s]=e(s)))},Do=/-\w/g,Ne=As(e=>e.replace(Do,t=>t.slice(1).toUpperCase())),Ro=/\B([A-Z])/g,bt=As(e=>e.replace(Ro,"-$1").toLowerCase()),_i=As(e=>e.charAt(0).toUpperCase()+e.slice(1)),Ns=As(e=>e?`on${_i(e)}`:""),Ye=(e,t)=>!Object.is(e,t),hs=(e,...t)=>{for(let s=0;s{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:n,value:s})},$s=e=>{const t=parseFloat(e);return isNaN(t)?e:t};let In;const Os=()=>In||(In=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function fn(e){if(F(e)){const t={};for(let s=0;s{if(s){const n=s.split(Io);n.length>1&&(t[n[0].trim()]=n[1].trim())}}),t}function $e(e){let t="";if(de(e))t=e;else if(F(e))for(let s=0;sht(s,t))}const ki=e=>!!(e&&e.__v_isRef===!0),m=e=>de(e)?e:e==null?"":F(e)||te(e)&&(e.toString===vi||!W(e.toString))?ki(e)?m(e.value):JSON.stringify(e,Ti,2):String(e),Ti=(e,t)=>ki(t)?Ti(e,t.value):Ct(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((s,[n,i],o)=>(s[Ls(n,o)+" =>"]=i,s),{})}:Ut(t)?{[`Set(${t.size})`]:[...t.values()].map(s=>Ls(s))}:Qe(t)?Ls(t):te(t)&&!F(t)&&!yi(t)?String(t):t,Ls=(e,t="")=>{var s;return Qe(e)?`Symbol(${(s=e.description)!=null?s:t})`:e};/** +* @vue/reactivity v3.5.39 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/let ve;class Fo{constructor(t=!1){this.detached=t,this._active=!0,this._on=0,this.effects=[],this.cleanups=[],this._isPaused=!1,this._warnOnRun=!0,this.__v_skip=!0,!t&&ve&&(ve.active?(this.parent=ve,this.index=(ve.scopes||(ve.scopes=[])).push(this)-1):(this._active=!1,this._warnOnRun=!1))}get active(){return this._active}pause(){if(this._active){this._isPaused=!0;let t,s;if(this.scopes)for(t=0,s=this.scopes.length;t0&&--this._on===0){if(ve===this)ve=this.prevScope;else{let t=ve;for(;t;){if(t.prevScope===this){t.prevScope=this.prevScope;break}t=t.prevScope}}this.prevScope=void 0}}stop(t){if(this._active){this._active=!1;let s,n;for(s=0,n=this.effects.length;s0)return;if(Wt){let t=Wt;for(Wt=void 0;t;){const s=t.next;t.next=void 0,t.flags&=-9,t=s}}let e;for(;Kt;){let t=Kt;for(Kt=void 0;t;){const s=t.next;if(t.next=void 0,t.flags&=-9,t.flags&1)try{t.trigger()}catch(n){e||(e=n)}t=s}}if(e)throw e}function Ci(e){for(let t=e.deps;t;t=t.nextDep)t.version=-1,t.prevActiveLink=t.dep.activeLink,t.dep.activeLink=t}function Ai(e){let t,s=e.depsTail,n=s;for(;n;){const i=n.prevDep;n.version===-1?(n===s&&(s=i),bn(n),Ho(n)):t=n,n.dep.activeLink=n.prevActiveLink,n.prevActiveLink=void 0,n=i}e.deps=t,e.depsTail=s}function Ys(e){for(let t=e.deps;t;t=t.nextDep)if(t.dep.version!==t.version||t.dep.computed&&($i(t.dep.computed)||t.dep.version!==t.version))return!0;return!!e._dirty}function $i(e){if(e.flags&4&&!(e.flags&16)||(e.flags&=-17,e.globalVersion===Xt)||(e.globalVersion=Xt,!e.isSSR&&e.flags&128&&(!e.deps&&!e._dirty||!Ys(e))))return;e.flags|=2;const t=e.dep,s=oe,n=Le;oe=e,Le=!0;try{Ci(e);const i=e.fn(e._value);(t.version===0||Ye(i,e._value))&&(e.flags|=128,e._value=i,t.version++)}catch(i){throw t.version++,i}finally{oe=s,Le=n,Ai(e),e.flags&=-3}}function bn(e,t=!1){const{dep:s,prevSub:n,nextSub:i}=e;if(n&&(n.nextSub=i,e.prevSub=void 0),i&&(i.prevSub=n,e.nextSub=void 0),s.subs===e&&(s.subs=n,!n&&s.computed)){s.computed.flags&=-5;for(let o=s.computed.deps;o;o=o.nextDep)bn(o,!0)}!t&&!--s.sc&&s.map&&s.map.delete(s.key)}function Ho(e){const{prevDep:t,nextDep:s}=e;t&&(t.nextDep=s,e.prevDep=void 0),s&&(s.prevDep=t,e.nextDep=void 0)}let Le=!0;const Oi=[];function et(){Oi.push(Le),Le=!1}function tt(){const e=Oi.pop();Le=e===void 0?!0:e}function jn(e){const{cleanup:t}=e;if(e.cleanup=void 0,t){const s=oe;oe=void 0;try{t()}finally{oe=s}}}let Xt=0;class Vo{constructor(t,s){this.sub=t,this.dep=s,this.version=s.version,this.nextDep=this.prevDep=this.nextSub=this.prevSub=this.prevActiveLink=void 0}}class vn{constructor(t){this.computed=t,this.version=0,this.activeLink=void 0,this.subs=void 0,this.map=void 0,this.key=void 0,this.sc=0,this.__v_skip=!0}track(t){if(!oe||!Le||oe===this.computed)return;let s=this.activeLink;if(s===void 0||s.sub!==oe)s=this.activeLink=new Vo(oe,this),oe.deps?(s.prevDep=oe.depsTail,oe.depsTail.nextDep=s,oe.depsTail=s):oe.deps=oe.depsTail=s,Di(s);else if(s.version===-1&&(s.version=this.version,s.nextDep)){const n=s.nextDep;n.prevDep=s.prevDep,s.prevDep&&(s.prevDep.nextDep=n),s.prevDep=oe.depsTail,s.nextDep=void 0,oe.depsTail.nextDep=s,oe.depsTail=s,oe.deps===s&&(oe.deps=n)}return s}trigger(t){this.version++,Xt++,this.notify(t)}notify(t){gn();try{for(let s=this.subs;s;s=s.prevSub)s.sub.notify()&&s.sub.dep.notify()}finally{mn()}}}function Di(e){if(e.dep.sc++,e.sub.flags&4){const t=e.dep.computed;if(t&&!e.dep.subs){t.flags|=20;for(let n=t.deps;n;n=n.nextDep)Di(n)}const s=e.dep.subs;s!==e&&(e.prevSub=s,s&&(s.nextSub=e)),e.dep.subs=e}}const Xs=new WeakMap,kt=Symbol(""),Qs=Symbol(""),Qt=Symbol("");function _e(e,t,s){if(Le&&oe){let n=Xs.get(e);n||Xs.set(e,n=new Map);let i=n.get(s);i||(n.set(s,i=new vn),i.map=n,i.key=s),i.track()}}function at(e,t,s,n,i,o){const r=Xs.get(e);if(!r){Xt++;return}const a=l=>{l&&l.trigger()};if(gn(),t==="clear")r.forEach(a);else{const l=F(e),g=l&&pn(s);if(l&&s==="length"){const d=Number(n);r.forEach((b,E)=>{(E==="length"||E===Qt||!Qe(E)&&E>=d)&&a(b)})}else switch((s!==void 0||r.has(void 0))&&a(r.get(s)),g&&a(r.get(Qt)),t){case"add":l?g&&a(r.get("length")):(a(r.get(kt)),Ct(e)&&a(r.get(Qs)));break;case"delete":l||(a(r.get(kt)),Ct(e)&&a(r.get(Qs)));break;case"set":Ct(e)&&a(r.get(kt));break}}mn()}function St(e){const t=Y(e);return t===e?t:(_e(t,"iterate",Qt),Ue(e)?t:t.map(Fe))}function Ds(e){return _e(e=Y(e),"iterate",Qt),e}function Ze(e,t){return ut(e)?Dt(Tt(e)?Fe(t):t):Fe(t)}const Go={__proto__:null,[Symbol.iterator](){return Bs(this,Symbol.iterator,e=>Ze(this,e))},concat(...e){return St(this).concat(...e.map(t=>F(t)?St(t):t))},entries(){return Bs(this,"entries",e=>(e[1]=Ze(this,e[1]),e))},every(e,t){return nt(this,"every",e,t,void 0,arguments)},filter(e,t){return nt(this,"filter",e,t,s=>s.map(n=>Ze(this,n)),arguments)},find(e,t){return nt(this,"find",e,t,s=>Ze(this,s),arguments)},findIndex(e,t){return nt(this,"findIndex",e,t,void 0,arguments)},findLast(e,t){return nt(this,"findLast",e,t,s=>Ze(this,s),arguments)},findLastIndex(e,t){return nt(this,"findLastIndex",e,t,void 0,arguments)},forEach(e,t){return nt(this,"forEach",e,t,void 0,arguments)},includes(...e){return Hs(this,"includes",e)},indexOf(...e){return Hs(this,"indexOf",e)},join(e){return St(this).join(e)},lastIndexOf(...e){return Hs(this,"lastIndexOf",e)},map(e,t){return nt(this,"map",e,t,void 0,arguments)},pop(){return Ft(this,"pop")},push(...e){return Ft(this,"push",e)},reduce(e,...t){return Un(this,"reduce",e,t)},reduceRight(e,...t){return Un(this,"reduceRight",e,t)},shift(){return Ft(this,"shift")},some(e,t){return nt(this,"some",e,t,void 0,arguments)},splice(...e){return Ft(this,"splice",e)},toReversed(){return St(this).toReversed()},toSorted(e){return St(this).toSorted(e)},toSpliced(...e){return St(this).toSpliced(...e)},unshift(...e){return Ft(this,"unshift",e)},values(){return Bs(this,"values",e=>Ze(this,e))}};function Bs(e,t,s){const n=Ds(e),i=n[t]();return n!==e&&!Ue(e)&&(i._next=i.next,i.next=()=>{const o=i._next();return o.done||(o.value=s(o.value)),o}),i}const Ko=Array.prototype;function nt(e,t,s,n,i,o){const r=Ds(e),a=r!==e&&!Ue(e),l=r[t];if(l!==Ko[t]){const b=l.apply(e,o);return a?Fe(b):b}let g=s;r!==e&&(a?g=function(b,E){return s.call(this,Ze(e,b),E,e)}:s.length>2&&(g=function(b,E){return s.call(this,b,E,e)}));const d=l.call(r,g,n);return a&&i?i(d):d}function Un(e,t,s,n){const i=Ds(e),o=i!==e&&!Ue(e);let r=s,a=!1;i!==e&&(o?(a=n.length===0,r=function(g,d,b){return a&&(a=!1,g=Ze(e,g)),s.call(this,g,Ze(e,d),b,e)}):s.length>3&&(r=function(g,d,b){return s.call(this,g,d,b,e)}));const l=i[t](r,...n);return a?Ze(e,l):l}function Hs(e,t,s){const n=Y(e);_e(n,"iterate",Qt);const i=n[t](...s);return(i===-1||i===!1)&&wn(s[0])?(s[0]=Y(s[0]),n[t](...s)):i}function Ft(e,t,s=[]){et(),gn();const n=Y(e)[t].apply(e,s);return mn(),tt(),n}const Wo=un("__proto__,__v_isRef,__isVue"),Ri=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(Qe));function qo(e){Qe(e)||(e=String(e));const t=Y(this);return _e(t,"has",e),t.hasOwnProperty(e)}class zi{constructor(t=!1,s=!1){this._isReadonly=t,this._isShallow=s}get(t,s,n){if(s==="__v_skip")return t.__v_skip;const i=this._isReadonly,o=this._isShallow;if(s==="__v_isReactive")return!i;if(s==="__v_isReadonly")return i;if(s==="__v_isShallow")return o;if(s==="__v_raw")return n===(i?o?ir:Mi:o?Ui:ji).get(t)||Object.getPrototypeOf(t)===Object.getPrototypeOf(n)?t:void 0;const r=F(t);if(!i){let l;if(r&&(l=Go[s]))return l;if(s==="hasOwnProperty")return qo}const a=Reflect.get(t,s,we(t)?t:n);if((Qe(s)?Ri.has(s):Wo(s))||(i||_e(t,"get",s),o))return a;if(we(a)){const l=r&&pn(s)?a:a.value;return i&&te(l)?tn(l):l}return te(a)?i?tn(a):es(a):a}}class Ii extends zi{constructor(t=!1){super(!1,t)}set(t,s,n,i){let o=t[s];const r=F(t)&&pn(s);if(!this._isShallow){const g=ut(o);if(!Ue(n)&&!ut(n)&&(o=Y(o),n=Y(n)),!r&&we(o)&&!we(n))return g||(o.value=n),!0}const a=r?Number(s)e,us=e=>Reflect.getPrototypeOf(e);function Qo(e,t,s){return function(...n){const i=this.__v_raw,o=Y(i),r=Ct(o),a=e==="entries"||e===Symbol.iterator&&r,l=e==="keys"&&r,g=i[e](...n),d=s?en:t?Dt:Fe;return!t&&_e(o,"iterate",l?Qs:kt),xe(Object.create(g),{next(){const{value:b,done:E}=g.next();return E?{value:b,done:E}:{value:a?[d(b[0]),d(b[1])]:d(b),done:E}}})}}function ds(e){return function(...t){return e==="delete"?!1:e==="clear"?void 0:this}}function er(e,t){const s={get(i){const o=this.__v_raw,r=Y(o),a=Y(i);e||(Ye(i,a)&&_e(r,"get",i),_e(r,"get",a));const{has:l}=us(r),g=t?en:e?Dt:Fe;if(l.call(r,i))return g(o.get(i));if(l.call(r,a))return g(o.get(a));o!==r&&o.get(i)},get size(){const i=this.__v_raw;return!e&&_e(Y(i),"iterate",kt),i.size},has(i){const o=this.__v_raw,r=Y(o),a=Y(i);return e||(Ye(i,a)&&_e(r,"has",i),_e(r,"has",a)),i===a?o.has(i):o.has(i)||o.has(a)},forEach(i,o){const r=this,a=r.__v_raw,l=Y(a),g=t?en:e?Dt:Fe;return!e&&_e(l,"iterate",kt),a.forEach((d,b)=>i.call(o,g(d),g(b),r))}};return xe(s,e?{add:ds("add"),set:ds("set"),delete:ds("delete"),clear:ds("clear")}:{add(i){const o=Y(this),r=us(o),a=Y(i),l=!t&&!Ue(i)&&!ut(i)?a:i;return r.has.call(o,l)||Ye(i,l)&&r.has.call(o,i)||Ye(a,l)&&r.has.call(o,a)||(o.add(l),at(o,"add",l,l)),this},set(i,o){!t&&!Ue(o)&&!ut(o)&&(o=Y(o));const r=Y(this),{has:a,get:l}=us(r);let g=a.call(r,i);g||(i=Y(i),g=a.call(r,i));const d=l.call(r,i);return r.set(i,o),g?Ye(o,d)&&at(r,"set",i,o):at(r,"add",i,o),this},delete(i){const o=Y(this),{has:r,get:a}=us(o);let l=r.call(o,i);l||(i=Y(i),l=r.call(o,i)),a&&a.call(o,i);const g=o.delete(i);return l&&at(o,"delete",i,void 0),g},clear(){const i=Y(this),o=i.size!==0,r=i.clear();return o&&at(i,"clear",void 0,void 0),r}}),["keys","values","entries",Symbol.iterator].forEach(i=>{s[i]=Qo(i,e,t)}),s}function yn(e,t){const s=er(e,t);return(n,i,o)=>i==="__v_isReactive"?!e:i==="__v_isReadonly"?e:i==="__v_raw"?n:Reflect.get(X(s,i)&&i in n?s:n,i,o)}const tr={get:yn(!1,!1)},sr={get:yn(!1,!0)},nr={get:yn(!0,!1)};const ji=new WeakMap,Ui=new WeakMap,Mi=new WeakMap,ir=new WeakMap;function or(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function es(e){return ut(e)?e:_n(e,!1,Jo,tr,ji)}function rr(e){return _n(e,!1,Xo,sr,Ui)}function tn(e){return _n(e,!0,Yo,nr,Mi)}function _n(e,t,s,n,i){if(!te(e)||e.__v_raw&&!(t&&e.__v_isReactive)||e.__v_skip||!Object.isExtensible(e))return e;const o=i.get(e);if(o)return o;const r=or(Oo(e));if(r===0)return e;const a=new Proxy(e,r===2?n:s);return i.set(e,a),a}function Tt(e){return ut(e)?Tt(e.__v_raw):!!(e&&e.__v_isReactive)}function ut(e){return!!(e&&e.__v_isReadonly)}function Ue(e){return!!(e&&e.__v_isShallow)}function wn(e){return e?!!e.__v_raw:!1}function Y(e){const t=e&&e.__v_raw;return t?Y(t):e}function ar(e){return!X(e,"__v_skip")&&Object.isExtensible(e)&&wi(e,"__v_skip",!0),e}const Fe=e=>te(e)?es(e):e,Dt=e=>te(e)?tn(e):e;function we(e){return e?e.__v_isRef===!0:!1}function V(e){return lr(e,!1)}function lr(e,t){return we(e)?e:new cr(e,t)}class cr{constructor(t,s){this.dep=new vn,this.__v_isRef=!0,this.__v_isShallow=!1,this._rawValue=s?t:Y(t),this._value=s?t:Fe(t),this.__v_isShallow=s}get value(){return this.dep.track(),this._value}set value(t){const s=this._rawValue,n=this.__v_isShallow||Ue(t)||ut(t);t=n?t:Y(t),Ye(t,s)&&(this._rawValue=t,this._value=n?t:Fe(t),this.dep.trigger())}}function h(e){return we(e)?e.value:e}const ur={get:(e,t,s)=>t==="__v_raw"?e:h(Reflect.get(e,t,s)),set:(e,t,s,n)=>{const i=e[t];return we(i)&&!we(s)?(i.value=s,!0):Reflect.set(e,t,s,n)}};function Ni(e){return Tt(e)?e:new Proxy(e,ur)}class dr{constructor(t,s,n){this.fn=t,this.setter=s,this._value=void 0,this.dep=new vn(this),this.__v_isRef=!0,this.deps=void 0,this.depsTail=void 0,this.flags=16,this.globalVersion=Xt-1,this.next=void 0,this.effect=this,this.__v_isReadonly=!s,this.isSSR=n}notify(){if(this.flags|=16,!(this.flags&8)&&oe!==this)return Pi(this,!0),!0}get value(){const t=this.dep.track();return $i(this),t&&(t.version=this.dep.version),this._value}set value(t){this.setter&&this.setter(t)}}function pr(e,t,s=!1){let n,i;return W(e)?n=e:(n=e.get,i=e.set),new dr(n,i,s)}const ps={},vs=new WeakMap;let xt;function fr(e,t=!1,s=xt){if(s){let n=vs.get(s);n||vs.set(s,n=[]),n.push(e)}}function hr(e,t,s=ne){const{immediate:n,deep:i,once:o,scheduler:r,augmentJob:a,call:l}=s,g=j=>i?j:Ue(j)||i===!1||i===0?lt(j,1):lt(j);let d,b,E,C,G=!1,k=!1;if(we(e)?(b=()=>e.value,G=Ue(e)):Tt(e)?(b=()=>g(e),G=!0):F(e)?(k=!0,G=e.some(j=>Tt(j)||Ue(j)),b=()=>e.map(j=>{if(we(j))return j.value;if(Tt(j))return g(j);if(W(j))return l?l(j,2):j()})):W(e)?t?b=l?()=>l(e,2):e:b=()=>{if(E){et();try{E()}finally{tt()}}const j=xt;xt=d;try{return l?l(e,3,[C]):e(C)}finally{xt=j}}:b=Xe,t&&i){const j=b,ce=i===!0?1/0:i;b=()=>lt(j(),ce)}const M=Bo(),z=()=>{d.stop(),M&&M.active&&dn(M.effects,d)};if(o&&t){const j=t;t=(...ce)=>{const Ee=j(...ce);return z(),Ee}}let K=k?new Array(e.length).fill(ps):ps;const Z=j=>{if(!(!(d.flags&1)||!d.dirty&&!j))if(t){const ce=d.run();if(j||i||G||(k?ce.some((Ee,Pe)=>Ye(Ee,K[Pe])):Ye(ce,K))){E&&E();const Ee=xt;xt=d;try{const Pe=[ce,K===ps?void 0:k&&K[0]===ps?[]:K,C];K=ce,l?l(t,3,Pe):t(...Pe)}finally{xt=Ee}}}else d.run()};return a&&a(Z),d=new Si(b),d.scheduler=r?()=>r(Z,!1):Z,C=j=>fr(j,!1,d),E=d.onStop=()=>{const j=vs.get(d);if(j){if(l)l(j,4);else for(const ce of j)ce();vs.delete(d)}},t?n?Z(!0):K=d.run():r?r(Z.bind(null,!0),!0):d.run(),z.pause=d.pause.bind(d),z.resume=d.resume.bind(d),z.stop=z,z}function lt(e,t=1/0,s){if(t<=0||!te(e)||e.__v_skip||(s=s||new Map,(s.get(e)||0)>=t))return e;if(s.set(e,t),t--,we(e))lt(e.value,t,s);else if(F(e))for(let n=0;n{lt(n,t,s)});else if(yi(e)){for(const n in e)lt(e[n],t,s);for(const n of Object.getOwnPropertySymbols(e))Object.prototype.propertyIsEnumerable.call(e,n)&<(e[n],t,s)}return e}/** +* @vue/runtime-core v3.5.39 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/function os(e,t,s,n){try{return n?e(...n):e()}catch(i){Rs(i,t,s)}}function Be(e,t,s,n){if(W(e)){const i=os(e,t,s,n);return i&&bi(i)&&i.catch(o=>{Rs(o,t,s)}),i}if(F(e)){const i=[];for(let o=0;o>>1,i=Te[n],o=ts(i);o=ts(s)?Te.push(e):Te.splice(mr(t),0,e),e.flags|=1,Bi()}}function Bi(){ys||(ys=Li.then(Vi))}function br(e){F(e)?At.push(...e):ft&&e.id===-1?ft.splice(Et+1,0,e):e.flags&1||(At.push(e),e.flags|=1),Bi()}function Mn(e,t,s=qe+1){for(;sts(s)-ts(n));if(At.length=0,ft){ft.push(...t);return}for(ft=t,Et=0;Ete.id==null?e.flags&2?-1:1/0:e.id;function Vi(e){try{for(qe=0;qe{n._d&&Zn(-1);const o=_s(t);let r;try{r=e(...i)}finally{_s(o),n._d&&Zn(1)}return r};return n._n=!0,n._c=!0,n._d=!0,n}function fe(e,t){if(je===null)return e;const s=Us(je),n=e.dirs||(e.dirs=[]);for(let i=0;i1)return s&&W(t)?t.call(n&&n.proxy):t}}const _r=Symbol.for("v-scx"),wr=()=>gs(_r);function Vs(e,t,s){return Ki(e,t,s)}function Ki(e,t,s=ne){const{immediate:n,deep:i,flush:o,once:r}=s,a=xe({},s),l=t&&n||!t&&o!=="post";let g;if(ns){if(o==="sync"){const C=wr();g=C.__watcherHandles||(C.__watcherHandles=[])}else if(!l){const C=()=>{};return C.stop=Xe,C.resume=Xe,C.pause=Xe,C}}const d=Se;a.call=(C,G,k)=>Be(C,d,G,k);let b=!1;o==="post"?a.scheduler=C=>{Ce(C,d&&d.suspense)}:o!=="sync"&&(b=!0,a.scheduler=(C,G)=>{G?C():xn(C)}),a.augmentJob=C=>{t&&(C.flags|=4),b&&(C.flags|=2,d&&(C.id=d.uid,C.i=d))};const E=hr(e,t,a);return ns&&(g?g.push(E):l&&E()),E}function xr(e,t,s){const n=this.proxy,i=de(e)?e.includes(".")?Wi(n,e):()=>n[e]:e.bind(n,n);let o;W(t)?o=t:(o=t.handler,s=t);const r=rs(this),a=Ki(i,o.bind(n),s);return r(),a}function Wi(e,t){const s=t.split(".");return()=>{let n=e;for(let i=0;ie.__isTeleport,Gs=Symbol("_leaveCb");function kn(e,t){e.shapeFlag&6&&e.component?(e.transition=t,kn(e.component.subTree,t)):e.shapeFlag&128?(e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback)):e.transition=t}function qi(e){e.ids=[e.ids[0]+e.ids[2]+++"-",0,0]}function Nn(e,t){let s;return!!((s=Object.getOwnPropertyDescriptor(e,t))&&!s.configurable)}const ws=new WeakMap;function qt(e,t,s,n,i=!1){if(F(e)){e.forEach((k,M)=>qt(k,t&&(F(t)?t[M]:t),s,n,i));return}if(Zt(n)&&!i){n.shapeFlag&512&&n.type.__asyncResolved&&n.component.subTree.component&&qt(e,t,s,n.component.subTree);return}const o=n.shapeFlag&4?Us(n.component):n.el,r=i?null:o,{i:a,r:l}=e,g=t&&t.r,d=a.refs===ne?a.refs={}:a.refs,b=a.setupState,E=Y(b),C=b===ne?mi:k=>Nn(d,k)?!1:X(E,k),G=(k,M)=>!(M&&Nn(d,M));if(g!=null&&g!==l){if(Ln(t),de(g))d[g]=null,C(g)&&(b[g]=null);else if(we(g)){const k=t;G(g,k.k)&&(g.value=null),k.k&&(d[k.k]=null)}}if(W(l)){et();try{os(l,a,12,[r,d])}finally{tt()}}else{const k=de(l),M=we(l);if(k||M){const z=()=>{if(e.f){const K=k?C(l)?b[l]:d[l]:G()||!e.k?l.value:d[e.k];if(i)F(K)&&dn(K,o);else if(F(K))K.includes(o)||K.push(o);else if(k)d[l]=[o],C(l)&&(b[l]=d[l]);else{const Z=[o];G(l,e.k)&&(l.value=Z),e.k&&(d[e.k]=Z)}}else k?(d[l]=r,C(l)&&(b[l]=r)):M&&(G(l,e.k)&&(l.value=r),e.k&&(d[e.k]=r))};if(r){const K=()=>{z(),ws.delete(e)};K.id=-1,ws.set(e,K),Ce(K,s)}else Ln(e),z()}}}function Ln(e){const t=ws.get(e);t&&(t.flags|=8,ws.delete(e))}Os().requestIdleCallback;Os().cancelIdleCallback;const Zt=e=>!!e.type.__asyncLoader,Zi=e=>e.type.__isKeepAlive;function Sr(e,t){Ji(e,"a",t)}function Er(e,t){Ji(e,"da",t)}function Ji(e,t,s=Se){const n=e.__wdc||(e.__wdc=()=>{let i=s;for(;i;){if(i.isDeactivated)return;i=i.parent}return e()});if(zs(t,n,s),s){let i=s.parent;for(;i&&i.parent;)Zi(i.parent.vnode)&&Pr(n,t,s,i),i=i.parent}}function Pr(e,t,s,n){const i=zs(t,e,n,!0);Tn(()=>{dn(n[t],i)},s)}function zs(e,t,s=Se,n=!1){if(s){const i=s[e]||(s[e]=[]),o=t.__weh||(t.__weh=(...r)=>{et();const a=rs(s),l=Be(t,s,e,r);return a(),tt(),l});return n?i.unshift(o):i.push(o),o}}const dt=e=>(t,s=Se)=>{(!ns||e==="sp")&&zs(e,(...n)=>t(...n),s)},Cr=dt("bm"),pt=dt("m"),Ar=dt("bu"),$r=dt("u"),Or=dt("bum"),Tn=dt("um"),Dr=dt("sp"),Rr=dt("rtg"),zr=dt("rtc");function Ir(e,t=Se){zs("ec",e,t)}const jr=Symbol.for("v-ndc");function Ae(e,t,s,n){let i;const o=s,r=F(e);if(r||de(e)){const a=r&&Tt(e);let l=!1,g=!1;a&&(l=!Ue(e),g=ut(e),e=Ds(e)),i=new Array(e.length);for(let d=0,b=e.length;dt(a,l,void 0,o));else{const a=Object.keys(e);i=new Array(a.length);for(let l=0,g=a.length;le?vo(e)?Us(e):sn(e.parent):null,Jt=xe(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>sn(e.parent),$root:e=>sn(e.root),$host:e=>e.ce,$emit:e=>e.emit,$options:e=>Xi(e),$forceUpdate:e=>e.f||(e.f=()=>{xn(e.update)}),$nextTick:e=>e.n||(e.n=Fi.bind(e.proxy)),$watch:e=>xr.bind(e)}),Ks=(e,t)=>e!==ne&&!e.__isScriptSetup&&X(e,t),Ur={get({_:e},t){if(t==="__v_skip")return!0;const{ctx:s,setupState:n,data:i,props:o,accessCache:r,type:a,appContext:l}=e;if(t[0]!=="$"){const E=r[t];if(E!==void 0)switch(E){case 1:return n[t];case 2:return i[t];case 4:return s[t];case 3:return o[t]}else{if(Ks(n,t))return r[t]=1,n[t];if(i!==ne&&X(i,t))return r[t]=2,i[t];if(X(o,t))return r[t]=3,o[t];if(s!==ne&&X(s,t))return r[t]=4,s[t];nn&&(r[t]=0)}}const g=Jt[t];let d,b;if(g)return t==="$attrs"&&_e(e.attrs,"get",""),g(e);if((d=a.__cssModules)&&(d=d[t]))return d;if(s!==ne&&X(s,t))return r[t]=4,s[t];if(b=l.config.globalProperties,X(b,t))return b[t]},set({_:e},t,s){const{data:n,setupState:i,ctx:o}=e;return Ks(i,t)?(i[t]=s,!0):n!==ne&&X(n,t)?(n[t]=s,!0):X(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(o[t]=s,!0)},has({_:{data:e,setupState:t,accessCache:s,ctx:n,appContext:i,props:o,type:r}},a){let l;return!!(s[a]||e!==ne&&a[0]!=="$"&&X(e,a)||Ks(t,a)||X(o,a)||X(n,a)||X(Jt,a)||X(i.config.globalProperties,a)||(l=r.__cssModules)&&l[a])},defineProperty(e,t,s){return s.get!=null?e._.accessCache[t]=0:X(s,"value")&&this.set(e,t,s.value,null),Reflect.defineProperty(e,t,s)}};function Fn(e){return F(e)?e.reduce((t,s)=>(t[s]=null,t),{}):e}let nn=!0;function Mr(e){const t=Xi(e),s=e.proxy,n=e.ctx;nn=!1,t.beforeCreate&&Bn(t.beforeCreate,e,"bc");const{data:i,computed:o,methods:r,watch:a,provide:l,inject:g,created:d,beforeMount:b,mounted:E,beforeUpdate:C,updated:G,activated:k,deactivated:M,beforeDestroy:z,beforeUnmount:K,destroyed:Z,unmounted:j,render:ce,renderTracked:Ee,renderTriggered:Pe,errorCaptured:ue,serverPrefetch:D,expose:I,inheritAttrs:A,components:N,directives:le,filters:st}=t;if(g&&Nr(g,n,null),r)for(const J in r){const ie=r[J];W(ie)&&(n[J]=ie.bind(s))}if(i){const J=i.call(s,s);te(J)&&(e.data=es(J))}if(nn=!0,o)for(const J in o){const ie=o[J],vt=W(ie)?ie.bind(s,s):W(ie.get)?ie.get.bind(s,s):Xe,ls=!W(ie)&&W(ie.set)?ie.set.bind(s):Xe,yt=ze({get:vt,set:ls});Object.defineProperty(n,J,{enumerable:!0,configurable:!0,get:()=>yt.value,set:He=>yt.value=He})}if(a)for(const J in a)Yi(a[J],n,s,J);if(l){const J=W(l)?l.call(s):l;Reflect.ownKeys(J).forEach(ie=>{yr(ie,J[ie])})}d&&Bn(d,e,"c");function he(J,ie){F(ie)?ie.forEach(vt=>J(vt.bind(s))):ie&&J(ie.bind(s))}if(he(Cr,b),he(pt,E),he(Ar,C),he($r,G),he(Sr,k),he(Er,M),he(Ir,ue),he(zr,Ee),he(Rr,Pe),he(Or,K),he(Tn,j),he(Dr,D),F(I))if(I.length){const J=e.exposed||(e.exposed={});I.forEach(ie=>{Object.defineProperty(J,ie,{get:()=>s[ie],set:vt=>s[ie]=vt,enumerable:!0})})}else e.exposed||(e.exposed={});ce&&e.render===Xe&&(e.render=ce),A!=null&&(e.inheritAttrs=A),N&&(e.components=N),le&&(e.directives=le),D&&qi(e)}function Nr(e,t,s=Xe){F(e)&&(e=on(e));for(const n in e){const i=e[n];let o;te(i)?"default"in i?o=gs(i.from||n,i.default,!0):o=gs(i.from||n):o=gs(i),we(o)?Object.defineProperty(t,n,{enumerable:!0,configurable:!0,get:()=>o.value,set:r=>o.value=r}):t[n]=o}}function Bn(e,t,s){Be(F(e)?e.map(n=>n.bind(t.proxy)):e.bind(t.proxy),t,s)}function Yi(e,t,s,n){let i=n.includes(".")?Wi(s,n):()=>s[n];if(de(e)){const o=t[e];W(o)&&Vs(i,o)}else if(W(e))Vs(i,e.bind(s));else if(te(e))if(F(e))e.forEach(o=>Yi(o,t,s,n));else{const o=W(e.handler)?e.handler.bind(s):t[e.handler];W(o)&&Vs(i,o,e)}}function Xi(e){const t=e.type,{mixins:s,extends:n}=t,{mixins:i,optionsCache:o,config:{optionMergeStrategies:r}}=e.appContext,a=o.get(t);let l;return a?l=a:!i.length&&!s&&!n?l=t:(l={},i.length&&i.forEach(g=>xs(l,g,r,!0)),xs(l,t,r)),te(t)&&o.set(t,l),l}function xs(e,t,s,n=!1){const{mixins:i,extends:o}=t;o&&xs(e,o,s,!0),i&&i.forEach(r=>xs(e,r,s,!0));for(const r in t)if(!(n&&r==="expose")){const a=Lr[r]||s&&s[r];e[r]=a?a(e[r],t[r]):t[r]}return e}const Lr={data:Hn,props:Vn,emits:Vn,methods:Ht,computed:Ht,beforeCreate:ke,created:ke,beforeMount:ke,mounted:ke,beforeUpdate:ke,updated:ke,beforeDestroy:ke,beforeUnmount:ke,destroyed:ke,unmounted:ke,activated:ke,deactivated:ke,errorCaptured:ke,serverPrefetch:ke,components:Ht,directives:Ht,watch:Br,provide:Hn,inject:Fr};function Hn(e,t){return t?e?function(){return xe(W(e)?e.call(this,this):e,W(t)?t.call(this,this):t)}:t:e}function Fr(e,t){return Ht(on(e),on(t))}function on(e){if(F(e)){const t={};for(let s=0;st==="modelValue"||t==="model-value"?e.modelModifiers:e[`${t}Modifiers`]||e[`${Ne(t)}Modifiers`]||e[`${bt(t)}Modifiers`];function Kr(e,t,...s){if(e.isUnmounted)return;const n=e.vnode.props||ne;let i=s;const o=t.startsWith("update:"),r=o&&Gr(n,t.slice(7));r&&(r.trim&&(i=s.map(d=>de(d)?d.trim():d)),r.number&&(i=s.map($s)));let a,l=n[a=Ns(t)]||n[a=Ns(Ne(t))];!l&&o&&(l=n[a=Ns(bt(t))]),l&&Be(l,e,6,i);const g=n[a+"Once"];if(g){if(!e.emitted)e.emitted={};else if(e.emitted[a])return;e.emitted[a]=!0,Be(g,e,6,i)}}const Wr=new WeakMap;function eo(e,t,s=!1){const n=s?Wr:t.emitsCache,i=n.get(e);if(i!==void 0)return i;const o=e.emits;let r={},a=!1;if(!W(e)){const l=g=>{const d=eo(g,t,!0);d&&(a=!0,xe(r,d))};!s&&t.mixins.length&&t.mixins.forEach(l),e.extends&&l(e.extends),e.mixins&&e.mixins.forEach(l)}return!o&&!a?(te(e)&&n.set(e,null),null):(F(o)?o.forEach(l=>r[l]=null):xe(r,o),te(e)&&n.set(e,r),r)}function Is(e,t){return!e||!Ps(t)?!1:(t=t.slice(2),t=t==="Once"?t:t.replace(/Once$/,""),X(e,t[0].toLowerCase()+t.slice(1))||X(e,bt(t))||X(e,t))}function Gn(e){const{type:t,vnode:s,proxy:n,withProxy:i,propsOptions:[o],slots:r,attrs:a,emit:l,render:g,renderCache:d,props:b,data:E,setupState:C,ctx:G,inheritAttrs:k}=e,M=_s(e);let z,K;try{if(s.shapeFlag&4){const j=i||n,ce=j;z=Je(g.call(ce,j,d,b,C,E,G)),K=a}else{const j=t;z=Je(j.length>1?j(b,{attrs:a,slots:r,emit:l}):j(b,null)),K=t.props?a:qr(a)}}catch(j){Yt.length=0,Rs(j,e,1),z=ee(gt)}let Z=z;if(K&&k!==!1){const j=Object.keys(K),{shapeFlag:ce}=Z;j.length&&ce&7&&(o&&j.some(Cs)&&(K=Zr(K,o)),Z=Rt(Z,K,!1,!0))}return s.dirs&&(Z=Rt(Z,null,!1,!0),Z.dirs=Z.dirs?Z.dirs.concat(s.dirs):s.dirs),s.transition&&kn(Z,s.transition),z=Z,_s(M),z}const qr=e=>{let t;for(const s in e)(s==="class"||s==="style"||Ps(s))&&((t||(t={}))[s]=e[s]);return t},Zr=(e,t)=>{const s={};for(const n in e)(!Cs(n)||!(n.slice(9)in t))&&(s[n]=e[n]);return s};function Jr(e,t,s){const{props:n,children:i,component:o}=e,{props:r,children:a,patchFlag:l}=t,g=o.emitsOptions;if(t.dirs||t.transition)return!0;if(s&&l>=0){if(l&1024)return!0;if(l&16)return n?Kn(n,r,g):!!r;if(l&8){const d=t.dynamicProps;for(let b=0;bObject.create(so),io=e=>Object.getPrototypeOf(e)===so;function Xr(e,t,s,n=!1){const i={},o=no();e.propsDefaults=Object.create(null),oo(e,t,i,o);for(const r in e.propsOptions[0])r in i||(i[r]=void 0);s?e.props=n?i:rr(i):e.type.props?e.props=i:e.props=o,e.attrs=o}function Qr(e,t,s,n){const{props:i,attrs:o,vnode:{patchFlag:r}}=e,a=Y(i),[l]=e.propsOptions;let g=!1;if((n||r>0)&&!(r&16)){if(r&8){const d=e.vnode.dynamicProps;for(let b=0;b{l=!0;const[E,C]=ro(b,t,!0);xe(r,E),C&&a.push(...C)};!s&&t.mixins.length&&t.mixins.forEach(d),e.extends&&d(e.extends),e.mixins&&e.mixins.forEach(d)}if(!o&&!l)return te(e)&&n.set(e,Pt),Pt;if(F(o))for(let d=0;de==="_"||e==="_ctx"||e==="$stable",En=e=>F(e)?e.map(Je):[Je(e)],ta=(e,t,s)=>{if(t._n)return t;const n=vr((...i)=>En(t(...i)),s);return n._c=!1,n},ao=(e,t,s)=>{const n=e._ctx;for(const i in e){if(Sn(i))continue;const o=e[i];if(W(o))t[i]=ta(i,o,n);else if(o!=null){const r=En(o);t[i]=()=>r}}},lo=(e,t)=>{const s=En(t);e.slots.default=()=>s},co=(e,t,s)=>{for(const n in t)(s||!Sn(n))&&(e[n]=t[n])},sa=(e,t,s)=>{const n=e.slots=no();if(e.vnode.shapeFlag&32){const i=t._;i?(co(n,t,s),s&&wi(n,"_",i,!0)):ao(t,n)}else t&&lo(e,t)},na=(e,t,s)=>{const{vnode:n,slots:i}=e;let o=!0,r=ne;if(n.shapeFlag&32){const a=t._;a?s&&a===1?o=!1:co(i,t,s):(o=!t.$stable,ao(t,i)),r=t}else t&&(lo(e,t),r={default:1});if(o)for(const a in i)!Sn(a)&&r[a]==null&&delete i[a]},Ce=la;function ia(e){return oa(e)}function oa(e,t){const s=Os();s.__VUE__=!0;const{insert:n,remove:i,patchProp:o,createElement:r,createText:a,createComment:l,setText:g,setElementText:d,parentNode:b,nextSibling:E,setScopeId:C=Xe,insertStaticContent:G}=e,k=(c,p,v,S=null,T=null,w=null,O=void 0,$=null,P=!!p.dynamicChildren)=>{if(c===p)return;c&&!Bt(c,p)&&(S=cs(c),He(c,T,w,!0),c=null),p.patchFlag===-2&&(P=!1,p.dynamicChildren=null);const{type:x,ref:L,shapeFlag:R}=p;switch(x){case js:M(c,p,v,S);break;case gt:z(c,p,v,S);break;case qs:c==null&&K(p,v,S,O);break;case re:N(c,p,v,S,T,w,O,$,P);break;default:R&1?ce(c,p,v,S,T,w,O,$,P):R&6?le(c,p,v,S,T,w,O,$,P):(R&64||R&128)&&x.process(c,p,v,S,T,w,O,$,P,Nt)}L!=null&&T?qt(L,c&&c.ref,w,p||c,!p):L==null&&c&&c.ref!=null&&qt(c.ref,null,w,c,!0)},M=(c,p,v,S)=>{if(c==null)n(p.el=a(p.children),v,S);else{const T=p.el=c.el;p.children!==c.children&&g(T,p.children)}},z=(c,p,v,S)=>{c==null?n(p.el=l(p.children||""),v,S):p.el=c.el},K=(c,p,v,S)=>{[c.el,c.anchor]=G(c.children,p,v,S,c.el,c.anchor)},Z=({el:c,anchor:p},v,S)=>{let T;for(;c&&c!==p;)T=E(c),n(c,v,S),c=T;n(p,v,S)},j=({el:c,anchor:p})=>{let v;for(;c&&c!==p;)v=E(c),i(c),c=v;i(p)},ce=(c,p,v,S,T,w,O,$,P)=>{if(p.type==="svg"?O="svg":p.type==="math"&&(O="mathml"),c==null)Ee(p,v,S,T,w,O,$,P);else{const x=c.el&&c.el._isVueCE?c.el:null;try{x&&x._beginPatch(),D(c,p,T,w,O,$,P)}finally{x&&x._endPatch()}}},Ee=(c,p,v,S,T,w,O,$)=>{let P,x;const{props:L,shapeFlag:R,transition:U,dirs:H}=c;if(P=c.el=r(c.type,w,L&&L.is,L),R&8?d(P,c.children):R&16&&ue(c.children,P,null,S,T,Ws(c,w),O,$),H&&_t(c,null,S,"created"),Pe(P,c,c.scopeId,O,S),L){for(const se in L)se!=="value"&&!Gt(se)&&o(P,se,null,L[se],w,S);"value"in L&&o(P,"value",null,L.value,w),(x=L.onVnodeBeforeMount)&&We(x,S,c)}H&&_t(c,null,S,"beforeMount");const q=ra(T,U);q&&U.beforeEnter(P),n(P,p,v),((x=L&&L.onVnodeMounted)||q||H)&&Ce(()=>{try{x&&We(x,S,c),q&&U.enter(P),H&&_t(c,null,S,"mounted")}finally{}},T)},Pe=(c,p,v,S,T)=>{if(v&&C(c,v),S)for(let w=0;w{for(let x=P;x{const $=p.el=c.el;let{patchFlag:P,dynamicChildren:x,dirs:L}=p;P|=c.patchFlag&16;const R=c.props||ne,U=p.props||ne;let H;if(v&&wt(v,!1),(H=U.onVnodeBeforeUpdate)&&We(H,v,p,c),L&&_t(p,c,v,"beforeUpdate"),v&&wt(v,!0),x&&(!c.dynamicChildren||c.dynamicChildren.length!==x.length)&&(P=0,O=!1,x=null),(R.innerHTML&&U.innerHTML==null||R.textContent&&U.textContent==null)&&d($,""),x?I(c.dynamicChildren,x,$,v,S,Ws(p,T),w):O||ie(c,p,$,null,v,S,Ws(p,T),w,!1),P>0){if(P&16)A($,R,U,v,T);else if(P&2&&R.class!==U.class&&o($,"class",null,U.class,T),P&4&&o($,"style",R.style,U.style,T),P&8){const q=p.dynamicProps;for(let se=0;se{H&&We(H,v,p,c),L&&_t(p,c,v,"updated")},S)},I=(c,p,v,S,T,w,O)=>{for(let $=0;${if(p!==v){if(p!==ne)for(const w in p)!Gt(w)&&!(w in v)&&o(c,w,p[w],null,T,S);for(const w in v){if(Gt(w))continue;const O=v[w],$=p[w];O!==$&&w!=="value"&&o(c,w,$,O,T,S)}"value"in v&&o(c,"value",p.value,v.value,T)}},N=(c,p,v,S,T,w,O,$,P)=>{const x=p.el=c?c.el:a(""),L=p.anchor=c?c.anchor:a("");let{patchFlag:R,dynamicChildren:U,slotScopeIds:H}=p;H&&($=$?$.concat(H):H),c==null?(n(x,v,S),n(L,v,S),ue(p.children||[],v,L,T,w,O,$,P)):R>0&&R&64&&U&&c.dynamicChildren&&c.dynamicChildren.length===U.length?(I(c.dynamicChildren,U,v,T,w,O,$),(p.key!=null||T&&p===T.subTree)&&uo(c,p,!0)):ie(c,p,v,L,T,w,O,$,P)},le=(c,p,v,S,T,w,O,$,P)=>{p.slotScopeIds=$,c==null?p.shapeFlag&512?T.ctx.activate(p,v,S,O,P):st(p,v,S,T,w,O,P):as(c,p,P)},st=(c,p,v,S,T,w,O)=>{const $=c.component=ga(c,S,T);if(Zi(c)&&($.ctx.renderer=Nt),ba($,!1,O),$.asyncDep){if(T&&T.registerDep($,he,O),!c.el){const P=$.subTree=ee(gt);z(null,P,p,v),c.placeholder=P.el}}else he($,c,p,v,T,w,O)},as=(c,p,v)=>{const S=p.component=c.component;if(Jr(c,p,v))if(S.asyncDep&&!S.asyncResolved){J(S,p,v);return}else S.next=p,S.update();else p.el=c.el,S.vnode=p},he=(c,p,v,S,T,w,O)=>{const $=()=>{if(c.isMounted){let{next:R,bu:U,u:H,parent:q,vnode:se}=c;{const Ge=po(c);if(Ge){R&&(R.el=se.el,J(c,R,O)),Ge.asyncDep.then(()=>{Ce(()=>{c.isUnmounted||x()},T)});return}}let Q=R,pe;wt(c,!1),R?(R.el=se.el,J(c,R,O)):R=se,U&&hs(U),(pe=R.props&&R.props.onVnodeBeforeUpdate)&&We(pe,q,R,se),wt(c,!0);const be=Gn(c),Ve=c.subTree;c.subTree=be,k(Ve,be,b(Ve.el),cs(Ve),c,T,w),R.el=be.el,Q===null&&Yr(c,be.el),H&&Ce(H,T),(pe=R.props&&R.props.onVnodeUpdated)&&Ce(()=>We(pe,q,R,se),T)}else{let R;const{el:U,props:H}=p,{bm:q,m:se,parent:Q,root:pe,type:be}=c,Ve=Zt(p);wt(c,!1),q&&hs(q),!Ve&&(R=H&&H.onVnodeBeforeMount)&&We(R,Q,p),wt(c,!0);{pe.ce&&pe.ce._hasShadowRoot()&&pe.ce._injectChildStyle(be,c.parent?c.parent.type:void 0);const Ge=c.subTree=Gn(c);k(null,Ge,v,S,c,T,w),p.el=Ge.el}if(se&&Ce(se,T),!Ve&&(R=H&&H.onVnodeMounted)){const Ge=p;Ce(()=>We(R,Q,Ge),T)}(p.shapeFlag&256||Q&&Zt(Q.vnode)&&Q.vnode.shapeFlag&256)&&c.a&&Ce(c.a,T),c.isMounted=!0,p=v=S=null}};c.scope.on();const P=c.effect=new Si($);c.scope.off();const x=c.update=P.run.bind(P),L=c.job=P.runIfDirty.bind(P);L.i=c,L.id=c.uid,P.scheduler=()=>xn(L),wt(c,!0),x()},J=(c,p,v)=>{p.component=c;const S=c.vnode.props;c.vnode=p,c.next=null,Qr(c,p.props,S,v),na(c,p.children,v),et(),Mn(c),tt()},ie=(c,p,v,S,T,w,O,$,P=!1)=>{const x=c&&c.children,L=c?c.shapeFlag:0,R=p.children,{patchFlag:U,shapeFlag:H}=p;if(U>0){if(U&128){ls(x,R,v,S,T,w,O,$,P);return}else if(U&256){vt(x,R,v,S,T,w,O,$,P);return}}H&8?(L&16&&Mt(x,T,w),R!==x&&d(v,R)):L&16?H&16?ls(x,R,v,S,T,w,O,$,P):Mt(x,T,w,!0):(L&8&&d(v,""),H&16&&ue(R,v,S,T,w,O,$,P))},vt=(c,p,v,S,T,w,O,$,P)=>{c=c||Pt,p=p||Pt;const x=c.length,L=p.length,R=Math.min(x,L);let U;for(U=0;UL?Mt(c,T,w,!0,!1,R):ue(p,v,S,T,w,O,$,P,R)},ls=(c,p,v,S,T,w,O,$,P)=>{let x=0;const L=p.length;let R=c.length-1,U=L-1;for(;x<=R&&x<=U;){const H=c[x],q=p[x]=P?rt(p[x]):Je(p[x]);if(Bt(H,q))k(H,q,v,null,T,w,O,$,P);else break;x++}for(;x<=R&&x<=U;){const H=c[R],q=p[U]=P?rt(p[U]):Je(p[U]);if(Bt(H,q))k(H,q,v,null,T,w,O,$,P);else break;R--,U--}if(x>R){if(x<=U){const H=U+1,q=HU)for(;x<=R;)He(c[x],T,w,!0),x++;else{const H=x,q=x,se=new Map;for(x=q;x<=U;x++){const Oe=p[x]=P?rt(p[x]):Je(p[x]);Oe.key!=null&&se.set(Oe.key,x)}let Q,pe=0;const be=U-q+1;let Ve=!1,Ge=0;const Lt=new Array(be);for(x=0;x=be){He(Oe,T,w,!0);continue}let Ke;if(Oe.key!=null)Ke=se.get(Oe.key);else for(Q=q;Q<=U;Q++)if(Lt[Q-q]===0&&Bt(Oe,p[Q])){Ke=Q;break}Ke===void 0?He(Oe,T,w,!0):(Lt[Ke-q]=x+1,Ke>=Ge?Ge=Ke:Ve=!0,k(Oe,p[Ke],v,null,T,w,O,$,P),pe++)}const On=Ve?aa(Lt):Pt;for(Q=On.length-1,x=be-1;x>=0;x--){const Oe=q+x,Ke=p[Oe],Dn=p[Oe+1],Rn=Oe+1{const{el:w,type:O,transition:$,children:P,shapeFlag:x}=c;if(x&6){yt(c.component.subTree,p,v,S);return}if(x&128){c.suspense.move(p,v,S);return}if(x&64){O.move(c,p,v,Nt);return}if(O===re){n(w,p,v);for(let R=0;R$.enter(w),T));else{const{leave:R,delayLeave:U,afterLeave:H}=$,q=()=>{c.ctx.isUnmounted?i(w):n(w,p,v)},se=()=>{const Q=w._isLeaving||!!w[Gs];w._isLeaving&&w[Gs](!0),$.persisted&&!Q?q():R(w,()=>{q(),H&&H()})};U?U(w,q,se):se()}else n(w,p,v)},He=(c,p,v,S=!1,T=!1)=>{const{type:w,props:O,ref:$,children:P,dynamicChildren:x,shapeFlag:L,patchFlag:R,dirs:U,cacheIndex:H,memo:q}=c;if(R===-2&&(T=!1),$!=null&&(et(),qt($,null,v,c,!0),tt()),H!=null&&(p.renderCache[H]=void 0),L&256){p.ctx.deactivate(c);return}const se=L&1&&U,Q=!Zt(c);let pe;if(Q&&(pe=O&&O.onVnodeBeforeUnmount)&&We(pe,p,c),L&6)Ao(c.component,v,S);else{if(L&128){c.suspense.unmount(v,S);return}se&&_t(c,null,p,"beforeUnmount"),L&64?c.type.remove(c,p,v,Nt,S):x&&!x.hasOnce&&(w!==re||R>0&&R&64)?Mt(x,p,v,!1,!0):(w===re&&R&384||!T&&L&16)&&Mt(P,p,v),S&&An(c)}const be=q!=null&&H==null;(Q&&(pe=O&&O.onVnodeUnmounted)||se||be)&&Ce(()=>{pe&&We(pe,p,c),se&&_t(c,null,p,"unmounted"),be&&(c.el=null)},v)},An=c=>{const{type:p,el:v,anchor:S,transition:T}=c;if(p===re){Co(v,S);return}if(p===qs){j(c);return}const w=()=>{i(v),T&&!T.persisted&&T.afterLeave&&T.afterLeave()};if(c.shapeFlag&1&&T&&!T.persisted){const{leave:O,delayLeave:$}=T,P=()=>O(v,w);$?$(c.el,w,P):P()}else w()},Co=(c,p)=>{let v;for(;c!==p;)v=E(c),i(c),c=v;i(p)},Ao=(c,p,v)=>{const{bum:S,scope:T,job:w,subTree:O,um:$,m:P,a:x}=c;qn(P),qn(x),S&&hs(S),T.stop(),w&&(w.flags|=8,He(O,c,p,v)),$&&Ce($,p),Ce(()=>{c.isUnmounted=!0},p)},Mt=(c,p,v,S=!1,T=!1,w=0)=>{for(let O=w;O{if(c.shapeFlag&6)return cs(c.component.subTree);if(c.shapeFlag&128)return c.suspense.next();const p=E(c.anchor||c.el),v=p&&p[kr];return v?E(v):p};let Ms=!1;const $n=(c,p,v)=>{let S;c==null?p._vnode&&(He(p._vnode,null,null,!0),S=p._vnode.component):k(p._vnode||null,c,p,null,null,null,v),p._vnode=c,Ms||(Ms=!0,Mn(S),Hi(),Ms=!1)},Nt={p:k,um:He,m:yt,r:An,mt:st,mc:ue,pc:ie,pbc:I,n:cs,o:e};return{render:$n,hydrate:void 0,createApp:Vr($n)}}function Ws({type:e,props:t},s){return s==="svg"&&e==="foreignObject"||s==="mathml"&&e==="annotation-xml"&&t&&t.encoding&&t.encoding.includes("html")?void 0:s}function wt({effect:e,job:t},s){s?(e.flags|=32,t.flags|=4):(e.flags&=-33,t.flags&=-5)}function ra(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}function uo(e,t,s=!1){const n=e.children,i=t.children;if(F(n)&&F(i))for(let o=0;o>1,e[s[a]]0&&(t[n]=s[o-1]),s[o]=n)}}for(o=s.length,r=s[o-1];o-- >0;)s[o]=r,r=t[r];return s}function po(e){const t=e.subTree.component;if(t)return t.asyncDep&&!t.asyncResolved?t:po(t)}function qn(e){if(e)for(let t=0;te.__isSuspense;function la(e,t){t&&t.pendingBranch?F(e)?t.effects.push(...e):t.effects.push(e):br(e)}const re=Symbol.for("v-fgt"),js=Symbol.for("v-txt"),gt=Symbol.for("v-cmt"),qs=Symbol.for("v-stc"),Yt=[];let De=null;function y(e=!1){Yt.push(De=e?null:[])}function ca(){Yt.pop(),De=Yt[Yt.length-1]||null}let ss=1;function Zn(e,t=!1){ss+=e,e<0&&De&&t&&(De.hasOnce=!0)}function go(e){return e.dynamicChildren=ss>0?De||Pt:null,ca(),ss>0&&De&&De.push(e),e}function _(e,t,s,n,i,o){return go(u(e,t,s,n,i,o,!0))}function it(e,t,s,n,i){return go(ee(e,t,s,n,i,!0))}function mo(e){return e?e.__v_isVNode===!0:!1}function Bt(e,t){return e.type===t.type&&e.key===t.key}const bo=({key:e})=>e??null,ms=({ref:e,ref_key:t,ref_for:s})=>(typeof e=="number"&&(e=""+e),e!=null?de(e)||we(e)||W(e)?{i:je,r:e,k:t,f:!!s}:e:null);function u(e,t=null,s=null,n=0,i=null,o=e===re?0:1,r=!1,a=!1){const l={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&bo(t),ref:t&&ms(t),scopeId:Gi,slotScopeIds:null,children:s,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetStart:null,targetAnchor:null,staticCount:0,shapeFlag:o,patchFlag:n,dynamicProps:i,dynamicChildren:null,appContext:null,ctx:je};return a?(ks(l,s),o&128&&e.normalize(l)):s&&(l.shapeFlag|=de(s)?8:16),ss>0&&!r&&De&&(l.patchFlag>0||o&6)&&l.patchFlag!==32&&De.push(l),l}const ee=ua;function ua(e,t=null,s=null,n=0,i=null,o=!1){if((!e||e===jr)&&(e=gt),mo(e)){const a=Rt(e,t,!0);return s&&ks(a,s),ss>0&&!o&&De&&(a.shapeFlag&6?De[De.indexOf(e)]=a:De.push(a)),a.patchFlag=-2,a}if(wa(e)&&(e=e.__vccOpts),t){t=da(t);let{class:a,style:l}=t;a&&!de(a)&&(t.class=$e(a)),te(l)&&(wn(l)&&!F(l)&&(l=xe({},l)),t.style=fn(l))}const r=de(e)?1:ho(e)?128:Tr(e)?64:te(e)?4:W(e)?2:0;return u(e,t,s,n,i,r,o,!0)}function da(e){return e?wn(e)||io(e)?xe({},e):e:null}function Rt(e,t,s=!1,n=!1){const{props:i,ref:o,patchFlag:r,children:a,transition:l}=e,g=t?pa(i||{},t):i,d={__v_isVNode:!0,__v_skip:!0,type:e.type,props:g,key:g&&bo(g),ref:t&&t.ref?s&&o?F(o)?o.concat(ms(t)):[o,ms(t)]:ms(t):o,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:a,target:e.target,targetStart:e.targetStart,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==re?r===-1?16:r|16:r,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:l,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&Rt(e.ssContent),ssFallback:e.ssFallback&&Rt(e.ssFallback),placeholder:e.placeholder,el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce};return l&&n&&kn(d,l.clone(d)),d}function Re(e=" ",t=0){return ee(js,null,e,t)}function B(e="",t=!1){return t?(y(),it(gt,null,e)):ee(gt,null,e)}function Je(e){return e==null||typeof e=="boolean"?ee(gt):F(e)?ee(re,null,e.slice()):mo(e)?rt(e):ee(js,null,String(e))}function rt(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:Rt(e)}function ks(e,t){let s=0;const{shapeFlag:n}=e;if(t==null)t=null;else if(F(t))s=16;else if(typeof t=="object")if(n&65){const i=t.default;i&&(i._c&&(i._d=!1),ks(e,i()),i._c&&(i._d=!0));return}else{s=32;const i=t._;!i&&!io(t)?t._ctx=je:i===3&&je&&(je.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else if(W(t)){if(n&65){ks(e,{default:t});return}t={default:t,_ctx:je},s=32}else t=String(t),n&64?(s=16,t=[Re(t)]):s=8;e.children=t,e.shapeFlag|=s}function pa(...e){const t={};for(let s=0;sSe||je;let Ts,an;{const e=Os(),t=(s,n)=>{let i;return(i=e[s])||(i=e[s]=[]),i.push(n),o=>{i.length>1?i.forEach(r=>r(o)):i[0](o)}};Ts=t("__VUE_INSTANCE_SETTERS__",s=>Se=s),an=t("__VUE_SSR_SETTERS__",s=>ns=s)}const rs=e=>{const t=Se;return Ts(e),e.scope.on(),()=>{e.scope.off(),Ts(t)}},Jn=()=>{Se&&Se.scope.off(),Ts(null)};function vo(e){return e.vnode.shapeFlag&4}let ns=!1;function ba(e,t=!1,s=!1){t&&an(t);const{props:n,children:i}=e.vnode,o=vo(e);Xr(e,n,o,t),sa(e,i,s||t);const r=o?va(e,t):void 0;return t&&an(!1),r}function va(e,t){const s=e.type;e.accessCache=Object.create(null),e.proxy=new Proxy(e.ctx,Ur);const{setup:n}=s;if(n){et();const i=e.setupContext=n.length>1?_a(e):null,o=rs(e),r=os(n,e,0,[e.props,i]),a=bi(r);if(tt(),o(),(a||e.sp)&&!Zt(e)&&qi(e),a){if(r.then(Jn,Jn),t)return r.then(l=>{Yn(e,l)}).catch(l=>{Rs(l,e,0)});e.asyncDep=r}else Yn(e,r)}else yo(e)}function Yn(e,t,s){W(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:te(t)&&(e.setupState=Ni(t)),yo(e)}function yo(e,t,s){const n=e.type;e.render||(e.render=n.render||Xe);{const i=rs(e);et();try{Mr(e)}finally{tt(),i()}}}const ya={get(e,t){return _e(e,"get",""),e[t]}};function _a(e){const t=s=>{e.exposed=s||{}};return{attrs:new Proxy(e.attrs,ya),slots:e.slots,emit:e.emit,expose:t}}function Us(e){return e.exposed?e.exposeProxy||(e.exposeProxy=new Proxy(Ni(ar(e.exposed)),{get(t,s){if(s in t)return t[s];if(s in Jt)return Jt[s](e)},has(t,s){return s in t||s in Jt}})):e.proxy}function wa(e){return W(e)&&"__vccOpts"in e}const ze=(e,t)=>pr(e,t,ns),xa="3.5.39";/** +* @vue/runtime-dom v3.5.39 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/let ln;const Xn=typeof window<"u"&&window.trustedTypes;if(Xn)try{ln=Xn.createPolicy("vue",{createHTML:e=>e})}catch{}const _o=ln?e=>ln.createHTML(e):e=>e,ka="http://www.w3.org/2000/svg",Ta="http://www.w3.org/1998/Math/MathML",ot=typeof document<"u"?document:null,Qn=ot&&ot.createElement("template"),Sa={insert:(e,t,s)=>{t.insertBefore(e,s||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,s,n)=>{const i=t==="svg"?ot.createElementNS(ka,e):t==="mathml"?ot.createElementNS(Ta,e):s?ot.createElement(e,{is:s}):ot.createElement(e);return e==="select"&&n&&n.multiple!=null&&i.setAttribute("multiple",n.multiple),i},createText:e=>ot.createTextNode(e),createComment:e=>ot.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>ot.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,s,n,i,o){const r=s?s.previousSibling:t.lastChild;if(i&&(i===o||i.nextSibling))for(;t.insertBefore(i.cloneNode(!0),s),!(i===o||!(i=i.nextSibling)););else{Qn.innerHTML=_o(n==="svg"?`${e}`:n==="mathml"?`${e}`:e);const a=Qn.content;if(n==="svg"||n==="mathml"){const l=a.firstChild;for(;l.firstChild;)a.appendChild(l.firstChild);a.removeChild(l)}t.insertBefore(a,s)}return[r?r.nextSibling:t.firstChild,s?s.previousSibling:t.lastChild]}},Ea=Symbol("_vtc");function Pa(e,t,s){const n=e[Ea];n&&(t=(t?[t,...n]:[...n]).join(" ")),t==null?e.removeAttribute("class"):s?e.setAttribute("class",t):e.className=t}const ei=Symbol("_vod"),Ca=Symbol("_vsh"),Aa=Symbol(""),$a=/(?:^|;)\s*display\s*:/;function Oa(e,t,s){const n=e.style,i=de(s);let o=!1;if(s&&!i){if(t)if(de(t))for(const r of t.split(";")){const a=r.slice(0,r.indexOf(":")).trim();s[a]==null&&Vt(n,a,"")}else for(const r in t)s[r]==null&&Vt(n,r,"");for(const r in s){r==="display"&&(o=!0);const a=s[r];a!=null?Ra(e,r,!de(t)&&t?t[r]:void 0,a)||Vt(n,r,a):Vt(n,r,"")}}else if(i){if(t!==s){const r=n[Aa];r&&(s+=";"+r),n.cssText=s,o=$a.test(s)}}else t&&e.removeAttribute("style");ei in e&&(e[ei]=o?n.display:"",e[Ca]&&(n.display="none"))}const ti=/\s*!important$/;function Vt(e,t,s){if(F(s))s.forEach(n=>Vt(e,t,n));else if(s==null&&(s=""),t.startsWith("--"))e.setProperty(t,s);else{const n=Da(e,t);ti.test(s)?e.setProperty(bt(n),s.replace(ti,""),"important"):e[n]=s}}const si=["Webkit","Moz","ms"],Zs={};function Da(e,t){const s=Zs[t];if(s)return s;let n=Ne(t);if(n!=="filter"&&n in e)return Zs[t]=n;n=_i(n);for(let i=0;iJs||(Na.then(()=>Js=0),Js=Date.now());function Fa(e,t){const s=n=>{if(!n._vts)n._vts=Date.now();else if(n._vts<=s.attached)return;const i=s.value;if(F(i)){const o=n.stopImmediatePropagation;n.stopImmediatePropagation=()=>{o.call(n),n._stopped=!0};const r=i.slice(),a=[n];for(let l=0;le.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,Ba=(e,t,s,n,i,o)=>{const r=i==="svg";t==="class"?Pa(e,n,r):t==="style"?Oa(e,s,n):Ps(t)?Cs(t)||Ia(e,t,s,n,o):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):Ha(e,t,n,r))?(oi(e,t,n),!e.tagName.includes("-")&&(t==="value"||t==="checked"||t==="selected")&&ii(e,t,n,r,o,t!=="value")):e._isVueCE&&(Va(e,t)||e._def.__asyncLoader&&(/[A-Z]/.test(t)||!de(n)))?oi(e,Ne(t),n,o,t):(t==="true-value"?e._trueValue=n:t==="false-value"&&(e._falseValue=n),ii(e,t,n,r))};function Ha(e,t,s,n){if(n)return!!(t==="innerHTML"||t==="textContent"||t in e&&ai(t)&&W(s));if(t==="spellcheck"||t==="draggable"||t==="translate"||t==="autocorrect"||t==="sandbox"&&e.tagName==="IFRAME"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA")return!1;if(t==="width"||t==="height"){const i=e.tagName;if(i==="IMG"||i==="VIDEO"||i==="CANVAS"||i==="SOURCE")return!1}return ai(t)&&de(s)?!1:t in e}function Va(e,t){const s=e._def.props;if(!s)return!1;const n=Ne(t);return Array.isArray(s)?s.some(i=>Ne(i)===n):Object.keys(s).some(i=>Ne(i)===n)}const mt=e=>{const t=e.props["onUpdate:modelValue"]||!1;return F(t)?s=>hs(t,s):t};function Ga(e){e.target.composing=!0}function li(e){const t=e.target;t.composing&&(t.composing=!1,t.dispatchEvent(new Event("input")))}const Me=Symbol("_assign");function ci(e,t,s){return t&&(e=e.trim()),s&&(e=$s(e)),e}const ye={created(e,{modifiers:{lazy:t,trim:s,number:n}},i){e[Me]=mt(i);const o=n||i.props&&i.props.type==="number";ct(e,t?"change":"input",r=>{r.target.composing||e[Me](ci(e.value,s,o))}),(s||o)&&ct(e,"change",()=>{e.value=ci(e.value,s,o)}),t||(ct(e,"compositionstart",Ga),ct(e,"compositionend",li),ct(e,"change",li))},mounted(e,{value:t}){e.value=t??""},beforeUpdate(e,{value:t,oldValue:s,modifiers:{lazy:n,trim:i,number:o}},r){if(e[Me]=mt(r),e.composing)return;const a=(o||e.type==="number")&&!/^0\d/.test(e.value)?$s(e.value):e.value,l=t??"";if(a===l)return;const g=e.getRootNode();(g instanceof Document||g instanceof ShadowRoot)&&g.activeElement===e&&e.type!=="range"&&(n&&t===s||i&&e.value.trim()===l)||(e.value=l)}},Ka={deep:!0,created(e,t,s){e[Me]=mt(s),ct(e,"change",()=>{const n=e._modelValue,i=zt(e),o=e.checked,r=e[Me];if(F(n)){const a=hn(n,i),l=a!==-1;if(o&&!l)r(n.concat(i));else if(!o&&l){const g=[...n];g.splice(a,1),r(g)}}else if(Ut(n)){const a=new Set(n);o?a.add(i):a.delete(i),r(a)}else r(wo(e,o))})},mounted:ui,beforeUpdate(e,t,s){e[Me]=mt(s),ui(e,t,s)}};function ui(e,{value:t,oldValue:s},n){e._modelValue=t;let i;if(F(t))i=hn(t,n.props.value)>-1;else if(Ut(t))i=t.has(n.props.value);else{if(t===s)return;i=ht(t,wo(e,!0))}e.checked!==i&&(e.checked=i)}const Wa={created(e,{value:t},s){e.checked=ht(t,s.props.value),e[Me]=mt(s),ct(e,"change",()=>{e[Me](zt(e))})},beforeUpdate(e,{value:t,oldValue:s},n){e[Me]=mt(n),t!==s&&(e.checked=ht(t,n.props.value))}},Ss={deep:!0,created(e,{value:t,modifiers:{number:s}},n){const i=Ut(t);ct(e,"change",()=>{const o=Array.prototype.filter.call(e.options,r=>r.selected).map(r=>s?$s(zt(r)):zt(r));e[Me](e.multiple?i?new Set(o):o:o[0]),e._assigning=!0,Fi(()=>{e._assigning=!1})}),e[Me]=mt(n)},mounted(e,{value:t}){di(e,t)},beforeUpdate(e,t,s){e[Me]=mt(s)},updated(e,{value:t}){e._assigning||di(e,t)}};function di(e,t){const s=e.multiple,n=F(t);if(!(s&&!n&&!Ut(t))){for(let i=0,o=e.options.length;iString(g)===String(a)):r.selected=hn(t,a)>-1}else r.selected=t.has(a);else if(ht(zt(r),t)){e.selectedIndex!==i&&(e.selectedIndex=i);return}}!s&&e.selectedIndex!==-1&&(e.selectedIndex=-1)}}function zt(e){return"_value"in e?e._value:e.value}function wo(e,t){const s=t?"_trueValue":"_falseValue";return s in e?e[s]:t}const qa={created(e,t,s){fs(e,t,s,null,"created")},mounted(e,t,s){fs(e,t,s,null,"mounted")},beforeUpdate(e,t,s,n){fs(e,t,s,n,"beforeUpdate")},updated(e,t,s,n){fs(e,t,s,n,"updated")}};function Za(e,t){switch(e){case"SELECT":return Ss;case"TEXTAREA":return ye;default:switch(t){case"checkbox":return Ka;case"radio":return Wa;default:return ye}}}function fs(e,t,s,n,i){const r=Za(e.tagName,s.props&&s.props.type)[i];r&&r(e,t,s,n)}const Ja=["ctrl","shift","alt","meta"],Ya={stop:e=>e.stopPropagation(),prevent:e=>e.preventDefault(),self:e=>e.target!==e.currentTarget,ctrl:e=>!e.ctrlKey,shift:e=>!e.shiftKey,alt:e=>!e.altKey,meta:e=>!e.metaKey,left:e=>"button"in e&&e.button!==0,middle:e=>"button"in e&&e.button!==1,right:e=>"button"in e&&e.button!==2,exact:(e,t)=>Ja.some(s=>e[`${s}Key`]&&!t.includes(s))},Xa=(e,t)=>{if(!e)return e;const s=e._withMods||(e._withMods={}),n=t.join(".");return s[n]||(s[n]=((i,...o)=>{for(let r=0;r{const s=e._withKeys||(e._withKeys={}),n=t.join(".");return s[n]||(s[n]=(i=>{if(!("key"in i))return;const o=bt(i.key);if(t.some(r=>r===o||Qa[r]===o))return e(i)}))},el=xe({patchProp:Ba},Sa);let pi;function tl(){return pi||(pi=ia(el))}const sl=((...e)=>{const t=tl().createApp(...e),{mount:s}=t;return t.mount=n=>{const i=il(n);if(!i)return;const o=t._component;!W(o)&&!o.render&&!o.template&&(o.template=i.innerHTML),i.nodeType===1&&(i.textContent="");const r=s(i,!1,nl(i));return i instanceof Element&&(i.removeAttribute("v-cloak"),i.setAttribute("data-v-app","")),r},t});function nl(e){if(e instanceof SVGElement)return"svg";if(typeof MathMLElement=="function"&&e instanceof MathMLElement)return"mathml"}function il(e){return de(e)?document.querySelector(e):e}const ko="dh-panel-theme";function ol(){var e;try{const t=localStorage.getItem(ko);if(t==="dark"||t==="light")return t}catch{}return(e=window.matchMedia)!=null&&e.call(window,"(prefers-color-scheme: dark)").matches?"dark":"light"}const Ot=V(ol());function To(e){Ot.value=e,document.documentElement.classList.toggle("dark",e==="dark");try{localStorage.setItem(ko,e)}catch{}}function fi(){To(Ot.value==="dark"?"light":"dark")}To(Ot.value);const rl={apiServer:"API server",switchToLight:"Switch to light theme",switchToDark:"Switch to dark theme",theme:"Theme",signOut:"Sign out",loading:"Loading…",standardUserNote:"Signed in as a standard user — management sections need an admin role",footer:"DriverVault — car maintenance & service tracker."},al={overview:"Overview",users:"Users",orgs:"Organizations",server:"API Server",pocketbase:"PocketBase",webapp:"Web App",plugins:"Plugins",api:"API"},ll={title:"Sign in",subtitle:"Superadmin console for the DriverVault API Server.",email:"Email",password:"Password",submit:"Sign in",submitting:"Signing in…",invalid:"Invalid email or password.",failed:"Could not sign in.",authNote:"Authenticates against PocketBase through this server"},cl={title:"Status",unreachable:"unreachable",checking:"Checking…",apiServer:"API Server",pocketBase:"PocketBase",webApp:"Web App",thisProcess:"this process"},ul={create:"Create",save:"Save",cancel:"Cancel",edit:"Edit",delete:"Delete",rename:"Rename",empty:"—",name:"Name",email:"Email",role:"Role",organization:"Organization"},dl={title:"Users",allOrgs:"All organizations",yourOrg:"Your organization",newUser:"New user",password:"Password",passwordUnchanged:"Password (blank = unchanged)",passwordPlaceholder:"min 8 characters",orgNone:"— none —",you:"you",empty:"No users.",confirmDelete:"Delete {email}? This cannot be undone."},pl={title:"Organizations",subtitle:"Tenants users belong to",subtitleOwn:"Your organization",subtitleNone:"Create one to manage your own team",newOrg:"New organization",namePlaceholder:"Acme Fleet",empty:"No organizations yet.",createHint:"You have no organization yet. Create one to become its admin.",colId:"ID",confirmDelete:'Delete the organization "{name}"?',confirmDeleteOwn:'Delete your organization "{name}"? You will be removed from it and become a regular user.'},fl={title:"API Server",subtitle:"How this server identifies itself to the clients that connect to it",name:"Server name",nameHint:"Shown by clients that can be pointed at more than one DriverVault, such as the Web App's server switcher. Reported by /api/health.",saveApply:"Save & apply",persistedEnv:"persisted to .env",savedNotice:"Saved. The new name applies to the next request."},hl={title:"PocketBase",subtitle:"Database connection used by every endpoint",connected:"connected",noSuperuser:"no superuser",unreachable:"unreachable",baseUrl:"Base URL",superuserEmail:"Superuser email",superuserPassword:"Superuser password",passwordUnchanged:"unchanged",passwordNotSet:"not set",saveApply:"Save & apply",testConnection:"Test connection",persistedEnv:"persisted to .env",testOk:"Connection OK — superuser authenticated.",testReachableNoAuth:"PocketBase is reachable, but the service account did not authenticate.",testUnreachable:"PocketBase is not reachable at that address.",savedNotice:"Saved. The server is now using this PocketBase."},gl={title:"Web App",subtitle:"Address probed by the status check, and who may call this API from a browser",reachable:"reachable",unreachable:"unreachable",baseUrl:"Base URL",allowedOrigins:"Allowed origins",originsHint:"Comma separated, or {star} for any. Native mobile apps are not subject to CORS.",saveApply:"Save & apply",testConnection:"Test connection",persistedEnv:"persisted to .env",testOk:"Web App is reachable.",testFailed:"Web App did not answer its health check at that address.",savedNotice:"Saved. New origins apply to the next request."},ml={title:"Plugins",subtitle:"Third-party service integrations",categories:{vehicles:"Car manufacturers",chargers:"EV chargers",notifications:"Notifications","apis-external":"Other APIs","drives-external":"Remote drives","drives-local":"Local drives"},registerExternal:"Register external",cancelRegister:"Cancel",name:"Name",baseUrl:"Base URL",provider:"Provider",register:"Register",empty:"No plugins yet. Register an external one above, or compile a built-in connector.",builtin:"builtin",enabled:"enabled",disabled:"disabled",health:"Health",configure:"Configure",close:"Close",noConfig:"This plugin takes no configuration.",notSet:"Not set — let organizations and users choose",capabilities:"Capabilities",saved:"Saved.",checking:"Checking…",save:"Save",saveEnable:"Save & enable",disable:"Disable",remove:"Remove",builtinNote:"Built-in plugins can be disabled but not removed",confirmRemove:'Remove the external plugin "{name}"? Its saved config is deleted.'},bl={colEndpoint:"Endpoint",colDescription:"Description",authNone:"No auth",authBearer:"Bearer token",authManager:"Admin / superadmin",authSuperadmin:"Superadmin",authCharger:"Charger credentials",groupPublic:"Public",groupIdentity:"Identity",groupCars:"Cars",groupService:"Service records",groupTechnical:"Technical checks",groupParts:"Parts",groupFuel:"Fuel",groupCharging:"Charging",groupMaintenance:"Maintenance",groupDocuments:"Documents",groupReminders:"Reminders",groupAttachments:"Attachments",groupProviders:"Vehicle providers",groupIntegrations:"Integrations",groupOcpp:"OCPP",groupAccount:"Account",groupManagement:"Management",groupSuperadmin:"Superadmin"},vl={app:rl,sections:al,login:ll,status:cl,common:ul,users:dl,orgs:pl,server:fl,pocketbase:hl,webapp:gl,plugins:ml,api:bl},yl={apiServer:"Serwer API",switchToLight:"Przełącz na motyw jasny",switchToDark:"Przełącz na motyw ciemny",theme:"Motyw",signOut:"Wyloguj się",loading:"Ładowanie…",standardUserNote:"Zalogowano jako zwykły użytkownik — sekcje zarządzania wymagają roli administratora",footer:"DriverVault — rejestr serwisu i konserwacji samochodu."},_l={overview:"Przegląd",users:"Użytkownicy",orgs:"Organizacje",server:"Serwer API",pocketbase:"PocketBase",webapp:"Aplikacja webowa",plugins:"Wtyczki",api:"API"},wl={title:"Zaloguj się",subtitle:"Konsola superadministratora serwera API DriverVault.",email:"E-mail",password:"Hasło",submit:"Zaloguj się",submitting:"Logowanie…",invalid:"Nieprawidłowy e-mail lub hasło.",failed:"Nie udało się zalogować.",authNote:"Uwierzytelnia w PocketBase za pośrednictwem tego serwera"},xl={title:"Status",unreachable:"niedostępny",checking:"Sprawdzanie…",apiServer:"Serwer API",pocketBase:"PocketBase",webApp:"Aplikacja webowa",thisProcess:"ten proces"},kl={create:"Utwórz",save:"Zapisz",cancel:"Anuluj",edit:"Edytuj",delete:"Usuń",rename:"Zmień nazwę",empty:"—",name:"Nazwa",email:"E-mail",role:"Rola",organization:"Organizacja"},Tl={title:"Użytkownicy",allOrgs:"Wszystkie organizacje",yourOrg:"Twoja organizacja",newUser:"Nowy użytkownik",password:"Hasło",passwordUnchanged:"Hasło (puste = bez zmian)",passwordPlaceholder:"min. 8 znaków",orgNone:"— brak —",you:"Ty",empty:"Brak użytkowników.",confirmDelete:"Usunąć {email}? Tej operacji nie można cofnąć."},Sl={title:"Organizacje",subtitle:"Podmioty, do których należą użytkownicy",subtitleOwn:"Twoja organizacja",subtitleNone:"Utwórz ją, aby zarządzać własnym zespołem",newOrg:"Nowa organizacja",namePlaceholder:"Acme Fleet",empty:"Brak organizacji.",createHint:"Nie masz jeszcze organizacji. Utwórz ją, aby zostać jej administratorem.",colId:"ID",confirmDelete:"Usunąć organizację „{name}”?",confirmDeleteOwn:"Usunąć Twoją organizację „{name}”? Zostaniesz z niej usunięty i staniesz się zwykłym użytkownikiem."},El={title:"Serwer API",subtitle:"Jak ten serwer przedstawia się klientom, które się z nim łączą",name:"Nazwa serwera",nameHint:"Widoczna w klientach, które można skierować na więcej niż jeden DriverVault, na przykład w przełączniku serwerów aplikacji webowej. Zwracana przez /api/health.",saveApply:"Zapisz i zastosuj",persistedEnv:"zapisano w .env",savedNotice:"Zapisano. Nowa nazwa obowiązuje od następnego żądania."},Pl={title:"PocketBase",subtitle:"Połączenie z bazą danych używane przez każdy punkt końcowy",connected:"połączono",noSuperuser:"brak superużytkownika",unreachable:"niedostępny",baseUrl:"Adres bazowy",superuserEmail:"E-mail superużytkownika",superuserPassword:"Hasło superużytkownika",passwordUnchanged:"bez zmian",passwordNotSet:"nie ustawiono",saveApply:"Zapisz i zastosuj",testConnection:"Testuj połączenie",persistedEnv:"zapisano w .env",testOk:"Połączenie OK — superużytkownik uwierzytelniony.",testReachableNoAuth:"PocketBase jest dostępny, ale konto usługowe nie zostało uwierzytelnione.",testUnreachable:"PocketBase jest niedostępny pod tym adresem.",savedNotice:"Zapisano. Serwer korzysta teraz z tego PocketBase."},Cl={title:"Aplikacja webowa",subtitle:"Adres sprawdzany podczas kontroli statusu oraz kto może wywoływać to API z przeglądarki",reachable:"dostępna",unreachable:"niedostępna",baseUrl:"Adres bazowy",allowedOrigins:"Dozwolone źródła",originsHint:"Oddzielone przecinkami lub {star} dla dowolnego. Natywne aplikacje mobilne nie podlegają CORS.",saveApply:"Zapisz i zastosuj",testConnection:"Testuj połączenie",persistedEnv:"zapisano w .env",testOk:"Aplikacja webowa jest dostępna.",testFailed:"Aplikacja webowa nie odpowiedziała na kontrolę stanu pod tym adresem.",savedNotice:"Zapisano. Nowe źródła obowiązują od następnego żądania."},Al={title:"Wtyczki",subtitle:"Integracje z usługami zewnętrznymi",categories:{vehicles:"Producenci samochodów",chargers:"Ładowarki EV",notifications:"Powiadomienia","apis-external":"Pozostałe API","drives-external":"Dyski zdalne","drives-local":"Dyski lokalne"},registerExternal:"Zarejestruj zewnętrzną",cancelRegister:"Anuluj",name:"Nazwa",baseUrl:"Adres bazowy",provider:"Dostawca",register:"Zarejestruj",empty:"Brak wtyczek. Zarejestruj zewnętrzną powyżej lub skompiluj wbudowany łącznik.",builtin:"wbudowana",enabled:"włączona",disabled:"wyłączona",health:"Stan",configure:"Konfiguruj",close:"Zamknij",noConfig:"Ta wtyczka nie wymaga konfiguracji.",notSet:"Nie ustawiono — pozwól organizacjom i użytkownikom wybrać",capabilities:"Możliwości",saved:"Zapisano.",checking:"Sprawdzanie…",save:"Zapisz",saveEnable:"Zapisz i włącz",disable:"Wyłącz",remove:"Usuń",builtinNote:"Wtyczki wbudowane można wyłączyć, ale nie usunąć",confirmRemove:"Usunąć zewnętrzną wtyczkę „{name}”? Jej zapisana konfiguracja zostanie usunięta."},$l={colEndpoint:"Punkt końcowy",colDescription:"Opis",authNone:"Bez uwierzytelniania",authBearer:"Token Bearer",authManager:"Administrator / superadministrator",authSuperadmin:"Superadministrator",authCharger:"Dane logowania ładowarki",groupPublic:"Publiczne",groupIdentity:"Tożsamość",groupCars:"Samochody",groupService:"Wpisy serwisowe",groupTechnical:"Przeglądy techniczne",groupParts:"Części",groupFuel:"Paliwo",groupCharging:"Ładowanie",groupMaintenance:"Naprawy",groupDocuments:"Dokumenty",groupReminders:"Przypomnienia",groupAttachments:"Załączniki",groupProviders:"Dostawcy pojazdów",groupIntegrations:"Integracje",groupOcpp:"OCPP",groupAccount:"Konto",groupManagement:"Zarządzanie",groupSuperadmin:"Superadministrator"},Ol={app:yl,sections:_l,login:wl,status:xl,common:kl,users:Tl,orgs:Sl,server:El,pocketbase:Pl,webapp:Cl,plugins:Al,api:$l},Dl={apiServer:"API-server",switchToLight:"Skift til lyst tema",switchToDark:"Skift til mørkt tema",theme:"Tema",signOut:"Log ud",loading:"Indlæser…",standardUserNote:"Logget ind som almindelig bruger — administrationssektioner kræver en administratorrolle",footer:"DriverVault — bilservice- og vedligeholdelsesregister."},Rl={overview:"Oversigt",users:"Brugere",orgs:"Organisationer",server:"API-server",pocketbase:"PocketBase",webapp:"Webapp",plugins:"Plugins",api:"API"},zl={title:"Log ind",subtitle:"Superadmin-konsol til DriverVault API-serveren.",email:"E-mail",password:"Adgangskode",submit:"Log ind",submitting:"Logger ind…",invalid:"Ugyldig e-mail eller adgangskode.",failed:"Kunne ikke logge ind.",authNote:"Godkender mod PocketBase gennem denne server"},Il={title:"Status",unreachable:"utilgængelig",checking:"Tjekker…",apiServer:"API-server",pocketBase:"PocketBase",webApp:"Webapp",thisProcess:"denne proces"},jl={create:"Opret",save:"Gem",cancel:"Annuller",edit:"Rediger",delete:"Slet",rename:"Omdøb",empty:"—",name:"Navn",email:"E-mail",role:"Rolle",organization:"Organisation"},Ul={title:"Brugere",allOrgs:"Alle organisationer",yourOrg:"Din organisation",newUser:"Ny bruger",password:"Adgangskode",passwordUnchanged:"Adgangskode (tom = uændret)",passwordPlaceholder:"mindst 8 tegn",orgNone:"— ingen —",you:"dig",empty:"Ingen brugere.",confirmDelete:"Slet {email}? Dette kan ikke fortrydes."},Ml={title:"Organisationer",subtitle:"Enheder, som brugere tilhører",subtitleOwn:"Din organisation",subtitleNone:"Opret en for at administrere dit eget team",newOrg:"Ny organisation",namePlaceholder:"Acme Fleet",empty:"Ingen organisationer endnu.",createHint:"Du har endnu ingen organisation. Opret en for at blive dens administrator.",colId:"ID",confirmDelete:'Slet organisationen "{name}"?',confirmDeleteOwn:"Slet din organisation „{name}“? Du fjernes fra den og bliver en almindelig bruger."},Nl={title:"API-server",subtitle:"Hvordan denne server identificerer sig over for de klienter, der forbinder til den",name:"Servernavn",nameHint:"Vises af klienter, der kan pege på mere end én DriverVault, for eksempel webappens serverskifter. Returneres af /api/health.",saveApply:"Gem og anvend",persistedEnv:"gemt i .env",savedNotice:"Gemt. Det nye navn gælder fra næste anmodning."},Ll={title:"PocketBase",subtitle:"Databaseforbindelse brugt af hvert endpoint",connected:"forbundet",noSuperuser:"ingen superbruger",unreachable:"utilgængelig",baseUrl:"Basis-URL",superuserEmail:"Superbrugerens e-mail",superuserPassword:"Superbrugerens adgangskode",passwordUnchanged:"uændret",passwordNotSet:"ikke angivet",saveApply:"Gem og anvend",testConnection:"Test forbindelse",persistedEnv:"gemt i .env",testOk:"Forbindelse OK — superbruger godkendt.",testReachableNoAuth:"PocketBase er tilgængelig, men servicekontoen blev ikke godkendt.",testUnreachable:"PocketBase er ikke tilgængelig på den adresse.",savedNotice:"Gemt. Serveren bruger nu denne PocketBase."},Fl={title:"Webapp",subtitle:"Adressen, der tjekkes ved statuskontrol, og hvem der må kalde dette API fra en browser",reachable:"tilgængelig",unreachable:"utilgængelig",baseUrl:"Basis-URL",allowedOrigins:"Tilladte oprindelser",originsHint:"Kommasepareret, eller {star} for enhver. Native mobilapps er ikke underlagt CORS.",saveApply:"Gem og anvend",testConnection:"Test forbindelse",persistedEnv:"gemt i .env",testOk:"Webappen er tilgængelig.",testFailed:"Webappen svarede ikke på sit helbredstjek på den adresse.",savedNotice:"Gemt. Nye oprindelser gælder fra næste anmodning."},Bl={title:"Plugins",subtitle:"Integrationer med tredjepartstjenester",categories:{vehicles:"Bilproducenter",chargers:"EV-ladere",notifications:"Notifikationer","apis-external":"Øvrige API'er","drives-external":"Eksterne drev","drives-local":"Lokale drev"},registerExternal:"Registrér ekstern",cancelRegister:"Annuller",name:"Navn",baseUrl:"Basis-URL",provider:"Udbyder",register:"Registrér",empty:"Ingen plugins endnu. Registrér et eksternt ovenfor, eller kompilér et indbygget stik.",builtin:"indbygget",enabled:"aktiveret",disabled:"deaktiveret",health:"Helbred",configure:"Konfigurer",close:"Luk",noConfig:"Dette plugin kræver ingen konfiguration.",notSet:"Ikke angivet — lad organisationer og brugere vælge",capabilities:"Funktioner",saved:"Gemt.",checking:"Tjekker…",save:"Gem",saveEnable:"Gem og aktivér",disable:"Deaktiver",remove:"Fjern",builtinNote:"Indbyggede plugins kan deaktiveres, men ikke fjernes",confirmRemove:'Fjern det eksterne plugin "{name}"? Dets gemte konfiguration slettes.'},Hl={colEndpoint:"Endpoint",colDescription:"Beskrivelse",authNone:"Ingen godkendelse",authBearer:"Bearer-token",authManager:"Admin / superadmin",authSuperadmin:"Superadmin",authCharger:"Laderens loginoplysninger",groupPublic:"Offentlig",groupIdentity:"Identitet",groupCars:"Biler",groupService:"Serviceposter",groupTechnical:"Syn",groupParts:"Reservedele",groupFuel:"Brændstof",groupCharging:"Opladning",groupMaintenance:"Værksted",groupDocuments:"Dokumenter",groupReminders:"Påmindelser",groupAttachments:"Vedhæftede filer",groupProviders:"Køretøjsudbydere",groupIntegrations:"Integrationer",groupOcpp:"OCPP",groupAccount:"Konto",groupManagement:"Administration",groupSuperadmin:"Superadmin"},Vl={app:Dl,sections:Rl,login:zl,status:Il,common:jl,users:Ul,orgs:Ml,server:Nl,pocketbase:Ll,webapp:Fl,plugins:Bl,api:Hl},So="dh-panel-lang",Eo="en",It={en:vl,pl:Ol,da:Vl},Gl=Object.keys(It);function Kl(){try{const t=localStorage.getItem(So);if(t&&It[t])return t}catch{}const e=(navigator.language||"en").split("-")[0];return It[e]?e:Eo}const Pn=V(Kl());function Wl(e){if(It[e]){Pn.value=e;try{localStorage.setItem(So,e)}catch{}}}function hi(e,t){return t.split(".").reduce((s,n)=>s==null?void 0:s[n],e)}function ql(e,t){return t?e.replace(/\{(\w+)\}/g,(s,n)=>t[n]==null?s:String(t[n])):e}function Zl(e,t,s){let n="other";try{n=new Intl.PluralRules(s).select(t)}catch{n=t===1?"one":"other"}return e[n]??e.other??e.one}function f(e,t){const s=Pn.value;let n=hi(It[s],e);if(n==null&&(n=hi(It[Eo],e)),n==null)return e;if(typeof n=="object"){if((t==null?void 0:t.n)==null)return e;n=Zl(n,t.n,s)}return typeof n!="string"?e:ql(n,t)}function gi(e,t,s){const i=f(e,{...s,[t]:"\0"}),o=i.indexOf("\0");return o===-1?{before:i,after:""}:{before:i.slice(0,o),after:i.slice(o+1)}}const cn="dh-panel-token";function Jl(){try{return localStorage.getItem(cn)||""}catch{return""}}const jt=V(Jl()),me=V(null),Ie=ze(()=>{var e;return((e=me.value)==null?void 0:e.role)==="superadmin"}),bs=ze(()=>{var e,t;return((e=me.value)==null?void 0:e.role)==="admin"||((t=me.value)==null?void 0:t.role)==="superadmin"});function Po(e){jt.value=e;try{e?localStorage.setItem(cn,e):localStorage.removeItem(cn)}catch{}}class Yl extends Error{constructor(t,s,n){super(t),this.status=s,this.body=n}}function Xl(e,t){if(!e||typeof e!="object")return`HTTP ${t}`;if(e.error)return e.error;const s=Object.entries(e.data||{}).map(([n,i])=>`${n}: ${(i==null?void 0:i.message)||i}`).filter(Boolean);return s.length?s.join("; "):e.message||`HTTP ${t}`}async function ae(e,{method:t="GET",body:s,auth:n=!0}={}){const i={};s!==void 0&&(i["Content-Type"]="application/json"),n&&jt.value&&(i.Authorization=jt.value);const o=await fetch(e,{method:t,headers:i,body:s===void 0?void 0:JSON.stringify(s)}),r=await o.text();let a=null;try{a=r?JSON.parse(r):null}catch{a=null}if(!o.ok)throw o.status===401&&n&&Cn(),new Yl(Xl(a,o.status),o.status,a);return a}async function Ql(e,t){const s=await ae("/api/auth/login",{method:"POST",body:{email:e,password:t},auth:!1});return Po(s.token),await Es(),me.value}async function Es(){return me.value=await ae("/api/identity"),me.value}function Cn(){Po(""),me.value=null}async function ec(){if(!jt.value)return null;try{return await Es()}catch{return Cn(),null}}const tc={class:"inline-flex items-center gap-2.5 select-none"},sc={class:"h-full w-auto shrink-0",viewBox:"0 0 48 48",fill:"none","aria-hidden":"true"},nc={transform:"translate(7 0) skewX(-13)"},ic=["fill"],oc=["fill"],rc=["fill"],ac={key:0,class:"text-[1.35em] font-extrabold italic leading-none tracking-[-0.03em]"},lc={__name:"Logo",props:{iconOnly:{type:Boolean,default:!1},onDark:{type:Boolean,default:!1}},setup(e){return(t,s)=>(y(),_("span",tc,[(y(),_("svg",sc,[u("g",nc,[u("rect",{x:"9",y:"16",width:"6",height:"16",rx:"3",fill:e.onDark?"#60A5FA":"var(--brand-700)"},null,8,ic),u("rect",{x:"19",y:"12",width:"6",height:"24",rx:"3",fill:e.onDark?"#93C5FD":"var(--brand-500)"},null,8,oc),u("rect",{x:"29",y:"8",width:"6",height:"32",rx:"3",fill:e.onDark?"#ffffff":"var(--brand-400)"},null,8,rc)])])),e.iconOnly?B("",!0):(y(),_("span",ac,[u("span",{class:$e(e.onDark?"text-white":"text-strong")},"Driver",2),u("span",{class:$e(e.onDark?"text-brand-400":"text-brandtext")},"Vault",2)])),s[0]||(s[0]=u("span",{class:"sr-only"},"DriverVault",-1))]))}},cc={class:"mx-auto flex w-full max-w-sm flex-col gap-5 pt-24"},uc={class:"dh-card p-6"},dc={class:"text-lg font-bold tracking-[-0.02em] text-strong"},pc={class:"mt-1 mb-5 text-sm text-body"},fc={class:"dh-label",for:"login-email"},hc={class:"dh-label",for:"login-password"},gc={key:0,class:"rounded-control bg-danger-soft px-3 py-2 text-xs text-danger"},mc=["disabled"],bc={class:"eyebrow text-center"},vc={__name:"LoginView",emits:["authenticated"],setup(e,{emit:t}){const s=t,n=V(""),i=V(""),o=V(""),r=V(!1),a=ze(()=>n.value.trim()!==""&&i.value!==""&&!r.value);async function l(){if(a.value){o.value="",r.value=!0;try{const g=await Ql(n.value.trim(),i.value);s("authenticated",g)}catch(g){o.value=g.status===400||g.status===404?f("login.invalid"):g.message||f("login.failed"),i.value=""}finally{r.value=!1}}}return(g,d)=>(y(),_("div",cc,[u("div",uc,[u("h1",dc,m(h(f)("login.title")),1),u("p",pc,m(h(f)("login.subtitle")),1),u("form",{class:"flex flex-col gap-4",onSubmit:Xa(l,["prevent"])},[u("div",null,[u("label",fc,m(h(f)("login.email")),1),fe(u("input",{id:"login-email","onUpdate:modelValue":d[0]||(d[0]=b=>n.value=b),class:"dh-input",type:"email",autocomplete:"username",autofocus:"",placeholder:"you@example.com"},null,512),[[ye,n.value]])]),u("div",null,[u("label",hc,m(h(f)("login.password")),1),fe(u("input",{id:"login-password","onUpdate:modelValue":d[1]||(d[1]=b=>i.value=b),class:"dh-input",type:"password",autocomplete:"current-password",placeholder:"••••••••"},null,512),[[ye,i.value]])]),o.value?(y(),_("p",gc,m(o.value),1)):B("",!0),u("button",{class:"dh-btn w-full",type:"submit",disabled:!a.value},m(r.value?h(f)("login.submitting"):h(f)("login.submit")),9,mc)],32)]),u("p",bc,m(h(f)("login.authNote")),1)]))}},yc={class:"dh-card overflow-hidden"},_c={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},wc={class:"text-base font-bold tracking-[-0.02em] text-strong"},xc={key:0,class:"dh-pill bg-danger-soft text-danger"},kc={key:0,class:"px-5 py-4 text-sm text-danger"},Tc={key:1,class:"w-full text-left text-sm"},Sc={class:"px-5 py-3 font-medium text-strong"},Ec={class:"data px-5 py-3 text-xs text-muted"},Pc={class:"data px-5 py-3 text-right text-xs text-muted"},Cc={class:"px-5 py-3 text-right"},Ac={key:2,class:"px-5 py-4 text-sm text-muted"},$c={__name:"StatusCard",setup(e){const t=V(null),s=V("");let n=null;async function i(){try{t.value=await ae("/api/status",{auth:!1}),s.value=""}catch(a){t.value=null,s.value=a.message||f("status.unreachable")}}const o=ze(()=>{var a,l,g;return[{key:"apiServer",label:f("status.apiServer"),h:(a=t.value)==null?void 0:a.apiServer},{key:"pocketBase",label:f("status.pocketBase"),h:(l=t.value)==null?void 0:l.pocketBase},{key:"webApp",label:f("status.webApp"),h:(g=t.value)==null?void 0:g.webApp}]});pt(()=>{i(),n=setInterval(i,1e4)}),Tn(()=>clearInterval(n));const r=a=>a==="ok"?"bg-success-soft text-success":"bg-danger-soft text-danger";return(a,l)=>(y(),_("div",yc,[u("div",_c,[u("div",wc,m(h(f)("status.title")),1),s.value?(y(),_("span",xc,[l[0]||(l[0]=u("span",{class:"h-1.5 w-1.5 rounded-full bg-current"},null,-1)),Re(m(h(f)("status.unreachable")),1)])):B("",!0)]),s.value?(y(),_("div",kc,m(s.value),1)):t.value?(y(),_("table",Tc,[u("tbody",null,[(y(!0),_(re,null,Ae(o.value,g=>(y(),_("tr",{key:g.key,class:"border-t border-subtle first:border-t-0"},[u("td",Sc,m(g.label),1),u("td",Ec,m(g.h.url||h(f)("status.thisProcess")),1),u("td",Pc,m(g.h.latencyMs!=null?g.h.latencyMs+"ms":h(f)("common.empty")),1),u("td",Cc,[u("span",{class:$e(["dh-pill",r(g.h.status)])},[l[1]||(l[1]=u("span",{class:"h-1.5 w-1.5 rounded-full bg-current"},null,-1)),Re(m(g.h.status),1)],2)])]))),128))])])):(y(),_("div",Ac,m(h(f)("status.checking")),1))]))}},Oc={class:"dh-card overflow-hidden"},Dc={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},Rc={class:"text-base font-bold tracking-[-0.02em] text-strong"},zc={class:"mt-0.5 text-xs text-muted"},Ic={class:"flex flex-col gap-4 px-5 py-4"},jc={class:"dh-label",for:"pb-url"},Uc={class:"grid gap-4 sm:grid-cols-2"},Mc={class:"dh-label",for:"pb-email"},Nc={class:"dh-label",for:"pb-password"},Lc=["placeholder"],Fc={key:0,class:"data text-xs text-muted"},Bc={key:1,class:"rounded-control bg-info-soft px-3 py-2 text-xs text-info"},Hc={key:2,class:"rounded-control bg-danger-soft px-3 py-2 text-xs text-danger"},Vc={class:"flex items-center gap-2"},Gc=["disabled"],Kc=["disabled"],Wc={class:"eyebrow"},qc={__name:"PocketBaseCard",setup(e){const t=V(null),s=V({url:"",adminEmail:"",adminPassword:""}),n=V(null),i=V(""),o=V(""),r=V(!1);async function a(){try{t.value=await ae("/api/admin/pb-config"),s.value={url:t.value.url,adminEmail:t.value.adminEmail,adminPassword:""},n.value=t.value.probe}catch(d){i.value=d.message}}pt(a);async function l(){i.value="",o.value="",r.value=!0;try{n.value=await ae("/api/admin/pb-config/test",{method:"POST",body:s.value}),o.value=n.value.superuser?f("pocketbase.testOk"):n.value.reachable?f("pocketbase.testReachableNoAuth"):f("pocketbase.testUnreachable")}catch(d){i.value=d.message}finally{r.value=!1}}async function g(){i.value="",o.value="",r.value=!0;try{const d=await ae("/api/admin/pb-config",{method:"PUT",body:s.value});t.value=d.config,n.value=d.config.probe,s.value.adminPassword="",o.value=d.warning||f("pocketbase.savedNotice")}catch(d){i.value=d.message}finally{r.value=!1}}return(d,b)=>{var E,C;return y(),_("div",Oc,[u("div",Dc,[u("div",null,[u("div",Rc,m(h(f)("pocketbase.title")),1),u("p",zc,m(h(f)("pocketbase.subtitle")),1)]),n.value?(y(),_("span",{key:0,class:$e(["dh-pill",n.value.superuser?"bg-success-soft text-success":n.value.reachable?"bg-warning-soft text-warning":"bg-danger-soft text-danger"])},[b[3]||(b[3]=u("span",{class:"h-1.5 w-1.5 rounded-full bg-current"},null,-1)),Re(" "+m(n.value.superuser?h(f)("pocketbase.connected"):n.value.reachable?h(f)("pocketbase.noSuperuser"):h(f)("pocketbase.unreachable")),1)],2)):B("",!0)]),u("div",Ic,[u("div",null,[u("label",jc,m(h(f)("pocketbase.baseUrl")),1),fe(u("input",{id:"pb-url","onUpdate:modelValue":b[0]||(b[0]=G=>s.value.url=G),class:"dh-input",placeholder:"http://10.2.1.10:8027"},null,512),[[ye,s.value.url]])]),u("div",Uc,[u("div",null,[u("label",Mc,m(h(f)("pocketbase.superuserEmail")),1),fe(u("input",{id:"pb-email","onUpdate:modelValue":b[1]||(b[1]=G=>s.value.adminEmail=G),class:"dh-input",autocomplete:"off"},null,512),[[ye,s.value.adminEmail]])]),u("div",null,[u("label",Nc,m(h(f)("pocketbase.superuserPassword")),1),fe(u("input",{id:"pb-password","onUpdate:modelValue":b[2]||(b[2]=G=>s.value.adminPassword=G),class:"dh-input",type:"password",autocomplete:"new-password",placeholder:(E=t.value)!=null&&E.adminConfigured?h(f)("pocketbase.passwordUnchanged"):h(f)("pocketbase.passwordNotSet")},null,8,Lc),[[ye,s.value.adminPassword]])])]),(C=n.value)!=null&&C.detail?(y(),_("p",Fc,m(n.value.detail),1)):B("",!0),o.value?(y(),_("p",Bc,m(o.value),1)):B("",!0),i.value?(y(),_("p",Hc,m(i.value),1)):B("",!0),u("div",Vc,[u("button",{class:"dh-btn",disabled:r.value,onClick:g},m(h(f)("pocketbase.saveApply")),9,Gc),u("button",{class:"dh-btn-ghost",disabled:r.value,onClick:l},m(h(f)("pocketbase.testConnection")),9,Kc),b[4]||(b[4]=u("span",{class:"flex-1"},null,-1)),u("span",Wc,m(h(f)("pocketbase.persistedEnv")),1)])])])}}},Zc={class:"dh-card overflow-hidden"},Jc={class:"border-b border-subtle px-5 py-4"},Yc={class:"text-base font-bold tracking-[-0.02em] text-strong"},Xc={class:"mt-0.5 text-xs text-muted"},Qc={class:"flex flex-col gap-4 px-5 py-4"},eu={class:"dh-label",for:"server-name"},tu={class:"mt-1 text-xs text-muted"},su={key:0,class:"rounded-control bg-info-soft px-3 py-2 text-xs text-info"},nu={key:1,class:"rounded-control bg-danger-soft px-3 py-2 text-xs text-danger"},iu={class:"flex items-center gap-2"},ou=["disabled"],ru={class:"eyebrow"},au={__name:"ServerCard",setup(e){const t=V({name:""}),s=V(""),n=V(""),i=V(!1);async function o(){try{const a=await ae("/api/admin/server-config");t.value={name:a.name}}catch(a){s.value=a.message}}pt(o);async function r(){s.value="",n.value="",i.value=!0;try{const a=await ae("/api/admin/server-config",{method:"PUT",body:{name:t.value.name}});t.value={name:a.config.name},n.value=a.warning||f("server.savedNotice")}catch(a){s.value=a.message}finally{i.value=!1}}return(a,l)=>(y(),_("div",Zc,[u("div",Jc,[u("div",Yc,m(h(f)("server.title")),1),u("p",Xc,m(h(f)("server.subtitle")),1)]),u("div",Qc,[u("div",null,[u("label",eu,m(h(f)("server.name")),1),fe(u("input",{id:"server-name","onUpdate:modelValue":l[0]||(l[0]=g=>t.value.name=g),class:"dh-input",maxlength:"64",placeholder:"DriverVault API Server",onKeyup:xo(r,["enter"])},null,544),[[ye,t.value.name]]),u("p",tu,m(h(f)("server.nameHint")),1)]),n.value?(y(),_("p",su,m(n.value),1)):B("",!0),s.value?(y(),_("p",nu,m(s.value),1)):B("",!0),u("div",iu,[u("button",{class:"dh-btn",disabled:i.value,onClick:r},m(h(f)("server.saveApply")),9,ou),l[1]||(l[1]=u("span",{class:"flex-1"},null,-1)),u("span",ru,m(h(f)("server.persistedEnv")),1)])])]))}},lu={class:"dh-card overflow-hidden"},cu={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},uu={class:"text-base font-bold tracking-[-0.02em] text-strong"},du={class:"mt-0.5 text-xs text-muted"},pu={class:"flex flex-col gap-4 px-5 py-4"},fu={class:"dh-label",for:"web-url"},hu={class:"dh-label",for:"web-origins"},gu={class:"mt-1 text-xs text-muted"},mu={key:0,class:"data text-xs text-muted"},bu={key:1,class:"rounded-control bg-info-soft px-3 py-2 text-xs text-info"},vu={key:2,class:"rounded-control bg-danger-soft px-3 py-2 text-xs text-danger"},yu={class:"flex items-center gap-2"},_u=["disabled"],wu=["disabled"],xu={class:"eyebrow"},ku={__name:"WebAppCard",setup(e){const t=V(null),s=V({url:"",origins:""}),n=V(null),i=V(""),o=V(""),r=V(!1),a=E=>E.split(",").map(C=>C.trim()).filter(Boolean);function l(E){t.value=E,s.value={url:E.url,origins:(E.allowOrigins||[]).join(", ")},n.value=E.probe}async function g(){try{l(await ae("/api/admin/webapp-config"))}catch(E){i.value=E.message}}pt(g);async function d(){i.value="",o.value="",r.value=!0;try{n.value=await ae("/api/admin/webapp-config/test",{method:"POST",body:{url:s.value.url}}),o.value=n.value.status==="ok"?f("webapp.testOk"):f("webapp.testFailed")}catch(E){i.value=E.message}finally{r.value=!1}}async function b(){i.value="",o.value="",r.value=!0;try{const E=await ae("/api/admin/webapp-config",{method:"PUT",body:{url:s.value.url,allowOrigins:a(s.value.origins)}});l(E.config),o.value=E.warning||f("webapp.savedNotice")}catch(E){i.value=E.message}finally{r.value=!1}}return(E,C)=>{var G;return y(),_("div",lu,[u("div",cu,[u("div",null,[u("div",uu,m(h(f)("webapp.title")),1),u("p",du,m(h(f)("webapp.subtitle")),1)]),n.value?(y(),_("span",{key:0,class:$e(["dh-pill",n.value.status==="ok"?"bg-success-soft text-success":"bg-danger-soft text-danger"])},[C[2]||(C[2]=u("span",{class:"h-1.5 w-1.5 rounded-full bg-current"},null,-1)),Re(" "+m(n.value.status==="ok"?h(f)("webapp.reachable"):h(f)("webapp.unreachable")),1)],2)):B("",!0)]),u("div",pu,[u("div",null,[u("label",fu,m(h(f)("webapp.baseUrl")),1),fe(u("input",{id:"web-url","onUpdate:modelValue":C[0]||(C[0]=k=>s.value.url=k),class:"dh-input",placeholder:"http://localhost:8090"},null,512),[[ye,s.value.url]])]),u("div",null,[u("label",hu,m(h(f)("webapp.allowedOrigins")),1),fe(u("input",{id:"web-origins","onUpdate:modelValue":C[1]||(C[1]=k=>s.value.origins=k),class:"dh-input",placeholder:"http://localhost:8090, https://app.example.com"},null,512),[[ye,s.value.origins]]),u("p",gu,[Re(m(h(gi)("webapp.originsHint","star").before),1),C[3]||(C[3]=u("span",{class:"data"},"*",-1)),Re(m(h(gi)("webapp.originsHint","star").after),1)])]),(G=n.value)!=null&&G.error?(y(),_("p",mu,m(n.value.error),1)):B("",!0),o.value?(y(),_("p",bu,m(o.value),1)):B("",!0),i.value?(y(),_("p",vu,m(i.value),1)):B("",!0),u("div",yu,[u("button",{class:"dh-btn",disabled:r.value,onClick:b},m(h(f)("webapp.saveApply")),9,_u),u("button",{class:"dh-btn-ghost",disabled:r.value,onClick:d},m(h(f)("webapp.testConnection")),9,wu),C[4]||(C[4]=u("span",{class:"flex-1"},null,-1)),u("span",xu,m(h(f)("webapp.persistedEnv")),1)])])])}}},Tu={class:"dh-card overflow-hidden"},Su={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},Eu={class:"text-base font-bold tracking-[-0.02em] text-strong"},Pu={class:"mt-0.5 text-xs text-muted"},Cu={key:0,class:"border-b border-subtle bg-sunken px-5 py-4"},Au={class:"grid gap-3 sm:grid-cols-3"},$u={class:"dh-label"},Ou={class:"dh-label"},Du={class:"dh-label"},Ru=["disabled"],zu={key:1,class:"border-b border-subtle px-5 py-3 text-xs text-danger"},Iu={key:2,class:"px-5 py-6 text-center text-sm text-muted"},ju={key:3,class:"flex flex-wrap gap-1.5 border-b border-subtle px-5 py-3"},Uu=["onClick"],Mu={class:"dh-pill bg-sunken text-muted"},Nu={class:"flex items-center gap-3 px-5 py-3"},Lu=["onClick"],Fu={class:"font-semibold text-strong"},Bu={class:"dh-pill bg-sunken text-muted"},Hu={key:0,class:"text-xs text-muted"},Vu=["disabled","onClick"],Gu=["disabled","onClick"],Ku={key:0,class:"bg-sunken px-5 py-4"},Wu={key:0,class:"data mb-3 text-xs text-muted"},qu={key:1,class:"grid gap-3 sm:grid-cols-2"},Zu={class:"dh-label"},Ju={key:0,class:"text-danger"},Yu={key:0,class:"flex flex-col gap-1.5 pt-1"},Xu=["checked","onChange"],Qu=["onUpdate:modelValue"],ed={key:0,value:""},td=["value"],sd=["onUpdate:modelValue","type","placeholder"],nd={key:3,class:"mt-1 text-xs text-muted"},id={key:2,class:"text-xs text-muted"},od={key:3,class:"mt-4"},rd={class:"eyebrow mb-1.5"},ad={class:"data flex flex-col gap-1 text-xs text-muted"},ld={class:"text-strong"},cd={key:0},ud={key:1},dd={key:4,class:"data mt-3 text-xs text-body"},pd={class:"mt-4 flex items-center gap-2"},fd=["disabled","onClick"],hd=["disabled","onClick"],gd=["disabled","onClick"],md={key:5,class:"eyebrow mt-2"},bd={__name:"PluginsCard",setup(e){const t=V([]),s=V(""),n=V(!1),i=V(null),o=es({}),r=es({}),a=V(!1),l=V({name:"",baseURL:"",provider:""}),g=V(""),d=["vehicles","chargers","notifications","apis-external","drives-external","drives-local"],b=D=>d.includes(D.category)?D.category:"apis-external",E=ze(()=>{var I;const D={};for(const A of t.value)(D[I=b(A)]||(D[I]=[])).push(A);return d.filter(A=>D[A]).map(A=>({id:A,label:f(`plugins.categories.${A}`),plugins:D[A]}))}),C=ze(()=>E.value.find(D=>D.id===g.value)||E.value[0]),G=ze(()=>{var D;return((D=C.value)==null?void 0:D.plugins)||[]});async function k(){try{const D=await ae("/api/admin/plugins");t.value=D.plugins||[],s.value=""}catch(D){s.value=D.message}}pt(k);function M(D){var A;if(i.value===D.name){i.value=null;return}const I={};for(const N of D.configFields||[])I[N.key]=((A=D.config)==null?void 0:A[N.key])??"";o[D.name]=I,i.value=D.name}function z(D,I){var A;return String(((A=o[D])==null?void 0:A[I])??"").split(",").map(N=>N.trim()).filter(Boolean)}function K(D,I,A){return z(D,I).includes(A)}function Z(D,I,A,N){var he;const le=new Set(z(D,I));N?le.add(A):le.delete(A);const st=t.value.find(J=>J.name===D),as=((he=((st==null?void 0:st.configFields)||[]).find(J=>J.key===I))==null?void 0:he.options)||[];o[D][I]=as.map(J=>J.value).filter(J=>le.has(J)).join(",")}async function j(D,I){n.value=!0,r[D.name]="";try{const A=await ae(`/api/admin/plugins/${encodeURIComponent(D.name)}`,{method:"PUT",body:{enabled:I,config:o[D.name]??{}}});r[D.name]=A.warning||f("plugins.saved"),await k()}catch(A){r[D.name]=A.message}finally{n.value=!1}}async function ce(D){n.value=!0,r[D.name]=f("plugins.checking");try{const I=await ae(`/api/admin/plugins/${encodeURIComponent(D.name)}/health`,{method:"POST"});r[D.name]=`${I.health.status}${I.health.detail?" — "+I.health.detail:""}`,await k()}catch(I){r[D.name]=I.message}finally{n.value=!1}}async function Ee(D){if(confirm(f("plugins.confirmRemove",{name:D.name}))){n.value=!0;try{await ae(`/api/admin/plugins/${encodeURIComponent(D.name)}`,{method:"DELETE"}),i.value===D.name&&(i.value=null),await k()}catch(I){r[D.name]=I.message}finally{n.value=!1}}}async function Pe(){n.value=!0,s.value="";try{await ae("/api/admin/plugins",{method:"POST",body:l.value}),l.value={name:"",baseURL:"",provider:""},a.value=!1,await k()}catch(D){s.value=D.message}finally{n.value=!1}}const ue=D=>D==="ok"?"bg-success-soft text-success":D==="degraded"?"bg-warning-soft text-warning":"bg-danger-soft text-danger";return(D,I)=>(y(),_("div",Tu,[u("div",Su,[u("div",null,[u("div",Eu,m(h(f)("plugins.title")),1),u("p",Pu,m(h(f)("plugins.subtitle")),1)]),u("button",{class:"dh-btn-ghost",onClick:I[0]||(I[0]=A=>a.value=!a.value)},m(a.value?h(f)("plugins.cancelRegister"):h(f)("plugins.registerExternal")),1)]),a.value?(y(),_("div",Cu,[u("div",Au,[u("div",null,[u("label",$u,m(h(f)("plugins.name")),1),fe(u("input",{"onUpdate:modelValue":I[1]||(I[1]=A=>l.value.name=A),class:"dh-input",placeholder:"acme-parts"},null,512),[[ye,l.value.name]])]),u("div",null,[u("label",Ou,m(h(f)("plugins.baseUrl")),1),fe(u("input",{"onUpdate:modelValue":I[2]||(I[2]=A=>l.value.baseURL=A),class:"dh-input",placeholder:"http://127.0.0.1:9100"},null,512),[[ye,l.value.baseURL]])]),u("div",null,[u("label",Du,m(h(f)("plugins.provider")),1),fe(u("input",{"onUpdate:modelValue":I[3]||(I[3]=A=>l.value.provider=A),class:"dh-input",placeholder:"ACME Corp"},null,512),[[ye,l.value.provider]])])]),u("button",{class:"dh-btn mt-3",disabled:n.value||!l.value.name||!l.value.baseURL,onClick:Pe},m(h(f)("plugins.register")),9,Ru)])):B("",!0),s.value?(y(),_("p",zu,m(s.value),1)):B("",!0),t.value.length?B("",!0):(y(),_("p",Iu,m(h(f)("plugins.empty")),1)),E.value.length>1?(y(),_("nav",ju,[(y(!0),_(re,null,Ae(E.value,A=>{var N;return y(),_("button",{key:A.id,class:$e(["dh-btn-ghost",((N=C.value)==null?void 0:N.id)===A.id?"border-accent text-brandtext":""]),onClick:le=>g.value=A.id},[Re(m(A.label)+" ",1),u("span",Mu,m(A.plugins.length),1)],10,Uu)}),128))])):B("",!0),(y(!0),_(re,null,Ae(G.value,A=>(y(),_("div",{key:A.name,class:"border-t border-subtle first:border-t-0"},[u("div",Nu,[u("button",{class:"flex flex-1 items-center gap-3 text-left",onClick:N=>M(A)},[u("span",Fu,m(A.name),1),u("span",Bu,m(A.kind||h(f)("plugins.builtin")),1),A.provider?(y(),_("span",Hu,m(A.provider),1)):B("",!0),A.health?(y(),_("span",{key:1,class:$e(["dh-pill",ue(A.health.status)])},[I[4]||(I[4]=u("span",{class:"h-1.5 w-1.5 rounded-full bg-current"},null,-1)),Re(m(A.health.status),1)],2)):B("",!0)],8,Lu),u("span",{class:$e(["dh-pill",A.enabled?"bg-success-soft text-success":"bg-sunken text-muted"])},m(A.enabled?h(f)("plugins.enabled"):h(f)("plugins.disabled")),3),u("button",{class:"dh-btn-ghost",disabled:n.value,onClick:N=>ce(A)},m(h(f)("plugins.health")),9,Vu),u("button",{class:"dh-btn-ghost",disabled:n.value,onClick:N=>M(A)},m(i.value===A.name?h(f)("plugins.close"):h(f)("plugins.configure")),9,Gu)]),i.value===A.name?(y(),_("div",Ku,[A.baseURL?(y(),_("div",Wu,m(A.baseURL),1)):B("",!0),(A.configFields||[]).length?(y(),_("div",qu,[(y(!0),_(re,null,Ae(A.configFields,N=>(y(),_("div",{key:N.key},[u("label",Zu,[Re(m(N.label||N.key),1),N.required?(y(),_("span",Ju," *")):B("",!0)]),N.type==="multiselect"?(y(),_("div",Yu,[(y(!0),_(re,null,Ae(N.options||[],le=>(y(),_("label",{key:le.value,class:"flex items-center gap-2 text-sm text-body"},[u("input",{type:"checkbox",class:"dh-checkbox",checked:K(A.name,N.key,le.value),onChange:st=>Z(A.name,N.key,le.value,st.target.checked)},null,40,Xu),u("span",null,m(le.label||le.value),1)]))),128))])):N.type==="select"?fe((y(),_("select",{key:1,"onUpdate:modelValue":le=>o[A.name][N.key]=le,class:"dh-select"},[N.required?B("",!0):(y(),_("option",ed,m(h(f)("plugins.notSet")),1)),(y(!0),_(re,null,Ae(N.options||[],le=>(y(),_("option",{key:le.value,value:le.value},m(le.label||le.value),9,td))),128))],8,Qu)),[[Ss,o[A.name][N.key]]]):fe((y(),_("input",{key:2,"onUpdate:modelValue":le=>o[A.name][N.key]=le,class:"dh-input",type:N.type==="password"?"password":N.type==="number"?"number":"text",placeholder:N.default||"",autocomplete:"off"},null,8,sd)),[[qa,o[A.name][N.key]]]),N.help?(y(),_("p",nd,m(N.help),1)):B("",!0)]))),128))])):(y(),_("p",id,m(h(f)("plugins.noConfig")),1)),(A.capabilities||[]).length?(y(),_("div",od,[u("div",rd,m(h(f)("plugins.capabilities")),1),u("ul",ad,[(y(!0),_(re,null,Ae(A.capabilities,N=>(y(),_("li",{key:N.id},[u("span",ld,m(N.id),1),N.method||N.endpoint?(y(),_("span",cd," — "+m(N.method)+" "+m(N.endpoint),1)):B("",!0),N.description?(y(),_("span",ud," · "+m(N.description),1)):B("",!0)]))),128))])])):B("",!0),r[A.name]?(y(),_("p",dd,m(r[A.name]),1)):B("",!0),u("div",pd,[u("button",{class:"dh-btn",disabled:n.value,onClick:N=>j(A,!0)},m(A.enabled?h(f)("plugins.save"):h(f)("plugins.saveEnable")),9,fd),A.enabled?(y(),_("button",{key:0,class:"dh-btn-ghost",disabled:n.value,onClick:N=>j(A,!1)},m(h(f)("plugins.disable")),9,hd)):B("",!0),I[5]||(I[5]=u("span",{class:"flex-1"},null,-1)),A.kind==="external"?(y(),_("button",{key:1,class:"dh-btn-danger",disabled:n.value,onClick:N=>Ee(A)},m(h(f)("plugins.remove")),9,gd)):B("",!0)]),A.kind!=="external"?(y(),_("p",md,m(h(f)("plugins.builtinNote")),1)):B("",!0)])):B("",!0)]))),128))]))}},vd={class:"dh-card overflow-hidden"},yd={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},_d={class:"text-base font-bold tracking-[-0.02em] text-strong"},wd={class:"mt-0.5 text-xs text-muted"},xd={key:0,class:"border-b border-subtle px-5 py-3 text-xs text-danger"},kd={key:1,class:"border-b border-subtle bg-sunken px-5 py-4"},Td={class:"grid gap-3 sm:grid-cols-2"},Sd={class:"dh-label"},Ed={class:"dh-label"},Pd={class:"dh-label"},Cd=["placeholder"],Ad={class:"dh-label"},$d=["value"],Od={key:0},Dd={class:"dh-label"},Rd={value:""},zd=["value"],Id={class:"mt-3 flex items-center gap-2"},jd=["disabled"],Ud=["disabled"],Md={key:2,class:"px-5 py-6 text-center text-sm text-muted"},Nd={key:3,class:"w-full text-left text-sm"},Ld={class:"[&>th]:eyebrow [&>th]:px-5 [&>th]:py-2.5 [&>th]:font-medium"},Fd={class:"data px-5 py-2.5 text-xs text-strong"},Bd={key:0,class:"eyebrow ml-1"},Hd={class:"px-5 py-2.5 text-body"},Vd={class:"px-5 py-2.5 text-body"},Gd={class:"px-5 py-2.5"},Kd={class:"px-5 py-2.5 text-right whitespace-nowrap"},Wd=["onClick"],qd=["disabled","onClick"],Zd={__name:"UsersCard",setup(e){const t=V([]),s=V([]),n=V(""),i=V(!1),o=V(null),r=V({}),a=ze(()=>Ie.value?["user","admin","superadmin"]:["user","admin"]);async function l(){try{const[k,M]=await Promise.all([ae("/api/users"),ae("/api/orgs")]);t.value=k.users||[],s.value=M.organizations||[],n.value=""}catch(k){n.value=k.message}}pt(l);function g(){var k;o.value="new",r.value={email:"",name:"",password:"",role:"user",organization:Ie.value?"":((k=me.value)==null?void 0:k.organization)||""}}function d(k){o.value=k.id,r.value={email:k.email,name:k.name||"",password:"",role:k.role,organization:k.organization||""}}function b(){o.value=null,n.value=""}async function E(){i.value=!0,n.value="";try{if(o.value==="new")await ae("/api/users",{method:"POST",body:r.value});else{const k={...r.value};k.password||delete k.password,await ae(`/api/users/${o.value}`,{method:"PATCH",body:k})}o.value=null,await l()}catch(k){n.value=k.message}finally{i.value=!1}}async function C(k){if(confirm(f("users.confirmDelete",{email:k.email}))){i.value=!0,n.value="";try{await ae(`/api/users/${k.id}`,{method:"DELETE"}),await l()}catch(M){n.value=M.message}finally{i.value=!1}}}const G=k=>k==="superadmin"?"bg-info-soft text-info":k==="admin"?"bg-warning-soft text-warning":"bg-sunken text-muted";return(k,M)=>(y(),_("div",vd,[u("div",yd,[u("div",null,[u("div",_d,m(h(f)("users.title")),1),u("p",wd,m(h(Ie)?h(f)("users.allOrgs"):h(f)("users.yourOrg")),1)]),u("button",{class:"dh-btn",onClick:g},m(h(f)("users.newUser")),1)]),n.value?(y(),_("p",xd,m(n.value),1)):B("",!0),o.value?(y(),_("div",kd,[u("div",Td,[u("div",null,[u("label",Sd,m(h(f)("common.email")),1),fe(u("input",{"onUpdate:modelValue":M[0]||(M[0]=z=>r.value.email=z),class:"dh-input",type:"email",autocomplete:"off"},null,512),[[ye,r.value.email]])]),u("div",null,[u("label",Ed,m(h(f)("common.name")),1),fe(u("input",{"onUpdate:modelValue":M[1]||(M[1]=z=>r.value.name=z),class:"dh-input",autocomplete:"off"},null,512),[[ye,r.value.name]])]),u("div",null,[u("label",Pd,m(o.value==="new"?h(f)("users.password"):h(f)("users.passwordUnchanged")),1),fe(u("input",{"onUpdate:modelValue":M[2]||(M[2]=z=>r.value.password=z),class:"dh-input",type:"password",autocomplete:"new-password",placeholder:h(f)("users.passwordPlaceholder")},null,8,Cd),[[ye,r.value.password]])]),u("div",null,[u("label",Ad,m(h(f)("common.role")),1),fe(u("select",{"onUpdate:modelValue":M[3]||(M[3]=z=>r.value.role=z),class:"dh-select"},[(y(!0),_(re,null,Ae(a.value,z=>(y(),_("option",{key:z,value:z},m(z),9,$d))),128))],512),[[Ss,r.value.role]])]),h(Ie)?(y(),_("div",Od,[u("label",Dd,m(h(f)("common.organization")),1),fe(u("select",{"onUpdate:modelValue":M[4]||(M[4]=z=>r.value.organization=z),class:"dh-select"},[u("option",Rd,m(h(f)("users.orgNone")),1),(y(!0),_(re,null,Ae(s.value,z=>(y(),_("option",{key:z.id,value:z.id},m(z.name),9,zd))),128))],512),[[Ss,r.value.organization]])])):B("",!0)]),u("div",Id,[u("button",{class:"dh-btn",disabled:i.value,onClick:E},m(o.value==="new"?h(f)("common.create"):h(f)("common.save")),9,jd),u("button",{class:"dh-btn-ghost",disabled:i.value,onClick:b},m(h(f)("common.cancel")),9,Ud)])])):B("",!0),t.value.length?(y(),_("table",Nd,[u("thead",null,[u("tr",Ld,[u("th",null,m(h(f)("common.email")),1),u("th",null,m(h(f)("common.name")),1),u("th",null,m(h(f)("common.organization")),1),u("th",null,m(h(f)("common.role")),1),M[5]||(M[5]=u("th",null,null,-1))])]),u("tbody",null,[(y(!0),_(re,null,Ae(t.value,z=>{var K,Z;return y(),_("tr",{key:z.id,class:"border-t border-subtle transition-colors hover:bg-sunken"},[u("td",Fd,[Re(m(z.email)+" ",1),z.id===((K=h(me))==null?void 0:K.id)?(y(),_("span",Bd,m(h(f)("users.you")),1)):B("",!0)]),u("td",Hd,m(z.name||h(f)("common.empty")),1),u("td",Vd,m(z.organizationName||h(f)("common.empty")),1),u("td",Gd,[u("span",{class:$e(["dh-pill",G(z.role)])},m(z.role),3)]),u("td",Kd,[u("button",{class:"dh-btn-ghost",onClick:j=>d(z)},m(h(f)("common.edit")),9,Wd),z.id!==((Z=h(me))==null?void 0:Z.id)?(y(),_("button",{key:0,class:"dh-btn-danger ml-1.5",disabled:i.value,onClick:j=>C(z)},m(h(f)("common.delete")),9,qd)):B("",!0)])])}),128))])])):(y(),_("p",Md,m(h(f)("users.empty")),1))]))}},Jd={class:"dh-card overflow-hidden"},Yd={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},Xd={class:"text-base font-bold tracking-[-0.02em] text-strong"},Qd={class:"mt-0.5 text-xs text-muted"},ep={key:0,class:"border-b border-subtle px-5 py-3 text-xs text-danger"},tp={key:1,class:"border-b border-subtle bg-sunken px-5 py-4"},sp={class:"dh-label"},np=["placeholder"],ip={class:"mt-3 flex items-center gap-2"},op=["disabled"],rp=["disabled"],ap={key:2,class:"px-5 py-6 text-center text-sm text-muted"},lp={key:3,class:"w-full text-left text-sm"},cp={class:"[&>th]:eyebrow [&>th]:px-5 [&>th]:py-2.5 [&>th]:font-medium"},up={class:"px-5 py-2.5 font-medium text-strong"},dp={class:"data px-5 py-2.5 text-xs text-muted"},pp={class:"px-5 py-2.5 text-right whitespace-nowrap"},fp=["onClick"],hp=["disabled","onClick"],gp={__name:"OrgsCard",setup(e){const t=V([]),s=V(""),n=V(!1),i=V(null),o=V(""),r=ze(()=>{var k;return((k=me.value)==null?void 0:k.organization)||""}),a=ze(()=>Ie.value||!r.value);function l(k){return Ie.value||k.id===r.value}async function g(){if(!bs.value){t.value=[];return}try{const k=await ae("/api/orgs");t.value=k.organizations||[],s.value=""}catch(k){s.value=k.message}}pt(g);function d(){i.value="new",o.value=""}function b(k){i.value=k.id,o.value=k.name}function E(){i.value=null,s.value=""}async function C(){n.value=!0,s.value="";try{i.value==="new"?(await ae("/api/orgs",{method:"POST",body:{name:o.value}}),Ie.value||await Es()):await ae(`/api/orgs/${i.value}`,{method:"PATCH",body:{name:o.value}}),i.value=null,await g()}catch(k){s.value=k.message}finally{n.value=!1}}async function G(k){const M=!Ie.value&&k.id===r.value;if(confirm(f(M?"orgs.confirmDeleteOwn":"orgs.confirmDelete",{name:k.name}))){n.value=!0,s.value="";try{await ae(`/api/orgs/${k.id}`,{method:"DELETE"}),M&&await Es(),await g()}catch(K){s.value=K.message}finally{n.value=!1}}}return(k,M)=>(y(),_("div",Jd,[u("div",Yd,[u("div",null,[u("div",Xd,m(h(Ie)?h(f)("orgs.title"):h(f)("common.organization")),1),u("p",Qd,m(h(Ie)?h(f)("orgs.subtitle"):r.value?h(f)("orgs.subtitleOwn"):h(f)("orgs.subtitleNone")),1)]),a.value?(y(),_("button",{key:0,class:"dh-btn",onClick:d},m(h(f)("orgs.newOrg")),1)):B("",!0)]),s.value?(y(),_("p",ep,m(s.value),1)):B("",!0),i.value?(y(),_("div",tp,[u("label",sp,m(h(f)("common.name")),1),fe(u("input",{"onUpdate:modelValue":M[0]||(M[0]=z=>o.value=z),class:"dh-input",placeholder:h(f)("orgs.namePlaceholder"),onKeyup:xo(C,["enter"])},null,40,np),[[ye,o.value]]),u("div",ip,[u("button",{class:"dh-btn",disabled:n.value||!o.value.trim(),onClick:C},m(i.value==="new"?h(f)("common.create"):h(f)("common.save")),9,op),u("button",{class:"dh-btn-ghost",disabled:n.value,onClick:E},m(h(f)("common.cancel")),9,rp)])])):B("",!0),t.value.length?(y(),_("table",lp,[u("thead",null,[u("tr",cp,[u("th",null,m(h(f)("common.name")),1),u("th",null,m(h(f)("orgs.colId")),1),M[1]||(M[1]=u("th",null,null,-1))])]),u("tbody",null,[(y(!0),_(re,null,Ae(t.value,z=>(y(),_("tr",{key:z.id,class:"border-t border-subtle transition-colors hover:bg-sunken"},[u("td",up,m(z.name),1),u("td",dp,m(z.id),1),u("td",pp,[l(z)?(y(),_(re,{key:0},[u("button",{class:"dh-btn-ghost",onClick:K=>b(z)},m(h(f)("common.rename")),9,fp),u("button",{class:"dh-btn-danger ml-1.5",disabled:n.value,onClick:K=>G(z)},m(h(f)("common.delete")),9,hp)],64)):B("",!0)])]))),128))])])):(y(),_("p",ap,m(a.value&&!h(Ie)?h(f)("orgs.createHint"):h(f)("orgs.empty")),1))]))}},mp={class:"dh-card overflow-hidden"},bp={class:"border-b border-subtle px-5 py-4"},vp={class:"flex items-center justify-between"},yp={class:"text-base font-bold tracking-[-0.02em] text-strong"},_p={class:"eyebrow"},wp={key:0,class:"mt-1.5 text-xs text-muted"},xp={class:"overflow-x-auto"},kp={class:"w-full text-left text-sm"},Tp={class:"[&>th]:eyebrow [&>th]:px-5 [&>th]:py-2.5 [&>th]:font-medium"},Sp={class:"data border-t border-subtle px-5 py-2.5 text-xs whitespace-nowrap"},Ep={class:"text-strong"},Pp={class:"border-t border-subtle px-5 py-2.5 text-body"},ge={__name:"EndpointTable",props:{title:String,auth:String,endpoints:Array,note:String},setup(e){const t={GET:"text-success",POST:"text-brandtext",PUT:"text-info",PATCH:"text-warning",DELETE:"text-danger"};return(s,n)=>(y(),_("div",mp,[u("div",bp,[u("div",vp,[u("div",yp,m(e.title),1),u("span",_p,m(e.auth),1)]),e.note?(y(),_("p",wp,m(e.note),1)):B("",!0)]),u("div",xp,[u("table",kp,[u("thead",null,[u("tr",Tp,[u("th",null,m(h(f)("api.colEndpoint")),1),u("th",null,m(h(f)("api.colDescription")),1)])]),u("tbody",null,[(y(!0),_(re,null,Ae(e.endpoints,i=>(y(),_("tr",{key:i.method+i.path,class:"transition-colors hover:bg-sunken"},[u("td",Sp,[u("span",{class:$e(["font-semibold",t[i.method]])},m(i.method),3),u("span",Ep,m(i.path),1)]),u("td",Pp,m(i.desc),1)]))),128))])])])]))}},Cp={class:"mx-auto flex max-w-[1368px] flex-col gap-6 px-6 pt-12 pb-16"},Ap={class:"flex items-center gap-3"},$p={class:"eyebrow mt-1.5"},Op={key:0,class:"data hidden text-xs text-muted sm:inline"},Dp={key:0},Rp={key:1,class:"dh-pill bg-info-soft text-info"},zp=["value","aria-label"],Ip=["value"],jp=["title"],Up={key:0,xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"1.75",class:"h-4 w-4"},Mp={key:1,xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"1.75",class:"h-4 w-4"},Np={key:0,class:"eyebrow py-16 text-center"},Lp={class:"flex flex-wrap gap-1.5"},Fp=["onClick"],Bp={key:8,class:"eyebrow text-center"},Hp={class:"eyebrow text-center"},Vp="{records} is any of service-records, technical-checks, maintenance, fuel-entries, charging-sessions, car-documents, parts.",Gp={__name:"App",setup(e){const t=V(!0),s=V("overview");pt(async()=>{await ec(),t.value=!1});const n=ze(()=>{const ue=[{id:"overview",label:f("sections.overview")}];return bs.value&&ue.push({id:"users",label:f("sections.users")}),(bs.value||me.value)&&ue.push({id:"orgs",label:f("sections.orgs")}),Ie.value&&ue.push({id:"server",label:f("sections.server")},{id:"pocketbase",label:f("sections.pocketbase")},{id:"webapp",label:f("sections.webapp")},{id:"plugins",label:f("sections.plugins")}),ue.push({id:"api",label:f("sections.api")}),ue}),i=ze(()=>Gl.map(ue=>{let D=ue;try{D=new Intl.DisplayNames([ue],{type:"language"}).of(ue)||ue}catch{}return{code:ue,label:D.charAt(0).toUpperCase()+D.slice(1)}}));function o(){Cn(),s.value="overview"}const r=[{method:"GET",path:"/api/health",desc:"Liveness probe (no auth)"},{method:"GET",path:"/healthz",desc:"The same probe under the conventional container path"},{method:"GET",path:"/api/status",desc:"Health of PocketBase + Web App"},{method:"POST",path:"/api/auth/login",desc:"Exchange email + password for a PocketBase token"},{method:"GET",path:"/api/auth/validate",desc:"Check whether a token is still valid"}],a=[{method:"GET",path:"/api/auth/me",desc:"Identity of the bearer token"},{method:"GET",path:"/api/identity",desc:"Identity incl. role + organization"}],l=[{method:"GET",path:"/api/cars",desc:"List owned + shared cars"},{method:"POST",path:"/api/cars",desc:"Create a car"},{method:"GET",path:"/api/cars/{id}",desc:"Fetch one car"},{method:"PATCH",path:"/api/cars/{id}",desc:"Update a car"},{method:"PUT",path:"/api/cars/{id}/view",desc:"Save the car's layout — hidden tabs/fields/columns and their order"},{method:"DELETE",path:"/api/cars/{id}",desc:"Delete a car (owner only)"},{method:"GET",path:"/api/cars/{id}/service-records",desc:"A car's service history"},{method:"GET",path:"/api/cars/{id}/technical-checks",desc:"A car's roadworthiness inspections"},{method:"GET",path:"/api/cars/{id}/parts",desc:"A car's parts catalog"},{method:"GET",path:"/api/cars/{id}/fuel-entries",desc:"A car's refuelings"},{method:"GET",path:"/api/cars/{id}/fuel-stats",desc:"Consumption + cost totals from the fuel log"},{method:"GET",path:"/api/cars/{id}/charging-sessions",desc:"A car's charging sessions"},{method:"GET",path:"/api/cars/{id}/charging-stats",desc:"Energy + cost totals from the charging log"},{method:"GET",path:"/api/cars/{id}/maintenance",desc:"A car's maintenance log"},{method:"GET",path:"/api/cars/{id}/documents",desc:"A car's documents"},{method:"GET",path:"/api/cars/{id}/reminders",desc:"A car's reminders"},{method:"GET",path:"/api/cars/{id}/provider",desc:"Live snapshot from the car's connected service"},{method:"POST",path:"/api/cars/{id}/provider",desc:"Link the car to a provider vehicle (an empty provider unlinks)"},{method:"POST",path:"/api/cars/{id}/provider/sync",desc:"Re-apply the provider's data to the car"},{method:"GET",path:"/api/cars/{id}/shares",desc:"Who a car is shared with (owner)"},{method:"POST",path:"/api/cars/{id}/shares",desc:"Share a car by email (owner)"},{method:"DELETE",path:"/api/cars/{id}/shares/{userId}",desc:"Revoke a share (owner)"}],g=[{method:"GET",path:"/api/service-records",desc:"List one car's service records (?car={id})"},{method:"POST",path:"/api/service-records",desc:"Log a service record"},{method:"GET",path:"/api/service-records/{id}",desc:"Fetch one record"},{method:"PATCH",path:"/api/service-records/{id}",desc:"Update a record"},{method:"DELETE",path:"/api/service-records/{id}",desc:"Delete a record"}],d=[{method:"GET",path:"/api/technical-checks",desc:"List one car's inspections (?car={id})"},{method:"POST",path:"/api/technical-checks",desc:"Log an inspection"},{method:"GET",path:"/api/technical-checks/{id}",desc:"Fetch one inspection"},{method:"PATCH",path:"/api/technical-checks/{id}",desc:"Update an inspection"},{method:"DELETE",path:"/api/technical-checks/{id}",desc:"Delete an inspection"}],b=[{method:"GET",path:"/api/parts",desc:"List one car's parts (?car={id})"},{method:"POST",path:"/api/parts",desc:"Add a part"},{method:"GET",path:"/api/parts/{id}",desc:"Fetch one part"},{method:"PATCH",path:"/api/parts/{id}",desc:"Update a part"},{method:"DELETE",path:"/api/parts/{id}",desc:"Delete a part"}],E=[{method:"GET",path:"/api/fuel-entries",desc:"List one car's refuelings (?car={id})"},{method:"POST",path:"/api/fuel-entries",desc:"Log a refueling"},{method:"GET",path:"/api/fuel-entries/{id}",desc:"Fetch one refueling"},{method:"PATCH",path:"/api/fuel-entries/{id}",desc:"Update a refueling"},{method:"DELETE",path:"/api/fuel-entries/{id}",desc:"Delete a refueling"}],C=[{method:"GET",path:"/api/charging-sessions",desc:"List one car's charging sessions (?car={id})"},{method:"POST",path:"/api/charging-sessions",desc:"Log a charging session"},{method:"GET",path:"/api/charging-sessions/{id}",desc:"Fetch one session"},{method:"PATCH",path:"/api/charging-sessions/{id}",desc:"Update a session"},{method:"DELETE",path:"/api/charging-sessions/{id}",desc:"Delete a session"}],G=[{method:"GET",path:"/api/maintenance",desc:"List one car's maintenance jobs (?car={id})"},{method:"POST",path:"/api/maintenance",desc:"Log a maintenance job"},{method:"GET",path:"/api/maintenance/{id}",desc:"Fetch one job"},{method:"PATCH",path:"/api/maintenance/{id}",desc:"Update a job"},{method:"DELETE",path:"/api/maintenance/{id}",desc:"Delete a job"}],k=[{method:"GET",path:"/api/car-documents",desc:"List one car's documents (?car={id})"},{method:"POST",path:"/api/car-documents",desc:"Add a document"},{method:"GET",path:"/api/car-documents/{id}",desc:"Fetch one document"},{method:"PATCH",path:"/api/car-documents/{id}",desc:"Update a document"},{method:"DELETE",path:"/api/car-documents/{id}",desc:"Delete a document"}],M=[{method:"GET",path:"/api/reminders",desc:"List one car's reminders (?car={id})"},{method:"POST",path:"/api/reminders",desc:"Create a reminder"},{method:"GET",path:"/api/reminders/{id}",desc:"Fetch one reminder"},{method:"PATCH",path:"/api/reminders/{id}",desc:"Update a reminder"},{method:"DELETE",path:"/api/reminders/{id}",desc:"Delete a reminder"},{method:"POST",path:"/api/reminders/{id}/complete",desc:"Mark done — a recurring reminder rolls forward from now"}],z=[{method:"POST",path:"/api/{records}/{id}/file",desc:"Attach a file, replacing any previous one (PDF or image, max 10 MB)"},{method:"GET",path:"/api/{records}/{id}/file",desc:"Download the attachment (car access re-checked on every request)"},{method:"DELETE",path:"/api/{records}/{id}/file",desc:"Detach and delete the file"}],K=[{method:"GET",path:"/api/vehicle-providers",desc:"Registered providers and whether the caller can use each one"},{method:"GET",path:"/api/vehicle-providers/{provider}/vehicles",desc:"Vehicles on the caller's provider account, as importable cars"},{method:"POST",path:"/api/vehicle-providers/{provider}/import",desc:"Create a car from a provider vehicle (409 if already imported)"}],Z=[{method:"GET",path:"/api/integrations/toyota",desc:"Resolved Toyota Connected settings (secrets masked)"},{method:"PUT",path:"/api/integrations/toyota",desc:"Save the caller's own layer (user or org scope)"},{method:"POST",path:"/api/integrations/toyota/health",desc:"Live probe with the resolved credentials"},{method:"GET",path:"/api/integrations/toyota/vehicles",desc:"Raw MyToyota vehicle payload"},{method:"GET",path:"/api/integrations/anker-solix",desc:"Resolved Anker Solix settings (secrets masked)"},{method:"PUT",path:"/api/integrations/anker-solix",desc:"Save the caller's own layer (user or org scope)"},{method:"POST",path:"/api/integrations/anker-solix/health",desc:"Live probe with the resolved credentials"},{method:"GET",path:"/api/integrations/anker-solix/chargers",desc:"EV chargers on the linked Anker account"},{method:"GET",path:"/api/integrations/anker-solix/chargers/{sn}/control",desc:"Control mode, token state and live session or Modbus snapshot for one charger"},{method:"POST",path:"/api/integrations/anker-solix/chargers/{sn}/control/token",desc:"(Re)issue the charger's control token"},{method:"DELETE",path:"/api/integrations/anker-solix/chargers/{sn}/control/token",desc:"Revoke the control token"},{method:"PUT",path:"/api/integrations/anker-solix/chargers/{sn}/control/address",desc:"Save the charger's local Modbus TCP address"},{method:"DELETE",path:"/api/integrations/anker-solix/chargers/{sn}/control/address",desc:"Forget the charger's local Modbus TCP address"},{method:"POST",path:"/api/integrations/anker-solix/chargers/{sn}/{action}",desc:"One control command. Over OCPP: start, stop, limit, clear-limit, availability, reset, unlock, trigger, config. Over Modbus TCP: start, stop, limit, boost, phase, timeout, status"},{method:"GET",path:"/api/integrations/greencell",desc:"Resolved Greencell settings (secrets masked)"},{method:"PUT",path:"/api/integrations/greencell",desc:"Save the caller's own layer (user or org scope)"},{method:"POST",path:"/api/integrations/greencell/health",desc:"Live probe: connect to the broker and broadcast for devices"},{method:"GET",path:"/api/integrations/greencell/chargers",desc:"Greencell chargers answering on the configured MQTT broker"},{method:"GET",path:"/api/integrations/greencell/chargers/{sn}/state",desc:"Live EVSE state, access level, power and per-phase current/voltage"}],j=[{method:"GET",path:"/ocpp/{serial}",desc:"WebSocket the charger dials out to; OCPP Basic auth with the serial + its control token"}],ce=[{method:"GET",path:"/api/me",desc:"Current user profile"},{method:"PATCH",path:"/api/me",desc:"Update profile"},{method:"POST",path:"/api/me/password",desc:"Change password"},{method:"POST",path:"/api/me/avatar",desc:"Upload avatar"},{method:"GET",path:"/api/me/avatar",desc:"Fetch avatar"},{method:"DELETE",path:"/api/me/avatar",desc:"Remove avatar"},{method:"POST",path:"/api/me/verify/request",desc:"Request email verification"},{method:"GET",path:"/api/me/export",desc:"Export your data"},{method:"POST",path:"/api/me/import",desc:"Import data"},{method:"POST",path:"/api/me/delete",desc:"Request account deletion"},{method:"POST",path:"/api/me/delete/cancel",desc:"Cancel deletion request"},{method:"DELETE",path:"/api/me",desc:"Finalize account deletion"}],Ee=[{method:"GET",path:"/api/users",desc:"List users (scoped by role)"},{method:"POST",path:"/api/users",desc:"Create a user"},{method:"PATCH",path:"/api/users/{id}",desc:"Update email / name / role / org / password"},{method:"DELETE",path:"/api/users/{id}",desc:"Delete a user"},{method:"GET",path:"/api/orgs",desc:"List organizations"},{method:"POST",path:"/api/orgs",desc:"Create an organization (any user without one; creator becomes admin)"},{method:"PATCH",path:"/api/orgs/{id}",desc:"Rename an organization (own org; any as superadmin)"},{method:"DELETE",path:"/api/orgs/{id}",desc:"Delete an organization (own org; any as superadmin)"}],Pe=[{method:"GET",path:"/api/admin/pb-config",desc:"PocketBase connection + live probe"},{method:"POST",path:"/api/admin/pb-config/test",desc:"Probe a candidate connection"},{method:"PUT",path:"/api/admin/pb-config",desc:"Apply + persist a connection"},{method:"GET",path:"/api/admin/server-config",desc:"This server's display name"},{method:"PUT",path:"/api/admin/server-config",desc:"Rename this server (applied + persisted)"},{method:"GET",path:"/api/admin/webapp-config",desc:"Web App URL + CORS origins, with a live probe"},{method:"POST",path:"/api/admin/webapp-config/test",desc:"Probe a candidate Web App address"},{method:"PUT",path:"/api/admin/webapp-config",desc:"Apply + persist Web App settings"},{method:"GET",path:"/api/admin/plugins",desc:"List plugins (secrets masked)"},{method:"POST",path:"/api/admin/plugins",desc:"Register an external plugin"},{method:"GET",path:"/api/admin/plugins/{name}",desc:"Fetch one plugin"},{method:"PUT",path:"/api/admin/plugins/{name}",desc:"Enable/disable + configure"},{method:"DELETE",path:"/api/admin/plugins/{name}",desc:"Remove an external plugin"},{method:"POST",path:"/api/admin/plugins/{name}/health",desc:"Run a health check now"}];return(ue,D)=>(y(),_("div",Cp,[u("div",Ap,[ee(lc,{"on-dark":h(Ot)==="dark",class:"h-7"},null,8,["on-dark"]),u("span",$p,m(h(f)("app.apiServer")),1),D[4]||(D[4]=u("div",{class:"flex-1"},null,-1)),h(me)?(y(),_("span",Op,[Re(m(h(me).email),1),h(me).organizationName?(y(),_("span",Dp," · "+m(h(me).organizationName),1)):B("",!0)])):B("",!0),h(me)?(y(),_("span",Rp,m(h(me).role),1)):B("",!0),u("select",{class:"dh-select !w-auto !py-1 !text-xs",value:h(Pn),"aria-label":h(f)("sections.overview"),onChange:D[0]||(D[0]=I=>h(Wl)(I.target.value))},[(y(!0),_(re,null,Ae(i.value,I=>(y(),_("option",{key:I.code,value:I.code},m(I.label),9,Ip))),128))],40,zp),u("button",{class:"dh-btn-ghost",title:h(Ot)==="dark"?h(f)("app.switchToLight"):h(f)("app.switchToDark"),onClick:D[1]||(D[1]=(...I)=>h(fi)&&h(fi)(...I))},[h(Ot)==="dark"?(y(),_("svg",Up,[...D[2]||(D[2]=[u("circle",{cx:"12",cy:"12",r:"4"},null,-1),u("path",{"stroke-linecap":"round",d:"M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4"},null,-1)])])):(y(),_("svg",Mp,[...D[3]||(D[3]=[u("path",{"stroke-linecap":"round","stroke-linejoin":"round",d:"M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8Z"},null,-1)])])),Re(" "+m(h(f)("app.theme")),1)],8,jp),h(jt)?(y(),_("button",{key:2,class:"dh-btn-ghost",onClick:o},m(h(f)("app.signOut")),1)):B("",!0)]),t.value?(y(),_("p",Np,m(h(f)("app.loading")),1)):h(jt)?(y(),_(re,{key:2},[u("nav",Lp,[(y(!0),_(re,null,Ae(n.value,I=>(y(),_("button",{key:I.id,class:$e(["dh-btn-ghost",s.value===I.id?"border-accent text-brandtext":""]),onClick:A=>s.value=I.id},m(I.label),11,Fp))),128))]),s.value==="overview"?(y(),it($c,{key:0})):s.value==="users"?(y(),it(Zd,{key:1})):s.value==="orgs"?(y(),it(gp,{key:2})):s.value==="server"?(y(),it(au,{key:3})):s.value==="pocketbase"?(y(),it(qc,{key:4})):s.value==="webapp"?(y(),it(ku,{key:5})):s.value==="plugins"?(y(),it(bd,{key:6})):s.value==="api"?(y(),_(re,{key:7},[ee(ge,{title:h(f)("api.groupPublic"),auth:h(f)("api.authNone"),endpoints:r},null,8,["title","auth"]),ee(ge,{title:h(f)("api.groupIdentity"),auth:h(f)("api.authBearer"),endpoints:a},null,8,["title","auth"]),ee(ge,{title:h(f)("api.groupCars"),auth:h(f)("api.authBearer"),endpoints:l},null,8,["title","auth"]),ee(ge,{title:h(f)("api.groupService"),auth:h(f)("api.authBearer"),endpoints:g},null,8,["title","auth"]),ee(ge,{title:h(f)("api.groupTechnical"),auth:h(f)("api.authBearer"),endpoints:d},null,8,["title","auth"]),ee(ge,{title:h(f)("api.groupParts"),auth:h(f)("api.authBearer"),endpoints:b},null,8,["title","auth"]),ee(ge,{title:h(f)("api.groupFuel"),auth:h(f)("api.authBearer"),endpoints:E},null,8,["title","auth"]),ee(ge,{title:h(f)("api.groupCharging"),auth:h(f)("api.authBearer"),endpoints:C},null,8,["title","auth"]),ee(ge,{title:h(f)("api.groupMaintenance"),auth:h(f)("api.authBearer"),endpoints:G},null,8,["title","auth"]),ee(ge,{title:h(f)("api.groupDocuments"),auth:h(f)("api.authBearer"),endpoints:k},null,8,["title","auth"]),ee(ge,{title:h(f)("api.groupReminders"),auth:h(f)("api.authBearer"),endpoints:M},null,8,["title","auth"]),ee(ge,{title:h(f)("api.groupAttachments"),auth:h(f)("api.authBearer"),endpoints:z,note:Vp},null,8,["title","auth"]),ee(ge,{title:h(f)("api.groupProviders"),auth:h(f)("api.authBearer"),endpoints:K},null,8,["title","auth"]),ee(ge,{title:h(f)("api.groupIntegrations"),auth:h(f)("api.authBearer"),endpoints:Z},null,8,["title","auth"]),ee(ge,{title:h(f)("api.groupOcpp"),auth:h(f)("api.authCharger"),endpoints:j},null,8,["title","auth"]),ee(ge,{title:h(f)("api.groupAccount"),auth:h(f)("api.authBearer"),endpoints:ce},null,8,["title","auth"]),ee(ge,{title:h(f)("api.groupManagement"),auth:h(f)("api.authManager"),endpoints:Ee},null,8,["title","auth"]),ee(ge,{title:h(f)("api.groupSuperadmin"),auth:h(f)("api.authSuperadmin"),endpoints:Pe},null,8,["title","auth"])],64)):B("",!0),!h(bs)&&s.value==="overview"?(y(),_("p",Bp,m(h(f)("app.standardUserNote")),1)):B("",!0)],64)):(y(),it(vc,{key:1})),u("p",Hp,m(h(f)("app.footer")),1)]))}};sl(Gp).mount("#app"); diff --git a/API Server/internal/api/dist/assets/index-_8IdQ1wh.css b/API Server/internal/api/dist/assets/index-Cd85xDqG.css similarity index 50% rename from API Server/internal/api/dist/assets/index-_8IdQ1wh.css rename to API Server/internal/api/dist/assets/index-Cd85xDqG.css index 43e6581..c175f5a 100644 --- a/API Server/internal/api/dist/assets/index-_8IdQ1wh.css +++ b/API Server/internal/api/dist/assets/index-Cd85xDqG.css @@ -1 +1 @@ -@import"https://fonts.googleapis.com/css2?family=Archivo:ital,wght@0,400;0,500;0,600;0,700;0,800;1,700;1,800&family=DM+Mono:ital,wght@0,400;0,500&display=swap";/*! tailwindcss v4.3.2 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial}}}@layer theme{:root,:host{--font-sans:var(--font-sans);--font-mono:var(--font-mono);--color-white:#fff;--spacing:.25rem;--container-sm:24rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height: 1.5 ;--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--font-weight-extrabold:800;--shadow-xs:var(--shadow-xs);--shadow-sm:var(--shadow-sm);--shadow-md:0 4px 6px -1px #0000001a, 0 2px 4px -2px #0000001a;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--radius-control:12px;--radius-card:18px;--radius-pill:999px}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.container{width:100%}@media(min-width:40rem){.container{max-width:40rem}}@media(min-width:48rem){.container{max-width:48rem}}@media(min-width:64rem){.container{max-width:64rem}}@media(min-width:80rem){.container{max-width:80rem}}@media(min-width:96rem){.container{max-width:96rem}}.mx-auto{margin-inline:auto}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:var(--spacing)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-5{margin-bottom:calc(var(--spacing) * 5)}.ml-1{margin-left:var(--spacing)}.ml-1\.5{margin-left:calc(var(--spacing) * 1.5)}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline-flex{display:inline-flex}.table{display:table}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-4{height:calc(var(--spacing) * 4)}.h-7{height:calc(var(--spacing) * 7)}.h-full{height:100%}.\!w-auto{width:auto!important}.w-1\.5{width:calc(var(--spacing) * 1.5)}.w-4{width:calc(var(--spacing) * 4)}.w-auto{width:auto}.w-full{width:100%}.max-w-\[1368px\]{max-width:1368px}.max-w-sm{max-width:var(--container-sm)}.flex-1{flex:1}.shrink-0{flex-shrink:0}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-between{justify-content:space-between}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}.gap-6{gap:calc(var(--spacing) * 6)}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.rounded-control{border-radius:12px}.rounded-full{border-radius:3.40282e38px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-accent{border-color:var(--accent)}.border-subtle{border-color:var(--border-subtle)}.bg-current{background-color:currentColor}.bg-danger-soft{background-color:var(--danger-100)}.bg-info-soft{background-color:var(--info-100)}.bg-success-soft{background-color:var(--success-100)}.bg-sunken{background-color:var(--surface-sunken)}.bg-warning-soft{background-color:var(--warning-100)}.p-6{padding:calc(var(--spacing) * 6)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-5{padding-inline:calc(var(--spacing) * 5)}.px-6{padding-inline:calc(var(--spacing) * 6)}.\!py-1{padding-block:var(--spacing)!important}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-6{padding-block:calc(var(--spacing) * 6)}.py-16{padding-block:calc(var(--spacing) * 16)}.pt-12{padding-top:calc(var(--spacing) * 12)}.pt-24{padding-top:calc(var(--spacing) * 24)}.pb-16{padding-bottom:calc(var(--spacing) * 16)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.\!text-xs{font-size:var(--text-xs)!important;line-height:var(--tw-leading,var(--text-xs--line-height))!important}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[1\.35em\]{font-size:1.35em}.leading-none{--tw-leading:1;line-height:1}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-extrabold{--tw-font-weight:var(--font-weight-extrabold);font-weight:var(--font-weight-extrabold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-\[-0\.02em\]{--tw-tracking:-.02em;letter-spacing:-.02em}.tracking-\[-0\.03em\]{--tw-tracking:-.03em;letter-spacing:-.03em}.whitespace-nowrap{white-space:nowrap}.text-body{color:var(--text-body)}.text-brand-400{color:var(--brand-400)}.text-brandtext{color:var(--text-brand)}.text-danger{color:var(--danger-600)}.text-info{color:var(--info-600)}.text-muted{color:var(--text-muted)}.text-strong{color:var(--text-strong)}.text-success{color:var(--success-600)}.text-warning{color:var(--warning-600)}.text-white{color:var(--color-white)}.italic{font-style:italic}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.select-none{-webkit-user-select:none;user-select:none}.first\:border-t-0:first-child{border-top-style:var(--tw-border-style);border-top-width:0}@media(hover:hover){.hover\:bg-sunken:hover{background-color:var(--surface-sunken)}}@media(min-width:40rem){.sm\:inline{display:inline}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}.\[\&\>th\]\:px-5>th{padding-inline:calc(var(--spacing) * 5)}.\[\&\>th\]\:py-2\.5>th{padding-block:calc(var(--spacing) * 2.5)}.\[\&\>th\]\:font-medium>th{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}}:root{color-scheme:light;--brand-900:#0b1730;--brand-800:#0f1e3d;--brand-700:#1e40af;--brand-600:#2563eb;--brand-500:#3b82f6;--brand-400:#60a5fa;--brand-300:#93c5fd;--brand-200:#c7dbfb;--brand-100:#e8f0fd;--ink-900:#0f1e3d;--ink-700:#28374f;--ink-600:#3e4e68;--ink-500:#5c6b85;--ink-400:#7a8aa6;--ink-300:#b4bece;--ink-200:#d6deea;--ink-100:#e4e9f2;--ink-50:#eef2f8;--ink-25:#f7f9fc;--white:#fff;--success-600:#1f8a5b;--success-100:#e1f3ea;--warning-600:#d9822b;--warning-100:#fbeddd;--danger-600:#dc2a45;--danger-100:#fbe3e7;--info-600:#2563eb;--info-100:#e8f0fd;--surface-page:var(--ink-25);--surface-card:var(--white);--surface-sunken:var(--ink-50);--border-subtle:var(--ink-100);--border-default:var(--ink-200);--border-strong:var(--ink-300);--text-strong:var(--ink-900);--text-body:var(--ink-600);--text-muted:var(--ink-400);--text-brand:var(--brand-700);--accent:var(--brand-600);--accent-hover:var(--brand-700);--focus-ring:var(--brand-400);--shadow-xs:0 1px 2px #0f1e3d0f;--shadow-sm:0 1px 2px #0f1e3d0a, 0 2px 6px #0f1e3d0f;--shadow-md:0 1px 2px #0f1e3d0a, 0 12px 30px -12px #0f1e3d24;--font-display:"Archivo", system-ui, sans-serif;--font-sans:"Archivo", system-ui, sans-serif;--font-mono:"DM Mono", ui-monospace, "SF Mono", monospace}html.dark{color-scheme:dark;--success-100:#12352a;--warning-100:#3a2a16;--danger-100:#3a1620;--info-100:#122a4d;--surface-page:#0b1730;--surface-card:#13233f;--surface-sunken:#0f1e38;--border-subtle:#21324f;--border-default:#2c3f5e;--border-strong:#3c5173;--text-strong:#f2f6fc;--text-body:#b7c4d9;--text-muted:#7c8ca8;--text-brand:#93c5fd;--accent:#3b82f6;--accent-hover:#60a5fa;--focus-ring:#60a5fa;--success-600:#35b27a;--warning-600:#e0a03a;--danger-600:#e85c74;--shadow-xs:0 1px 2px #0006;--shadow-sm:0 1px 2px #0006, 0 2px 6px #0006;--shadow-md:0 1px 2px #00000059, 0 12px 30px -12px #0000008c}html,body,#app{height:100%}body{font-family:var(--font-sans);background:var(--surface-page);color:var(--text-body);-webkit-font-smoothing:antialiased;margin:0}.eyebrow{font-family:var(--font-mono);text-transform:uppercase;letter-spacing:.16em;color:var(--text-muted);font-size:11px}.data{font-family:var(--font-mono);letter-spacing:.02em;font-variant-numeric:tabular-nums}.dh-btn-ghost{border-radius:var(--radius-control);border:1px solid var(--border-default);background:var(--surface-card);height:34px;color:var(--text-strong);font-family:var(--font-sans);cursor:pointer;justify-content:center;align-items:center;gap:8px;padding:0 12px;font-size:.8125rem;font-weight:600;transition:background-color .14s,border-color .14s;display:inline-flex}.dh-btn-ghost:hover{background:var(--surface-sunken);border-color:var(--border-strong)}.dh-btn-ghost:focus-visible{box-shadow:0 0 0 3px var(--focus-ring);outline:none}.dh-btn{border-radius:var(--radius-control);background:var(--accent);color:#fff;height:34px;font-family:var(--font-sans);cursor:pointer;border:1px solid #0000;justify-content:center;align-items:center;gap:8px;padding:0 14px;font-size:.8125rem;font-weight:600;transition:background-color .14s;display:inline-flex}.dh-btn:hover:not(:disabled){background:var(--accent-hover)}.dh-btn:focus-visible{box-shadow:0 0 0 3px var(--focus-ring);outline:none}.dh-btn:disabled,.dh-btn-ghost:disabled,.dh-btn-danger:disabled{opacity:.55;cursor:not-allowed}.dh-btn-danger{border-radius:var(--radius-control);border:1px solid var(--border-default);height:30px;color:var(--danger-600);font-family:var(--font-sans);cursor:pointer;background:0 0;justify-content:center;align-items:center;gap:6px;padding:0 10px;font-size:.75rem;font-weight:600;transition:background-color .14s,border-color .14s;display:inline-flex}.dh-btn-danger:hover:not(:disabled){background:var(--danger-100);border-color:var(--danger-600)}.dh-input,.dh-select{border-radius:var(--radius-control);border:1px solid var(--border-default);background:var(--surface-card);width:100%;height:36px;color:var(--text-strong);font-family:var(--font-sans);padding:0 10px;font-size:.8125rem;transition:border-color .14s}.dh-input::placeholder{color:var(--text-muted)}.dh-input:focus,.dh-select:focus{border-color:var(--accent);box-shadow:0 0 0 3px var(--focus-ring);outline:none}.dh-label{font-family:var(--font-mono);text-transform:uppercase;letter-spacing:.16em;color:var(--text-muted);margin-bottom:5px;font-size:10px;display:block}.dh-pill{border-radius:var(--radius-pill);font-family:var(--font-mono);white-space:nowrap;align-items:center;gap:6px;padding:3px 9px;font-size:11px;font-weight:500;display:inline-flex}.dh-card{border:1px solid var(--border-subtle);background:var(--surface-card);border-radius:var(--radius-card);box-shadow:var(--shadow-sm)}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false} +@import"https://fonts.googleapis.com/css2?family=Archivo:ital,wght@0,400;0,500;0,600;0,700;0,800;1,700;1,800&family=DM+Mono:ital,wght@0,400;0,500&display=swap";/*! tailwindcss v4.3.2 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial}}}@layer theme{:root,:host{--font-sans:var(--font-sans);--font-mono:var(--font-mono);--color-white:#fff;--spacing:.25rem;--container-sm:24rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height: 1.5 ;--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--font-weight-extrabold:800;--shadow-xs:var(--shadow-xs);--shadow-sm:var(--shadow-sm);--shadow-md:0 4px 6px -1px #0000001a, 0 2px 4px -2px #0000001a;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--radius-control:12px;--radius-card:18px;--radius-pill:999px}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.container{width:100%}@media(min-width:40rem){.container{max-width:40rem}}@media(min-width:48rem){.container{max-width:48rem}}@media(min-width:64rem){.container{max-width:64rem}}@media(min-width:80rem){.container{max-width:80rem}}@media(min-width:96rem){.container{max-width:96rem}}.mx-auto{margin-inline:auto}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:var(--spacing)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-5{margin-bottom:calc(var(--spacing) * 5)}.ml-1{margin-left:var(--spacing)}.ml-1\.5{margin-left:calc(var(--spacing) * 1.5)}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline-flex{display:inline-flex}.table{display:table}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-4{height:calc(var(--spacing) * 4)}.h-7{height:calc(var(--spacing) * 7)}.h-full{height:100%}.\!w-auto{width:auto!important}.w-1\.5{width:calc(var(--spacing) * 1.5)}.w-4{width:calc(var(--spacing) * 4)}.w-auto{width:auto}.w-full{width:100%}.max-w-\[1368px\]{max-width:1368px}.max-w-sm{max-width:var(--container-sm)}.flex-1{flex:1}.shrink-0{flex-shrink:0}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-between{justify-content:space-between}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}.gap-6{gap:calc(var(--spacing) * 6)}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.rounded-control{border-radius:12px}.rounded-full{border-radius:3.40282e38px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-accent{border-color:var(--accent)}.border-subtle{border-color:var(--border-subtle)}.bg-current{background-color:currentColor}.bg-danger-soft{background-color:var(--danger-100)}.bg-info-soft{background-color:var(--info-100)}.bg-success-soft{background-color:var(--success-100)}.bg-sunken{background-color:var(--surface-sunken)}.bg-warning-soft{background-color:var(--warning-100)}.p-6{padding:calc(var(--spacing) * 6)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-5{padding-inline:calc(var(--spacing) * 5)}.px-6{padding-inline:calc(var(--spacing) * 6)}.\!py-1{padding-block:var(--spacing)!important}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-6{padding-block:calc(var(--spacing) * 6)}.py-16{padding-block:calc(var(--spacing) * 16)}.pt-1{padding-top:var(--spacing)}.pt-12{padding-top:calc(var(--spacing) * 12)}.pt-24{padding-top:calc(var(--spacing) * 24)}.pb-16{padding-bottom:calc(var(--spacing) * 16)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.\!text-xs{font-size:var(--text-xs)!important;line-height:var(--tw-leading,var(--text-xs--line-height))!important}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[1\.35em\]{font-size:1.35em}.leading-none{--tw-leading:1;line-height:1}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-extrabold{--tw-font-weight:var(--font-weight-extrabold);font-weight:var(--font-weight-extrabold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-\[-0\.02em\]{--tw-tracking:-.02em;letter-spacing:-.02em}.tracking-\[-0\.03em\]{--tw-tracking:-.03em;letter-spacing:-.03em}.whitespace-nowrap{white-space:nowrap}.text-body{color:var(--text-body)}.text-brand-400{color:var(--brand-400)}.text-brandtext{color:var(--text-brand)}.text-danger{color:var(--danger-600)}.text-info{color:var(--info-600)}.text-muted{color:var(--text-muted)}.text-strong{color:var(--text-strong)}.text-success{color:var(--success-600)}.text-warning{color:var(--warning-600)}.text-white{color:var(--color-white)}.italic{font-style:italic}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.select-none{-webkit-user-select:none;user-select:none}.first\:border-t-0:first-child{border-top-style:var(--tw-border-style);border-top-width:0}@media(hover:hover){.hover\:bg-sunken:hover{background-color:var(--surface-sunken)}}@media(min-width:40rem){.sm\:inline{display:inline}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}.\[\&\>th\]\:px-5>th{padding-inline:calc(var(--spacing) * 5)}.\[\&\>th\]\:py-2\.5>th{padding-block:calc(var(--spacing) * 2.5)}.\[\&\>th\]\:font-medium>th{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}}:root{color-scheme:light;--brand-900:#0b1730;--brand-800:#0f1e3d;--brand-700:#1e40af;--brand-600:#2563eb;--brand-500:#3b82f6;--brand-400:#60a5fa;--brand-300:#93c5fd;--brand-200:#c7dbfb;--brand-100:#e8f0fd;--ink-900:#0f1e3d;--ink-700:#28374f;--ink-600:#3e4e68;--ink-500:#5c6b85;--ink-400:#7a8aa6;--ink-300:#b4bece;--ink-200:#d6deea;--ink-100:#e4e9f2;--ink-50:#eef2f8;--ink-25:#f7f9fc;--white:#fff;--success-600:#1f8a5b;--success-100:#e1f3ea;--warning-600:#d9822b;--warning-100:#fbeddd;--danger-600:#dc2a45;--danger-100:#fbe3e7;--info-600:#2563eb;--info-100:#e8f0fd;--surface-page:var(--ink-25);--surface-card:var(--white);--surface-sunken:var(--ink-50);--border-subtle:var(--ink-100);--border-default:var(--ink-200);--border-strong:var(--ink-300);--text-strong:var(--ink-900);--text-body:var(--ink-600);--text-muted:var(--ink-400);--text-brand:var(--brand-700);--accent:var(--brand-600);--accent-hover:var(--brand-700);--focus-ring:var(--brand-400);--shadow-xs:0 1px 2px #0f1e3d0f;--shadow-sm:0 1px 2px #0f1e3d0a, 0 2px 6px #0f1e3d0f;--shadow-md:0 1px 2px #0f1e3d0a, 0 12px 30px -12px #0f1e3d24;--font-display:"Archivo", system-ui, sans-serif;--font-sans:"Archivo", system-ui, sans-serif;--font-mono:"DM Mono", ui-monospace, "SF Mono", monospace}html.dark{color-scheme:dark;--success-100:#12352a;--warning-100:#3a2a16;--danger-100:#3a1620;--info-100:#122a4d;--surface-page:#0b1730;--surface-card:#13233f;--surface-sunken:#0f1e38;--border-subtle:#21324f;--border-default:#2c3f5e;--border-strong:#3c5173;--text-strong:#f2f6fc;--text-body:#b7c4d9;--text-muted:#7c8ca8;--text-brand:#93c5fd;--accent:#3b82f6;--accent-hover:#60a5fa;--focus-ring:#60a5fa;--success-600:#35b27a;--warning-600:#e0a03a;--danger-600:#e85c74;--shadow-xs:0 1px 2px #0006;--shadow-sm:0 1px 2px #0006, 0 2px 6px #0006;--shadow-md:0 1px 2px #00000059, 0 12px 30px -12px #0000008c}html,body,#app{height:100%}body{font-family:var(--font-sans);background:var(--surface-page);color:var(--text-body);-webkit-font-smoothing:antialiased;margin:0}.eyebrow{font-family:var(--font-mono);text-transform:uppercase;letter-spacing:.16em;color:var(--text-muted);font-size:11px}.data{font-family:var(--font-mono);letter-spacing:.02em;font-variant-numeric:tabular-nums}.dh-btn-ghost{border-radius:var(--radius-control);border:1px solid var(--border-default);background:var(--surface-card);height:34px;color:var(--text-strong);font-family:var(--font-sans);cursor:pointer;justify-content:center;align-items:center;gap:8px;padding:0 12px;font-size:.8125rem;font-weight:600;transition:background-color .14s,border-color .14s;display:inline-flex}.dh-btn-ghost:hover{background:var(--surface-sunken);border-color:var(--border-strong)}.dh-btn-ghost:focus-visible{box-shadow:0 0 0 3px var(--focus-ring);outline:none}.dh-btn{border-radius:var(--radius-control);background:var(--accent);color:#fff;height:34px;font-family:var(--font-sans);cursor:pointer;border:1px solid #0000;justify-content:center;align-items:center;gap:8px;padding:0 14px;font-size:.8125rem;font-weight:600;transition:background-color .14s;display:inline-flex}.dh-btn:hover:not(:disabled){background:var(--accent-hover)}.dh-btn:focus-visible{box-shadow:0 0 0 3px var(--focus-ring);outline:none}.dh-btn:disabled,.dh-btn-ghost:disabled,.dh-btn-danger:disabled{opacity:.55;cursor:not-allowed}.dh-btn-danger{border-radius:var(--radius-control);border:1px solid var(--border-default);height:30px;color:var(--danger-600);font-family:var(--font-sans);cursor:pointer;background:0 0;justify-content:center;align-items:center;gap:6px;padding:0 10px;font-size:.75rem;font-weight:600;transition:background-color .14s,border-color .14s;display:inline-flex}.dh-btn-danger:hover:not(:disabled){background:var(--danger-100);border-color:var(--danger-600)}.dh-input,.dh-select{border-radius:var(--radius-control);border:1px solid var(--border-default);background:var(--surface-card);width:100%;height:36px;color:var(--text-strong);font-family:var(--font-sans);padding:0 10px;font-size:.8125rem;transition:border-color .14s}.dh-input::placeholder{color:var(--text-muted)}.dh-input:focus,.dh-select:focus{border-color:var(--accent);box-shadow:0 0 0 3px var(--focus-ring);outline:none}.dh-checkbox{width:15px;height:15px;accent-color:var(--accent);cursor:pointer;flex:none}.dh-checkbox:focus-visible{box-shadow:0 0 0 3px var(--focus-ring);border-radius:3px;outline:none}.dh-label{font-family:var(--font-mono);text-transform:uppercase;letter-spacing:.16em;color:var(--text-muted);margin-bottom:5px;font-size:10px;display:block}.dh-pill{border-radius:var(--radius-pill);font-family:var(--font-mono);white-space:nowrap;align-items:center;gap:6px;padding:3px 9px;font-size:11px;font-weight:500;display:inline-flex}.dh-card{border:1px solid var(--border-subtle);background:var(--surface-card);border-radius:var(--radius-card);box-shadow:var(--shadow-sm)}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false} diff --git a/API Server/internal/api/dist/index.html b/API Server/internal/api/dist/index.html index 3832a77..6227472 100644 --- a/API Server/internal/api/dist/index.html +++ b/API Server/internal/api/dist/index.html @@ -6,8 +6,8 @@ DriverVault · API Server - - + +
diff --git a/API Server/internal/api/integrations_ankersolix.go b/API Server/internal/api/integrations_ankersolix.go index d823552..da30fc4 100644 --- a/API Server/internal/api/integrations_ankersolix.go +++ b/API Server/internal/api/integrations_ankersolix.go @@ -62,6 +62,52 @@ func normalizeControlMode(v string) string { } } +// ankerControlModesAll lists every control mode, in the order the clients offer +// them. off leads because it is the default and the fallback. +var ankerControlModesAll = []string{ankerControlOff, ankerControlMqtt, ankerControlModbus, ankerControlOwn, ankerControlProxy} + +// parseControlModes reads a stored comma-separated mode list into a set, +// dropping anything unrecognized. off is never in it: monitoring-only is what a +// charger falls back to, so no layer may take it away from the layers below. +func parseControlModes(v string) map[string]bool { + out := map[string]bool{} + for _, part := range strings.Split(v, ",") { + if m := normalizeControlMode(part); m != "" && m != ankerControlOff { + out[m] = true + } + } + return out +} + +// joinControlModes renders a mode set back to its stored form, in the canonical +// order, so what a client sends round-trips to a predictable string. +func joinControlModes(set map[string]bool) string { + return strings.Join(controlModeList(set), ",") +} + +// controlModeList sorts a mode set into the canonical order. +func controlModeList(set map[string]bool) []string { + out := []string{} + for _, m := range ankerControlModesAll { + if set[m] { + out = append(out, m) + } + } + return out +} + +// controlModesOffered lists the modes a layer may still choose once the layers +// above it have hidden theirs. +func controlModesOffered(hidden map[string]bool) []string { + out := []string{} + for _, m := range ankerControlModesAll { + if !hidden[m] { + out = append(out, m) + } + } + return out +} + // ankerConfig is one layer's Anker Solix settings. type ankerConfig struct { Email string `json:"email"` @@ -70,6 +116,12 @@ type ankerConfig struct { // ControlMode is the control path: off | mqtt | modbus | own | proxy. // It resolves independently of the credentials, like Country. ControlMode string `json:"controlMode"` + // ControlModesDisabled is a comma-separated list of modes this layer hides + // from the layers below it — a mode a deployment (or an organization) does + // not want offered at all. It does not constrain this layer's own choice, and + // it never hides off. Meaningful on the global and organization layers only: + // a user has nobody below them. + ControlModesDisabled string `json:"controlModesDisabled,omitempty"` } // ankerChargerBinding is what we know about one charger the caller controls: @@ -128,6 +180,14 @@ type ankerResolution struct { available bool // global master switch (plugin enabled in the panel) orgEnabled bool // org gate (default true; gates the org's users) enabled bool // caller's personal enable flag + + // hiddenForOrg is what the global layer hides from everyone below it; + // hiddenForUser adds what the caller's organization hides from its own users. + // They gate both the pickers the clients draw and which layer's stored mode + // is allowed to take effect. + hiddenForOrg map[string]bool + hiddenForUser map[string]bool + orgHidden map[string]bool // the organization layer's own list, for its editor } // ankerLayerRank orders the cascade layers; a higher number is lower priority. @@ -137,7 +197,8 @@ var ankerLayerRank = map[string]int{"global": 1, "org": 2, "user": 3} // pluginSettings blob (read from their user record). func (s *Server) resolveAnker(ctx context.Context, who *callerIdentity, userRaw json.RawMessage) ankerResolution { g, masterEnabled, _ := s.plugins.RawConfig(ankerPlugin) - gc := ankerConfig{Email: g["email"], Password: g["password"], Country: g["country"], ControlMode: g["controlMode"]} + gc := ankerConfig{Email: g["email"], Password: g["password"], Country: g["country"], + ControlMode: g["controlMode"], ControlModesDisabled: g["controlModesDisabled"]} var oStored ankerStored if who.OrgID != "" { @@ -166,6 +227,21 @@ func (s *Server) resolveAnker(ctx context.Context, who *callerIdentity, userRaw enabled: uStored.Enabled, } + // What each layer below may still be offered. The global list reaches + // everyone; an organization's own list reaches only its users, so it narrows + // the set once more on the way down. + res.hiddenForOrg = parseControlModes(gc.ControlModesDisabled) + res.orgHidden = parseControlModes(oc.ControlModesDisabled) + res.hiddenForUser = map[string]bool{} + for m := range res.hiddenForOrg { + res.hiddenForUser[m] = true + } + if who.OrgID != "" { + for m := range res.orgHidden { + res.hiddenForUser[m] = true + } + } + // Ordered layers, top (highest priority) first. type layer struct { name string @@ -189,13 +265,18 @@ func (s *Server) resolveAnker(ctx context.Context, who *callerIdentity, userRaw // Control mode resolves independently too, defaulting to off (monitoring // only). The highest layer that sets a recognized value wins; an explicit // "off" set above still wins (and locks lower layers to monitoring). + // A mode hidden by a layer above is not merely absent from the picker: a value + // stored below before it was hidden stops taking effect too, so switching a + // mode off really does switch it off everywhere underneath. res.eff.ControlMode = ankerControlOff res.source["controlMode"] = "unset" for _, l := range layers { - if v := normalizeControlMode(l.c.ControlMode); v != "" { - res.eff.ControlMode, res.source["controlMode"] = v, l.name - break + v := normalizeControlMode(l.c.ControlMode) + if v == "" || res.hiddenAt(l.name)[v] { + continue } + res.eff.ControlMode, res.source["controlMode"] = v, l.name + break } // Credentials resolve as a pair from the highest layer with an email, so the @@ -212,6 +293,19 @@ func (s *Server) resolveAnker(ctx context.Context, who *callerIdentity, userRaw return res } +// hiddenAt is the set of modes hidden from one cascade layer by the layers above +// it. The global layer answers to nobody, so nothing is hidden from it. +func (r ankerResolution) hiddenAt(layer string) map[string]bool { + switch layer { + case "org": + return r.hiddenForOrg + case "user": + return r.hiddenForUser + default: + return map[string]bool{} + } +} + // ankerLockedFor reports whether a field whose value comes from source is locked // for a caller whose editable layer is editable (i.e. the value is set above them). func ankerLockedFor(source, editable string) bool { @@ -301,7 +395,13 @@ func (s *Server) ankerScopeView(res ankerResolution, editable string) map[string } return fv } - return map[string]any{ + // The modes this scope may pick from: everything the layers above it left + // standing. A superadmin's read-only view answers as the user layer they are. + hidden := res.hiddenForUser + if editable == "org" { + hidden = res.hiddenForOrg + } + out := map[string]any{ "editableLayer": editable, "fields": map[string]ankerFieldView{ "email": field("email", res.eff.Email, own.Email, false), @@ -309,7 +409,15 @@ func (s *Server) ankerScopeView(res ankerResolution, editable string) map[string "country": field("country", res.eff.Country, own.Country, false), "controlMode": field("controlMode", res.eff.ControlMode, own.ControlMode, false), }, + "controlModes": controlModesOffered(hidden), } + if editable == "org" { + // The organization's own hide-list, which its admin edits here. Modes the + // global layer already hid are not in controlModes above, so they simply + // never come up. + out["controlModesDisabled"] = controlModeList(res.orgHidden) + } + return out } // ankerView builds the masked, client-safe response body from a resolution. @@ -319,6 +427,7 @@ func (s *Server) ankerView(who *callerIdentity, res ankerResolution) map[string] "orgEnabled": res.orgEnabled, "enabled": res.enabled, "controlMode": res.eff.ControlMode, // effective control mode (off|mqtt|modbus|own|proxy) + "controlModes": controlModesOffered(res.hiddenForUser), // modes still offered to this caller "role": who.Role, "orgId": who.OrgID, "canEditOrg": res.canOrg, @@ -430,7 +539,21 @@ func (s *Server) handlePutAnker(w http.ResponseWriter, r *http.Request) { applyField("email", func(c *ankerConfig, v string) { c.Email = v }) applyField("password", func(c *ankerConfig, v string) { c.Password = v }) applyField("country", func(c *ankerConfig, v string) { c.Country = strings.ToUpper(v) }) - applyField("controlMode", func(c *ankerConfig, v string) { c.ControlMode = normalizeControlMode(v) }) + applyField("controlMode", func(c *ankerConfig, v string) { + m := normalizeControlMode(v) + // A mode hidden above is not a choice this layer can make; keep whatever it + // had rather than storing something that would never take effect. + if m != "" && res.hiddenAt(editable)[m] { + return + } + c.ControlMode = m + }) + if editable == "org" { + // Only a layer with users under it has anything to hide from them. + applyField("controlModesDisabled", func(c *ankerConfig, v string) { + c.ControlModesDisabled = joinControlModes(parseControlModes(v)) + }) + } // Persist the organization layer (admins) via the service account. if editable == "org" { diff --git a/API Server/internal/api/integrations_ankersolix_test.go b/API Server/internal/api/integrations_ankersolix_test.go index f5f2797..bebdbd9 100644 --- a/API Server/internal/api/integrations_ankersolix_test.go +++ b/API Server/internal/api/integrations_ankersolix_test.go @@ -241,3 +241,83 @@ func TestAnkerCardRoutesAreRegistered(t *testing.T) { } } } + +func TestParseControlModes(t *testing.T) { + got := parseControlModes(" Proxy , own ,bogus,, off ") + // off is never hideable: monitoring only is what a charger falls back to. + want := map[string]bool{"proxy": true, "own": true} + if len(got) != len(want) { + t.Fatalf("parseControlModes = %v, want %v", got, want) + } + for m := range want { + if !got[m] { + t.Errorf("parseControlModes is missing %q", m) + } + } + if s := joinControlModes(got); s != "own,proxy" { + t.Errorf("joinControlModes = %q, want own,proxy (canonical order)", s) + } +} + +func TestControlModesOffered(t *testing.T) { + got := controlModesOffered(map[string]bool{"own": true, "proxy": true}) + want := []string{"off", "mqtt", "modbus"} + if len(got) != len(want) { + t.Fatalf("controlModesOffered = %v, want %v", got, want) + } + for i, m := range want { + if got[i] != m { + t.Errorf("controlModesOffered[%d] = %q, want %q", i, got[i], m) + } + } +} + +// A mode the global layer hides is not merely absent from a lower picker: a +// value stored below before it was hidden stops taking effect too. +func TestHiddenControlModeDoesNotTakeEffect(t *testing.T) { + res := ankerResolution{ + hiddenForOrg: map[string]bool{"own": true, "proxy": true}, + hiddenForUser: map[string]bool{"own": true, "proxy": true}, + } + if !res.hiddenAt("user")["proxy"] { + t.Error("proxy should be hidden from the user layer") + } + if res.hiddenAt("global")["proxy"] { + t.Error("nothing is hidden from the global layer — it is the one hiding") + } + view := (&Server{}).ankerScopeView(res, "user") + for _, m := range view["controlModes"].([]string) { + if m == "own" || m == "proxy" { + t.Errorf("hidden mode %q is still offered to the user scope", m) + } + } + if _, ok := view["controlModesDisabled"]; ok { + t.Error("the user scope has nobody below it and must carry no hide-list") + } +} + +// An organization narrows the set once more for its own users, and its admin +// edits that list in the org scope. +func TestOrgScopeCarriesItsOwnHideList(t *testing.T) { + res := ankerResolution{ + hiddenForOrg: map[string]bool{"proxy": true}, + hiddenForUser: map[string]bool{"proxy": true, "own": true}, + orgHidden: map[string]bool{"own": true}, + } + org := (&Server{}).ankerScopeView(res, "org") + offered := org["controlModes"].([]string) + var sawOwn, sawProxy bool + for _, m := range offered { + sawOwn = sawOwn || m == "own" + sawProxy = sawProxy || m == "proxy" + } + if !sawOwn { + t.Error("an org may still choose a mode it only hides from its users") + } + if sawProxy { + t.Error("a mode the global layer hid must not reach the org picker") + } + if got := org["controlModesDisabled"].([]string); len(got) != 1 || got[0] != "own" { + t.Errorf("org hide-list = %v, want [own]", got) + } +} diff --git a/API Server/internal/plugins/builtin/ankersolix/ankersolix.go b/API Server/internal/plugins/builtin/ankersolix/ankersolix.go index 48d0165..3d05532 100644 --- a/API Server/internal/plugins/builtin/ankersolix/ankersolix.go +++ b/API Server/internal/plugins/builtin/ankersolix/ankersolix.go @@ -334,6 +334,19 @@ func (p *Plugin) Descriptor() plugins.Descriptor { {Value: "own", Label: "Own CSMS (full control)"}, {Value: "proxy", Label: "Proxy CSMS (relay + control)"}, }}, + // controlModesDisabled hides modes from the layers *below* this one. It + // is how a superadmin takes a mode that is broken or unwanted in this + // deployment (OCPP, say) out of every organization's and user's picker + // without touching the mode this layer itself runs. Organizations carry + // the same field for their own users; see integrations_ankersolix.go. + {Key: "controlModesDisabled", Label: "Hidden control modes", Type: "multiselect", + Help: "Control modes to hide from organizations and users. A hidden mode disappears from their picker and stops taking effect for them; the mode chosen above, which is this layer's own, is unaffected. Off (monitoring only) can never be hidden — it is what a charger falls back to.", + Options: []plugins.SelectOption{ + {Value: "mqtt", Label: "Anker cloud (works anywhere)"}, + {Value: "modbus", Label: "Modbus TCP (local network)"}, + {Value: "own", Label: "Own CSMS (full control)"}, + {Value: "proxy", Label: "Proxy CSMS (relay + control)"}, + }}, }, } } diff --git a/API Server/internal/plugins/builtin/ankersolix/ankersolix_test.go b/API Server/internal/plugins/builtin/ankersolix/ankersolix_test.go index 27d71a4..12b1105 100644 --- a/API Server/internal/plugins/builtin/ankersolix/ankersolix_test.go +++ b/API Server/internal/plugins/builtin/ankersolix/ankersolix_test.go @@ -66,6 +66,31 @@ func TestDescriptor(t *testing.T) { t.Errorf("controlMode is missing option %q", v) } } + + // controlModesDisabled is the superadmin's hide-list: which of the modes the + // organizations and users below are offered at all. off is not among them — + // monitoring only is the fallback, so no layer may take it away. + hide, ok := fields["controlModesDisabled"] + if !ok { + t.Fatal("controlModesDisabled config field should be present") + } + if hide.Type != "multiselect" { + t.Errorf("controlModesDisabled type = %q, want multiselect", hide.Type) + } + hideable := map[string]bool{"mqtt": false, "modbus": false, "own": false, "proxy": false} + for _, o := range hide.Options { + if o.Value == "off" { + t.Error("off must not be hideable — it is what a charger falls back to") + } + if _, known := hideable[o.Value]; known { + hideable[o.Value] = true + } + } + for v, seen := range hideable { + if !seen { + t.Errorf("controlModesDisabled is missing option %q", v) + } + } } func TestRegistered(t *testing.T) { diff --git a/API Server/internal/plugins/plugin.go b/API Server/internal/plugins/plugin.go index b7f23bf..9ae1416 100644 --- a/API Server/internal/plugins/plugin.go +++ b/API Server/internal/plugins/plugin.go @@ -44,7 +44,8 @@ const ( StatusDown = "down" ) -// SelectOption is one choice for a ConfigField of Type "select". +// SelectOption is one choice for a ConfigField of Type "select" (pick one) or +// "multiselect" (pick any number; stored as a comma-separated list of values). type SelectOption struct { Value string `json:"value"` Label string `json:"label"` @@ -55,12 +56,12 @@ type SelectOption struct { type ConfigField struct { Key string `json:"key"` Label string `json:"label"` - Type string `json:"type"` // "text" | "password" | "number" | "select" + Type string `json:"type"` // "text" | "password" | "number" | "select" | "multiselect" Required bool `json:"required"` Secret bool `json:"secret"` // never echoed back to clients in clear Help string `json:"help,omitempty"` Default string `json:"default,omitempty"` // effective default when unset - Options []SelectOption `json:"options,omitempty"` // for Type "select" + Options []SelectOption `json:"options,omitempty"` // for Type "select" and "multiselect" } // Capability is one operation a plugin exposes. It maps a stable id to the diff --git a/API Server/panel/src/components/PluginsCard.vue b/API Server/panel/src/components/PluginsCard.vue index eef1bda..9261562 100644 --- a/API Server/panel/src/components/PluginsCard.vue +++ b/API Server/panel/src/components/PluginsCard.vue @@ -62,6 +62,31 @@ function expand(p) { open.value = p.name; } +// A multiselect field is a comma-separated list of option values in the same +// flat string map every other field uses, so the PUT body stays unchanged. +function multiValues(name, key) { + return String(drafts[name]?.[key] ?? "") + .split(",") + .map((v) => v.trim()) + .filter(Boolean); +} +function hasMulti(name, key, value) { + return multiValues(name, key).includes(value); +} +function toggleMulti(name, key, value, on) { + const set = new Set(multiValues(name, key)); + if (on) set.add(value); + else set.delete(value); + // Keep the declared option order rather than click order, so the stored value + // is stable across edits. + const p = plugins.value.find((x) => x.name === name); + const order = (p?.configFields || []).find((f) => f.key === key)?.options || []; + drafts[name][key] = order + .map((o) => o.value) + .filter((v) => set.has(v)) + .join(","); +} + async function save(p, enabled) { busy.value = true; rowNotice[p.name] = ""; @@ -224,7 +249,25 @@ const healthClass = (s) => - + {{ o.label || o.value }} + + + - - - - - +

{{ ankerSourceLabel('controlMode') }}

{{ t("settings.integrations.controlModeHint") }}

+ +
+ +
+ +
+

{{ t("settings.integrations.controlModesHiddenHint") }}

+