Add a Drones fleet section that fills itself in on connect

The fleet lived as a tab inside the Logbook, which buried it, and every
drone had to be typed in by hand — model, serial and firmware copied off
an airframe the app was already talking to.

Promote it to its own nav section above Logbook, and let a connecting
drone register itself. The Fly App already forwarded model, serial and
firmware upstream; the hub was keeping only the model. It now carries the
identity through to DeviceState, and the Web App offers it to a new
POST /api/drones/auto, which upserts keyed by serial. The auto path only
writes what the aircraft is authoritative about (model, both firmware
versions) and never touches what the pilot curates.

Serial and the firmware versions resolve on their own schedules after
connect — the serial in seconds, the aircraft firmware sometimes a minute
later — so nothing along the path treats an absent value as a cleared one,
and a later event filling firmware in still reaches the server. The auto
call rides every telemetry frame, so the client remembers the identity
tuple it last sent and only a change goes out; a 4xx is the server's
settled answer and is not retried, or one drone connected for an hour
would mean one request per frame for an hour.

New fields on drones: firmware, controller_firmware, and registration for
the FAA/CAA aircraft number — distinct from operator_number, which stays
the EU operator ID. Controller firmware is the remote controller's own
version, read from its component; the flight controller's version is a
different quantity and stays off this field (see 002e484). name becomes
optional and is now the pilot's custom name: auto-added drones arrive
unnamed, so the API serves a computed displayName (name, else model +
serial) for the fleet table, the flight picker and the CSV export. A
unique index on serial is what keeps the find-then-create path from
forking a drone's history across two records.

The schema is applied to the remote PocketBase; the migration is here for
fresh deployments, which the remote does not read.

Verified against a simulated device over the real socket with identity
resolving late: one record from four events, both firmware versions
filled, curated fields intact across re-registration, and a drone deleted
while connected coming back on the next frame.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
tajniak81andClaude Opus 4.8 committed 2026-07-16 17:04:12 +02:00
1 parent 3e066c0a99
commit 33595c99e8
19 files changed
+931 -426

No files matched your search

