diff --git a/API Server/README.md b/API Server/README.md index 2fe37fa..3a428a1 100644 --- a/API Server/README.md +++ b/API Server/README.md @@ -76,6 +76,22 @@ their own account. An organization cannot be deleted while it still has members. membership. A superadmin spans all organizations; an admin is scoped by the server to their own. Users may have no organization at all. +Creating one is self-service: any user who does not already belong to an +organization may `POST /api/orgs`, and becomes that organization's **admin** and +first member in the same request (if the promotion fails the new organization is +rolled back, so it is never left with nobody able to administer it). A user who +already belongs to one is refused — membership is a single relation, so creating +a second would mean silently abandoning the first. + +A superadmin is the exception: they create organizations without joining them, +since they already span every tenant. + +From there an admin manages **their own** organization — rename it, or delete it +once they are its only member. Deleting it detaches and demotes them back to a +plain `user` before the record is removed, so the organization is empty when it +goes. A superadmin may rename or delete any organization, but still only once it +has no members at all. + ### Per-user car ownership + sharing Cars are not a global list. `cars.owner` marks ownership and `car_shares` grants @@ -139,7 +155,7 @@ POST /api/me/verify/request GET /api/me/export POST /api/me/import POST /api/me/delete POST /api/me/delete/cancel -# users + organizations (admin or superadmin; org writes are superadmin-only) +# users + organizations (admin or superadmin; POST /api/orgs is open to any user) GET /api/users POST /api/users PATCH /api/users/{id} DELETE /api/users/{id} GET /api/orgs POST /api/orgs diff --git a/API Server/internal/api/dist/assets/index-D-rTgBao.js b/API Server/internal/api/dist/assets/index-D-rTgBao.js deleted file mode 100644 index 3ebb755..0000000 --- a/API Server/internal/api/dist/assets/index-D-rTgBao.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 ln(e){const t=Object.create(null);for(const s of e.split(","))t[s]=1;return s=>s in t}const Y={},xt=[],He=()=>{},gi=()=>!1,ks=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),Ss=e=>e.startsWith("onUpdate:"),he=Object.assign,an=(e,t)=>{const s=e.indexOf(t);s>-1&&e.splice(s,1)},$o=Object.prototype.hasOwnProperty,G=(e,t)=>$o.call(e,t),L=Array.isArray,kt=e=>es(e)==="[object Map]",Rt=e=>es(e)==="[object Set]",Rn=e=>es(e)==="[object Date]",H=e=>typeof e=="function",ne=e=>typeof e=="string",Ve=e=>typeof e=="symbol",Z=e=>e!==null&&typeof e=="object",mi=e=>(Z(e)||H(e))&&H(e.then)&&H(e.catch),bi=Object.prototype.toString,es=e=>bi.call(e),Ao=e=>es(e).slice(8,-1),vi=e=>es(e)==="[object Object]",cn=e=>ne(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,Ft=ln(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),Ts=e=>{const t=Object.create(null);return(s=>t[s]||(t[s]=e(s)))},Oo=/-\w/g,Ce=Ts(e=>e.replace(Oo,t=>t.slice(1).toUpperCase())),Ro=/\B([A-Z])/g,ct=Ts(e=>e.replace(Ro,"-$1").toLowerCase()),_i=Ts(e=>e.charAt(0).toUpperCase()+e.slice(1)),Ms=Ts(e=>e?`on${_i(e)}`:""),Be=(e,t)=>!Object.is(e,t),fs=(e,...t)=>{for(let s=0;s{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:n,value:s})},Es=e=>{const t=parseFloat(e);return isNaN(t)?e:t};let In;const Cs=()=>In||(In=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function un(e){if(L(e)){const t={};for(let s=0;s{if(s){const n=s.split(Uo);n.length>1&&(t[n[0].trim()]=n[1].trim())}}),t}function $e(e){let t="";if(ne(e))t=e;else if(L(e))for(let s=0;srt(s,t))}const xi=e=>!!(e&&e.__v_isRef===!0),b=e=>ne(e)?e:e==null?"":L(e)||Z(e)&&(e.toString===bi||!H(e.toString))?xi(e)?b(e.value):JSON.stringify(e,ki,2):String(e),ki=(e,t)=>xi(t)?ki(e,t.value):kt(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((s,[n,i],o)=>(s[Ns(n,o)+" =>"]=i,s),{})}:Rt(t)?{[`Set(${t.size})`]:[...t.values()].map(s=>Ns(s))}:Ve(t)?Ns(t):Z(t)&&!L(t)&&!vi(t)?String(t):t,Ns=(e,t="")=>{var s;return Ve(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 ae;class Lo{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&&ae&&(ae.active?(this.parent=ae,this.index=(ae.scopes||(ae.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(ae===this)ae=this.prevScope;else{let t=ae;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(Ht){let t=Ht;for(Ht=void 0;t;){const s=t.next;t.next=void 0,t.flags&=-9,t=s}}let e;for(;Bt;){let t=Bt;for(Bt=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 Pi(e){let t,s=e.depsTail,n=s;for(;n;){const i=n.prevDep;n.version===-1?(n===s&&(s=i),hn(n),Bo(n)):t=n,n.dep.activeLink=n.prevActiveLink,n.prevActiveLink=void 0,n=i}e.deps=t,e.depsTail=s}function qs(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===qt)||(e.globalVersion=qt,!e.isSSR&&e.flags&128&&(!e.deps&&!e._dirty||!qs(e))))return;e.flags|=2;const t=e.dep,s=Q,n=Pe;Q=e,Pe=!0;try{Ci(e);const i=e.fn(e._value);(t.version===0||Be(i,e._value))&&(e.flags|=128,e._value=i,t.version++)}catch(i){throw t.version++,i}finally{Q=s,Pe=n,Pi(e),e.flags&=-3}}function hn(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)hn(o,!0)}!t&&!--s.sc&&s.map&&s.map.delete(s.key)}function Bo(e){const{prevDep:t,nextDep:s}=e;t&&(t.nextDep=s,e.prevDep=void 0),s&&(s.prevDep=t,e.nextDep=void 0)}let Pe=!0;const Ai=[];function Ke(){Ai.push(Pe),Pe=!1}function We(){const e=Ai.pop();Pe=e===void 0?!0:e}function Un(e){const{cleanup:t}=e;if(e.cleanup=void 0,t){const s=Q;Q=void 0;try{t()}finally{Q=s}}}let qt=0;class Ho{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 gn{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(!Q||!Pe||Q===this.computed)return;let s=this.activeLink;if(s===void 0||s.sub!==Q)s=this.activeLink=new Ho(Q,this),Q.deps?(s.prevDep=Q.depsTail,Q.depsTail.nextDep=s,Q.depsTail=s):Q.deps=Q.depsTail=s,Oi(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=Q.depsTail,s.nextDep=void 0,Q.depsTail.nextDep=s,Q.depsTail=s,Q.deps===s&&(Q.deps=n)}return s}trigger(t){this.version++,qt++,this.notify(t)}notify(t){fn();try{for(let s=this.subs;s;s=s.prevSub)s.sub.notify()&&s.sub.dep.notify()}finally{pn()}}}function Oi(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)Oi(n)}const s=e.dep.subs;s!==e&&(e.prevSub=s,s&&(s.nextSub=e)),e.dep.subs=e}}const Zs=new WeakMap,vt=Symbol(""),Js=Symbol(""),Zt=Symbol("");function ue(e,t,s){if(Pe&&Q){let n=Zs.get(e);n||Zs.set(e,n=new Map);let i=n.get(s);i||(n.set(s,i=new gn),i.map=n,i.key=s),i.track()}}function Je(e,t,s,n,i,o){const r=Zs.get(e);if(!r){qt++;return}const l=a=>{a&&a.trigger()};if(fn(),t==="clear")r.forEach(l);else{const a=L(e),p=a&&cn(s);if(a&&s==="length"){const u=Number(n);r.forEach((m,y)=>{(y==="length"||y===Zt||!Ve(y)&&y>=u)&&l(m)})}else switch((s!==void 0||r.has(void 0))&&l(r.get(s)),p&&l(r.get(Zt)),t){case"add":a?p&&l(r.get("length")):(l(r.get(vt)),kt(e)&&l(r.get(Js)));break;case"delete":a||(l(r.get(vt)),kt(e)&&l(r.get(Js)));break;case"set":kt(e)&&l(r.get(vt));break}}pn()}function yt(e){const t=W(e);return t===e?t:(ue(t,"iterate",Zt),Se(e)?t:t.map(Ae))}function Ps(e){return ue(e=W(e),"iterate",Zt),e}function Le(e,t){return et(e)?Ct(_t(e)?Ae(t):t):Ae(t)}const Vo={__proto__:null,[Symbol.iterator](){return zs(this,Symbol.iterator,e=>Le(this,e))},concat(...e){return yt(this).concat(...e.map(t=>L(t)?yt(t):t))},entries(){return zs(this,"entries",e=>(e[1]=Le(this,e[1]),e))},every(e,t){return Ge(this,"every",e,t,void 0,arguments)},filter(e,t){return Ge(this,"filter",e,t,s=>s.map(n=>Le(this,n)),arguments)},find(e,t){return Ge(this,"find",e,t,s=>Le(this,s),arguments)},findIndex(e,t){return Ge(this,"findIndex",e,t,void 0,arguments)},findLast(e,t){return Ge(this,"findLast",e,t,s=>Le(this,s),arguments)},findLastIndex(e,t){return Ge(this,"findLastIndex",e,t,void 0,arguments)},forEach(e,t){return Ge(this,"forEach",e,t,void 0,arguments)},includes(...e){return Ls(this,"includes",e)},indexOf(...e){return Ls(this,"indexOf",e)},join(e){return yt(this).join(e)},lastIndexOf(...e){return Ls(this,"lastIndexOf",e)},map(e,t){return Ge(this,"map",e,t,void 0,arguments)},pop(){return Nt(this,"pop")},push(...e){return Nt(this,"push",e)},reduce(e,...t){return jn(this,"reduce",e,t)},reduceRight(e,...t){return jn(this,"reduceRight",e,t)},shift(){return Nt(this,"shift")},some(e,t){return Ge(this,"some",e,t,void 0,arguments)},splice(...e){return Nt(this,"splice",e)},toReversed(){return yt(this).toReversed()},toSorted(e){return yt(this).toSorted(e)},toSpliced(...e){return yt(this).toSpliced(...e)},unshift(...e){return Nt(this,"unshift",e)},values(){return zs(this,"values",e=>Le(this,e))}};function zs(e,t,s){const n=Ps(e),i=n[t]();return n!==e&&!Se(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 Ge(e,t,s,n,i,o){const r=Ps(e),l=r!==e&&!Se(e),a=r[t];if(a!==Ko[t]){const m=a.apply(e,o);return l?Ae(m):m}let p=s;r!==e&&(l?p=function(m,y){return s.call(this,Le(e,m),y,e)}:s.length>2&&(p=function(m,y){return s.call(this,m,y,e)}));const u=a.call(r,p,n);return l&&i?i(u):u}function jn(e,t,s,n){const i=Ps(e),o=i!==e&&!Se(e);let r=s,l=!1;i!==e&&(o?(l=n.length===0,r=function(p,u,m){return l&&(l=!1,p=Le(e,p)),s.call(this,p,Le(e,u),m,e)}):s.length>3&&(r=function(p,u,m){return s.call(this,p,u,m,e)}));const a=i[t](r,...n);return l?Le(e,a):a}function Ls(e,t,s){const n=W(e);ue(n,"iterate",Zt);const i=n[t](...s);return(i===-1||i===!1)&&vn(s[0])?(s[0]=W(s[0]),n[t](...s)):i}function Nt(e,t,s=[]){Ke(),fn();const n=W(e)[t].apply(e,s);return pn(),We(),n}const Wo=ln("__proto__,__v_isRef,__isVue"),Ri=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(Ve));function Go(e){Ve(e)||(e=String(e));const t=W(this);return ue(t,"has",e),t.hasOwnProperty(e)}class Ii{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?nr:Ni:o?Mi:ji).get(t)||Object.getPrototypeOf(t)===Object.getPrototypeOf(n)?t:void 0;const r=L(t);if(!i){let a;if(r&&(a=Vo[s]))return a;if(s==="hasOwnProperty")return Go}const l=Reflect.get(t,s,fe(t)?t:n);if((Ve(s)?Ri.has(s):Wo(s))||(i||ue(t,"get",s),o))return l;if(fe(l)){const a=r&&cn(s)?l:l.value;return i&&Z(a)?Xs(a):a}return Z(l)?i?Xs(l):Jt(l):l}}class Ui extends Ii{constructor(t=!1){super(!1,t)}set(t,s,n,i){let o=t[s];const r=L(t)&&cn(s);if(!this._isShallow){const p=et(o);if(!Se(n)&&!et(n)&&(o=W(o),n=W(n)),!r&&fe(o)&&!fe(n))return p||(o.value=n),!0}const l=r?Number(s)e,as=e=>Reflect.getPrototypeOf(e);function Xo(e,t,s){return function(...n){const i=this.__v_raw,o=W(i),r=kt(o),l=e==="entries"||e===Symbol.iterator&&r,a=e==="keys"&&r,p=i[e](...n),u=s?Ys:t?Ct:Ae;return!t&&ue(o,"iterate",a?Js:vt),he(Object.create(p),{next(){const{value:m,done:y}=p.next();return y?{value:m,done:y}:{value:l?[u(m[0]),u(m[1])]:u(m),done:y}}})}}function cs(e){return function(...t){return e==="delete"?!1:e==="clear"?void 0:this}}function Qo(e,t){const s={get(i){const o=this.__v_raw,r=W(o),l=W(i);e||(Be(i,l)&&ue(r,"get",i),ue(r,"get",l));const{has:a}=as(r),p=t?Ys:e?Ct:Ae;if(a.call(r,i))return p(o.get(i));if(a.call(r,l))return p(o.get(l));o!==r&&o.get(i)},get size(){const i=this.__v_raw;return!e&&ue(W(i),"iterate",vt),i.size},has(i){const o=this.__v_raw,r=W(o),l=W(i);return e||(Be(i,l)&&ue(r,"has",i),ue(r,"has",l)),i===l?o.has(i):o.has(i)||o.has(l)},forEach(i,o){const r=this,l=r.__v_raw,a=W(l),p=t?Ys:e?Ct:Ae;return!e&&ue(a,"iterate",vt),l.forEach((u,m)=>i.call(o,p(u),p(m),r))}};return he(s,e?{add:cs("add"),set:cs("set"),delete:cs("delete"),clear:cs("clear")}:{add(i){const o=W(this),r=as(o),l=W(i),a=!t&&!Se(i)&&!et(i)?l:i;return r.has.call(o,a)||Be(i,a)&&r.has.call(o,i)||Be(l,a)&&r.has.call(o,l)||(o.add(a),Je(o,"add",a,a)),this},set(i,o){!t&&!Se(o)&&!et(o)&&(o=W(o));const r=W(this),{has:l,get:a}=as(r);let p=l.call(r,i);p||(i=W(i),p=l.call(r,i));const u=a.call(r,i);return r.set(i,o),p?Be(o,u)&&Je(r,"set",i,o):Je(r,"add",i,o),this},delete(i){const o=W(this),{has:r,get:l}=as(o);let a=r.call(o,i);a||(i=W(i),a=r.call(o,i)),l&&l.call(o,i);const p=o.delete(i);return a&&Je(o,"delete",i,void 0),p},clear(){const i=W(this),o=i.size!==0,r=i.clear();return o&&Je(i,"clear",void 0,void 0),r}}),["keys","values","entries",Symbol.iterator].forEach(i=>{s[i]=Xo(i,e,t)}),s}function mn(e,t){const s=Qo(e,t);return(n,i,o)=>i==="__v_isReactive"?!e:i==="__v_isReadonly"?e:i==="__v_raw"?n:Reflect.get(G(s,i)&&i in n?s:n,i,o)}const er={get:mn(!1,!1)},tr={get:mn(!1,!0)},sr={get:mn(!0,!1)};const ji=new WeakMap,Mi=new WeakMap,Ni=new WeakMap,nr=new WeakMap;function ir(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function Jt(e){return et(e)?e:bn(e,!1,Zo,er,ji)}function or(e){return bn(e,!1,Yo,tr,Mi)}function Xs(e){return bn(e,!0,Jo,sr,Ni)}function bn(e,t,s,n,i){if(!Z(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=ir(Ao(e));if(r===0)return e;const l=new Proxy(e,r===2?n:s);return i.set(e,l),l}function _t(e){return et(e)?_t(e.__v_raw):!!(e&&e.__v_isReactive)}function et(e){return!!(e&&e.__v_isReadonly)}function Se(e){return!!(e&&e.__v_isShallow)}function vn(e){return e?!!e.__v_raw:!1}function W(e){const t=e&&e.__v_raw;return t?W(t):e}function rr(e){return!G(e,"__v_skip")&&Object.isExtensible(e)&&yi(e,"__v_skip",!0),e}const Ae=e=>Z(e)?Jt(e):e,Ct=e=>Z(e)?Xs(e):e;function fe(e){return e?e.__v_isRef===!0:!1}function V(e){return lr(e,!1)}function lr(e,t){return fe(e)?e:new ar(e,t)}class ar{constructor(t,s){this.dep=new gn,this.__v_isRef=!0,this.__v_isShallow=!1,this._rawValue=s?t:W(t),this._value=s?t:Ae(t),this.__v_isShallow=s}get value(){return this.dep.track(),this._value}set value(t){const s=this._rawValue,n=this.__v_isShallow||Se(t)||et(t);t=n?t:W(t),Be(t,s)&&(this._rawValue=t,this._value=n?t:Ae(t),this.dep.trigger())}}function g(e){return fe(e)?e.value:e}const cr={get:(e,t,s)=>t==="__v_raw"?e:g(Reflect.get(e,t,s)),set:(e,t,s,n)=>{const i=e[t];return fe(i)&&!fe(s)?(i.value=s,!0):Reflect.set(e,t,s,n)}};function Di(e){return _t(e)?e:new Proxy(e,cr)}class ur{constructor(t,s,n){this.fn=t,this.setter=s,this._value=void 0,this.dep=new gn(this),this.__v_isRef=!0,this.deps=void 0,this.depsTail=void 0,this.flags=16,this.globalVersion=qt-1,this.next=void 0,this.effect=this,this.__v_isReadonly=!s,this.isSSR=n}notify(){if(this.flags|=16,!(this.flags&8)&&Q!==this)return Ei(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 dr(e,t,s=!1){let n,i;return H(e)?n=e:(n=e.get,i=e.set),new ur(n,i,s)}const us={},gs=new WeakMap;let mt;function fr(e,t=!1,s=mt){if(s){let n=gs.get(s);n||gs.set(s,n=[]),n.push(e)}}function pr(e,t,s=Y){const{immediate:n,deep:i,once:o,scheduler:r,augmentJob:l,call:a}=s,p=M=>i?M:Se(M)||i===!1||i===0?Ye(M,1):Ye(M);let u,m,y,A,D=!1,C=!1;if(fe(e)?(m=()=>e.value,D=Se(e)):_t(e)?(m=()=>p(e),D=!0):L(e)?(C=!0,D=e.some(M=>_t(M)||Se(M)),m=()=>e.map(M=>{if(fe(M))return M.value;if(_t(M))return p(M);if(H(M))return a?a(M,2):M()})):H(e)?t?m=a?()=>a(e,2):e:m=()=>{if(y){Ke();try{y()}finally{We()}}const M=mt;mt=u;try{return a?a(e,3,[A]):e(A)}finally{mt=M}}:m=He,t&&i){const M=m,oe=i===!0?1/0:i;m=()=>Ye(M(),oe)}const P=Fo(),T=()=>{u.stop(),P&&P.active&&an(P.effects,u)};if(o&&t){const M=t;t=(...oe)=>{const Re=M(...oe);return T(),Re}}let $=C?new Array(e.length).fill(us):us;const j=M=>{if(!(!(u.flags&1)||!u.dirty&&!M))if(t){const oe=u.run();if(M||i||D||(C?oe.some((Re,Ie)=>Be(Re,$[Ie])):Be(oe,$))){y&&y();const Re=mt;mt=u;try{const Ie=[oe,$===us?void 0:C&&$[0]===us?[]:$,A];$=oe,a?a(t,3,Ie):t(...Ie)}finally{mt=Re}}}else u.run()};return l&&l(j),u=new Si(m),u.scheduler=r?()=>r(j,!1):j,A=M=>fr(M,!1,u),y=u.onStop=()=>{const M=gs.get(u);if(M){if(a)a(M,4);else for(const oe of M)oe();gs.delete(u)}},t?n?j(!0):$=u.run():r?r(j.bind(null,!0),!0):u.run(),T.pause=u.pause.bind(u),T.resume=u.resume.bind(u),T.stop=T,T}function Ye(e,t=1/0,s){if(t<=0||!Z(e)||e.__v_skip||(s=s||new Map,(s.get(e)||0)>=t))return e;if(s.set(e,t),t--,fe(e))Ye(e.value,t,s);else if(L(e))for(let n=0;n{Ye(n,t,s)});else if(vi(e)){for(const n in e)Ye(e[n],t,s);for(const n of Object.getOwnPropertySymbols(e))Object.prototype.propertyIsEnumerable.call(e,n)&&Ye(e[n],t,s)}return e}/** -* @vue/runtime-core v3.5.39 -* (c) 2018-present Yuxi (Evan) You and Vue contributors -* @license MIT -**/function ts(e,t,s,n){try{return n?e(...n):e()}catch(i){$s(i,t,s)}}function Oe(e,t,s,n){if(H(e)){const i=ts(e,t,s,n);return i&&mi(i)&&i.catch(o=>{$s(o,t,s)}),i}if(L(e)){const i=[];for(let o=0;o>>1,i=be[n],o=Yt(i);o=Yt(s)?be.push(e):be.splice(gr(t),0,e),e.flags|=1,Fi()}}function Fi(){ms||(ms=zi.then(Hi))}function mr(e){L(e)?St.push(...e):ot&&e.id===-1?ot.splice(wt+1,0,e):e.flags&1||(St.push(e),e.flags|=1),Fi()}function Mn(e,t,s=ze+1){for(;sYt(s)-Yt(n));if(St.length=0,ot){ot.push(...t);return}for(ot=t,wt=0;wte.id==null?e.flags&2?-1:1/0:e.id;function Hi(e){try{for(ze=0;ze{n._d&&Gn(-1);const o=bs(t);let r;try{r=e(...i)}finally{bs(o),n._d&&Gn(1)}return r};return n._n=!0,n._c=!0,n._d=!0,n}function re(e,t){if(xe===null)return e;const s=Is(xe),n=e.dirs||(e.dirs=[]);for(let i=0;i1)return s&&H(t)?t.call(n&&n.proxy):t}}const _r=Symbol.for("v-scx"),yr=()=>ps(_r);function Fs(e,t,s){return Ki(e,t,s)}function Ki(e,t,s=Y){const{immediate:n,deep:i,flush:o,once:r}=s,l=he({},s),a=t&&n||!t&&o!=="post";let p;if(Qt){if(o==="sync"){const A=yr();p=A.__watcherHandles||(A.__watcherHandles=[])}else if(!a){const A=()=>{};return A.stop=He,A.resume=He,A.pause=He,A}}const u=ve;l.call=(A,D,C)=>Oe(A,u,D,C);let m=!1;o==="post"?l.scheduler=A=>{_e(A,u&&u.suspense)}:o!=="sync"&&(m=!0,l.scheduler=(A,D)=>{D?A():_n(A)}),l.augmentJob=A=>{t&&(A.flags|=4),m&&(A.flags|=2,u&&(A.id=u.uid,A.i=u))};const y=pr(e,t,l);return Qt&&(p?p.push(y):a&&y()),y}function wr(e,t,s){const n=this.proxy,i=ne(e)?e.includes(".")?Wi(n,e):()=>n[e]:e.bind(n,n);let o;H(t)?o=t:(o=t.handler,s=t);const r=ss(this),l=Ki(i,o.bind(n),s);return r(),l}function Wi(e,t){const s=t.split(".");return()=>{let n=e;for(let i=0;ie.__isTeleport,Bs=Symbol("_leaveCb");function yn(e,t){e.shapeFlag&6&&e.component?(e.transition=t,yn(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 Gi(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 vs=new WeakMap;function Vt(e,t,s,n,i=!1){if(L(e)){e.forEach((C,P)=>Vt(C,t&&(L(t)?t[P]:t),s,n,i));return}if(Kt(n)&&!i){n.shapeFlag&512&&n.type.__asyncResolved&&n.component.subTree.component&&Vt(e,t,s,n.component.subTree);return}const o=n.shapeFlag&4?Is(n.component):n.el,r=i?null:o,{i:l,r:a}=e,p=t&&t.r,u=l.refs===Y?l.refs={}:l.refs,m=l.setupState,y=W(m),A=m===Y?gi:C=>Nn(u,C)?!1:G(y,C),D=(C,P)=>!(P&&Nn(u,P));if(p!=null&&p!==a){if(Dn(t),ne(p))u[p]=null,A(p)&&(m[p]=null);else if(fe(p)){const C=t;D(p,C.k)&&(p.value=null),C.k&&(u[C.k]=null)}}if(H(a)){Ke();try{ts(a,l,12,[r,u])}finally{We()}}else{const C=ne(a),P=fe(a);if(C||P){const T=()=>{if(e.f){const $=C?A(a)?m[a]:u[a]:D()||!e.k?a.value:u[e.k];if(i)L($)&&an($,o);else if(L($))$.includes(o)||$.push(o);else if(C)u[a]=[o],A(a)&&(m[a]=u[a]);else{const j=[o];D(a,e.k)&&(a.value=j),e.k&&(u[e.k]=j)}}else C?(u[a]=r,A(a)&&(m[a]=r)):P&&(D(a,e.k)&&(a.value=r),e.k&&(u[e.k]=r))};if(r){const $=()=>{T(),vs.delete(e)};$.id=-1,vs.set(e,$),_e($,s)}else Dn(e),T()}}}function Dn(e){const t=vs.get(e);t&&(t.flags|=8,vs.delete(e))}Cs().requestIdleCallback;Cs().cancelIdleCallback;const Kt=e=>!!e.type.__asyncLoader,qi=e=>e.type.__isKeepAlive;function Sr(e,t){Zi(e,"a",t)}function Tr(e,t){Zi(e,"da",t)}function Zi(e,t,s=ve){const n=e.__wdc||(e.__wdc=()=>{let i=s;for(;i;){if(i.isDeactivated)return;i=i.parent}return e()});if(As(t,n,s),s){let i=s.parent;for(;i&&i.parent;)qi(i.parent.vnode)&&Er(n,t,s,i),i=i.parent}}function Er(e,t,s,n){const i=As(t,e,n,!0);wn(()=>{an(n[t],i)},s)}function As(e,t,s=ve,n=!1){if(s){const i=s[e]||(s[e]=[]),o=t.__weh||(t.__weh=(...r)=>{Ke();const l=ss(s),a=Oe(t,s,e,r);return l(),We(),a});return n?i.unshift(o):i.push(o),o}}const tt=e=>(t,s=ve)=>{(!Qt||e==="sp")&&As(e,(...n)=>t(...n),s)},Cr=tt("bm"),ut=tt("m"),Pr=tt("bu"),$r=tt("u"),Ar=tt("bum"),wn=tt("um"),Or=tt("sp"),Rr=tt("rtg"),Ir=tt("rtc");function Ur(e,t=ve){As("ec",e,t)}const jr=Symbol.for("v-ndc");function ke(e,t,s,n){let i;const o=s,r=L(e);if(r||ne(e)){const l=r&&_t(e);let a=!1,p=!1;l&&(a=!Se(e),p=et(e),e=Ps(e)),i=new Array(e.length);for(let u=0,m=e.length;ut(l,a,void 0,o));else{const l=Object.keys(e);i=new Array(l.length);for(let a=0,p=l.length;ae?bo(e)?Is(e):Qs(e.parent):null,Wt=he(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=>Qs(e.parent),$root:e=>Qs(e.root),$host:e=>e.ce,$emit:e=>e.emit,$options:e=>Yi(e),$forceUpdate:e=>e.f||(e.f=()=>{_n(e.update)}),$nextTick:e=>e.n||(e.n=Li.bind(e.proxy)),$watch:e=>wr.bind(e)}),Hs=(e,t)=>e!==Y&&!e.__isScriptSetup&&G(e,t),Mr={get({_:e},t){if(t==="__v_skip")return!0;const{ctx:s,setupState:n,data:i,props:o,accessCache:r,type:l,appContext:a}=e;if(t[0]!=="$"){const y=r[t];if(y!==void 0)switch(y){case 1:return n[t];case 2:return i[t];case 4:return s[t];case 3:return o[t]}else{if(Hs(n,t))return r[t]=1,n[t];if(i!==Y&&G(i,t))return r[t]=2,i[t];if(G(o,t))return r[t]=3,o[t];if(s!==Y&&G(s,t))return r[t]=4,s[t];en&&(r[t]=0)}}const p=Wt[t];let u,m;if(p)return t==="$attrs"&&ue(e.attrs,"get",""),p(e);if((u=l.__cssModules)&&(u=u[t]))return u;if(s!==Y&&G(s,t))return r[t]=4,s[t];if(m=a.config.globalProperties,G(m,t))return m[t]},set({_:e},t,s){const{data:n,setupState:i,ctx:o}=e;return Hs(i,t)?(i[t]=s,!0):n!==Y&&G(n,t)?(n[t]=s,!0):G(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}},l){let a;return!!(s[l]||e!==Y&&l[0]!=="$"&&G(e,l)||Hs(t,l)||G(o,l)||G(n,l)||G(Wt,l)||G(i.config.globalProperties,l)||(a=r.__cssModules)&&a[l])},defineProperty(e,t,s){return s.get!=null?e._.accessCache[t]=0:G(s,"value")&&this.set(e,t,s.value,null),Reflect.defineProperty(e,t,s)}};function zn(e){return L(e)?e.reduce((t,s)=>(t[s]=null,t),{}):e}let en=!0;function Nr(e){const t=Yi(e),s=e.proxy,n=e.ctx;en=!1,t.beforeCreate&&Ln(t.beforeCreate,e,"bc");const{data:i,computed:o,methods:r,watch:l,provide:a,inject:p,created:u,beforeMount:m,mounted:y,beforeUpdate:A,updated:D,activated:C,deactivated:P,beforeDestroy:T,beforeUnmount:$,destroyed:j,unmounted:M,render:oe,renderTracked:Re,renderTriggered:Ie,errorCaptured:st,serverPrefetch:ns,expose:dt,inheritAttrs:It,components:is,directives:os,filters:Us}=t;if(p&&Dr(p,n,null),r)for(const te in r){const X=r[te];H(X)&&(n[te]=X.bind(s))}if(i){const te=i.call(s,s);Z(te)&&(e.data=Jt(te))}if(en=!0,o)for(const te in o){const X=o[te],ft=H(X)?X.bind(s,s):H(X.get)?X.get.bind(s,s):He,rs=!H(X)&&H(X.set)?X.set.bind(s):He,pt=Qe({get:ft,set:rs});Object.defineProperty(n,te,{enumerable:!0,configurable:!0,get:()=>pt.value,set:Ue=>pt.value=Ue})}if(l)for(const te in l)Ji(l[te],n,s,te);if(a){const te=H(a)?a.call(s):a;Reflect.ownKeys(te).forEach(X=>{vr(X,te[X])})}u&&Ln(u,e,"c");function ge(te,X){L(X)?X.forEach(ft=>te(ft.bind(s))):X&&te(X.bind(s))}if(ge(Cr,m),ge(ut,y),ge(Pr,A),ge($r,D),ge(Sr,C),ge(Tr,P),ge(Ur,st),ge(Ir,Re),ge(Rr,Ie),ge(Ar,$),ge(wn,M),ge(Or,ns),L(dt))if(dt.length){const te=e.exposed||(e.exposed={});dt.forEach(X=>{Object.defineProperty(te,X,{get:()=>s[X],set:ft=>s[X]=ft,enumerable:!0})})}else e.exposed||(e.exposed={});oe&&e.render===He&&(e.render=oe),It!=null&&(e.inheritAttrs=It),is&&(e.components=is),os&&(e.directives=os),ns&&Gi(e)}function Dr(e,t,s=He){L(e)&&(e=tn(e));for(const n in e){const i=e[n];let o;Z(i)?"default"in i?o=ps(i.from||n,i.default,!0):o=ps(i.from||n):o=ps(i),fe(o)?Object.defineProperty(t,n,{enumerable:!0,configurable:!0,get:()=>o.value,set:r=>o.value=r}):t[n]=o}}function Ln(e,t,s){Oe(L(e)?e.map(n=>n.bind(t.proxy)):e.bind(t.proxy),t,s)}function Ji(e,t,s,n){let i=n.includes(".")?Wi(s,n):()=>s[n];if(ne(e)){const o=t[e];H(o)&&Fs(i,o)}else if(H(e))Fs(i,e.bind(s));else if(Z(e))if(L(e))e.forEach(o=>Ji(o,t,s,n));else{const o=H(e.handler)?e.handler.bind(s):t[e.handler];H(o)&&Fs(i,o,e)}}function Yi(e){const t=e.type,{mixins:s,extends:n}=t,{mixins:i,optionsCache:o,config:{optionMergeStrategies:r}}=e.appContext,l=o.get(t);let a;return l?a=l:!i.length&&!s&&!n?a=t:(a={},i.length&&i.forEach(p=>_s(a,p,r,!0)),_s(a,t,r)),Z(t)&&o.set(t,a),a}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 l=zr[r]||s&&s[r];e[r]=l?l(e[r],t[r]):t[r]}return e}const zr={data:Fn,props:Bn,emits:Bn,methods:zt,computed:zt,beforeCreate:me,created:me,beforeMount:me,mounted:me,beforeUpdate:me,updated:me,beforeDestroy:me,beforeUnmount:me,destroyed:me,unmounted:me,activated:me,deactivated:me,errorCaptured:me,serverPrefetch:me,components:zt,directives:zt,watch:Fr,provide:Fn,inject:Lr};function Fn(e,t){return t?e?function(){return he(H(e)?e.call(this,this):e,H(t)?t.call(this,this):t)}:t:e}function Lr(e,t){return zt(tn(e),tn(t))}function tn(e){if(L(e)){const t={};for(let s=0;st==="modelValue"||t==="model-value"?e.modelModifiers:e[`${t}Modifiers`]||e[`${Ce(t)}Modifiers`]||e[`${ct(t)}Modifiers`];function Kr(e,t,...s){if(e.isUnmounted)return;const n=e.vnode.props||Y;let i=s;const o=t.startsWith("update:"),r=o&&Vr(n,t.slice(7));r&&(r.trim&&(i=s.map(u=>ne(u)?u.trim():u)),r.number&&(i=s.map(Es)));let l,a=n[l=Ms(t)]||n[l=Ms(Ce(t))];!a&&o&&(a=n[l=Ms(ct(t))]),a&&Oe(a,e,6,i);const p=n[l+"Once"];if(p){if(!e.emitted)e.emitted={};else if(e.emitted[l])return;e.emitted[l]=!0,Oe(p,e,6,i)}}const Wr=new WeakMap;function Qi(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={},l=!1;if(!H(e)){const a=p=>{const u=Qi(p,t,!0);u&&(l=!0,he(r,u))};!s&&t.mixins.length&&t.mixins.forEach(a),e.extends&&a(e.extends),e.mixins&&e.mixins.forEach(a)}return!o&&!l?(Z(e)&&n.set(e,null),null):(L(o)?o.forEach(a=>r[a]=null):he(r,o),Z(e)&&n.set(e,r),r)}function Os(e,t){return!e||!ks(t)?!1:(t=t.slice(2),t=t==="Once"?t:t.replace(/Once$/,""),G(e,t[0].toLowerCase()+t.slice(1))||G(e,ct(t))||G(e,t))}function Hn(e){const{type:t,vnode:s,proxy:n,withProxy:i,propsOptions:[o],slots:r,attrs:l,emit:a,render:p,renderCache:u,props:m,data:y,setupState:A,ctx:D,inheritAttrs:C}=e,P=bs(e);let T,$;try{if(s.shapeFlag&4){const M=i||n,oe=M;T=Fe(p.call(oe,M,u,m,A,y,D)),$=l}else{const M=t;T=Fe(M.length>1?M(m,{attrs:l,slots:r,emit:a}):M(m,null)),$=t.props?l:Gr(l)}}catch(M){Gt.length=0,$s(M,e,1),T=ce(lt)}let j=T;if($&&C!==!1){const M=Object.keys($),{shapeFlag:oe}=j;M.length&&oe&7&&(o&&M.some(Ss)&&($=qr($,o)),j=Pt(j,$,!1,!0))}return s.dirs&&(j=Pt(j,null,!1,!0),j.dirs=j.dirs?j.dirs.concat(s.dirs):s.dirs),s.transition&&yn(j,s.transition),T=j,bs(P),T}const Gr=e=>{let t;for(const s in e)(s==="class"||s==="style"||ks(s))&&((t||(t={}))[s]=e[s]);return t},qr=(e,t)=>{const s={};for(const n in e)(!Ss(n)||!(n.slice(9)in t))&&(s[n]=e[n]);return s};function Zr(e,t,s){const{props:n,children:i,component:o}=e,{props:r,children:l,patchFlag:a}=t,p=o.emitsOptions;if(t.dirs||t.transition)return!0;if(s&&a>=0){if(a&1024)return!0;if(a&16)return n?Vn(n,r,p):!!r;if(a&8){const u=t.dynamicProps;for(let m=0;mObject.create(to),no=e=>Object.getPrototypeOf(e)===to;function Yr(e,t,s,n=!1){const i={},o=so();e.propsDefaults=Object.create(null),io(e,t,i,o);for(const r in e.propsOptions[0])r in i||(i[r]=void 0);s?e.props=n?i:or(i):e.type.props?e.props=i:e.props=o,e.attrs=o}function Xr(e,t,s,n){const{props:i,attrs:o,vnode:{patchFlag:r}}=e,l=W(i),[a]=e.propsOptions;let p=!1;if((n||r>0)&&!(r&16)){if(r&8){const u=e.vnode.dynamicProps;for(let m=0;m{a=!0;const[y,A]=oo(m,t,!0);he(r,y),A&&l.push(...A)};!s&&t.mixins.length&&t.mixins.forEach(u),e.extends&&u(e.extends),e.mixins&&e.mixins.forEach(u)}if(!o&&!a)return Z(e)&&n.set(e,xt),xt;if(L(o))for(let u=0;ue==="_"||e==="_ctx"||e==="$stable",kn=e=>L(e)?e.map(Fe):[Fe(e)],el=(e,t,s)=>{if(t._n)return t;const n=br((...i)=>kn(t(...i)),s);return n._c=!1,n},ro=(e,t,s)=>{const n=e._ctx;for(const i in e){if(xn(i))continue;const o=e[i];if(H(o))t[i]=el(i,o,n);else if(o!=null){const r=kn(o);t[i]=()=>r}}},lo=(e,t)=>{const s=kn(t);e.slots.default=()=>s},ao=(e,t,s)=>{for(const n in t)(s||!xn(n))&&(e[n]=t[n])},tl=(e,t,s)=>{const n=e.slots=so();if(e.vnode.shapeFlag&32){const i=t._;i?(ao(n,t,s),s&&yi(n,"_",i,!0)):ro(t,n)}else t&&lo(e,t)},sl=(e,t,s)=>{const{vnode:n,slots:i}=e;let o=!0,r=Y;if(n.shapeFlag&32){const l=t._;l?s&&l===1?o=!1:ao(i,t,s):(o=!t.$stable,ro(t,i)),r=t}else t&&(lo(e,t),r={default:1});if(o)for(const l in i)!xn(l)&&r[l]==null&&delete i[l]},_e=ll;function nl(e){return il(e)}function il(e,t){const s=Cs();s.__VUE__=!0;const{insert:n,remove:i,patchProp:o,createElement:r,createText:l,createComment:a,setText:p,setElementText:u,parentNode:m,nextSibling:y,setScopeId:A=He,insertStaticContent:D}=e,C=(c,f,v,S=null,x=null,_=null,I=void 0,R=null,O=!!f.dynamicChildren)=>{if(c===f)return;c&&!Dt(c,f)&&(S=ls(c),Ue(c,x,_,!0),c=null),f.patchFlag===-2&&(O=!1,f.dynamicChildren=null);const{type:w,ref:z,shapeFlag:U}=f;switch(w){case Rs:P(c,f,v,S);break;case lt:T(c,f,v,S);break;case Ks:c==null&&$(f,v,S,I);break;case ee:is(c,f,v,S,x,_,I,R,O);break;default:U&1?oe(c,f,v,S,x,_,I,R,O):U&6?os(c,f,v,S,x,_,I,R,O):(U&64||U&128)&&w.process(c,f,v,S,x,_,I,R,O,jt)}z!=null&&x?Vt(z,c&&c.ref,_,f||c,!f):z==null&&c&&c.ref!=null&&Vt(c.ref,null,_,c,!0)},P=(c,f,v,S)=>{if(c==null)n(f.el=l(f.children),v,S);else{const x=f.el=c.el;f.children!==c.children&&p(x,f.children)}},T=(c,f,v,S)=>{c==null?n(f.el=a(f.children||""),v,S):f.el=c.el},$=(c,f,v,S)=>{[c.el,c.anchor]=D(c.children,f,v,S,c.el,c.anchor)},j=({el:c,anchor:f},v,S)=>{let x;for(;c&&c!==f;)x=y(c),n(c,v,S),c=x;n(f,v,S)},M=({el:c,anchor:f})=>{let v;for(;c&&c!==f;)v=y(c),i(c),c=v;i(f)},oe=(c,f,v,S,x,_,I,R,O)=>{if(f.type==="svg"?I="svg":f.type==="math"&&(I="mathml"),c==null)Re(f,v,S,x,_,I,R,O);else{const w=c.el&&c.el._isVueCE?c.el:null;try{w&&w._beginPatch(),ns(c,f,x,_,I,R,O)}finally{w&&w._endPatch()}}},Re=(c,f,v,S,x,_,I,R)=>{let O,w;const{props:z,shapeFlag:U,transition:N,dirs:F}=c;if(O=c.el=r(c.type,_,z&&z.is,z),U&8?u(O,c.children):U&16&&st(c.children,O,null,S,x,Vs(c,_),I,R),F&&ht(c,null,S,"created"),Ie(O,c,c.scopeId,I,S),z){for(const J in z)J!=="value"&&!Ft(J)&&o(O,J,null,z[J],_,S);"value"in z&&o(O,"value",null,z.value,_),(w=z.onVnodeBeforeMount)&&De(w,S,c)}F&&ht(c,null,S,"beforeMount");const K=ol(x,N);K&&N.beforeEnter(O),n(O,f,v),((w=z&&z.onVnodeMounted)||K||F)&&_e(()=>{try{w&&De(w,S,c),K&&N.enter(O),F&&ht(c,null,S,"mounted")}finally{}},x)},Ie=(c,f,v,S,x)=>{if(v&&A(c,v),S)for(let _=0;_{for(let w=O;w{const R=f.el=c.el;let{patchFlag:O,dynamicChildren:w,dirs:z}=f;O|=c.patchFlag&16;const U=c.props||Y,N=f.props||Y;let F;if(v&>(v,!1),(F=N.onVnodeBeforeUpdate)&&De(F,v,f,c),z&&ht(f,c,v,"beforeUpdate"),v&>(v,!0),w&&(!c.dynamicChildren||c.dynamicChildren.length!==w.length)&&(O=0,I=!1,w=null),(U.innerHTML&&N.innerHTML==null||U.textContent&&N.textContent==null)&&u(R,""),w?dt(c.dynamicChildren,w,R,v,S,Vs(f,x),_):I||X(c,f,R,null,v,S,Vs(f,x),_,!1),O>0){if(O&16)It(R,U,N,v,x);else if(O&2&&U.class!==N.class&&o(R,"class",null,N.class,x),O&4&&o(R,"style",U.style,N.style,x),O&8){const K=f.dynamicProps;for(let J=0;J{F&&De(F,v,f,c),z&&ht(f,c,v,"updated")},S)},dt=(c,f,v,S,x,_,I)=>{for(let R=0;R{if(f!==v){if(f!==Y)for(const _ in f)!Ft(_)&&!(_ in v)&&o(c,_,f[_],null,x,S);for(const _ in v){if(Ft(_))continue;const I=v[_],R=f[_];I!==R&&_!=="value"&&o(c,_,R,I,x,S)}"value"in v&&o(c,"value",f.value,v.value,x)}},is=(c,f,v,S,x,_,I,R,O)=>{const w=f.el=c?c.el:l(""),z=f.anchor=c?c.anchor:l("");let{patchFlag:U,dynamicChildren:N,slotScopeIds:F}=f;F&&(R=R?R.concat(F):F),c==null?(n(w,v,S),n(z,v,S),st(f.children||[],v,z,x,_,I,R,O)):U>0&&U&64&&N&&c.dynamicChildren&&c.dynamicChildren.length===N.length?(dt(c.dynamicChildren,N,v,x,_,I,R),(f.key!=null||x&&f===x.subTree)&&co(c,f,!0)):X(c,f,v,z,x,_,I,R,O)},os=(c,f,v,S,x,_,I,R,O)=>{f.slotScopeIds=R,c==null?f.shapeFlag&512?x.ctx.activate(f,v,S,I,O):Us(f,v,S,x,_,I,O):En(c,f,O)},Us=(c,f,v,S,x,_,I)=>{const R=c.component=hl(c,S,x);if(qi(c)&&(R.ctx.renderer=jt),ml(R,!1,I),R.asyncDep){if(x&&x.registerDep(R,ge,I),!c.el){const O=R.subTree=ce(lt);T(null,O,f,v),c.placeholder=O.el}}else ge(R,c,f,v,x,_,I)},En=(c,f,v)=>{const S=f.component=c.component;if(Zr(c,f,v))if(S.asyncDep&&!S.asyncResolved){te(S,f,v);return}else S.next=f,S.update();else f.el=c.el,S.vnode=f},ge=(c,f,v,S,x,_,I)=>{const R=()=>{if(c.isMounted){let{next:U,bu:N,u:F,parent:K,vnode:J}=c;{const Me=uo(c);if(Me){U&&(U.el=J.el,te(c,U,I)),Me.asyncDep.then(()=>{_e(()=>{c.isUnmounted||w()},x)});return}}let q=U,ie;gt(c,!1),U?(U.el=J.el,te(c,U,I)):U=J,N&&fs(N),(ie=U.props&&U.props.onVnodeBeforeUpdate)&&De(ie,K,U,J),gt(c,!0);const le=Hn(c),je=c.subTree;c.subTree=le,C(je,le,m(je.el),ls(je),c,x,_),U.el=le.el,q===null&&Jr(c,le.el),F&&_e(F,x),(ie=U.props&&U.props.onVnodeUpdated)&&_e(()=>De(ie,K,U,J),x)}else{let U;const{el:N,props:F}=f,{bm:K,m:J,parent:q,root:ie,type:le}=c,je=Kt(f);gt(c,!1),K&&fs(K),!je&&(U=F&&F.onVnodeBeforeMount)&&De(U,q,f),gt(c,!0);{ie.ce&&ie.ce._hasShadowRoot()&&ie.ce._injectChildStyle(le,c.parent?c.parent.type:void 0);const Me=c.subTree=Hn(c);C(null,Me,v,S,c,x,_),f.el=Me.el}if(J&&_e(J,x),!je&&(U=F&&F.onVnodeMounted)){const Me=f;_e(()=>De(U,q,Me),x)}(f.shapeFlag&256||q&&Kt(q.vnode)&&q.vnode.shapeFlag&256)&&c.a&&_e(c.a,x),c.isMounted=!0,f=v=S=null}};c.scope.on();const O=c.effect=new Si(R);c.scope.off();const w=c.update=O.run.bind(O),z=c.job=O.runIfDirty.bind(O);z.i=c,z.id=c.uid,O.scheduler=()=>_n(z),gt(c,!0),w()},te=(c,f,v)=>{f.component=c;const S=c.vnode.props;c.vnode=f,c.next=null,Xr(c,f.props,S,v),sl(c,f.children,v),Ke(),Mn(c),We()},X=(c,f,v,S,x,_,I,R,O=!1)=>{const w=c&&c.children,z=c?c.shapeFlag:0,U=f.children,{patchFlag:N,shapeFlag:F}=f;if(N>0){if(N&128){rs(w,U,v,S,x,_,I,R,O);return}else if(N&256){ft(w,U,v,S,x,_,I,R,O);return}}F&8?(z&16&&Ut(w,x,_),U!==w&&u(v,U)):z&16?F&16?rs(w,U,v,S,x,_,I,R,O):Ut(w,x,_,!0):(z&8&&u(v,""),F&16&&st(U,v,S,x,_,I,R,O))},ft=(c,f,v,S,x,_,I,R,O)=>{c=c||xt,f=f||xt;const w=c.length,z=f.length,U=Math.min(w,z);let N;for(N=0;Nz?Ut(c,x,_,!0,!1,U):st(f,v,S,x,_,I,R,O,U)},rs=(c,f,v,S,x,_,I,R,O)=>{let w=0;const z=f.length;let U=c.length-1,N=z-1;for(;w<=U&&w<=N;){const F=c[w],K=f[w]=O?Ze(f[w]):Fe(f[w]);if(Dt(F,K))C(F,K,v,null,x,_,I,R,O);else break;w++}for(;w<=U&&w<=N;){const F=c[U],K=f[N]=O?Ze(f[N]):Fe(f[N]);if(Dt(F,K))C(F,K,v,null,x,_,I,R,O);else break;U--,N--}if(w>U){if(w<=N){const F=N+1,K=FN)for(;w<=U;)Ue(c[w],x,_,!0),w++;else{const F=w,K=w,J=new Map;for(w=K;w<=N;w++){const ye=f[w]=O?Ze(f[w]):Fe(f[w]);ye.key!=null&&J.set(ye.key,w)}let q,ie=0;const le=N-K+1;let je=!1,Me=0;const Mt=new Array(le);for(w=0;w=le){Ue(ye,x,_,!0);continue}let Ne;if(ye.key!=null)Ne=J.get(ye.key);else for(q=K;q<=N;q++)if(Mt[q-K]===0&&Dt(ye,f[q])){Ne=q;break}Ne===void 0?Ue(ye,x,_,!0):(Mt[Ne-K]=w+1,Ne>=Me?Me=Ne:je=!0,C(ye,f[Ne],v,null,x,_,I,R,O),ie++)}const $n=je?rl(Mt):xt;for(q=$n.length-1,w=le-1;w>=0;w--){const ye=K+w,Ne=f[ye],An=f[ye+1],On=ye+1{const{el:_,type:I,transition:R,children:O,shapeFlag:w}=c;if(w&6){pt(c.component.subTree,f,v,S);return}if(w&128){c.suspense.move(f,v,S);return}if(w&64){I.move(c,f,v,jt);return}if(I===ee){n(_,f,v);for(let U=0;UR.enter(_),x));else{const{leave:U,delayLeave:N,afterLeave:F}=R,K=()=>{c.ctx.isUnmounted?i(_):n(_,f,v)},J=()=>{const q=_._isLeaving||!!_[Bs];_._isLeaving&&_[Bs](!0),R.persisted&&!q?K():U(_,()=>{K(),F&&F()})};N?N(_,K,J):J()}else n(_,f,v)},Ue=(c,f,v,S=!1,x=!1)=>{const{type:_,props:I,ref:R,children:O,dynamicChildren:w,shapeFlag:z,patchFlag:U,dirs:N,cacheIndex:F,memo:K}=c;if(U===-2&&(x=!1),R!=null&&(Ke(),Vt(R,null,v,c,!0),We()),F!=null&&(f.renderCache[F]=void 0),z&256){f.ctx.deactivate(c);return}const J=z&1&&N,q=!Kt(c);let ie;if(q&&(ie=I&&I.onVnodeBeforeUnmount)&&De(ie,f,c),z&6)Po(c.component,v,S);else{if(z&128){c.suspense.unmount(v,S);return}J&&ht(c,null,f,"beforeUnmount"),z&64?c.type.remove(c,f,v,jt,S):w&&!w.hasOnce&&(_!==ee||U>0&&U&64)?Ut(w,f,v,!1,!0):(_===ee&&U&384||!x&&z&16)&&Ut(O,f,v),S&&Cn(c)}const le=K!=null&&F==null;(q&&(ie=I&&I.onVnodeUnmounted)||J||le)&&_e(()=>{ie&&De(ie,f,c),J&&ht(c,null,f,"unmounted"),le&&(c.el=null)},v)},Cn=c=>{const{type:f,el:v,anchor:S,transition:x}=c;if(f===ee){Co(v,S);return}if(f===Ks){M(c);return}const _=()=>{i(v),x&&!x.persisted&&x.afterLeave&&x.afterLeave()};if(c.shapeFlag&1&&x&&!x.persisted){const{leave:I,delayLeave:R}=x,O=()=>I(v,_);R?R(c.el,_,O):O()}else _()},Co=(c,f)=>{let v;for(;c!==f;)v=y(c),i(c),c=v;i(f)},Po=(c,f,v)=>{const{bum:S,scope:x,job:_,subTree:I,um:R,m:O,a:w}=c;Wn(O),Wn(w),S&&fs(S),x.stop(),_&&(_.flags|=8,Ue(I,c,f,v)),R&&_e(R,f),_e(()=>{c.isUnmounted=!0},f)},Ut=(c,f,v,S=!1,x=!1,_=0)=>{for(let I=_;I{if(c.shapeFlag&6)return ls(c.component.subTree);if(c.shapeFlag&128)return c.suspense.next();const f=y(c.anchor||c.el),v=f&&f[xr];return v?y(v):f};let js=!1;const Pn=(c,f,v)=>{let S;c==null?f._vnode&&(Ue(f._vnode,null,null,!0),S=f._vnode.component):C(f._vnode||null,c,f,null,null,null,v),f._vnode=c,js||(js=!0,Mn(S),Bi(),js=!1)},jt={p:C,um:Ue,m:pt,r:Cn,mt:Us,mc:st,pc:X,pbc:dt,n:ls,o:e};return{render:Pn,hydrate:void 0,createApp:Hr(Pn)}}function Vs({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 gt({effect:e,job:t},s){s?(e.flags|=32,t.flags|=4):(e.flags&=-33,t.flags&=-5)}function ol(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}function co(e,t,s=!1){const n=e.children,i=t.children;if(L(n)&&L(i))for(let o=0;o>1,e[s[l]]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 uo(e){const t=e.subTree.component;if(t)return t.asyncDep&&!t.asyncResolved?t:uo(t)}function Wn(e){if(e)for(let t=0;te.__isSuspense;function ll(e,t){t&&t.pendingBranch?L(e)?t.effects.push(...e):t.effects.push(e):mr(e)}const ee=Symbol.for("v-fgt"),Rs=Symbol.for("v-txt"),lt=Symbol.for("v-cmt"),Ks=Symbol.for("v-stc"),Gt=[];let we=null;function k(e=!1){Gt.push(we=e?null:[])}function al(){Gt.pop(),we=Gt[Gt.length-1]||null}let Xt=1;function Gn(e,t=!1){Xt+=e,e<0&&we&&t&&(we.hasOnce=!0)}function ho(e){return e.dynamicChildren=Xt>0?we||xt:null,al(),Xt>0&&we&&we.push(e),e}function E(e,t,s,n,i,o){return ho(d(e,t,s,n,i,o,!0))}function it(e,t,s,n,i){return ho(ce(e,t,s,n,i,!0))}function go(e){return e?e.__v_isVNode===!0:!1}function Dt(e,t){return e.type===t.type&&e.key===t.key}const mo=({key:e})=>e??null,hs=({ref:e,ref_key:t,ref_for:s})=>(typeof e=="number"&&(e=""+e),e!=null?ne(e)||fe(e)||H(e)?{i:xe,r:e,k:t,f:!!s}:e:null);function d(e,t=null,s=null,n=0,i=null,o=e===ee?0:1,r=!1,l=!1){const a={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&mo(t),ref:t&&hs(t),scopeId:Vi,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:xe};return l?(ys(a,s),o&128&&e.normalize(a)):s&&(a.shapeFlag|=ne(s)?8:16),Xt>0&&!r&&we&&(a.patchFlag>0||o&6)&&a.patchFlag!==32&&we.push(a),a}const ce=cl;function cl(e,t=null,s=null,n=0,i=null,o=!1){if((!e||e===jr)&&(e=lt),go(e)){const l=Pt(e,t,!0);return s&&ys(l,s),Xt>0&&!o&&we&&(l.shapeFlag&6?we[we.indexOf(e)]=l:we.push(l)),l.patchFlag=-2,l}if(yl(e)&&(e=e.__vccOpts),t){t=ul(t);let{class:l,style:a}=t;l&&!ne(l)&&(t.class=$e(l)),Z(a)&&(vn(a)&&!L(a)&&(a=he({},a)),t.style=un(a))}const r=ne(e)?1:po(e)?128:kr(e)?64:Z(e)?4:H(e)?2:0;return d(e,t,s,n,i,r,o,!0)}function ul(e){return e?vn(e)||no(e)?he({},e):e:null}function Pt(e,t,s=!1,n=!1){const{props:i,ref:o,patchFlag:r,children:l,transition:a}=e,p=t?dl(i||{},t):i,u={__v_isVNode:!0,__v_skip:!0,type:e.type,props:p,key:p&&mo(p),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:l,target:e.target,targetStart:e.targetStart,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==ee?r===-1?16:r|16:r,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:a,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&Pt(e.ssContent),ssFallback:e.ssFallback&&Pt(e.ssFallback),placeholder:e.placeholder,el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce};return a&&n&&yn(u,a.clone(u)),u}function Te(e=" ",t=0){return ce(Rs,null,e,t)}function B(e="",t=!1){return t?(k(),it(lt,null,e)):ce(lt,null,e)}function Fe(e){return e==null||typeof e=="boolean"?ce(lt):L(e)?ce(ee,null,e.slice()):go(e)?Ze(e):ce(Rs,null,String(e))}function Ze(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:Pt(e)}function ys(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),ys(e,i()),i._c&&(i._d=!0));return}else{s=32;const i=t._;!i&&!no(t)?t._ctx=xe:i===3&&xe&&(xe.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else if(H(t)){if(n&65){ys(e,{default:t});return}t={default:t,_ctx:xe},s=32}else t=String(t),n&64?(s=16,t=[Te(t)]):s=8;e.children=t,e.shapeFlag|=s}function dl(...e){const t={};for(let s=0;sve||xe;let ws,nn;{const e=Cs(),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)}};ws=t("__VUE_INSTANCE_SETTERS__",s=>ve=s),nn=t("__VUE_SSR_SETTERS__",s=>Qt=s)}const ss=e=>{const t=ve;return ws(e),e.scope.on(),()=>{e.scope.off(),ws(t)}},qn=()=>{ve&&ve.scope.off(),ws(null)};function bo(e){return e.vnode.shapeFlag&4}let Qt=!1;function ml(e,t=!1,s=!1){t&&nn(t);const{props:n,children:i}=e.vnode,o=bo(e);Yr(e,n,o,t),tl(e,i,s||t);const r=o?bl(e,t):void 0;return t&&nn(!1),r}function bl(e,t){const s=e.type;e.accessCache=Object.create(null),e.proxy=new Proxy(e.ctx,Mr);const{setup:n}=s;if(n){Ke();const i=e.setupContext=n.length>1?_l(e):null,o=ss(e),r=ts(n,e,0,[e.props,i]),l=mi(r);if(We(),o(),(l||e.sp)&&!Kt(e)&&Gi(e),l){if(r.then(qn,qn),t)return r.then(a=>{Zn(e,a)}).catch(a=>{$s(a,e,0)});e.asyncDep=r}else Zn(e,r)}else vo(e)}function Zn(e,t,s){H(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:Z(t)&&(e.setupState=Di(t)),vo(e)}function vo(e,t,s){const n=e.type;e.render||(e.render=n.render||He);{const i=ss(e);Ke();try{Nr(e)}finally{We(),i()}}}const vl={get(e,t){return ue(e,"get",""),e[t]}};function _l(e){const t=s=>{e.exposed=s||{}};return{attrs:new Proxy(e.attrs,vl),slots:e.slots,emit:e.emit,expose:t}}function Is(e){return e.exposed?e.exposeProxy||(e.exposeProxy=new Proxy(Di(rr(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 yl(e){return H(e)&&"__vccOpts"in e}const Qe=(e,t)=>dr(e,t,Qt),wl="3.5.39";/** -* @vue/runtime-dom v3.5.39 -* (c) 2018-present Yuxi (Evan) You and Vue contributors -* @license MIT -**/let on;const Jn=typeof window<"u"&&window.trustedTypes;if(Jn)try{on=Jn.createPolicy("vue",{createHTML:e=>e})}catch{}const _o=on?e=>on.createHTML(e):e=>e,xl="http://www.w3.org/2000/svg",kl="http://www.w3.org/1998/Math/MathML",qe=typeof document<"u"?document:null,Yn=qe&&qe.createElement("template"),Sl={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"?qe.createElementNS(xl,e):t==="mathml"?qe.createElementNS(kl,e):s?qe.createElement(e,{is:s}):qe.createElement(e);return e==="select"&&n&&n.multiple!=null&&i.setAttribute("multiple",n.multiple),i},createText:e=>qe.createTextNode(e),createComment:e=>qe.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>qe.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{Yn.innerHTML=_o(n==="svg"?`${e}`:n==="mathml"?`${e}`:e);const l=Yn.content;if(n==="svg"||n==="mathml"){const a=l.firstChild;for(;a.firstChild;)l.appendChild(a.firstChild);l.removeChild(a)}t.insertBefore(l,s)}return[r?r.nextSibling:t.firstChild,s?s.previousSibling:t.lastChild]}},Tl=Symbol("_vtc");function El(e,t,s){const n=e[Tl];n&&(t=(t?[t,...n]:[...n]).join(" ")),t==null?e.removeAttribute("class"):s?e.setAttribute("class",t):e.className=t}const Xn=Symbol("_vod"),Cl=Symbol("_vsh"),Pl=Symbol(""),$l=/(?:^|;)\s*display\s*:/;function Al(e,t,s){const n=e.style,i=ne(s);let o=!1;if(s&&!i){if(t)if(ne(t))for(const r of t.split(";")){const l=r.slice(0,r.indexOf(":")).trim();s[l]==null&&Lt(n,l,"")}else for(const r in t)s[r]==null&&Lt(n,r,"");for(const r in s){r==="display"&&(o=!0);const l=s[r];l!=null?Rl(e,r,!ne(t)&&t?t[r]:void 0,l)||Lt(n,r,l):Lt(n,r,"")}}else if(i){if(t!==s){const r=n[Pl];r&&(s+=";"+r),n.cssText=s,o=$l.test(s)}}else t&&e.removeAttribute("style");Xn in e&&(e[Xn]=o?n.display:"",e[Cl]&&(n.display="none"))}const Qn=/\s*!important$/;function Lt(e,t,s){if(L(s))s.forEach(n=>Lt(e,t,n));else if(s==null&&(s=""),t.startsWith("--"))e.setProperty(t,s);else{const n=Ol(e,t);Qn.test(s)?e.setProperty(ct(n),s.replace(Qn,""),"important"):e[n]=s}}const ei=["Webkit","Moz","ms"],Ws={};function Ol(e,t){const s=Ws[t];if(s)return s;let n=Ce(t);if(n!=="filter"&&n in e)return Ws[t]=n;n=_i(n);for(let i=0;iGs||(Dl.then(()=>Gs=0),Gs=Date.now());function Ll(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(),l=[n];for(let a=0;ae.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,Fl=(e,t,s,n,i,o)=>{const r=i==="svg";t==="class"?El(e,n,r):t==="style"?Al(e,s,n):ks(t)?Ss(t)||Ul(e,t,s,n,o):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):Bl(e,t,n,r))?(ni(e,t,n),!e.tagName.includes("-")&&(t==="value"||t==="checked"||t==="selected")&&si(e,t,n,r,o,t!=="value")):e._isVueCE&&(Hl(e,t)||e._def.__asyncLoader&&(/[A-Z]/.test(t)||!ne(n)))?ni(e,Ce(t),n,o,t):(t==="true-value"?e._trueValue=n:t==="false-value"&&(e._falseValue=n),si(e,t,n,r))};function Bl(e,t,s,n){if(n)return!!(t==="innerHTML"||t==="textContent"||t in e&&oi(t)&&H(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 oi(t)&&ne(s)?!1:t in e}function Hl(e,t){const s=e._def.props;if(!s)return!1;const n=Ce(t);return Array.isArray(s)?s.some(i=>Ce(i)===n):Object.keys(s).some(i=>Ce(i)===n)}const at=e=>{const t=e.props["onUpdate:modelValue"]||!1;return L(t)?s=>fs(t,s):t};function Vl(e){e.target.composing=!0}function ri(e){const t=e.target;t.composing&&(t.composing=!1,t.dispatchEvent(new Event("input")))}const Ee=Symbol("_assign");function li(e,t,s){return t&&(e=e.trim()),s&&(e=Es(e)),e}const pe={created(e,{modifiers:{lazy:t,trim:s,number:n}},i){e[Ee]=at(i);const o=n||i.props&&i.props.type==="number";Xe(e,t?"change":"input",r=>{r.target.composing||e[Ee](li(e.value,s,o))}),(s||o)&&Xe(e,"change",()=>{e.value=li(e.value,s,o)}),t||(Xe(e,"compositionstart",Vl),Xe(e,"compositionend",ri),Xe(e,"change",ri))},mounted(e,{value:t}){e.value=t??""},beforeUpdate(e,{value:t,oldValue:s,modifiers:{lazy:n,trim:i,number:o}},r){if(e[Ee]=at(r),e.composing)return;const l=(o||e.type==="number")&&!/^0\d/.test(e.value)?Es(e.value):e.value,a=t??"";if(l===a)return;const p=e.getRootNode();(p instanceof Document||p instanceof ShadowRoot)&&p.activeElement===e&&e.type!=="range"&&(n&&t===s||i&&e.value.trim()===a)||(e.value=a)}},Kl={deep:!0,created(e,t,s){e[Ee]=at(s),Xe(e,"change",()=>{const n=e._modelValue,i=$t(e),o=e.checked,r=e[Ee];if(L(n)){const l=dn(n,i),a=l!==-1;if(o&&!a)r(n.concat(i));else if(!o&&a){const p=[...n];p.splice(l,1),r(p)}}else if(Rt(n)){const l=new Set(n);o?l.add(i):l.delete(i),r(l)}else r(yo(e,o))})},mounted:ai,beforeUpdate(e,t,s){e[Ee]=at(s),ai(e,t,s)}};function ai(e,{value:t,oldValue:s},n){e._modelValue=t;let i;if(L(t))i=dn(t,n.props.value)>-1;else if(Rt(t))i=t.has(n.props.value);else{if(t===s)return;i=rt(t,yo(e,!0))}e.checked!==i&&(e.checked=i)}const Wl={created(e,{value:t},s){e.checked=rt(t,s.props.value),e[Ee]=at(s),Xe(e,"change",()=>{e[Ee]($t(e))})},beforeUpdate(e,{value:t,oldValue:s},n){e[Ee]=at(n),t!==s&&(e.checked=rt(t,n.props.value))}},xs={deep:!0,created(e,{value:t,modifiers:{number:s}},n){const i=Rt(t);Xe(e,"change",()=>{const o=Array.prototype.filter.call(e.options,r=>r.selected).map(r=>s?Es($t(r)):$t(r));e[Ee](e.multiple?i?new Set(o):o:o[0]),e._assigning=!0,Li(()=>{e._assigning=!1})}),e[Ee]=at(n)},mounted(e,{value:t}){ci(e,t)},beforeUpdate(e,t,s){e[Ee]=at(s)},updated(e,{value:t}){e._assigning||ci(e,t)}};function ci(e,t){const s=e.multiple,n=L(t);if(!(s&&!n&&!Rt(t))){for(let i=0,o=e.options.length;iString(p)===String(l)):r.selected=dn(t,l)>-1}else r.selected=t.has(l);else if(rt($t(r),t)){e.selectedIndex!==i&&(e.selectedIndex=i);return}}!s&&e.selectedIndex!==-1&&(e.selectedIndex=-1)}}function $t(e){return"_value"in e?e._value:e.value}function yo(e,t){const s=t?"_trueValue":"_falseValue";return s in e?e[s]:t}const Gl={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 ql(e,t){switch(e){case"SELECT":return xs;case"TEXTAREA":return pe;default:switch(t){case"checkbox":return Kl;case"radio":return Wl;default:return pe}}}function ds(e,t,s,n,i){const r=ql(e.tagName,s.props&&s.props.type)[i];r&&r(e,t,s,n)}const Zl=["ctrl","shift","alt","meta"],Jl={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)=>Zl.some(s=>e[`${s}Key`]&&!t.includes(s))},Yl=(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=ct(i.key);if(t.some(r=>r===o||Xl[r]===o))return e(i)}))},ea=he({patchProp:Fl},Sl);let ui;function ta(){return ui||(ui=nl(ea))}const sa=((...e)=>{const t=ta().createApp(...e),{mount:s}=t;return t.mount=n=>{const i=ia(n);if(!i)return;const o=t._component;!H(o)&&!o.render&&!o.template&&(o.template=i.innerHTML),i.nodeType===1&&(i.textContent="");const r=s(i,!1,na(i));return i instanceof Element&&(i.removeAttribute("v-cloak"),i.setAttribute("data-v-app","")),r},t});function na(e){if(e instanceof SVGElement)return"svg";if(typeof MathMLElement=="function"&&e instanceof MathMLElement)return"mathml"}function ia(e){return ne(e)?document.querySelector(e):e}const wo="dh-panel-theme";function oa(){var e;try{const t=localStorage.getItem(wo);if(t==="dark"||t==="light")return t}catch{}return(e=window.matchMedia)!=null&&e.call(window,"(prefers-color-scheme: dark)").matches?"dark":"light"}const Et=V(oa());function xo(e){Et.value=e,document.documentElement.classList.toggle("dark",e==="dark");try{localStorage.setItem(wo,e)}catch{}}function di(){xo(Et.value==="dark"?"light":"dark")}xo(Et.value);const ra={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."},la={overview:"Overview",users:"Users",orgs:"Organizations",pocketbase:"PocketBase",webapp:"Web App",plugins:"Plugins",api:"API"},aa={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"},ca={title:"Status",unreachable:"unreachable",checking:"Checking…",apiServer:"API Server",pocketBase:"PocketBase",webApp:"Web App",thisProcess:"this process"},ua={create:"Create",save:"Save",cancel:"Cancel",edit:"Edit",delete:"Delete",rename:"Rename",empty:"—",name:"Name",email:"Email",role:"Role",organization:"Organization"},da={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."},fa={title:"Organizations",subtitle:"Tenants users belong to",newOrg:"New organization",namePlaceholder:"Acme Fleet",empty:"No organizations yet.",colId:"ID",confirmDelete:'Delete the organization "{name}"?'},pa={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."},ha={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."},ga={title:"Plugins",subtitle:"Third-party service integrations",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.'},ma={colEndpoint:"Endpoint",colDescription:"Description",authNone:"No auth",authBearer:"Bearer token",authManager:"Admin / superadmin",authSuperadmin:"Superadmin",groupPublic:"Public",groupIdentity:"Identity",groupCars:"Cars",groupService:"Service records",groupParts:"Parts",groupAccount:"Account",groupManagement:"Management",groupSuperadmin:"Superadmin"},ba={app:ra,sections:la,login:aa,status:ca,common:ua,users:da,orgs:fa,pocketbase:pa,webapp:ha,plugins:ga,api:ma},va={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."},_a={overview:"Przegląd",users:"Użytkownicy",orgs:"Organizacje",pocketbase:"PocketBase",webapp:"Aplikacja webowa",plugins:"Wtyczki",api:"API"},ya={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"},wa={title:"Status",unreachable:"niedostępny",checking:"Sprawdzanie…",apiServer:"Serwer API",pocketBase:"PocketBase",webApp:"Aplikacja webowa",thisProcess:"ten proces"},xa={create:"Utwórz",save:"Zapisz",cancel:"Anuluj",edit:"Edytuj",delete:"Usuń",rename:"Zmień nazwę",empty:"—",name:"Nazwa",email:"E-mail",role:"Rola",organization:"Organizacja"},ka={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ąć."},Sa={title:"Organizacje",subtitle:"Podmioty, do których należą użytkownicy",newOrg:"Nowa organizacja",namePlaceholder:"Acme Fleet",empty:"Brak organizacji.",colId:"ID",confirmDelete:"Usunąć organizację „{name}”?"},Ta={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."},Ea={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."},Ca={title:"Wtyczki",subtitle:"Integracje z usługami zewnętrznymi",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."},Pa={colEndpoint:"Punkt końcowy",colDescription:"Opis",authNone:"Bez uwierzytelniania",authBearer:"Token Bearer",authManager:"Administrator / superadministrator",authSuperadmin:"Superadministrator",groupPublic:"Publiczne",groupIdentity:"Tożsamość",groupCars:"Samochody",groupService:"Wpisy serwisowe",groupParts:"Części",groupAccount:"Konto",groupManagement:"Zarządzanie",groupSuperadmin:"Superadministrator"},$a={app:va,sections:_a,login:ya,status:wa,common:xa,users:ka,orgs:Sa,pocketbase:Ta,webapp:Ea,plugins:Ca,api:Pa},Aa={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."},Oa={overview:"Oversigt",users:"Brugere",orgs:"Organisationer",pocketbase:"PocketBase",webapp:"Webapp",plugins:"Plugins",api:"API"},Ra={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"},Ia={title:"Status",unreachable:"utilgængelig",checking:"Tjekker…",apiServer:"API-server",pocketBase:"PocketBase",webApp:"Webapp",thisProcess:"denne proces"},Ua={create:"Opret",save:"Gem",cancel:"Annuller",edit:"Rediger",delete:"Slet",rename:"Omdøb",empty:"—",name:"Navn",email:"E-mail",role:"Rolle",organization:"Organisation"},ja={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."},Ma={title:"Organisationer",subtitle:"Enheder, som brugere tilhører",newOrg:"Ny organisation",namePlaceholder:"Acme Fleet",empty:"Ingen organisationer endnu.",colId:"ID",confirmDelete:'Slet organisationen "{name}"?'},Na={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."},Da={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."},za={title:"Plugins",subtitle:"Integrationer med tredjepartstjenester",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.'},La={colEndpoint:"Endpoint",colDescription:"Beskrivelse",authNone:"Ingen godkendelse",authBearer:"Bearer-token",authManager:"Admin / superadmin",authSuperadmin:"Superadmin",groupPublic:"Offentlig",groupIdentity:"Identitet",groupCars:"Biler",groupService:"Serviceposter",groupParts:"Reservedele",groupAccount:"Konto",groupManagement:"Administration",groupSuperadmin:"Superadmin"},Fa={app:Aa,sections:Oa,login:Ra,status:Ia,common:Ua,users:ja,orgs:Ma,pocketbase:Na,webapp:Da,plugins:za,api:La},ko="dh-panel-lang",So="en",At={en:ba,pl:$a,da:Fa},Ba=Object.keys(At);function Ha(){try{const t=localStorage.getItem(ko);if(t&&At[t])return t}catch{}const e=(navigator.language||"en").split("-")[0];return At[e]?e:So}const Sn=V(Ha());function Va(e){if(At[e]){Sn.value=e;try{localStorage.setItem(ko,e)}catch{}}}function fi(e,t){return t.split(".").reduce((s,n)=>s==null?void 0:s[n],e)}function Ka(e,t){return t?e.replace(/\{(\w+)\}/g,(s,n)=>t[n]==null?s:String(t[n])):e}function Wa(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 h(e,t){const s=Sn.value;let n=fi(At[s],e);if(n==null&&(n=fi(At[So],e)),n==null)return e;if(typeof n=="object"){if((t==null?void 0:t.n)==null)return e;n=Wa(n,t.n,s)}return typeof n!="string"?e:Ka(n,t)}function pi(e,t,s){const i=h(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 rn="dh-panel-token";function Ga(){try{return localStorage.getItem(rn)||""}catch{return""}}const Ot=V(Ga()),de=V(null),bt=Qe(()=>{var e;return((e=de.value)==null?void 0:e.role)==="superadmin"}),hi=Qe(()=>{var e,t;return((e=de.value)==null?void 0:e.role)==="admin"||((t=de.value)==null?void 0:t.role)==="superadmin"});function To(e){Ot.value=e;try{e?localStorage.setItem(rn,e):localStorage.removeItem(rn)}catch{}}class qa extends Error{constructor(t,s,n){super(t),this.status=s,this.body=n}}function Za(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 se(e,{method:t="GET",body:s,auth:n=!0}={}){const i={};s!==void 0&&(i["Content-Type"]="application/json"),n&&Ot.value&&(i.Authorization=Ot.value);const o=await fetch(e,{method:t,headers:i,body:s===void 0?void 0:JSON.stringify(s)}),r=await o.text();let l=null;try{l=r?JSON.parse(r):null}catch{l=null}if(!o.ok)throw o.status===401&&n&&Tn(),new qa(Za(l,o.status),o.status,l);return l}async function Ja(e,t){const s=await se("/api/auth/login",{method:"POST",body:{email:e,password:t},auth:!1});return To(s.token),await Eo(),de.value}async function Eo(){return de.value=await se("/api/identity"),de.value}function Tn(){To(""),de.value=null}async function Ya(){if(!Ot.value)return null;try{return await Eo()}catch{return Tn(),null}}const Xa={class:"mx-auto flex w-full max-w-sm flex-col gap-5 pt-24"},Qa={class:"dh-card p-6"},ec={class:"text-lg font-bold tracking-[-0.02em] text-strong"},tc={class:"mt-1 mb-5 text-sm text-body"},sc={class:"dh-label",for:"login-email"},nc={class:"dh-label",for:"login-password"},ic={key:0,class:"rounded-control bg-danger-soft px-3 py-2 text-xs text-danger"},oc=["disabled"],rc={class:"eyebrow text-center"},lc={__name:"LoginView",emits:["authenticated"],setup(e,{emit:t}){const s=t,n=V(""),i=V(""),o=V(""),r=V(!1),l=Qe(()=>n.value.trim()!==""&&i.value!==""&&!r.value);async function a(){if(l.value){o.value="",r.value=!0;try{const p=await Ja(n.value.trim(),i.value);s("authenticated",p)}catch(p){o.value=p.status===400||p.status===404?h("login.invalid"):p.message||h("login.failed"),i.value=""}finally{r.value=!1}}}return(p,u)=>(k(),E("div",Xa,[d("div",Qa,[d("h1",ec,b(g(h)("login.title")),1),d("p",tc,b(g(h)("login.subtitle")),1),d("form",{class:"flex flex-col gap-4",onSubmit:Yl(a,["prevent"])},[d("div",null,[d("label",sc,b(g(h)("login.email")),1),re(d("input",{id:"login-email","onUpdate:modelValue":u[0]||(u[0]=m=>n.value=m),class:"dh-input",type:"email",autocomplete:"username",autofocus:"",placeholder:"you@example.com"},null,512),[[pe,n.value]])]),d("div",null,[d("label",nc,b(g(h)("login.password")),1),re(d("input",{id:"login-password","onUpdate:modelValue":u[1]||(u[1]=m=>i.value=m),class:"dh-input",type:"password",autocomplete:"current-password",placeholder:"••••••••"},null,512),[[pe,i.value]])]),o.value?(k(),E("p",ic,b(o.value),1)):B("",!0),d("button",{class:"dh-btn w-full",type:"submit",disabled:!l.value},b(r.value?g(h)("login.submitting"):g(h)("login.submit")),9,oc)],32)]),d("p",rc,b(g(h)("login.authNote")),1)]))}},ac={class:"dh-card overflow-hidden"},cc={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},uc={class:"text-base font-bold tracking-[-0.02em] text-strong"},dc={key:0,class:"dh-pill bg-danger-soft text-danger"},fc={key:0,class:"px-5 py-4 text-sm text-danger"},pc={key:1,class:"w-full text-left text-sm"},hc={class:"px-5 py-3 font-medium text-strong"},gc={class:"data px-5 py-3 text-xs text-muted"},mc={class:"data px-5 py-3 text-right text-xs text-muted"},bc={class:"px-5 py-3 text-right"},vc={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 se("/api/status",{auth:!1}),s.value=""}catch(l){t.value=null,s.value=l.message||h("status.unreachable")}}const o=Qe(()=>{var l,a,p;return[{key:"apiServer",label:h("status.apiServer"),h:(l=t.value)==null?void 0:l.apiServer},{key:"pocketBase",label:h("status.pocketBase"),h:(a=t.value)==null?void 0:a.pocketBase},{key:"webApp",label:h("status.webApp"),h:(p=t.value)==null?void 0:p.webApp}]});ut(()=>{i(),n=setInterval(i,1e4)}),wn(()=>clearInterval(n));const r=l=>l==="ok"?"bg-success-soft text-success":"bg-danger-soft text-danger";return(l,a)=>(k(),E("div",ac,[d("div",cc,[d("div",uc,b(g(h)("status.title")),1),s.value?(k(),E("span",dc,[a[0]||(a[0]=d("span",{class:"h-1.5 w-1.5 rounded-full bg-current"},null,-1)),Te(b(g(h)("status.unreachable")),1)])):B("",!0)]),s.value?(k(),E("div",fc,b(s.value),1)):t.value?(k(),E("table",pc,[d("tbody",null,[(k(!0),E(ee,null,ke(o.value,p=>(k(),E("tr",{key:p.key,class:"border-t border-subtle first:border-t-0"},[d("td",hc,b(p.label),1),d("td",gc,b(p.h.url||g(h)("status.thisProcess")),1),d("td",mc,b(p.h.latencyMs!=null?p.h.latencyMs+"ms":g(h)("common.empty")),1),d("td",bc,[d("span",{class:$e(["dh-pill",r(p.h.status)])},[a[1]||(a[1]=d("span",{class:"h-1.5 w-1.5 rounded-full bg-current"},null,-1)),Te(b(p.h.status),1)],2)])]))),128))])])):(k(),E("div",vc,b(g(h)("status.checking")),1))]))}},yc={class:"dh-card overflow-hidden"},wc={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},xc={class:"text-base font-bold tracking-[-0.02em] text-strong"},kc={class:"mt-0.5 text-xs text-muted"},Sc={class:"flex flex-col gap-4 px-5 py-4"},Tc={class:"dh-label",for:"pb-url"},Ec={class:"grid gap-4 sm:grid-cols-2"},Cc={class:"dh-label",for:"pb-email"},Pc={class:"dh-label",for:"pb-password"},$c=["placeholder"],Ac={key:0,class:"data text-xs text-muted"},Oc={key:1,class:"rounded-control bg-info-soft px-3 py-2 text-xs text-info"},Rc={key:2,class:"rounded-control bg-danger-soft px-3 py-2 text-xs text-danger"},Ic={class:"flex items-center gap-2"},Uc=["disabled"],jc=["disabled"],Mc={class:"eyebrow"},Nc={__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 l(){try{t.value=await se("/api/admin/pb-config"),s.value={url:t.value.url,adminEmail:t.value.adminEmail,adminPassword:""},n.value=t.value.probe}catch(u){i.value=u.message}}ut(l);async function a(){i.value="",o.value="",r.value=!0;try{n.value=await se("/api/admin/pb-config/test",{method:"POST",body:s.value}),o.value=n.value.superuser?h("pocketbase.testOk"):n.value.reachable?h("pocketbase.testReachableNoAuth"):h("pocketbase.testUnreachable")}catch(u){i.value=u.message}finally{r.value=!1}}async function p(){i.value="",o.value="",r.value=!0;try{const u=await se("/api/admin/pb-config",{method:"PUT",body:s.value});t.value=u.config,n.value=u.config.probe,s.value.adminPassword="",o.value=u.warning||h("pocketbase.savedNotice")}catch(u){i.value=u.message}finally{r.value=!1}}return(u,m)=>{var y,A;return k(),E("div",yc,[d("div",wc,[d("div",null,[d("div",xc,b(g(h)("pocketbase.title")),1),d("p",kc,b(g(h)("pocketbase.subtitle")),1)]),n.value?(k(),E("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"])},[m[3]||(m[3]=d("span",{class:"h-1.5 w-1.5 rounded-full bg-current"},null,-1)),Te(" "+b(n.value.superuser?g(h)("pocketbase.connected"):n.value.reachable?g(h)("pocketbase.noSuperuser"):g(h)("pocketbase.unreachable")),1)],2)):B("",!0)]),d("div",Sc,[d("div",null,[d("label",Tc,b(g(h)("pocketbase.baseUrl")),1),re(d("input",{id:"pb-url","onUpdate:modelValue":m[0]||(m[0]=D=>s.value.url=D),class:"dh-input",placeholder:"http://10.2.1.10:8027"},null,512),[[pe,s.value.url]])]),d("div",Ec,[d("div",null,[d("label",Cc,b(g(h)("pocketbase.superuserEmail")),1),re(d("input",{id:"pb-email","onUpdate:modelValue":m[1]||(m[1]=D=>s.value.adminEmail=D),class:"dh-input",autocomplete:"off"},null,512),[[pe,s.value.adminEmail]])]),d("div",null,[d("label",Pc,b(g(h)("pocketbase.superuserPassword")),1),re(d("input",{id:"pb-password","onUpdate:modelValue":m[2]||(m[2]=D=>s.value.adminPassword=D),class:"dh-input",type:"password",autocomplete:"new-password",placeholder:(y=t.value)!=null&&y.adminConfigured?g(h)("pocketbase.passwordUnchanged"):g(h)("pocketbase.passwordNotSet")},null,8,$c),[[pe,s.value.adminPassword]])])]),(A=n.value)!=null&&A.detail?(k(),E("p",Ac,b(n.value.detail),1)):B("",!0),o.value?(k(),E("p",Oc,b(o.value),1)):B("",!0),i.value?(k(),E("p",Rc,b(i.value),1)):B("",!0),d("div",Ic,[d("button",{class:"dh-btn",disabled:r.value,onClick:p},b(g(h)("pocketbase.saveApply")),9,Uc),d("button",{class:"dh-btn-ghost",disabled:r.value,onClick:a},b(g(h)("pocketbase.testConnection")),9,jc),m[4]||(m[4]=d("span",{class:"flex-1"},null,-1)),d("span",Mc,b(g(h)("pocketbase.persistedEnv")),1)])])])}}},Dc={class:"dh-card overflow-hidden"},zc={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},Lc={class:"text-base font-bold tracking-[-0.02em] text-strong"},Fc={class:"mt-0.5 text-xs text-muted"},Bc={class:"flex flex-col gap-4 px-5 py-4"},Hc={class:"dh-label",for:"web-url"},Vc={class:"dh-label",for:"web-origins"},Kc={class:"mt-1 text-xs text-muted"},Wc={key:0,class:"data text-xs text-muted"},Gc={key:1,class:"rounded-control bg-info-soft px-3 py-2 text-xs text-info"},qc={key:2,class:"rounded-control bg-danger-soft px-3 py-2 text-xs text-danger"},Zc={class:"flex items-center gap-2"},Jc=["disabled"],Yc=["disabled"],Xc={class:"eyebrow"},Qc={__name:"WebAppCard",setup(e){const t=V(null),s=V({url:"",origins:""}),n=V(null),i=V(""),o=V(""),r=V(!1),l=y=>y.split(",").map(A=>A.trim()).filter(Boolean);function a(y){t.value=y,s.value={url:y.url,origins:(y.allowOrigins||[]).join(", ")},n.value=y.probe}async function p(){try{a(await se("/api/admin/webapp-config"))}catch(y){i.value=y.message}}ut(p);async function u(){i.value="",o.value="",r.value=!0;try{n.value=await se("/api/admin/webapp-config/test",{method:"POST",body:{url:s.value.url}}),o.value=n.value.status==="ok"?h("webapp.testOk"):h("webapp.testFailed")}catch(y){i.value=y.message}finally{r.value=!1}}async function m(){i.value="",o.value="",r.value=!0;try{const y=await se("/api/admin/webapp-config",{method:"PUT",body:{url:s.value.url,allowOrigins:l(s.value.origins)}});a(y.config),o.value=y.warning||h("webapp.savedNotice")}catch(y){i.value=y.message}finally{r.value=!1}}return(y,A)=>{var D;return k(),E("div",Dc,[d("div",zc,[d("div",null,[d("div",Lc,b(g(h)("webapp.title")),1),d("p",Fc,b(g(h)("webapp.subtitle")),1)]),n.value?(k(),E("span",{key:0,class:$e(["dh-pill",n.value.status==="ok"?"bg-success-soft text-success":"bg-danger-soft text-danger"])},[A[2]||(A[2]=d("span",{class:"h-1.5 w-1.5 rounded-full bg-current"},null,-1)),Te(" "+b(n.value.status==="ok"?g(h)("webapp.reachable"):g(h)("webapp.unreachable")),1)],2)):B("",!0)]),d("div",Bc,[d("div",null,[d("label",Hc,b(g(h)("webapp.baseUrl")),1),re(d("input",{id:"web-url","onUpdate:modelValue":A[0]||(A[0]=C=>s.value.url=C),class:"dh-input",placeholder:"http://localhost:8090"},null,512),[[pe,s.value.url]])]),d("div",null,[d("label",Vc,b(g(h)("webapp.allowedOrigins")),1),re(d("input",{id:"web-origins","onUpdate:modelValue":A[1]||(A[1]=C=>s.value.origins=C),class:"dh-input",placeholder:"http://localhost:8090, https://app.example.com"},null,512),[[pe,s.value.origins]]),d("p",Kc,[Te(b(g(pi)("webapp.originsHint","star").before),1),A[3]||(A[3]=d("span",{class:"data"},"*",-1)),Te(b(g(pi)("webapp.originsHint","star").after),1)])]),(D=n.value)!=null&&D.error?(k(),E("p",Wc,b(n.value.error),1)):B("",!0),o.value?(k(),E("p",Gc,b(o.value),1)):B("",!0),i.value?(k(),E("p",qc,b(i.value),1)):B("",!0),d("div",Zc,[d("button",{class:"dh-btn",disabled:r.value,onClick:m},b(g(h)("webapp.saveApply")),9,Jc),d("button",{class:"dh-btn-ghost",disabled:r.value,onClick:u},b(g(h)("webapp.testConnection")),9,Yc),A[4]||(A[4]=d("span",{class:"flex-1"},null,-1)),d("span",Xc,b(g(h)("webapp.persistedEnv")),1)])])])}}},eu={class:"dh-card overflow-hidden"},tu={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},su={class:"text-base font-bold tracking-[-0.02em] text-strong"},nu={class:"mt-0.5 text-xs text-muted"},iu={key:0,class:"border-b border-subtle bg-sunken px-5 py-4"},ou={class:"grid gap-3 sm:grid-cols-3"},ru={class:"dh-label"},lu={class:"dh-label"},au={class:"dh-label"},cu=["disabled"],uu={key:1,class:"border-b border-subtle px-5 py-3 text-xs text-danger"},du={key:2,class:"px-5 py-6 text-center text-sm text-muted"},fu={class:"flex items-center gap-3 px-5 py-3"},pu=["onClick"],hu={class:"font-semibold text-strong"},gu={class:"dh-pill bg-sunken text-muted"},mu={key:0,class:"text-xs text-muted"},bu=["disabled","onClick"],vu=["disabled","onClick"],_u={key:0,class:"bg-sunken px-5 py-4"},yu={key:0,class:"data mb-3 text-xs text-muted"},wu={key:1,class:"grid gap-3 sm:grid-cols-2"},xu={class:"dh-label"},ku={key:0,class:"text-danger"},Su=["onUpdate:modelValue"],Tu={key:0,value:""},Eu=["value"],Cu=["onUpdate:modelValue","type","placeholder"],Pu={key:2,class:"mt-1 text-xs text-muted"},$u={key:2,class:"text-xs text-muted"},Au={key:3,class:"mt-4"},Ou={class:"eyebrow mb-1.5"},Ru={class:"data flex flex-col gap-1 text-xs text-muted"},Iu={class:"text-strong"},Uu={key:0},ju={key:1},Mu={key:4,class:"data mt-3 text-xs text-body"},Nu={class:"mt-4 flex items-center gap-2"},Du=["disabled","onClick"],zu=["disabled","onClick"],Lu=["disabled","onClick"],Fu={key:5,class:"eyebrow mt-2"},Bu={__name:"PluginsCard",setup(e){const t=V([]),s=V(""),n=V(!1),i=V(null),o=Jt({}),r=Jt({}),l=V(!1),a=V({name:"",baseURL:"",provider:""});async function p(){try{const P=await se("/api/admin/plugins");t.value=P.plugins||[],s.value=""}catch(P){s.value=P.message}}ut(p);function u(P){var $;if(i.value===P.name){i.value=null;return}const T={};for(const j of P.configFields||[])T[j.key]=(($=P.config)==null?void 0:$[j.key])??"";o[P.name]=T,i.value=P.name}async function m(P,T){n.value=!0,r[P.name]="";try{const $=await se(`/api/admin/plugins/${encodeURIComponent(P.name)}`,{method:"PUT",body:{enabled:T,config:o[P.name]??{}}});r[P.name]=$.warning||h("plugins.saved"),await p()}catch($){r[P.name]=$.message}finally{n.value=!1}}async function y(P){n.value=!0,r[P.name]=h("plugins.checking");try{const T=await se(`/api/admin/plugins/${encodeURIComponent(P.name)}/health`,{method:"POST"});r[P.name]=`${T.health.status}${T.health.detail?" — "+T.health.detail:""}`,await p()}catch(T){r[P.name]=T.message}finally{n.value=!1}}async function A(P){if(confirm(h("plugins.confirmRemove",{name:P.name}))){n.value=!0;try{await se(`/api/admin/plugins/${encodeURIComponent(P.name)}`,{method:"DELETE"}),i.value===P.name&&(i.value=null),await p()}catch(T){r[P.name]=T.message}finally{n.value=!1}}}async function D(){n.value=!0,s.value="";try{await se("/api/admin/plugins",{method:"POST",body:a.value}),a.value={name:"",baseURL:"",provider:""},l.value=!1,await p()}catch(P){s.value=P.message}finally{n.value=!1}}const C=P=>P==="ok"?"bg-success-soft text-success":P==="degraded"?"bg-warning-soft text-warning":"bg-danger-soft text-danger";return(P,T)=>(k(),E("div",eu,[d("div",tu,[d("div",null,[d("div",su,b(g(h)("plugins.title")),1),d("p",nu,b(g(h)("plugins.subtitle")),1)]),d("button",{class:"dh-btn-ghost",onClick:T[0]||(T[0]=$=>l.value=!l.value)},b(l.value?g(h)("plugins.cancelRegister"):g(h)("plugins.registerExternal")),1)]),l.value?(k(),E("div",iu,[d("div",ou,[d("div",null,[d("label",ru,b(g(h)("plugins.name")),1),re(d("input",{"onUpdate:modelValue":T[1]||(T[1]=$=>a.value.name=$),class:"dh-input",placeholder:"acme-parts"},null,512),[[pe,a.value.name]])]),d("div",null,[d("label",lu,b(g(h)("plugins.baseUrl")),1),re(d("input",{"onUpdate:modelValue":T[2]||(T[2]=$=>a.value.baseURL=$),class:"dh-input",placeholder:"http://127.0.0.1:9100"},null,512),[[pe,a.value.baseURL]])]),d("div",null,[d("label",au,b(g(h)("plugins.provider")),1),re(d("input",{"onUpdate:modelValue":T[3]||(T[3]=$=>a.value.provider=$),class:"dh-input",placeholder:"ACME Corp"},null,512),[[pe,a.value.provider]])])]),d("button",{class:"dh-btn mt-3",disabled:n.value||!a.value.name||!a.value.baseURL,onClick:D},b(g(h)("plugins.register")),9,cu)])):B("",!0),s.value?(k(),E("p",uu,b(s.value),1)):B("",!0),t.value.length?B("",!0):(k(),E("p",du,b(g(h)("plugins.empty")),1)),(k(!0),E(ee,null,ke(t.value,$=>(k(),E("div",{key:$.name,class:"border-t border-subtle first:border-t-0"},[d("div",fu,[d("button",{class:"flex flex-1 items-center gap-3 text-left",onClick:j=>u($)},[d("span",hu,b($.name),1),d("span",gu,b($.kind||g(h)("plugins.builtin")),1),$.provider?(k(),E("span",mu,b($.provider),1)):B("",!0),$.health?(k(),E("span",{key:1,class:$e(["dh-pill",C($.health.status)])},[T[4]||(T[4]=d("span",{class:"h-1.5 w-1.5 rounded-full bg-current"},null,-1)),Te(b($.health.status),1)],2)):B("",!0)],8,pu),d("span",{class:$e(["dh-pill",$.enabled?"bg-success-soft text-success":"bg-sunken text-muted"])},b($.enabled?g(h)("plugins.enabled"):g(h)("plugins.disabled")),3),d("button",{class:"dh-btn-ghost",disabled:n.value,onClick:j=>y($)},b(g(h)("plugins.health")),9,bu),d("button",{class:"dh-btn-ghost",disabled:n.value,onClick:j=>u($)},b(i.value===$.name?g(h)("plugins.close"):g(h)("plugins.configure")),9,vu)]),i.value===$.name?(k(),E("div",_u,[$.baseURL?(k(),E("div",yu,b($.baseURL),1)):B("",!0),($.configFields||[]).length?(k(),E("div",wu,[(k(!0),E(ee,null,ke($.configFields,j=>(k(),E("div",{key:j.key},[d("label",xu,[Te(b(j.label||j.key),1),j.required?(k(),E("span",ku," *")):B("",!0)]),j.type==="select"?re((k(),E("select",{key:0,"onUpdate:modelValue":M=>o[$.name][j.key]=M,class:"dh-select"},[j.required?B("",!0):(k(),E("option",Tu,b(g(h)("plugins.notSet")),1)),(k(!0),E(ee,null,ke(j.options||[],M=>(k(),E("option",{key:M.value,value:M.value},b(M.label||M.value),9,Eu))),128))],8,Su)),[[xs,o[$.name][j.key]]]):re((k(),E("input",{key:1,"onUpdate:modelValue":M=>o[$.name][j.key]=M,class:"dh-input",type:j.type==="password"?"password":j.type==="number"?"number":"text",placeholder:j.default||"",autocomplete:"off"},null,8,Cu)),[[Gl,o[$.name][j.key]]]),j.help?(k(),E("p",Pu,b(j.help),1)):B("",!0)]))),128))])):(k(),E("p",$u,b(g(h)("plugins.noConfig")),1)),($.capabilities||[]).length?(k(),E("div",Au,[d("div",Ou,b(g(h)("plugins.capabilities")),1),d("ul",Ru,[(k(!0),E(ee,null,ke($.capabilities,j=>(k(),E("li",{key:j.id},[d("span",Iu,b(j.id),1),j.method||j.endpoint?(k(),E("span",Uu," — "+b(j.method)+" "+b(j.endpoint),1)):B("",!0),j.description?(k(),E("span",ju," · "+b(j.description),1)):B("",!0)]))),128))])])):B("",!0),r[$.name]?(k(),E("p",Mu,b(r[$.name]),1)):B("",!0),d("div",Nu,[d("button",{class:"dh-btn",disabled:n.value,onClick:j=>m($,!0)},b($.enabled?g(h)("plugins.save"):g(h)("plugins.saveEnable")),9,Du),$.enabled?(k(),E("button",{key:0,class:"dh-btn-ghost",disabled:n.value,onClick:j=>m($,!1)},b(g(h)("plugins.disable")),9,zu)):B("",!0),T[5]||(T[5]=d("span",{class:"flex-1"},null,-1)),$.kind==="external"?(k(),E("button",{key:1,class:"dh-btn-danger",disabled:n.value,onClick:j=>A($)},b(g(h)("plugins.remove")),9,Lu)):B("",!0)]),$.kind!=="external"?(k(),E("p",Fu,b(g(h)("plugins.builtinNote")),1)):B("",!0)])):B("",!0)]))),128))]))}},Hu={class:"dh-card overflow-hidden"},Vu={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},Ku={class:"text-base font-bold tracking-[-0.02em] text-strong"},Wu={class:"mt-0.5 text-xs text-muted"},Gu={key:0,class:"border-b border-subtle px-5 py-3 text-xs text-danger"},qu={key:1,class:"border-b border-subtle bg-sunken px-5 py-4"},Zu={class:"grid gap-3 sm:grid-cols-2"},Ju={class:"dh-label"},Yu={class:"dh-label"},Xu={class:"dh-label"},Qu=["placeholder"],ed={class:"dh-label"},td=["value"],sd={key:0},nd={class:"dh-label"},id={value:""},od=["value"],rd={class:"mt-3 flex items-center gap-2"},ld=["disabled"],ad=["disabled"],cd={key:2,class:"px-5 py-6 text-center text-sm text-muted"},ud={key:3,class:"w-full text-left text-sm"},dd={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"},pd={key:0,class:"eyebrow ml-1"},hd={class:"px-5 py-2.5 text-body"},gd={class:"px-5 py-2.5 text-body"},md={class:"px-5 py-2.5"},bd={class:"px-5 py-2.5 text-right whitespace-nowrap"},vd=["onClick"],_d=["disabled","onClick"],yd={__name:"UsersCard",setup(e){const t=V([]),s=V([]),n=V(""),i=V(!1),o=V(null),r=V({}),l=Qe(()=>bt.value?["user","admin","superadmin"]:["user","admin"]);async function a(){try{const[C,P]=await Promise.all([se("/api/users"),se("/api/orgs")]);t.value=C.users||[],s.value=P.organizations||[],n.value=""}catch(C){n.value=C.message}}ut(a);function p(){var C;o.value="new",r.value={email:"",name:"",password:"",role:"user",organization:bt.value?"":((C=de.value)==null?void 0:C.organization)||""}}function u(C){o.value=C.id,r.value={email:C.email,name:C.name||"",password:"",role:C.role,organization:C.organization||""}}function m(){o.value=null,n.value=""}async function y(){i.value=!0,n.value="";try{if(o.value==="new")await se("/api/users",{method:"POST",body:r.value});else{const C={...r.value};C.password||delete C.password,await se(`/api/users/${o.value}`,{method:"PATCH",body:C})}o.value=null,await a()}catch(C){n.value=C.message}finally{i.value=!1}}async function A(C){if(confirm(h("users.confirmDelete",{email:C.email}))){i.value=!0,n.value="";try{await se(`/api/users/${C.id}`,{method:"DELETE"}),await a()}catch(P){n.value=P.message}finally{i.value=!1}}}const D=C=>C==="superadmin"?"bg-info-soft text-info":C==="admin"?"bg-warning-soft text-warning":"bg-sunken text-muted";return(C,P)=>(k(),E("div",Hu,[d("div",Vu,[d("div",null,[d("div",Ku,b(g(h)("users.title")),1),d("p",Wu,b(g(bt)?g(h)("users.allOrgs"):g(h)("users.yourOrg")),1)]),d("button",{class:"dh-btn",onClick:p},b(g(h)("users.newUser")),1)]),n.value?(k(),E("p",Gu,b(n.value),1)):B("",!0),o.value?(k(),E("div",qu,[d("div",Zu,[d("div",null,[d("label",Ju,b(g(h)("common.email")),1),re(d("input",{"onUpdate:modelValue":P[0]||(P[0]=T=>r.value.email=T),class:"dh-input",type:"email",autocomplete:"off"},null,512),[[pe,r.value.email]])]),d("div",null,[d("label",Yu,b(g(h)("common.name")),1),re(d("input",{"onUpdate:modelValue":P[1]||(P[1]=T=>r.value.name=T),class:"dh-input",autocomplete:"off"},null,512),[[pe,r.value.name]])]),d("div",null,[d("label",Xu,b(o.value==="new"?g(h)("users.password"):g(h)("users.passwordUnchanged")),1),re(d("input",{"onUpdate:modelValue":P[2]||(P[2]=T=>r.value.password=T),class:"dh-input",type:"password",autocomplete:"new-password",placeholder:g(h)("users.passwordPlaceholder")},null,8,Qu),[[pe,r.value.password]])]),d("div",null,[d("label",ed,b(g(h)("common.role")),1),re(d("select",{"onUpdate:modelValue":P[3]||(P[3]=T=>r.value.role=T),class:"dh-select"},[(k(!0),E(ee,null,ke(l.value,T=>(k(),E("option",{key:T,value:T},b(T),9,td))),128))],512),[[xs,r.value.role]])]),g(bt)?(k(),E("div",sd,[d("label",nd,b(g(h)("common.organization")),1),re(d("select",{"onUpdate:modelValue":P[4]||(P[4]=T=>r.value.organization=T),class:"dh-select"},[d("option",id,b(g(h)("users.orgNone")),1),(k(!0),E(ee,null,ke(s.value,T=>(k(),E("option",{key:T.id,value:T.id},b(T.name),9,od))),128))],512),[[xs,r.value.organization]])])):B("",!0)]),d("div",rd,[d("button",{class:"dh-btn",disabled:i.value,onClick:y},b(o.value==="new"?g(h)("common.create"):g(h)("common.save")),9,ld),d("button",{class:"dh-btn-ghost",disabled:i.value,onClick:m},b(g(h)("common.cancel")),9,ad)])])):B("",!0),t.value.length?(k(),E("table",ud,[d("thead",null,[d("tr",dd,[d("th",null,b(g(h)("common.email")),1),d("th",null,b(g(h)("common.name")),1),d("th",null,b(g(h)("common.organization")),1),d("th",null,b(g(h)("common.role")),1),P[5]||(P[5]=d("th",null,null,-1))])]),d("tbody",null,[(k(!0),E(ee,null,ke(t.value,T=>{var $,j;return k(),E("tr",{key:T.id,class:"border-t border-subtle transition-colors hover:bg-sunken"},[d("td",fd,[Te(b(T.email)+" ",1),T.id===(($=g(de))==null?void 0:$.id)?(k(),E("span",pd,b(g(h)("users.you")),1)):B("",!0)]),d("td",hd,b(T.name||g(h)("common.empty")),1),d("td",gd,b(T.organizationName||g(h)("common.empty")),1),d("td",md,[d("span",{class:$e(["dh-pill",D(T.role)])},b(T.role),3)]),d("td",bd,[d("button",{class:"dh-btn-ghost",onClick:M=>u(T)},b(g(h)("common.edit")),9,vd),T.id!==((j=g(de))==null?void 0:j.id)?(k(),E("button",{key:0,class:"dh-btn-danger ml-1.5",disabled:i.value,onClick:M=>A(T)},b(g(h)("common.delete")),9,_d)):B("",!0)])])}),128))])])):(k(),E("p",cd,b(g(h)("users.empty")),1))]))}},wd={class:"dh-card overflow-hidden"},xd={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},kd={class:"text-base font-bold tracking-[-0.02em] text-strong"},Sd={class:"mt-0.5 text-xs text-muted"},Td={key:0,class:"border-b border-subtle px-5 py-3 text-xs text-danger"},Ed={key:1,class:"border-b border-subtle bg-sunken px-5 py-4"},Cd={class:"dh-label"},Pd=["placeholder"],$d={class:"mt-3 flex items-center gap-2"},Ad=["disabled"],Od=["disabled"],Rd={key:2,class:"px-5 py-6 text-center text-sm text-muted"},Id={key:3,class:"w-full text-left text-sm"},Ud={class:"[&>th]:eyebrow [&>th]:px-5 [&>th]:py-2.5 [&>th]:font-medium"},jd={class:"px-5 py-2.5 font-medium text-strong"},Md={class:"data px-5 py-2.5 text-xs text-muted"},Nd={class:"px-5 py-2.5 text-right whitespace-nowrap"},Dd=["onClick"],zd=["disabled","onClick"],Ld={__name:"OrgsCard",setup(e){const t=V([]),s=V(""),n=V(!1),i=V(null),o=V("");async function r(){try{const y=await se("/api/orgs");t.value=y.organizations||[],s.value=""}catch(y){s.value=y.message}}ut(r);function l(){i.value="new",o.value=""}function a(y){i.value=y.id,o.value=y.name}function p(){i.value=null,s.value=""}async function u(){n.value=!0,s.value="";try{i.value==="new"?await se("/api/orgs",{method:"POST",body:{name:o.value}}):await se(`/api/orgs/${i.value}`,{method:"PATCH",body:{name:o.value}}),i.value=null,await r()}catch(y){s.value=y.message}finally{n.value=!1}}async function m(y){if(confirm(h("orgs.confirmDelete",{name:y.name}))){n.value=!0,s.value="";try{await se(`/api/orgs/${y.id}`,{method:"DELETE"}),await r()}catch(A){s.value=A.message}finally{n.value=!1}}}return(y,A)=>(k(),E("div",wd,[d("div",xd,[d("div",null,[d("div",kd,b(g(h)("orgs.title")),1),d("p",Sd,b(g(h)("orgs.subtitle")),1)]),g(bt)?(k(),E("button",{key:0,class:"dh-btn",onClick:l},b(g(h)("orgs.newOrg")),1)):B("",!0)]),s.value?(k(),E("p",Td,b(s.value),1)):B("",!0),i.value?(k(),E("div",Ed,[d("label",Cd,b(g(h)("common.name")),1),re(d("input",{"onUpdate:modelValue":A[0]||(A[0]=D=>o.value=D),class:"dh-input",placeholder:g(h)("orgs.namePlaceholder"),onKeyup:Ql(u,["enter"])},null,40,Pd),[[pe,o.value]]),d("div",$d,[d("button",{class:"dh-btn",disabled:n.value||!o.value.trim(),onClick:u},b(i.value==="new"?g(h)("common.create"):g(h)("common.save")),9,Ad),d("button",{class:"dh-btn-ghost",disabled:n.value,onClick:p},b(g(h)("common.cancel")),9,Od)])])):B("",!0),t.value.length?(k(),E("table",Id,[d("thead",null,[d("tr",Ud,[d("th",null,b(g(h)("common.name")),1),d("th",null,b(g(h)("orgs.colId")),1),A[1]||(A[1]=d("th",null,null,-1))])]),d("tbody",null,[(k(!0),E(ee,null,ke(t.value,D=>(k(),E("tr",{key:D.id,class:"border-t border-subtle transition-colors hover:bg-sunken"},[d("td",jd,b(D.name),1),d("td",Md,b(D.id),1),d("td",Nd,[g(bt)?(k(),E(ee,{key:0},[d("button",{class:"dh-btn-ghost",onClick:C=>a(D)},b(g(h)("common.rename")),9,Dd),d("button",{class:"dh-btn-danger ml-1.5",disabled:n.value,onClick:C=>m(D)},b(g(h)("common.delete")),9,zd)],64)):B("",!0)])]))),128))])])):(k(),E("p",Rd,b(g(h)("orgs.empty")),1))]))}},Fd={class:"dh-card overflow-hidden"},Bd={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},Hd={class:"text-base font-bold tracking-[-0.02em] text-strong"},Vd={class:"eyebrow"},Kd={class:"w-full text-left text-sm"},Wd={class:"[&>th]:eyebrow [&>th]:px-5 [&>th]:py-2.5 [&>th]:font-medium"},Gd={class:"data border-t border-subtle px-5 py-2.5 text-xs whitespace-nowrap"},qd={class:"text-strong"},Zd={class:"border-t border-subtle px-5 py-2.5 text-body"},nt={__name:"EndpointTable",props:{title:String,auth:String,endpoints:Array},setup(e){const t={GET:"text-success",POST:"text-brandtext",PATCH:"text-warning",DELETE:"text-danger"};return(s,n)=>(k(),E("div",Fd,[d("div",Bd,[d("div",Hd,b(e.title),1),d("span",Vd,b(e.auth),1)]),d("table",Kd,[d("thead",null,[d("tr",Wd,[d("th",null,b(g(h)("api.colEndpoint")),1),d("th",null,b(g(h)("api.colDescription")),1)])]),d("tbody",null,[(k(!0),E(ee,null,ke(e.endpoints,i=>(k(),E("tr",{key:i.method+i.path,class:"transition-colors hover:bg-sunken"},[d("td",Gd,[d("span",{class:$e(["font-semibold",t[i.method]])},b(i.method),3),d("span",qd,b(i.path),1)]),d("td",Zd,b(i.desc),1)]))),128))])])]))}},Jd={class:"mx-auto flex max-w-4xl flex-col gap-6 px-6 pt-12 pb-16"},Yd={class:"flex items-center gap-3"},Xd={class:"inline-flex items-center gap-2.5 select-none"},Qd={class:"h-8 w-8 shrink-0",viewBox:"0 0 48 48",fill:"none","aria-hidden":"true"},ef={transform:"translate(7 0) skewX(-13)"},tf=["fill"],sf=["fill"],nf=["fill"],of={class:"eyebrow mt-1.5"},rf={key:0,class:"data hidden text-xs text-muted sm:inline"},lf={key:0},af={key:1,class:"dh-pill bg-info-soft text-info"},cf=["value","aria-label"],uf=["value"],df=["title"],ff={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"},pf={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"},hf={key:0,class:"eyebrow py-16 text-center"},gf={class:"flex flex-wrap gap-1.5"},mf=["onClick"],bf={key:7,class:"eyebrow text-center"},vf={class:"eyebrow text-center"},_f={__name:"App",setup(e){const t=V(!0),s=V("overview");ut(async()=>{await Ya(),t.value=!1});const n=Qe(()=>{const C=[{id:"overview",label:h("sections.overview")}];return hi.value&&C.push({id:"users",label:h("sections.users")},{id:"orgs",label:h("sections.orgs")}),bt.value&&C.push({id:"pocketbase",label:h("sections.pocketbase")},{id:"webapp",label:h("sections.webapp")},{id:"plugins",label:h("sections.plugins")}),C.push({id:"api",label:h("sections.api")}),C}),i=Qe(()=>Ba.map(C=>{let P=C;try{P=new Intl.DisplayNames([C],{type:"language"}).of(C)||C}catch{}return{code:C,label:P.charAt(0).toUpperCase()+P.slice(1)}}));function o(){Tn(),s.value="overview"}const r=Qe(()=>Et.value==="dark"?["#60a5fa","#93c5fd","#ffffff"]:["var(--brand-700)","var(--brand-500)","var(--brand-400)"]),l=[{method:"GET",path:"/api/health",desc:"Liveness probe (no auth)"},{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"}],p=[{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:"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}/parts",desc:"A car's parts catalog"},{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)"}],u=[{method:"GET",path:"/api/service-records",desc:"List service records"},{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"}],m=[{method:"GET",path:"/api/parts",desc:"List parts"},{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"}],y=[{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"}],A=[{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 (superadmin)"},{method:"PATCH",path:"/api/orgs/{id}",desc:"Rename an organization (superadmin)"},{method:"DELETE",path:"/api/orgs/{id}",desc:"Delete an organization (superadmin)"}],D=[{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/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(C,P)=>(k(),E("div",Jd,[d("div",Yd,[d("span",Xd,[(k(),E("svg",Qd,[d("g",ef,[d("rect",{x:"9",y:"16",width:"6",height:"16",rx:"3",fill:r.value[0]},null,8,tf),d("rect",{x:"19",y:"12",width:"6",height:"24",rx:"3",fill:r.value[1]},null,8,sf),d("rect",{x:"29",y:"8",width:"6",height:"32",rx:"3",fill:r.value[2]},null,8,nf)])])),P[2]||(P[2]=d("span",{class:"text-2xl leading-none font-extrabold tracking-[-0.03em] italic"},[d("span",{class:"text-strong"},"Driver"),d("span",{class:"text-brandtext"},"Vault")],-1))]),d("span",of,b(g(h)("app.apiServer")),1),P[5]||(P[5]=d("div",{class:"flex-1"},null,-1)),g(de)?(k(),E("span",rf,[Te(b(g(de).email),1),g(de).organizationName?(k(),E("span",lf," · "+b(g(de).organizationName),1)):B("",!0)])):B("",!0),g(de)?(k(),E("span",af,b(g(de).role),1)):B("",!0),d("select",{class:"dh-select !w-auto !py-1 !text-xs",value:g(Sn),"aria-label":g(h)("sections.overview"),onChange:P[0]||(P[0]=T=>g(Va)(T.target.value))},[(k(!0),E(ee,null,ke(i.value,T=>(k(),E("option",{key:T.code,value:T.code},b(T.label),9,uf))),128))],40,cf),d("button",{class:"dh-btn-ghost",title:g(Et)==="dark"?g(h)("app.switchToLight"):g(h)("app.switchToDark"),onClick:P[1]||(P[1]=(...T)=>g(di)&&g(di)(...T))},[g(Et)==="dark"?(k(),E("svg",ff,[...P[3]||(P[3]=[d("circle",{cx:"12",cy:"12",r:"4"},null,-1),d("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)])])):(k(),E("svg",pf,[...P[4]||(P[4]=[d("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)])])),Te(" "+b(g(h)("app.theme")),1)],8,df),g(Ot)?(k(),E("button",{key:2,class:"dh-btn-ghost",onClick:o},b(g(h)("app.signOut")),1)):B("",!0)]),t.value?(k(),E("p",hf,b(g(h)("app.loading")),1)):g(Ot)?(k(),E(ee,{key:2},[d("nav",gf,[(k(!0),E(ee,null,ke(n.value,T=>(k(),E("button",{key:T.id,class:$e(["dh-btn-ghost",s.value===T.id?"border-accent text-brandtext":""]),onClick:$=>s.value=T.id},b(T.label),11,mf))),128))]),s.value==="overview"?(k(),it(_c,{key:0})):s.value==="users"?(k(),it(yd,{key:1})):s.value==="orgs"?(k(),it(Ld,{key:2})):s.value==="pocketbase"?(k(),it(Nc,{key:3})):s.value==="webapp"?(k(),it(Qc,{key:4})):s.value==="plugins"?(k(),it(Bu,{key:5})):s.value==="api"?(k(),E(ee,{key:6},[ce(nt,{title:g(h)("api.groupPublic"),auth:g(h)("api.authNone"),endpoints:l},null,8,["title","auth"]),ce(nt,{title:g(h)("api.groupIdentity"),auth:g(h)("api.authBearer"),endpoints:a},null,8,["title","auth"]),ce(nt,{title:g(h)("api.groupCars"),auth:g(h)("api.authBearer"),endpoints:p},null,8,["title","auth"]),ce(nt,{title:g(h)("api.groupService"),auth:g(h)("api.authBearer"),endpoints:u},null,8,["title","auth"]),ce(nt,{title:g(h)("api.groupParts"),auth:g(h)("api.authBearer"),endpoints:m},null,8,["title","auth"]),ce(nt,{title:g(h)("api.groupAccount"),auth:g(h)("api.authBearer"),endpoints:y},null,8,["title","auth"]),ce(nt,{title:g(h)("api.groupManagement"),auth:g(h)("api.authManager"),endpoints:A},null,8,["title","auth"]),ce(nt,{title:g(h)("api.groupSuperadmin"),auth:g(h)("api.authSuperadmin"),endpoints:D},null,8,["title","auth"])],64)):B("",!0),!g(hi)&&s.value==="overview"?(k(),E("p",bf,b(g(h)("app.standardUserNote")),1)):B("",!0)],64)):(k(),it(lc,{key:1})),d("p",vf,b(g(h)("app.footer")),1)]))}};sa(_f).mount("#app"); diff --git a/API Server/internal/api/dist/assets/index-OHZkxAdj.js b/API Server/internal/api/dist/assets/index-OHZkxAdj.js new file mode 100644 index 0000000..fee5676 --- /dev/null +++ b/API Server/internal/api/dist/assets/index-OHZkxAdj.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 cn(e){const t=Object.create(null);for(const s of e.split(","))t[s]=1;return s=>s in t}const J={},xt=[],Ke=()=>{},mi=()=>!1,Ts=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),Es=e=>e.startsWith("onUpdate:"),he=Object.assign,un=(e,t)=>{const s=e.indexOf(t);s>-1&&e.splice(s,1)},$o=Object.prototype.hasOwnProperty,G=(e,t)=>$o.call(e,t),M=Array.isArray,kt=e=>es(e)==="[object Map]",Rt=e=>es(e)==="[object Set]",jn=e=>es(e)==="[object Date]",H=e=>typeof e=="function",ne=e=>typeof e=="string",We=e=>typeof e=="symbol",Z=e=>e!==null&&typeof e=="object",bi=e=>(Z(e)||H(e))&&H(e.then)&&H(e.catch),vi=Object.prototype.toString,es=e=>vi.call(e),Ao=e=>es(e).slice(8,-1),_i=e=>es(e)==="[object Object]",dn=e=>ne(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,Ft=cn(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),Cs=e=>{const t=Object.create(null);return(s=>t[s]||(t[s]=e(s)))},Oo=/-\w/g,Pe=Cs(e=>e.replace(Oo,t=>t.slice(1).toUpperCase())),Ro=/\B([A-Z])/g,ut=Cs(e=>e.replace(Ro,"-$1").toLowerCase()),yi=Cs(e=>e.charAt(0).toUpperCase()+e.slice(1)),Ds=Cs(e=>e?`on${yi(e)}`:""),Ve=(e,t)=>!Object.is(e,t),fs=(e,...t)=>{for(let s=0;s{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:n,value:s})},Ps=e=>{const t=parseFloat(e);return isNaN(t)?e:t};let zn;const $s=()=>zn||(zn=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function fn(e){if(M(e)){const t={};for(let s=0;s{if(s){const n=s.split(jo);n.length>1&&(t[n[0].trim()]=n[1].trim())}}),t}function Oe(e){let t="";if(ne(e))t=e;else if(M(e))for(let s=0;slt(s,t))}const ki=e=>!!(e&&e.__v_isRef===!0),b=e=>ne(e)?e:e==null?"":M(e)||Z(e)&&(e.toString===vi||!H(e.toString))?ki(e)?b(e.value):JSON.stringify(e,Si,2):String(e),Si=(e,t)=>ki(t)?Si(e,t.value):kt(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((s,[n,i],o)=>(s[Ms(n,o)+" =>"]=i,s),{})}:Rt(t)?{[`Set(${t.size})`]:[...t.values()].map(s=>Ms(s))}:We(t)?Ms(t):Z(t)&&!M(t)&&!_i(t)?String(t):t,Ms=(e,t="")=>{var s;return We(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 ce;class Lo{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&&ce&&(ce.active?(this.parent=ce,this.index=(ce.scopes||(ce.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(ce===this)ce=this.prevScope;else{let t=ce;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(Ht){let t=Ht;for(Ht=void 0;t;){const s=t.next;t.next=void 0,t.flags&=-9,t=s}}let e;for(;Bt;){let t=Bt;for(Bt=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 Pi(e){for(let t=e.deps;t;t=t.nextDep)t.version=-1,t.prevActiveLink=t.dep.activeLink,t.dep.activeLink=t}function $i(e){let t,s=e.depsTail,n=s;for(;n;){const i=n.prevDep;n.version===-1?(n===s&&(s=i),mn(n),Bo(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&&(Ai(t.dep.computed)||t.dep.version!==t.version))return!0;return!!e._dirty}function Ai(e){if(e.flags&4&&!(e.flags&16)||(e.flags&=-17,e.globalVersion===qt)||(e.globalVersion=qt,!e.isSSR&&e.flags&128&&(!e.deps&&!e._dirty||!Ys(e))))return;e.flags|=2;const t=e.dep,s=Q,n=$e;Q=e,$e=!0;try{Pi(e);const i=e.fn(e._value);(t.version===0||Ve(i,e._value))&&(e.flags|=128,e._value=i,t.version++)}catch(i){throw t.version++,i}finally{Q=s,$e=n,$i(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 Bo(e){const{prevDep:t,nextDep:s}=e;t&&(t.nextDep=s,e.prevDep=void 0),s&&(s.prevDep=t,e.nextDep=void 0)}let $e=!0;const Oi=[];function Ge(){Oi.push($e),$e=!1}function qe(){const e=Oi.pop();$e=e===void 0?!0:e}function Un(e){const{cleanup:t}=e;if(e.cleanup=void 0,t){const s=Q;Q=void 0;try{t()}finally{Q=s}}}let qt=0;class Ho{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(!Q||!$e||Q===this.computed)return;let s=this.activeLink;if(s===void 0||s.sub!==Q)s=this.activeLink=new Ho(Q,this),Q.deps?(s.prevDep=Q.depsTail,Q.depsTail.nextDep=s,Q.depsTail=s):Q.deps=Q.depsTail=s,Ri(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=Q.depsTail,s.nextDep=void 0,Q.depsTail.nextDep=s,Q.depsTail=s,Q.deps===s&&(Q.deps=n)}return s}trigger(t){this.version++,qt++,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 Ri(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)Ri(n)}const s=e.dep.subs;s!==e&&(e.prevSub=s,s&&(s.nextSub=e)),e.dep.subs=e}}const Js=new WeakMap,vt=Symbol(""),Xs=Symbol(""),Zt=Symbol("");function de(e,t,s){if($e&&Q){let n=Js.get(e);n||Js.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 Xe(e,t,s,n,i,o){const r=Js.get(e);if(!r){qt++;return}const l=a=>{a&&a.trigger()};if(hn(),t==="clear")r.forEach(l);else{const a=M(e),p=a&&dn(s);if(a&&s==="length"){const u=Number(n);r.forEach((m,P)=>{(P==="length"||P===Zt||!We(P)&&P>=u)&&l(m)})}else switch((s!==void 0||r.has(void 0))&&l(r.get(s)),p&&l(r.get(Zt)),t){case"add":a?p&&l(r.get("length")):(l(r.get(vt)),kt(e)&&l(r.get(Xs)));break;case"delete":a||(l(r.get(vt)),kt(e)&&l(r.get(Xs)));break;case"set":kt(e)&&l(r.get(vt));break}}gn()}function yt(e){const t=W(e);return t===e?t:(de(t,"iterate",Zt),Te(e)?t:t.map(Re))}function As(e){return de(e=W(e),"iterate",Zt),e}function Be(e,t){return tt(e)?Ct(_t(e)?Re(t):t):Re(t)}const Vo={__proto__:null,[Symbol.iterator](){return Fs(this,Symbol.iterator,e=>Be(this,e))},concat(...e){return yt(this).concat(...e.map(t=>M(t)?yt(t):t))},entries(){return Fs(this,"entries",e=>(e[1]=Be(this,e[1]),e))},every(e,t){return Ze(this,"every",e,t,void 0,arguments)},filter(e,t){return Ze(this,"filter",e,t,s=>s.map(n=>Be(this,n)),arguments)},find(e,t){return Ze(this,"find",e,t,s=>Be(this,s),arguments)},findIndex(e,t){return Ze(this,"findIndex",e,t,void 0,arguments)},findLast(e,t){return Ze(this,"findLast",e,t,s=>Be(this,s),arguments)},findLastIndex(e,t){return Ze(this,"findLastIndex",e,t,void 0,arguments)},forEach(e,t){return Ze(this,"forEach",e,t,void 0,arguments)},includes(...e){return Bs(this,"includes",e)},indexOf(...e){return Bs(this,"indexOf",e)},join(e){return yt(this).join(e)},lastIndexOf(...e){return Bs(this,"lastIndexOf",e)},map(e,t){return Ze(this,"map",e,t,void 0,arguments)},pop(){return Nt(this,"pop")},push(...e){return Nt(this,"push",e)},reduce(e,...t){return Nn(this,"reduce",e,t)},reduceRight(e,...t){return Nn(this,"reduceRight",e,t)},shift(){return Nt(this,"shift")},some(e,t){return Ze(this,"some",e,t,void 0,arguments)},splice(...e){return Nt(this,"splice",e)},toReversed(){return yt(this).toReversed()},toSorted(e){return yt(this).toSorted(e)},toSpliced(...e){return yt(this).toSpliced(...e)},unshift(...e){return Nt(this,"unshift",e)},values(){return Fs(this,"values",e=>Be(this,e))}};function Fs(e,t,s){const n=As(e),i=n[t]();return n!==e&&!Te(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 Ze(e,t,s,n,i,o){const r=As(e),l=r!==e&&!Te(e),a=r[t];if(a!==Ko[t]){const m=a.apply(e,o);return l?Re(m):m}let p=s;r!==e&&(l?p=function(m,P){return s.call(this,Be(e,m),P,e)}:s.length>2&&(p=function(m,P){return s.call(this,m,P,e)}));const u=a.call(r,p,n);return l&&i?i(u):u}function Nn(e,t,s,n){const i=As(e),o=i!==e&&!Te(e);let r=s,l=!1;i!==e&&(o?(l=n.length===0,r=function(p,u,m){return l&&(l=!1,p=Be(e,p)),s.call(this,p,Be(e,u),m,e)}):s.length>3&&(r=function(p,u,m){return s.call(this,p,u,m,e)}));const a=i[t](r,...n);return l?Be(e,a):a}function Bs(e,t,s){const n=W(e);de(n,"iterate",Zt);const i=n[t](...s);return(i===-1||i===!1)&&yn(s[0])?(s[0]=W(s[0]),n[t](...s)):i}function Nt(e,t,s=[]){Ge(),hn();const n=W(e)[t].apply(e,s);return gn(),qe(),n}const Wo=cn("__proto__,__v_isRef,__isVue"),Ii=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(We));function Go(e){We(e)||(e=String(e));const t=W(this);return de(t,"has",e),t.hasOwnProperty(e)}class ji{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?nr:Di:o?Ni:Ui).get(t)||Object.getPrototypeOf(t)===Object.getPrototypeOf(n)?t:void 0;const r=M(t);if(!i){let a;if(r&&(a=Vo[s]))return a;if(s==="hasOwnProperty")return Go}const l=Reflect.get(t,s,fe(t)?t:n);if((We(s)?Ii.has(s):Wo(s))||(i||de(t,"get",s),o))return l;if(fe(l)){const a=r&&dn(s)?l:l.value;return i&&Z(a)?en(a):a}return Z(l)?i?en(l):Yt(l):l}}class zi extends ji{constructor(t=!1){super(!1,t)}set(t,s,n,i){let o=t[s];const r=M(t)&&dn(s);if(!this._isShallow){const p=tt(o);if(!Te(n)&&!tt(n)&&(o=W(o),n=W(n)),!r&&fe(o)&&!fe(n))return p||(o.value=n),!0}const l=r?Number(s)e,as=e=>Reflect.getPrototypeOf(e);function Xo(e,t,s){return function(...n){const i=this.__v_raw,o=W(i),r=kt(o),l=e==="entries"||e===Symbol.iterator&&r,a=e==="keys"&&r,p=i[e](...n),u=s?Qs:t?Ct:Re;return!t&&de(o,"iterate",a?Xs:vt),he(Object.create(p),{next(){const{value:m,done:P}=p.next();return P?{value:m,done:P}:{value:l?[u(m[0]),u(m[1])]:u(m),done:P}}})}}function cs(e){return function(...t){return e==="delete"?!1:e==="clear"?void 0:this}}function Qo(e,t){const s={get(i){const o=this.__v_raw,r=W(o),l=W(i);e||(Ve(i,l)&&de(r,"get",i),de(r,"get",l));const{has:a}=as(r),p=t?Qs:e?Ct:Re;if(a.call(r,i))return p(o.get(i));if(a.call(r,l))return p(o.get(l));o!==r&&o.get(i)},get size(){const i=this.__v_raw;return!e&&de(W(i),"iterate",vt),i.size},has(i){const o=this.__v_raw,r=W(o),l=W(i);return e||(Ve(i,l)&&de(r,"has",i),de(r,"has",l)),i===l?o.has(i):o.has(i)||o.has(l)},forEach(i,o){const r=this,l=r.__v_raw,a=W(l),p=t?Qs:e?Ct:Re;return!e&&de(a,"iterate",vt),l.forEach((u,m)=>i.call(o,p(u),p(m),r))}};return he(s,e?{add:cs("add"),set:cs("set"),delete:cs("delete"),clear:cs("clear")}:{add(i){const o=W(this),r=as(o),l=W(i),a=!t&&!Te(i)&&!tt(i)?l:i;return r.has.call(o,a)||Ve(i,a)&&r.has.call(o,i)||Ve(l,a)&&r.has.call(o,l)||(o.add(a),Xe(o,"add",a,a)),this},set(i,o){!t&&!Te(o)&&!tt(o)&&(o=W(o));const r=W(this),{has:l,get:a}=as(r);let p=l.call(r,i);p||(i=W(i),p=l.call(r,i));const u=a.call(r,i);return r.set(i,o),p?Ve(o,u)&&Xe(r,"set",i,o):Xe(r,"add",i,o),this},delete(i){const o=W(this),{has:r,get:l}=as(o);let a=r.call(o,i);a||(i=W(i),a=r.call(o,i)),l&&l.call(o,i);const p=o.delete(i);return a&&Xe(o,"delete",i,void 0),p},clear(){const i=W(this),o=i.size!==0,r=i.clear();return o&&Xe(i,"clear",void 0,void 0),r}}),["keys","values","entries",Symbol.iterator].forEach(i=>{s[i]=Xo(i,e,t)}),s}function vn(e,t){const s=Qo(e,t);return(n,i,o)=>i==="__v_isReactive"?!e:i==="__v_isReadonly"?e:i==="__v_raw"?n:Reflect.get(G(s,i)&&i in n?s:n,i,o)}const er={get:vn(!1,!1)},tr={get:vn(!1,!0)},sr={get:vn(!0,!1)};const Ui=new WeakMap,Ni=new WeakMap,Di=new WeakMap,nr=new WeakMap;function ir(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 tt(e)?e:_n(e,!1,Zo,er,Ui)}function or(e){return _n(e,!1,Jo,tr,Ni)}function en(e){return _n(e,!0,Yo,sr,Di)}function _n(e,t,s,n,i){if(!Z(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=ir(Ao(e));if(r===0)return e;const l=new Proxy(e,r===2?n:s);return i.set(e,l),l}function _t(e){return tt(e)?_t(e.__v_raw):!!(e&&e.__v_isReactive)}function tt(e){return!!(e&&e.__v_isReadonly)}function Te(e){return!!(e&&e.__v_isShallow)}function yn(e){return e?!!e.__v_raw:!1}function W(e){const t=e&&e.__v_raw;return t?W(t):e}function rr(e){return!G(e,"__v_skip")&&Object.isExtensible(e)&&wi(e,"__v_skip",!0),e}const Re=e=>Z(e)?Yt(e):e,Ct=e=>Z(e)?en(e):e;function fe(e){return e?e.__v_isRef===!0:!1}function V(e){return lr(e,!1)}function lr(e,t){return fe(e)?e:new ar(e,t)}class ar{constructor(t,s){this.dep=new bn,this.__v_isRef=!0,this.__v_isShallow=!1,this._rawValue=s?t:W(t),this._value=s?t:Re(t),this.__v_isShallow=s}get value(){return this.dep.track(),this._value}set value(t){const s=this._rawValue,n=this.__v_isShallow||Te(t)||tt(t);t=n?t:W(t),Ve(t,s)&&(this._rawValue=t,this._value=n?t:Re(t),this.dep.trigger())}}function g(e){return fe(e)?e.value:e}const cr={get:(e,t,s)=>t==="__v_raw"?e:g(Reflect.get(e,t,s)),set:(e,t,s,n)=>{const i=e[t];return fe(i)&&!fe(s)?(i.value=s,!0):Reflect.set(e,t,s,n)}};function Mi(e){return _t(e)?e:new Proxy(e,cr)}class ur{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=qt-1,this.next=void 0,this.effect=this,this.__v_isReadonly=!s,this.isSSR=n}notify(){if(this.flags|=16,!(this.flags&8)&&Q!==this)return Ci(this,!0),!0}get value(){const t=this.dep.track();return Ai(this),t&&(t.version=this.dep.version),this._value}set value(t){this.setter&&this.setter(t)}}function dr(e,t,s=!1){let n,i;return H(e)?n=e:(n=e.get,i=e.set),new ur(n,i,s)}const us={},ms=new WeakMap;let bt;function fr(e,t=!1,s=bt){if(s){let n=ms.get(s);n||ms.set(s,n=[]),n.push(e)}}function pr(e,t,s=J){const{immediate:n,deep:i,once:o,scheduler:r,augmentJob:l,call:a}=s,p=U=>i?U:Te(U)||i===!1||i===0?Qe(U,1):Qe(U);let u,m,P,O,F=!1,_=!1;if(fe(e)?(m=()=>e.value,F=Te(e)):_t(e)?(m=()=>p(e),F=!0):M(e)?(_=!0,F=e.some(U=>_t(U)||Te(U)),m=()=>e.map(U=>{if(fe(U))return U.value;if(_t(U))return p(U);if(H(U))return a?a(U,2):U()})):H(e)?t?m=a?()=>a(e,2):e:m=()=>{if(P){Ge();try{P()}finally{qe()}}const U=bt;bt=u;try{return a?a(e,3,[O]):e(O)}finally{bt=U}}:m=Ke,t&&i){const U=m,oe=i===!0?1/0:i;m=()=>Qe(U(),oe)}const E=Fo(),y=()=>{u.stop(),E&&E.active&&un(E.effects,u)};if(o&&t){const U=t;t=(...oe)=>{const je=U(...oe);return y(),je}}let $=_?new Array(e.length).fill(us):us;const z=U=>{if(!(!(u.flags&1)||!u.dirty&&!U))if(t){const oe=u.run();if(U||i||F||(_?oe.some((je,ze)=>Ve(je,$[ze])):Ve(oe,$))){P&&P();const je=bt;bt=u;try{const ze=[oe,$===us?void 0:_&&$[0]===us?[]:$,O];$=oe,a?a(t,3,ze):t(...ze)}finally{bt=je}}}else u.run()};return l&&l(z),u=new Ti(m),u.scheduler=r?()=>r(z,!1):z,O=U=>fr(U,!1,u),P=u.onStop=()=>{const U=ms.get(u);if(U){if(a)a(U,4);else for(const oe of U)oe();ms.delete(u)}},t?n?z(!0):$=u.run():r?r(z.bind(null,!0),!0):u.run(),y.pause=u.pause.bind(u),y.resume=u.resume.bind(u),y.stop=y,y}function Qe(e,t=1/0,s){if(t<=0||!Z(e)||e.__v_skip||(s=s||new Map,(s.get(e)||0)>=t))return e;if(s.set(e,t),t--,fe(e))Qe(e.value,t,s);else if(M(e))for(let n=0;n{Qe(n,t,s)});else if(_i(e)){for(const n in e)Qe(e[n],t,s);for(const n of Object.getOwnPropertySymbols(e))Object.prototype.propertyIsEnumerable.call(e,n)&&Qe(e[n],t,s)}return e}/** +* @vue/runtime-core v3.5.39 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/function ts(e,t,s,n){try{return n?e(...n):e()}catch(i){Os(i,t,s)}}function Ie(e,t,s,n){if(H(e)){const i=ts(e,t,s,n);return i&&bi(i)&&i.catch(o=>{Os(o,t,s)}),i}if(M(e)){const i=[];for(let o=0;o>>1,i=be[n],o=Jt(i);o=Jt(s)?be.push(e):be.splice(gr(t),0,e),e.flags|=1,Bi()}}function Bi(){bs||(bs=Li.then(Vi))}function mr(e){M(e)?St.push(...e):rt&&e.id===-1?rt.splice(wt+1,0,e):e.flags&1||(St.push(e),e.flags|=1),Bi()}function Dn(e,t,s=Fe+1){for(;sJt(s)-Jt(n));if(St.length=0,rt){rt.push(...t);return}for(rt=t,wt=0;wte.id==null?e.flags&2?-1:1/0:e.id;function Vi(e){try{for(Fe=0;Fe{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 le(e,t){if(ke===null)return e;const s=zs(ke),n=e.dirs||(e.dirs=[]);for(let i=0;i1)return s&&H(t)?t.call(n&&n.proxy):t}}const _r=Symbol.for("v-scx"),yr=()=>ps(_r);function Hs(e,t,s){return Wi(e,t,s)}function Wi(e,t,s=J){const{immediate:n,deep:i,flush:o,once:r}=s,l=he({},s),a=t&&n||!t&&o!=="post";let p;if(Qt){if(o==="sync"){const O=yr();p=O.__watcherHandles||(O.__watcherHandles=[])}else if(!a){const O=()=>{};return O.stop=Ke,O.resume=Ke,O.pause=Ke,O}}const u=ve;l.call=(O,F,_)=>Ie(O,u,F,_);let m=!1;o==="post"?l.scheduler=O=>{_e(O,u&&u.suspense)}:o!=="sync"&&(m=!0,l.scheduler=(O,F)=>{F?O():wn(O)}),l.augmentJob=O=>{t&&(O.flags|=4),m&&(O.flags|=2,u&&(O.id=u.uid,O.i=u))};const P=pr(e,t,l);return Qt&&(p?p.push(P):a&&P()),P}function wr(e,t,s){const n=this.proxy,i=ne(e)?e.includes(".")?Gi(n,e):()=>n[e]:e.bind(n,n);let o;H(t)?o=t:(o=t.handler,s=t);const r=ss(this),l=Wi(i,o.bind(n),s);return r(),l}function Gi(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 _s=new WeakMap;function Vt(e,t,s,n,i=!1){if(M(e)){e.forEach((_,E)=>Vt(_,t&&(M(t)?t[E]:t),s,n,i));return}if(Kt(n)&&!i){n.shapeFlag&512&&n.type.__asyncResolved&&n.component.subTree.component&&Vt(e,t,s,n.component.subTree);return}const o=n.shapeFlag&4?zs(n.component):n.el,r=i?null:o,{i:l,r:a}=e,p=t&&t.r,u=l.refs===J?l.refs={}:l.refs,m=l.setupState,P=W(m),O=m===J?mi:_=>Mn(u,_)?!1:G(P,_),F=(_,E)=>!(E&&Mn(u,E));if(p!=null&&p!==a){if(Ln(t),ne(p))u[p]=null,O(p)&&(m[p]=null);else if(fe(p)){const _=t;F(p,_.k)&&(p.value=null),_.k&&(u[_.k]=null)}}if(H(a)){Ge();try{ts(a,l,12,[r,u])}finally{qe()}}else{const _=ne(a),E=fe(a);if(_||E){const y=()=>{if(e.f){const $=_?O(a)?m[a]:u[a]:F()||!e.k?a.value:u[e.k];if(i)M($)&&un($,o);else if(M($))$.includes(o)||$.push(o);else if(_)u[a]=[o],O(a)&&(m[a]=u[a]);else{const z=[o];F(a,e.k)&&(a.value=z),e.k&&(u[e.k]=z)}}else _?(u[a]=r,O(a)&&(m[a]=r)):E&&(F(a,e.k)&&(a.value=r),e.k&&(u[e.k]=r))};if(r){const $=()=>{y(),_s.delete(e)};$.id=-1,_s.set(e,$),_e($,s)}else Ln(e),y()}}}function Ln(e){const t=_s.get(e);t&&(t.flags|=8,_s.delete(e))}$s().requestIdleCallback;$s().cancelIdleCallback;const Kt=e=>!!e.type.__asyncLoader,Zi=e=>e.type.__isKeepAlive;function Sr(e,t){Yi(e,"a",t)}function Tr(e,t){Yi(e,"da",t)}function Yi(e,t,s=ve){const n=e.__wdc||(e.__wdc=()=>{let i=s;for(;i;){if(i.isDeactivated)return;i=i.parent}return e()});if(Rs(t,n,s),s){let i=s.parent;for(;i&&i.parent;)Zi(i.parent.vnode)&&Er(n,t,s,i),i=i.parent}}function Er(e,t,s,n){const i=Rs(t,e,n,!0);kn(()=>{un(n[t],i)},s)}function Rs(e,t,s=ve,n=!1){if(s){const i=s[e]||(s[e]=[]),o=t.__weh||(t.__weh=(...r)=>{Ge();const l=ss(s),a=Ie(t,s,e,r);return l(),qe(),a});return n?i.unshift(o):i.push(o),o}}const st=e=>(t,s=ve)=>{(!Qt||e==="sp")&&Rs(e,(...n)=>t(...n),s)},Cr=st("bm"),dt=st("m"),Pr=st("bu"),$r=st("u"),Ar=st("bum"),kn=st("um"),Or=st("sp"),Rr=st("rtg"),Ir=st("rtc");function jr(e,t=ve){Rs("ec",e,t)}const zr=Symbol.for("v-ndc");function Se(e,t,s,n){let i;const o=s,r=M(e);if(r||ne(e)){const l=r&&_t(e);let a=!1,p=!1;l&&(a=!Te(e),p=tt(e),e=As(e)),i=new Array(e.length);for(let u=0,m=e.length;ut(l,a,void 0,o));else{const l=Object.keys(e);i=new Array(l.length);for(let a=0,p=l.length;ae?vo(e)?zs(e):tn(e.parent):null,Wt=he(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=>wr.bind(e)}),Ks=(e,t)=>e!==J&&!e.__isScriptSetup&&G(e,t),Ur={get({_:e},t){if(t==="__v_skip")return!0;const{ctx:s,setupState:n,data:i,props:o,accessCache:r,type:l,appContext:a}=e;if(t[0]!=="$"){const P=r[t];if(P!==void 0)switch(P){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!==J&&G(i,t))return r[t]=2,i[t];if(G(o,t))return r[t]=3,o[t];if(s!==J&&G(s,t))return r[t]=4,s[t];sn&&(r[t]=0)}}const p=Wt[t];let u,m;if(p)return t==="$attrs"&&de(e.attrs,"get",""),p(e);if((u=l.__cssModules)&&(u=u[t]))return u;if(s!==J&&G(s,t))return r[t]=4,s[t];if(m=a.config.globalProperties,G(m,t))return m[t]},set({_:e},t,s){const{data:n,setupState:i,ctx:o}=e;return Ks(i,t)?(i[t]=s,!0):n!==J&&G(n,t)?(n[t]=s,!0):G(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}},l){let a;return!!(s[l]||e!==J&&l[0]!=="$"&&G(e,l)||Ks(t,l)||G(o,l)||G(n,l)||G(Wt,l)||G(i.config.globalProperties,l)||(a=r.__cssModules)&&a[l])},defineProperty(e,t,s){return s.get!=null?e._.accessCache[t]=0:G(s,"value")&&this.set(e,t,s.value,null),Reflect.defineProperty(e,t,s)}};function Fn(e){return M(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:l,provide:a,inject:p,created:u,beforeMount:m,mounted:P,beforeUpdate:O,updated:F,activated:_,deactivated:E,beforeDestroy:y,beforeUnmount:$,destroyed:z,unmounted:U,render:oe,renderTracked:je,renderTriggered:ze,errorCaptured:nt,serverPrefetch:ns,expose:ft,inheritAttrs:It,components:is,directives:os,filters:Us}=t;if(p&&Dr(p,n,null),r)for(const te in r){const X=r[te];H(X)&&(n[te]=X.bind(s))}if(i){const te=i.call(s,s);Z(te)&&(e.data=Yt(te))}if(sn=!0,o)for(const te in o){const X=o[te],pt=H(X)?X.bind(s,s):H(X.get)?X.get.bind(s,s):Ke,rs=!H(X)&&H(X.set)?X.set.bind(s):Ke,ht=Ae({get:pt,set:rs});Object.defineProperty(n,te,{enumerable:!0,configurable:!0,get:()=>ht.value,set:Ue=>ht.value=Ue})}if(l)for(const te in l)Ji(l[te],n,s,te);if(a){const te=H(a)?a.call(s):a;Reflect.ownKeys(te).forEach(X=>{vr(X,te[X])})}u&&Bn(u,e,"c");function ge(te,X){M(X)?X.forEach(pt=>te(pt.bind(s))):X&&te(X.bind(s))}if(ge(Cr,m),ge(dt,P),ge(Pr,O),ge($r,F),ge(Sr,_),ge(Tr,E),ge(jr,nt),ge(Ir,je),ge(Rr,ze),ge(Ar,$),ge(kn,U),ge(Or,ns),M(ft))if(ft.length){const te=e.exposed||(e.exposed={});ft.forEach(X=>{Object.defineProperty(te,X,{get:()=>s[X],set:pt=>s[X]=pt,enumerable:!0})})}else e.exposed||(e.exposed={});oe&&e.render===Ke&&(e.render=oe),It!=null&&(e.inheritAttrs=It),is&&(e.components=is),os&&(e.directives=os),ns&&qi(e)}function Dr(e,t,s=Ke){M(e)&&(e=nn(e));for(const n in e){const i=e[n];let o;Z(i)?"default"in i?o=ps(i.from||n,i.default,!0):o=ps(i.from||n):o=ps(i),fe(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){Ie(M(e)?e.map(n=>n.bind(t.proxy)):e.bind(t.proxy),t,s)}function Ji(e,t,s,n){let i=n.includes(".")?Gi(s,n):()=>s[n];if(ne(e)){const o=t[e];H(o)&&Hs(i,o)}else if(H(e))Hs(i,e.bind(s));else if(Z(e))if(M(e))e.forEach(o=>Ji(o,t,s,n));else{const o=H(e.handler)?e.handler.bind(s):t[e.handler];H(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,l=o.get(t);let a;return l?a=l:!i.length&&!s&&!n?a=t:(a={},i.length&&i.forEach(p=>ys(a,p,r,!0)),ys(a,t,r)),Z(t)&&o.set(t,a),a}function ys(e,t,s,n=!1){const{mixins:i,extends:o}=t;o&&ys(e,o,s,!0),i&&i.forEach(r=>ys(e,r,s,!0));for(const r in t)if(!(n&&r==="expose")){const l=Mr[r]||s&&s[r];e[r]=l?l(e[r],t[r]):t[r]}return e}const Mr={data:Hn,props:Vn,emits:Vn,methods:Mt,computed:Mt,beforeCreate:me,created:me,beforeMount:me,mounted:me,beforeUpdate:me,updated:me,beforeDestroy:me,beforeUnmount:me,destroyed:me,unmounted:me,activated:me,deactivated:me,errorCaptured:me,serverPrefetch:me,components:Mt,directives:Mt,watch:Fr,provide:Hn,inject:Lr};function Hn(e,t){return t?e?function(){return he(H(e)?e.call(this,this):e,H(t)?t.call(this,this):t)}:t:e}function Lr(e,t){return Mt(nn(e),nn(t))}function nn(e){if(M(e)){const t={};for(let s=0;st==="modelValue"||t==="model-value"?e.modelModifiers:e[`${t}Modifiers`]||e[`${Pe(t)}Modifiers`]||e[`${ut(t)}Modifiers`];function Kr(e,t,...s){if(e.isUnmounted)return;const n=e.vnode.props||J;let i=s;const o=t.startsWith("update:"),r=o&&Vr(n,t.slice(7));r&&(r.trim&&(i=s.map(u=>ne(u)?u.trim():u)),r.number&&(i=s.map(Ps)));let l,a=n[l=Ds(t)]||n[l=Ds(Pe(t))];!a&&o&&(a=n[l=Ds(ut(t))]),a&&Ie(a,e,6,i);const p=n[l+"Once"];if(p){if(!e.emitted)e.emitted={};else if(e.emitted[l])return;e.emitted[l]=!0,Ie(p,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={},l=!1;if(!H(e)){const a=p=>{const u=eo(p,t,!0);u&&(l=!0,he(r,u))};!s&&t.mixins.length&&t.mixins.forEach(a),e.extends&&a(e.extends),e.mixins&&e.mixins.forEach(a)}return!o&&!l?(Z(e)&&n.set(e,null),null):(M(o)?o.forEach(a=>r[a]=null):he(r,o),Z(e)&&n.set(e,r),r)}function Is(e,t){return!e||!Ts(t)?!1:(t=t.slice(2),t=t==="Once"?t:t.replace(/Once$/,""),G(e,t[0].toLowerCase()+t.slice(1))||G(e,ut(t))||G(e,t))}function Kn(e){const{type:t,vnode:s,proxy:n,withProxy:i,propsOptions:[o],slots:r,attrs:l,emit:a,render:p,renderCache:u,props:m,data:P,setupState:O,ctx:F,inheritAttrs:_}=e,E=vs(e);let y,$;try{if(s.shapeFlag&4){const U=i||n,oe=U;y=He(p.call(oe,U,u,m,O,P,F)),$=l}else{const U=t;y=He(U.length>1?U(m,{attrs:l,slots:r,emit:a}):U(m,null)),$=t.props?l:Gr(l)}}catch(U){Gt.length=0,Os(U,e,1),y=ue(at)}let z=y;if($&&_!==!1){const U=Object.keys($),{shapeFlag:oe}=z;U.length&&oe&7&&(o&&U.some(Es)&&($=qr($,o)),z=Pt(z,$,!1,!0))}return s.dirs&&(z=Pt(z,null,!1,!0),z.dirs=z.dirs?z.dirs.concat(s.dirs):s.dirs),s.transition&&xn(z,s.transition),y=z,vs(E),y}const Gr=e=>{let t;for(const s in e)(s==="class"||s==="style"||Ts(s))&&((t||(t={}))[s]=e[s]);return t},qr=(e,t)=>{const s={};for(const n in e)(!Es(n)||!(n.slice(9)in t))&&(s[n]=e[n]);return s};function Zr(e,t,s){const{props:n,children:i,component:o}=e,{props:r,children:l,patchFlag:a}=t,p=o.emitsOptions;if(t.dirs||t.transition)return!0;if(s&&a>=0){if(a&1024)return!0;if(a&16)return n?Wn(n,r,p):!!r;if(a&8){const u=t.dynamicProps;for(let m=0;mObject.create(so),io=e=>Object.getPrototypeOf(e)===so;function Jr(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:or(i):e.type.props?e.props=i:e.props=o,e.attrs=o}function Xr(e,t,s,n){const{props:i,attrs:o,vnode:{patchFlag:r}}=e,l=W(i),[a]=e.propsOptions;let p=!1;if((n||r>0)&&!(r&16)){if(r&8){const u=e.vnode.dynamicProps;for(let m=0;m{a=!0;const[P,O]=ro(m,t,!0);he(r,P),O&&l.push(...O)};!s&&t.mixins.length&&t.mixins.forEach(u),e.extends&&u(e.extends),e.mixins&&e.mixins.forEach(u)}if(!o&&!a)return Z(e)&&n.set(e,xt),xt;if(M(o))for(let u=0;ue==="_"||e==="_ctx"||e==="$stable",Tn=e=>M(e)?e.map(He):[He(e)],el=(e,t,s)=>{if(t._n)return t;const n=br((...i)=>Tn(t(...i)),s);return n._c=!1,n},lo=(e,t,s)=>{const n=e._ctx;for(const i in e){if(Sn(i))continue;const o=e[i];if(H(o))t[i]=el(i,o,n);else if(o!=null){const r=Tn(o);t[i]=()=>r}}},ao=(e,t)=>{const s=Tn(t);e.slots.default=()=>s},co=(e,t,s)=>{for(const n in t)(s||!Sn(n))&&(e[n]=t[n])},tl=(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)):lo(t,n)}else t&&ao(e,t)},sl=(e,t,s)=>{const{vnode:n,slots:i}=e;let o=!0,r=J;if(n.shapeFlag&32){const l=t._;l?s&&l===1?o=!1:co(i,t,s):(o=!t.$stable,lo(t,i)),r=t}else t&&(ao(e,t),r={default:1});if(o)for(const l in i)!Sn(l)&&r[l]==null&&delete i[l]},_e=ll;function nl(e){return il(e)}function il(e,t){const s=$s();s.__VUE__=!0;const{insert:n,remove:i,patchProp:o,createElement:r,createText:l,createComment:a,setText:p,setElementText:u,parentNode:m,nextSibling:P,setScopeId:O=Ke,insertStaticContent:F}=e,_=(c,f,v,T=null,k=null,w=null,I=void 0,R=null,A=!!f.dynamicChildren)=>{if(c===f)return;c&&!Dt(c,f)&&(T=ls(c),Ue(c,k,w,!0),c=null),f.patchFlag===-2&&(A=!1,f.dynamicChildren=null);const{type:x,ref:D,shapeFlag:j}=f;switch(x){case js:E(c,f,v,T);break;case at:y(c,f,v,T);break;case Gs:c==null&&$(f,v,T,I);break;case ee:is(c,f,v,T,k,w,I,R,A);break;default:j&1?oe(c,f,v,T,k,w,I,R,A):j&6?os(c,f,v,T,k,w,I,R,A):(j&64||j&128)&&x.process(c,f,v,T,k,w,I,R,A,zt)}D!=null&&k?Vt(D,c&&c.ref,w,f||c,!f):D==null&&c&&c.ref!=null&&Vt(c.ref,null,w,c,!0)},E=(c,f,v,T)=>{if(c==null)n(f.el=l(f.children),v,T);else{const k=f.el=c.el;f.children!==c.children&&p(k,f.children)}},y=(c,f,v,T)=>{c==null?n(f.el=a(f.children||""),v,T):f.el=c.el},$=(c,f,v,T)=>{[c.el,c.anchor]=F(c.children,f,v,T,c.el,c.anchor)},z=({el:c,anchor:f},v,T)=>{let k;for(;c&&c!==f;)k=P(c),n(c,v,T),c=k;n(f,v,T)},U=({el:c,anchor:f})=>{let v;for(;c&&c!==f;)v=P(c),i(c),c=v;i(f)},oe=(c,f,v,T,k,w,I,R,A)=>{if(f.type==="svg"?I="svg":f.type==="math"&&(I="mathml"),c==null)je(f,v,T,k,w,I,R,A);else{const x=c.el&&c.el._isVueCE?c.el:null;try{x&&x._beginPatch(),ns(c,f,k,w,I,R,A)}finally{x&&x._endPatch()}}},je=(c,f,v,T,k,w,I,R)=>{let A,x;const{props:D,shapeFlag:j,transition:N,dirs:L}=c;if(A=c.el=r(c.type,w,D&&D.is,D),j&8?u(A,c.children):j&16&&nt(c.children,A,null,T,k,Ws(c,w),I,R),L&>(c,null,T,"created"),ze(A,c,c.scopeId,I,T),D){for(const Y in D)Y!=="value"&&!Ft(Y)&&o(A,Y,null,D[Y],w,T);"value"in D&&o(A,"value",null,D.value,w),(x=D.onVnodeBeforeMount)&&Le(x,T,c)}L&>(c,null,T,"beforeMount");const K=ol(k,N);K&&N.beforeEnter(A),n(A,f,v),((x=D&&D.onVnodeMounted)||K||L)&&_e(()=>{try{x&&Le(x,T,c),K&&N.enter(A),L&>(c,null,T,"mounted")}finally{}},k)},ze=(c,f,v,T,k)=>{if(v&&O(c,v),T)for(let w=0;w{for(let x=A;x{const R=f.el=c.el;let{patchFlag:A,dynamicChildren:x,dirs:D}=f;A|=c.patchFlag&16;const j=c.props||J,N=f.props||J;let L;if(v&&mt(v,!1),(L=N.onVnodeBeforeUpdate)&&Le(L,v,f,c),D&>(f,c,v,"beforeUpdate"),v&&mt(v,!0),x&&(!c.dynamicChildren||c.dynamicChildren.length!==x.length)&&(A=0,I=!1,x=null),(j.innerHTML&&N.innerHTML==null||j.textContent&&N.textContent==null)&&u(R,""),x?ft(c.dynamicChildren,x,R,v,T,Ws(f,k),w):I||X(c,f,R,null,v,T,Ws(f,k),w,!1),A>0){if(A&16)It(R,j,N,v,k);else if(A&2&&j.class!==N.class&&o(R,"class",null,N.class,k),A&4&&o(R,"style",j.style,N.style,k),A&8){const K=f.dynamicProps;for(let Y=0;Y{L&&Le(L,v,f,c),D&>(f,c,v,"updated")},T)},ft=(c,f,v,T,k,w,I)=>{for(let R=0;R{if(f!==v){if(f!==J)for(const w in f)!Ft(w)&&!(w in v)&&o(c,w,f[w],null,k,T);for(const w in v){if(Ft(w))continue;const I=v[w],R=f[w];I!==R&&w!=="value"&&o(c,w,R,I,k,T)}"value"in v&&o(c,"value",f.value,v.value,k)}},is=(c,f,v,T,k,w,I,R,A)=>{const x=f.el=c?c.el:l(""),D=f.anchor=c?c.anchor:l("");let{patchFlag:j,dynamicChildren:N,slotScopeIds:L}=f;L&&(R=R?R.concat(L):L),c==null?(n(x,v,T),n(D,v,T),nt(f.children||[],v,D,k,w,I,R,A)):j>0&&j&64&&N&&c.dynamicChildren&&c.dynamicChildren.length===N.length?(ft(c.dynamicChildren,N,v,k,w,I,R),(f.key!=null||k&&f===k.subTree)&&uo(c,f,!0)):X(c,f,v,D,k,w,I,R,A)},os=(c,f,v,T,k,w,I,R,A)=>{f.slotScopeIds=R,c==null?f.shapeFlag&512?k.ctx.activate(f,v,T,I,A):Us(f,v,T,k,w,I,A):Pn(c,f,A)},Us=(c,f,v,T,k,w,I)=>{const R=c.component=hl(c,T,k);if(Zi(c)&&(R.ctx.renderer=zt),ml(R,!1,I),R.asyncDep){if(k&&k.registerDep(R,ge,I),!c.el){const A=R.subTree=ue(at);y(null,A,f,v),c.placeholder=A.el}}else ge(R,c,f,v,k,w,I)},Pn=(c,f,v)=>{const T=f.component=c.component;if(Zr(c,f,v))if(T.asyncDep&&!T.asyncResolved){te(T,f,v);return}else T.next=f,T.update();else f.el=c.el,T.vnode=f},ge=(c,f,v,T,k,w,I)=>{const R=()=>{if(c.isMounted){let{next:j,bu:N,u:L,parent:K,vnode:Y}=c;{const De=fo(c);if(De){j&&(j.el=Y.el,te(c,j,I)),De.asyncDep.then(()=>{_e(()=>{c.isUnmounted||x()},k)});return}}let q=j,ie;mt(c,!1),j?(j.el=Y.el,te(c,j,I)):j=Y,N&&fs(N),(ie=j.props&&j.props.onVnodeBeforeUpdate)&&Le(ie,K,j,Y),mt(c,!0);const ae=Kn(c),Ne=c.subTree;c.subTree=ae,_(Ne,ae,m(Ne.el),ls(Ne),c,k,w),j.el=ae.el,q===null&&Yr(c,ae.el),L&&_e(L,k),(ie=j.props&&j.props.onVnodeUpdated)&&_e(()=>Le(ie,K,j,Y),k)}else{let j;const{el:N,props:L}=f,{bm:K,m:Y,parent:q,root:ie,type:ae}=c,Ne=Kt(f);mt(c,!1),K&&fs(K),!Ne&&(j=L&&L.onVnodeBeforeMount)&&Le(j,q,f),mt(c,!0);{ie.ce&&ie.ce._hasShadowRoot()&&ie.ce._injectChildStyle(ae,c.parent?c.parent.type:void 0);const De=c.subTree=Kn(c);_(null,De,v,T,c,k,w),f.el=De.el}if(Y&&_e(Y,k),!Ne&&(j=L&&L.onVnodeMounted)){const De=f;_e(()=>Le(j,q,De),k)}(f.shapeFlag&256||q&&Kt(q.vnode)&&q.vnode.shapeFlag&256)&&c.a&&_e(c.a,k),c.isMounted=!0,f=v=T=null}};c.scope.on();const A=c.effect=new Ti(R);c.scope.off();const x=c.update=A.run.bind(A),D=c.job=A.runIfDirty.bind(A);D.i=c,D.id=c.uid,A.scheduler=()=>wn(D),mt(c,!0),x()},te=(c,f,v)=>{f.component=c;const T=c.vnode.props;c.vnode=f,c.next=null,Xr(c,f.props,T,v),sl(c,f.children,v),Ge(),Dn(c),qe()},X=(c,f,v,T,k,w,I,R,A=!1)=>{const x=c&&c.children,D=c?c.shapeFlag:0,j=f.children,{patchFlag:N,shapeFlag:L}=f;if(N>0){if(N&128){rs(x,j,v,T,k,w,I,R,A);return}else if(N&256){pt(x,j,v,T,k,w,I,R,A);return}}L&8?(D&16&&jt(x,k,w),j!==x&&u(v,j)):D&16?L&16?rs(x,j,v,T,k,w,I,R,A):jt(x,k,w,!0):(D&8&&u(v,""),L&16&&nt(j,v,T,k,w,I,R,A))},pt=(c,f,v,T,k,w,I,R,A)=>{c=c||xt,f=f||xt;const x=c.length,D=f.length,j=Math.min(x,D);let N;for(N=0;ND?jt(c,k,w,!0,!1,j):nt(f,v,T,k,w,I,R,A,j)},rs=(c,f,v,T,k,w,I,R,A)=>{let x=0;const D=f.length;let j=c.length-1,N=D-1;for(;x<=j&&x<=N;){const L=c[x],K=f[x]=A?Je(f[x]):He(f[x]);if(Dt(L,K))_(L,K,v,null,k,w,I,R,A);else break;x++}for(;x<=j&&x<=N;){const L=c[j],K=f[N]=A?Je(f[N]):He(f[N]);if(Dt(L,K))_(L,K,v,null,k,w,I,R,A);else break;j--,N--}if(x>j){if(x<=N){const L=N+1,K=LN)for(;x<=j;)Ue(c[x],k,w,!0),x++;else{const L=x,K=x,Y=new Map;for(x=K;x<=N;x++){const ye=f[x]=A?Je(f[x]):He(f[x]);ye.key!=null&&Y.set(ye.key,x)}let q,ie=0;const ae=N-K+1;let Ne=!1,De=0;const Ut=new Array(ae);for(x=0;x=ae){Ue(ye,k,w,!0);continue}let Me;if(ye.key!=null)Me=Y.get(ye.key);else for(q=K;q<=N;q++)if(Ut[q-K]===0&&Dt(ye,f[q])){Me=q;break}Me===void 0?Ue(ye,k,w,!0):(Ut[Me-K]=x+1,Me>=De?De=Me:Ne=!0,_(ye,f[Me],v,null,k,w,I,R,A),ie++)}const On=Ne?rl(Ut):xt;for(q=On.length-1,x=ae-1;x>=0;x--){const ye=K+x,Me=f[ye],Rn=f[ye+1],In=ye+1{const{el:w,type:I,transition:R,children:A,shapeFlag:x}=c;if(x&6){ht(c.component.subTree,f,v,T);return}if(x&128){c.suspense.move(f,v,T);return}if(x&64){I.move(c,f,v,zt);return}if(I===ee){n(w,f,v);for(let j=0;jR.enter(w),k));else{const{leave:j,delayLeave:N,afterLeave:L}=R,K=()=>{c.ctx.isUnmounted?i(w):n(w,f,v)},Y=()=>{const q=w._isLeaving||!!w[Vs];w._isLeaving&&w[Vs](!0),R.persisted&&!q?K():j(w,()=>{K(),L&&L()})};N?N(w,K,Y):Y()}else n(w,f,v)},Ue=(c,f,v,T=!1,k=!1)=>{const{type:w,props:I,ref:R,children:A,dynamicChildren:x,shapeFlag:D,patchFlag:j,dirs:N,cacheIndex:L,memo:K}=c;if(j===-2&&(k=!1),R!=null&&(Ge(),Vt(R,null,v,c,!0),qe()),L!=null&&(f.renderCache[L]=void 0),D&256){f.ctx.deactivate(c);return}const Y=D&1&&N,q=!Kt(c);let ie;if(q&&(ie=I&&I.onVnodeBeforeUnmount)&&Le(ie,f,c),D&6)Po(c.component,v,T);else{if(D&128){c.suspense.unmount(v,T);return}Y&>(c,null,f,"beforeUnmount"),D&64?c.type.remove(c,f,v,zt,T):x&&!x.hasOnce&&(w!==ee||j>0&&j&64)?jt(x,f,v,!1,!0):(w===ee&&j&384||!k&&D&16)&&jt(A,f,v),T&&$n(c)}const ae=K!=null&&L==null;(q&&(ie=I&&I.onVnodeUnmounted)||Y||ae)&&_e(()=>{ie&&Le(ie,f,c),Y&>(c,null,f,"unmounted"),ae&&(c.el=null)},v)},$n=c=>{const{type:f,el:v,anchor:T,transition:k}=c;if(f===ee){Co(v,T);return}if(f===Gs){U(c);return}const w=()=>{i(v),k&&!k.persisted&&k.afterLeave&&k.afterLeave()};if(c.shapeFlag&1&&k&&!k.persisted){const{leave:I,delayLeave:R}=k,A=()=>I(v,w);R?R(c.el,w,A):A()}else w()},Co=(c,f)=>{let v;for(;c!==f;)v=P(c),i(c),c=v;i(f)},Po=(c,f,v)=>{const{bum:T,scope:k,job:w,subTree:I,um:R,m:A,a:x}=c;qn(A),qn(x),T&&fs(T),k.stop(),w&&(w.flags|=8,Ue(I,c,f,v)),R&&_e(R,f),_e(()=>{c.isUnmounted=!0},f)},jt=(c,f,v,T=!1,k=!1,w=0)=>{for(let I=w;I{if(c.shapeFlag&6)return ls(c.component.subTree);if(c.shapeFlag&128)return c.suspense.next();const f=P(c.anchor||c.el),v=f&&f[xr];return v?P(v):f};let Ns=!1;const An=(c,f,v)=>{let T;c==null?f._vnode&&(Ue(f._vnode,null,null,!0),T=f._vnode.component):_(f._vnode||null,c,f,null,null,null,v),f._vnode=c,Ns||(Ns=!0,Dn(T),Hi(),Ns=!1)},zt={p:_,um:Ue,m:ht,r:$n,mt:Us,mc:nt,pc:X,pbc:ft,n:ls,o:e};return{render:An,hydrate:void 0,createApp:Hr(An)}}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 mt({effect:e,job:t},s){s?(e.flags|=32,t.flags|=4):(e.flags&=-33,t.flags&=-5)}function ol(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}function uo(e,t,s=!1){const n=e.children,i=t.children;if(M(n)&&M(i))for(let o=0;o>1,e[s[l]]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 fo(e){const t=e.subTree.component;if(t)return t.asyncDep&&!t.asyncResolved?t:fo(t)}function qn(e){if(e)for(let t=0;te.__isSuspense;function ll(e,t){t&&t.pendingBranch?M(e)?t.effects.push(...e):t.effects.push(e):mr(e)}const ee=Symbol.for("v-fgt"),js=Symbol.for("v-txt"),at=Symbol.for("v-cmt"),Gs=Symbol.for("v-stc"),Gt=[];let we=null;function S(e=!1){Gt.push(we=e?null:[])}function al(){Gt.pop(),we=Gt[Gt.length-1]||null}let Xt=1;function Zn(e,t=!1){Xt+=e,e<0&&we&&t&&(we.hasOnce=!0)}function go(e){return e.dynamicChildren=Xt>0?we||xt:null,al(),Xt>0&&we&&we.push(e),e}function C(e,t,s,n,i,o){return go(d(e,t,s,n,i,o,!0))}function ot(e,t,s,n,i){return go(ue(e,t,s,n,i,!0))}function mo(e){return e?e.__v_isVNode===!0:!1}function Dt(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?ne(e)||fe(e)||H(e)?{i:ke,r:e,k:t,f:!!s}:e:null);function d(e,t=null,s=null,n=0,i=null,o=e===ee?0:1,r=!1,l=!1){const a={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&bo(t),ref:t&&hs(t),scopeId:Ki,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:ke};return l?(ws(a,s),o&128&&e.normalize(a)):s&&(a.shapeFlag|=ne(s)?8:16),Xt>0&&!r&&we&&(a.patchFlag>0||o&6)&&a.patchFlag!==32&&we.push(a),a}const ue=cl;function cl(e,t=null,s=null,n=0,i=null,o=!1){if((!e||e===zr)&&(e=at),mo(e)){const l=Pt(e,t,!0);return s&&ws(l,s),Xt>0&&!o&&we&&(l.shapeFlag&6?we[we.indexOf(e)]=l:we.push(l)),l.patchFlag=-2,l}if(yl(e)&&(e=e.__vccOpts),t){t=ul(t);let{class:l,style:a}=t;l&&!ne(l)&&(t.class=Oe(l)),Z(a)&&(yn(a)&&!M(a)&&(a=he({},a)),t.style=fn(a))}const r=ne(e)?1:ho(e)?128:kr(e)?64:Z(e)?4:H(e)?2:0;return d(e,t,s,n,i,r,o,!0)}function ul(e){return e?yn(e)||io(e)?he({},e):e:null}function Pt(e,t,s=!1,n=!1){const{props:i,ref:o,patchFlag:r,children:l,transition:a}=e,p=t?dl(i||{},t):i,u={__v_isVNode:!0,__v_skip:!0,type:e.type,props:p,key:p&&bo(p),ref:t&&t.ref?s&&o?M(o)?o.concat(hs(t)):[o,hs(t)]:hs(t):o,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:l,target:e.target,targetStart:e.targetStart,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==ee?r===-1?16:r|16:r,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:a,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&Pt(e.ssContent),ssFallback:e.ssFallback&&Pt(e.ssFallback),placeholder:e.placeholder,el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce};return a&&n&&xn(u,a.clone(u)),u}function Ee(e=" ",t=0){return ue(js,null,e,t)}function B(e="",t=!1){return t?(S(),ot(at,null,e)):ue(at,null,e)}function He(e){return e==null||typeof e=="boolean"?ue(at):M(e)?ue(ee,null,e.slice()):mo(e)?Je(e):ue(js,null,String(e))}function Je(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:Pt(e)}function ws(e,t){let s=0;const{shapeFlag:n}=e;if(t==null)t=null;else if(M(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=ke:i===3&&ke&&(ke.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else if(H(t)){if(n&65){ws(e,{default:t});return}t={default:t,_ctx:ke},s=32}else t=String(t),n&64?(s=16,t=[Ee(t)]):s=8;e.children=t,e.shapeFlag|=s}function dl(...e){const t={};for(let s=0;sve||ke;let xs,rn;{const e=$s(),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=>ve=s),rn=t("__VUE_SSR_SETTERS__",s=>Qt=s)}const ss=e=>{const t=ve;return xs(e),e.scope.on(),()=>{e.scope.off(),xs(t)}},Yn=()=>{ve&&ve.scope.off(),xs(null)};function vo(e){return e.vnode.shapeFlag&4}let Qt=!1;function ml(e,t=!1,s=!1){t&&rn(t);const{props:n,children:i}=e.vnode,o=vo(e);Jr(e,n,o,t),tl(e,i,s||t);const r=o?bl(e,t):void 0;return t&&rn(!1),r}function bl(e,t){const s=e.type;e.accessCache=Object.create(null),e.proxy=new Proxy(e.ctx,Ur);const{setup:n}=s;if(n){Ge();const i=e.setupContext=n.length>1?_l(e):null,o=ss(e),r=ts(n,e,0,[e.props,i]),l=bi(r);if(qe(),o(),(l||e.sp)&&!Kt(e)&&qi(e),l){if(r.then(Yn,Yn),t)return r.then(a=>{Jn(e,a)}).catch(a=>{Os(a,e,0)});e.asyncDep=r}else Jn(e,r)}else _o(e)}function Jn(e,t,s){H(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:Z(t)&&(e.setupState=Mi(t)),_o(e)}function _o(e,t,s){const n=e.type;e.render||(e.render=n.render||Ke);{const i=ss(e);Ge();try{Nr(e)}finally{qe(),i()}}}const vl={get(e,t){return de(e,"get",""),e[t]}};function _l(e){const t=s=>{e.exposed=s||{}};return{attrs:new Proxy(e.attrs,vl),slots:e.slots,emit:e.emit,expose:t}}function zs(e){return e.exposed?e.exposeProxy||(e.exposeProxy=new Proxy(Mi(rr(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 yl(e){return H(e)&&"__vccOpts"in e}const Ae=(e,t)=>dr(e,t,Qt),wl="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 yo=ln?e=>ln.createHTML(e):e=>e,xl="http://www.w3.org/2000/svg",kl="http://www.w3.org/1998/Math/MathML",Ye=typeof document<"u"?document:null,Qn=Ye&&Ye.createElement("template"),Sl={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"?Ye.createElementNS(xl,e):t==="mathml"?Ye.createElementNS(kl,e):s?Ye.createElement(e,{is:s}):Ye.createElement(e);return e==="select"&&n&&n.multiple!=null&&i.setAttribute("multiple",n.multiple),i},createText:e=>Ye.createTextNode(e),createComment:e=>Ye.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>Ye.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=yo(n==="svg"?`${e}`:n==="mathml"?`${e}`:e);const l=Qn.content;if(n==="svg"||n==="mathml"){const a=l.firstChild;for(;a.firstChild;)l.appendChild(a.firstChild);l.removeChild(a)}t.insertBefore(l,s)}return[r?r.nextSibling:t.firstChild,s?s.previousSibling:t.lastChild]}},Tl=Symbol("_vtc");function El(e,t,s){const n=e[Tl];n&&(t=(t?[t,...n]:[...n]).join(" ")),t==null?e.removeAttribute("class"):s?e.setAttribute("class",t):e.className=t}const ei=Symbol("_vod"),Cl=Symbol("_vsh"),Pl=Symbol(""),$l=/(?:^|;)\s*display\s*:/;function Al(e,t,s){const n=e.style,i=ne(s);let o=!1;if(s&&!i){if(t)if(ne(t))for(const r of t.split(";")){const l=r.slice(0,r.indexOf(":")).trim();s[l]==null&&Lt(n,l,"")}else for(const r in t)s[r]==null&&Lt(n,r,"");for(const r in s){r==="display"&&(o=!0);const l=s[r];l!=null?Rl(e,r,!ne(t)&&t?t[r]:void 0,l)||Lt(n,r,l):Lt(n,r,"")}}else if(i){if(t!==s){const r=n[Pl];r&&(s+=";"+r),n.cssText=s,o=$l.test(s)}}else t&&e.removeAttribute("style");ei in e&&(e[ei]=o?n.display:"",e[Cl]&&(n.display="none"))}const ti=/\s*!important$/;function Lt(e,t,s){if(M(s))s.forEach(n=>Lt(e,t,n));else if(s==null&&(s=""),t.startsWith("--"))e.setProperty(t,s);else{const n=Ol(e,t);ti.test(s)?e.setProperty(ut(n),s.replace(ti,""),"important"):e[n]=s}}const si=["Webkit","Moz","ms"],qs={};function Ol(e,t){const s=qs[t];if(s)return s;let n=Pe(t);if(n!=="filter"&&n in e)return qs[t]=n;n=yi(n);for(let i=0;iZs||(Dl.then(()=>Zs=0),Zs=Date.now());function Ll(e,t){const s=n=>{if(!n._vts)n._vts=Date.now();else if(n._vts<=s.attached)return;const i=s.value;if(M(i)){const o=n.stopImmediatePropagation;n.stopImmediatePropagation=()=>{o.call(n),n._stopped=!0};const r=i.slice(),l=[n];for(let a=0;ae.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,Fl=(e,t,s,n,i,o)=>{const r=i==="svg";t==="class"?El(e,n,r):t==="style"?Al(e,s,n):Ts(t)?Es(t)||jl(e,t,s,n,o):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):Bl(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&&(Hl(e,t)||e._def.__asyncLoader&&(/[A-Z]/.test(t)||!ne(n)))?oi(e,Pe(t),n,o,t):(t==="true-value"?e._trueValue=n:t==="false-value"&&(e._falseValue=n),ii(e,t,n,r))};function Bl(e,t,s,n){if(n)return!!(t==="innerHTML"||t==="textContent"||t in e&&li(t)&&H(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 li(t)&&ne(s)?!1:t in e}function Hl(e,t){const s=e._def.props;if(!s)return!1;const n=Pe(t);return Array.isArray(s)?s.some(i=>Pe(i)===n):Object.keys(s).some(i=>Pe(i)===n)}const ct=e=>{const t=e.props["onUpdate:modelValue"]||!1;return M(t)?s=>fs(t,s):t};function Vl(e){e.target.composing=!0}function ai(e){const t=e.target;t.composing&&(t.composing=!1,t.dispatchEvent(new Event("input")))}const Ce=Symbol("_assign");function ci(e,t,s){return t&&(e=e.trim()),s&&(e=Ps(e)),e}const pe={created(e,{modifiers:{lazy:t,trim:s,number:n}},i){e[Ce]=ct(i);const o=n||i.props&&i.props.type==="number";et(e,t?"change":"input",r=>{r.target.composing||e[Ce](ci(e.value,s,o))}),(s||o)&&et(e,"change",()=>{e.value=ci(e.value,s,o)}),t||(et(e,"compositionstart",Vl),et(e,"compositionend",ai),et(e,"change",ai))},mounted(e,{value:t}){e.value=t??""},beforeUpdate(e,{value:t,oldValue:s,modifiers:{lazy:n,trim:i,number:o}},r){if(e[Ce]=ct(r),e.composing)return;const l=(o||e.type==="number")&&!/^0\d/.test(e.value)?Ps(e.value):e.value,a=t??"";if(l===a)return;const p=e.getRootNode();(p instanceof Document||p instanceof ShadowRoot)&&p.activeElement===e&&e.type!=="range"&&(n&&t===s||i&&e.value.trim()===a)||(e.value=a)}},Kl={deep:!0,created(e,t,s){e[Ce]=ct(s),et(e,"change",()=>{const n=e._modelValue,i=$t(e),o=e.checked,r=e[Ce];if(M(n)){const l=pn(n,i),a=l!==-1;if(o&&!a)r(n.concat(i));else if(!o&&a){const p=[...n];p.splice(l,1),r(p)}}else if(Rt(n)){const l=new Set(n);o?l.add(i):l.delete(i),r(l)}else r(wo(e,o))})},mounted:ui,beforeUpdate(e,t,s){e[Ce]=ct(s),ui(e,t,s)}};function ui(e,{value:t,oldValue:s},n){e._modelValue=t;let i;if(M(t))i=pn(t,n.props.value)>-1;else if(Rt(t))i=t.has(n.props.value);else{if(t===s)return;i=lt(t,wo(e,!0))}e.checked!==i&&(e.checked=i)}const Wl={created(e,{value:t},s){e.checked=lt(t,s.props.value),e[Ce]=ct(s),et(e,"change",()=>{e[Ce]($t(e))})},beforeUpdate(e,{value:t,oldValue:s},n){e[Ce]=ct(n),t!==s&&(e.checked=lt(t,n.props.value))}},ks={deep:!0,created(e,{value:t,modifiers:{number:s}},n){const i=Rt(t);et(e,"change",()=>{const o=Array.prototype.filter.call(e.options,r=>r.selected).map(r=>s?Ps($t(r)):$t(r));e[Ce](e.multiple?i?new Set(o):o:o[0]),e._assigning=!0,Fi(()=>{e._assigning=!1})}),e[Ce]=ct(n)},mounted(e,{value:t}){di(e,t)},beforeUpdate(e,t,s){e[Ce]=ct(s)},updated(e,{value:t}){e._assigning||di(e,t)}};function di(e,t){const s=e.multiple,n=M(t);if(!(s&&!n&&!Rt(t))){for(let i=0,o=e.options.length;iString(p)===String(l)):r.selected=pn(t,l)>-1}else r.selected=t.has(l);else if(lt($t(r),t)){e.selectedIndex!==i&&(e.selectedIndex=i);return}}!s&&e.selectedIndex!==-1&&(e.selectedIndex=-1)}}function $t(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 Gl={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 ql(e,t){switch(e){case"SELECT":return ks;case"TEXTAREA":return pe;default:switch(t){case"checkbox":return Kl;case"radio":return Wl;default:return pe}}}function ds(e,t,s,n,i){const r=ql(e.tagName,s.props&&s.props.type)[i];r&&r(e,t,s,n)}const Zl=["ctrl","shift","alt","meta"],Yl={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)=>Zl.some(s=>e[`${s}Key`]&&!t.includes(s))},Jl=(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=ut(i.key);if(t.some(r=>r===o||Xl[r]===o))return e(i)}))},ea=he({patchProp:Fl},Sl);let fi;function ta(){return fi||(fi=nl(ea))}const sa=((...e)=>{const t=ta().createApp(...e),{mount:s}=t;return t.mount=n=>{const i=ia(n);if(!i)return;const o=t._component;!H(o)&&!o.render&&!o.template&&(o.template=i.innerHTML),i.nodeType===1&&(i.textContent="");const r=s(i,!1,na(i));return i instanceof Element&&(i.removeAttribute("v-cloak"),i.setAttribute("data-v-app","")),r},t});function na(e){if(e instanceof SVGElement)return"svg";if(typeof MathMLElement=="function"&&e instanceof MathMLElement)return"mathml"}function ia(e){return ne(e)?document.querySelector(e):e}const xo="dh-panel-theme";function oa(){var e;try{const t=localStorage.getItem(xo);if(t==="dark"||t==="light")return t}catch{}return(e=window.matchMedia)!=null&&e.call(window,"(prefers-color-scheme: dark)").matches?"dark":"light"}const Et=V(oa());function ko(e){Et.value=e,document.documentElement.classList.toggle("dark",e==="dark");try{localStorage.setItem(xo,e)}catch{}}function pi(){ko(Et.value==="dark"?"light":"dark")}ko(Et.value);const ra={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."},la={overview:"Overview",users:"Users",orgs:"Organizations",pocketbase:"PocketBase",webapp:"Web App",plugins:"Plugins",api:"API"},aa={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"},ca={title:"Status",unreachable:"unreachable",checking:"Checking…",apiServer:"API Server",pocketBase:"PocketBase",webApp:"Web App",thisProcess:"this process"},ua={create:"Create",save:"Save",cancel:"Cancel",edit:"Edit",delete:"Delete",rename:"Rename",empty:"—",name:"Name",email:"Email",role:"Role",organization:"Organization"},da={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."},fa={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.'},pa={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."},ha={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."},ga={title:"Plugins",subtitle:"Third-party service integrations",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.'},ma={colEndpoint:"Endpoint",colDescription:"Description",authNone:"No auth",authBearer:"Bearer token",authManager:"Admin / superadmin",authSuperadmin:"Superadmin",groupPublic:"Public",groupIdentity:"Identity",groupCars:"Cars",groupService:"Service records",groupParts:"Parts",groupAccount:"Account",groupManagement:"Management",groupSuperadmin:"Superadmin"},ba={app:ra,sections:la,login:aa,status:ca,common:ua,users:da,orgs:fa,pocketbase:pa,webapp:ha,plugins:ga,api:ma},va={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."},_a={overview:"Przegląd",users:"Użytkownicy",orgs:"Organizacje",pocketbase:"PocketBase",webapp:"Aplikacja webowa",plugins:"Wtyczki",api:"API"},ya={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"},wa={title:"Status",unreachable:"niedostępny",checking:"Sprawdzanie…",apiServer:"Serwer API",pocketBase:"PocketBase",webApp:"Aplikacja webowa",thisProcess:"ten proces"},xa={create:"Utwórz",save:"Zapisz",cancel:"Anuluj",edit:"Edytuj",delete:"Usuń",rename:"Zmień nazwę",empty:"—",name:"Nazwa",email:"E-mail",role:"Rola",organization:"Organizacja"},ka={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ąć."},Sa={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."},Ta={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."},Ea={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."},Ca={title:"Wtyczki",subtitle:"Integracje z usługami zewnętrznymi",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."},Pa={colEndpoint:"Punkt końcowy",colDescription:"Opis",authNone:"Bez uwierzytelniania",authBearer:"Token Bearer",authManager:"Administrator / superadministrator",authSuperadmin:"Superadministrator",groupPublic:"Publiczne",groupIdentity:"Tożsamość",groupCars:"Samochody",groupService:"Wpisy serwisowe",groupParts:"Części",groupAccount:"Konto",groupManagement:"Zarządzanie",groupSuperadmin:"Superadministrator"},$a={app:va,sections:_a,login:ya,status:wa,common:xa,users:ka,orgs:Sa,pocketbase:Ta,webapp:Ea,plugins:Ca,api:Pa},Aa={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."},Oa={overview:"Oversigt",users:"Brugere",orgs:"Organisationer",pocketbase:"PocketBase",webapp:"Webapp",plugins:"Plugins",api:"API"},Ra={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"},Ia={title:"Status",unreachable:"utilgængelig",checking:"Tjekker…",apiServer:"API-server",pocketBase:"PocketBase",webApp:"Webapp",thisProcess:"denne proces"},ja={create:"Opret",save:"Gem",cancel:"Annuller",edit:"Rediger",delete:"Slet",rename:"Omdøb",empty:"—",name:"Navn",email:"E-mail",role:"Rolle",organization:"Organisation"},za={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."},Ua={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."},Na={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."},Da={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."},Ma={title:"Plugins",subtitle:"Integrationer med tredjepartstjenester",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.'},La={colEndpoint:"Endpoint",colDescription:"Beskrivelse",authNone:"Ingen godkendelse",authBearer:"Bearer-token",authManager:"Admin / superadmin",authSuperadmin:"Superadmin",groupPublic:"Offentlig",groupIdentity:"Identitet",groupCars:"Biler",groupService:"Serviceposter",groupParts:"Reservedele",groupAccount:"Konto",groupManagement:"Administration",groupSuperadmin:"Superadmin"},Fa={app:Aa,sections:Oa,login:Ra,status:Ia,common:ja,users:za,orgs:Ua,pocketbase:Na,webapp:Da,plugins:Ma,api:La},So="dh-panel-lang",To="en",At={en:ba,pl:$a,da:Fa},Ba=Object.keys(At);function Ha(){try{const t=localStorage.getItem(So);if(t&&At[t])return t}catch{}const e=(navigator.language||"en").split("-")[0];return At[e]?e:To}const En=V(Ha());function Va(e){if(At[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 Ka(e,t){return t?e.replace(/\{(\w+)\}/g,(s,n)=>t[n]==null?s:String(t[n])):e}function Wa(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 h(e,t){const s=En.value;let n=hi(At[s],e);if(n==null&&(n=hi(At[To],e)),n==null)return e;if(typeof n=="object"){if((t==null?void 0:t.n)==null)return e;n=Wa(n,t.n,s)}return typeof n!="string"?e:Ka(n,t)}function gi(e,t,s){const i=h(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 an="dh-panel-token";function Ga(){try{return localStorage.getItem(an)||""}catch{return""}}const Ot=V(Ga()),re=V(null),xe=Ae(()=>{var e;return((e=re.value)==null?void 0:e.role)==="superadmin"}),gs=Ae(()=>{var e,t;return((e=re.value)==null?void 0:e.role)==="admin"||((t=re.value)==null?void 0:t.role)==="superadmin"});function Eo(e){Ot.value=e;try{e?localStorage.setItem(an,e):localStorage.removeItem(an)}catch{}}class qa extends Error{constructor(t,s,n){super(t),this.status=s,this.body=n}}function Za(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 se(e,{method:t="GET",body:s,auth:n=!0}={}){const i={};s!==void 0&&(i["Content-Type"]="application/json"),n&&Ot.value&&(i.Authorization=Ot.value);const o=await fetch(e,{method:t,headers:i,body:s===void 0?void 0:JSON.stringify(s)}),r=await o.text();let l=null;try{l=r?JSON.parse(r):null}catch{l=null}if(!o.ok)throw o.status===401&&n&&Cn(),new qa(Za(l,o.status),o.status,l);return l}async function Ya(e,t){const s=await se("/api/auth/login",{method:"POST",body:{email:e,password:t},auth:!1});return Eo(s.token),await Ss(),re.value}async function Ss(){return re.value=await se("/api/identity"),re.value}function Cn(){Eo(""),re.value=null}async function Ja(){if(!Ot.value)return null;try{return await Ss()}catch{return Cn(),null}}const Xa={class:"mx-auto flex w-full max-w-sm flex-col gap-5 pt-24"},Qa={class:"dh-card p-6"},ec={class:"text-lg font-bold tracking-[-0.02em] text-strong"},tc={class:"mt-1 mb-5 text-sm text-body"},sc={class:"dh-label",for:"login-email"},nc={class:"dh-label",for:"login-password"},ic={key:0,class:"rounded-control bg-danger-soft px-3 py-2 text-xs text-danger"},oc=["disabled"],rc={class:"eyebrow text-center"},lc={__name:"LoginView",emits:["authenticated"],setup(e,{emit:t}){const s=t,n=V(""),i=V(""),o=V(""),r=V(!1),l=Ae(()=>n.value.trim()!==""&&i.value!==""&&!r.value);async function a(){if(l.value){o.value="",r.value=!0;try{const p=await Ya(n.value.trim(),i.value);s("authenticated",p)}catch(p){o.value=p.status===400||p.status===404?h("login.invalid"):p.message||h("login.failed"),i.value=""}finally{r.value=!1}}}return(p,u)=>(S(),C("div",Xa,[d("div",Qa,[d("h1",ec,b(g(h)("login.title")),1),d("p",tc,b(g(h)("login.subtitle")),1),d("form",{class:"flex flex-col gap-4",onSubmit:Jl(a,["prevent"])},[d("div",null,[d("label",sc,b(g(h)("login.email")),1),le(d("input",{id:"login-email","onUpdate:modelValue":u[0]||(u[0]=m=>n.value=m),class:"dh-input",type:"email",autocomplete:"username",autofocus:"",placeholder:"you@example.com"},null,512),[[pe,n.value]])]),d("div",null,[d("label",nc,b(g(h)("login.password")),1),le(d("input",{id:"login-password","onUpdate:modelValue":u[1]||(u[1]=m=>i.value=m),class:"dh-input",type:"password",autocomplete:"current-password",placeholder:"••••••••"},null,512),[[pe,i.value]])]),o.value?(S(),C("p",ic,b(o.value),1)):B("",!0),d("button",{class:"dh-btn w-full",type:"submit",disabled:!l.value},b(r.value?g(h)("login.submitting"):g(h)("login.submit")),9,oc)],32)]),d("p",rc,b(g(h)("login.authNote")),1)]))}},ac={class:"dh-card overflow-hidden"},cc={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},uc={class:"text-base font-bold tracking-[-0.02em] text-strong"},dc={key:0,class:"dh-pill bg-danger-soft text-danger"},fc={key:0,class:"px-5 py-4 text-sm text-danger"},pc={key:1,class:"w-full text-left text-sm"},hc={class:"px-5 py-3 font-medium text-strong"},gc={class:"data px-5 py-3 text-xs text-muted"},mc={class:"data px-5 py-3 text-right text-xs text-muted"},bc={class:"px-5 py-3 text-right"},vc={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 se("/api/status",{auth:!1}),s.value=""}catch(l){t.value=null,s.value=l.message||h("status.unreachable")}}const o=Ae(()=>{var l,a,p;return[{key:"apiServer",label:h("status.apiServer"),h:(l=t.value)==null?void 0:l.apiServer},{key:"pocketBase",label:h("status.pocketBase"),h:(a=t.value)==null?void 0:a.pocketBase},{key:"webApp",label:h("status.webApp"),h:(p=t.value)==null?void 0:p.webApp}]});dt(()=>{i(),n=setInterval(i,1e4)}),kn(()=>clearInterval(n));const r=l=>l==="ok"?"bg-success-soft text-success":"bg-danger-soft text-danger";return(l,a)=>(S(),C("div",ac,[d("div",cc,[d("div",uc,b(g(h)("status.title")),1),s.value?(S(),C("span",dc,[a[0]||(a[0]=d("span",{class:"h-1.5 w-1.5 rounded-full bg-current"},null,-1)),Ee(b(g(h)("status.unreachable")),1)])):B("",!0)]),s.value?(S(),C("div",fc,b(s.value),1)):t.value?(S(),C("table",pc,[d("tbody",null,[(S(!0),C(ee,null,Se(o.value,p=>(S(),C("tr",{key:p.key,class:"border-t border-subtle first:border-t-0"},[d("td",hc,b(p.label),1),d("td",gc,b(p.h.url||g(h)("status.thisProcess")),1),d("td",mc,b(p.h.latencyMs!=null?p.h.latencyMs+"ms":g(h)("common.empty")),1),d("td",bc,[d("span",{class:Oe(["dh-pill",r(p.h.status)])},[a[1]||(a[1]=d("span",{class:"h-1.5 w-1.5 rounded-full bg-current"},null,-1)),Ee(b(p.h.status),1)],2)])]))),128))])])):(S(),C("div",vc,b(g(h)("status.checking")),1))]))}},yc={class:"dh-card overflow-hidden"},wc={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},xc={class:"text-base font-bold tracking-[-0.02em] text-strong"},kc={class:"mt-0.5 text-xs text-muted"},Sc={class:"flex flex-col gap-4 px-5 py-4"},Tc={class:"dh-label",for:"pb-url"},Ec={class:"grid gap-4 sm:grid-cols-2"},Cc={class:"dh-label",for:"pb-email"},Pc={class:"dh-label",for:"pb-password"},$c=["placeholder"],Ac={key:0,class:"data text-xs text-muted"},Oc={key:1,class:"rounded-control bg-info-soft px-3 py-2 text-xs text-info"},Rc={key:2,class:"rounded-control bg-danger-soft px-3 py-2 text-xs text-danger"},Ic={class:"flex items-center gap-2"},jc=["disabled"],zc=["disabled"],Uc={class:"eyebrow"},Nc={__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 l(){try{t.value=await se("/api/admin/pb-config"),s.value={url:t.value.url,adminEmail:t.value.adminEmail,adminPassword:""},n.value=t.value.probe}catch(u){i.value=u.message}}dt(l);async function a(){i.value="",o.value="",r.value=!0;try{n.value=await se("/api/admin/pb-config/test",{method:"POST",body:s.value}),o.value=n.value.superuser?h("pocketbase.testOk"):n.value.reachable?h("pocketbase.testReachableNoAuth"):h("pocketbase.testUnreachable")}catch(u){i.value=u.message}finally{r.value=!1}}async function p(){i.value="",o.value="",r.value=!0;try{const u=await se("/api/admin/pb-config",{method:"PUT",body:s.value});t.value=u.config,n.value=u.config.probe,s.value.adminPassword="",o.value=u.warning||h("pocketbase.savedNotice")}catch(u){i.value=u.message}finally{r.value=!1}}return(u,m)=>{var P,O;return S(),C("div",yc,[d("div",wc,[d("div",null,[d("div",xc,b(g(h)("pocketbase.title")),1),d("p",kc,b(g(h)("pocketbase.subtitle")),1)]),n.value?(S(),C("span",{key:0,class:Oe(["dh-pill",n.value.superuser?"bg-success-soft text-success":n.value.reachable?"bg-warning-soft text-warning":"bg-danger-soft text-danger"])},[m[3]||(m[3]=d("span",{class:"h-1.5 w-1.5 rounded-full bg-current"},null,-1)),Ee(" "+b(n.value.superuser?g(h)("pocketbase.connected"):n.value.reachable?g(h)("pocketbase.noSuperuser"):g(h)("pocketbase.unreachable")),1)],2)):B("",!0)]),d("div",Sc,[d("div",null,[d("label",Tc,b(g(h)("pocketbase.baseUrl")),1),le(d("input",{id:"pb-url","onUpdate:modelValue":m[0]||(m[0]=F=>s.value.url=F),class:"dh-input",placeholder:"http://10.2.1.10:8027"},null,512),[[pe,s.value.url]])]),d("div",Ec,[d("div",null,[d("label",Cc,b(g(h)("pocketbase.superuserEmail")),1),le(d("input",{id:"pb-email","onUpdate:modelValue":m[1]||(m[1]=F=>s.value.adminEmail=F),class:"dh-input",autocomplete:"off"},null,512),[[pe,s.value.adminEmail]])]),d("div",null,[d("label",Pc,b(g(h)("pocketbase.superuserPassword")),1),le(d("input",{id:"pb-password","onUpdate:modelValue":m[2]||(m[2]=F=>s.value.adminPassword=F),class:"dh-input",type:"password",autocomplete:"new-password",placeholder:(P=t.value)!=null&&P.adminConfigured?g(h)("pocketbase.passwordUnchanged"):g(h)("pocketbase.passwordNotSet")},null,8,$c),[[pe,s.value.adminPassword]])])]),(O=n.value)!=null&&O.detail?(S(),C("p",Ac,b(n.value.detail),1)):B("",!0),o.value?(S(),C("p",Oc,b(o.value),1)):B("",!0),i.value?(S(),C("p",Rc,b(i.value),1)):B("",!0),d("div",Ic,[d("button",{class:"dh-btn",disabled:r.value,onClick:p},b(g(h)("pocketbase.saveApply")),9,jc),d("button",{class:"dh-btn-ghost",disabled:r.value,onClick:a},b(g(h)("pocketbase.testConnection")),9,zc),m[4]||(m[4]=d("span",{class:"flex-1"},null,-1)),d("span",Uc,b(g(h)("pocketbase.persistedEnv")),1)])])])}}},Dc={class:"dh-card overflow-hidden"},Mc={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},Lc={class:"text-base font-bold tracking-[-0.02em] text-strong"},Fc={class:"mt-0.5 text-xs text-muted"},Bc={class:"flex flex-col gap-4 px-5 py-4"},Hc={class:"dh-label",for:"web-url"},Vc={class:"dh-label",for:"web-origins"},Kc={class:"mt-1 text-xs text-muted"},Wc={key:0,class:"data text-xs text-muted"},Gc={key:1,class:"rounded-control bg-info-soft px-3 py-2 text-xs text-info"},qc={key:2,class:"rounded-control bg-danger-soft px-3 py-2 text-xs text-danger"},Zc={class:"flex items-center gap-2"},Yc=["disabled"],Jc=["disabled"],Xc={class:"eyebrow"},Qc={__name:"WebAppCard",setup(e){const t=V(null),s=V({url:"",origins:""}),n=V(null),i=V(""),o=V(""),r=V(!1),l=P=>P.split(",").map(O=>O.trim()).filter(Boolean);function a(P){t.value=P,s.value={url:P.url,origins:(P.allowOrigins||[]).join(", ")},n.value=P.probe}async function p(){try{a(await se("/api/admin/webapp-config"))}catch(P){i.value=P.message}}dt(p);async function u(){i.value="",o.value="",r.value=!0;try{n.value=await se("/api/admin/webapp-config/test",{method:"POST",body:{url:s.value.url}}),o.value=n.value.status==="ok"?h("webapp.testOk"):h("webapp.testFailed")}catch(P){i.value=P.message}finally{r.value=!1}}async function m(){i.value="",o.value="",r.value=!0;try{const P=await se("/api/admin/webapp-config",{method:"PUT",body:{url:s.value.url,allowOrigins:l(s.value.origins)}});a(P.config),o.value=P.warning||h("webapp.savedNotice")}catch(P){i.value=P.message}finally{r.value=!1}}return(P,O)=>{var F;return S(),C("div",Dc,[d("div",Mc,[d("div",null,[d("div",Lc,b(g(h)("webapp.title")),1),d("p",Fc,b(g(h)("webapp.subtitle")),1)]),n.value?(S(),C("span",{key:0,class:Oe(["dh-pill",n.value.status==="ok"?"bg-success-soft text-success":"bg-danger-soft text-danger"])},[O[2]||(O[2]=d("span",{class:"h-1.5 w-1.5 rounded-full bg-current"},null,-1)),Ee(" "+b(n.value.status==="ok"?g(h)("webapp.reachable"):g(h)("webapp.unreachable")),1)],2)):B("",!0)]),d("div",Bc,[d("div",null,[d("label",Hc,b(g(h)("webapp.baseUrl")),1),le(d("input",{id:"web-url","onUpdate:modelValue":O[0]||(O[0]=_=>s.value.url=_),class:"dh-input",placeholder:"http://localhost:8090"},null,512),[[pe,s.value.url]])]),d("div",null,[d("label",Vc,b(g(h)("webapp.allowedOrigins")),1),le(d("input",{id:"web-origins","onUpdate:modelValue":O[1]||(O[1]=_=>s.value.origins=_),class:"dh-input",placeholder:"http://localhost:8090, https://app.example.com"},null,512),[[pe,s.value.origins]]),d("p",Kc,[Ee(b(g(gi)("webapp.originsHint","star").before),1),O[3]||(O[3]=d("span",{class:"data"},"*",-1)),Ee(b(g(gi)("webapp.originsHint","star").after),1)])]),(F=n.value)!=null&&F.error?(S(),C("p",Wc,b(n.value.error),1)):B("",!0),o.value?(S(),C("p",Gc,b(o.value),1)):B("",!0),i.value?(S(),C("p",qc,b(i.value),1)):B("",!0),d("div",Zc,[d("button",{class:"dh-btn",disabled:r.value,onClick:m},b(g(h)("webapp.saveApply")),9,Yc),d("button",{class:"dh-btn-ghost",disabled:r.value,onClick:u},b(g(h)("webapp.testConnection")),9,Jc),O[4]||(O[4]=d("span",{class:"flex-1"},null,-1)),d("span",Xc,b(g(h)("webapp.persistedEnv")),1)])])])}}},eu={class:"dh-card overflow-hidden"},tu={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},su={class:"text-base font-bold tracking-[-0.02em] text-strong"},nu={class:"mt-0.5 text-xs text-muted"},iu={key:0,class:"border-b border-subtle bg-sunken px-5 py-4"},ou={class:"grid gap-3 sm:grid-cols-3"},ru={class:"dh-label"},lu={class:"dh-label"},au={class:"dh-label"},cu=["disabled"],uu={key:1,class:"border-b border-subtle px-5 py-3 text-xs text-danger"},du={key:2,class:"px-5 py-6 text-center text-sm text-muted"},fu={class:"flex items-center gap-3 px-5 py-3"},pu=["onClick"],hu={class:"font-semibold text-strong"},gu={class:"dh-pill bg-sunken text-muted"},mu={key:0,class:"text-xs text-muted"},bu=["disabled","onClick"],vu=["disabled","onClick"],_u={key:0,class:"bg-sunken px-5 py-4"},yu={key:0,class:"data mb-3 text-xs text-muted"},wu={key:1,class:"grid gap-3 sm:grid-cols-2"},xu={class:"dh-label"},ku={key:0,class:"text-danger"},Su=["onUpdate:modelValue"],Tu={key:0,value:""},Eu=["value"],Cu=["onUpdate:modelValue","type","placeholder"],Pu={key:2,class:"mt-1 text-xs text-muted"},$u={key:2,class:"text-xs text-muted"},Au={key:3,class:"mt-4"},Ou={class:"eyebrow mb-1.5"},Ru={class:"data flex flex-col gap-1 text-xs text-muted"},Iu={class:"text-strong"},ju={key:0},zu={key:1},Uu={key:4,class:"data mt-3 text-xs text-body"},Nu={class:"mt-4 flex items-center gap-2"},Du=["disabled","onClick"],Mu=["disabled","onClick"],Lu=["disabled","onClick"],Fu={key:5,class:"eyebrow mt-2"},Bu={__name:"PluginsCard",setup(e){const t=V([]),s=V(""),n=V(!1),i=V(null),o=Yt({}),r=Yt({}),l=V(!1),a=V({name:"",baseURL:"",provider:""});async function p(){try{const E=await se("/api/admin/plugins");t.value=E.plugins||[],s.value=""}catch(E){s.value=E.message}}dt(p);function u(E){var $;if(i.value===E.name){i.value=null;return}const y={};for(const z of E.configFields||[])y[z.key]=(($=E.config)==null?void 0:$[z.key])??"";o[E.name]=y,i.value=E.name}async function m(E,y){n.value=!0,r[E.name]="";try{const $=await se(`/api/admin/plugins/${encodeURIComponent(E.name)}`,{method:"PUT",body:{enabled:y,config:o[E.name]??{}}});r[E.name]=$.warning||h("plugins.saved"),await p()}catch($){r[E.name]=$.message}finally{n.value=!1}}async function P(E){n.value=!0,r[E.name]=h("plugins.checking");try{const y=await se(`/api/admin/plugins/${encodeURIComponent(E.name)}/health`,{method:"POST"});r[E.name]=`${y.health.status}${y.health.detail?" — "+y.health.detail:""}`,await p()}catch(y){r[E.name]=y.message}finally{n.value=!1}}async function O(E){if(confirm(h("plugins.confirmRemove",{name:E.name}))){n.value=!0;try{await se(`/api/admin/plugins/${encodeURIComponent(E.name)}`,{method:"DELETE"}),i.value===E.name&&(i.value=null),await p()}catch(y){r[E.name]=y.message}finally{n.value=!1}}}async function F(){n.value=!0,s.value="";try{await se("/api/admin/plugins",{method:"POST",body:a.value}),a.value={name:"",baseURL:"",provider:""},l.value=!1,await p()}catch(E){s.value=E.message}finally{n.value=!1}}const _=E=>E==="ok"?"bg-success-soft text-success":E==="degraded"?"bg-warning-soft text-warning":"bg-danger-soft text-danger";return(E,y)=>(S(),C("div",eu,[d("div",tu,[d("div",null,[d("div",su,b(g(h)("plugins.title")),1),d("p",nu,b(g(h)("plugins.subtitle")),1)]),d("button",{class:"dh-btn-ghost",onClick:y[0]||(y[0]=$=>l.value=!l.value)},b(l.value?g(h)("plugins.cancelRegister"):g(h)("plugins.registerExternal")),1)]),l.value?(S(),C("div",iu,[d("div",ou,[d("div",null,[d("label",ru,b(g(h)("plugins.name")),1),le(d("input",{"onUpdate:modelValue":y[1]||(y[1]=$=>a.value.name=$),class:"dh-input",placeholder:"acme-parts"},null,512),[[pe,a.value.name]])]),d("div",null,[d("label",lu,b(g(h)("plugins.baseUrl")),1),le(d("input",{"onUpdate:modelValue":y[2]||(y[2]=$=>a.value.baseURL=$),class:"dh-input",placeholder:"http://127.0.0.1:9100"},null,512),[[pe,a.value.baseURL]])]),d("div",null,[d("label",au,b(g(h)("plugins.provider")),1),le(d("input",{"onUpdate:modelValue":y[3]||(y[3]=$=>a.value.provider=$),class:"dh-input",placeholder:"ACME Corp"},null,512),[[pe,a.value.provider]])])]),d("button",{class:"dh-btn mt-3",disabled:n.value||!a.value.name||!a.value.baseURL,onClick:F},b(g(h)("plugins.register")),9,cu)])):B("",!0),s.value?(S(),C("p",uu,b(s.value),1)):B("",!0),t.value.length?B("",!0):(S(),C("p",du,b(g(h)("plugins.empty")),1)),(S(!0),C(ee,null,Se(t.value,$=>(S(),C("div",{key:$.name,class:"border-t border-subtle first:border-t-0"},[d("div",fu,[d("button",{class:"flex flex-1 items-center gap-3 text-left",onClick:z=>u($)},[d("span",hu,b($.name),1),d("span",gu,b($.kind||g(h)("plugins.builtin")),1),$.provider?(S(),C("span",mu,b($.provider),1)):B("",!0),$.health?(S(),C("span",{key:1,class:Oe(["dh-pill",_($.health.status)])},[y[4]||(y[4]=d("span",{class:"h-1.5 w-1.5 rounded-full bg-current"},null,-1)),Ee(b($.health.status),1)],2)):B("",!0)],8,pu),d("span",{class:Oe(["dh-pill",$.enabled?"bg-success-soft text-success":"bg-sunken text-muted"])},b($.enabled?g(h)("plugins.enabled"):g(h)("plugins.disabled")),3),d("button",{class:"dh-btn-ghost",disabled:n.value,onClick:z=>P($)},b(g(h)("plugins.health")),9,bu),d("button",{class:"dh-btn-ghost",disabled:n.value,onClick:z=>u($)},b(i.value===$.name?g(h)("plugins.close"):g(h)("plugins.configure")),9,vu)]),i.value===$.name?(S(),C("div",_u,[$.baseURL?(S(),C("div",yu,b($.baseURL),1)):B("",!0),($.configFields||[]).length?(S(),C("div",wu,[(S(!0),C(ee,null,Se($.configFields,z=>(S(),C("div",{key:z.key},[d("label",xu,[Ee(b(z.label||z.key),1),z.required?(S(),C("span",ku," *")):B("",!0)]),z.type==="select"?le((S(),C("select",{key:0,"onUpdate:modelValue":U=>o[$.name][z.key]=U,class:"dh-select"},[z.required?B("",!0):(S(),C("option",Tu,b(g(h)("plugins.notSet")),1)),(S(!0),C(ee,null,Se(z.options||[],U=>(S(),C("option",{key:U.value,value:U.value},b(U.label||U.value),9,Eu))),128))],8,Su)),[[ks,o[$.name][z.key]]]):le((S(),C("input",{key:1,"onUpdate:modelValue":U=>o[$.name][z.key]=U,class:"dh-input",type:z.type==="password"?"password":z.type==="number"?"number":"text",placeholder:z.default||"",autocomplete:"off"},null,8,Cu)),[[Gl,o[$.name][z.key]]]),z.help?(S(),C("p",Pu,b(z.help),1)):B("",!0)]))),128))])):(S(),C("p",$u,b(g(h)("plugins.noConfig")),1)),($.capabilities||[]).length?(S(),C("div",Au,[d("div",Ou,b(g(h)("plugins.capabilities")),1),d("ul",Ru,[(S(!0),C(ee,null,Se($.capabilities,z=>(S(),C("li",{key:z.id},[d("span",Iu,b(z.id),1),z.method||z.endpoint?(S(),C("span",ju," — "+b(z.method)+" "+b(z.endpoint),1)):B("",!0),z.description?(S(),C("span",zu," · "+b(z.description),1)):B("",!0)]))),128))])])):B("",!0),r[$.name]?(S(),C("p",Uu,b(r[$.name]),1)):B("",!0),d("div",Nu,[d("button",{class:"dh-btn",disabled:n.value,onClick:z=>m($,!0)},b($.enabled?g(h)("plugins.save"):g(h)("plugins.saveEnable")),9,Du),$.enabled?(S(),C("button",{key:0,class:"dh-btn-ghost",disabled:n.value,onClick:z=>m($,!1)},b(g(h)("plugins.disable")),9,Mu)):B("",!0),y[5]||(y[5]=d("span",{class:"flex-1"},null,-1)),$.kind==="external"?(S(),C("button",{key:1,class:"dh-btn-danger",disabled:n.value,onClick:z=>O($)},b(g(h)("plugins.remove")),9,Lu)):B("",!0)]),$.kind!=="external"?(S(),C("p",Fu,b(g(h)("plugins.builtinNote")),1)):B("",!0)])):B("",!0)]))),128))]))}},Hu={class:"dh-card overflow-hidden"},Vu={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},Ku={class:"text-base font-bold tracking-[-0.02em] text-strong"},Wu={class:"mt-0.5 text-xs text-muted"},Gu={key:0,class:"border-b border-subtle px-5 py-3 text-xs text-danger"},qu={key:1,class:"border-b border-subtle bg-sunken px-5 py-4"},Zu={class:"grid gap-3 sm:grid-cols-2"},Yu={class:"dh-label"},Ju={class:"dh-label"},Xu={class:"dh-label"},Qu=["placeholder"],ed={class:"dh-label"},td=["value"],sd={key:0},nd={class:"dh-label"},id={value:""},od=["value"],rd={class:"mt-3 flex items-center gap-2"},ld=["disabled"],ad=["disabled"],cd={key:2,class:"px-5 py-6 text-center text-sm text-muted"},ud={key:3,class:"w-full text-left text-sm"},dd={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"},pd={key:0,class:"eyebrow ml-1"},hd={class:"px-5 py-2.5 text-body"},gd={class:"px-5 py-2.5 text-body"},md={class:"px-5 py-2.5"},bd={class:"px-5 py-2.5 text-right whitespace-nowrap"},vd=["onClick"],_d=["disabled","onClick"],yd={__name:"UsersCard",setup(e){const t=V([]),s=V([]),n=V(""),i=V(!1),o=V(null),r=V({}),l=Ae(()=>xe.value?["user","admin","superadmin"]:["user","admin"]);async function a(){try{const[_,E]=await Promise.all([se("/api/users"),se("/api/orgs")]);t.value=_.users||[],s.value=E.organizations||[],n.value=""}catch(_){n.value=_.message}}dt(a);function p(){var _;o.value="new",r.value={email:"",name:"",password:"",role:"user",organization:xe.value?"":((_=re.value)==null?void 0:_.organization)||""}}function u(_){o.value=_.id,r.value={email:_.email,name:_.name||"",password:"",role:_.role,organization:_.organization||""}}function m(){o.value=null,n.value=""}async function P(){i.value=!0,n.value="";try{if(o.value==="new")await se("/api/users",{method:"POST",body:r.value});else{const _={...r.value};_.password||delete _.password,await se(`/api/users/${o.value}`,{method:"PATCH",body:_})}o.value=null,await a()}catch(_){n.value=_.message}finally{i.value=!1}}async function O(_){if(confirm(h("users.confirmDelete",{email:_.email}))){i.value=!0,n.value="";try{await se(`/api/users/${_.id}`,{method:"DELETE"}),await a()}catch(E){n.value=E.message}finally{i.value=!1}}}const F=_=>_==="superadmin"?"bg-info-soft text-info":_==="admin"?"bg-warning-soft text-warning":"bg-sunken text-muted";return(_,E)=>(S(),C("div",Hu,[d("div",Vu,[d("div",null,[d("div",Ku,b(g(h)("users.title")),1),d("p",Wu,b(g(xe)?g(h)("users.allOrgs"):g(h)("users.yourOrg")),1)]),d("button",{class:"dh-btn",onClick:p},b(g(h)("users.newUser")),1)]),n.value?(S(),C("p",Gu,b(n.value),1)):B("",!0),o.value?(S(),C("div",qu,[d("div",Zu,[d("div",null,[d("label",Yu,b(g(h)("common.email")),1),le(d("input",{"onUpdate:modelValue":E[0]||(E[0]=y=>r.value.email=y),class:"dh-input",type:"email",autocomplete:"off"},null,512),[[pe,r.value.email]])]),d("div",null,[d("label",Ju,b(g(h)("common.name")),1),le(d("input",{"onUpdate:modelValue":E[1]||(E[1]=y=>r.value.name=y),class:"dh-input",autocomplete:"off"},null,512),[[pe,r.value.name]])]),d("div",null,[d("label",Xu,b(o.value==="new"?g(h)("users.password"):g(h)("users.passwordUnchanged")),1),le(d("input",{"onUpdate:modelValue":E[2]||(E[2]=y=>r.value.password=y),class:"dh-input",type:"password",autocomplete:"new-password",placeholder:g(h)("users.passwordPlaceholder")},null,8,Qu),[[pe,r.value.password]])]),d("div",null,[d("label",ed,b(g(h)("common.role")),1),le(d("select",{"onUpdate:modelValue":E[3]||(E[3]=y=>r.value.role=y),class:"dh-select"},[(S(!0),C(ee,null,Se(l.value,y=>(S(),C("option",{key:y,value:y},b(y),9,td))),128))],512),[[ks,r.value.role]])]),g(xe)?(S(),C("div",sd,[d("label",nd,b(g(h)("common.organization")),1),le(d("select",{"onUpdate:modelValue":E[4]||(E[4]=y=>r.value.organization=y),class:"dh-select"},[d("option",id,b(g(h)("users.orgNone")),1),(S(!0),C(ee,null,Se(s.value,y=>(S(),C("option",{key:y.id,value:y.id},b(y.name),9,od))),128))],512),[[ks,r.value.organization]])])):B("",!0)]),d("div",rd,[d("button",{class:"dh-btn",disabled:i.value,onClick:P},b(o.value==="new"?g(h)("common.create"):g(h)("common.save")),9,ld),d("button",{class:"dh-btn-ghost",disabled:i.value,onClick:m},b(g(h)("common.cancel")),9,ad)])])):B("",!0),t.value.length?(S(),C("table",ud,[d("thead",null,[d("tr",dd,[d("th",null,b(g(h)("common.email")),1),d("th",null,b(g(h)("common.name")),1),d("th",null,b(g(h)("common.organization")),1),d("th",null,b(g(h)("common.role")),1),E[5]||(E[5]=d("th",null,null,-1))])]),d("tbody",null,[(S(!0),C(ee,null,Se(t.value,y=>{var $,z;return S(),C("tr",{key:y.id,class:"border-t border-subtle transition-colors hover:bg-sunken"},[d("td",fd,[Ee(b(y.email)+" ",1),y.id===(($=g(re))==null?void 0:$.id)?(S(),C("span",pd,b(g(h)("users.you")),1)):B("",!0)]),d("td",hd,b(y.name||g(h)("common.empty")),1),d("td",gd,b(y.organizationName||g(h)("common.empty")),1),d("td",md,[d("span",{class:Oe(["dh-pill",F(y.role)])},b(y.role),3)]),d("td",bd,[d("button",{class:"dh-btn-ghost",onClick:U=>u(y)},b(g(h)("common.edit")),9,vd),y.id!==((z=g(re))==null?void 0:z.id)?(S(),C("button",{key:0,class:"dh-btn-danger ml-1.5",disabled:i.value,onClick:U=>O(y)},b(g(h)("common.delete")),9,_d)):B("",!0)])])}),128))])])):(S(),C("p",cd,b(g(h)("users.empty")),1))]))}},wd={class:"dh-card overflow-hidden"},xd={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},kd={class:"text-base font-bold tracking-[-0.02em] text-strong"},Sd={class:"mt-0.5 text-xs text-muted"},Td={key:0,class:"border-b border-subtle px-5 py-3 text-xs text-danger"},Ed={key:1,class:"border-b border-subtle bg-sunken px-5 py-4"},Cd={class:"dh-label"},Pd=["placeholder"],$d={class:"mt-3 flex items-center gap-2"},Ad=["disabled"],Od=["disabled"],Rd={key:2,class:"px-5 py-6 text-center text-sm text-muted"},Id={key:3,class:"w-full text-left text-sm"},jd={class:"[&>th]:eyebrow [&>th]:px-5 [&>th]:py-2.5 [&>th]:font-medium"},zd={class:"px-5 py-2.5 font-medium text-strong"},Ud={class:"data px-5 py-2.5 text-xs text-muted"},Nd={class:"px-5 py-2.5 text-right whitespace-nowrap"},Dd=["onClick"],Md=["disabled","onClick"],Ld={__name:"OrgsCard",setup(e){const t=V([]),s=V(""),n=V(!1),i=V(null),o=V(""),r=Ae(()=>{var _;return((_=re.value)==null?void 0:_.organization)||""}),l=Ae(()=>xe.value||!r.value);function a(_){return xe.value||_.id===r.value}async function p(){if(!gs.value){t.value=[];return}try{const _=await se("/api/orgs");t.value=_.organizations||[],s.value=""}catch(_){s.value=_.message}}dt(p);function u(){i.value="new",o.value=""}function m(_){i.value=_.id,o.value=_.name}function P(){i.value=null,s.value=""}async function O(){n.value=!0,s.value="";try{i.value==="new"?(await se("/api/orgs",{method:"POST",body:{name:o.value}}),xe.value||await Ss()):await se(`/api/orgs/${i.value}`,{method:"PATCH",body:{name:o.value}}),i.value=null,await p()}catch(_){s.value=_.message}finally{n.value=!1}}async function F(_){const E=!xe.value&&_.id===r.value;if(confirm(h(E?"orgs.confirmDeleteOwn":"orgs.confirmDelete",{name:_.name}))){n.value=!0,s.value="";try{await se(`/api/orgs/${_.id}`,{method:"DELETE"}),E&&await Ss(),await p()}catch($){s.value=$.message}finally{n.value=!1}}}return(_,E)=>(S(),C("div",wd,[d("div",xd,[d("div",null,[d("div",kd,b(g(xe)?g(h)("orgs.title"):g(h)("common.organization")),1),d("p",Sd,b(g(xe)?g(h)("orgs.subtitle"):r.value?g(h)("orgs.subtitleOwn"):g(h)("orgs.subtitleNone")),1)]),l.value?(S(),C("button",{key:0,class:"dh-btn",onClick:u},b(g(h)("orgs.newOrg")),1)):B("",!0)]),s.value?(S(),C("p",Td,b(s.value),1)):B("",!0),i.value?(S(),C("div",Ed,[d("label",Cd,b(g(h)("common.name")),1),le(d("input",{"onUpdate:modelValue":E[0]||(E[0]=y=>o.value=y),class:"dh-input",placeholder:g(h)("orgs.namePlaceholder"),onKeyup:Ql(O,["enter"])},null,40,Pd),[[pe,o.value]]),d("div",$d,[d("button",{class:"dh-btn",disabled:n.value||!o.value.trim(),onClick:O},b(i.value==="new"?g(h)("common.create"):g(h)("common.save")),9,Ad),d("button",{class:"dh-btn-ghost",disabled:n.value,onClick:P},b(g(h)("common.cancel")),9,Od)])])):B("",!0),t.value.length?(S(),C("table",Id,[d("thead",null,[d("tr",jd,[d("th",null,b(g(h)("common.name")),1),d("th",null,b(g(h)("orgs.colId")),1),E[1]||(E[1]=d("th",null,null,-1))])]),d("tbody",null,[(S(!0),C(ee,null,Se(t.value,y=>(S(),C("tr",{key:y.id,class:"border-t border-subtle transition-colors hover:bg-sunken"},[d("td",zd,b(y.name),1),d("td",Ud,b(y.id),1),d("td",Nd,[a(y)?(S(),C(ee,{key:0},[d("button",{class:"dh-btn-ghost",onClick:$=>m(y)},b(g(h)("common.rename")),9,Dd),d("button",{class:"dh-btn-danger ml-1.5",disabled:n.value,onClick:$=>F(y)},b(g(h)("common.delete")),9,Md)],64)):B("",!0)])]))),128))])])):(S(),C("p",Rd,b(l.value&&!g(xe)?g(h)("orgs.createHint"):g(h)("orgs.empty")),1))]))}},Fd={class:"dh-card overflow-hidden"},Bd={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},Hd={class:"text-base font-bold tracking-[-0.02em] text-strong"},Vd={class:"eyebrow"},Kd={class:"w-full text-left text-sm"},Wd={class:"[&>th]:eyebrow [&>th]:px-5 [&>th]:py-2.5 [&>th]:font-medium"},Gd={class:"data border-t border-subtle px-5 py-2.5 text-xs whitespace-nowrap"},qd={class:"text-strong"},Zd={class:"border-t border-subtle px-5 py-2.5 text-body"},it={__name:"EndpointTable",props:{title:String,auth:String,endpoints:Array},setup(e){const t={GET:"text-success",POST:"text-brandtext",PATCH:"text-warning",DELETE:"text-danger"};return(s,n)=>(S(),C("div",Fd,[d("div",Bd,[d("div",Hd,b(e.title),1),d("span",Vd,b(e.auth),1)]),d("table",Kd,[d("thead",null,[d("tr",Wd,[d("th",null,b(g(h)("api.colEndpoint")),1),d("th",null,b(g(h)("api.colDescription")),1)])]),d("tbody",null,[(S(!0),C(ee,null,Se(e.endpoints,i=>(S(),C("tr",{key:i.method+i.path,class:"transition-colors hover:bg-sunken"},[d("td",Gd,[d("span",{class:Oe(["font-semibold",t[i.method]])},b(i.method),3),d("span",qd,b(i.path),1)]),d("td",Zd,b(i.desc),1)]))),128))])])]))}},Yd={class:"mx-auto flex max-w-4xl flex-col gap-6 px-6 pt-12 pb-16"},Jd={class:"flex items-center gap-3"},Xd={class:"inline-flex items-center gap-2.5 select-none"},Qd={class:"h-8 w-8 shrink-0",viewBox:"0 0 48 48",fill:"none","aria-hidden":"true"},ef={transform:"translate(7 0) skewX(-13)"},tf=["fill"],sf=["fill"],nf=["fill"],of={class:"eyebrow mt-1.5"},rf={key:0,class:"data hidden text-xs text-muted sm:inline"},lf={key:0},af={key:1,class:"dh-pill bg-info-soft text-info"},cf=["value","aria-label"],uf=["value"],df=["title"],ff={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"},pf={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"},hf={key:0,class:"eyebrow py-16 text-center"},gf={class:"flex flex-wrap gap-1.5"},mf=["onClick"],bf={key:7,class:"eyebrow text-center"},vf={class:"eyebrow text-center"},_f={__name:"App",setup(e){const t=V(!0),s=V("overview");dt(async()=>{await Ja(),t.value=!1});const n=Ae(()=>{const _=[{id:"overview",label:h("sections.overview")}];return gs.value&&_.push({id:"users",label:h("sections.users")}),(gs.value||re.value)&&_.push({id:"orgs",label:h("sections.orgs")}),xe.value&&_.push({id:"pocketbase",label:h("sections.pocketbase")},{id:"webapp",label:h("sections.webapp")},{id:"plugins",label:h("sections.plugins")}),_.push({id:"api",label:h("sections.api")}),_}),i=Ae(()=>Ba.map(_=>{let E=_;try{E=new Intl.DisplayNames([_],{type:"language"}).of(_)||_}catch{}return{code:_,label:E.charAt(0).toUpperCase()+E.slice(1)}}));function o(){Cn(),s.value="overview"}const r=Ae(()=>Et.value==="dark"?["#60a5fa","#93c5fd","#ffffff"]:["var(--brand-700)","var(--brand-500)","var(--brand-400)"]),l=[{method:"GET",path:"/api/health",desc:"Liveness probe (no auth)"},{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"}],p=[{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:"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}/parts",desc:"A car's parts catalog"},{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)"}],u=[{method:"GET",path:"/api/service-records",desc:"List service records"},{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"}],m=[{method:"GET",path:"/api/parts",desc:"List parts"},{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"}],P=[{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"}],O=[{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)"}],F=[{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/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(_,E)=>(S(),C("div",Yd,[d("div",Jd,[d("span",Xd,[(S(),C("svg",Qd,[d("g",ef,[d("rect",{x:"9",y:"16",width:"6",height:"16",rx:"3",fill:r.value[0]},null,8,tf),d("rect",{x:"19",y:"12",width:"6",height:"24",rx:"3",fill:r.value[1]},null,8,sf),d("rect",{x:"29",y:"8",width:"6",height:"32",rx:"3",fill:r.value[2]},null,8,nf)])])),E[2]||(E[2]=d("span",{class:"text-2xl leading-none font-extrabold tracking-[-0.03em] italic"},[d("span",{class:"text-strong"},"Driver"),d("span",{class:"text-brandtext"},"Vault")],-1))]),d("span",of,b(g(h)("app.apiServer")),1),E[5]||(E[5]=d("div",{class:"flex-1"},null,-1)),g(re)?(S(),C("span",rf,[Ee(b(g(re).email),1),g(re).organizationName?(S(),C("span",lf," · "+b(g(re).organizationName),1)):B("",!0)])):B("",!0),g(re)?(S(),C("span",af,b(g(re).role),1)):B("",!0),d("select",{class:"dh-select !w-auto !py-1 !text-xs",value:g(En),"aria-label":g(h)("sections.overview"),onChange:E[0]||(E[0]=y=>g(Va)(y.target.value))},[(S(!0),C(ee,null,Se(i.value,y=>(S(),C("option",{key:y.code,value:y.code},b(y.label),9,uf))),128))],40,cf),d("button",{class:"dh-btn-ghost",title:g(Et)==="dark"?g(h)("app.switchToLight"):g(h)("app.switchToDark"),onClick:E[1]||(E[1]=(...y)=>g(pi)&&g(pi)(...y))},[g(Et)==="dark"?(S(),C("svg",ff,[...E[3]||(E[3]=[d("circle",{cx:"12",cy:"12",r:"4"},null,-1),d("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)])])):(S(),C("svg",pf,[...E[4]||(E[4]=[d("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)])])),Ee(" "+b(g(h)("app.theme")),1)],8,df),g(Ot)?(S(),C("button",{key:2,class:"dh-btn-ghost",onClick:o},b(g(h)("app.signOut")),1)):B("",!0)]),t.value?(S(),C("p",hf,b(g(h)("app.loading")),1)):g(Ot)?(S(),C(ee,{key:2},[d("nav",gf,[(S(!0),C(ee,null,Se(n.value,y=>(S(),C("button",{key:y.id,class:Oe(["dh-btn-ghost",s.value===y.id?"border-accent text-brandtext":""]),onClick:$=>s.value=y.id},b(y.label),11,mf))),128))]),s.value==="overview"?(S(),ot(_c,{key:0})):s.value==="users"?(S(),ot(yd,{key:1})):s.value==="orgs"?(S(),ot(Ld,{key:2})):s.value==="pocketbase"?(S(),ot(Nc,{key:3})):s.value==="webapp"?(S(),ot(Qc,{key:4})):s.value==="plugins"?(S(),ot(Bu,{key:5})):s.value==="api"?(S(),C(ee,{key:6},[ue(it,{title:g(h)("api.groupPublic"),auth:g(h)("api.authNone"),endpoints:l},null,8,["title","auth"]),ue(it,{title:g(h)("api.groupIdentity"),auth:g(h)("api.authBearer"),endpoints:a},null,8,["title","auth"]),ue(it,{title:g(h)("api.groupCars"),auth:g(h)("api.authBearer"),endpoints:p},null,8,["title","auth"]),ue(it,{title:g(h)("api.groupService"),auth:g(h)("api.authBearer"),endpoints:u},null,8,["title","auth"]),ue(it,{title:g(h)("api.groupParts"),auth:g(h)("api.authBearer"),endpoints:m},null,8,["title","auth"]),ue(it,{title:g(h)("api.groupAccount"),auth:g(h)("api.authBearer"),endpoints:P},null,8,["title","auth"]),ue(it,{title:g(h)("api.groupManagement"),auth:g(h)("api.authManager"),endpoints:O},null,8,["title","auth"]),ue(it,{title:g(h)("api.groupSuperadmin"),auth:g(h)("api.authSuperadmin"),endpoints:F},null,8,["title","auth"])],64)):B("",!0),!g(gs)&&s.value==="overview"?(S(),C("p",bf,b(g(h)("app.standardUserNote")),1)):B("",!0)],64)):(S(),ot(lc,{key:1})),d("p",vf,b(g(h)("app.footer")),1)]))}};sa(_f).mount("#app"); diff --git a/API Server/internal/api/dist/index.html b/API Server/internal/api/dist/index.html index 1cb0f90..3e43359 100644 --- a/API Server/internal/api/dist/index.html +++ b/API Server/internal/api/dist/index.html @@ -6,7 +6,7 @@ DriverVault · API Server - + diff --git a/API Server/internal/api/me.go b/API Server/internal/api/me.go index afbb9d9..30cdbf3 100644 --- a/API Server/internal/api/me.go +++ b/API Server/internal/api/me.go @@ -33,6 +33,7 @@ type userRecord struct { FontSize string `json:"font_size"` DeletionRequestedAt string `json:"deletion_requested_at"` Role string `json:"role"` + Organization string `json:"organization"` Created string `json:"created"` } @@ -51,6 +52,8 @@ func (rec userRecord) toModel() models.User { FontSize: orDefault(rec.FontSize, "medium"), Role: orDefault(rec.Role, "user"), Created: rec.Created, + + Organization: rec.Organization, } if t := parsePBDate(rec.DeletionRequestedAt); !t.IsZero() { u.DeletionRequestedAt = &t @@ -65,6 +68,17 @@ func orDefault(v, fallback string) string { return v } +// profileOf builds the profile payload for a user record, resolving their +// organization's name so the clients can label the membership without a second +// round trip. The lookup is best effort — an unresolvable name leaves the id. +func (s *Server) profileOf(r *http.Request, rec *userRecord) models.User { + u := rec.toModel() + if u.Organization != "" { + u.OrganizationName = s.orgName(r.Context(), u.Organization) + } + return u +} + func (s *Server) fetchUser(r *http.Request, id string) (*userRecord, error) { var rec userRecord if err := s.pb.GetOne(r.Context(), s.usersCollection(), id, &rec); err != nil { @@ -84,7 +98,7 @@ func (s *Server) handleGetMe(w http.ResponseWriter, r *http.Request) { writePBError(w, err) return } - writeJSON(w, http.StatusOK, rec.toModel()) + writeJSON(w, http.StatusOK, s.profileOf(r, rec)) } type updateMeRequest struct { @@ -181,7 +195,7 @@ func (s *Server) handleUpdateMe(w http.ResponseWriter, r *http.Request) { writePBError(w, err) return } - writeJSON(w, http.StatusOK, rec.toModel()) + writeJSON(w, http.StatusOK, s.profileOf(r, &rec)) } type changePasswordRequest struct { @@ -256,7 +270,7 @@ func (s *Server) handleUploadAvatar(w http.ResponseWriter, r *http.Request) { writePBError(w, err) return } - writeJSON(w, http.StatusOK, rec.toModel()) + writeJSON(w, http.StatusOK, s.profileOf(r, rec)) } func (s *Server) handleDeleteAvatar(w http.ResponseWriter, r *http.Request) { diff --git a/API Server/internal/api/orgs.go b/API Server/internal/api/orgs.go index caa3d9d..ac863eb 100644 --- a/API Server/internal/api/orgs.go +++ b/API Server/internal/api/orgs.go @@ -81,8 +81,24 @@ func (s *Server) handleListOrgs(w http.ResponseWriter, r *http.Request) { writeJSON(w, http.StatusOK, map[string]any{"organizations": list.Items}) } -// POST /api/orgs — create an organization (superadmin only). Body: {name}. +// POST /api/orgs — create an organization. Body: {name}. A superadmin may create +// any number of organizations and is not attached to them (they manage every +// tenant centrally). Any other user may create one only if they don't already +// belong to an organization, and they become its admin and first member — the +// self-service path for standing up a new tenant. +// +// This handler carries no requireRole gate (any authenticated caller may reach +// it), so it checks the service account itself. func (s *Server) handleCreateOrg(w http.ResponseWriter, r *http.Request) { + if !s.pb.Configured() { + writeError(w, http.StatusServiceUnavailable, "organizations are not configured on the server") + return + } + who := caller(r) + if !who.isSuperadmin() && who.OrgID != "" { + writeError(w, http.StatusForbidden, "you already belong to an organization") + return + } name, ok := decodeOrgName(w, r) if !ok { return @@ -100,16 +116,42 @@ func (s *Server) handleCreateOrg(w http.ResponseWriter, r *http.Request) { } var org orgView _ = json.Unmarshal(data, &org) + + // A non-superadmin creator becomes the admin of, and first member of, the org + // they just made. If that promotion fails, roll the org back so we never leave + // a stranded organization that nobody can administer. + if !who.isSuperadmin() { + data, status, err = s.pb.Raw(r.Context(), http.MethodPatch, + "/api/collections/"+s.usersCollection()+"/records/"+url.PathEscape(who.ID), + map[string]any{"organization": org.ID, "role": roleAdmin}) + if err != nil || status != http.StatusOK { + _, _, _ = s.pb.Raw(r.Context(), http.MethodDelete, + "/api/collections/"+colOrgs+"/records/"+url.PathEscape(org.ID), nil) + if err != nil { + writeUpstreamDown(w, err) + return + } + relay(w, status, data) + return + } + } writeJSON(w, http.StatusCreated, map[string]any{"organization": org}) } -// PATCH /api/orgs/{id} — rename an organization (superadmin only). Body: {name}. +// PATCH /api/orgs/{id} — rename an organization (manager only). A superadmin may +// rename any organization; an admin may rename only their own. Body: {name}. func (s *Server) handleUpdateOrg(w http.ResponseWriter, r *http.Request) { + who := caller(r) id := r.PathValue("id") if id == "" { writeError(w, http.StatusBadRequest, "missing organization id") return } + // An admin is scoped to their own organization; a superadmin spans all. + if !who.isSuperadmin() && (who.OrgID == "" || id != who.OrgID) { + writeError(w, http.StatusForbidden, "you can only rename your own organization") + return + } name, ok := decodeOrgName(w, r) if !ok { return @@ -129,18 +171,35 @@ func (s *Server) handleUpdateOrg(w http.ResponseWriter, r *http.Request) { writeJSON(w, http.StatusOK, map[string]any{"organization": org}) } -// DELETE /api/orgs/{id} — delete an organization (superadmin only). Refused -// while the org still has members, to avoid silently orphaning users. +// DELETE /api/orgs/{id} — delete an organization (manager only). A superadmin may +// delete any organization, but only once it has no members. An admin may delete +// only their own organization, and only when they are its sole member: the admin +// is detached and demoted back to a plain user, then the org is removed. Either +// path refuses to silently orphan other members. func (s *Server) handleDeleteOrg(w http.ResponseWriter, r *http.Request) { + who := caller(r) id := r.PathValue("id") if id == "" { writeError(w, http.StatusBadRequest, "missing organization id") return } - // Guard: block deletion if any user still belongs to this org. + // Count the members that block deletion. A superadmin is blocked by anyone at + // all; an admin deleting their own org is blocked only by *other* members, + // since they detach themselves below. + filter := "organization = \"" + id + "\"" + blocked := "organization still has members; reassign or remove them first" + if !who.isSuperadmin() { + // An admin is scoped to their own organization. + if who.OrgID == "" || id != who.OrgID { + writeError(w, http.StatusForbidden, "you can only delete your own organization") + return + } + filter += " && id != \"" + who.ID + "\"" + blocked = "organization still has other members; reassign or remove them first" + } countPath := "/api/collections/" + s.usersCollection() + "/records?perPage=1&fields=id&filter=" + - url.QueryEscape("organization = \""+id+"\"") + url.QueryEscape(filter) data, status, err := s.pb.Raw(r.Context(), http.MethodGet, countPath, nil) if err != nil { writeUpstreamDown(w, err) @@ -152,7 +211,25 @@ func (s *Server) handleDeleteOrg(w http.ResponseWriter, r *http.Request) { } _ = json.Unmarshal(data, &page) if page.TotalItems > 0 { - writeError(w, http.StatusConflict, "organization still has members; reassign or remove them first") + writeError(w, http.StatusConflict, blocked) + return + } + } + + // Detach and demote the admin so the org is empty before it is removed. Done + // before the delete because users.organization does not cascade: a failed + // delete leaves an empty org a superadmin can clean up, which beats leaving a + // member pointing at an organization that no longer exists. + if !who.isSuperadmin() { + data, status, err = s.pb.Raw(r.Context(), http.MethodPatch, + "/api/collections/"+s.usersCollection()+"/records/"+url.PathEscape(who.ID), + map[string]any{"organization": "", "role": roleUser}) + if err != nil { + writeUpstreamDown(w, err) + return + } + if status != http.StatusOK { + relay(w, status, data) return } } diff --git a/API Server/internal/api/orgs_test.go b/API Server/internal/api/orgs_test.go new file mode 100644 index 0000000..4aeb427 --- /dev/null +++ b/API Server/internal/api/orgs_test.go @@ -0,0 +1,333 @@ +package api + +import ( + "bytes" + "encoding/json" + "net/http" + "net/http/httptest" + "sync" + "testing" + + "drivervault/apiserver/internal/config" + "drivervault/apiserver/internal/pb" +) + +// These tests cover the self-service organization flows through the real +// Handler + middleware chain: an org-less user creating an org and being +// promoted to its admin (including the rollback when that promotion fails), and +// an admin renaming or deleting only their own organization. A stand-in +// PocketBase (orgFakePB) serves exactly the endpoints those paths hit. + +const ( + orgTestUserID = "u1" + orgTestBearer = "user-bearer-token" + orgTestNewID = "neworg1" +) + +// orgFakePB answers the identity, organization and user-record calls the org +// handlers make, and records the writes so tests can assert on them. +type orgFakePB struct { + mu sync.Mutex + + // Identity returned by auth-refresh. + callerRole string + callerOrg string + + // Behaviour switches. + userPatchStatus int // status for a caller promotion/demotion (200 when 0) + memberCount int // totalItems for the blocking-member query + + // Recorded effects. + createdOrgs []string + orgPatches []map[string]any + orgDeletes []string + userPatches []map[string]any +} + +func (f *orgFakePB) handler(t *testing.T) http.Handler { + t.Helper() + mux := http.NewServeMux() + + // Service-account auth (pb.Client.Authenticate). + mux.HandleFunc("POST /api/collections/_superusers/auth-with-password", func(w http.ResponseWriter, r *http.Request) { + writeJSON(w, 200, map[string]any{"token": "svc-token"}) + }) + + // Identify the bearer (withAuth → identify → AuthRefresh). + mux.HandleFunc("POST /api/collections/users/auth-refresh", func(w http.ResponseWriter, r *http.Request) { + if r.Header.Get("Authorization") == "" { + writeJSON(w, 401, map[string]any{}) + return + } + f.mu.Lock() + defer f.mu.Unlock() + writeJSON(w, 200, map[string]any{"record": map[string]any{ + "id": orgTestUserID, "email": "owner@test.local", "name": "Owner", + "role": f.callerRole, "organization": f.callerOrg, + }}) + }) + + // Organization create / rename / delete. + mux.HandleFunc("POST /api/collections/organizations/records", func(w http.ResponseWriter, r *http.Request) { + var body map[string]any + _ = json.NewDecoder(r.Body).Decode(&body) + f.mu.Lock() + f.createdOrgs = append(f.createdOrgs, orgTestNewID) + f.mu.Unlock() + writeJSON(w, 200, map[string]any{"id": orgTestNewID, "name": body["name"], "created": "2026-08-17 10:00:00Z"}) + }) + mux.HandleFunc("PATCH /api/collections/organizations/records/{id}", func(w http.ResponseWriter, r *http.Request) { + var body map[string]any + _ = json.NewDecoder(r.Body).Decode(&body) + f.mu.Lock() + f.orgPatches = append(f.orgPatches, body) + f.mu.Unlock() + writeJSON(w, 200, map[string]any{"id": r.PathValue("id"), "name": body["name"]}) + }) + mux.HandleFunc("DELETE /api/collections/organizations/records/{id}", func(w http.ResponseWriter, r *http.Request) { + f.mu.Lock() + f.orgDeletes = append(f.orgDeletes, r.PathValue("id")) + f.mu.Unlock() + writeJSON(w, 204, nil) + }) + + // Blocking-member count for a delete. + mux.HandleFunc("GET /api/collections/users/records", func(w http.ResponseWriter, r *http.Request) { + f.mu.Lock() + defer f.mu.Unlock() + writeJSON(w, 200, map[string]any{"totalItems": f.memberCount, "items": []any{}}) + }) + + // Caller promotion / demotion. + mux.HandleFunc("PATCH /api/collections/users/records/{id}", func(w http.ResponseWriter, r *http.Request) { + var body map[string]any + _ = json.NewDecoder(r.Body).Decode(&body) + f.mu.Lock() + f.userPatches = append(f.userPatches, body) + status := f.userPatchStatus + f.mu.Unlock() + if status != 0 && status != 200 { + writeJSON(w, status, map[string]any{"message": "cannot update user"}) + return + } + writeJSON(w, 200, map[string]any{"id": r.PathValue("id")}) + }) + + return mux +} + +// newOrgTestServer wires the fake PocketBase to a real Handler and returns the +// app's base URL. +func newOrgTestServer(t *testing.T, f *orgFakePB) string { + t.Helper() + pbSrv := httptest.NewServer(f.handler(t)) + t.Cleanup(pbSrv.Close) + + s := New(config.Config{UsersCollection: "users"}, pb.New(pbSrv.URL, "admin@test.local", "pw")) + appSrv := httptest.NewServer(s.Handler()) + t.Cleanup(appSrv.Close) + return appSrv.URL +} + +// orgReq issues an authenticated request and returns the status and decoded body. +func orgReq(t *testing.T, base, method, path string, body any) (int, map[string]any) { + t.Helper() + var buf bytes.Buffer + if body != nil { + if err := json.NewEncoder(&buf).Encode(body); err != nil { + t.Fatal(err) + } + } + req, err := http.NewRequest(method, base+path, &buf) + if err != nil { + t.Fatal(err) + } + req.Header.Set("Authorization", "Bearer "+orgTestBearer) + req.Header.Set("Content-Type", "application/json") + resp, err := http.DefaultClient.Do(req) + if err != nil { + t.Fatal(err) + } + defer resp.Body.Close() + out := map[string]any{} + _ = json.NewDecoder(resp.Body).Decode(&out) + return resp.StatusCode, out +} + +func TestCreateOrgPromotesCreatorToAdmin(t *testing.T) { + f := &orgFakePB{callerRole: roleUser, callerOrg: ""} + base := newOrgTestServer(t, f) + + status, body := orgReq(t, base, http.MethodPost, "/api/orgs", map[string]any{"name": "Acme Inc."}) + if status != http.StatusCreated { + t.Fatalf("status = %d, want 201 (body %v)", status, body) + } + org, _ := body["organization"].(map[string]any) + if org["id"] != orgTestNewID || org["name"] != "Acme Inc." { + t.Fatalf("organization = %v, want id %q name %q", org, orgTestNewID, "Acme Inc.") + } + + if len(f.userPatches) != 1 { + t.Fatalf("user patches = %d, want 1 (%v)", len(f.userPatches), f.userPatches) + } + patch := f.userPatches[0] + if patch["organization"] != orgTestNewID { + t.Errorf("patched organization = %v, want %q", patch["organization"], orgTestNewID) + } + if patch["role"] != roleAdmin { + t.Errorf("patched role = %v, want %q", patch["role"], roleAdmin) + } + if len(f.orgDeletes) != 0 { + t.Errorf("org was rolled back unexpectedly: %v", f.orgDeletes) + } +} + +func TestCreateOrgRejectedWhenCallerAlreadyHasOne(t *testing.T) { + f := &orgFakePB{callerRole: roleUser, callerOrg: "existing1"} + base := newOrgTestServer(t, f) + + status, body := orgReq(t, base, http.MethodPost, "/api/orgs", map[string]any{"name": "Second Org"}) + if status != http.StatusForbidden { + t.Fatalf("status = %d, want 403 (body %v)", status, body) + } + if len(f.createdOrgs) != 0 { + t.Errorf("created orgs = %v, want none", f.createdOrgs) + } + if len(f.userPatches) != 0 { + t.Errorf("user patches = %v, want none", f.userPatches) + } +} + +// A superadmin manages every tenant centrally, so creating one must not move +// them into it or change their role. +func TestCreateOrgLeavesSuperadminUnattached(t *testing.T) { + f := &orgFakePB{callerRole: roleSuperadmin, callerOrg: ""} + base := newOrgTestServer(t, f) + + status, body := orgReq(t, base, http.MethodPost, "/api/orgs", map[string]any{"name": "Tenant A"}) + if status != http.StatusCreated { + t.Fatalf("status = %d, want 201 (body %v)", status, body) + } + if len(f.userPatches) != 0 { + t.Errorf("user patches = %v, want none for a superadmin", f.userPatches) + } +} + +// If the creator cannot be promoted, the new org must not survive — otherwise it +// is stranded with nobody able to administer it. +func TestCreateOrgRollsBackWhenPromotionFails(t *testing.T) { + f := &orgFakePB{callerRole: roleUser, callerOrg: "", userPatchStatus: http.StatusBadRequest} + base := newOrgTestServer(t, f) + + status, _ := orgReq(t, base, http.MethodPost, "/api/orgs", map[string]any{"name": "Doomed"}) + if status == http.StatusCreated { + t.Fatalf("status = %d, want a failure", status) + } + if len(f.orgDeletes) != 1 || f.orgDeletes[0] != orgTestNewID { + t.Errorf("org deletes = %v, want rollback of %q", f.orgDeletes, orgTestNewID) + } +} + +func TestCreateOrgRejectsBadName(t *testing.T) { + f := &orgFakePB{callerRole: roleUser, callerOrg: ""} + base := newOrgTestServer(t, f) + + status, _ := orgReq(t, base, http.MethodPost, "/api/orgs", map[string]any{"name": " "}) + if status != http.StatusBadRequest { + t.Fatalf("status = %d, want 400", status) + } + if len(f.createdOrgs) != 0 { + t.Errorf("created orgs = %v, want none", f.createdOrgs) + } +} + +func TestUpdateOrgAdminScopedToOwnOrg(t *testing.T) { + f := &orgFakePB{callerRole: roleAdmin, callerOrg: "o1"} + base := newOrgTestServer(t, f) + + // Someone else's organization is off limits. + status, _ := orgReq(t, base, http.MethodPatch, "/api/orgs/o2", map[string]any{"name": "Hijack"}) + if status != http.StatusForbidden { + t.Fatalf("foreign org status = %d, want 403", status) + } + if len(f.orgPatches) != 0 { + t.Fatalf("org patches = %v, want none", f.orgPatches) + } + + // Their own is fine. + status, body := orgReq(t, base, http.MethodPatch, "/api/orgs/o1", map[string]any{"name": "Renamed"}) + if status != http.StatusOK { + t.Fatalf("own org status = %d, want 200 (body %v)", status, body) + } + if len(f.orgPatches) != 1 || f.orgPatches[0]["name"] != "Renamed" { + t.Errorf("org patches = %v, want one rename to %q", f.orgPatches, "Renamed") + } +} + +// An admin deleting their own org is detached and demoted first, so the org is +// empty by the time it is removed. +func TestDeleteOrgAdminSoleMemberIsDetachedAndDemoted(t *testing.T) { + f := &orgFakePB{callerRole: roleAdmin, callerOrg: "o1", memberCount: 0} + base := newOrgTestServer(t, f) + + status, body := orgReq(t, base, http.MethodDelete, "/api/orgs/o1", nil) + if status != http.StatusOK { + t.Fatalf("status = %d, want 200 (body %v)", status, body) + } + if len(f.userPatches) != 1 { + t.Fatalf("user patches = %d, want 1 (%v)", len(f.userPatches), f.userPatches) + } + patch := f.userPatches[0] + if patch["organization"] != "" { + t.Errorf("patched organization = %v, want cleared", patch["organization"]) + } + if patch["role"] != roleUser { + t.Errorf("patched role = %v, want %q", patch["role"], roleUser) + } + if len(f.orgDeletes) != 1 || f.orgDeletes[0] != "o1" { + t.Errorf("org deletes = %v, want [o1]", f.orgDeletes) + } +} + +func TestDeleteOrgBlockedByOtherMembers(t *testing.T) { + f := &orgFakePB{callerRole: roleAdmin, callerOrg: "o1", memberCount: 2} + base := newOrgTestServer(t, f) + + status, _ := orgReq(t, base, http.MethodDelete, "/api/orgs/o1", nil) + if status != http.StatusConflict { + t.Fatalf("status = %d, want 409", status) + } + if len(f.orgDeletes) != 0 { + t.Errorf("org deletes = %v, want none", f.orgDeletes) + } + if len(f.userPatches) != 0 { + t.Errorf("user patches = %v, want none — the admin must stay put", f.userPatches) + } +} + +func TestDeleteOrgAdminCannotDeleteForeignOrg(t *testing.T) { + f := &orgFakePB{callerRole: roleAdmin, callerOrg: "o1"} + base := newOrgTestServer(t, f) + + status, _ := orgReq(t, base, http.MethodDelete, "/api/orgs/o2", nil) + if status != http.StatusForbidden { + t.Fatalf("status = %d, want 403", status) + } + if len(f.orgDeletes) != 0 { + t.Errorf("org deletes = %v, want none", f.orgDeletes) + } +} + +// A plain user is not a manager, so rename/delete stay closed to them even for +// the org they belong to. +func TestPlainUserCannotManageOrgs(t *testing.T) { + f := &orgFakePB{callerRole: roleUser, callerOrg: "o1"} + base := newOrgTestServer(t, f) + + if status, _ := orgReq(t, base, http.MethodPatch, "/api/orgs/o1", map[string]any{"name": "Nope"}); status != http.StatusForbidden { + t.Errorf("rename status = %d, want 403", status) + } + if status, _ := orgReq(t, base, http.MethodDelete, "/api/orgs/o1", nil); status != http.StatusForbidden { + t.Errorf("delete status = %d, want 403", status) + } +} diff --git a/API Server/internal/api/server.go b/API Server/internal/api/server.go index 6742d93..144fc49 100644 --- a/API Server/internal/api/server.go +++ b/API Server/internal/api/server.go @@ -28,7 +28,7 @@ // GET /api/me/export POST /api/me/import // POST /api/me/delete POST /api/me/delete/cancel // -// # users + organizations (manager; writes to orgs are superadmin-only) +// # users + organizations (manager; POST /api/orgs is open to any user) // GET /api/users POST /api/users // PATCH /api/users/{id} DELETE /api/users/{id} // GET /api/orgs POST /api/orgs @@ -285,12 +285,15 @@ func (s *Server) Handler() http.Handler { mux.HandleFunc("PATCH /api/users/{id}", s.requireManager(s.handleUpdateUser)) mux.HandleFunc("DELETE /api/users/{id}", s.requireManager(s.handleDeleteUser)) - // Organizations — listing is manager-scoped; create/edit/delete are - // superadmin-only (a superadmin spans all organizations). + // Organizations — the tenants users belong to. Listing is manager-scoped (an + // admin sees only their own org). Any org-less user may create an org and + // becomes its admin; an admin may rename or delete their own org; a superadmin + // spans every organization. Create carries no role gate, so it checks the + // service account itself. mux.HandleFunc("GET /api/orgs", s.requireManager(s.handleListOrgs)) - mux.HandleFunc("POST /api/orgs", s.requireSuperadmin(s.handleCreateOrg)) - mux.HandleFunc("PATCH /api/orgs/{id}", s.requireSuperadmin(s.handleUpdateOrg)) - mux.HandleFunc("DELETE /api/orgs/{id}", s.requireSuperadmin(s.handleDeleteOrg)) + mux.HandleFunc("POST /api/orgs", s.handleCreateOrg) + mux.HandleFunc("PATCH /api/orgs/{id}", s.requireManager(s.handleUpdateOrg)) + mux.HandleFunc("DELETE /api/orgs/{id}", s.requireManager(s.handleDeleteOrg)) // PocketBase connection settings — superadmin only. These do NOT require the // service account to already be configured (they exist to configure it). diff --git a/API Server/internal/models/models.go b/API Server/internal/models/models.go index 47f8407..bc1231b 100644 --- a/API Server/internal/models/models.go +++ b/API Server/internal/models/models.go @@ -335,6 +335,11 @@ type User struct { FontSize string `json:"fontSize"` // small | medium | large Role string `json:"role"` // user | admin + // Organization membership. Empty when the user belongs to no organization — + // the clients use that to offer creating one (which makes them its admin). + Organization string `json:"organization"` + OrganizationName string `json:"organizationName,omitempty"` + // Non-empty while an account-deletion request is pending its cooldown. DeletionRequestedAt *time.Time `json:"deletionRequestedAt,omitempty"` diff --git a/API Server/panel/src/App.vue b/API Server/panel/src/App.vue index 055ca68..9b17f0a 100644 --- a/API Server/panel/src/App.vue +++ b/API Server/panel/src/App.vue @@ -26,7 +26,14 @@ onMounted(async () => { const sections = computed(() => { const out = [{ id: "overview", label: t("sections.overview") }]; if (isManager.value) { - out.push({ id: "users", label: t("sections.users") }, { id: "orgs", label: t("sections.orgs") }); + out.push({ id: "users", label: t("sections.users") }); + } + // Organizations is open to everyone: a manager sees the org(s) they manage, + // and an org-less user gets the form that stands one up (making them its + // admin). Only a caller with neither an org nor a manager role sees nothing + // to do there, and they still get the create form. + if (isManager.value || me.value) { + out.push({ id: "orgs", label: t("sections.orgs") }); } if (isSuperadmin.value) { out.push( @@ -129,9 +136,9 @@ const managementApi = [ { 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 (superadmin)" }, - { method: "PATCH", path: "/api/orgs/{id}", desc: "Rename an organization (superadmin)" }, - { method: "DELETE", path: "/api/orgs/{id}", desc: "Delete an organization (superadmin)" }, + { 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)" }, ]; const superadminApi = [ diff --git a/API Server/panel/src/components/OrgsCard.vue b/API Server/panel/src/components/OrgsCard.vue index 7ae4227..7795d9e 100644 --- a/API Server/panel/src/components/OrgsCard.vue +++ b/API Server/panel/src/components/OrgsCard.vue @@ -1,17 +1,31 @@ + + diff --git a/Web App/web/src/i18n/da.json b/Web App/web/src/i18n/da.json index 5628a95..6524c8d 100644 --- a/Web App/web/src/i18n/da.json +++ b/Web App/web/src/i18n/da.json @@ -108,7 +108,7 @@ "title": "Brugere", "subtitleAll": "Konti på tværs af alle organisationer.", "subtitleOrg": "Konti i din organisation.", - "subtitleOrgsNote": "Organisationer tildeles i API-panelet.", + "subtitleOrgsNote": "Organisationer administreres under Indstillinger.", "addUser": "Tilføj bruger", "colEmail": "E-mail", "colName": "Navn", @@ -199,6 +199,23 @@ "saveBio": "Gem beskrivelse" }, + "org": { + "title": "Organisation", + "titleAll": "Organisationer", + "subtitleOwn": "Den organisation du administrerer", + "subtitleNone": "Opret en for at administrere dit eget team", + "subtitleAll": "Enheder, som brugere tilhører", + "nameLabel": "Organisationsnavn", + "namePlaceholder": "Acme Fleet", + "newOrg": "Ny organisation", + "create": "Opret organisation", + "createHint": "Du bliver dens administrator og kan derefter tilføje og administrere brugere.", + "rename": "Omdøb", + "empty": "Ingen organisationer endnu.", + "confirmDelete": "Slet organisationen „{name}“? Dette kan ikke fortrydes.", + "confirmDeleteOwn": "Slet din organisation „{name}“? Du fjernes fra den og bliver en almindelig bruger. Dette kan ikke fortrydes." + }, + "privacy": { "title": "Privatliv og sikkerhed", "signOut": "Log ud", diff --git a/Web App/web/src/i18n/en.json b/Web App/web/src/i18n/en.json index 544329e..75d7fbf 100644 --- a/Web App/web/src/i18n/en.json +++ b/Web App/web/src/i18n/en.json @@ -126,7 +126,7 @@ "title": "Users", "subtitleAll": "Accounts across every organization.", "subtitleOrg": "Accounts in your organization.", - "subtitleOrgsNote": "Organizations are assigned in the API panel.", + "subtitleOrgsNote": "Organizations are managed in Settings.", "addUser": "Add user", "colEmail": "Email", "colName": "Name", @@ -274,6 +274,23 @@ "controlDisconnected": "Not connected" }, + "org": { + "title": "Organization", + "titleAll": "Organizations", + "subtitleOwn": "The organization you administer", + "subtitleNone": "Create one to manage your own team", + "subtitleAll": "Tenants users belong to", + "nameLabel": "Organization name", + "namePlaceholder": "Acme Fleet", + "newOrg": "New organization", + "create": "Create organization", + "createHint": "You'll become its admin and can then add and manage users.", + "rename": "Rename", + "empty": "No organizations yet.", + "confirmDelete": "Delete the organization “{name}”? This cannot be undone.", + "confirmDeleteOwn": "Delete your organization “{name}”? You'll be removed from it and become a regular user. This cannot be undone." + }, + "privacy": { "title": "Privacy & security", "signOut": "Sign out", diff --git a/Web App/web/src/i18n/pl.json b/Web App/web/src/i18n/pl.json index cc4c1be..d5eb4e1 100644 --- a/Web App/web/src/i18n/pl.json +++ b/Web App/web/src/i18n/pl.json @@ -112,7 +112,7 @@ "title": "Użytkownicy", "subtitleAll": "Konta ze wszystkich organizacji.", "subtitleOrg": "Konta w Twojej organizacji.", - "subtitleOrgsNote": "Organizacje przypisuje się w panelu API.", + "subtitleOrgsNote": "Organizacjami zarządza się w Ustawieniach.", "addUser": "Dodaj użytkownika", "colEmail": "E-mail", "colName": "Imię i nazwisko", @@ -203,6 +203,23 @@ "saveBio": "Zapisz opis" }, + "org": { + "title": "Organizacja", + "titleAll": "Organizacje", + "subtitleOwn": "Organizacja, którą administrujesz", + "subtitleNone": "Utwórz ją, aby zarządzać własnym zespołem", + "subtitleAll": "Podmioty, do których należą użytkownicy", + "nameLabel": "Nazwa organizacji", + "namePlaceholder": "Acme Fleet", + "newOrg": "Nowa organizacja", + "create": "Utwórz organizację", + "createHint": "Zostaniesz jej administratorem i będziesz móc dodawać użytkowników oraz nimi zarządzać.", + "rename": "Zmień nazwę", + "empty": "Brak organizacji.", + "confirmDelete": "Usunąć organizację „{name}”? Tego nie można cofnąć.", + "confirmDeleteOwn": "Usunąć Twoją organizację „{name}”? Zostaniesz z niej usunięty i staniesz się zwykłym użytkownikiem. Tego nie można cofnąć." + }, + "privacy": { "title": "Prywatność i bezpieczeństwo", "signOut": "Wyloguj się", diff --git a/Web App/web/src/views/Settings.vue b/Web App/web/src/views/Settings.vue index d123486..ab99d35 100644 --- a/Web App/web/src/views/Settings.vue +++ b/Web App/web/src/views/Settings.vue @@ -6,6 +6,7 @@ import { state, logout, refreshProfile } from "../auth"; import { prefs, applyProfilePrefs } from "../prefs"; import { formatDate, formatMoney } from "../lib/format.js"; import { t, tSplit, TRANSLATED_LANGUAGES } from "../i18n"; +import OrgManager from "../components/OrgManager.vue"; const router = useRouter(); @@ -1258,6 +1259,9 @@ onBeforeUnmount(() => {
+ + +