Make air-traffic refresh interval configurable, resolved from plan

Add a refresh-interval control to the Map settings popover: Auto (follows
the OpenSky plan) or a fixed 15/30/60/120s. The states endpoint now
resolves a recommended interval from the resolved plan (anonymous 60s,
standard 30s, contributor 15s) and returns it alongside the aircraft, so
"Auto" tracks the plan's credit budget and update rate. Polling reschedules
live when the effective interval changes; the map caption reflects it. New
airTrafficInterval preference (default 'auto', persisted + synced).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
tajniak81andClaude Opus 4.8 committed 2026-07-13 22:58:19 +02:00
1 parent 2509fb9c07
commit 125d0ccc7d
9 files changed
+116 -38

No files matched your search

+28 -2
View File
@@ -564,8 +564,15 @@ func (s *Server) handleOpenSkyStates(w http.ResponseWriter, r *http.Request) {
who := callerFromRecord(rec) who := callerFromRecord(rec)
res := s.resolveOpenSky(r.Context(), who, rec.Record["pluginSettings"]) res := s.resolveOpenSky(r.Context(), who, rec.Record["pluginSettings"])
// The plan drives the recommended refresh cadence (its daily credit budget and
// upstream update rate). Surfaced on every response so the "Auto" interval in the
// Map settings popover resolves even before the overlay is enabled.
plan := res.eff.Plan
recInterval := recommendedOpenSkyInterval(plan)
disabled := func(detail string) { disabled := func(detail string) {
writeJSON(w, http.StatusOK, map[string]any{"states": []osAircraft{}, "unavailable": true, "detail": detail}) writeJSON(w, http.StatusOK, map[string]any{
"states": []osAircraft{}, "unavailable": true, "detail": detail,
"plan": plan, "recommendedInterval": recInterval})
} }
switch { switch {
case !res.available: case !res.available:
@@ -630,7 +637,26 @@ func (s *Server) handleOpenSkyStates(w http.ResponseWriter, r *http.Request) {
} }
aircraft = append(aircraft, a) aircraft = append(aircraft, a)
} }
writeJSON(w, http.StatusOK, map[string]any{"time": osResp.Time, "states": aircraft}) writeJSON(w, http.StatusOK, map[string]any{
"time": osResp.Time, "states": aircraft,
"plan": plan, "recommendedInterval": recInterval})
}
// recommendedOpenSkyInterval maps a resolved plan to a sensible default poll
// interval (seconds) for the Live map. It balances the plan's daily credit budget
// (anonymous 400 · standard 4000 · contributor 8000) against how often OpenSky
// actually refreshes state vectors (~10s anonymous, ~5s authenticated), so the map
// stays fresh without draining credits. An unset plan resolves as standard (the
// runtime default). See planDailyCredits in the opensky plugin.
func recommendedOpenSkyInterval(plan string) int {
switch plan {
case "anonymous":
return 60
case "contributor":
return 15
default: // standard or unset
return 30
}
} }
// rawFloat reads element i of an OpenSky state array as a float, reporting ok=false // rawFloat reads element i of an OpenSky state array as a float, reporting ok=false
+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 d of u)if(d.type==="childList")for(const h of d.addedNodes)h.tagName==="LINK"&&h.rel==="modulepreload"&&l(h)}).observe(document,{childList:!0,subtree:!0});function o(u){const d={};return u.integrity&&(d.integrity=u.integrity),u.referrerPolicy&&(d.referrerPolicy=u.referrerPolicy),u.crossOrigin==="use-credentials"?d.credentials="include":u.crossOrigin==="anonymous"?d.credentials="omit":d.credentials="same-origin",d}function l(u){if(u.ep)return;u.ep=!0;const d=o(u);fetch(u.href,d)}})();/**
* @vue/shared v3.5.39
* (c) 2018-present Yuxi (Evan) You and Vue contributors
* @license MIT
**/function Pr(t){const i=Object.create(null);for(const o of t.split(","))i[o]=1;return o=>o in i}const pt={},xs=[],Un=()=>{},mu=()=>!1,pa=t=>t.charCodeAt(0)===111&&t.charCodeAt(1)===110&&(t.charCodeAt(2)>122||t.charCodeAt(2)<97),ma=t=>t.startsWith("onUpdate:"),At=Object.assign,Cr=(t,i)=>{const o=t.indexOf(i);o>-1&&t.splice(o,1)},cd=Object.prototype.hasOwnProperty,ct=(t,i)=>cd.call(t,i),De=Array.isArray,ws=t=>yo(t)==="[object Map]",Es=t=>yo(t)==="[object Set]",hl=t=>yo(t)==="[object Date]",je=t=>typeof t=="function",bt=t=>typeof t=="string",Ln=t=>typeof t=="symbol",dt=t=>t!==null&&typeof t=="object",gu=t=>(dt(t)||je(t))&&je(t.then)&&je(t.catch),vu=Object.prototype.toString,yo=t=>vu.call(t),dd=t=>yo(t).slice(8,-1),_u=t=>yo(t)==="[object Object]",Lr=t=>bt(t)&&t!=="NaN"&&t[0]!=="-"&&""+parseInt(t,10)===t,io=Pr(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),ga=t=>{const i=Object.create(null);return(o=>i[o]||(i[o]=t(o)))},fd=/-\w/g,Pn=ga(t=>t.replace(fd,i=>i.slice(1).toUpperCase())),hd=/\B([A-Z])/g,Ei=ga(t=>t.replace(hd,"-$1").toLowerCase()),yu=ga(t=>t.charAt(0).toUpperCase()+t.slice(1)),Ya=ga(t=>t?`on${yu(t)}`:""),Vn=(t,i)=>!Object.is(t,i),ea=(t,...i)=>{for(let o=0;o<t.length;o++)t[o](...i)},bu=(t,i,o,l=!1)=>{Object.defineProperty(t,i,{configurable:!0,enumerable:!1,writable:l,value:o})},va=t=>{const i=parseFloat(t);return isNaN(i)?t:i},pd=t=>{const i=bt(t)?Number(t):NaN;return isNaN(i)?t:i};let pl;const _a=()=>pl||(pl=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function Cs(t){if(De(t)){const i={};for(let o=0;o<t.length;o++){const l=t[o],u=bt(l)?_d(l):Cs(l);if(u)for(const d in u)i[d]=u[d]}return i}else if(bt(t)||dt(t))return t}const md=/;(?![^(]*\))/g,gd=/:([^]+)/,vd=/\/\*[^]*?\*\//g;function _d(t){const i={};return t.replace(vd,"").split(md).forEach(o=>{if(o){const l=o.split(gd);l.length>1&&(i[l[0].trim()]=l[1].trim())}}),i}function Oe(t){let i="";if(bt(t))i=t;else if(De(t))for(let o=0;o<t.length;o++){const l=Oe(t[o]);l&&(i+=l+" ")}else if(dt(t))for(const o in t)t[o]&&(i+=o+" ");return i.trim()}const yd="itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly",bd=Pr(yd);function xu(t){return!!t||t===""}function xd(t,i){if(t.length!==i.length)return!1;let o=!0;for(let l=0;o&&l<t.length;l++)o=Ci(t[l],i[l]);return o}function Ci(t,i){if(t===i)return!0;let o=hl(t),l=hl(i);if(o||l)return o&&l?t.getTime()===i.getTime():!1;if(o=Ln(t),l=Ln(i),o||l)return t===i;if(o=De(t),l=De(i),o||l)return o&&l?xd(t,i):!1;if(o=dt(t),l=dt(i),o||l){if(!o||!l)return!1;const u=Object.keys(t).length,d=Object.keys(i).length;if(u!==d)return!1;for(const h in t){const _=t.hasOwnProperty(h),y=i.hasOwnProperty(h);if(_&&!y||!_&&y||!Ci(t[h],i[h]))return!1}}return String(t)===String(i)}function Mr(t,i){return t.findIndex(o=>Ci(o,i))}const wu=t=>!!(t&&t.__v_isRef===!0),k=t=>bt(t)?t:t==null?"":De(t)||dt(t)&&(t.toString===vu||!je(t.toString))?wu(t)?k(t.value):JSON.stringify(t,ku,2):String(t),ku=(t,i)=>wu(i)?ku(t,i.value):ws(i)?{[`Map(${i.size})`]:[...i.entries()].reduce((o,[l,u],d)=>(o[Ja(l,d)+" =>"]=u,o),{})}:Es(i)?{[`Set(${i.size})`]:[...i.values()].map(o=>Ja(o))}:Ln(i)?Ja(i):dt(i)&&!De(i)&&!_u(i)?String(i):i,Ja=(t,i="")=>{var o;return Ln(t)?`Symbol(${(o=t.description)!=null?o:i})`:t};/**
* @vue/reactivity v3.5.39
* (c) 2018-present Yuxi (Evan) You and Vue contributors
* @license MIT
**/let Dt;class wd{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&&Dt&&(Dt.active?(this.parent=Dt,this.index=(Dt.scopes||(Dt.scopes=[])).push(this)-1):(this._active=!1,this._warnOnRun=!1))}get active(){return this._active}pause(){if(this._active){this._isPaused=!0;let i,o;if(this.scopes)for(i=0,o=this.scopes.length;i<o;i++)this.scopes[i].pause();for(i=0,o=this.effects.length;i<o;i++)this.effects[i].pause()}}resume(){if(this._active&&this._isPaused){this._isPaused=!1;let i,o;if(this.scopes)for(i=0,o=this.scopes.length;i<o;i++)this.scopes[i].resume();for(i=0,o=this.effects.length;i<o;i++)this.effects[i].resume()}}run(i){if(this._active){const o=Dt;try{return Dt=this,i()}finally{Dt=o}}}on(){++this._on===1&&(this.prevScope=Dt,Dt=this)}off(){if(this._on>0&&--this._on===0){if(Dt===this)Dt=this.prevScope;else{let i=Dt;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 o,l;for(o=0,l=this.effects.length;o<l;o++)this.effects[o].stop();for(this.effects.length=0,o=0,l=this.cleanups.length;o<l;o++)this.cleanups[o]();if(this.cleanups.length=0,this.scopes){for(o=0,l=this.scopes.length;o<l;o++)this.scopes[o].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 kd(){return Dt}let vt;const Xa=new WeakSet;class Su{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,Dt&&(Dt.active?Dt.effects.push(this):this.flags&=-2)}pause(){this.flags|=64}resume(){this.flags&64&&(this.flags&=-65,Xa.has(this)&&(Xa.delete(this),this.trigger()))}notify(){this.flags&2&&!(this.flags&32)||this.flags&8||Pu(this)}run(){if(!(this.flags&1))return this.fn();this.flags|=2,ml(this),Cu(this);const i=vt,o=Cn;vt=this,Cn=!0;try{return this.fn()}finally{Lu(this),vt=i,Cn=o,this.flags&=-3}}stop(){if(this.flags&1){for(let i=this.deps;i;i=i.nextDep)zr(i);this.deps=this.depsTail=void 0,ml(this),this.onStop&&this.onStop(),this.flags&=-2}}trigger(){this.flags&64?Xa.add(this):this.scheduler?this.scheduler():this.runIfDirty()}runIfDirty(){ur(this)&&this.run()}get dirty(){return ur(this)}}let Tu=0,so,oo;function Pu(t,i=!1){if(t.flags|=8,i){t.next=oo,oo=t;return}t.next=so,so=t}function Er(){Tu++}function Or(){if(--Tu>0)return;if(oo){let i=oo;for(oo=void 0;i;){const o=i.next;i.next=void 0,i.flags&=-9,i=o}}let t;for(;so;){let i=so;for(so=void 0;i;){const o=i.next;if(i.next=void 0,i.flags&=-9,i.flags&1)try{i.trigger()}catch(l){t||(t=l)}i=o}}if(t)throw t}function Cu(t){for(let i=t.deps;i;i=i.nextDep)i.version=-1,i.prevActiveLink=i.dep.activeLink,i.dep.activeLink=i}function Lu(t){let i,o=t.depsTail,l=o;for(;l;){const u=l.prevDep;l.version===-1?(l===o&&(o=u),zr(l),Sd(l)):i=l,l.dep.activeLink=l.prevActiveLink,l.prevActiveLink=void 0,l=u}t.deps=i,t.depsTail=o}function ur(t){for(let i=t.deps;i;i=i.nextDep)if(i.dep.version!==i.version||i.dep.computed&&(Mu(i.dep.computed)||i.dep.version!==i.version))return!0;return!!t._dirty}function Mu(t){if(t.flags&4&&!(t.flags&16)||(t.flags&=-17,t.globalVersion===co)||(t.globalVersion=co,!t.isSSR&&t.flags&128&&(!t.deps&&!t._dirty||!ur(t))))return;t.flags|=2;const i=t.dep,o=vt,l=Cn;vt=t,Cn=!0;try{Cu(t);const u=t.fn(t._value);(i.version===0||Vn(u,t._value))&&(t.flags|=128,t._value=u,i.version++)}catch(u){throw i.version++,u}finally{vt=o,Cn=l,Lu(t),t.flags&=-3}}function zr(t,i=!1){const{dep:o,prevSub:l,nextSub:u}=t;if(l&&(l.nextSub=u,t.prevSub=void 0),u&&(u.prevSub=l,t.nextSub=void 0),o.subs===t&&(o.subs=l,!l&&o.computed)){o.computed.flags&=-5;for(let d=o.computed.deps;d;d=d.nextDep)zr(d,!0)}!i&&!--o.sc&&o.map&&o.map.delete(o.key)}function Sd(t){const{prevDep:i,nextDep:o}=t;i&&(i.nextDep=o,t.prevDep=void 0),o&&(o.prevDep=i,t.nextDep=void 0)}let Cn=!0;const Eu=[];function Zn(){Eu.push(Cn),Cn=!1}function Hn(){const t=Eu.pop();Cn=t===void 0?!0:t}function ml(t){const{cleanup:i}=t;if(t.cleanup=void 0,i){const o=vt;vt=void 0;try{i()}finally{vt=o}}}let co=0;class Td{constructor(i,o){this.sub=i,this.dep=o,this.version=o.version,this.nextDep=this.prevDep=this.nextSub=this.prevSub=this.prevActiveLink=void 0}}class Ar{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(!vt||!Cn||vt===this.computed)return;let o=this.activeLink;if(o===void 0||o.sub!==vt)o=this.activeLink=new Td(vt,this),vt.deps?(o.prevDep=vt.depsTail,vt.depsTail.nextDep=o,vt.depsTail=o):vt.deps=vt.depsTail=o,Ou(o);else if(o.version===-1&&(o.version=this.version,o.nextDep)){const l=o.nextDep;l.prevDep=o.prevDep,o.prevDep&&(o.prevDep.nextDep=l),o.prevDep=vt.depsTail,o.nextDep=void 0,vt.depsTail.nextDep=o,vt.depsTail=o,vt.deps===o&&(vt.deps=l)}return o}trigger(i){this.versiLine truncated
* @vue/runtime-core v3.5.39
* (c) 2018-present Yuxi (Evan) You and Vue contributors
* @license MIT
**/function bo(t,i,o,l){try{return l?t(...l):t()}catch(u){ba(u,i,o)}}function vn(t,i,o,l){if(je(t)){const u=bo(t,i,o,l);return u&&gu(u)&&u.catch(d=>{ba(d,i,o)}),u}if(De(t)){const u=[];for(let d=0;d<t.length;d++)u.push(vn(t[d],i,o,l));return u}}function ba(t,i,o,l=!0){const u=i?i.vnode:null,{errorHandler:d,throwUnhandledErrorInProduction:h}=i&&i.appContext.config||pt;if(i){let _=i.parent;const y=i.proxy,M=`https://vuejs.org/error-reference/#runtime-${o}`;for(;_;){const S=_.ec;if(S){for(let O=0;O<S.length;O++)if(S[O](t,y,M)===!1)return}_=_.parent}if(d){Zn(),bo(d,null,10,[t,y,M]),Hn();return}}Yd(t,o,u,l,h)}function Yd(t,i,o,l=!0,u=!1){if(u)throw t;console.error(t)}const Yt=[];let Rn=-1;const ks=[];let Pi=null,bs=0;const Fu=Promise.resolve();let ia=null;function Bu(t){const i=ia||Fu;return t?i.then(this?t.bind(this):t):i}function Jd(t){let i=Rn+1,o=Yt.length;for(;i<o;){const l=i+o>>>1,u=Yt[l],d=ho(u);d<t||d===t&&u.flags&2?i=l+1:o=l}return i}function Nr(t){if(!(t.flags&1)){const i=ho(t),o=Yt[Yt.length-1];!o||!(t.flags&2)&&i>=ho(o)?Yt.push(t):Yt.splice(Jd(i),0,t),t.flags|=1,Vu()}}function Vu(){ia||(ia=Fu.then(Zu))}function Xd(t){De(t)?ks.push(...t):Pi&&t.id===-1?Pi.splice(bs+1,0,t):t.flags&1||(ks.push(t),t.flags|=1),Vu()}function vl(t,i,o=Rn+1){for(;o<Yt.length;o++){const l=Yt[o];if(l&&l.flags&2){if(t&&l.id!==t.uid)continue;Yt.splice(o,1),o--,l.flags&4&&(l.flags&=-2),l(),l.flags&4||(l.flags&=-2)}}}function Uu(t){if(ks.length){const i=[...new Set(ks)].sort((o,l)=>ho(o)-ho(l));if(ks.length=0,Pi){Pi.push(...i);return}for(Pi=i,bs=0;bs<Pi.length;bs++){const o=Pi[bs];o.flags&4&&(o.flags&=-2),o.flags&8||o(),o.flags&=-2}Pi=null,bs=0}}const ho=t=>t.id==null?t.flags&2?-1:1/0:t.id;function Zu(t){try{for(Rn=0;Rn<Yt.length;Rn++){const i=Yt[Rn];i&&!(i.flags&8)&&(i.flags&4&&(i.flags&=-2),bo(i,i.i,i.i?15:14),i.flags&4||(i.flags&=-2))}}finally{for(;Rn<Yt.length;Rn++){const i=Yt[Rn];i&&(i.flags&=-2)}Rn=-1,Yt.length=0,Uu(),ia=null,(Yt.length||ks.length)&&Zu()}}let Vt=null,Hu=null;function sa(t){const i=Vt;return Vt=t,Hu=t&&t.type.__scopeId||null,i}function Le(t,i=Vt,o){if(!i||t._n)return t;const l=(...u)=>{l._d&&ra(-1);const d=sa(i);let h;try{h=t(...u)}finally{sa(d),l._d&&ra(1)}return h};return l._n=!0,l._c=!0,l._d=!0,l}function re(t,i){if(Vt===null)return t;const o=Ta(Vt),l=t.dirs||(t.dirs=[]);for(let u=0;u<i.length;u++){let[d,h,_,y=pt]=i[u];d&&(je(d)&&(d={mounted:d,updated:d}),d.deep&&ai(h),l.push({dir:d,instance:o,value:h,oldValue:void 0,arg:_,modifiers:y}))}return t}function Hi(t,i,o,l){const u=t.dirs,d=i&&i.dirs;for(let h=0;h<u.length;h++){const _=u[h];d&&(_.oldValue=d[h].value);let y=_.dir[l];y&&(Zn(),vn(y,o,8,[t.el,_,t,i]),Hn())}}function ju(t,i){if(Jt){let o=Jt.provides;const l=Jt.parent&&Jt.parent.provides;l===o&&(o=Jt.provides=Object.create(l)),o[t]=i}}function ao(t,i,o=!1){const l=kc();if(l||Ts){let u=Ts?Ts._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 o&&je(i)?i.call(l&&l.proxy):i}}const Qd=Symbol.for("v-scx"),ef=()=>ao(Qd);function zt(t,i,o){return Wu(t,i,o)}function Wu(t,i,o=pt){const{immediate:l,deep:u,flush:d,once:h}=o,_=At({},o),y=i&&l||!i&&d!=="post";let M;if(vo){if(d==="sync"){const V=ef();M=V.__watcherHandles||(V.__watcherHandles=[])}else if(!y){const V=()=>{};return V.stop=Un,V.resume=Un,V.pause=Un,V}}const S=Jt;_.call=(V,Z,F)=>vn(V,S,Z,F);let O=!1;d==="post"?_.scheduler=V=>{qt(V,S&&S.suspense)}:d!=="sync"&&(O=!0,_.scheduler=(V,Z)=>{Z?V():Nr(V)}),_.augmentJob=V=>{i&&(V.flags|=4),O&&(V.flags|=2,S&&(V.id=S.uid,V.i=S))};const B=qd(t,i,_);return vo&&(M?M.push(B):y&&B()),B}function tf(t,i,o){const l=this.proxy,u=bt(t)?t.includes(".")?Ku(l,t):()=>l[t]:t.bind(l,l);let d;je(i)?d=i:(d=i.handler,o=i);const h=xo(this),_=Wu(u,d.bind(l),o);return h(),_}function Ku(t,i){const o=i.split(".");return()=>{let l=t;for(let u=0;u<o.length&&l;u++)l=l[o[u]];return l}}const Ti=new WeakMap,Gu=Symbol("_vte"),qu=t=>t.__isTeleport,qi=t=>t&&(t.disabled||t.disabled===""),nf=t=>t&&(t.defer||t.defer===""),_l=t=>typeof SVGElement<"u"&&t instanceof SVGElement,yl=t=>typeof MathMLElement=="function"&&t instanceof MathMLElement,pr=(t,i)=>{const o=t&&t.to;return bt(o)?i?i(o):null:o},sf={name:"Teleport",__isTeleport:!0,process(t,i,o,l,u,d,h,_,y,M){const{mc:S,pc:O,pbc:B,o:{insert:V,querySelector:Z,createText:F,createComment:fe,parentNode:ve}}=M,q=qi(i.props);let{dynamicChildren:Ce}=i;const he=(Ie,Ue,pe)=>{Ie.shapeFlag&16&&S(Ie.children,Ue,pe,u,d,h,_,y)},be=(Ie=i)=>{const Ue=qi(Ie.props),pe=Ie.target=pr(Ie.props,Z),Ae=mr(pe,Ie,F,V);pe&&(h!=="svg"&&_l(pe)?h="svg":h!=="mathml"&&yl(pe)&&(h="mathml"),u&&u.isCE&&(u.ce._teleportTargets||(u.ce._teleportTargets=new Set)).add(pe),Ue||(he(Ie,pe,Ae),Qs(Ie,!1)))},Re=Ie=>{const Ue=()=>{if(Ti.get(Ie)===Ue){if(Ti.delete(Ie),qi(Ie.props)){const pe=ve(Ie.el)||o;he(Ie,pe,Ie.anchor),Qs(Ie,!0)}be(Ie)}};Ti.set(Ie,Ue),qt(Ue,d)};if(t==null){const Ie=i.el=F(""),Ue=i.anchor=F("");if(V(Ie,o,l),V(Ue,o,l),nf Line truncated
* @vue/runtime-dom v3.5.39
* (c) 2018-present Yuxi (Evan) You and Vue contributors
* @license MIT
**/let wr;const Al=typeof window<"u"&&window.trustedTypes;if(Al)try{wr=Al.createPolicy("vue",{createHTML:t=>t})}catch{}const Pc=wr?t=>wr.createHTML(t):t=>t,lh="http://www.w3.org/2000/svg",uh="http://www.w3.org/1998/Math/MathML",ii=typeof document<"u"?document:null,$l=ii&&ii.createElement("template"),ch={insert:(t,i,o)=>{i.insertBefore(t,o||null)},remove:t=>{const i=t.parentNode;i&&i.removeChild(t)},createElement:(t,i,o,l)=>{const u=i==="svg"?ii.createElementNS(lh,t):i==="mathml"?ii.createElementNS(uh,t):o?ii.createElement(t,{is:o}):ii.createElement(t);return t==="select"&&l&&l.multiple!=null&&u.setAttribute("multiple",l.multiple),u},createText:t=>ii.createTextNode(t),createComment:t=>ii.createComment(t),setText:(t,i)=>{t.nodeValue=i},setElementText:(t,i)=>{t.textContent=i},parentNode:t=>t.parentNode,nextSibling:t=>t.nextSibling,querySelector:t=>ii.querySelector(t),setScopeId(t,i){t.setAttribute(i,"")},insertStaticContent(t,i,o,l,u,d){const h=o?o.previousSibling:i.lastChild;if(u&&(u===d||u.nextSibling))for(;i.insertBefore(u.cloneNode(!0),o),!(u===d||!(u=u.nextSibling)););else{$l.innerHTML=Pc(l==="svg"?`<svg>${t}</svg>`:l==="mathml"?`<math>${t}</math>`:t);const _=$l.content;if(l==="svg"||l==="mathml"){const y=_.firstChild;for(;y.firstChild;)_.appendChild(y.firstChild);_.removeChild(y)}i.insertBefore(_,o)}return[h?h.nextSibling:i.firstChild,o?o.previousSibling:i.lastChild]}},ki="transition",Js="animation",_o=Symbol("_vtc"),Cc={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},dh=At({},Yu,Cc),fh=t=>(t.displayName="Transition",t.props=dh,t),hh=fh((t,{slots:i})=>ah(uf,ph(t),i)),Wi=(t,i=[])=>{De(t)?t.forEach(o=>o(...i)):t&&t(...i)},Il=t=>t?De(t)?t.some(i=>i.length>1):t.length>1:!1;function ph(t){const i={};for(const te in t)te in Cc||(i[te]=t[te]);if(t.css===!1)return i;const{name:o="v",type:l,duration:u,enterFromClass:d=`${o}-enter-from`,enterActiveClass:h=`${o}-enter-active`,enterToClass:_=`${o}-enter-to`,appearFromClass:y=d,appearActiveClass:M=h,appearToClass:S=_,leaveFromClass:O=`${o}-leave-from`,leaveActiveClass:B=`${o}-leave-active`,leaveToClass:V=`${o}-leave-to`}=t,Z=mh(u),F=Z&&Z[0],fe=Z&&Z[1],{onBeforeEnter:ve,onEnter:q,onEnterCancelled:Ce,onLeave:he,onLeaveCancelled:be,onBeforeAppear:Re=ve,onAppear:Ie=q,onAppearCancelled:Ue=Ce}=i,pe=(te,de,ye,Se)=>{te._enterCancelled=Se,Ki(te,de?S:_),Ki(te,de?M:h),ye&&ye()},Ae=(te,de)=>{te._isLeaving=!1,Ki(te,O),Ki(te,V),Ki(te,B),de&&de()},Te=te=>(de,ye)=>{const Se=te?Ie:q,ae=()=>pe(de,te,ye);Wi(Se,[de,ae]),Dl(()=>{Ki(de,te?y:d),ni(de,te?S:_),Il(Se)||Nl(de,l,F,ae)})};return At(i,{onBeforeEnter(te){Wi(ve,[te]),ni(te,d),ni(te,h)},onBeforeAppear(te){Wi(Re,[te]),ni(te,y),ni(te,M)},onEnter:Te(!1),onAppear:Te(!0),onLeave(te,de){te._isLeaving=!0;const ye=()=>Ae(te,de);ni(te,O),te._enterCancelled?(ni(te,B),Bl(te)):(Bl(te),ni(te,B)),Dl(()=>{te._isLeaving&&(Ki(te,O),ni(te,V),Il(he)||Nl(te,l,fe,ye))}),Wi(he,[te,ye])},onEnterCancelled(te){pe(te,!1,void 0,!0),Wi(Ce,[te])},onAppearCancelled(te){pe(te,!0,void 0,!0),Wi(Ue,[te])},onLeaveCancelled(te){Ae(te),Wi(be,[te])}})}function mh(t){if(t==null)return null;if(dt(t))return[or(t.enter),or(t.leave)];{const i=or(t);return[i,i]}}function or(t){return pd(t)}function ni(t,i){i.split(/\s+/).forEach(o=>o&&t.classList.add(o)),(t[_o]||(t[_o]=new Set)).add(i)}function Ki(t,i){i.split(/\s+/).forEach(l=>l&&t.classList.remove(l));const o=t[_o];o&&(o.delete(i),o.size||(t[_o]=void 0))}function Dl(t){requestAnimationFrame(()=>{requestAnimationFrame(t)})}let gh=0;function Nl(t,i,o,l){const u=t._endId=++gh,d=()=>{u===t._endId&&l()};if(o!=null)return setTimeout(d,o);const{type:h,timeout:_,propCount:y}=vh(t,i);if(!h)return l();const M=h+"end";let S=0;const O=()=>{t.removeEventListener(M,B),d()},B=V=>{V.target===t&&++S>=y&&O()};setTimeout(()=>{S<y&&O()},_+1),t.addEventListener(M,B)}function vh(t,i){const o=window.getComputedStyle(t),l=Z=>(o[Z]||"").split(", "),u=l(`${ki}Delay`),d=l(`${ki}Duration`),h=Rl(u,d),_=l(`${Js}Delay`),y=l(`${Js}Duration`),M=Rl(_,y);let S=null,O=0,B=0;i===ki?h>0&&(S=ki,O=h,B=d.length):i===Js?M>0&&(S=Js,O=M,B=y.length):(O=Math.max(h,M),S=O>0?h>M?ki:Js:null,B=S?S===ki?d.length:y.length:0);const V=S===ki&&/\b(?:transform|all)(?:,|$)/.test(l(`${ki}Property`).toString());return{type:S,timeout:O,propCount:B,hasTransform:V}}function Rl(t,i){for(;t.length<i.length;)t=t.concat(t);return Math.max(...i.map((o,l)=>Fl(o)+Fl(t[l])))}function Fl(t){return t==="auto"?0:Number(t.slice(0,-1).replace(",","."))*1e3}function Bl(t){return(t?t.ownerDocument:document).body.offsetHeight}function _h(t,i,o){const l=t[_o];l&&(i=(i?[i,...l]:[...l]).join(" ")),i==null?t.removeAttribute("class"):o?t.setAttribute("class",i):t.className=i}const ca=Symbol("_vod"),Lc=Symbol("_vsh"),yh={name:"show",beforeMount(t,{value:i},{transition:o 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 tm=no.exports,uu;function nm(){return uu||(uu=1,(function(t,i){(function(o,l){l(i)})(tm,(function(o){var l="1.9.4";function u(e){var n,s,a,c;for(s=1,a=arguments.length;s<a;s++){c=arguments[s];for(n in c)e[n]=c[n]}return e}var d=Object.create||(function(){function e(){}return function(n){return e.prototype=n,new e}})();function h(e,n){var s=Array.prototype.slice;if(e.bind)return e.bind.apply(e,s.call(arguments,1));var a=s.call(arguments,2);return function(){return e.apply(n,a.length?a.concat(s.call(arguments)):arguments)}}var _=0;function y(e){return"_leaflet_id"in e||(e._leaflet_id=++_),e._leaflet_id}function M(e,n,s){var a,c,m,C;return C=function(){a=!1,c&&(m.apply(s,c),c=!1)},m=function(){a?c=arguments:(e.apply(s,arguments),setTimeout(C,n),a=!0)},m}function S(e,n,s){var a=n[1],c=n[0],m=a-c;return e===a&&s?e:((e-c)%m+m)%m+c}function O(){return!1}function B(e,n){if(n===!1)return e;var s=Math.pow(10,n===void 0?6:n);return Math.round(e*s)/s}function V(e){return e.trim?e.trim():e.replace(/^\s+|\s+$/g,"")}function Z(e){return V(e).split(/\s+/)}function F(e,n){Object.prototype.hasOwnProperty.call(e,"options")||(e.options=e.options?d(e.options):{});for(var s in n)e.options[s]=n[s];return e.options}function fe(e,n,s){var a=[];for(var c in e)a.push(encodeURIComponent(s?c.toUpperCase():c)+"="+encodeURIComponent(e[c]));return(!n||n.indexOf("?")===-1?"?":"&")+a.join("&")}var ve=/\{ *([\w_ -]+) *\}/g;function q(e,n){return e.replace(ve,function(s,a){var c=n[a];if(c===void 0)throw new Error("No value provided for variable "+s);return typeof c=="function"&&(c=c(n)),c})}var Ce=Array.isArray||function(e){return Object.prototype.toString.call(e)==="[object Array]"};function he(e,n){for(var s=0;s<e.length;s++)if(e[s]===n)return s;return-1}var be="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=";function Re(e){return window["webkit"+e]||window["moz"+e]||window["ms"+e]}var Ie=0;function Ue(e){var n=+new Date,s=Math.max(0,16-(n-Ie));return Ie=n+s,window.setTimeout(e,s)}var pe=window.requestAnimationFrame||Re("RequestAnimationFrame")||Ue,Ae=window.cancelAnimationFrame||Re("CancelAnimationFrame")||Re("CancelRequestAnimationFrame")||function(e){window.clearTimeout(e)};function Te(e,n,s){if(s&&pe===Ue)e.call(n);else return pe.call(window,h(e,n))}function te(e){e&&Ae.call(window,e)}var de={__proto__:null,extend:u,create:d,bind:h,get lastId(){return _},stamp:y,throttle:M,wrapNum:S,falseFn:O,formatNum:B,trim:V,splitWords:Z,setOptions:F,getParamString:fe,template:q,isArray:Ce,indexOf:he,emptyImageUrl:be,requestFn:pe,cancelFn:Ae,requestAnimFrame:Te,cancelAnimFrame:te};function ye(){}ye.extend=function(e){var n=function(){F(this),this.initialize&&this.initialize.apply(this,arguments),this.callInitHooks()},s=n.__super__=this.prototype,a=d(s);a.constructor=n,n.prototype=a;for(var c in this)Object.prototype.hasOwnProperty.call(this,c)&&c!=="prototype"&&c!=="__super__"&&(n[c]=this[c]);return e.statics&&u(n,e.statics),e.includes&&(Se(e.includes),u.apply(null,[a].concat(e.includes))),u(a,e),delete a.statics,delete a.includes,a.options&&(a.options=s.options?d(s.options):{},u(a.options,e.options)),a._initHooks=[],a.callInitHooks=function(){if(!this._initHooksCalled){s.callInitHooks&&s.callInitHooks.call(this),this._initHooksCalled=!0;for(var m=0,C=a._initHooks.length;m<C;m++)a._initHooks[m].call(this)}},n},ye.include=function(e){var n=this.prototype.options;return u(this.prototype,e),e.options&&(this.prototype.options=n,this.mergeOptions(e.options)),this},ye.mergeOptions=function(e){return u(this.prototype.options,e),this},ye.addInitHook=function(e){var n=Array.prototype.slice.call(arguments,1),s=typeof e=="function"?e:function(){this[e].apply(this,n)};return this.prototype._initHooks=this.prototype._initHooks||[],this.prototype._initHooks.push(s),this};function Se(e){if(!(typeof L>"u"||!L||!L.Mixin)){e=Ce(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 ae={on:function(e,n,s){if(typeof e=="object")for(var a in e)this._on(a,e[a],n);else{e=Z(e);for(var c=0,m=e.length;c<m;c++)this._on(e[c],n,s)}return this},off:function(e,n,s){if(!arguments.length)delete this._events;else if(typeof e=="object")for(var a in e)this._off(a,e[a],n);else{e=Z(e);for(var c=arguments.length===1,m=0,C=e.length;m<C;m++)c?this._off(e[m]):this._off(e[m],n,s)}return this},_on:function(e,n,s,a){if(typeof n!="function"){console.warn("wrong listener type: "+typeof n);return}if(this._listens(e,n,s)===!1){s===this&&(s=void 0);var c={fn:n,ctx:s};a&&(c.once=!0),this._events=this._events||{},this._events[e]=this._events[e]||[],this._events[e].push(c)}},_off:function(e,n,s){var a,c,m;if(this._events&&(a=this._events[e],!!a)){if(arguments.length===1){if(this._firingCount)for(c=0,m=a.length;c<m;c++)a[c].fn=O;delete this._events[e];return}if(typeof n!="function"){console.warn("wrong listener type:Line truncated
+1
View File
@@ -0,0 +1 @@
:root,[data-theme=light]{--navy-950: #0B1730;--navy-900: #0F1E3D;--navy-800: #1B2E52;--navy-700: #26406E;--blue-50: #EAF1FE;--blue-100: #D6E3FD;--blue-200: #B4CDFA;--blue-300: #8FB4F6;--blue-400: #5B93F5;--blue-500: #3D7BF0;--blue-600: #2B62CC;--blue-700: #1F4CA0;--slate-0: #FFFFFF;--slate-50: #F6F7F9;--slate-100: #EEF0F3;--slate-150: #E6E9EE;--slate-200: #DCE0E7;--slate-300: #C5CCD7;--slate-400: #97A1B0;--slate-500: #6B7688;--slate-600: #4C5566;--slate-700: #333B4A;--slate-800: #1E2635;--slate-900: #131A28;--slate-950: #0B111C;--steel: #5A6B85;--green-500: #1F8A5B;--green-100: #DCF1E7;--green-600:#177049;--amber-500: #D9852B;--amber-100: #FBEBD5;--amber-600:#B86C1B;--red-500: #D64545;--red-100: #FBE0E0;--red-600: #B83232;--bg-app: var(--slate-100);--bg-subtle: var(--slate-50);--surface: var(--slate-0);--surface-2: var(--slate-50);--surface-inset: var(--slate-100);--border: var(--slate-200);--border-strong: var(--slate-300);--border-subtle: var(--slate-150);--text-primary: var(--navy-900);--text-secondary:var(--steel);--text-tertiary: var(--slate-400);--text-inverse: var(--slate-0);--text-on-accent:#FFFFFF;--accent: var(--blue-500);--accent-hover: var(--blue-600);--accent-active: var(--blue-700);--accent-soft: var(--blue-50);--accent-soft-fg:var(--blue-700);--focus-ring: color-mix(in srgb, var(--blue-500) 45%, transparent);--success: var(--green-500);--success-soft: var(--green-100);--success-fg: var(--green-600);--warning: var(--amber-500);--warning-soft: var(--amber-100);--warning-fg: var(--amber-600);--danger: var(--red-500);--danger-soft: var(--red-100);--danger-fg: var(--red-600);--overlay: color-mix(in srgb, var(--navy-950) 55%, transparent);--font-sans: "Space Grotesk", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;--font-mono: "Space Mono", ui-monospace, "SF Mono", "JetBrains Mono", monospace;--radius-xs: 4px;--radius-sm: 6px;--radius-md: 10px;--radius-lg: 14px;--radius-xl: 20px;--radius-pill: 999px;--shadow-xs: 0 1px 2px rgba(15,30,61,.06);--shadow-sm: 0 1px 2px rgba(15,30,61,.06), 0 1px 3px rgba(15,30,61,.04);--shadow-md: 0 2px 4px rgba(15,30,61,.06), 0 6px 16px rgba(15,30,61,.08);--shadow-lg: 0 8px 24px rgba(15,30,61,.1), 0 2px 6px rgba(15,30,61,.06);--ease-standard: cubic-bezier(.4, 0, .2, 1);--ease-out: cubic-bezier(.16, 1, .3, 1);--dur-fast: .12s;--dur-base: .2s;color-scheme:light}[data-theme=dark]{--bg-app: var(--navy-950);--bg-subtle: var(--slate-950);--surface: #10203F;--surface-2: #142748;--surface-inset: var(--navy-950);--border: color-mix(in srgb, #FFFFFF 10%, transparent);--border-strong: color-mix(in srgb, #FFFFFF 18%, transparent);--border-subtle: color-mix(in srgb, #FFFFFF 6%, transparent);--text-primary: #F4F7FC;--text-secondary:#8FA0BE;--text-tertiary: #5E6E8C;--text-inverse: var(--navy-900);--text-on-accent:#FFFFFF;--accent: var(--blue-400);--accent-hover: var(--blue-300);--accent-active: var(--blue-200);--accent-soft: color-mix(in srgb, var(--blue-500) 18%, transparent);--accent-soft-fg:var(--blue-300);--focus-ring: color-mix(in srgb, var(--blue-400) 55%, transparent);--success:var(--green-500);--success-soft: color-mix(in srgb, var(--green-500) 22%, transparent);--success-fg:#5FD3A0;--warning:var(--amber-500);--warning-soft: color-mix(in srgb, var(--amber-500) 22%, transparent);--warning-fg:#F0B26A;--danger: var(--red-500);--danger-soft: color-mix(in srgb, var(--red-500) 22%, transparent);--danger-fg: #F08A8A;--overlay: color-mix(in srgb, #000000 62%, transparent);--shadow-xs: 0 1px 2px rgba(0,0,0,.35);--shadow-sm: 0 1px 3px rgba(0,0,0,.4);--shadow-md: 0 4px 12px rgba(0,0,0,.45);--shadow-lg: 0 12px 32px rgba(0,0,0,.5);color-scheme:dark}*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-Line truncated
-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 d of u)if(d.type==="childList")for(const h of d.addedNodes)h.tagName==="LINK"&&h.rel==="modulepreload"&&l(h)}).observe(document,{childList:!0,subtree:!0});function o(u){const d={};return u.integrity&&(d.integrity=u.integrity),u.referrerPolicy&&(d.referrerPolicy=u.referrerPolicy),u.crossOrigin==="use-credentials"?d.credentials="include":u.crossOrigin==="anonymous"?d.credentials="omit":d.credentials="same-origin",d}function l(u){if(u.ep)return;u.ep=!0;const d=o(u);fetch(u.href,d)}})();/**
* @vue/shared v3.5.39
* (c) 2018-present Yuxi (Evan) You and Vue contributors
* @license MIT
**/function Pr(t){const i=Object.create(null);for(const o of t.split(","))i[o]=1;return o=>o in i}const ht={},xs=[],Un=()=>{},mu=()=>!1,pa=t=>t.charCodeAt(0)===111&&t.charCodeAt(1)===110&&(t.charCodeAt(2)>122||t.charCodeAt(2)<97),ma=t=>t.startsWith("onUpdate:"),zt=Object.assign,Cr=(t,i)=>{const o=t.indexOf(i);o>-1&&t.splice(o,1)},cd=Object.prototype.hasOwnProperty,rt=(t,i)=>cd.call(t,i),Ae=Array.isArray,ws=t=>yo(t)==="[object Map]",Es=t=>yo(t)==="[object Set]",hl=t=>yo(t)==="[object Date]",je=t=>typeof t=="function",yt=t=>typeof t=="string",Ln=t=>typeof t=="symbol",lt=t=>t!==null&&typeof t=="object",gu=t=>(lt(t)||je(t))&&je(t.then)&&je(t.catch),vu=Object.prototype.toString,yo=t=>vu.call(t),dd=t=>yo(t).slice(8,-1),_u=t=>yo(t)==="[object Object]",Lr=t=>yt(t)&&t!=="NaN"&&t[0]!=="-"&&""+parseInt(t,10)===t,io=Pr(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),ga=t=>{const i=Object.create(null);return(o=>i[o]||(i[o]=t(o)))},fd=/-\w/g,Pn=ga(t=>t.replace(fd,i=>i.slice(1).toUpperCase())),hd=/\B([A-Z])/g,Ei=ga(t=>t.replace(hd,"-$1").toLowerCase()),yu=ga(t=>t.charAt(0).toUpperCase()+t.slice(1)),Ya=ga(t=>t?`on${yu(t)}`:""),Vn=(t,i)=>!Object.is(t,i),ea=(t,...i)=>{for(let o=0;o<t.length;o++)t[o](...i)},bu=(t,i,o,l=!1)=>{Object.defineProperty(t,i,{configurable:!0,enumerable:!1,writable:l,value:o})},va=t=>{const i=parseFloat(t);return isNaN(i)?t:i},pd=t=>{const i=yt(t)?Number(t):NaN;return isNaN(i)?t:i};let pl;const _a=()=>pl||(pl=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function Cs(t){if(Ae(t)){const i={};for(let o=0;o<t.length;o++){const l=t[o],u=yt(l)?_d(l):Cs(l);if(u)for(const d in u)i[d]=u[d]}return i}else if(yt(t)||lt(t))return t}const md=/;(?![^(]*\))/g,gd=/:([^]+)/,vd=/\/\*[^]*?\*\//g;function _d(t){const i={};return t.replace(vd,"").split(md).forEach(o=>{if(o){const l=o.split(gd);l.length>1&&(i[l[0].trim()]=l[1].trim())}}),i}function Ee(t){let i="";if(yt(t))i=t;else if(Ae(t))for(let o=0;o<t.length;o++){const l=Ee(t[o]);l&&(i+=l+" ")}else if(lt(t))for(const o in t)t[o]&&(i+=o+" ");return i.trim()}const yd="itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly",bd=Pr(yd);function xu(t){return!!t||t===""}function xd(t,i){if(t.length!==i.length)return!1;let o=!0;for(let l=0;o&&l<t.length;l++)o=Ci(t[l],i[l]);return o}function Ci(t,i){if(t===i)return!0;let o=hl(t),l=hl(i);if(o||l)return o&&l?t.getTime()===i.getTime():!1;if(o=Ln(t),l=Ln(i),o||l)return t===i;if(o=Ae(t),l=Ae(i),o||l)return o&&l?xd(t,i):!1;if(o=lt(t),l=lt(i),o||l){if(!o||!l)return!1;const u=Object.keys(t).length,d=Object.keys(i).length;if(u!==d)return!1;for(const h in t){const _=t.hasOwnProperty(h),y=i.hasOwnProperty(h);if(_&&!y||!_&&y||!Ci(t[h],i[h]))return!1}}return String(t)===String(i)}function Mr(t,i){return t.findIndex(o=>Ci(o,i))}const wu=t=>!!(t&&t.__v_isRef===!0),T=t=>yt(t)?t:t==null?"":Ae(t)||lt(t)&&(t.toString===vu||!je(t.toString))?wu(t)?T(t.value):JSON.stringify(t,ku,2):String(t),ku=(t,i)=>wu(i)?ku(t,i.value):ws(i)?{[`Map(${i.size})`]:[...i.entries()].reduce((o,[l,u],d)=>(o[Ja(l,d)+" =>"]=u,o),{})}:Es(i)?{[`Set(${i.size})`]:[...i.values()].map(o=>Ja(o))}:Ln(i)?Ja(i):lt(i)&&!Ae(i)&&!_u(i)?String(i):i,Ja=(t,i="")=>{var o;return Ln(t)?`Symbol(${(o=t.description)!=null?o:i})`:t};/**
* @vue/reactivity v3.5.39
* (c) 2018-present Yuxi (Evan) You and Vue contributors
* @license MIT
**/let It;class wd{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&&It&&(It.active?(this.parent=It,this.index=(It.scopes||(It.scopes=[])).push(this)-1):(this._active=!1,this._warnOnRun=!1))}get active(){return this._active}pause(){if(this._active){this._isPaused=!0;let i,o;if(this.scopes)for(i=0,o=this.scopes.length;i<o;i++)this.scopes[i].pause();for(i=0,o=this.effects.length;i<o;i++)this.effects[i].pause()}}resume(){if(this._active&&this._isPaused){this._isPaused=!1;let i,o;if(this.scopes)for(i=0,o=this.scopes.length;i<o;i++)this.scopes[i].resume();for(i=0,o=this.effects.length;i<o;i++)this.effects[i].resume()}}run(i){if(this._active){const o=It;try{return It=this,i()}finally{It=o}}}on(){++this._on===1&&(this.prevScope=It,It=this)}off(){if(this._on>0&&--this._on===0){if(It===this)It=this.prevScope;else{let i=It;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 o,l;for(o=0,l=this.effects.length;o<l;o++)this.effects[o].stop();for(this.effects.length=0,o=0,l=this.cleanups.length;o<l;o++)this.cleanups[o]();if(this.cleanups.length=0,this.scopes){for(o=0,l=this.scopes.length;o<l;o++)this.scopes[o].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 kd(){return It}let mt;const Xa=new WeakSet;class Su{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,It&&(It.active?It.effects.push(this):this.flags&=-2)}pause(){this.flags|=64}resume(){this.flags&64&&(this.flags&=-65,Xa.has(this)&&(Xa.delete(this),this.trigger()))}notify(){this.flags&2&&!(this.flags&32)||this.flags&8||Pu(this)}run(){if(!(this.flags&1))return this.fn();this.flags|=2,ml(this),Cu(this);const i=mt,o=Cn;mt=this,Cn=!0;try{return this.fn()}finally{Lu(this),mt=i,Cn=o,this.flags&=-3}}stop(){if(this.flags&1){for(let i=this.deps;i;i=i.nextDep)zr(i);this.deps=this.depsTail=void 0,ml(this),this.onStop&&this.onStop(),this.flags&=-2}}trigger(){this.flags&64?Xa.add(this):this.scheduler?this.scheduler():this.runIfDirty()}runIfDirty(){ur(this)&&this.run()}get dirty(){return ur(this)}}let Tu=0,so,oo;function Pu(t,i=!1){if(t.flags|=8,i){t.next=oo,oo=t;return}t.next=so,so=t}function Er(){Tu++}function Or(){if(--Tu>0)return;if(oo){let i=oo;for(oo=void 0;i;){const o=i.next;i.next=void 0,i.flags&=-9,i=o}}let t;for(;so;){let i=so;for(so=void 0;i;){const o=i.next;if(i.next=void 0,i.flags&=-9,i.flags&1)try{i.trigger()}catch(l){t||(t=l)}i=o}}if(t)throw t}function Cu(t){for(let i=t.deps;i;i=i.nextDep)i.version=-1,i.prevActiveLink=i.dep.activeLink,i.dep.activeLink=i}function Lu(t){let i,o=t.depsTail,l=o;for(;l;){const u=l.prevDep;l.version===-1?(l===o&&(o=u),zr(l),Sd(l)):i=l,l.dep.activeLink=l.prevActiveLink,l.prevActiveLink=void 0,l=u}t.deps=i,t.depsTail=o}function ur(t){for(let i=t.deps;i;i=i.nextDep)if(i.dep.version!==i.version||i.dep.computed&&(Mu(i.dep.computed)||i.dep.version!==i.version))return!0;return!!t._dirty}function Mu(t){if(t.flags&4&&!(t.flags&16)||(t.flags&=-17,t.globalVersion===co)||(t.globalVersion=co,!t.isSSR&&t.flags&128&&(!t.deps&&!t._dirty||!ur(t))))return;t.flags|=2;const i=t.dep,o=mt,l=Cn;mt=t,Cn=!0;try{Cu(t);const u=t.fn(t._value);(i.version===0||Vn(u,t._value))&&(t.flags|=128,t._value=u,i.version++)}catch(u){throw i.version++,u}finally{mt=o,Cn=l,Lu(t),t.flags&=-3}}function zr(t,i=!1){const{dep:o,prevSub:l,nextSub:u}=t;if(l&&(l.nextSub=u,t.prevSub=void 0),u&&(u.prevSub=l,t.nextSub=void 0),o.subs===t&&(o.subs=l,!l&&o.computed)){o.computed.flags&=-5;for(let d=o.computed.deps;d;d=d.nextDep)zr(d,!0)}!i&&!--o.sc&&o.map&&o.map.delete(o.key)}function Sd(t){const{prevDep:i,nextDep:o}=t;i&&(i.nextDep=o,t.prevDep=void 0),o&&(o.prevDep=i,t.nextDep=void 0)}let Cn=!0;const Eu=[];function Zn(){Eu.push(Cn),Cn=!1}function Hn(){const t=Eu.pop();Cn=t===void 0?!0:t}function ml(t){const{cleanup:i}=t;if(t.cleanup=void 0,i){const o=mt;mt=void 0;try{i()}finally{mt=o}}}let co=0;class Td{constructor(i,o){this.sub=i,this.dep=o,this.version=o.version,this.nextDep=this.prevDep=this.nextSub=this.prevSub=this.prevActiveLink=void 0}}class Ar{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(!mt||!Cn||mt===this.computed)return;let o=this.activeLink;if(o===void 0||o.sub!==mt)o=this.activeLink=new Td(mt,this),mt.deps?(o.prevDep=mt.depsTail,mt.depsTail.nextDep=o,mt.depsTail=o):mt.deps=mt.depsTail=o,Ou(o);else if(o.version===-1&&(o.version=this.version,o.nextDep)){const l=o.nextDep;l.prevDep=o.prevDep,o.prevDep&&(o.prevDep.nextDep=l),o.prevDep=mt.depsTail,o.nextDep=void 0,mt.depsTail.nextDep=o,mt.depsTail=o,mt.deps===o&&(mt.deps=l)}return o}trigger(i){this.versiLine truncated
* @vue/runtime-core v3.5.39
* (c) 2018-present Yuxi (Evan) You and Vue contributors
* @license MIT
**/function bo(t,i,o,l){try{return l?t(...l):t()}catch(u){ba(u,i,o)}}function vn(t,i,o,l){if(je(t)){const u=bo(t,i,o,l);return u&&gu(u)&&u.catch(d=>{ba(d,i,o)}),u}if(Ae(t)){const u=[];for(let d=0;d<t.length;d++)u.push(vn(t[d],i,o,l));return u}}function ba(t,i,o,l=!0){const u=i?i.vnode:null,{errorHandler:d,throwUnhandledErrorInProduction:h}=i&&i.appContext.config||ht;if(i){let _=i.parent;const y=i.proxy,M=`https://vuejs.org/error-reference/#runtime-${o}`;for(;_;){const S=_.ec;if(S){for(let O=0;O<S.length;O++)if(S[O](t,y,M)===!1)return}_=_.parent}if(d){Zn(),bo(d,null,10,[t,y,M]),Hn();return}}Yd(t,o,u,l,h)}function Yd(t,i,o,l=!0,u=!1){if(u)throw t;console.error(t)}const Yt=[];let Rn=-1;const ks=[];let Pi=null,bs=0;const Fu=Promise.resolve();let ia=null;function Bu(t){const i=ia||Fu;return t?i.then(this?t.bind(this):t):i}function Jd(t){let i=Rn+1,o=Yt.length;for(;i<o;){const l=i+o>>>1,u=Yt[l],d=ho(u);d<t||d===t&&u.flags&2?i=l+1:o=l}return i}function Nr(t){if(!(t.flags&1)){const i=ho(t),o=Yt[Yt.length-1];!o||!(t.flags&2)&&i>=ho(o)?Yt.push(t):Yt.splice(Jd(i),0,t),t.flags|=1,Vu()}}function Vu(){ia||(ia=Fu.then(Zu))}function Xd(t){Ae(t)?ks.push(...t):Pi&&t.id===-1?Pi.splice(bs+1,0,t):t.flags&1||(ks.push(t),t.flags|=1),Vu()}function vl(t,i,o=Rn+1){for(;o<Yt.length;o++){const l=Yt[o];if(l&&l.flags&2){if(t&&l.id!==t.uid)continue;Yt.splice(o,1),o--,l.flags&4&&(l.flags&=-2),l(),l.flags&4||(l.flags&=-2)}}}function Uu(t){if(ks.length){const i=[...new Set(ks)].sort((o,l)=>ho(o)-ho(l));if(ks.length=0,Pi){Pi.push(...i);return}for(Pi=i,bs=0;bs<Pi.length;bs++){const o=Pi[bs];o.flags&4&&(o.flags&=-2),o.flags&8||o(),o.flags&=-2}Pi=null,bs=0}}const ho=t=>t.id==null?t.flags&2?-1:1/0:t.id;function Zu(t){try{for(Rn=0;Rn<Yt.length;Rn++){const i=Yt[Rn];i&&!(i.flags&8)&&(i.flags&4&&(i.flags&=-2),bo(i,i.i,i.i?15:14),i.flags&4||(i.flags&=-2))}}finally{for(;Rn<Yt.length;Rn++){const i=Yt[Rn];i&&(i.flags&=-2)}Rn=-1,Yt.length=0,Uu(),ia=null,(Yt.length||ks.length)&&Zu()}}let Vt=null,Hu=null;function sa(t){const i=Vt;return Vt=t,Hu=t&&t.type.__scopeId||null,i}function ke(t,i=Vt,o){if(!i||t._n)return t;const l=(...u)=>{l._d&&ra(-1);const d=sa(i);let h;try{h=t(...u)}finally{sa(d),l._d&&ra(1)}return h};return l._n=!0,l._c=!0,l._d=!0,l}function re(t,i){if(Vt===null)return t;const o=Ta(Vt),l=t.dirs||(t.dirs=[]);for(let u=0;u<i.length;u++){let[d,h,_,y=ht]=i[u];d&&(je(d)&&(d={mounted:d,updated:d}),d.deep&&ai(h),l.push({dir:d,instance:o,value:h,oldValue:void 0,arg:_,modifiers:y}))}return t}function Hi(t,i,o,l){const u=t.dirs,d=i&&i.dirs;for(let h=0;h<u.length;h++){const _=u[h];d&&(_.oldValue=d[h].value);let y=_.dir[l];y&&(Zn(),vn(y,o,8,[t.el,_,t,i]),Hn())}}function ju(t,i){if(Jt){let o=Jt.provides;const l=Jt.parent&&Jt.parent.provides;l===o&&(o=Jt.provides=Object.create(l)),o[t]=i}}function ao(t,i,o=!1){const l=kc();if(l||Ts){let u=Ts?Ts._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 o&&je(i)?i.call(l&&l.proxy):i}}const Qd=Symbol.for("v-scx"),ef=()=>ao(Qd);function Dt(t,i,o){return Wu(t,i,o)}function Wu(t,i,o=ht){const{immediate:l,deep:u,flush:d,once:h}=o,_=zt({},o),y=i&&l||!i&&d!=="post";let M;if(vo){if(d==="sync"){const V=ef();M=V.__watcherHandles||(V.__watcherHandles=[])}else if(!y){const V=()=>{};return V.stop=Un,V.resume=Un,V.pause=Un,V}}const S=Jt;_.call=(V,j,F)=>vn(V,S,j,F);let O=!1;d==="post"?_.scheduler=V=>{qt(V,S&&S.suspense)}:d!=="sync"&&(O=!0,_.scheduler=(V,j)=>{j?V():Nr(V)}),_.augmentJob=V=>{i&&(V.flags|=4),O&&(V.flags|=2,S&&(V.id=S.uid,V.i=S))};const B=qd(t,i,_);return vo&&(M?M.push(B):y&&B()),B}function tf(t,i,o){const l=this.proxy,u=yt(t)?t.includes(".")?Ku(l,t):()=>l[t]:t.bind(l,l);let d;je(i)?d=i:(d=i.handler,o=i);const h=xo(this),_=Wu(u,d.bind(l),o);return h(),_}function Ku(t,i){const o=i.split(".");return()=>{let l=t;for(let u=0;u<o.length&&l;u++)l=l[o[u]];return l}}const Ti=new WeakMap,Gu=Symbol("_vte"),qu=t=>t.__isTeleport,qi=t=>t&&(t.disabled||t.disabled===""),nf=t=>t&&(t.defer||t.defer===""),_l=t=>typeof SVGElement<"u"&&t instanceof SVGElement,yl=t=>typeof MathMLElement=="function"&&t instanceof MathMLElement,pr=(t,i)=>{const o=t&&t.to;return yt(o)?i?i(o):null:o},sf={name:"Teleport",__isTeleport:!0,process(t,i,o,l,u,d,h,_,y,M){const{mc:S,pc:O,pbc:B,o:{insert:V,querySelector:j,createText:F,createComment:pe,parentNode:ve}}=M,U=qi(i.props);let{dynamicChildren:we}=i;const de=(Le,De,me)=>{Le.shapeFlag&16&&S(Le.children,De,me,u,d,h,_,y)},Oe=(Le=i)=>{const De=qi(Le.props),me=Le.target=pr(Le.props,j),$e=mr(me,Le,F,V);me&&(h!=="svg"&&_l(me)?h="svg":h!=="mathml"&&yl(me)&&(h="mathml"),u&&u.isCE&&(u.ce._teleportTargets||(u.ce._teleportTargets=new Set)).add(me),De||(de(Le,me,$e),Qs(Le,!1)))},ze=Le=>{const De=()=>{if(Ti.get(Le)===De){if(Ti.delete(Le),qi(Le.props)){const me=ve(Le.el)||o;de(Le,me,Le.anchor),Qs(Le,!0)}Oe(Le)}};Ti.set(Le,De),qt(De,d)};if(t==null){const Le=i.el=F(""),De=i.anchor=F("");if(V(Le,o,l),V(De,o,l),nf Line truncated
* @vue/runtime-dom v3.5.39
* (c) 2018-present Yuxi (Evan) You and Vue contributors
* @license MIT
**/let wr;const Al=typeof window<"u"&&window.trustedTypes;if(Al)try{wr=Al.createPolicy("vue",{createHTML:t=>t})}catch{}const Pc=wr?t=>wr.createHTML(t):t=>t,lh="http://www.w3.org/2000/svg",uh="http://www.w3.org/1998/Math/MathML",ii=typeof document<"u"?document:null,$l=ii&&ii.createElement("template"),ch={insert:(t,i,o)=>{i.insertBefore(t,o||null)},remove:t=>{const i=t.parentNode;i&&i.removeChild(t)},createElement:(t,i,o,l)=>{const u=i==="svg"?ii.createElementNS(lh,t):i==="mathml"?ii.createElementNS(uh,t):o?ii.createElement(t,{is:o}):ii.createElement(t);return t==="select"&&l&&l.multiple!=null&&u.setAttribute("multiple",l.multiple),u},createText:t=>ii.createTextNode(t),createComment:t=>ii.createComment(t),setText:(t,i)=>{t.nodeValue=i},setElementText:(t,i)=>{t.textContent=i},parentNode:t=>t.parentNode,nextSibling:t=>t.nextSibling,querySelector:t=>ii.querySelector(t),setScopeId(t,i){t.setAttribute(i,"")},insertStaticContent(t,i,o,l,u,d){const h=o?o.previousSibling:i.lastChild;if(u&&(u===d||u.nextSibling))for(;i.insertBefore(u.cloneNode(!0),o),!(u===d||!(u=u.nextSibling)););else{$l.innerHTML=Pc(l==="svg"?`<svg>${t}</svg>`:l==="mathml"?`<math>${t}</math>`:t);const _=$l.content;if(l==="svg"||l==="mathml"){const y=_.firstChild;for(;y.firstChild;)_.appendChild(y.firstChild);_.removeChild(y)}i.insertBefore(_,o)}return[h?h.nextSibling:i.firstChild,o?o.previousSibling:i.lastChild]}},ki="transition",Js="animation",_o=Symbol("_vtc"),Cc={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},dh=zt({},Yu,Cc),fh=t=>(t.displayName="Transition",t.props=dh,t),hh=fh((t,{slots:i})=>ah(uf,ph(t),i)),Wi=(t,i=[])=>{Ae(t)?t.forEach(o=>o(...i)):t&&t(...i)},Il=t=>t?Ae(t)?t.some(i=>i.length>1):t.length>1:!1;function ph(t){const i={};for(const Q in t)Q in Cc||(i[Q]=t[Q]);if(t.css===!1)return i;const{name:o="v",type:l,duration:u,enterFromClass:d=`${o}-enter-from`,enterActiveClass:h=`${o}-enter-active`,enterToClass:_=`${o}-enter-to`,appearFromClass:y=d,appearActiveClass:M=h,appearToClass:S=_,leaveFromClass:O=`${o}-leave-from`,leaveActiveClass:B=`${o}-leave-active`,leaveToClass:V=`${o}-leave-to`}=t,j=mh(u),F=j&&j[0],pe=j&&j[1],{onBeforeEnter:ve,onEnter:U,onEnterCancelled:we,onLeave:de,onLeaveCancelled:Oe,onBeforeAppear:ze=ve,onAppear:Le=U,onAppearCancelled:De=we}=i,me=(Q,ne,xe,Re)=>{Q._enterCancelled=Re,Ki(Q,ne?S:_),Ki(Q,ne?M:h),xe&&xe()},$e=(Q,ne)=>{Q._isLeaving=!1,Ki(Q,O),Ki(Q,V),Ki(Q,B),ne&&ne()},be=Q=>(ne,xe)=>{const Re=Q?Le:U,ge=()=>me(ne,Q,xe);Wi(Re,[ne,ge]),Dl(()=>{Ki(ne,Q?y:d),ni(ne,Q?S:_),Il(Re)||Nl(ne,l,F,ge)})};return zt(i,{onBeforeEnter(Q){Wi(ve,[Q]),ni(Q,d),ni(Q,h)},onBeforeAppear(Q){Wi(ze,[Q]),ni(Q,y),ni(Q,M)},onEnter:be(!1),onAppear:be(!0),onLeave(Q,ne){Q._isLeaving=!0;const xe=()=>$e(Q,ne);ni(Q,O),Q._enterCancelled?(ni(Q,B),Bl(Q)):(Bl(Q),ni(Q,B)),Dl(()=>{Q._isLeaving&&(Ki(Q,O),ni(Q,V),Il(de)||Nl(Q,l,pe,xe))}),Wi(de,[Q,xe])},onEnterCancelled(Q){me(Q,!1,void 0,!0),Wi(we,[Q])},onAppearCancelled(Q){me(Q,!0,void 0,!0),Wi(De,[Q])},onLeaveCancelled(Q){$e(Q),Wi(Oe,[Q])}})}function mh(t){if(t==null)return null;if(lt(t))return[or(t.enter),or(t.leave)];{const i=or(t);return[i,i]}}function or(t){return pd(t)}function ni(t,i){i.split(/\s+/).forEach(o=>o&&t.classList.add(o)),(t[_o]||(t[_o]=new Set)).add(i)}function Ki(t,i){i.split(/\s+/).forEach(l=>l&&t.classList.remove(l));const o=t[_o];o&&(o.delete(i),o.size||(t[_o]=void 0))}function Dl(t){requestAnimationFrame(()=>{requestAnimationFrame(t)})}let gh=0;function Nl(t,i,o,l){const u=t._endId=++gh,d=()=>{u===t._endId&&l()};if(o!=null)return setTimeout(d,o);const{type:h,timeout:_,propCount:y}=vh(t,i);if(!h)return l();const M=h+"end";let S=0;const O=()=>{t.removeEventListener(M,B),d()},B=V=>{V.target===t&&++S>=y&&O()};setTimeout(()=>{S<y&&O()},_+1),t.addEventListener(M,B)}function vh(t,i){const o=window.getComputedStyle(t),l=j=>(o[j]||"").split(", "),u=l(`${ki}Delay`),d=l(`${ki}Duration`),h=Rl(u,d),_=l(`${Js}Delay`),y=l(`${Js}Duration`),M=Rl(_,y);let S=null,O=0,B=0;i===ki?h>0&&(S=ki,O=h,B=d.length):i===Js?M>0&&(S=Js,O=M,B=y.length):(O=Math.max(h,M),S=O>0?h>M?ki:Js:null,B=S?S===ki?d.length:y.length:0);const V=S===ki&&/\b(?:transform|all)(?:,|$)/.test(l(`${ki}Property`).toString());return{type:S,timeout:O,propCount:B,hasTransform:V}}function Rl(t,i){for(;t.length<i.length;)t=t.concat(t);return Math.max(...i.map((o,l)=>Fl(o)+Fl(t[l])))}function Fl(t){return t==="auto"?0:Number(t.slice(0,-1).replace(",","."))*1e3}function Bl(t){return(t?t.ownerDocument:document).body.offsetHeight}function _h(t,i,o){const l=t[_o];l&&(i=(i?[i,...l]:[...l]).join(" ")),i==null?t.removeAttribute("class"):o?t.setAttribute("class",i):t.className=i}const ca=Symbol("_vod"),Lc=Symbol("_vsh"),yh={name:"show",beforeMount(t,{value:i},{transition:o}){t[ca]=t.style.display==="none"?"":t.style.disp 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 tm=no.exports,uu;function nm(){return uu||(uu=1,(function(t,i){(function(o,l){l(i)})(tm,(function(o){var l="1.9.4";function u(e){var n,s,a,c;for(s=1,a=arguments.length;s<a;s++){c=arguments[s];for(n in c)e[n]=c[n]}return e}var d=Object.create||(function(){function e(){}return function(n){return e.prototype=n,new e}})();function h(e,n){var s=Array.prototype.slice;if(e.bind)return e.bind.apply(e,s.call(arguments,1));var a=s.call(arguments,2);return function(){return e.apply(n,a.length?a.concat(s.call(arguments)):arguments)}}var _=0;function y(e){return"_leaflet_id"in e||(e._leaflet_id=++_),e._leaflet_id}function M(e,n,s){var a,c,m,C;return C=function(){a=!1,c&&(m.apply(s,c),c=!1)},m=function(){a?c=arguments:(e.apply(s,arguments),setTimeout(C,n),a=!0)},m}function S(e,n,s){var a=n[1],c=n[0],m=a-c;return e===a&&s?e:((e-c)%m+m)%m+c}function O(){return!1}function B(e,n){if(n===!1)return e;var s=Math.pow(10,n===void 0?6:n);return Math.round(e*s)/s}function V(e){return e.trim?e.trim():e.replace(/^\s+|\s+$/g,"")}function j(e){return V(e).split(/\s+/)}function F(e,n){Object.prototype.hasOwnProperty.call(e,"options")||(e.options=e.options?d(e.options):{});for(var s in n)e.options[s]=n[s];return e.options}function pe(e,n,s){var a=[];for(var c in e)a.push(encodeURIComponent(s?c.toUpperCase():c)+"="+encodeURIComponent(e[c]));return(!n||n.indexOf("?")===-1?"?":"&")+a.join("&")}var ve=/\{ *([\w_ -]+) *\}/g;function U(e,n){return e.replace(ve,function(s,a){var c=n[a];if(c===void 0)throw new Error("No value provided for variable "+s);return typeof c=="function"&&(c=c(n)),c})}var we=Array.isArray||function(e){return Object.prototype.toString.call(e)==="[object Array]"};function de(e,n){for(var s=0;s<e.length;s++)if(e[s]===n)return s;return-1}var Oe="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=";function ze(e){return window["webkit"+e]||window["moz"+e]||window["ms"+e]}var Le=0;function De(e){var n=+new Date,s=Math.max(0,16-(n-Le));return Le=n+s,window.setTimeout(e,s)}var me=window.requestAnimationFrame||ze("RequestAnimationFrame")||De,$e=window.cancelAnimationFrame||ze("CancelAnimationFrame")||ze("CancelRequestAnimationFrame")||function(e){window.clearTimeout(e)};function be(e,n,s){if(s&&me===De)e.call(n);else return me.call(window,h(e,n))}function Q(e){e&&$e.call(window,e)}var ne={__proto__:null,extend:u,create:d,bind:h,get lastId(){return _},stamp:y,throttle:M,wrapNum:S,falseFn:O,formatNum:B,trim:V,splitWords:j,setOptions:F,getParamString:pe,template:U,isArray:we,indexOf:de,emptyImageUrl:Oe,requestFn:me,cancelFn:$e,requestAnimFrame:be,cancelAnimFrame:Q};function xe(){}xe.extend=function(e){var n=function(){F(this),this.initialize&&this.initialize.apply(this,arguments),this.callInitHooks()},s=n.__super__=this.prototype,a=d(s);a.constructor=n,n.prototype=a;for(var c in this)Object.prototype.hasOwnProperty.call(this,c)&&c!=="prototype"&&c!=="__super__"&&(n[c]=this[c]);return e.statics&&u(n,e.statics),e.includes&&(Re(e.includes),u.apply(null,[a].concat(e.includes))),u(a,e),delete a.statics,delete a.includes,a.options&&(a.options=s.options?d(s.options):{},u(a.options,e.options)),a._initHooks=[],a.callInitHooks=function(){if(!this._initHooksCalled){s.callInitHooks&&s.callInitHooks.call(this),this._initHooksCalled=!0;for(var m=0,C=a._initHooks.length;m<C;m++)a._initHooks[m].call(this)}},n},xe.include=function(e){var n=this.prototype.options;return u(this.prototype,e),e.options&&(this.prototype.options=n,this.mergeOptions(e.options)),this},xe.mergeOptions=function(e){return u(this.prototype.options,e),this},xe.addInitHook=function(e){var n=Array.prototype.slice.call(arguments,1),s=typeof e=="function"?e:function(){this[e].apply(this,n)};return this.prototype._initHooks=this.prototype._initHooks||[],this.prototype._initHooks.push(s),this};function Re(e){if(!(typeof L>"u"||!L||!L.Mixin)){e=we(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 ge={on:function(e,n,s){if(typeof e=="object")for(var a in e)this._on(a,e[a],n);else{e=j(e);for(var c=0,m=e.length;c<m;c++)this._on(e[c],n,s)}return this},off:function(e,n,s){if(!arguments.length)delete this._events;else if(typeof e=="object")for(var a in e)this._off(a,e[a],n);else{e=j(e);for(var c=arguments.length===1,m=0,C=e.length;m<C;m++)c?this._off(e[m]):this._off(e[m],n,s)}return this},_on:function(e,n,s,a){if(typeof n!="function"){console.warn("wrong listener type: "+typeof n);return}if(this._listens(e,n,s)===!1){s===this&&(s=void 0);var c={fn:n,ctx:s};a&&(c.once=!0),this._events=this._events||{},this._events[e]=this._events[e]||[],this._events[e].push(c)}},_off:function(e,n,s){var a,c,m;if(this._events&&(a=this._events[e],!!a)){if(arguments.length===1){if(this._firingCount)for(c=0,m=a.length;c<m;c++)a[c].fn=O;delete this._events[e];return}if(typeof n!="function"){console.warn("wrong listener type: "Line truncated
-1
View File
@@ -1 +0,0 @@
:root,[data-theme=light]{--navy-950: #0B1730;--navy-900: #0F1E3D;--navy-800: #1B2E52;--navy-700: #26406E;--blue-50: #EAF1FE;--blue-100: #D6E3FD;--blue-200: #B4CDFA;--blue-300: #8FB4F6;--blue-400: #5B93F5;--blue-500: #3D7BF0;--blue-600: #2B62CC;--blue-700: #1F4CA0;--slate-0: #FFFFFF;--slate-50: #F6F7F9;--slate-100: #EEF0F3;--slate-150: #E6E9EE;--slate-200: #DCE0E7;--slate-300: #C5CCD7;--slate-400: #97A1B0;--slate-500: #6B7688;--slate-600: #4C5566;--slate-700: #333B4A;--slate-800: #1E2635;--slate-900: #131A28;--slate-950: #0B111C;--steel: #5A6B85;--green-500: #1F8A5B;--green-100: #DCF1E7;--green-600:#177049;--amber-500: #D9852B;--amber-100: #FBEBD5;--amber-600:#B86C1B;--red-500: #D64545;--red-100: #FBE0E0;--red-600: #B83232;--bg-app: var(--slate-100);--bg-subtle: var(--slate-50);--surface: var(--slate-0);--surface-2: var(--slate-50);--surface-inset: var(--slate-100);--border: var(--slate-200);--border-strong: var(--slate-300);--border-subtle: var(--slate-150);--text-primary: var(--navy-900);--text-secondary:var(--steel);--text-tertiary: var(--slate-400);--text-inverse: var(--slate-0);--text-on-accent:#FFFFFF;--accent: var(--blue-500);--accent-hover: var(--blue-600);--accent-active: var(--blue-700);--accent-soft: var(--blue-50);--accent-soft-fg:var(--blue-700);--focus-ring: color-mix(in srgb, var(--blue-500) 45%, transparent);--success: var(--green-500);--success-soft: var(--green-100);--success-fg: var(--green-600);--warning: var(--amber-500);--warning-soft: var(--amber-100);--warning-fg: var(--amber-600);--danger: var(--red-500);--danger-soft: var(--red-100);--danger-fg: var(--red-600);--overlay: color-mix(in srgb, var(--navy-950) 55%, transparent);--font-sans: "Space Grotesk", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;--font-mono: "Space Mono", ui-monospace, "SF Mono", "JetBrains Mono", monospace;--radius-xs: 4px;--radius-sm: 6px;--radius-md: 10px;--radius-lg: 14px;--radius-xl: 20px;--radius-pill: 999px;--shadow-xs: 0 1px 2px rgba(15,30,61,.06);--shadow-sm: 0 1px 2px rgba(15,30,61,.06), 0 1px 3px rgba(15,30,61,.04);--shadow-md: 0 2px 4px rgba(15,30,61,.06), 0 6px 16px rgba(15,30,61,.08);--shadow-lg: 0 8px 24px rgba(15,30,61,.1), 0 2px 6px rgba(15,30,61,.06);--ease-standard: cubic-bezier(.4, 0, .2, 1);--ease-out: cubic-bezier(.16, 1, .3, 1);--dur-fast: .12s;--dur-base: .2s;color-scheme:light}[data-theme=dark]{--bg-app: var(--navy-950);--bg-subtle: var(--slate-950);--surface: #10203F;--surface-2: #142748;--surface-inset: var(--navy-950);--border: color-mix(in srgb, #FFFFFF 10%, transparent);--border-strong: color-mix(in srgb, #FFFFFF 18%, transparent);--border-subtle: color-mix(in srgb, #FFFFFF 6%, transparent);--text-primary: #F4F7FC;--text-secondary:#8FA0BE;--text-tertiary: #5E6E8C;--text-inverse: var(--navy-900);--text-on-accent:#FFFFFF;--accent: var(--blue-400);--accent-hover: var(--blue-300);--accent-active: var(--blue-200);--accent-soft: color-mix(in srgb, var(--blue-500) 18%, transparent);--accent-soft-fg:var(--blue-300);--focus-ring: color-mix(in srgb, var(--blue-400) 55%, transparent);--success:var(--green-500);--success-soft: color-mix(in srgb, var(--green-500) 22%, transparent);--success-fg:#5FD3A0;--warning:var(--amber-500);--warning-soft: color-mix(in srgb, var(--amber-500) 22%, transparent);--warning-fg:#F0B26A;--danger: var(--red-500);--danger-soft: color-mix(in srgb, var(--red-500) 22%, transparent);--danger-fg: #F08A8A;--overlay: color-mix(in srgb, #000000 62%, transparent);--shadow-xs: 0 1px 2px rgba(0,0,0,.35);--shadow-sm: 0 1px 3px rgba(0,0,0,.4);--shadow-md: 0 4px 12px rgba(0,0,0,.45);--shadow-lg: 0 12px 32px rgba(0,0,0,.5);color-scheme:dark}*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-Line truncated
+2 -2
View File
@@ -35,8 +35,8 @@
})() })()
</script> </script>
<title>PilotVault — Control Panel</title> <title>PilotVault — Control Panel</title>
<script type="module" crossorigin src="./assets/index-CYlCe7LJ.js"></script> <script type="module" crossorigin src="./assets/index-BdIdzNiz.js"></script>
<link rel="stylesheet" crossorigin href="./assets/index-Cy2Ed59q.css"> <link rel="stylesheet" crossorigin href="./assets/index-CYeDXsw9.css">
</head> </head>
<body> <body>
<div id="app"></div> <div id="app"></div>
+11 -2
View File
@@ -168,13 +168,22 @@ export async function testOpenSky() {
// Live aircraft positions (OpenSky state vectors) within the caller's resolved // Live aircraft positions (OpenSky state vectors) within the caller's resolved
// bounding box, for plotting on the Live map. Returns { states, unavailable?, // bounding box, for plotting on the Live map. Returns { states, unavailable?,
// detail? } — an empty list with `unavailable` when OpenSky is off for the caller. // detail?, plan, recommendedInterval } — an empty list with `unavailable` when
// OpenSky is off for the caller. `recommendedInterval` (seconds) is derived from
// the resolved plan and drives the "Auto" refresh cadence.
export async function getOpenSkyStates() { export async function getOpenSkyStates() {
try { try {
const r = await fetch('/bff/integrations/opensky/states') const r = await fetch('/bff/integrations/opensky/states')
if (!r.ok) return { states: [], unavailable: true, detail: 'OpenSky unavailable' } if (!r.ok) return { states: [], unavailable: true, detail: 'OpenSky unavailable' }
const d = await r.json() const d = await r.json()
return { states: d.states || [], time: d.time, unavailable: !!d.unavailable, detail: d.detail || '' } return {
states: d.states || [],
time: d.time,
unavailable: !!d.unavailable,
detail: d.detail || '',
plan: d.plan || '',
recommendedInterval: d.recommendedInterval || 0,
}
} catch { } catch {
return { states: [], unavailable: true, detail: 'OpenSky unavailable' } return { states: [], unavailable: true, detail: 'OpenSky unavailable' }
} }
+51 -11
View File
@@ -27,29 +27,51 @@ const search = ref('')
/* ---------- OpenSky live air traffic (Overview map overlay) ---------- */ /* ---------- OpenSky live air traffic (Overview map overlay) ---------- */
const aircraft = ref([]) // [{ icao24, callsign, lat, lng, heading, velocity, altitude, onGround }] const aircraft = ref([]) // [{ icao24, callsign, lat, lng, heading, velocity, altitude, onGround }]
const airspace = reactive({ unavailable: false, detail: '', loaded: false }) // plan + recommendedInterval are resolved server-side from the OpenSky plan.
const airspace = reactive({ unavailable: false, detail: '', loaded: false, plan: '', recommendedInterval: 30 })
const airborneCount = computed(() => aircraft.value.filter((a) => !a.onGround).length) const airborneCount = computed(() => aircraft.value.filter((a) => !a.onGround).length)
const mapMenu = ref(false) // "Map settings" popover open state const mapMenu = ref(false) // "Map settings" popover open state
let airTimer = null let airTimer = null
// User-selectable cadences; "Auto" defers to the plan-recommended interval.
const INTERVAL_OPTIONS = [
{ value: 'auto', label: 'Auto' },
{ value: 15, label: '15s' },
{ value: 30, label: '30s' },
{ value: 60, label: '60s' },
{ value: 120, label: '120s' },
]
// Effective poll interval in seconds: the plan recommendation when 'auto', else the
// chosen fixed value. Falls back to 30s if the recommendation hasn't loaded yet.
const airIntervalSeconds = computed(() => {
if (prefs.airTrafficInterval === 'auto') return airspace.recommendedInterval || 30
const n = Number(prefs.airTrafficInterval)
return Number.isFinite(n) && n > 0 ? n : 30
})
async function refreshAirspace() { async function refreshAirspace() {
if (!prefs.showAirTraffic) return if (!prefs.showAirTraffic) return
const { states, unavailable, detail } = await getOpenSkyStates() const { states, unavailable, detail, plan, recommendedInterval } = await getOpenSkyStates()
aircraft.value = states aircraft.value = states
airspace.unavailable = unavailable airspace.unavailable = unavailable
airspace.detail = detail airspace.detail = detail
airspace.plan = plan || ''
if (recommendedInterval) airspace.recommendedInterval = recommendedInterval
airspace.loaded = true airspace.loaded = true
} }
// Poll OpenSky only while the Overview map is on screen and the overlay is // Poll OpenSky only while the Overview map is on screen and the overlay is enabled,
// enabled, on a credit-friendly cadence (state vectors refresh at most every // on the resolved cadence (state vectors refresh at most every ~5–10s upstream).
// ~10s upstream anyway). function scheduleAirspace() {
function startAirspace() { if (airTimer) clearInterval(airTimer)
if (airTimer) return
refreshAirspace()
airTimer = setInterval(() => { airTimer = setInterval(() => {
if (active.value === 'Overview' && prefs.showAirTraffic) refreshAirspace() if (active.value === 'Overview' && prefs.showAirTraffic) refreshAirspace()
}, 30000) }, airIntervalSeconds.value * 1000)
}
function startAirspace() {
refreshAirspace()
scheduleAirspace()
} }
function stopAirspace() { function stopAirspace() {
if (airTimer) clearInterval(airTimer) if (airTimer) clearInterval(airTimer)
@@ -296,6 +318,10 @@ watch(
}, },
) )
// Reschedule polling whenever the effective interval changes (a manual choice, or
// the plan recommendation arriving while on "Auto").
watch(airIntervalSeconds, scheduleAirspace)
onMounted(async () => { onMounted(async () => {
;(await getDevices()).forEach(upsert) ;(await getDevices()).forEach(upsert)
connect() connect()
@@ -450,12 +476,26 @@ onBeforeUnmount(() => {
</button> </button>
<template v-if="mapMenu"> <template v-if="mapMenu">
<div class="fixed inset-0 z-[1190]" @click="mapMenu = false"></div> <div class="fixed inset-0 z-[1190]" @click="mapMenu = false"></div>
<div class="panel absolute right-0 z-[1200] mt-1.5 w-64 p-3.5 shadow-lg"> <div class="panel absolute right-0 z-[1200] mt-1.5 w-72 p-3.5 shadow-lg">
<div class="eyebrow mb-2.5">Map settings</div> <div class="eyebrow mb-2.5">Map settings</div>
<label class="flex items-center justify-between gap-3"> <label class="flex items-center justify-between gap-3">
<span class="text-sm text-ink-secondary">Show live air traffic</span> <span class="text-sm text-ink-secondary">Show live air traffic</span>
<Toggle v-model="prefs.showAirTraffic" /> <Toggle v-model="prefs.showAirTraffic" />
</label> </label>
<div class="mt-3.5" :class="prefs.showAirTraffic ? '' : 'pointer-events-none opacity-40'">
<div class="mb-1.5 flex items-center justify-between">
<span class="text-sm text-ink-secondary">Refresh interval</span>
<span class="font-mono text-[11px] text-ink-muted">every {{ airIntervalSeconds }}s</span>
</div>
<select v-model="prefs.airTrafficInterval" class="field">
<option v-for="o in INTERVAL_OPTIONS" :key="o.value" :value="o.value">
{{ o.label }}{{ o.value === 'auto' ? ` (plan: ${airspace.recommendedInterval}s)` : '' }}
</option>
</select>
<p v-if="airspace.plan" class="mt-1.5 text-[11px] text-ink-muted">
OpenSky plan: {{ airspace.plan }}
</p>
</div>
</div> </div>
</template> </template>
</div> </div>
@@ -469,7 +509,7 @@ onBeforeUnmount(() => {
{{ airspace.detail || 'Live air traffic is unavailable.' }} {{ airspace.detail || 'Live air traffic is unavailable.' }}
</p> </p>
<p v-else class="mt-2.5 text-xs text-ink-muted"> <p v-else class="mt-2.5 text-xs text-ink-muted">
Live air traffic from OpenSky Network · updates every 30s Live air traffic from OpenSky Network · updates every {{ airIntervalSeconds }}s
</p> </p>
</div> </div>
+3
View File
@@ -29,6 +29,9 @@ const defaults = {
// Live map: overlay live OpenSky air traffic (client-side toggle; the OpenSky // Live map: overlay live OpenSky air traffic (client-side toggle; the OpenSky
// integration itself is still gated in Settings → Integrations). // integration itself is still gated in Settings → Integrations).
showAirTraffic: true, showAirTraffic: true,
// Air-traffic refresh cadence: 'auto' follows the plan-recommended interval
// (from the server), or a fixed number of seconds (15 | 30 | 60 | 120).
airTrafficInterval: 'auto',
// Security (prototype) // Security (prototype)
twoFactor: false, twoFactor: false,
} }