+9
View File
@@ -442,6 +442,15 @@ func (a *App) handleCreateDrone(w http.ResponseWriter, r *http.Request) {
a.doRelay(w, req)
}
// POST /bff/drones/auto → API Server /api/drones/auto
func (a *App) handleAutoDrone(w http.ResponseWriter, r *http.Request) {
body, _ := io.ReadAll(r.Body)
req, _ := http.NewRequest(http.MethodPost, a.apiBaseFor(r)+"/api/drones/auto", bytes.NewReader(body))
req.Header.Set("Authorization", tokenOf(r))
req.Header.Set("Content-Type", "application/json")
a.doRelay(w, req)
}
// PATCH /bff/drones/{id} → API Server /api/drones/{id}
func (a *App) handleUpdateDrone(w http.ResponseWriter, r *http.Request) {
id := r.PathValue("id")
-20
View File
@@ -1,20 +0,0 @@
(function(){const i=document.createElement("link").relList;if(i&&i.supports&&i.supports("modulepreload"))return;for(const u of document.querySelectorAll('link[rel="modulepreload"]'))l(u);new MutationObserver(u=>{for(const f of u)if(f.type==="childList")for(const h of f.addedNodes)h.tagName==="LINK"&&h.rel==="modulepreload"&&l(h)}).observe(document,{childList:!0,subtree:!0});function s(u){const f={};return u.integrity&&(f.integrity=u.integrity),u.referrerPolicy&&(f.referrerPolicy=u.referrerPolicy),u.crossOrigin==="use-credentials"?f.credentials="include":u.crossOrigin==="anonymous"?f.credentials="omit":f.credentials="same-origin",f}function l(u){if(u.ep)return;u.ep=!0;const f=s(u);fetch(u.href,f)}})();/**
* @vue/shared v3.5.39
* (c) 2018-present Yuxi (Evan) You and Vue contributors
* @license MIT
**/function Xr(t){const i=Object.create(null);for(const s of t.split(","))i[s]=1;return s=>s in i}const wt={},es=[],di=()=>{},Ou=()=>!1,ja=t=>t.charCodeAt(0)===111&&t.charCodeAt(1)===110&&(t.charCodeAt(2)>122||t.charCodeAt(2)<97),Wa=t=>t.startsWith("onUpdate:"),Ht=Object.assign,Qr=(t,i)=>{const s=t.indexOf(i);s>-1&&t.splice(s,1)},pd=Object.prototype.hasOwnProperty,vt=(t,i)=>pd.call(t,i),De=Array.isArray,ts=t=>ea(t)==="[object Map]",ls=t=>ea(t)==="[object Set]",Ll=t=>ea(t)==="[object Date]",Ge=t=>typeof t=="function",Ct=t=>typeof t=="string",ti=t=>typeof t=="symbol",_t=t=>t!==null&&typeof t=="object",zu=t=>(_t(t)||Ge(t))&&Ge(t.then)&&Ge(t.catch),Iu=Object.prototype.toString,ea=t=>Iu.call(t),md=t=>ea(t).slice(8,-1),$u=t=>ea(t)==="[object Object]",el=t=>Ct(t)&&t!=="NaN"&&t[0]!=="-"&&""+parseInt(t,10)===t,Rs=Xr(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),Ka=t=>{const i=Object.create(null);return(s=>i[s]||(i[s]=t(s)))},gd=/-\w/g,Qn=Ka(t=>t.replace(gd,i=>i.slice(1).toUpperCase())),vd=/\B([A-Z])/g,eo=Ka(t=>t.replace(vd,"-$1").toLowerCase()),Nu=Ka(t=>t.charAt(0).toUpperCase()+t.slice(1)),xr=Ka(t=>t?`on${Nu(t)}`:""),ci=(t,i)=>!Object.is(t,i),Ea=(t,...i)=>{for(let s=0;s<t.length;s++)t[s](...i)},Du=(t,i,s,l=!1)=>{Object.defineProperty(t,i,{configurable:!0,enumerable:!1,writable:l,value:s})},Ga=t=>{const i=parseFloat(t);return isNaN(i)?t:i},_d=t=>{const i=Ct(t)?Number(t):NaN;return isNaN(i)?t:i};let Al;const qa=()=>Al||(Al=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function Mo(t){if(De(t)){const i={};for(let s=0;s<t.length;s++){const l=t[s],u=Ct(l)?wd(l):Mo(l);if(u)for(const f in u)i[f]=u[f]}return i}else if(Ct(t)||_t(t))return t}const bd=/;(?![^(]*\))/g,yd=/:([^]+)/,xd=/\/\*[^]*?\*\//g;function wd(t){const i={};return t.replace(xd,"").split(bd).forEach(s=>{if(s){const l=s.split(yd);l.length>1&&(i[l[0].trim()]=l[1].trim())}}),i}function Ae(t){let i="";if(Ct(t))i=t;else if(De(t))for(let s=0;s<t.length;s++){const l=Ae(t[s]);l&&(i+=l+" ")}else if(_t(t))for(const s in t)t[s]&&(i+=s+" ");return i.trim()}const kd="itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly",Sd=Xr(kd);function Fu(t){return!!t||t===""}function Td(t,i){if(t.length!==i.length)return!1;let s=!0;for(let l=0;s&&l<t.length;l++)s=Ji(t[l],i[l]);return s}function Ji(t,i){if(t===i)return!0;let s=Ll(t),l=Ll(i);if(s||l)return s&&l?t.getTime()===i.getTime():!1;if(s=ti(t),l=ti(i),s||l)return t===i;if(s=De(t),l=De(i),s||l)return s&&l?Td(t,i):!1;if(s=_t(t),l=_t(i),s||l){if(!s||!l)return!1;const u=Object.keys(t).length,f=Object.keys(i).length;if(u!==f)return!1;for(const h in t){const _=t.hasOwnProperty(h),y=i.hasOwnProperty(h);if(_&&!y||!_&&y||!Ji(t[h],i[h]))return!1}}return String(t)===String(i)}function tl(t,i){return t.findIndex(s=>Ji(s,i))}const Ru=t=>!!(t&&t.__v_isRef===!0),w=t=>Ct(t)?t:t==null?"":De(t)||_t(t)&&(t.toString===Iu||!Ge(t.toString))?Ru(t)?w(t.value):JSON.stringify(t,Bu,2):String(t),Bu=(t,i)=>Ru(i)?Bu(t,i.value):ts(i)?{[`Map(${i.size})`]:[...i.entries()].reduce((s,[l,u],f)=>(s[wr(l,f)+" =>"]=u,s),{})}:ls(i)?{[`Set(${i.size})`]:[...i.values()].map(s=>wr(s))}:ti(i)?wr(i):_t(i)&&!De(i)&&!$u(i)?String(i):i,wr=(t,i="")=>{var s;return ti(t)?`Symbol(${(s=t.description)!=null?s:i})`:t};/**
* @vue/reactivity v3.5.39
* (c) 2018-present Yuxi (Evan) You and Vue contributors
* @license MIT
**/let Wt;class Pd{constructor(i=!1){this.detached=i,this._active=!0,this._on=0,this.effects=[],this.cleanups=[],this._isPaused=!1,this._warnOnRun=!0,this.__v_skip=!0,!i&&Wt&&(Wt.active?(this.parent=Wt,this.index=(Wt.scopes||(Wt.scopes=[])).push(this)-1):(this._active=!1,this._warnOnRun=!1))}get active(){return this._active}pause(){if(this._active){this._isPaused=!0;let i,s;if(this.scopes)for(i=0,s=this.scopes.length;i<s;i++)this.scopes[i].pause();for(i=0,s=this.effects.length;i<s;i++)this.effects[i].pause()}}resume(){if(this._active&&this._isPaused){this._isPaused=!1;let i,s;if(this.scopes)for(i=0,s=this.scopes.length;i<s;i++)this.scopes[i].resume();for(i=0,s=this.effects.length;i<s;i++)this.effects[i].resume()}}run(i){if(this._active){const s=Wt;try{return Wt=this,i()}finally{Wt=s}}}on(){++this._on===1&&(this.prevScope=Wt,Wt=this)}off(){if(this._on>0&&--this._on===0){if(Wt===this)Wt=this.prevScope;else{let i=Wt;for(;i;){if(i.prevScope===this){i.prevScope=this.prevScope;break}i=i.prevScope}}this.prevScope=void 0}}stop(i){if(this._active){this._active=!1;let s,l;for(s=0,l=this.effects.length;s<l;s++)this.effects[s].stop();for(this.effects.length=0,s=0,l=this.cleanups.length;s<l;s++)this.cleanups[s]();if(this.cleanups.length=0,this.scopes){for(s=0,l=this.scopes.length;s<l;s++)this.scopes[s].stop(!0);this.scopes.length=0}if(!this.detached&&this.parent&&!i){const u=this.parent.scopes.pop();u&&u!==this&&(this.parent.scopes[this.index]=u,u.index=this.index)}this.parent=void 0}}}function Cd(){return Wt}let St;const kr=new WeakSet;class Uu{constructor(i){this.fn=i,this.deps=void 0,this.depsTail=void 0,this.flags=5,this.next=void 0,this.cleanup=void 0,this.scheduler=void 0,Wt&&(Wt.active?Wt.effects.push(this):this.flags&=-2)}pause(){this.flags|=64}resume(){this.flags&64&&(this.flags&=-65,kr.has(this)&&(kr.delete(this),this.trigger()))}notify(){this.flags&2&&!(this.flags&32)||this.flags&8||Zu(this)}run(){if(!(this.flags&1))return this.fn();this.flags|=2,Ml(this),Hu(this);const i=St,s=ei;St=this,ei=!0;try{return this.fn()}finally{ju(this),St=i,ei=s,this.flags&=-3}}stop(){if(this.flags&1){for(let i=this.deps;i;i=i.nextDep)ol(i);this.deps=this.depsTail=void 0,Ml(this),this.onStop&&this.onStop(),this.flags&=-2}}trigger(){this.flags&64?kr.add(this):this.scheduler?this.scheduler():this.runIfDirty()}runIfDirty(){$r(this)&&this.run()}get dirty(){return $r(this)}}let Vu=0,Bs,Us;function Zu(t,i=!1){if(t.flags|=8,i){t.next=Us,Us=t;return}t.next=Bs,Bs=t}function nl(){Vu++}function il(){if(--Vu>0)return;if(Us){let i=Us;for(Us=void 0;i;){const s=i.next;i.next=void 0,i.flags&=-9,i=s}}let t;for(;Bs;){let i=Bs;for(Bs=void 0;i;){const s=i.next;if(i.next=void 0,i.flags&=-9,i.flags&1)try{i.trigger()}catch(l){t||(t=l)}i=s}}if(t)throw t}function Hu(t){for(let i=t.deps;i;i=i.nextDep)i.version=-1,i.prevActiveLink=i.dep.activeLink,i.dep.activeLink=i}function ju(t){let i,s=t.depsTail,l=s;for(;l;){const u=l.prevDep;l.version===-1?(l===s&&(s=u),ol(l),Ld(l)):i=l,l.dep.activeLink=l.prevActiveLink,l.prevActiveLink=void 0,l=u}t.deps=i,t.depsTail=s}function $r(t){for(let i=t.deps;i;i=i.nextDep)if(i.dep.version!==i.version||i.dep.computed&&(Wu(i.dep.computed)||i.dep.version!==i.version))return!0;return!!t._dirty}function Wu(t){if(t.flags&4&&!(t.flags&16)||(t.flags&=-17,t.globalVersion===Ws)||(t.globalVersion=Ws,!t.isSSR&&t.flags&128&&(!t.deps&&!t._dirty||!$r(t))))return;t.flags|=2;const i=t.dep,s=St,l=ei;St=t,ei=!0;try{Hu(t);const u=t.fn(t._value);(i.version===0||ci(u,t._value))&&(t.flags|=128,t._value=u,i.version++)}catch(u){throw i.version++,u}finally{St=s,ei=l,ju(t),t.flags&=-3}}function ol(t,i=!1){const{dep:s,prevSub:l,nextSub:u}=t;if(l&&(l.nextSub=u,t.prevSub=void 0),u&&(u.prevSub=l,t.nextSub=void 0),s.subs===t&&(s.subs=l,!l&&s.computed)){s.computed.flags&=-5;for(let f=s.computed.deps;f;f=f.nextDep)ol(f,!0)}!i&&!--s.sc&&s.map&&s.map.delete(s.key)}function Ld(t){const{prevDep:i,nextDep:s}=t;i&&(i.nextDep=s,t.prevDep=void 0),s&&(s.prevDep=i,t.nextDep=void 0)}let ei=!0;const Ku=[];function fi(){Ku.push(ei),ei=!1}function hi(){const t=Ku.pop();ei=t===void 0?!0:t}function Ml(t){const{cleanup:i}=t;if(t.cleanup=void 0,i){const s=St;St=void 0;try{i()}finally{St=s}}}let Ws=0;class Ad{constructor(i,s){this.sub=i,this.dep=s,this.version=s.version,this.nextDep=this.prevDep=this.nextSub=this.prevSub=this.prevActiveLink=void 0}}class sl{constructor(i){this.computed=i,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(i){if(!St||!ei||St===this.computed)return;let s=this.activeLink;if(s===void 0||s.sub!==St)s=this.activeLink=new Ad(St,this),St.deps?(s.prevDep=St.depsTail,St.depsTail.nextDep=s,St.depsTail=s):St.deps=St.depsTail=s,Gu(s);else if(s.version===-1&&(s.version=this.version,s.nextDep)){const l=s.nextDep;l.prevDep=s.prevDep,s.prevDep&&(s.prevDep.nextDep=l),s.prevDep=St.depsTail,s.nextDep=void 0,St.depsTail.nextDep=s,St.depsTail=s,St.deps===s&&(St.deps=l)}return s}trigger(i){this.versiLine truncated
* @vue/runtime-core v3.5.39
* (c) 2018-present Yuxi (Evan) You and Vue contributors
* @license MIT
**/function ta(t,i,s,l){try{return l?t(...l):t()}catch(u){Ja(u,i,s)}}function Wn(t,i,s,l){if(Ge(t)){const u=ta(t,i,s,l);return u&&zu(u)&&u.catch(f=>{Ja(f,i,s)}),u}if(De(t)){const u=[];for(let f=0;f<t.length;f++)u.push(Wn(t[f],i,s,l));return u}}function Ja(t,i,s,l=!0){const u=i?i.vnode:null,{errorHandler:f,throwUnhandledErrorInProduction:h}=i&&i.appContext.config||wt;if(i){let _=i.parent;const y=i.proxy,C=`https://vuejs.org/error-reference/#runtime-${s}`;for(;_;){const T=_.ec;if(T){for(let M=0;M<T.length;M++)if(T[M](t,y,C)===!1)return}_=_.parent}if(f){fi(),ta(f,null,10,[t,y,C]),hi();return}}ef(t,s,u,l,h)}function ef(t,i,s,l=!0,u=!1){if(u)throw t;console.error(t)}const fn=[];let ri=-1;const ns=[];let Yi=null,Qo=0;const nc=Promise.resolve();let Ia=null;function ic(t){const i=Ia||nc;return t?i.then(this?t.bind(this):t):i}function tf(t){let i=ri+1,s=fn.length;for(;i<s;){const l=i+s>>>1,u=fn[l],f=Gs(u);f<t||f===t&&u.flags&2?i=l+1:s=l}return i}function ul(t){if(!(t.flags&1)){const i=Gs(t),s=fn[fn.length-1];!s||!(t.flags&2)&&i>=Gs(s)?fn.push(t):fn.splice(tf(i),0,t),t.flags|=1,oc()}}function oc(){Ia||(Ia=nc.then(ac))}function nf(t){De(t)?ns.push(...t):Yi&&t.id===-1?Yi.splice(Qo+1,0,t):t.flags&1||(ns.push(t),t.flags|=1),oc()}function Ol(t,i,s=ri+1){for(;s<fn.length;s++){const l=fn[s];if(l&&l.flags&2){if(t&&l.id!==t.uid)continue;fn.splice(s,1),s--,l.flags&4&&(l.flags&=-2),l(),l.flags&4||(l.flags&=-2)}}}function sc(t){if(ns.length){const i=[...new Set(ns)].sort((s,l)=>Gs(s)-Gs(l));if(ns.length=0,Yi){Yi.push(...i);return}for(Yi=i,Qo=0;Qo<Yi.length;Qo++){const s=Yi[Qo];s.flags&4&&(s.flags&=-2),s.flags&8||s(),s.flags&=-2}Yi=null,Qo=0}}const Gs=t=>t.id==null?t.flags&2?-1:1/0:t.id;function ac(t){try{for(ri=0;ri<fn.length;ri++){const i=fn[ri];i&&!(i.flags&8)&&(i.flags&4&&(i.flags&=-2),ta(i,i.i,i.i?15:14),i.flags&4||(i.flags&=-2))}}finally{for(;ri<fn.length;ri++){const i=fn[ri];i&&(i.flags&=-2)}ri=-1,fn.length=0,sc(),Ia=null,(fn.length||ns.length)&&ac()}}let on=null,rc=null;function $a(t){const i=on;return on=t,rc=t&&t.type.__scopeId||null,i}function xe(t,i=on,s){if(!i||t._n)return t;const l=(...u)=>{l._d&&Fa(-1);const f=$a(i);let h;try{h=t(...u)}finally{$a(f),l._d&&Fa(1)}return h};return l._n=!0,l._c=!0,l._d=!0,l}function Q(t,i){if(on===null)return t;const s=nr(on),l=t.dirs||(t.dirs=[]);for(let u=0;u<i.length;u++){let[f,h,_,y=wt]=i[u];f&&(Ge(f)&&(f={mounted:f,updated:f}),f.deep&&Li(h),l.push({dir:f,instance:s,value:h,oldValue:void 0,arg:_,modifiers:y}))}return t}function xo(t,i,s,l){const u=t.dirs,f=i&&i.dirs;for(let h=0;h<u.length;h++){const _=u[h];f&&(_.oldValue=f[h].value);let y=_.dir[l];y&&(fi(),Wn(y,s,8,[t.el,_,t,i]),hi())}}function lc(t,i){if(hn){let s=hn.provides;const l=hn.parent&&hn.parent.provides;l===s&&(s=hn.provides=Object.create(l)),s[t]=i}}function Vs(t,i,s=!1){const l=Bc();if(l||os){let u=os?os._context.provides:l?l.parent==null||l.ce?l.vnode.appContext&&l.vnode.appContext.provides:l.parent.provides:void 0;if(u&&t in u)return u[t];if(arguments.length>1)return s&&Ge(i)?i.call(l&&l.proxy):i}}const of=Symbol.for("v-scx"),sf=()=>Vs(of);function Rt(t,i,s){return uc(t,i,s)}function uc(t,i,s=wt){const{immediate:l,deep:u,flush:f,once:h}=s,_=Ht({},s),y=i&&l||!i&&f!=="post";let C;if(Xs){if(f==="sync"){const V=sf();C=V.__watcherHandles||(V.__watcherHandles=[])}else if(!y){const V=()=>{};return V.stop=di,V.resume=di,V.pause=di,V}}const T=hn;_.call=(V,K,F)=>Wn(V,T,K,F);let M=!1;f==="post"?_.scheduler=V=>{dn(V,T&&T.suspense)}:f!=="sync"&&(M=!0,_.scheduler=(V,K)=>{K?V():ul(V)}),_.augmentJob=V=>{i&&(V.flags|=4),M&&(V.flags|=2,T&&(V.id=T.uid,V.i=T))};const U=Qd(t,i,_);return Xs&&(C?C.push(U):y&&U()),U}function af(t,i,s){const l=this.proxy,u=Ct(t)?t.includes(".")?cc(l,t):()=>l[t]:t.bind(l,l);let f;Ge(i)?f=i:(f=i.handler,s=i);const h=na(this),_=uc(u,f.bind(l),s);return h(),_}function cc(t,i){const s=i.split(".");return()=>{let l=t;for(let u=0;u<s.length&&l;u++)l=l[s[u]];return l}}const qi=new WeakMap,dc=Symbol("_vte"),fc=t=>t.__isTeleport,Po=t=>t&&(t.disabled||t.disabled===""),rf=t=>t&&(t.defer||t.defer===""),zl=t=>typeof SVGElement<"u"&&t instanceof SVGElement,Il=t=>typeof MathMLElement=="function"&&t instanceof MathMLElement,Br=(t,i)=>{const s=t&&t.to;return Ct(s)?i?i(s):null:s},lf={name:"Teleport",__isTeleport:!0,process(t,i,s,l,u,f,h,_,y,C){const{mc:T,pc:M,pbc:U,o:{insert:V,querySelector:K,createText:F,createComment:me,parentNode:he}}=C,Y=Po(i.props);let{dynamicChildren:Le}=i;const ce=(ze,We,we)=>{ze.shapeFlag&16&&T(ze.children,We,we,u,f,h,_,y)},Be=(ze=i)=>{const We=Po(ze.props),we=ze.target=Br(ze.props,K),le=Ur(we,ze,F,V);we&&(h!=="svg"&&zl(we)?h="svg":h!=="mathml"&&Il(we)&&(h="mathml"),u&&u.isCE&&(u.ce._teleportTargets||(u.ce._teleportTargets=new Set)).add(we),We||(ce(ze,we,le),$s(ze,!1)))},Ne=ze=>{const We=()=>{if(qi.get(ze)===We){if(qi.delete(ze),Po(ze.props)){const we=he(ze.el)||s;ce(ze,we,ze.anchor),$s(ze,!0)}Be(ze)}};qi.set(ze,We),dn(We,f)};if(t==null){const ze=i.el=F(""),We=i.anchor=F("");if(V(ze,s,l),V(We,s,l),rf( Line truncated
* @vue/runtime-dom v3.5.39
* (c) 2018-present Yuxi (Evan) You and Vue contributors
* @license MIT
**/let Gr;const Gl=typeof window<"u"&&window.trustedTypes;if(Gl)try{Gr=Gl.createPolicy("vue",{createHTML:t=>t})}catch{}const Zc=Gr?t=>Gr.createHTML(t):t=>t,fh="http://www.w3.org/2000/svg",hh="http://www.w3.org/1998/Math/MathML",Ti=typeof document<"u"?document:null,ql=Ti&&Ti.createElement("template"),ph={insert:(t,i,s)=>{i.insertBefore(t,s||null)},remove:t=>{const i=t.parentNode;i&&i.removeChild(t)},createElement:(t,i,s,l)=>{const u=i==="svg"?Ti.createElementNS(fh,t):i==="mathml"?Ti.createElementNS(hh,t):s?Ti.createElement(t,{is:s}):Ti.createElement(t);return t==="select"&&l&&l.multiple!=null&&u.setAttribute("multiple",l.multiple),u},createText:t=>Ti.createTextNode(t),createComment:t=>Ti.createComment(t),setText:(t,i)=>{t.nodeValue=i},setElementText:(t,i)=>{t.textContent=i},parentNode:t=>t.parentNode,nextSibling:t=>t.nextSibling,querySelector:t=>Ti.querySelector(t),setScopeId(t,i){t.setAttribute(i,"")},insertStaticContent(t,i,s,l,u,f){const h=s?s.previousSibling:i.lastChild;if(u&&(u===f||u.nextSibling))for(;i.insertBefore(u.cloneNode(!0),s),!(u===f||!(u=u.nextSibling)););else{ql.innerHTML=Zc(l==="svg"?`<svg>${t}</svg>`:l==="mathml"?`<math>${t}</math>`:t);const _=ql.content;if(l==="svg"||l==="mathml"){const y=_.firstChild;for(;y.firstChild;)_.appendChild(y.firstChild);_.removeChild(y)}i.insertBefore(_,s)}return[h?h.nextSibling:i.firstChild,s?s.previousSibling:i.lastChild]}},Ki="transition",zs="animation",Qs=Symbol("_vtc"),Hc={name:String,type:String,css:{type:Boolean,default:!0},duration:[String,Number,Object],enterFromClass:String,enterActiveClass:String,enterToClass:String,appearFromClass:String,appearActiveClass:String,appearToClass:String,leaveFromClass:String,leaveActiveClass:String,leaveToClass:String},mh=Ht({},hc,Hc),gh=t=>(t.displayName="Transition",t.props=mh,t),vh=gh((t,{slots:i})=>ch(hf,_h(t),i)),ko=(t,i=[])=>{De(t)?t.forEach(s=>s(...i)):t&&t(...i)},Yl=t=>t?De(t)?t.some(i=>i.length>1):t.length>1:!1;function _h(t){const i={};for(const ie in t)ie in Hc||(i[ie]=t[ie]);if(t.css===!1)return i;const{name:s="v",type:l,duration:u,enterFromClass:f=`${s}-enter-from`,enterActiveClass:h=`${s}-enter-active`,enterToClass:_=`${s}-enter-to`,appearFromClass:y=f,appearActiveClass:C=h,appearToClass:T=_,leaveFromClass:M=`${s}-leave-from`,leaveActiveClass:U=`${s}-leave-active`,leaveToClass:V=`${s}-leave-to`}=t,K=bh(u),F=K&&K[0],me=K&&K[1],{onBeforeEnter:he,onEnter:Y,onEnterCancelled:Le,onLeave:ce,onLeaveCancelled:Be,onBeforeAppear:Ne=he,onAppear:ze=Y,onAppearCancelled:We=Le}=i,we=(ie,Ke,re,qe)=>{ie._enterCancelled=qe,So(ie,Ke?T:_),So(ie,Ke?C:h),re&&re()},le=(ie,Ke)=>{ie._isLeaving=!1,So(ie,M),So(ie,V),So(ie,U),Ke&&Ke()},Me=ie=>(Ke,re)=>{const qe=ie?ze:Y,fe=()=>we(Ke,ie,re);ko(qe,[Ke,fe]),Jl(()=>{So(Ke,ie?y:f),Si(Ke,ie?T:_),Yl(qe)||Xl(Ke,l,F,fe)})};return Ht(i,{onBeforeEnter(ie){ko(he,[ie]),Si(ie,f),Si(ie,h)},onBeforeAppear(ie){ko(Ne,[ie]),Si(ie,y),Si(ie,C)},onEnter:Me(!1),onAppear:Me(!0),onLeave(ie,Ke){ie._isLeaving=!0;const re=()=>le(ie,Ke);Si(ie,M),ie._enterCancelled?(Si(ie,U),tu(ie)):(tu(ie),Si(ie,U)),Jl(()=>{ie._isLeaving&&(So(ie,M),Si(ie,V),Yl(ce)||Xl(ie,l,me,re))}),ko(ce,[ie,re])},onEnterCancelled(ie){we(ie,!1,void 0,!0),ko(Le,[ie])},onAppearCancelled(ie){we(ie,!0,void 0,!0),ko(We,[ie])},onLeaveCancelled(ie){le(ie),ko(Be,[ie])}})}function bh(t){if(t==null)return null;if(_t(t))return[Mr(t.enter),Mr(t.leave)];{const i=Mr(t);return[i,i]}}function Mr(t){return _d(t)}function Si(t,i){i.split(/\s+/).forEach(s=>s&&t.classList.add(s)),(t[Qs]||(t[Qs]=new Set)).add(i)}function So(t,i){i.split(/\s+/).forEach(l=>l&&t.classList.remove(l));const s=t[Qs];s&&(s.delete(i),s.size||(t[Qs]=void 0))}function Jl(t){requestAnimationFrame(()=>{requestAnimationFrame(t)})}let yh=0;function Xl(t,i,s,l){const u=t._endId=++yh,f=()=>{u===t._endId&&l()};if(s!=null)return setTimeout(f,s);const{type:h,timeout:_,propCount:y}=xh(t,i);if(!h)return l();const C=h+"end";let T=0;const M=()=>{t.removeEventListener(C,U),f()},U=V=>{V.target===t&&++T>=y&&M()};setTimeout(()=>{T<y&&M()},_+1),t.addEventListener(C,U)}function xh(t,i){const s=window.getComputedStyle(t),l=K=>(s[K]||"").split(", "),u=l(`${Ki}Delay`),f=l(`${Ki}Duration`),h=Ql(u,f),_=l(`${zs}Delay`),y=l(`${zs}Duration`),C=Ql(_,y);let T=null,M=0,U=0;i===Ki?h>0&&(T=Ki,M=h,U=f.length):i===zs?C>0&&(T=zs,M=C,U=y.length):(M=Math.max(h,C),T=M>0?h>C?Ki:zs:null,U=T?T===Ki?f.length:y.length:0);const V=T===Ki&&/\b(?:transform|all)(?:,|$)/.test(l(`${Ki}Property`).toString());return{type:T,timeout:M,propCount:U,hasTransform:V}}function Ql(t,i){for(;t.length<i.length;)t=t.concat(t);return Math.max(...i.map((s,l)=>eu(s)+eu(t[l])))}function eu(t){return t==="auto"?0:Number(t.slice(0,-1).replace(",","."))*1e3}function tu(t){return(t?t.ownerDocument:document).body.offsetHeight}function wh(t,i,s){const l=t[Qs];l&&(i=(i?[i,...l]:[...l]).join(" ")),i==null?t.removeAttribute("class"):s?t.setAttribute("class",i):t.className=i}const Ua=Symbol("_vod"),jc=Symbol("_vsh"),kh={name:"show",beforeMount(t,{value:i},{transition:s Line truncated
* Leaflet 1.9.4, a JS library for interactive maps. https://leafletjs.com
* (c) 2010-2023 Vladimir Agafonkin, (c) 2010-2011 CloudMade
*/var lm=Fs.exports,Tu;function um(){return Tu||(Tu=1,(function(t,i){(function(s,l){l(i)})(lm,(function(s){var l="1.9.4";function u(e){var n,o,r,d;for(o=1,r=arguments.length;o<r;o++){d=arguments[o];for(n in d)e[n]=d[n]}return e}var f=Object.create||(function(){function e(){}return function(n){return e.prototype=n,new e}})();function h(e,n){var o=Array.prototype.slice;if(e.bind)return e.bind.apply(e,o.call(arguments,1));var r=o.call(arguments,2);return function(){return e.apply(n,r.length?r.concat(o.call(arguments)):arguments)}}var _=0;function y(e){return"_leaflet_id"in e||(e._leaflet_id=++_),e._leaflet_id}function C(e,n,o){var r,d,v,P;return P=function(){r=!1,d&&(v.apply(o,d),d=!1)},v=function(){r?d=arguments:(e.apply(o,arguments),setTimeout(P,n),r=!0)},v}function T(e,n,o){var r=n[1],d=n[0],v=r-d;return e===r&&o?e:((e-d)%v+v)%v+d}function M(){return!1}function U(e,n){if(n===!1)return e;var o=Math.pow(10,n===void 0?6:n);return Math.round(e*o)/o}function V(e){return e.trim?e.trim():e.replace(/^\s+|\s+$/g,"")}function K(e){return V(e).split(/\s+/)}function F(e,n){Object.prototype.hasOwnProperty.call(e,"options")||(e.options=e.options?f(e.options):{});for(var o in n)e.options[o]=n[o];return e.options}function me(e,n,o){var r=[];for(var d in e)r.push(encodeURIComponent(o?d.toUpperCase():d)+"="+encodeURIComponent(e[d]));return(!n||n.indexOf("?")===-1?"?":"&")+r.join("&")}var he=/\{ *([\w_ -]+) *\}/g;function Y(e,n){return e.replace(he,function(o,r){var d=n[r];if(d===void 0)throw new Error("No value provided for variable "+o);return typeof d=="function"&&(d=d(n)),d})}var Le=Array.isArray||function(e){return Object.prototype.toString.call(e)==="[object Array]"};function ce(e,n){for(var o=0;o<e.length;o++)if(e[o]===n)return o;return-1}var Be="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=";function Ne(e){return window["webkit"+e]||window["moz"+e]||window["ms"+e]}var ze=0;function We(e){var n=+new Date,o=Math.max(0,16-(n-ze));return ze=n+o,window.setTimeout(e,o)}var we=window.requestAnimationFrame||Ne("RequestAnimationFrame")||We,le=window.cancelAnimationFrame||Ne("CancelAnimationFrame")||Ne("CancelRequestAnimationFrame")||function(e){window.clearTimeout(e)};function Me(e,n,o){if(o&&we===We)e.call(n);else return we.call(window,h(e,n))}function ie(e){e&&le.call(window,e)}var Ke={__proto__:null,extend:u,create:f,bind:h,get lastId(){return _},stamp:y,throttle:C,wrapNum:T,falseFn:M,formatNum:U,trim:V,splitWords:K,setOptions:F,getParamString:me,template:Y,isArray:Le,indexOf:ce,emptyImageUrl:Be,requestFn:we,cancelFn:le,requestAnimFrame:Me,cancelAnimFrame:ie};function re(){}re.extend=function(e){var n=function(){F(this),this.initialize&&this.initialize.apply(this,arguments),this.callInitHooks()},o=n.__super__=this.prototype,r=f(o);r.constructor=n,n.prototype=r;for(var d in this)Object.prototype.hasOwnProperty.call(this,d)&&d!=="prototype"&&d!=="__super__"&&(n[d]=this[d]);return e.statics&&u(n,e.statics),e.includes&&(qe(e.includes),u.apply(null,[r].concat(e.includes))),u(r,e),delete r.statics,delete r.includes,r.options&&(r.options=o.options?f(o.options):{},u(r.options,e.options)),r._initHooks=[],r.callInitHooks=function(){if(!this._initHooksCalled){o.callInitHooks&&o.callInitHooks.call(this),this._initHooksCalled=!0;for(var v=0,P=r._initHooks.length;v<P;v++)r._initHooks[v].call(this)}},n},re.include=function(e){var n=this.prototype.options;return u(this.prototype,e),e.options&&(this.prototype.options=n,this.mergeOptions(e.options)),this},re.mergeOptions=function(e){return u(this.prototype.options,e),this},re.addInitHook=function(e){var n=Array.prototype.slice.call(arguments,1),o=typeof e=="function"?e:function(){this[e].apply(this,n)};return this.prototype._initHooks=this.prototype._initHooks||[],this.prototype._initHooks.push(o),this};function qe(e){if(!(typeof L>"u"||!L||!L.Mixin)){e=Le(e)?e:[e];for(var n=0;n<e.length;n++)e[n]===L.Mixin.Events&&console.warn("Deprecated include of L.Mixin.Events: this property will be removed in future releases, please inherit from L.Evented instead.",new Error().stack)}}var fe={on:function(e,n,o){if(typeof e=="object")for(var r in e)this._on(r,e[r],n);else{e=K(e);for(var d=0,v=e.length;d<v;d++)this._on(e[d],n,o)}return this},off:function(e,n,o){if(!arguments.length)delete this._events;else if(typeof e=="object")for(var r in e)this._off(r,e[r],n);else{e=K(e);for(var d=arguments.length===1,v=0,P=e.length;v<P;v++)d?this._off(e[v]):this._off(e[v],n,o)}return this},_on:function(e,n,o,r){if(typeof n!="function"){console.warn("wrong listener type: "+typeof n);return}if(this._listens(e,n,o)===!1){o===this&&(o=void 0);var d={fn:n,ctx:o};r&&(d.once=!0),this._events=this._events||{},this._events[e]=this._events[e]||[],this._events[e].push(d)}},_off:function(e,n,o){var r,d,v;if(this._events&&(r=this._events[e],!!r)){if(arguments.length===1){if(this._firingCount)for(d=0,v=r.length;d<v;d++)r[d].fn=M;delete this._events[e];return}if(typeof n!="function"){console.warn("wrong listener type:Line truncated
+20
View File
@@ -0,0 +1,20 @@
(function(){const i=document.createElement("link").relList;if(i&&i.supports&&i.supports("modulepreload"))return;for(const u of document.querySelectorAll('link[rel="modulepreload"]'))l(u);new MutationObserver(u=>{for(const f of u)if(f.type==="childList")for(const h of f.addedNodes)h.tagName==="LINK"&&h.rel==="modulepreload"&&l(h)}).observe(document,{childList:!0,subtree:!0});function s(u){const f={};return u.integrity&&(f.integrity=u.integrity),u.referrerPolicy&&(f.referrerPolicy=u.referrerPolicy),u.crossOrigin==="use-credentials"?f.credentials="include":u.crossOrigin==="anonymous"?f.credentials="omit":f.credentials="same-origin",f}function l(u){if(u.ep)return;u.ep=!0;const f=s(u);fetch(u.href,f)}})();/**
* @vue/shared v3.5.39
* (c) 2018-present Yuxi (Evan) You and Vue contributors
* @license MIT
**/function Xr(t){const i=Object.create(null);for(const s of t.split(","))i[s]=1;return s=>s in i}const vt={},es=[],ui=()=>{},zu=()=>!1,ja=t=>t.charCodeAt(0)===111&&t.charCodeAt(1)===110&&(t.charCodeAt(2)>122||t.charCodeAt(2)<97),Wa=t=>t.startsWith("onUpdate:"),Kt=Object.assign,Qr=(t,i)=>{const s=t.indexOf(i);s>-1&&t.splice(s,1)},pd=Object.prototype.hasOwnProperty,ct=(t,i)=>pd.call(t,i),$e=Array.isArray,ts=t=>ea(t)==="[object Map]",ls=t=>ea(t)==="[object Set]",Al=t=>ea(t)==="[object Date]",je=t=>typeof t=="function",Tt=t=>typeof t=="string",Qn=t=>typeof t=="symbol",dt=t=>t!==null&&typeof t=="object",$u=t=>(dt(t)||je(t))&&je(t.then)&&je(t.catch),Iu=Object.prototype.toString,ea=t=>Iu.call(t),md=t=>ea(t).slice(8,-1),Nu=t=>ea(t)==="[object Object]",el=t=>Tt(t)&&t!=="NaN"&&t[0]!=="-"&&""+parseInt(t,10)===t,Rs=Xr(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),Ka=t=>{const i=Object.create(null);return(s=>i[s]||(i[s]=t(s)))},gd=/-\w/g,Jn=Ka(t=>t.replace(gd,i=>i.slice(1).toUpperCase())),vd=/\B([A-Z])/g,to=Ka(t=>t.replace(vd,"-$1").toLowerCase()),Du=Ka(t=>t.charAt(0).toUpperCase()+t.slice(1)),xr=Ka(t=>t?`on${Du(t)}`:""),li=(t,i)=>!Object.is(t,i),Ea=(t,...i)=>{for(let s=0;s<t.length;s++)t[s](...i)},Fu=(t,i,s,l=!1)=>{Object.defineProperty(t,i,{configurable:!0,enumerable:!1,writable:l,value:s})},Ga=t=>{const i=parseFloat(t);return isNaN(i)?t:i},_d=t=>{const i=Tt(t)?Number(t):NaN;return isNaN(i)?t:i};let Ml;const qa=()=>Ml||(Ml=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function Eo(t){if($e(t)){const i={};for(let s=0;s<t.length;s++){const l=t[s],u=Tt(l)?wd(l):Eo(l);if(u)for(const f in u)i[f]=u[f]}return i}else if(Tt(t)||dt(t))return t}const bd=/;(?![^(]*\))/g,yd=/:([^]+)/,xd=/\/\*[^]*?\*\//g;function wd(t){const i={};return t.replace(xd,"").split(bd).forEach(s=>{if(s){const l=s.split(yd);l.length>1&&(i[l[0].trim()]=l[1].trim())}}),i}function Ce(t){let i="";if(Tt(t))i=t;else if($e(t))for(let s=0;s<t.length;s++){const l=Ce(t[s]);l&&(i+=l+" ")}else if(dt(t))for(const s in t)t[s]&&(i+=s+" ");return i.trim()}const kd="itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly",Sd=Xr(kd);function Ru(t){return!!t||t===""}function Td(t,i){if(t.length!==i.length)return!1;let s=!0;for(let l=0;s&&l<t.length;l++)s=Xi(t[l],i[l]);return s}function Xi(t,i){if(t===i)return!0;let s=Al(t),l=Al(i);if(s||l)return s&&l?t.getTime()===i.getTime():!1;if(s=Qn(t),l=Qn(i),s||l)return t===i;if(s=$e(t),l=$e(i),s||l)return s&&l?Td(t,i):!1;if(s=dt(t),l=dt(i),s||l){if(!s||!l)return!1;const u=Object.keys(t).length,f=Object.keys(i).length;if(u!==f)return!1;for(const h in t){const _=t.hasOwnProperty(h),y=i.hasOwnProperty(h);if(_&&!y||!_&&y||!Xi(t[h],i[h]))return!1}}return String(t)===String(i)}function tl(t,i){return t.findIndex(s=>Xi(s,i))}const Bu=t=>!!(t&&t.__v_isRef===!0),w=t=>Tt(t)?t:t==null?"":$e(t)||dt(t)&&(t.toString===Iu||!je(t.toString))?Bu(t)?w(t.value):JSON.stringify(t,Uu,2):String(t),Uu=(t,i)=>Bu(i)?Uu(t,i.value):ts(i)?{[`Map(${i.size})`]:[...i.entries()].reduce((s,[l,u],f)=>(s[wr(l,f)+" =>"]=u,s),{})}:ls(i)?{[`Set(${i.size})`]:[...i.values()].map(s=>wr(s))}:Qn(i)?wr(i):dt(i)&&!$e(i)&&!Nu(i)?String(i):i,wr=(t,i="")=>{var s;return Qn(t)?`Symbol(${(s=t.description)!=null?s:i})`:t};/**
* @vue/reactivity v3.5.39
* (c) 2018-present Yuxi (Evan) You and Vue contributors
* @license MIT
**/let Yt;class Pd{constructor(i=!1){this.detached=i,this._active=!0,this._on=0,this.effects=[],this.cleanups=[],this._isPaused=!1,this._warnOnRun=!0,this.__v_skip=!0,!i&&Yt&&(Yt.active?(this.parent=Yt,this.index=(Yt.scopes||(Yt.scopes=[])).push(this)-1):(this._active=!1,this._warnOnRun=!1))}get active(){return this._active}pause(){if(this._active){this._isPaused=!0;let i,s;if(this.scopes)for(i=0,s=this.scopes.length;i<s;i++)this.scopes[i].pause();for(i=0,s=this.effects.length;i<s;i++)this.effects[i].pause()}}resume(){if(this._active&&this._isPaused){this._isPaused=!1;let i,s;if(this.scopes)for(i=0,s=this.scopes.length;i<s;i++)this.scopes[i].resume();for(i=0,s=this.effects.length;i<s;i++)this.effects[i].resume()}}run(i){if(this._active){const s=Yt;try{return Yt=this,i()}finally{Yt=s}}}on(){++this._on===1&&(this.prevScope=Yt,Yt=this)}off(){if(this._on>0&&--this._on===0){if(Yt===this)Yt=this.prevScope;else{let i=Yt;for(;i;){if(i.prevScope===this){i.prevScope=this.prevScope;break}i=i.prevScope}}this.prevScope=void 0}}stop(i){if(this._active){this._active=!1;let s,l;for(s=0,l=this.effects.length;s<l;s++)this.effects[s].stop();for(this.effects.length=0,s=0,l=this.cleanups.length;s<l;s++)this.cleanups[s]();if(this.cleanups.length=0,this.scopes){for(s=0,l=this.scopes.length;s<l;s++)this.scopes[s].stop(!0);this.scopes.length=0}if(!this.detached&&this.parent&&!i){const u=this.parent.scopes.pop();u&&u!==this&&(this.parent.scopes[this.index]=u,u.index=this.index)}this.parent=void 0}}}function Cd(){return Yt}let xt;const kr=new WeakSet;class Vu{constructor(i){this.fn=i,this.deps=void 0,this.depsTail=void 0,this.flags=5,this.next=void 0,this.cleanup=void 0,this.scheduler=void 0,Yt&&(Yt.active?Yt.effects.push(this):this.flags&=-2)}pause(){this.flags|=64}resume(){this.flags&64&&(this.flags&=-65,kr.has(this)&&(kr.delete(this),this.trigger()))}notify(){this.flags&2&&!(this.flags&32)||this.flags&8||Hu(this)}run(){if(!(this.flags&1))return this.fn();this.flags|=2,El(this),ju(this);const i=xt,s=Xn;xt=this,Xn=!0;try{return this.fn()}finally{Wu(this),xt=i,Xn=s,this.flags&=-3}}stop(){if(this.flags&1){for(let i=this.deps;i;i=i.nextDep)ol(i);this.deps=this.depsTail=void 0,El(this),this.onStop&&this.onStop(),this.flags&=-2}}trigger(){this.flags&64?kr.add(this):this.scheduler?this.scheduler():this.runIfDirty()}runIfDirty(){Ir(this)&&this.run()}get dirty(){return Ir(this)}}let Zu=0,Bs,Us;function Hu(t,i=!1){if(t.flags|=8,i){t.next=Us,Us=t;return}t.next=Bs,Bs=t}function nl(){Zu++}function il(){if(--Zu>0)return;if(Us){let i=Us;for(Us=void 0;i;){const s=i.next;i.next=void 0,i.flags&=-9,i=s}}let t;for(;Bs;){let i=Bs;for(Bs=void 0;i;){const s=i.next;if(i.next=void 0,i.flags&=-9,i.flags&1)try{i.trigger()}catch(l){t||(t=l)}i=s}}if(t)throw t}function ju(t){for(let i=t.deps;i;i=i.nextDep)i.version=-1,i.prevActiveLink=i.dep.activeLink,i.dep.activeLink=i}function Wu(t){let i,s=t.depsTail,l=s;for(;l;){const u=l.prevDep;l.version===-1?(l===s&&(s=u),ol(l),Ld(l)):i=l,l.dep.activeLink=l.prevActiveLink,l.prevActiveLink=void 0,l=u}t.deps=i,t.depsTail=s}function Ir(t){for(let i=t.deps;i;i=i.nextDep)if(i.dep.version!==i.version||i.dep.computed&&(Ku(i.dep.computed)||i.dep.version!==i.version))return!0;return!!t._dirty}function Ku(t){if(t.flags&4&&!(t.flags&16)||(t.flags&=-17,t.globalVersion===Ws)||(t.globalVersion=Ws,!t.isSSR&&t.flags&128&&(!t.deps&&!t._dirty||!Ir(t))))return;t.flags|=2;const i=t.dep,s=xt,l=Xn;xt=t,Xn=!0;try{ju(t);const u=t.fn(t._value);(i.version===0||li(u,t._value))&&(t.flags|=128,t._value=u,i.version++)}catch(u){throw i.version++,u}finally{xt=s,Xn=l,Wu(t),t.flags&=-3}}function ol(t,i=!1){const{dep:s,prevSub:l,nextSub:u}=t;if(l&&(l.nextSub=u,t.prevSub=void 0),u&&(u.prevSub=l,t.nextSub=void 0),s.subs===t&&(s.subs=l,!l&&s.computed)){s.computed.flags&=-5;for(let f=s.computed.deps;f;f=f.nextDep)ol(f,!0)}!i&&!--s.sc&&s.map&&s.map.delete(s.key)}function Ld(t){const{prevDep:i,nextDep:s}=t;i&&(i.nextDep=s,t.prevDep=void 0),s&&(s.prevDep=i,t.nextDep=void 0)}let Xn=!0;const Gu=[];function ci(){Gu.push(Xn),Xn=!1}function di(){const t=Gu.pop();Xn=t===void 0?!0:t}function El(t){const{cleanup:i}=t;if(t.cleanup=void 0,i){const s=xt;xt=void 0;try{i()}finally{xt=s}}}let Ws=0;class Ad{constructor(i,s){this.sub=i,this.dep=s,this.version=s.version,this.nextDep=this.prevDep=this.nextSub=this.prevSub=this.prevActiveLink=void 0}}class sl{constructor(i){this.computed=i,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(i){if(!xt||!Xn||xt===this.computed)return;let s=this.activeLink;if(s===void 0||s.sub!==xt)s=this.activeLink=new Ad(xt,this),xt.deps?(s.prevDep=xt.depsTail,xt.depsTail.nextDep=s,xt.depsTail=s):xt.deps=xt.depsTail=s,qu(s);else if(s.version===-1&&(s.version=this.version,s.nextDep)){const l=s.nextDep;l.prevDep=s.prevDep,s.prevDep&&(s.prevDep.nextDep=l),s.prevDep=xt.depsTail,s.nextDep=void 0,xt.depsTail.nextDep=s,xt.depsTail=s,xt.deps===s&&(xt.deps=l)}return s}trigger(i){this.versiLine truncated
* @vue/runtime-core v3.5.39
* (c) 2018-present Yuxi (Evan) You and Vue contributors
* @license MIT
**/function ta(t,i,s,l){try{return l?t(...l):t()}catch(u){Ja(u,i,s)}}function Hn(t,i,s,l){if(je(t)){const u=ta(t,i,s,l);return u&&$u(u)&&u.catch(f=>{Ja(f,i,s)}),u}if($e(t)){const u=[];for(let f=0;f<t.length;f++)u.push(Hn(t[f],i,s,l));return u}}function Ja(t,i,s,l=!0){const u=i?i.vnode:null,{errorHandler:f,throwUnhandledErrorInProduction:h}=i&&i.appContext.config||vt;if(i){let _=i.parent;const y=i.proxy,C=`https://vuejs.org/error-reference/#runtime-${s}`;for(;_;){const T=_.ec;if(T){for(let M=0;M<T.length;M++)if(T[M](t,y,C)===!1)return}_=_.parent}if(f){ci(),ta(f,null,10,[t,y,C]),di();return}}ef(t,s,u,l,h)}function ef(t,i,s,l=!0,u=!1){if(u)throw t;console.error(t)}const fn=[];let si=-1;const ns=[];let Ji=null,Qo=0;const ic=Promise.resolve();let $a=null;function oc(t){const i=$a||ic;return t?i.then(this?t.bind(this):t):i}function tf(t){let i=si+1,s=fn.length;for(;i<s;){const l=i+s>>>1,u=fn[l],f=Gs(u);f<t||f===t&&u.flags&2?i=l+1:s=l}return i}function ul(t){if(!(t.flags&1)){const i=Gs(t),s=fn[fn.length-1];!s||!(t.flags&2)&&i>=Gs(s)?fn.push(t):fn.splice(tf(i),0,t),t.flags|=1,sc()}}function sc(){$a||($a=ic.then(rc))}function nf(t){$e(t)?ns.push(...t):Ji&&t.id===-1?Ji.splice(Qo+1,0,t):t.flags&1||(ns.push(t),t.flags|=1),sc()}function zl(t,i,s=si+1){for(;s<fn.length;s++){const l=fn[s];if(l&&l.flags&2){if(t&&l.id!==t.uid)continue;fn.splice(s,1),s--,l.flags&4&&(l.flags&=-2),l(),l.flags&4||(l.flags&=-2)}}}function ac(t){if(ns.length){const i=[...new Set(ns)].sort((s,l)=>Gs(s)-Gs(l));if(ns.length=0,Ji){Ji.push(...i);return}for(Ji=i,Qo=0;Qo<Ji.length;Qo++){const s=Ji[Qo];s.flags&4&&(s.flags&=-2),s.flags&8||s(),s.flags&=-2}Ji=null,Qo=0}}const Gs=t=>t.id==null?t.flags&2?-1:1/0:t.id;function rc(t){try{for(si=0;si<fn.length;si++){const i=fn[si];i&&!(i.flags&8)&&(i.flags&4&&(i.flags&=-2),ta(i,i.i,i.i?15:14),i.flags&4||(i.flags&=-2))}}finally{for(;si<fn.length;si++){const i=fn[si];i&&(i.flags&=-2)}si=-1,fn.length=0,ac(),$a=null,(fn.length||ns.length)&&rc()}}let an=null,lc=null;function Ia(t){const i=an;return an=t,lc=t&&t.type.__scopeId||null,i}function ye(t,i=an,s){if(!i||t._n)return t;const l=(...u)=>{l._d&&Fa(-1);const f=Ia(i);let h;try{h=t(...u)}finally{Ia(f),l._d&&Fa(1)}return h};return l._n=!0,l._c=!0,l._d=!0,l}function ie(t,i){if(an===null)return t;const s=nr(an),l=t.dirs||(t.dirs=[]);for(let u=0;u<i.length;u++){let[f,h,_,y=vt]=i[u];f&&(je(f)&&(f={mounted:f,updated:f}),f.deep&&Ai(h),l.push({dir:f,instance:s,value:h,oldValue:void 0,arg:_,modifiers:y}))}return t}function wo(t,i,s,l){const u=t.dirs,f=i&&i.dirs;for(let h=0;h<u.length;h++){const _=u[h];f&&(_.oldValue=f[h].value);let y=_.dir[l];y&&(ci(),Hn(y,s,8,[t.el,_,t,i]),di())}}function uc(t,i){if(hn){let s=hn.provides;const l=hn.parent&&hn.parent.provides;l===s&&(s=hn.provides=Object.create(l)),s[t]=i}}function Vs(t,i,s=!1){const l=Uc();if(l||os){let u=os?os._context.provides:l?l.parent==null||l.ce?l.vnode.appContext&&l.vnode.appContext.provides:l.parent.provides:void 0;if(u&&t in u)return u[t];if(arguments.length>1)return s&&je(i)?i.call(l&&l.proxy):i}}const of=Symbol.for("v-scx"),sf=()=>Vs(of);function Bt(t,i,s){return cc(t,i,s)}function cc(t,i,s=vt){const{immediate:l,deep:u,flush:f,once:h}=s,_=Kt({},s),y=i&&l||!i&&f!=="post";let C;if(Xs){if(f==="sync"){const j=sf();C=j.__watcherHandles||(j.__watcherHandles=[])}else if(!y){const j=()=>{};return j.stop=ui,j.resume=ui,j.pause=ui,j}}const T=hn;_.call=(j,K,F)=>Hn(j,T,K,F);let M=!1;f==="post"?_.scheduler=j=>{dn(j,T&&T.suspense)}:f!=="sync"&&(M=!0,_.scheduler=(j,K)=>{K?j():ul(j)}),_.augmentJob=j=>{i&&(j.flags|=4),M&&(j.flags|=2,T&&(j.id=T.uid,j.i=T))};const H=Qd(t,i,_);return Xs&&(C?C.push(H):y&&H()),H}function af(t,i,s){const l=this.proxy,u=Tt(t)?t.includes(".")?dc(l,t):()=>l[t]:t.bind(l,l);let f;je(i)?f=i:(f=i.handler,s=i);const h=na(this),_=cc(u,f.bind(l),s);return h(),_}function dc(t,i){const s=i.split(".");return()=>{let l=t;for(let u=0;u<s.length&&l;u++)l=l[s[u]];return l}}const Yi=new WeakMap,fc=Symbol("_vte"),hc=t=>t.__isTeleport,Co=t=>t&&(t.disabled||t.disabled===""),rf=t=>t&&(t.defer||t.defer===""),$l=t=>typeof SVGElement<"u"&&t instanceof SVGElement,Il=t=>typeof MathMLElement=="function"&&t instanceof MathMLElement,Br=(t,i)=>{const s=t&&t.to;return Tt(s)?i?i(s):null:s},lf={name:"Teleport",__isTeleport:!0,process(t,i,s,l,u,f,h,_,y,C){const{mc:T,pc:M,pbc:H,o:{insert:j,querySelector:K,createText:F,createComment:te,parentNode:X}}=C,fe=Co(i.props);let{dynamicChildren:Se}=i;const de=(Te,Ze,he)=>{Te.shapeFlag&16&&T(Te.children,Ze,he,u,f,h,_,y)},Fe=(Te=i)=>{const Ze=Co(Te.props),he=Te.target=Br(Te.props,K),Q=Ur(he,Te,F,j);he&&(h!=="svg"&&$l(he)?h="svg":h!=="mathml"&&Il(he)&&(h="mathml"),u&&u.isCE&&(u.ce._teleportTargets||(u.ce._teleportTargets=new Set)).add(he),Ze||(de(Te,he,Q),Is(Te,!1)))},Oe=Te=>{const Ze=()=>{if(Yi.get(Te)===Ze){if(Yi.delete(Te),Co(Te.props)){const he=X(Te.el)||s;de(Te,he,Te.anchor),Is(Te,!0)}Fe(Te)}};Yi.set(Te,Ze),dn(Ze,f)};if(t==null){const Te=i.el=F(""),Ze=i.anchor=F("");if(j(Te,s,l),j(Ze,s,l),rf(i. Line truncated
* @vue/runtime-dom v3.5.39
* (c) 2018-present Yuxi (Evan) You and Vue contributors
* @license MIT
**/let Gr;const ql=typeof window<"u"&&window.trustedTypes;if(ql)try{Gr=ql.createPolicy("vue",{createHTML:t=>t})}catch{}const Hc=Gr?t=>Gr.createHTML(t):t=>t,fh="http://www.w3.org/2000/svg",hh="http://www.w3.org/1998/Math/MathML",Pi=typeof document<"u"?document:null,Yl=Pi&&Pi.createElement("template"),ph={insert:(t,i,s)=>{i.insertBefore(t,s||null)},remove:t=>{const i=t.parentNode;i&&i.removeChild(t)},createElement:(t,i,s,l)=>{const u=i==="svg"?Pi.createElementNS(fh,t):i==="mathml"?Pi.createElementNS(hh,t):s?Pi.createElement(t,{is:s}):Pi.createElement(t);return t==="select"&&l&&l.multiple!=null&&u.setAttribute("multiple",l.multiple),u},createText:t=>Pi.createTextNode(t),createComment:t=>Pi.createComment(t),setText:(t,i)=>{t.nodeValue=i},setElementText:(t,i)=>{t.textContent=i},parentNode:t=>t.parentNode,nextSibling:t=>t.nextSibling,querySelector:t=>Pi.querySelector(t),setScopeId(t,i){t.setAttribute(i,"")},insertStaticContent(t,i,s,l,u,f){const h=s?s.previousSibling:i.lastChild;if(u&&(u===f||u.nextSibling))for(;i.insertBefore(u.cloneNode(!0),s),!(u===f||!(u=u.nextSibling)););else{Yl.innerHTML=Hc(l==="svg"?`<svg>${t}</svg>`:l==="mathml"?`<math>${t}</math>`:t);const _=Yl.content;if(l==="svg"||l==="mathml"){const y=_.firstChild;for(;y.firstChild;)_.appendChild(y.firstChild);_.removeChild(y)}i.insertBefore(_,s)}return[h?h.nextSibling:i.firstChild,s?s.previousSibling:i.lastChild]}},Gi="transition",zs="animation",Qs=Symbol("_vtc"),jc={name:String,type:String,css:{type:Boolean,default:!0},duration:[String,Number,Object],enterFromClass:String,enterActiveClass:String,enterToClass:String,appearFromClass:String,appearActiveClass:String,appearToClass:String,leaveFromClass:String,leaveActiveClass:String,leaveToClass:String},mh=Kt({},pc,jc),gh=t=>(t.displayName="Transition",t.props=mh,t),vh=gh((t,{slots:i})=>ch(hf,_h(t),i)),So=(t,i=[])=>{$e(t)?t.forEach(s=>s(...i)):t&&t(...i)},Jl=t=>t?$e(t)?t.some(i=>i.length>1):t.length>1:!1;function _h(t){const i={};for(const O in t)O in jc||(i[O]=t[O]);if(t.css===!1)return i;const{name:s="v",type:l,duration:u,enterFromClass:f=`${s}-enter-from`,enterActiveClass:h=`${s}-enter-active`,enterToClass:_=`${s}-enter-to`,appearFromClass:y=f,appearActiveClass:C=h,appearToClass:T=_,leaveFromClass:M=`${s}-leave-from`,leaveActiveClass:H=`${s}-leave-active`,leaveToClass:j=`${s}-leave-to`}=t,K=bh(u),F=K&&K[0],te=K&&K[1],{onBeforeEnter:X,onEnter:fe,onEnterCancelled:Se,onLeave:de,onLeaveCancelled:Fe,onBeforeAppear:Oe=X,onAppear:Te=fe,onAppearCancelled:Ze=Se}=i,he=(O,N,$,Ye)=>{O._enterCancelled=Ye,To(O,N?T:_),To(O,N?C:h),$&&$()},Q=(O,N)=>{O._isLeaving=!1,To(O,M),To(O,j),To(O,H),N&&N()},B=O=>(N,$)=>{const Ye=O?Te:fe,we=()=>he(N,O,$);So(Ye,[N,we]),Xl(()=>{To(N,O?y:f),Ti(N,O?T:_),Jl(Ye)||Ql(N,l,F,we)})};return Kt(i,{onBeforeEnter(O){So(X,[O]),Ti(O,f),Ti(O,h)},onBeforeAppear(O){So(Oe,[O]),Ti(O,y),Ti(O,C)},onEnter:B(!1),onAppear:B(!0),onLeave(O,N){O._isLeaving=!0;const $=()=>Q(O,N);Ti(O,M),O._enterCancelled?(Ti(O,H),nu(O)):(nu(O),Ti(O,H)),Xl(()=>{O._isLeaving&&(To(O,M),Ti(O,j),Jl(de)||Ql(O,l,te,$))}),So(de,[O,$])},onEnterCancelled(O){he(O,!1,void 0,!0),So(Se,[O])},onAppearCancelled(O){he(O,!0,void 0,!0),So(Ze,[O])},onLeaveCancelled(O){Q(O),So(Fe,[O])}})}function bh(t){if(t==null)return null;if(dt(t))return[Mr(t.enter),Mr(t.leave)];{const i=Mr(t);return[i,i]}}function Mr(t){return _d(t)}function Ti(t,i){i.split(/\s+/).forEach(s=>s&&t.classList.add(s)),(t[Qs]||(t[Qs]=new Set)).add(i)}function To(t,i){i.split(/\s+/).forEach(l=>l&&t.classList.remove(l));const s=t[Qs];s&&(s.delete(i),s.size||(t[Qs]=void 0))}function Xl(t){requestAnimationFrame(()=>{requestAnimationFrame(t)})}let yh=0;function Ql(t,i,s,l){const u=t._endId=++yh,f=()=>{u===t._endId&&l()};if(s!=null)return setTimeout(f,s);const{type:h,timeout:_,propCount:y}=xh(t,i);if(!h)return l();const C=h+"end";let T=0;const M=()=>{t.removeEventListener(C,H),f()},H=j=>{j.target===t&&++T>=y&&M()};setTimeout(()=>{T<y&&M()},_+1),t.addEventListener(C,H)}function xh(t,i){const s=window.getComputedStyle(t),l=K=>(s[K]||"").split(", "),u=l(`${Gi}Delay`),f=l(`${Gi}Duration`),h=eu(u,f),_=l(`${zs}Delay`),y=l(`${zs}Duration`),C=eu(_,y);let T=null,M=0,H=0;i===Gi?h>0&&(T=Gi,M=h,H=f.length):i===zs?C>0&&(T=zs,M=C,H=y.length):(M=Math.max(h,C),T=M>0?h>C?Gi:zs:null,H=T?T===Gi?f.length:y.length:0);const j=T===Gi&&/\b(?:transform|all)(?:,|$)/.test(l(`${Gi}Property`).toString());return{type:T,timeout:M,propCount:H,hasTransform:j}}function eu(t,i){for(;t.length<i.length;)t=t.concat(t);return Math.max(...i.map((s,l)=>tu(s)+tu(t[l])))}function tu(t){return t==="auto"?0:Number(t.slice(0,-1).replace(",","."))*1e3}function nu(t){return(t?t.ownerDocument:document).body.offsetHeight}function wh(t,i,s){const l=t[Qs];l&&(i=(i?[i,...l]:[...l]).join(" ")),i==null?t.removeAttribute("class"):s?t.setAttribute("class",i):t.className=i}const Ua=Symbol("_vod"),Wc=Symbol("_vsh"),kh={name:"show",beforeMount(t,{value:i},{transition:s}){t[Ua]=t.style.display==="none"?"":t.style.display,s&&i?s.beforeEnter(t):$s Line truncated
* Leaflet 1.9.4, a JS library for interactive maps. https://leafletjs.com
* (c) 2010-2023 Vladimir Agafonkin, (c) 2010-2011 CloudMade
*/var um=Fs.exports,Pu;function cm(){return Pu||(Pu=1,(function(t,i){(function(s,l){l(i)})(um,(function(s){var l="1.9.4";function u(e){var n,o,r,d;for(o=1,r=arguments.length;o<r;o++){d=arguments[o];for(n in d)e[n]=d[n]}return e}var f=Object.create||(function(){function e(){}return function(n){return e.prototype=n,new e}})();function h(e,n){var o=Array.prototype.slice;if(e.bind)return e.bind.apply(e,o.call(arguments,1));var r=o.call(arguments,2);return function(){return e.apply(n,r.length?r.concat(o.call(arguments)):arguments)}}var _=0;function y(e){return"_leaflet_id"in e||(e._leaflet_id=++_),e._leaflet_id}function C(e,n,o){var r,d,v,P;return P=function(){r=!1,d&&(v.apply(o,d),d=!1)},v=function(){r?d=arguments:(e.apply(o,arguments),setTimeout(P,n),r=!0)},v}function T(e,n,o){var r=n[1],d=n[0],v=r-d;return e===r&&o?e:((e-d)%v+v)%v+d}function M(){return!1}function H(e,n){if(n===!1)return e;var o=Math.pow(10,n===void 0?6:n);return Math.round(e*o)/o}function j(e){return e.trim?e.trim():e.replace(/^\s+|\s+$/g,"")}function K(e){return j(e).split(/\s+/)}function F(e,n){Object.prototype.hasOwnProperty.call(e,"options")||(e.options=e.options?f(e.options):{});for(var o in n)e.options[o]=n[o];return e.options}function te(e,n,o){var r=[];for(var d in e)r.push(encodeURIComponent(o?d.toUpperCase():d)+"="+encodeURIComponent(e[d]));return(!n||n.indexOf("?")===-1?"?":"&")+r.join("&")}var X=/\{ *([\w_ -]+) *\}/g;function fe(e,n){return e.replace(X,function(o,r){var d=n[r];if(d===void 0)throw new Error("No value provided for variable "+o);return typeof d=="function"&&(d=d(n)),d})}var Se=Array.isArray||function(e){return Object.prototype.toString.call(e)==="[object Array]"};function de(e,n){for(var o=0;o<e.length;o++)if(e[o]===n)return o;return-1}var Fe="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=";function Oe(e){return window["webkit"+e]||window["moz"+e]||window["ms"+e]}var Te=0;function Ze(e){var n=+new Date,o=Math.max(0,16-(n-Te));return Te=n+o,window.setTimeout(e,o)}var he=window.requestAnimationFrame||Oe("RequestAnimationFrame")||Ze,Q=window.cancelAnimationFrame||Oe("CancelAnimationFrame")||Oe("CancelRequestAnimationFrame")||function(e){window.clearTimeout(e)};function B(e,n,o){if(o&&he===Ze)e.call(n);else return he.call(window,h(e,n))}function O(e){e&&Q.call(window,e)}var N={__proto__:null,extend:u,create:f,bind:h,get lastId(){return _},stamp:y,throttle:C,wrapNum:T,falseFn:M,formatNum:H,trim:j,splitWords:K,setOptions:F,getParamString:te,template:fe,isArray:Se,indexOf:de,emptyImageUrl:Fe,requestFn:he,cancelFn:Q,requestAnimFrame:B,cancelAnimFrame:O};function $(){}$.extend=function(e){var n=function(){F(this),this.initialize&&this.initialize.apply(this,arguments),this.callInitHooks()},o=n.__super__=this.prototype,r=f(o);r.constructor=n,n.prototype=r;for(var d in this)Object.prototype.hasOwnProperty.call(this,d)&&d!=="prototype"&&d!=="__super__"&&(n[d]=this[d]);return e.statics&&u(n,e.statics),e.includes&&(Ye(e.includes),u.apply(null,[r].concat(e.includes))),u(r,e),delete r.statics,delete r.includes,r.options&&(r.options=o.options?f(o.options):{},u(r.options,e.options)),r._initHooks=[],r.callInitHooks=function(){if(!this._initHooksCalled){o.callInitHooks&&o.callInitHooks.call(this),this._initHooksCalled=!0;for(var v=0,P=r._initHooks.length;v<P;v++)r._initHooks[v].call(this)}},n},$.include=function(e){var n=this.prototype.options;return u(this.prototype,e),e.options&&(this.prototype.options=n,this.mergeOptions(e.options)),this},$.mergeOptions=function(e){return u(this.prototype.options,e),this},$.addInitHook=function(e){var n=Array.prototype.slice.call(arguments,1),o=typeof e=="function"?e:function(){this[e].apply(this,n)};return this.prototype._initHooks=this.prototype._initHooks||[],this.prototype._initHooks.push(o),this};function Ye(e){if(!(typeof L>"u"||!L||!L.Mixin)){e=Se(e)?e:[e];for(var n=0;n<e.length;n++)e[n]===L.Mixin.Events&&console.warn("Deprecated include of L.Mixin.Events: this property will be removed in future releases, please inherit from L.Evented instead.",new Error().stack)}}var we={on:function(e,n,o){if(typeof e=="object")for(var r in e)this._on(r,e[r],n);else{e=K(e);for(var d=0,v=e.length;d<v;d++)this._on(e[d],n,o)}return this},off:function(e,n,o){if(!arguments.length)delete this._events;else if(typeof e=="object")for(var r in e)this._off(r,e[r],n);else{e=K(e);for(var d=arguments.length===1,v=0,P=e.length;v<P;v++)d?this._off(e[v]):this._off(e[v],n,o)}return this},_on:function(e,n,o,r){if(typeof n!="function"){console.warn("wrong listener type: "+typeof n);return}if(this._listens(e,n,o)===!1){o===this&&(o=void 0);var d={fn:n,ctx:o};r&&(d.once=!0),this._events=this._events||{},this._events[e]=this._events[e]||[],this._events[e].push(d)}},_off:function(e,n,o){var r,d,v;if(this._events&&(r=this._events[e],!!r)){if(arguments.length===1){if(this._firingCount)for(d=0,v=r.length;d<v;d++)r[d].fn=M;delete this._events[e];return}if(typeof n!="function"){console.warn("wrong listener type: "+typeof n);Line truncated
+1 -1
View File
@@ -35,7 +35,7 @@
})()
</script>
<title>PilotVault — Control Panel</title>
<script type="module" crossorigin src="./assets/index-CHTNTK5I.js"></script>
<script type="module" crossorigin src="./assets/index-DrzdlcUJ.js"></script>
<link rel="stylesheet" crossorigin href="./assets/index-DgA6j1AP.css">
</head>
<body>
+1
View File
@@ -80,6 +80,7 @@ func main() {
// Logbook — drones, flights, and the compliance CSV export (scoping upstream)
mux.HandleFunc("GET /bff/drones", app.requireAuth(app.handleListDrones))
mux.HandleFunc("POST /bff/drones", app.requireAuth(app.handleCreateDrone))
mux.HandleFunc("POST /bff/drones/auto", app.requireAuth(app.handleAutoDrone))
mux.HandleFunc("PATCH /bff/drones/{id}", app.requireAuth(app.handleUpdateDrone))
mux.HandleFunc("DELETE /bff/drones/{id}", app.requireAuth(app.handleDeleteDrone))
mux.HandleFunc("GET /bff/flights", app.requireAuth(app.handleListFlights))