Add location-aware automatic default bounding box
The OpenSky "Default bounding box" now follows where flying happens. A new "Automatic" picker mode (the default) resolves the live-map area from a location cascade — drone telemetry → phone GPS → browser geolocation → the user's Region country → Europe — instead of a fixed box. Manual presets and Custom coordinates still work. - Web App: new shared countries.js dataset (all countries + bbox, offline point→country); the bbox picker gains all European countries and an Automatic option (client pref prefs.autoBbox); the Region setting expands from 6 locale entries to all countries; the live map resolves the cascade each poll and sends it as ?bbox=. - API Server: the states endpoint accepts and validates a ?bbox= override (validBBox); the Web App BFF forwards the query; the hub relays new phoneLatitude/phoneLongitude telemetry to the Web App. - Fly App: reports the phone's own GPS (geolocator) alongside telemetry, used as the "your location" fallback. - API panel: the OpenSky bbox picker lists all European countries. Builds verified across web, panel, both Go modules and the Fly App APK. Region list, Automatic default and the cascade ?bbox= override verified in the browser. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
150758b0bf
commit
94f6876024
20 files changed
+637
-71
No files matched your search
@@ -1,17 +0,0 @@
|
||||
(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const o of document.querySelectorAll('link[rel="modulepreload"]'))n(o);new MutationObserver(o=>{for(const i of o)if(i.type==="childList")for(const l of i.addedNodes)l.tagName==="LINK"&&l.rel==="modulepreload"&&n(l)}).observe(document,{childList:!0,subtree:!0});function s(o){const i={};return o.integrity&&(i.integrity=o.integrity),o.referrerPolicy&&(i.referrerPolicy=o.referrerPolicy),o.crossOrigin==="use-credentials"?i.credentials="include":o.crossOrigin==="anonymous"?i.credentials="omit":i.credentials="same-origin",i}function n(o){if(o.ep)return;o.ep=!0;const i=s(o);fetch(o.href,i)}})();/**
|
||||
* @vue/shared v3.5.39
|
||||
* (c) 2018-present Yuxi (Evan) You and Vue contributors
|
||||
* @license MIT
|
||||
**/function An(e){const t=Object.create(null);for(const s of e.split(","))t[s]=1;return s=>s in t}const ne={},Nt=[],tt=()=>{},$o=()=>!1,Ks=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),zs=e=>e.startsWith("onUpdate:"),Se=Object.assign,On=(e,t)=>{const s=e.indexOf(t);s>-1&&e.splice(s,1)},Qi=Object.prototype.hasOwnProperty,Q=(e,t)=>Qi.call(e,t),N=Array.isArray,Ft=e=>ms(e)==="[object Map]",Wt=e=>ms(e)==="[object Set]",eo=e=>ms(e)==="[object Date]",B=e=>typeof e=="function",ce=e=>typeof e=="string",st=e=>typeof e=="symbol",te=e=>e!==null&&typeof e=="object",jo=e=>(te(e)||B(e))&&B(e.then)&&B(e.catch),Do=Object.prototype.toString,ms=e=>Do.call(e),el=e=>ms(e).slice(8,-1),Lo=e=>ms(e)==="[object Object]",Rn=e=>ce(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,ss=An(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),Ws=e=>{const t=Object.create(null);return(s=>t[s]||(t[s]=e(s)))},tl=/-\w/g,Be=Ws(e=>e.replace(tl,t=>t.slice(1).toUpperCase())),sl=/\B([A-Z])/g,xt=Ws(e=>e.replace(sl,"-$1").toLowerCase()),No=Ws(e=>e.charAt(0).toUpperCase()+e.slice(1)),on=Ws(e=>e?`on${No(e)}`:""),et=(e,t)=>!Object.is(e,t),Is=(e,...t)=>{for(let s=0;s<e.length;s++)e[s](...t)},Fo=(e,t,s,n=!1)=>{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:n,value:s})},Gs=e=>{const t=parseFloat(e);return isNaN(t)?e:t};let to;const qs=()=>to||(to=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function In(e){if(N(e)){const t={};for(let s=0;s<e.length;s++){const n=e[s],o=ce(n)?ll(n):In(n);if(o)for(const i in o)t[i]=o[i]}return t}else if(ce(e)||te(e))return e}const nl=/;(?![^(]*\))/g,ol=/:([^]+)/,il=/\/\*[^]*?\*\//g;function ll(e){const t={};return e.replace(il,"").split(nl).forEach(s=>{if(s){const n=s.split(ol);n.length>1&&(t[n[0].trim()]=n[1].trim())}}),t}function Ue(e){let t="";if(ce(e))t=e;else if(N(e))for(let s=0;s<e.length;s++){const n=Ue(e[s]);n&&(t+=n+" ")}else if(te(e))for(const s in e)e[s]&&(t+=s+" ");return t.trim()}const rl="itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly",al=An(rl);function Vo(e){return!!e||e===""}function cl(e,t){if(e.length!==t.length)return!1;let s=!0;for(let n=0;s&&n<e.length;n++)s=vt(e[n],t[n]);return s}function vt(e,t){if(e===t)return!0;let s=eo(e),n=eo(t);if(s||n)return s&&n?e.getTime()===t.getTime():!1;if(s=st(e),n=st(t),s||n)return e===t;if(s=N(e),n=N(t),s||n)return s&&n?cl(e,t):!1;if(s=te(e),n=te(t),s||n){if(!s||!n)return!1;const o=Object.keys(e).length,i=Object.keys(t).length;if(o!==i)return!1;for(const l in e){const r=e.hasOwnProperty(l),c=t.hasOwnProperty(l);if(r&&!c||!r&&c||!vt(e[l],t[l]))return!1}}return String(e)===String(t)}function Mn(e,t){return e.findIndex(s=>vt(s,t))}const Ho=e=>!!(e&&e.__v_isRef===!0),O=e=>ce(e)?e:e==null?"":N(e)||te(e)&&(e.toString===Do||!B(e.toString))?Ho(e)?O(e.value):JSON.stringify(e,Bo,2):String(e),Bo=(e,t)=>Ho(t)?Bo(e,t.value):Ft(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((s,[n,o],i)=>(s[ln(n,i)+" =>"]=o,s),{})}:Wt(t)?{[`Set(${t.size})`]:[...t.values()].map(s=>ln(s))}:st(t)?ln(t):te(t)&&!N(t)&&!Lo(t)?String(t):t,ln=(e,t="")=>{var s;return st(e)?`Symbol(${(s=e.description)!=null?s:t})`:e};/**
|
||||
* @vue/reactivity v3.5.39
|
||||
* (c) 2018-present Yuxi (Evan) You and Vue contributors
|
||||
* @license MIT
|
||||
**/let ve;class ul{constructor(t=!1){this.detached=t,this._active=!0,this._on=0,this.effects=[],this.cleanups=[],this._isPaused=!1,this._warnOnRun=!0,this.__v_skip=!0,!t&&ve&&(ve.active?(this.parent=ve,this.index=(ve.scopes||(ve.scopes=[])).push(this)-1):(this._active=!1,this._warnOnRun=!1))}get active(){return this._active}pause(){if(this._active){this._isPaused=!0;let t,s;if(this.scopes)for(t=0,s=this.scopes.length;t<s;t++)this.scopes[t].pause();for(t=0,s=this.effects.length;t<s;t++)this.effects[t].pause()}}resume(){if(this._active&&this._isPaused){this._isPaused=!1;let t,s;if(this.scopes)for(t=0,s=this.scopes.length;t<s;t++)this.scopes[t].resume();for(t=0,s=this.effects.length;t<s;t++)this.effects[t].resume()}}run(t){if(this._active){const s=ve;try{return ve=this,t()}finally{ve=s}}}on(){++this._on===1&&(this.prevScope=ve,ve=this)}off(){if(this._on>0&&--this._on===0){if(ve===this)ve=this.prevScope;else{let t=ve;for(;t;){if(t.prevScope===this){t.prevScope=this.prevScope;break}t=t.prevScope}}this.prevScope=void 0}}stop(t){if(this._active){this._active=!1;let s,n;for(s=0,n=this.effects.length;s<n;s++)this.effects[s].stop();for(this.effects.length=0,s=0,n=this.cleanups.length;s<n;s++)this.cleanups[s]();if(this.cleanups.length=0,this.scopes){for(s=0,n=this.scopes.length;s<n;s++)this.scopes[s].stop(!0);this.scopes.length=0}if(!this.detached&&this.parent&&!t){const o=this.parent.scopes.pop();o&&o!==this&&(this.parent.scopes[this.index]=o,o.index=this.index)}this.parent=void 0}}}function fl(){return ve}let re;const rn=new WeakSet;class Ko{constructor(t){this.fn=t,this.deps=void 0,this.depsTail=void 0,this.flags=5,this.next=void 0,this.cleanup=void 0,this.scheduler=void 0,ve&&(ve.active?ve.effects.push(this):this.flags&=-2)}pause(){this.flags|=64}resume(){this.flags&64&&(this.flags&=-65,rn.has(this)&&(rn.delete(this),this.trigger()))}notify(){this.flags&2&&!(this.flags&32)||this.flags&8||Wo(this)}run(){if(!(this.flags&1))return this.fn();this.flags|=2,so(this),Go(this);const t=re,s=Ke;re=this,Ke=!0;try{return this.fn()}finally{qo(this),re=t,Ke=s,this.flags&=-3}}stop(){if(this.flags&1){for(let t=this.deps;t;t=t.nextDep)jn(t);this.deps=this.depsTail=void 0,so(this),this.onStop&&this.onStop(),this.flags&=-2}}trigger(){this.flags&64?rn.add(this):this.scheduler?this.scheduler():this.runIfDirty()}runIfDirty(){vn(this)&&this.run()}get dirty(){return vn(this)}}let zo=0,ns,os;function Wo(e,t=!1){if(e.flags|=8,t){e.next=os,os=e;return}e.next=ns,ns=e}function Un(){zo++}function $n(){if(--zo>0)return;if(os){let t=os;for(os=void 0;t;){const s=t.next;t.next=void 0,t.flags&=-9,t=s}}let e;for(;ns;){let t=ns;for(ns=void 0;t;){const s=t.next;if(t.next=void 0,t.flags&=-9,t.flags&1)try{t.trigger()}catch(n){e||(e=n)}t=s}}if(e)throw e}function Go(e){for(let t=e.deps;t;t=t.nextDep)t.version=-1,t.prevActiveLink=t.dep.activeLink,t.dep.activeLink=t}function qo(e){let t,s=e.depsTail,n=s;for(;n;){const o=n.prevDep;n.version===-1?(n===s&&(s=o),jn(n),dl(n)):t=n,n.dep.activeLink=n.prevActiveLink,n.prevActiveLink=void 0,n=o}e.deps=t,e.depsTail=s}function vn(e){for(let t=e.deps;t;t=t.nextDep)if(t.dep.version!==t.version||t.dep.computed&&(Jo(t.dep.computed)||t.dep.version!==t.version))return!0;return!!e._dirty}function Jo(e){if(e.flags&4&&!(e.flags&16)||(e.flags&=-17,e.globalVersion===cs)||(e.globalVersion=cs,!e.isSSR&&e.flags&128&&(!e.deps&&!e._dirty||!vn(e))))return;e.flags|=2;const t=e.dep,s=re,n=Ke;re=e,Ke=!0;try{Go(e);const o=e.fn(e._value);(t.version===0||et(o,e._value))&&(e.flags|=128,e._value=o,t.version++)}catch(o){throw t.version++,o}finally{re=s,Ke=n,qo(e),e.flags&=-3}}function jn(e,t=!1){const{dep:s,prevSub:n,nextSub:o}=e;if(n&&(n.nextSub=o,e.prevSub=void 0),o&&(o.prevSub=n,e.nextSub=void 0),s.subs===e&&(s.subs=n,!n&&s.computed)){s.computed.flags&=-5;for(let i=s.computed.deps;i;i=i.nextDep)jn(i,!0)}!t&&!--s.sc&&s.map&&s.map.delete(s.key)}function dl(e){const{prevDep:t,nextDep:s}=e;t&&(t.nextDep=s,e.prevDep=void 0),s&&(s.prevDep=t,e.nextDep=void 0)}let Ke=!0;const Yo=[];function nt(){Yo.push(Ke),Ke=!1}function ot(){const e=Yo.pop();Ke=e===void 0?!0:e}function so(e){const{cleanup:t}=e;if(e.cleanup=void 0,t){const s=re;re=void 0;try{t()}finally{re=s}}}let cs=0;class pl{constructor(t,s){this.sub=t,this.dep=s,this.version=s.version,this.nextDep=this.prevDep=this.nextSub=this.prevSub=this.prevActiveLink=void 0}}class Dn{constructor(t){this.computed=t,this.version=0,this.activeLink=void 0,this.subs=void 0,this.map=void 0,this.key=void 0,this.sc=0,this.__v_skip=!0}track(t){if(!re||!Ke||re===this.computed)return;let s=this.activeLink;if(s===void 0||s.sub!==re)s=this.activeLink=new pl(re,this),re.deps?(s.prevDep=re.depsTail,re.depsTail.nextDep=s,re.depsTail=s):re.deps=re.depsTail=s,Xo(s);else if(s.version===-1&&(s.version=this.version,s.nextDep)){const n=s.nextDep;n.prevDep=s.prevDep,s.prevDep&&(s.prevDep.nextDep=n),s.prevDep=re.depsTail,s.nextDep=void 0,re.depsTail.nextDep=s,re.depsTail=s,re.deps===s&&(re.deps=n)}return s}trigger(t){this.versiLine truncated
|
||||
* @vue/runtime-core v3.5.39
|
||||
* (c) 2018-present Yuxi (Evan) You and Vue contributors
|
||||
* @license MIT
|
||||
**/function gs(e,t,s,n){try{return n?e(...n):e()}catch(o){Ys(o,t,s)}}function We(e,t,s,n){if(B(e)){const o=gs(e,t,s,n);return o&&jo(o)&&o.catch(i=>{Ys(i,t,s)}),o}if(N(e)){const o=[];for(let i=0;i<e.length;i++)o.push(We(e[i],t,s,n));return o}}function Ys(e,t,s,n=!0){const o=t?t.vnode:null,{errorHandler:i,throwUnhandledErrorInProduction:l}=t&&t.appContext.config||ne;if(t){let r=t.parent;const c=t.proxy,g=`https://vuejs.org/error-reference/#runtime-${s}`;for(;r;){const h=r.ec;if(h){for(let y=0;y<h.length;y++)if(h[y](e,c,g)===!1)return}r=r.parent}if(i){nt(),gs(i,null,10,[e,c,g]),ot();return}}Ll(e,s,o,n,l)}function Ll(e,t,s,n=!0,o=!1){if(o)throw e;console.error(e)}const Pe=[];let Xe=-1;const Vt=[];let gt=null,Dt=0;const ii=Promise.resolve();let Ds=null;function li(e){const t=Ds||ii;return e?t.then(this?e.bind(this):e):t}function Nl(e){let t=Xe+1,s=Pe.length;for(;t<s;){const n=t+s>>>1,o=Pe[n],i=fs(o);i<e||i===e&&o.flags&2?t=n+1:s=n}return t}function Hn(e){if(!(e.flags&1)){const t=fs(e),s=Pe[Pe.length-1];!s||!(e.flags&2)&&t>=fs(s)?Pe.push(e):Pe.splice(Nl(t),0,e),e.flags|=1,ri()}}function ri(){Ds||(Ds=ii.then(ci))}function Fl(e){N(e)?Vt.push(...e):gt&&e.id===-1?gt.splice(Dt+1,0,e):e.flags&1||(Vt.push(e),e.flags|=1),ri()}function oo(e,t,s=Xe+1){for(;s<Pe.length;s++){const n=Pe[s];if(n&&n.flags&2){if(e&&n.id!==e.uid)continue;Pe.splice(s,1),s--,n.flags&4&&(n.flags&=-2),n(),n.flags&4||(n.flags&=-2)}}}function ai(e){if(Vt.length){const t=[...new Set(Vt)].sort((s,n)=>fs(s)-fs(n));if(Vt.length=0,gt){gt.push(...t);return}for(gt=t,Dt=0;Dt<gt.length;Dt++){const s=gt[Dt];s.flags&4&&(s.flags&=-2),s.flags&8||s(),s.flags&=-2}gt=null,Dt=0}}const fs=e=>e.id==null?e.flags&2?-1:1/0:e.id;function ci(e){try{for(Xe=0;Xe<Pe.length;Xe++){const t=Pe[Xe];t&&!(t.flags&8)&&(t.flags&4&&(t.flags&=-2),gs(t,t.i,t.i?15:14),t.flags&4||(t.flags&=-2))}}finally{for(;Xe<Pe.length;Xe++){const t=Pe[Xe];t&&(t.flags&=-2)}Xe=-1,Pe.length=0,ai(),Ds=null,(Pe.length||Vt.length)&&ci()}}let Fe=null,ui=null;function Ls(e){const t=Fe;return Fe=e,ui=e&&e.type.__scopeId||null,t}function Vl(e,t=Fe,s){if(!t||e._n)return e;const n=(...o)=>{n._d&&go(-1);const i=Ls(t);let l;try{l=e(...o)}finally{Ls(i),n._d&&go(1)}return l};return n._n=!0,n._c=!0,n._d=!0,n}function le(e,t){if(Fe===null)return e;const s=en(Fe),n=e.dirs||(e.dirs=[]);for(let o=0;o<t.length;o++){let[i,l,r,c=ne]=t[o];i&&(B(i)&&(i={mounted:i,updated:i}),i.deep&&ft(l),n.push({dir:i,instance:s,value:l,oldValue:void 0,arg:r,modifiers:c}))}return e}function St(e,t,s,n){const o=e.dirs,i=t&&t.dirs;for(let l=0;l<o.length;l++){const r=o[l];i&&(r.oldValue=i[l].value);let c=r.dir[n];c&&(nt(),We(c,s,8,[e.el,r,e,t]),ot())}}function Hl(e,t){if(Ae){let s=Ae.provides;const n=Ae.parent&&Ae.parent.provides;n===s&&(s=Ae.provides=Object.create(n)),s[e]=t}}function Ms(e,t,s=!1){const n=Vr();if(n||Ht){let o=Ht?Ht._context.provides:n?n.parent==null||n.ce?n.vnode.appContext&&n.vnode.appContext.provides:n.parent.provides:void 0;if(o&&e in o)return o[e];if(arguments.length>1)return s&&B(t)?t.call(n&&n.proxy):t}}const Bl=Symbol.for("v-scx"),Kl=()=>Ms(Bl);function un(e,t,s){return fi(e,t,s)}function fi(e,t,s=ne){const{immediate:n,deep:o,flush:i,once:l}=s,r=Se({},s),c=t&&n||!t&&i!=="post";let g;if(ps){if(i==="sync"){const M=Kl();g=M.__watcherHandles||(M.__watcherHandles=[])}else if(!c){const M=()=>{};return M.stop=tt,M.resume=tt,M.pause=tt,M}}const h=Ae;r.call=(M,q,U)=>We(M,h,q,U);let y=!1;i==="post"?r.scheduler=M=>{Re(M,h&&h.suspense)}:i!=="sync"&&(y=!0,r.scheduler=(M,q)=>{q?M():Hn(M)}),r.augmentJob=M=>{t&&(M.flags|=4),y&&(M.flags|=2,h&&(M.id=h.uid,M.i=h))};const R=Dl(e,t,r);return ps&&(g?g.push(R):c&&R()),R}function zl(e,t,s){const n=this.proxy,o=ce(e)?e.includes(".")?di(n,e):()=>n[e]:e.bind(n,n);let i;B(t)?i=t:(i=t.handler,s=t);const l=vs(this),r=fi(o,i.bind(n),s);return l(),r}function di(e,t){const s=t.split(".");return()=>{let n=e;for(let o=0;o<s.length&&n;o++)n=n[s[o]];return n}}const Wl=Symbol("_vte"),Gl=e=>e.__isTeleport,fn=Symbol("_leaveCb");function Bn(e,t){e.shapeFlag&6&&e.component?(e.transition=t,Bn(e.component.subTree,t)):e.shapeFlag&128?(e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback)):e.transition=t}function pi(e){e.ids=[e.ids[0]+e.ids[2]+++"-",0,0]}function io(e,t){let s;return!!((s=Object.getOwnPropertyDescriptor(e,t))&&!s.configurable)}const Ns=new WeakMap;function is(e,t,s,n,o=!1){if(N(e)){e.forEach((U,W)=>is(U,t&&(N(t)?t[W]:t),s,n,o));return}if(ls(n)&&!o){n.shapeFlag&512&&n.type.__asyncResolved&&n.component.subTree.component&&is(e,t,s,n.component.subTree);return}const i=n.shapeFlag&4?en(n.component):n.el,l=o?null:i,{i:r,r:c}=e,g=t&&t.r,h=r.refs===ne?r.refs={}:r.refs,y=r.setupState,R=Z(y),M=y===ne?$o:U=>io(h,U)?!1:Q(R,U),q=(U,W)=>!(W&&io(h,W));if(g!=null&&g!==c){if(lo(t),ce(g))h[g]=null,M(g)&&(y[g]=null);else if(Ce(g)){const U=t;q(g,U.k)&&(g.value=null),U.k&&(h[U.k]=null)}}if(B(c)){nt();try{gs(c,r,12,[l,h])}finally{ot()}}else{const U=ce(c),W=Ce(c);if(U||W){const Y=()=>{if(e.f
Line truncated
|
||||
* @vue/runtime-dom v3.5.39
|
||||
* (c) 2018-present Yuxi (Evan) You and Vue contributors
|
||||
* @license MIT
|
||||
**/let Pn;const yo=typeof window<"u"&&window.trustedTypes;if(yo)try{Pn=yo.createPolicy("vue",{createHTML:e=>e})}catch{}const Ni=Pn?e=>Pn.createHTML(e):e=>e,qr="http://www.w3.org/2000/svg",Jr="http://www.w3.org/1998/Math/MathML",at=typeof document<"u"?document:null,xo=at&&at.createElement("template"),Yr={insert:(e,t,s)=>{t.insertBefore(e,s||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,s,n)=>{const o=t==="svg"?at.createElementNS(qr,e):t==="mathml"?at.createElementNS(Jr,e):s?at.createElement(e,{is:s}):at.createElement(e);return e==="select"&&n&&n.multiple!=null&&o.setAttribute("multiple",n.multiple),o},createText:e=>at.createTextNode(e),createComment:e=>at.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>at.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,s,n,o,i){const l=s?s.previousSibling:t.lastChild;if(o&&(o===i||o.nextSibling))for(;t.insertBefore(o.cloneNode(!0),s),!(o===i||!(o=o.nextSibling)););else{xo.innerHTML=Ni(n==="svg"?`<svg>${e}</svg>`:n==="mathml"?`<math>${e}</math>`:e);const r=xo.content;if(n==="svg"||n==="mathml"){const c=r.firstChild;for(;c.firstChild;)r.appendChild(c.firstChild);r.removeChild(c)}t.insertBefore(r,s)}return[l?l.nextSibling:t.firstChild,s?s.previousSibling:t.lastChild]}},Xr=Symbol("_vtc");function Zr(e,t,s){const n=e[Xr];n&&(t=(t?[t,...n]:[...n]).join(" ")),t==null?e.removeAttribute("class"):s?e.setAttribute("class",t):e.className=t}const Bs=Symbol("_vod"),Fi=Symbol("_vsh"),Xt={name:"show",beforeMount(e,{value:t},{transition:s}){e[Bs]=e.style.display==="none"?"":e.style.display,s&&t?s.beforeEnter(e):Zt(e,t)},mounted(e,{value:t},{transition:s}){s&&t&&s.enter(e)},updated(e,{value:t,oldValue:s},{transition:n}){!t!=!s&&(n?t?(n.beforeEnter(e),Zt(e,!0),n.enter(e)):n.leave(e,()=>{Zt(e,!1)}):Zt(e,t))},beforeUnmount(e,{value:t}){Zt(e,t)}};function Zt(e,t){e.style.display=t?e[Bs]:"none",e[Fi]=!t}const Qr=Symbol(""),ea=/(?:^|;)\s*display\s*:/;function ta(e,t,s){const n=e.style,o=ce(s);let i=!1;if(s&&!o){if(t)if(ce(t))for(const l of t.split(";")){const r=l.slice(0,l.indexOf(":")).trim();s[r]==null&&ts(n,r,"")}else for(const l in t)s[l]==null&&ts(n,l,"");for(const l in s){l==="display"&&(i=!0);const r=s[l];r!=null?na(e,l,!ce(t)&&t?t[l]:void 0,r)||ts(n,l,r):ts(n,l,"")}}else if(o){if(t!==s){const l=n[Qr];l&&(s+=";"+l),n.cssText=s,i=ea.test(s)}}else t&&e.removeAttribute("style");Bs in e&&(e[Bs]=i?n.display:"",e[Fi]&&(n.display="none"))}const _o=/\s*!important$/;function ts(e,t,s){if(N(s))s.forEach(n=>ts(e,t,n));else if(s==null&&(s=""),t.startsWith("--"))e.setProperty(t,s);else{const n=sa(e,t);_o.test(s)?e.setProperty(xt(n),s.replace(_o,""),"important"):e[n]=s}}const wo=["Webkit","Moz","ms"],hn={};function sa(e,t){const s=hn[t];if(s)return s;let n=Be(t);if(n!=="filter"&&n in e)return hn[t]=n;n=No(n);for(let o=0;o<wo.length;o++){const i=wo[o]+n;if(i in e)return hn[t]=i}return t}function na(e,t,s,n){return e.tagName==="TEXTAREA"&&(t==="width"||t==="height")&&ce(n)&&s===n}const Co="http://www.w3.org/1999/xlink";function So(e,t,s,n,o,i=al(t)){n&&t.startsWith("xlink:")?s==null?e.removeAttributeNS(Co,t.slice(6,t.length)):e.setAttributeNS(Co,t,s):s==null||i&&!Vo(s)?e.removeAttribute(t):e.setAttribute(t,i?"":st(s)?String(s):s)}function ko(e,t,s,n,o){if(t==="innerHTML"||t==="textContent"){s!=null&&(e[t]=t==="innerHTML"?Ni(s):s);return}const i=e.tagName;if(t==="value"&&i!=="PROGRESS"&&!i.includes("-")){const r=i==="OPTION"?e.getAttribute("value")||"":e.value,c=s==null?e.type==="checkbox"?"on":"":String(s);(r!==c||!("_value"in e))&&(e.value=c),s==null&&e.removeAttribute(t),e._value=s;return}let l=!1;if(s===""||s==null){const r=typeof e[t];r==="boolean"?s=Vo(s):s==null&&r==="string"?(s="",l=!0):r==="number"&&(s=0,l=!0)}try{e[t]=s}catch{}l&&e.removeAttribute(o||t)}function dt(e,t,s,n){e.addEventListener(t,s,n)}function oa(e,t,s,n){e.removeEventListener(t,s,n)}const Eo=Symbol("_vei");function ia(e,t,s,n,o=null){const i=e[Eo]||(e[Eo]={}),l=i[t];if(n&&l)l.value=n;else{const[r,c]=aa(t);if(n){const g=i[t]=fa(n,o);dt(e,r,g,c)}else l&&(oa(e,r,l,c),i[t]=void 0)}}const la=/(Once|Passive|Capture)$/,ra=/^on:?(?:Once|Passive|Capture)$/;function aa(e){let t,s;for(;(s=e.match(la))&&!ra.test(e);)t||(t={}),e=e.slice(0,e.length-s[1].length),t[s[1].toLowerCase()]=!0;return[e[2]===":"?e.slice(3):xt(e.slice(2)),t]}let mn=0;const ca=Promise.resolve(),ua=()=>mn||(ca.then(()=>mn=0),mn=Date.now());function fa(e,t){const s=n=>{if(!n._vts)n._vts=Date.now();else if(n._vts<=s.attached)return;const o=s.value;if(N(o)){const i=n.stopImmediatePropagation;n.stopImmediatePropagation=()=>{i.call(n),n._stopped=!0};const l=o.slice(),r=[n];for(let c=0;c<l.length&&!n._stopped;c++){const g=l[c];g&&We(g,t,5,r)}}else We(o,t,5,[n])};return s.value=e,s.attached=ua(),s}const To=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,da=(e,t,s,n,o
Line truncated
|
||||
@@ -0,0 +1,17 @@
|
||||
(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const l of document.querySelectorAll('link[rel="modulepreload"]'))n(l);new MutationObserver(l=>{for(const o of l)if(o.type==="childList")for(const i of o.addedNodes)i.tagName==="LINK"&&i.rel==="modulepreload"&&n(i)}).observe(document,{childList:!0,subtree:!0});function s(l){const o={};return l.integrity&&(o.integrity=l.integrity),l.referrerPolicy&&(o.referrerPolicy=l.referrerPolicy),l.crossOrigin==="use-credentials"?o.credentials="include":l.crossOrigin==="anonymous"?o.credentials="omit":o.credentials="same-origin",o}function n(l){if(l.ep)return;l.ep=!0;const o=s(l);fetch(l.href,o)}})();/**
|
||||
* @vue/shared v3.5.39
|
||||
* (c) 2018-present Yuxi (Evan) You and Vue contributors
|
||||
* @license MIT
|
||||
**/function An(e){const t=Object.create(null);for(const s of e.split(","))t[s]=1;return s=>s in t}const ne={},Nt=[],tt=()=>{},Ul=()=>!1,Ks=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),zs=e=>e.startsWith("onUpdate:"),Se=Object.assign,On=(e,t)=>{const s=e.indexOf(t);s>-1&&e.splice(s,1)},Qo=Object.prototype.hasOwnProperty,Q=(e,t)=>Qo.call(e,t),N=Array.isArray,Ft=e=>gs(e)==="[object Map]",Wt=e=>gs(e)==="[object Set]",el=e=>gs(e)==="[object Date]",B=e=>typeof e=="function",ce=e=>typeof e=="string",st=e=>typeof e=="symbol",te=e=>e!==null&&typeof e=="object",$l=e=>(te(e)||B(e))&&B(e.then)&&B(e.catch),jl=Object.prototype.toString,gs=e=>jl.call(e),ei=e=>gs(e).slice(8,-1),Ll=e=>gs(e)==="[object Object]",Mn=e=>ce(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,ss=An(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),Ws=e=>{const t=Object.create(null);return(s=>t[s]||(t[s]=e(s)))},ti=/-\w/g,Be=Ws(e=>e.replace(ti,t=>t.slice(1).toUpperCase())),si=/\B([A-Z])/g,xt=Ws(e=>e.replace(si,"-$1").toLowerCase()),Dl=Ws(e=>e.charAt(0).toUpperCase()+e.slice(1)),ln=Ws(e=>e?`on${Dl(e)}`:""),et=(e,t)=>!Object.is(e,t),Rs=(e,...t)=>{for(let s=0;s<e.length;s++)e[s](...t)},Nl=(e,t,s,n=!1)=>{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:n,value:s})},Gs=e=>{const t=parseFloat(e);return isNaN(t)?e:t};let tl;const Js=()=>tl||(tl=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function Rn(e){if(N(e)){const t={};for(let s=0;s<e.length;s++){const n=e[s],l=ce(n)?ii(n):Rn(n);if(l)for(const o in l)t[o]=l[o]}return t}else if(ce(e)||te(e))return e}const ni=/;(?![^(]*\))/g,li=/:([^]+)/,oi=/\/\*[^]*?\*\//g;function ii(e){const t={};return e.replace(oi,"").split(ni).forEach(s=>{if(s){const n=s.split(li);n.length>1&&(t[n[0].trim()]=n[1].trim())}}),t}function Ue(e){let t="";if(ce(e))t=e;else if(N(e))for(let s=0;s<e.length;s++){const n=Ue(e[s]);n&&(t+=n+" ")}else if(te(e))for(const s in e)e[s]&&(t+=s+" ");return t.trim()}const ri="itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly",ai=An(ri);function Fl(e){return!!e||e===""}function ci(e,t){if(e.length!==t.length)return!1;let s=!0;for(let n=0;s&&n<e.length;n++)s=vt(e[n],t[n]);return s}function vt(e,t){if(e===t)return!0;let s=el(e),n=el(t);if(s||n)return s&&n?e.getTime()===t.getTime():!1;if(s=st(e),n=st(t),s||n)return e===t;if(s=N(e),n=N(t),s||n)return s&&n?ci(e,t):!1;if(s=te(e),n=te(t),s||n){if(!s||!n)return!1;const l=Object.keys(e).length,o=Object.keys(t).length;if(l!==o)return!1;for(const i in e){const r=e.hasOwnProperty(i),c=t.hasOwnProperty(i);if(r&&!c||!r&&c||!vt(e[i],t[i]))return!1}}return String(e)===String(t)}function In(e,t){return e.findIndex(s=>vt(s,t))}const Vl=e=>!!(e&&e.__v_isRef===!0),O=e=>ce(e)?e:e==null?"":N(e)||te(e)&&(e.toString===jl||!B(e.toString))?Vl(e)?O(e.value):JSON.stringify(e,Hl,2):String(e),Hl=(e,t)=>Vl(t)?Hl(e,t.value):Ft(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((s,[n,l],o)=>(s[on(n,o)+" =>"]=l,s),{})}:Wt(t)?{[`Set(${t.size})`]:[...t.values()].map(s=>on(s))}:st(t)?on(t):te(t)&&!N(t)&&!Ll(t)?String(t):t,on=(e,t="")=>{var s;return st(e)?`Symbol(${(s=e.description)!=null?s:t})`:e};/**
|
||||
* @vue/reactivity v3.5.39
|
||||
* (c) 2018-present Yuxi (Evan) You and Vue contributors
|
||||
* @license MIT
|
||||
**/let ve;class ui{constructor(t=!1){this.detached=t,this._active=!0,this._on=0,this.effects=[],this.cleanups=[],this._isPaused=!1,this._warnOnRun=!0,this.__v_skip=!0,!t&&ve&&(ve.active?(this.parent=ve,this.index=(ve.scopes||(ve.scopes=[])).push(this)-1):(this._active=!1,this._warnOnRun=!1))}get active(){return this._active}pause(){if(this._active){this._isPaused=!0;let t,s;if(this.scopes)for(t=0,s=this.scopes.length;t<s;t++)this.scopes[t].pause();for(t=0,s=this.effects.length;t<s;t++)this.effects[t].pause()}}resume(){if(this._active&&this._isPaused){this._isPaused=!1;let t,s;if(this.scopes)for(t=0,s=this.scopes.length;t<s;t++)this.scopes[t].resume();for(t=0,s=this.effects.length;t<s;t++)this.effects[t].resume()}}run(t){if(this._active){const s=ve;try{return ve=this,t()}finally{ve=s}}}on(){++this._on===1&&(this.prevScope=ve,ve=this)}off(){if(this._on>0&&--this._on===0){if(ve===this)ve=this.prevScope;else{let t=ve;for(;t;){if(t.prevScope===this){t.prevScope=this.prevScope;break}t=t.prevScope}}this.prevScope=void 0}}stop(t){if(this._active){this._active=!1;let s,n;for(s=0,n=this.effects.length;s<n;s++)this.effects[s].stop();for(this.effects.length=0,s=0,n=this.cleanups.length;s<n;s++)this.cleanups[s]();if(this.cleanups.length=0,this.scopes){for(s=0,n=this.scopes.length;s<n;s++)this.scopes[s].stop(!0);this.scopes.length=0}if(!this.detached&&this.parent&&!t){const l=this.parent.scopes.pop();l&&l!==this&&(this.parent.scopes[this.index]=l,l.index=this.index)}this.parent=void 0}}}function fi(){return ve}let re;const rn=new WeakSet;class Bl{constructor(t){this.fn=t,this.deps=void 0,this.depsTail=void 0,this.flags=5,this.next=void 0,this.cleanup=void 0,this.scheduler=void 0,ve&&(ve.active?ve.effects.push(this):this.flags&=-2)}pause(){this.flags|=64}resume(){this.flags&64&&(this.flags&=-65,rn.has(this)&&(rn.delete(this),this.trigger()))}notify(){this.flags&2&&!(this.flags&32)||this.flags&8||zl(this)}run(){if(!(this.flags&1))return this.fn();this.flags|=2,sl(this),Wl(this);const t=re,s=Ke;re=this,Ke=!0;try{return this.fn()}finally{Gl(this),re=t,Ke=s,this.flags&=-3}}stop(){if(this.flags&1){for(let t=this.deps;t;t=t.nextDep)jn(t);this.deps=this.depsTail=void 0,sl(this),this.onStop&&this.onStop(),this.flags&=-2}}trigger(){this.flags&64?rn.add(this):this.scheduler?this.scheduler():this.runIfDirty()}runIfDirty(){vn(this)&&this.run()}get dirty(){return vn(this)}}let Kl=0,ns,ls;function zl(e,t=!1){if(e.flags|=8,t){e.next=ls,ls=e;return}e.next=ns,ns=e}function Un(){Kl++}function $n(){if(--Kl>0)return;if(ls){let t=ls;for(ls=void 0;t;){const s=t.next;t.next=void 0,t.flags&=-9,t=s}}let e;for(;ns;){let t=ns;for(ns=void 0;t;){const s=t.next;if(t.next=void 0,t.flags&=-9,t.flags&1)try{t.trigger()}catch(n){e||(e=n)}t=s}}if(e)throw e}function Wl(e){for(let t=e.deps;t;t=t.nextDep)t.version=-1,t.prevActiveLink=t.dep.activeLink,t.dep.activeLink=t}function Gl(e){let t,s=e.depsTail,n=s;for(;n;){const l=n.prevDep;n.version===-1?(n===s&&(s=l),jn(n),di(n)):t=n,n.dep.activeLink=n.prevActiveLink,n.prevActiveLink=void 0,n=l}e.deps=t,e.depsTail=s}function vn(e){for(let t=e.deps;t;t=t.nextDep)if(t.dep.version!==t.version||t.dep.computed&&(Jl(t.dep.computed)||t.dep.version!==t.version))return!0;return!!e._dirty}function Jl(e){if(e.flags&4&&!(e.flags&16)||(e.flags&=-17,e.globalVersion===cs)||(e.globalVersion=cs,!e.isSSR&&e.flags&128&&(!e.deps&&!e._dirty||!vn(e))))return;e.flags|=2;const t=e.dep,s=re,n=Ke;re=e,Ke=!0;try{Wl(e);const l=e.fn(e._value);(t.version===0||et(l,e._value))&&(e.flags|=128,e._value=l,t.version++)}catch(l){throw t.version++,l}finally{re=s,Ke=n,Gl(e),e.flags&=-3}}function jn(e,t=!1){const{dep:s,prevSub:n,nextSub:l}=e;if(n&&(n.nextSub=l,e.prevSub=void 0),l&&(l.prevSub=n,e.nextSub=void 0),s.subs===e&&(s.subs=n,!n&&s.computed)){s.computed.flags&=-5;for(let o=s.computed.deps;o;o=o.nextDep)jn(o,!0)}!t&&!--s.sc&&s.map&&s.map.delete(s.key)}function di(e){const{prevDep:t,nextDep:s}=e;t&&(t.nextDep=s,e.prevDep=void 0),s&&(s.prevDep=t,e.nextDep=void 0)}let Ke=!0;const ql=[];function nt(){ql.push(Ke),Ke=!1}function lt(){const e=ql.pop();Ke=e===void 0?!0:e}function sl(e){const{cleanup:t}=e;if(e.cleanup=void 0,t){const s=re;re=void 0;try{t()}finally{re=s}}}let cs=0;class pi{constructor(t,s){this.sub=t,this.dep=s,this.version=s.version,this.nextDep=this.prevDep=this.nextSub=this.prevSub=this.prevActiveLink=void 0}}class Ln{constructor(t){this.computed=t,this.version=0,this.activeLink=void 0,this.subs=void 0,this.map=void 0,this.key=void 0,this.sc=0,this.__v_skip=!0}track(t){if(!re||!Ke||re===this.computed)return;let s=this.activeLink;if(s===void 0||s.sub!==re)s=this.activeLink=new pi(re,this),re.deps?(s.prevDep=re.depsTail,re.depsTail.nextDep=s,re.depsTail=s):re.deps=re.depsTail=s,Yl(s);else if(s.version===-1&&(s.version=this.version,s.nextDep)){const n=s.nextDep;n.prevDep=s.prevDep,s.prevDep&&(s.prevDep.nextDep=n),s.prevDep=re.depsTail,s.nextDep=void 0,re.depsTail.nextDep=s,re.depsTail=s,re.deps===s&&(re.deps=n)}return s}trigger(t){this.versiLine truncated
|
||||
* @vue/runtime-core v3.5.39
|
||||
* (c) 2018-present Yuxi (Evan) You and Vue contributors
|
||||
* @license MIT
|
||||
**/function ms(e,t,s,n){try{return n?e(...n):e()}catch(l){Ys(l,t,s)}}function We(e,t,s,n){if(B(e)){const l=ms(e,t,s,n);return l&&$l(l)&&l.catch(o=>{Ys(o,t,s)}),l}if(N(e)){const l=[];for(let o=0;o<e.length;o++)l.push(We(e[o],t,s,n));return l}}function Ys(e,t,s,n=!0){const l=t?t.vnode:null,{errorHandler:o,throwUnhandledErrorInProduction:i}=t&&t.appContext.config||ne;if(t){let r=t.parent;const c=t.proxy,m=`https://vuejs.org/error-reference/#runtime-${s}`;for(;r;){const h=r.ec;if(h){for(let y=0;y<h.length;y++)if(h[y](e,c,m)===!1)return}r=r.parent}if(o){nt(),ms(o,null,10,[e,c,m]),lt();return}}Di(e,s,l,n,i)}function Di(e,t,s,n=!0,l=!1){if(l)throw e;console.error(e)}const Pe=[];let Xe=-1;const Vt=[];let mt=null,Lt=0;const lo=Promise.resolve();let Ls=null;function oo(e){const t=Ls||lo;return e?t.then(this?e.bind(this):e):t}function Ni(e){let t=Xe+1,s=Pe.length;for(;t<s;){const n=t+s>>>1,l=Pe[n],o=fs(l);o<e||o===e&&l.flags&2?t=n+1:s=n}return t}function Hn(e){if(!(e.flags&1)){const t=fs(e),s=Pe[Pe.length-1];!s||!(e.flags&2)&&t>=fs(s)?Pe.push(e):Pe.splice(Ni(t),0,e),e.flags|=1,io()}}function io(){Ls||(Ls=lo.then(ao))}function Fi(e){N(e)?Vt.push(...e):mt&&e.id===-1?mt.splice(Lt+1,0,e):e.flags&1||(Vt.push(e),e.flags|=1),io()}function ll(e,t,s=Xe+1){for(;s<Pe.length;s++){const n=Pe[s];if(n&&n.flags&2){if(e&&n.id!==e.uid)continue;Pe.splice(s,1),s--,n.flags&4&&(n.flags&=-2),n(),n.flags&4||(n.flags&=-2)}}}function ro(e){if(Vt.length){const t=[...new Set(Vt)].sort((s,n)=>fs(s)-fs(n));if(Vt.length=0,mt){mt.push(...t);return}for(mt=t,Lt=0;Lt<mt.length;Lt++){const s=mt[Lt];s.flags&4&&(s.flags&=-2),s.flags&8||s(),s.flags&=-2}mt=null,Lt=0}}const fs=e=>e.id==null?e.flags&2?-1:1/0:e.id;function ao(e){try{for(Xe=0;Xe<Pe.length;Xe++){const t=Pe[Xe];t&&!(t.flags&8)&&(t.flags&4&&(t.flags&=-2),ms(t,t.i,t.i?15:14),t.flags&4||(t.flags&=-2))}}finally{for(;Xe<Pe.length;Xe++){const t=Pe[Xe];t&&(t.flags&=-2)}Xe=-1,Pe.length=0,ro(),Ls=null,(Pe.length||Vt.length)&&ao()}}let Fe=null,co=null;function Ds(e){const t=Fe;return Fe=e,co=e&&e.type.__scopeId||null,t}function Vi(e,t=Fe,s){if(!t||e._n)return e;const n=(...l)=>{n._d&&gl(-1);const o=Ds(t);let i;try{i=e(...l)}finally{Ds(o),n._d&&gl(1)}return i};return n._n=!0,n._c=!0,n._d=!0,n}function ie(e,t){if(Fe===null)return e;const s=en(Fe),n=e.dirs||(e.dirs=[]);for(let l=0;l<t.length;l++){let[o,i,r,c=ne]=t[l];o&&(B(o)&&(o={mounted:o,updated:o}),o.deep&&ft(i),n.push({dir:o,instance:s,value:i,oldValue:void 0,arg:r,modifiers:c}))}return e}function St(e,t,s,n){const l=e.dirs,o=t&&t.dirs;for(let i=0;i<l.length;i++){const r=l[i];o&&(r.oldValue=o[i].value);let c=r.dir[n];c&&(nt(),We(c,s,8,[e.el,r,e,t]),lt())}}function Hi(e,t){if(Ae){let s=Ae.provides;const n=Ae.parent&&Ae.parent.provides;n===s&&(s=Ae.provides=Object.create(n)),s[e]=t}}function Is(e,t,s=!1){const n=Vr();if(n||Ht){let l=Ht?Ht._context.provides:n?n.parent==null||n.ce?n.vnode.appContext&&n.vnode.appContext.provides:n.parent.provides:void 0;if(l&&e in l)return l[e];if(arguments.length>1)return s&&B(t)?t.call(n&&n.proxy):t}}const Bi=Symbol.for("v-scx"),Ki=()=>Is(Bi);function un(e,t,s){return uo(e,t,s)}function uo(e,t,s=ne){const{immediate:n,deep:l,flush:o,once:i}=s,r=Se({},s),c=t&&n||!t&&o!=="post";let m;if(ps){if(o==="sync"){const I=Ki();m=I.__watcherHandles||(I.__watcherHandles=[])}else if(!c){const I=()=>{};return I.stop=tt,I.resume=tt,I.pause=tt,I}}const h=Ae;r.call=(I,J,U)=>We(I,h,J,U);let y=!1;o==="post"?r.scheduler=I=>{Me(I,h&&h.suspense)}:o!=="sync"&&(y=!0,r.scheduler=(I,J)=>{J?I():Hn(I)}),r.augmentJob=I=>{t&&(I.flags|=4),y&&(I.flags|=2,h&&(I.id=h.uid,I.i=h))};const M=Li(e,t,r);return ps&&(m?m.push(M):c&&M()),M}function zi(e,t,s){const n=this.proxy,l=ce(e)?e.includes(".")?fo(n,e):()=>n[e]:e.bind(n,n);let o;B(t)?o=t:(o=t.handler,s=t);const i=vs(this),r=uo(l,o.bind(n),s);return i(),r}function fo(e,t){const s=t.split(".");return()=>{let n=e;for(let l=0;l<s.length&&n;l++)n=n[s[l]];return n}}const Wi=Symbol("_vte"),Gi=e=>e.__isTeleport,fn=Symbol("_leaveCb");function Bn(e,t){e.shapeFlag&6&&e.component?(e.transition=t,Bn(e.component.subTree,t)):e.shapeFlag&128?(e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback)):e.transition=t}function po(e){e.ids=[e.ids[0]+e.ids[2]+++"-",0,0]}function ol(e,t){let s;return!!((s=Object.getOwnPropertyDescriptor(e,t))&&!s.configurable)}const Ns=new WeakMap;function os(e,t,s,n,l=!1){if(N(e)){e.forEach((U,W)=>os(U,t&&(N(t)?t[W]:t),s,n,l));return}if(is(n)&&!l){n.shapeFlag&512&&n.type.__asyncResolved&&n.component.subTree.component&&os(e,t,s,n.component.subTree);return}const o=n.shapeFlag&4?en(n.component):n.el,i=l?null:o,{i:r,r:c}=e,m=t&&t.r,h=r.refs===ne?r.refs={}:r.refs,y=r.setupState,M=Z(y),I=y===ne?Ul:U=>ol(h,U)?!1:Q(M,U),J=(U,W)=>!(W&&ol(h,W));if(m!=null&&m!==c){if(il(t),ce(m))h[m]=null,I(m)&&(y[m]=null);else if(Ce(m)){const U=t;J(m,U.k)&&(m.value=null),U.k&&(h[U.k]=null)}}if(B(c)){nt();try{ms(c,r,12,[i,h])}finally{lt()}}else{const U=ce(c),W=Ce(c);if(U||W){const Y=()=>{if(e.f
Line truncated
|
||||
* @vue/runtime-dom v3.5.39
|
||||
* (c) 2018-present Yuxi (Evan) You and Vue contributors
|
||||
* @license MIT
|
||||
**/let Pn;const bl=typeof window<"u"&&window.trustedTypes;if(bl)try{Pn=bl.createPolicy("vue",{createHTML:e=>e})}catch{}const No=Pn?e=>Pn.createHTML(e):e=>e,Jr="http://www.w3.org/2000/svg",qr="http://www.w3.org/1998/Math/MathML",at=typeof document<"u"?document:null,yl=at&&at.createElement("template"),Yr={insert:(e,t,s)=>{t.insertBefore(e,s||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,s,n)=>{const l=t==="svg"?at.createElementNS(Jr,e):t==="mathml"?at.createElementNS(qr,e):s?at.createElement(e,{is:s}):at.createElement(e);return e==="select"&&n&&n.multiple!=null&&l.setAttribute("multiple",n.multiple),l},createText:e=>at.createTextNode(e),createComment:e=>at.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>at.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,s,n,l,o){const i=s?s.previousSibling:t.lastChild;if(l&&(l===o||l.nextSibling))for(;t.insertBefore(l.cloneNode(!0),s),!(l===o||!(l=l.nextSibling)););else{yl.innerHTML=No(n==="svg"?`<svg>${e}</svg>`:n==="mathml"?`<math>${e}</math>`:e);const r=yl.content;if(n==="svg"||n==="mathml"){const c=r.firstChild;for(;c.firstChild;)r.appendChild(c.firstChild);r.removeChild(c)}t.insertBefore(r,s)}return[i?i.nextSibling:t.firstChild,s?s.previousSibling:t.lastChild]}},Xr=Symbol("_vtc");function Zr(e,t,s){const n=e[Xr];n&&(t=(t?[t,...n]:[...n]).join(" ")),t==null?e.removeAttribute("class"):s?e.setAttribute("class",t):e.className=t}const Bs=Symbol("_vod"),Fo=Symbol("_vsh"),Xt={name:"show",beforeMount(e,{value:t},{transition:s}){e[Bs]=e.style.display==="none"?"":e.style.display,s&&t?s.beforeEnter(e):Zt(e,t)},mounted(e,{value:t},{transition:s}){s&&t&&s.enter(e)},updated(e,{value:t,oldValue:s},{transition:n}){!t!=!s&&(n?t?(n.beforeEnter(e),Zt(e,!0),n.enter(e)):n.leave(e,()=>{Zt(e,!1)}):Zt(e,t))},beforeUnmount(e,{value:t}){Zt(e,t)}};function Zt(e,t){e.style.display=t?e[Bs]:"none",e[Fo]=!t}const Qr=Symbol(""),ea=/(?:^|;)\s*display\s*:/;function ta(e,t,s){const n=e.style,l=ce(s);let o=!1;if(s&&!l){if(t)if(ce(t))for(const i of t.split(";")){const r=i.slice(0,i.indexOf(":")).trim();s[r]==null&&ts(n,r,"")}else for(const i in t)s[i]==null&&ts(n,i,"");for(const i in s){i==="display"&&(o=!0);const r=s[i];r!=null?na(e,i,!ce(t)&&t?t[i]:void 0,r)||ts(n,i,r):ts(n,i,"")}}else if(l){if(t!==s){const i=n[Qr];i&&(s+=";"+i),n.cssText=s,o=ea.test(s)}}else t&&e.removeAttribute("style");Bs in e&&(e[Bs]=o?n.display:"",e[Fo]&&(n.display="none"))}const xl=/\s*!important$/;function ts(e,t,s){if(N(s))s.forEach(n=>ts(e,t,n));else if(s==null&&(s=""),t.startsWith("--"))e.setProperty(t,s);else{const n=sa(e,t);xl.test(s)?e.setProperty(xt(n),s.replace(xl,""),"important"):e[n]=s}}const _l=["Webkit","Moz","ms"],hn={};function sa(e,t){const s=hn[t];if(s)return s;let n=Be(t);if(n!=="filter"&&n in e)return hn[t]=n;n=Dl(n);for(let l=0;l<_l.length;l++){const o=_l[l]+n;if(o in e)return hn[t]=o}return t}function na(e,t,s,n){return e.tagName==="TEXTAREA"&&(t==="width"||t==="height")&&ce(n)&&s===n}const wl="http://www.w3.org/1999/xlink";function Cl(e,t,s,n,l,o=ai(t)){n&&t.startsWith("xlink:")?s==null?e.removeAttributeNS(wl,t.slice(6,t.length)):e.setAttributeNS(wl,t,s):s==null||o&&!Fl(s)?e.removeAttribute(t):e.setAttribute(t,o?"":st(s)?String(s):s)}function Sl(e,t,s,n,l){if(t==="innerHTML"||t==="textContent"){s!=null&&(e[t]=t==="innerHTML"?No(s):s);return}const o=e.tagName;if(t==="value"&&o!=="PROGRESS"&&!o.includes("-")){const r=o==="OPTION"?e.getAttribute("value")||"":e.value,c=s==null?e.type==="checkbox"?"on":"":String(s);(r!==c||!("_value"in e))&&(e.value=c),s==null&&e.removeAttribute(t),e._value=s;return}let i=!1;if(s===""||s==null){const r=typeof e[t];r==="boolean"?s=Fl(s):s==null&&r==="string"?(s="",i=!0):r==="number"&&(s=0,i=!0)}try{e[t]=s}catch{}i&&e.removeAttribute(l||t)}function dt(e,t,s,n){e.addEventListener(t,s,n)}function la(e,t,s,n){e.removeEventListener(t,s,n)}const kl=Symbol("_vei");function oa(e,t,s,n,l=null){const o=e[kl]||(e[kl]={}),i=o[t];if(n&&i)i.value=n;else{const[r,c]=aa(t);if(n){const m=o[t]=fa(n,l);dt(e,r,m,c)}else i&&(la(e,r,i,c),o[t]=void 0)}}const ia=/(Once|Passive|Capture)$/,ra=/^on:?(?:Once|Passive|Capture)$/;function aa(e){let t,s;for(;(s=e.match(ia))&&!ra.test(e);)t||(t={}),e=e.slice(0,e.length-s[1].length),t[s[1].toLowerCase()]=!0;return[e[2]===":"?e.slice(3):xt(e.slice(2)),t]}let gn=0;const ca=Promise.resolve(),ua=()=>gn||(ca.then(()=>gn=0),gn=Date.now());function fa(e,t){const s=n=>{if(!n._vts)n._vts=Date.now();else if(n._vts<=s.attached)return;const l=s.value;if(N(l)){const o=n.stopImmediatePropagation;n.stopImmediatePropagation=()=>{o.call(n),n._stopped=!0};const i=l.slice(),r=[n];for(let c=0;c<i.length&&!n._stopped;c++){const m=i[c];m&&We(m,t,5,r)}}else We(l,t,5,[n])};return s.value=e,s.attached=ua(),s}const El=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,da=(e,t,s,n,l
Line truncated
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="theme-color" content="#0F1E3D" />
|
||||
<title>PilotVault · API Server</title>
|
||||
<script type="module" crossorigin src="/assets/index--4fMszzi.js"></script>
|
||||
<script type="module" crossorigin src="/assets/index-CwiTp2Sb.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-CVh8EDzq.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -7,9 +7,34 @@ import (
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// validBBox reports whether s is a well-formed "lamin,lomin,lamax,lomax" bounding
|
||||
// box: four numbers, latitudes in [-90,90], longitudes in [-180,180], and min < max
|
||||
// on each axis. Used to vet the Live map's client-supplied ?bbox= override before
|
||||
// it reaches OpenSky.
|
||||
func validBBox(s string) bool {
|
||||
parts := strings.Split(s, ",")
|
||||
if len(parts) != 4 {
|
||||
return false
|
||||
}
|
||||
n := make([]float64, 4)
|
||||
for i, p := range parts {
|
||||
v, err := strconv.ParseFloat(strings.TrimSpace(p), 64)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
n[i] = v
|
||||
}
|
||||
laMin, loMin, laMax, loMax := n[0], n[1], n[2], n[3]
|
||||
if laMin < -90 || laMax > 90 || loMin < -180 || loMax > 180 {
|
||||
return false
|
||||
}
|
||||
return laMin < laMax && loMin < loMax
|
||||
}
|
||||
|
||||
// Integrations exposes the OpenSky plugin's settings to end users under a
|
||||
// three-layer cascade (superadmin/global → organization → user). Each of the
|
||||
// four settings resolves independently, top wins, and a blank field falls
|
||||
@@ -586,11 +611,19 @@ func (s *Server) handleOpenSkyStates(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// The Live map may request a specific area (auto cascade: drone → device →
|
||||
// region). Honour a well-formed ?bbox= override; otherwise use the resolved
|
||||
// config bbox. Malformed input is ignored rather than erroring.
|
||||
bbox := res.eff.Bbox
|
||||
if q := strings.TrimSpace(r.URL.Query().Get("bbox")); q != "" && validBBox(q) {
|
||||
bbox = q
|
||||
}
|
||||
|
||||
cfg := map[string]string{
|
||||
"clientId": res.eff.ClientID,
|
||||
"clientSecret": res.eff.ClientSecret,
|
||||
"plan": res.eff.Plan,
|
||||
"bbox": res.eff.Bbox,
|
||||
"bbox": bbox,
|
||||
"allowAnonymous": boolStr(res.allowAnon),
|
||||
}
|
||||
raw, err := s.plugins.InvokeWith(r.Context(), openSkyPlugin, cfg, "states.bbox", nil)
|
||||
|
||||
@@ -11,6 +11,10 @@ type Telemetry struct {
|
||||
Altitude *float64 `json:"altitude,omitempty"`
|
||||
Latitude *float64 `json:"latitude,omitempty"`
|
||||
Longitude *float64 `json:"longitude,omitempty"`
|
||||
// Phone's own GPS (reported by the Fly App), distinct from the drone's fix
|
||||
// above — used as a location fallback for the Web App's auto bounding box.
|
||||
PhoneLatitude *float64 `json:"phoneLatitude,omitempty"`
|
||||
PhoneLongitude *float64 `json:"phoneLongitude,omitempty"`
|
||||
VelocityX *float64 `json:"velocityX,omitempty"`
|
||||
VelocityY *float64 `json:"velocityY,omitempty"`
|
||||
VelocityZ *float64 `json:"velocityZ,omitempty"`
|
||||
@@ -100,6 +104,12 @@ func applyTelemetry(t *Telemetry, raw map[string]any) {
|
||||
if v, ok := toFloat(raw["longitude"]); ok {
|
||||
t.Longitude = &v
|
||||
}
|
||||
if v, ok := toFloat(raw["phoneLatitude"]); ok {
|
||||
t.PhoneLatitude = &v
|
||||
}
|
||||
if v, ok := toFloat(raw["phoneLongitude"]); ok {
|
||||
t.PhoneLongitude = &v
|
||||
}
|
||||
if v, ok := toFloat(raw["velocityX"]); ok {
|
||||
t.VelocityX = &v
|
||||
}
|
||||
|
||||
@@ -190,15 +190,61 @@ const BBOX_GROUPS = [
|
||||
{ value: "-56,-82,13,-34", label: "South America" },
|
||||
{ value: "-48,110,-10,180", label: "Oceania" },
|
||||
] },
|
||||
{ label: "Countries", options: [
|
||||
{ value: "49,14.1,54.9,24.2", label: "Poland" },
|
||||
{ value: "50.5,3.2,53.7,7.3", label: "Netherlands" },
|
||||
{ value: "47.2,5.8,55.1,15.1", label: "Germany" },
|
||||
// European countries (mirrors Web App/web/src/countries.js — keep in sync).
|
||||
{ label: "European countries", options: [
|
||||
{ value: "39.6,19.3,42.7,21.1", label: "Albania" },
|
||||
{ value: "42.4,1.4,42.7,1.8", label: "Andorra" },
|
||||
{ value: "46.4,9.5,49.0,17.2", label: "Austria" },
|
||||
{ value: "51.2,23.2,56.2,32.8", label: "Belarus" },
|
||||
{ value: "49.5,2.5,51.5,6.4", label: "Belgium" },
|
||||
{ value: "42.6,15.7,45.3,19.6", label: "Bosnia and Herzegovina" },
|
||||
{ value: "41.2,22.4,44.2,28.6", label: "Bulgaria" },
|
||||
{ value: "42.4,13.5,46.6,19.4", label: "Croatia" },
|
||||
{ value: "34.6,32.3,35.7,34.6", label: "Cyprus" },
|
||||
{ value: "48.6,12.1,51.1,18.9", label: "Czechia" },
|
||||
{ value: "54.6,8.1,57.8,12.7", label: "Denmark" },
|
||||
{ value: "57.5,21.8,59.7,28.2", label: "Estonia" },
|
||||
{ value: "59.8,20.6,70.1,31.6", label: "Finland" },
|
||||
{ value: "41.3,-5.2,51.1,9.6", label: "France" },
|
||||
{ value: "49.9,-8.7,59,1.8", label: "United Kingdom" },
|
||||
{ value: "35.9,-9.6,43.8,3.4", label: "Spain" },
|
||||
{ value: "47.2,5.8,55.1,15.1", label: "Germany" },
|
||||
{ value: "34.8,19.4,41.8,28.3", label: "Greece" },
|
||||
{ value: "45.7,16.1,48.6,22.9", label: "Hungary" },
|
||||
{ value: "63.3,-24.6,66.6,-13.5", label: "Iceland" },
|
||||
{ value: "51.4,-10.6,55.4,-6.0", label: "Ireland" },
|
||||
{ value: "36.6,6.6,47.1,18.6", label: "Italy" },
|
||||
{ value: "41.8,20.0,43.3,21.8", label: "Kosovo" },
|
||||
{ value: "55.7,20.9,58.1,28.2", label: "Latvia" },
|
||||
{ value: "47.0,9.4,47.3,9.6", label: "Liechtenstein" },
|
||||
{ value: "53.9,20.9,56.5,26.9", label: "Lithuania" },
|
||||
{ value: "49.4,5.7,50.2,6.5", label: "Luxembourg" },
|
||||
{ value: "35.8,14.1,36.1,14.6", label: "Malta" },
|
||||
{ value: "45.4,26.6,48.5,30.2", label: "Moldova" },
|
||||
{ value: "43.72,7.40,43.75,7.44", label: "Monaco" },
|
||||
{ value: "41.8,18.4,43.6,20.4", label: "Montenegro" },
|
||||
{ value: "50.7,3.3,53.7,7.2", label: "Netherlands" },
|
||||
{ value: "40.8,20.4,42.4,23.0", label: "North Macedonia" },
|
||||
{ value: "57.9,4.6,71.2,31.1", label: "Norway" },
|
||||
{ value: "49.0,14.1,54.9,24.2", label: "Poland" },
|
||||
{ value: "36.9,-9.5,42.2,-6.2", label: "Portugal" },
|
||||
{ value: "43.6,20.2,48.3,29.7", label: "Romania" },
|
||||
{ value: "41.2,19.6,81.9,180", label: "Russia" },
|
||||
{ value: "43.89,12.40,43.99,12.52", label: "San Marino" },
|
||||
{ value: "42.2,18.8,46.2,23.0", label: "Serbia" },
|
||||
{ value: "47.7,16.8,49.6,22.6", label: "Slovakia" },
|
||||
{ value: "45.4,13.4,46.9,16.6", label: "Slovenia" },
|
||||
{ value: "35.9,-9.4,43.8,3.4", label: "Spain" },
|
||||
{ value: "55.3,11.1,69.1,24.2", label: "Sweden" },
|
||||
{ value: "45.8,5.9,47.8,10.5", label: "Switzerland" },
|
||||
{ value: "35.8,25.7,42.3,44.8", label: "Turkey" },
|
||||
{ value: "44.4,22.1,52.4,40.2", label: "Ukraine" },
|
||||
{ value: "49.9,-8.7,60.9,1.8", label: "United Kingdom" },
|
||||
{ value: "41.900,12.445,41.908,12.458", label: "Vatican City" },
|
||||
] },
|
||||
{ label: "Other countries", options: [
|
||||
{ value: "24,-125,49.5,-66.5", label: "United States" },
|
||||
{ value: "41.7,-141,83.1,-52.6", label: "Canada" },
|
||||
{ value: "-43.6,113.3,-10.7,153.6", label: "Australia" },
|
||||
{ value: "24,122.9,45.5,145.8", label: "Japan" },
|
||||
] },
|
||||
];
|
||||
const BBOX_FLAT = BBOX_GROUPS.flatMap((g) => g.options);
|
||||
|
||||
@@ -21,6 +21,10 @@ class FlightModel extends ChangeNotifier {
|
||||
double? altitude;
|
||||
double? latitude;
|
||||
double? longitude;
|
||||
// Phone's own GPS (independent of the drone's fix above); streamed to the
|
||||
// server as a location fallback for the Web App's automatic bounding box.
|
||||
double? phoneLatitude;
|
||||
double? phoneLongitude;
|
||||
int? batteryPercent;
|
||||
|
||||
UploadStatus upload = UploadStatus.disabled;
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:geolocator/geolocator.dart';
|
||||
|
||||
import 'dji_service.dart';
|
||||
import 'flight_model.dart';
|
||||
@@ -46,6 +47,7 @@ class _HomePageState extends State<HomePage> {
|
||||
final FlightModel _model = FlightModel();
|
||||
StreamSubscription<Map<String, dynamic>>? _sub;
|
||||
StreamSubscription<AuthStatus>? _authSub;
|
||||
StreamSubscription<Position>? _phoneLocSub;
|
||||
|
||||
// Streams telemetry to the API Server and receives commands back.
|
||||
late final ServerUploader _uploader;
|
||||
@@ -69,6 +71,43 @@ class _HomePageState extends State<HomePage> {
|
||||
if (mounted) setState(() {});
|
||||
});
|
||||
_init();
|
||||
_startPhoneLocation();
|
||||
}
|
||||
|
||||
/// Streams the phone's own GPS (coarse, low-frequency) and reports it to the
|
||||
/// server as a telemetry field — a location fallback for the Web App's auto
|
||||
/// bounding box when the drone has no fix. Best-effort: silently gives up if
|
||||
/// location services or permission are unavailable.
|
||||
Future<void> _startPhoneLocation() async {
|
||||
try {
|
||||
if (!await Geolocator.isLocationServiceEnabled()) return;
|
||||
LocationPermission perm = await Geolocator.checkPermission();
|
||||
if (perm == LocationPermission.denied) {
|
||||
perm = await Geolocator.requestPermission();
|
||||
}
|
||||
if (perm == LocationPermission.denied || perm == LocationPermission.deniedForever) {
|
||||
return;
|
||||
}
|
||||
_phoneLocSub = Geolocator.getPositionStream(
|
||||
locationSettings: const LocationSettings(
|
||||
accuracy: LocationAccuracy.low, // country-level is all the bbox needs
|
||||
distanceFilter: 1000, // metres — infrequent updates
|
||||
),
|
||||
).listen((Position pos) {
|
||||
_model.phoneLatitude = pos.latitude;
|
||||
_model.phoneLongitude = pos.longitude;
|
||||
_model.bump();
|
||||
// Report to the server (rides the existing telemetry channel; only the
|
||||
// phone fields are present, so it never disturbs drone telemetry).
|
||||
_uploader.onEvent(<String, dynamic>{
|
||||
'type': 'telemetry',
|
||||
'phoneLatitude': pos.latitude,
|
||||
'phoneLongitude': pos.longitude,
|
||||
});
|
||||
});
|
||||
} catch (_) {
|
||||
// Location plugin/permission unavailable — non-fatal.
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _init() async {
|
||||
@@ -195,6 +234,8 @@ class _HomePageState extends State<HomePage> {
|
||||
if (_model.altitude != null) tel['altitude'] = _model.altitude;
|
||||
if (_model.latitude != null) tel['latitude'] = _model.latitude;
|
||||
if (_model.longitude != null) tel['longitude'] = _model.longitude;
|
||||
if (_model.phoneLatitude != null) tel['phoneLatitude'] = _model.phoneLatitude;
|
||||
if (_model.phoneLongitude != null) tel['phoneLongitude'] = _model.phoneLongitude;
|
||||
if (tel.length > 1) events.add(tel);
|
||||
return events;
|
||||
}
|
||||
@@ -235,6 +276,7 @@ class _HomePageState extends State<HomePage> {
|
||||
void dispose() {
|
||||
_sub?.cancel();
|
||||
_authSub?.cancel();
|
||||
_phoneLocSub?.cancel();
|
||||
_uploadSub?.cancel();
|
||||
_uploader.dispose();
|
||||
_serverHost.dispose();
|
||||
|
||||
@@ -73,6 +73,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.19.1"
|
||||
crypto:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: crypto
|
||||
sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.7"
|
||||
cupertino_icons:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -105,6 +113,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.0.1"
|
||||
fixnum:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: fixnum
|
||||
sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
flutter:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
@@ -144,6 +160,54 @@ packages:
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
geolocator:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: geolocator
|
||||
sha256: f62bcd90459e63210bbf9c35deb6a51c521f992a78de19a1fe5c11704f9530e2
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "13.0.4"
|
||||
geolocator_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: geolocator_android
|
||||
sha256: fcb1760a50d7500deca37c9a666785c047139b5f9ee15aa5469fae7dbbe3170d
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.6.2"
|
||||
geolocator_apple:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: geolocator_apple
|
||||
sha256: "853803d6bb1713c094e935b4a5ae5f19c0308acf81da13fa9ff84fb4c70c0b73"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.14"
|
||||
geolocator_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: geolocator_platform_interface
|
||||
sha256: cdb082e4f048b69da244117b7914cc60d2a8897546ffaa4f2529c786ded7aee2
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.2.8"
|
||||
geolocator_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: geolocator_web
|
||||
sha256: "19e485a0f8d6a88abcf9c53cba3a4105e14b7435ed8ac1c108c067b938fe8429"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.1.4"
|
||||
geolocator_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: geolocator_windows
|
||||
sha256: "175435404d20278ffd220de83c2ca293b73db95eafbdc8131fe8609be1421eb6"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.5"
|
||||
image:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -437,6 +501,22 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.11"
|
||||
typed_data:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: typed_data
|
||||
sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.0"
|
||||
uuid:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: uuid
|
||||
sha256: "1fef9e8e11e2991bb773070d4656b7bd5d850967a2456cfc83cf47925ba79489"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.5.3"
|
||||
vector_math:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
@@ -43,6 +43,10 @@ dependencies:
|
||||
# the platform BiometricPrompt). Requires FlutterFragmentActivity on Android.
|
||||
local_auth: ^2.3.0
|
||||
|
||||
# Phone GPS — reported alongside telemetry as a location fallback for the Web
|
||||
# App's automatic bounding box when the drone has no fix.
|
||||
geolocator: ^13.0.1
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
|
||||
@@ -237,7 +237,12 @@ func (a *App) handleOpenSkyHealth(w http.ResponseWriter, r *http.Request) {
|
||||
// GET /bff/integrations/opensky/states → API Server /api/integrations/opensky/states.
|
||||
// Live aircraft positions for the Live map.
|
||||
func (a *App) handleOpenSkyStates(w http.ResponseWriter, r *http.Request) {
|
||||
req, _ := http.NewRequest(http.MethodGet, a.apiBaseFor(r)+"/api/integrations/opensky/states", nil)
|
||||
target := a.apiBaseFor(r) + "/api/integrations/opensky/states"
|
||||
// Forward the optional ?bbox= override the Live map sends in auto mode.
|
||||
if r.URL.RawQuery != "" {
|
||||
target += "?" + r.URL.RawQuery
|
||||
}
|
||||
req, _ := http.NewRequest(http.MethodGet, target, nil)
|
||||
req.Header.Set("Authorization", tokenOf(r))
|
||||
a.doRelay(w, req)
|
||||
}
|
||||
|
||||
+20
@@ -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 s(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=s(u);fetch(u.href,d)}})();/**
|
||||
* @vue/shared v3.5.39
|
||||
* (c) 2018-present Yuxi (Evan) You and Vue contributors
|
||||
* @license MIT
|
||||
**/function Or(t){const i=Object.create(null);for(const s of t.split(","))i[s]=1;return s=>s in i}const vt={},Io=[],Wn=()=>{},yu=()=>!1,Ca=t=>t.charCodeAt(0)===111&&t.charCodeAt(1)===110&&(t.charCodeAt(2)>122||t.charCodeAt(2)<97),La=t=>t.startsWith("onUpdate:"),$t=Object.assign,zr=(t,i)=>{const s=t.indexOf(i);s>-1&&t.splice(s,1)},fd=Object.prototype.hasOwnProperty,ft=(t,i)=>fd.call(t,i),De=Array.isArray,$o=t=>Ds(t)==="[object Map]",Zo=t=>Ds(t)==="[object Set]",_l=t=>Ds(t)==="[object Date]",Ye=t=>typeof t=="function",St=t=>typeof t=="string",Nn=t=>typeof t=="symbol",ht=t=>t!==null&&typeof t=="object",xu=t=>(ht(t)||Ye(t))&&Ye(t.then)&&Ye(t.catch),wu=Object.prototype.toString,Ds=t=>wu.call(t),hd=t=>Ds(t).slice(8,-1),ku=t=>Ds(t)==="[object Object]",Ir=t=>St(t)&&t!=="NaN"&&t[0]!=="-"&&""+parseInt(t,10)===t,ws=Or(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),Ma=t=>{const i=Object.create(null);return(s=>i[s]||(i[s]=t(s)))},pd=/-\w/g,In=Ma(t=>t.replace(pd,i=>i.slice(1).toUpperCase())),md=/\B([A-Z])/g,Ni=Ma(t=>t.replace(md,"-$1").toLowerCase()),Su=Ma(t=>t.charAt(0).toUpperCase()+t.slice(1)),tr=Ma(t=>t?`on${Su(t)}`:""),jn=(t,i)=>!Object.is(t,i),ha=(t,...i)=>{for(let s=0;s<t.length;s++)t[s](...i)},Tu=(t,i,s,l=!1)=>{Object.defineProperty(t,i,{configurable:!0,enumerable:!1,writable:l,value:s})},Aa=t=>{const i=parseFloat(t);return isNaN(i)?t:i},gd=t=>{const i=St(t)?Number(t):NaN;return isNaN(i)?t:i};let bl;const Ea=()=>bl||(bl=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function Bo(t){if(De(t)){const i={};for(let s=0;s<t.length;s++){const l=t[s],u=St(l)?yd(l):Bo(l);if(u)for(const d in u)i[d]=u[d]}return i}else if(St(t)||ht(t))return t}const vd=/;(?![^(]*\))/g,_d=/:([^]+)/,bd=/\/\*[^]*?\*\//g;function yd(t){const i={};return t.replace(bd,"").split(vd).forEach(s=>{if(s){const l=s.split(_d);l.length>1&&(i[l[0].trim()]=l[1].trim())}}),i}function Ee(t){let i="";if(St(t))i=t;else if(De(t))for(let s=0;s<t.length;s++){const l=Ee(t[s]);l&&(i+=l+" ")}else if(ht(t))for(const s in t)t[s]&&(i+=s+" ");return i.trim()}const xd="itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly",wd=Or(xd);function Pu(t){return!!t||t===""}function kd(t,i){if(t.length!==i.length)return!1;let s=!0;for(let l=0;s&&l<t.length;l++)s=zi(t[l],i[l]);return s}function zi(t,i){if(t===i)return!0;let s=_l(t),l=_l(i);if(s||l)return s&&l?t.getTime()===i.getTime():!1;if(s=Nn(t),l=Nn(i),s||l)return t===i;if(s=De(t),l=De(i),s||l)return s&&l?kd(t,i):!1;if(s=ht(t),l=ht(i),s||l){if(!s||!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 v=t.hasOwnProperty(h),b=i.hasOwnProperty(h);if(v&&!b||!v&&b||!zi(t[h],i[h]))return!1}}return String(t)===String(i)}function $r(t,i){return t.findIndex(s=>zi(s,i))}const Cu=t=>!!(t&&t.__v_isRef===!0),k=t=>St(t)?t:t==null?"":De(t)||ht(t)&&(t.toString===wu||!Ye(t.toString))?Cu(t)?k(t.value):JSON.stringify(t,Lu,2):String(t),Lu=(t,i)=>Cu(i)?Lu(t,i.value):$o(i)?{[`Map(${i.size})`]:[...i.entries()].reduce((s,[l,u],d)=>(s[nr(l,d)+" =>"]=u,s),{})}:Zo(i)?{[`Set(${i.size})`]:[...i.values()].map(s=>nr(s))}:Nn(i)?nr(i):ht(i)&&!De(i)&&!ku(i)?String(i):i,nr=(t,i="")=>{var s;return Nn(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 Ut;class Sd{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&&Ut&&(Ut.active?(this.parent=Ut,this.index=(Ut.scopes||(Ut.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=Ut;try{return Ut=this,i()}finally{Ut=s}}}on(){++this._on===1&&(this.prevScope=Ut,Ut=this)}off(){if(this._on>0&&--this._on===0){if(Ut===this)Ut=this.prevScope;else{let i=Ut;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 Td(){return Ut}let bt;const ir=new WeakSet;class Mu{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,Ut&&(Ut.active?Ut.effects.push(this):this.flags&=-2)}pause(){this.flags|=64}resume(){this.flags&64&&(this.flags&=-65,ir.has(this)&&(ir.delete(this),this.trigger()))}notify(){this.flags&2&&!(this.flags&32)||this.flags&8||Eu(this)}run(){if(!(this.flags&1))return this.fn();this.flags|=2,yl(this),Ou(this);const i=bt,s=$n;bt=this,$n=!0;try{return this.fn()}finally{zu(this),bt=i,$n=s,this.flags&=-3}}stop(){if(this.flags&1){for(let i=this.deps;i;i=i.nextDep)Fr(i);this.deps=this.depsTail=void 0,yl(this),this.onStop&&this.onStop(),this.flags&=-2}}trigger(){this.flags&64?ir.add(this):this.scheduler?this.scheduler():this.runIfDirty()}runIfDirty(){mr(this)&&this.run()}get dirty(){return mr(this)}}let Au=0,ks,Ss;function Eu(t,i=!1){if(t.flags|=8,i){t.next=Ss,Ss=t;return}t.next=ks,ks=t}function Nr(){Au++}function Dr(){if(--Au>0)return;if(Ss){let i=Ss;for(Ss=void 0;i;){const s=i.next;i.next=void 0,i.flags&=-9,i=s}}let t;for(;ks;){let i=ks;for(ks=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 Ou(t){for(let i=t.deps;i;i=i.nextDep)i.version=-1,i.prevActiveLink=i.dep.activeLink,i.dep.activeLink=i}function zu(t){let i,s=t.depsTail,l=s;for(;l;){const u=l.prevDep;l.version===-1?(l===s&&(s=u),Fr(l),Pd(l)):i=l,l.dep.activeLink=l.prevActiveLink,l.prevActiveLink=void 0,l=u}t.deps=i,t.depsTail=s}function mr(t){for(let i=t.deps;i;i=i.nextDep)if(i.dep.version!==i.version||i.dep.computed&&(Iu(i.dep.computed)||i.dep.version!==i.version))return!0;return!!t._dirty}function Iu(t){if(t.flags&4&&!(t.flags&16)||(t.flags&=-17,t.globalVersion===Ms)||(t.globalVersion=Ms,!t.isSSR&&t.flags&128&&(!t.deps&&!t._dirty||!mr(t))))return;t.flags|=2;const i=t.dep,s=bt,l=$n;bt=t,$n=!0;try{Ou(t);const u=t.fn(t._value);(i.version===0||jn(u,t._value))&&(t.flags|=128,t._value=u,i.version++)}catch(u){throw i.version++,u}finally{bt=s,$n=l,zu(t),t.flags&=-3}}function Fr(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 d=s.computed.deps;d;d=d.nextDep)Fr(d,!0)}!i&&!--s.sc&&s.map&&s.map.delete(s.key)}function Pd(t){const{prevDep:i,nextDep:s}=t;i&&(i.nextDep=s,t.prevDep=void 0),s&&(s.prevDep=i,t.nextDep=void 0)}let $n=!0;const $u=[];function Kn(){$u.push($n),$n=!1}function Gn(){const t=$u.pop();$n=t===void 0?!0:t}function yl(t){const{cleanup:i}=t;if(t.cleanup=void 0,i){const s=bt;bt=void 0;try{i()}finally{bt=s}}}let Ms=0;class Cd{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 Rr{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(!bt||!$n||bt===this.computed)return;let s=this.activeLink;if(s===void 0||s.sub!==bt)s=this.activeLink=new Cd(bt,this),bt.deps?(s.prevDep=bt.depsTail,bt.depsTail.nextDep=s,bt.depsTail=s):bt.deps=bt.depsTail=s,Nu(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=bt.depsTail,s.nextDep=void 0,bt.depsTail.nextDep=s,bt.depsTail=s,bt.deps===s&&(bt.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 Fs(t,i,s,l){try{return l?t(...l):t()}catch(u){za(u,i,s)}}function Mn(t,i,s,l){if(Ye(t)){const u=Fs(t,i,s,l);return u&&xu(u)&&u.catch(d=>{za(d,i,s)}),u}if(De(t)){const u=[];for(let d=0;d<t.length;d++)u.push(Mn(t[d],i,s,l));return u}}function za(t,i,s,l=!0){const u=i?i.vnode:null,{errorHandler:d,throwUnhandledErrorInProduction:h}=i&&i.appContext.config||vt;if(i){let v=i.parent;const b=i.proxy,C=`https://vuejs.org/error-reference/#runtime-${s}`;for(;v;){const T=v.ec;if(T){for(let M=0;M<T.length;M++)if(T[M](t,b,C)===!1)return}v=v.parent}if(d){Kn(),Fs(d,null,10,[t,b,C]),Gn();return}}Xd(t,s,u,l,h)}function Xd(t,i,s,l=!0,u=!1){if(u)throw t;console.error(t)}const Xt=[];let Vn=-1;const No=[];let Oi=null,zo=0;const Hu=Promise.resolve();let ga=null;function ju(t){const i=ga||Hu;return t?i.then(this?t.bind(this):t):i}function Qd(t){let i=Vn+1,s=Xt.length;for(;i<s;){const l=i+s>>>1,u=Xt[l],d=Es(u);d<t||d===t&&u.flags&2?i=l+1:s=l}return i}function Zr(t){if(!(t.flags&1)){const i=Es(t),s=Xt[Xt.length-1];!s||!(t.flags&2)&&i>=Es(s)?Xt.push(t):Xt.splice(Qd(i),0,t),t.flags|=1,Wu()}}function Wu(){ga||(ga=Hu.then(Gu))}function ef(t){De(t)?No.push(...t):Oi&&t.id===-1?Oi.splice(zo+1,0,t):t.flags&1||(No.push(t),t.flags|=1),Wu()}function wl(t,i,s=Vn+1){for(;s<Xt.length;s++){const l=Xt[s];if(l&&l.flags&2){if(t&&l.id!==t.uid)continue;Xt.splice(s,1),s--,l.flags&4&&(l.flags&=-2),l(),l.flags&4||(l.flags&=-2)}}}function Ku(t){if(No.length){const i=[...new Set(No)].sort((s,l)=>Es(s)-Es(l));if(No.length=0,Oi){Oi.push(...i);return}for(Oi=i,zo=0;zo<Oi.length;zo++){const s=Oi[zo];s.flags&4&&(s.flags&=-2),s.flags&8||s(),s.flags&=-2}Oi=null,zo=0}}const Es=t=>t.id==null?t.flags&2?-1:1/0:t.id;function Gu(t){try{for(Vn=0;Vn<Xt.length;Vn++){const i=Xt[Vn];i&&!(i.flags&8)&&(i.flags&4&&(i.flags&=-2),Fs(i,i.i,i.i?15:14),i.flags&4||(i.flags&=-2))}}finally{for(;Vn<Xt.length;Vn++){const i=Xt[Vn];i&&(i.flags&=-2)}Vn=-1,Xt.length=0,Ku(),ga=null,(Xt.length||No.length)&&Gu()}}let Kt=null,qu=null;function va(t){const i=Kt;return Kt=t,qu=t&&t.type.__scopeId||null,i}function Pe(t,i=Kt,s){if(!i||t._n)return t;const l=(...u)=>{l._d&&ya(-1);const d=va(i);let h;try{h=t(...u)}finally{va(d),l._d&&ya(1)}return h};return l._n=!0,l._c=!0,l._d=!0,l}function re(t,i){if(Kt===null)return t;const s=Fa(Kt),l=t.dirs||(t.dirs=[]);for(let u=0;u<i.length;u++){let[d,h,v,b=vt]=i[u];d&&(Ye(d)&&(d={mounted:d,updated:d}),d.deep&&ci(h),l.push({dir:d,instance:s,value:h,oldValue:void 0,arg:v,modifiers:b}))}return t}function to(t,i,s,l){const u=t.dirs,d=i&&i.dirs;for(let h=0;h<u.length;h++){const v=u[h];d&&(v.oldValue=d[h].value);let b=v.dir[l];b&&(Kn(),Mn(b,s,8,[t.el,v,t,i]),Gn())}}function Yu(t,i){if(Qt){let s=Qt.provides;const l=Qt.parent&&Qt.parent.provides;l===s&&(s=Qt.provides=Object.create(l)),s[t]=i}}function Ts(t,i,s=!1){const l=Lc();if(l||Fo){let u=Fo?Fo._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&&Ye(i)?i.call(l&&l.proxy):i}}const tf=Symbol.for("v-scx"),nf=()=>Ts(tf);function It(t,i,s){return Ju(t,i,s)}function Ju(t,i,s=vt){const{immediate:l,deep:u,flush:d,once:h}=s,v=$t({},s),b=i&&l||!i&&d!=="post";let C;if($s){if(d==="sync"){const B=nf();C=B.__watcherHandles||(B.__watcherHandles=[])}else if(!b){const B=()=>{};return B.stop=Wn,B.resume=Wn,B.pause=Wn,B}}const T=Qt;v.call=(B,Z,F)=>Mn(B,T,Z,F);let M=!1;d==="post"?v.scheduler=B=>{Jt(B,T&&T.suspense)}:d!=="sync"&&(M=!0,v.scheduler=(B,Z)=>{Z?B():Zr(B)}),v.augmentJob=B=>{i&&(B.flags|=4),M&&(B.flags|=2,T&&(B.id=T.uid,B.i=T))};const R=Jd(t,i,v);return $s&&(C?C.push(R):b&&R()),R}function of(t,i,s){const l=this.proxy,u=St(t)?t.includes(".")?Xu(l,t):()=>l[t]:t.bind(l,l);let d;Ye(i)?d=i:(d=i.handler,s=i);const h=Rs(this),v=Ju(u,d.bind(l),s);return h(),v}function Xu(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 Ei=new WeakMap,Qu=Symbol("_vte"),ec=t=>t.__isTeleport,ao=t=>t&&(t.disabled||t.disabled===""),sf=t=>t&&(t.defer||t.defer===""),kl=t=>typeof SVGElement<"u"&&t instanceof SVGElement,Sl=t=>typeof MathMLElement=="function"&&t instanceof MathMLElement,yr=(t,i)=>{const s=t&&t.to;return St(s)?i?i(s):null:s},af={name:"Teleport",__isTeleport:!0,process(t,i,s,l,u,d,h,v,b,C){const{mc:T,pc:M,pbc:R,o:{insert:B,querySelector:Z,createText:F,createComment:he,parentNode:pe}}=C,q=ao(i.props);let{dynamicChildren:Te}=i;const fe=(Ie,Ge,_e)=>{Ie.shapeFlag&16&&T(Ie.children,Ge,_e,u,d,h,v,b)},Ue=(Ie=i)=>{const Ge=ao(Ie.props),_e=Ie.target=yr(Ie.props,Z),ye=xr(_e,Ie,F,B);_e&&(h!=="svg"&&kl(_e)?h="svg":h!=="mathml"&&Sl(_e)&&(h="mathml"),u&&u.isCE&&(u.ce._teleportTargets||(u.ce._teleportTargets=new Set)).add(_e),Ge||(fe(Ie,_e,ye),_s(Ie,!1)))},$e=Ie=>{const Ge=()=>{if(Ei.get(Ie)===Ge){if(Ei.delete(Ie),ao(Ie.props)){const _e=pe(Ie.el)||s;fe(Ie,_e,Ie.anchor),_s(Ie,!0)}Ue(Ie)}};Ei.set(Ie,Ge),Jt(Ge,d)};if(t==null){const Ie=i.el=F(""),Ge=i.anchor=F("");if(B(Ie,s,l),B(Ge,s,l),sf
Line truncated
|
||||
* @vue/runtime-dom v3.5.39
|
||||
* (c) 2018-present Yuxi (Evan) You and Vue contributors
|
||||
* @license MIT
|
||||
**/let Lr;const Fl=typeof window<"u"&&window.trustedTypes;if(Fl)try{Lr=Fl.createPolicy("vue",{createHTML:t=>t})}catch{}const Ec=Lr?t=>Lr.createHTML(t):t=>t,ch="http://www.w3.org/2000/svg",dh="http://www.w3.org/1998/Math/MathML",ri=typeof document<"u"?document:null,Rl=ri&&ri.createElement("template"),fh={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"?ri.createElementNS(ch,t):i==="mathml"?ri.createElementNS(dh,t):s?ri.createElement(t,{is:s}):ri.createElement(t);return t==="select"&&l&&l.multiple!=null&&u.setAttribute("multiple",l.multiple),u},createText:t=>ri.createTextNode(t),createComment:t=>ri.createComment(t),setText:(t,i)=>{t.nodeValue=i},setElementText:(t,i)=>{t.textContent=i},parentNode:t=>t.parentNode,nextSibling:t=>t.nextSibling,querySelector:t=>ri.querySelector(t),setScopeId(t,i){t.setAttribute(i,"")},insertStaticContent(t,i,s,l,u,d){const h=s?s.previousSibling:i.lastChild;if(u&&(u===d||u.nextSibling))for(;i.insertBefore(u.cloneNode(!0),s),!(u===d||!(u=u.nextSibling)););else{Rl.innerHTML=Ec(l==="svg"?`<svg>${t}</svg>`:l==="mathml"?`<math>${t}</math>`:t);const v=Rl.content;if(l==="svg"||l==="mathml"){const b=v.firstChild;for(;b.firstChild;)v.appendChild(b.firstChild);v.removeChild(b)}i.insertBefore(v,s)}return[h?h.nextSibling:i.firstChild,s?s.previousSibling:i.lastChild]}},Mi="transition",gs="animation",Ns=Symbol("_vtc"),Oc={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},hh=$t({},tc,Oc),ph=t=>(t.displayName="Transition",t.props=hh,t),mh=ph((t,{slots:i})=>lh(df,gh(t),i)),io=(t,i=[])=>{De(t)?t.forEach(s=>s(...i)):t&&t(...i)},Bl=t=>t?De(t)?t.some(i=>i.length>1):t.length>1:!1;function gh(t){const i={};for(const ne in t)ne in Oc||(i[ne]=t[ne]);if(t.css===!1)return i;const{name:s="v",type:l,duration:u,enterFromClass:d=`${s}-enter-from`,enterActiveClass:h=`${s}-enter-active`,enterToClass:v=`${s}-enter-to`,appearFromClass:b=d,appearActiveClass:C=h,appearToClass:T=v,leaveFromClass:M=`${s}-leave-from`,leaveActiveClass:R=`${s}-leave-active`,leaveToClass:B=`${s}-leave-to`}=t,Z=vh(u),F=Z&&Z[0],he=Z&&Z[1],{onBeforeEnter:pe,onEnter:q,onEnterCancelled:Te,onLeave:fe,onLeaveCancelled:Ue,onBeforeAppear:$e=pe,onAppear:Ie=q,onAppearCancelled:Ge=Te}=i,_e=(ne,je,ie,We)=>{ne._enterCancelled=We,oo(ne,je?T:v),oo(ne,je?C:h),ie&&ie()},ye=(ne,je)=>{ne._isLeaving=!1,oo(ne,M),oo(ne,B),oo(ne,R),je&&je()},ze=ne=>(je,ie)=>{const We=ne?Ie:q,le=()=>_e(je,ne,ie);io(We,[je,le]),Ul(()=>{oo(je,ne?b:d),ai(je,ne?T:v),Bl(We)||Vl(je,l,F,le)})};return $t(i,{onBeforeEnter(ne){io(pe,[ne]),ai(ne,d),ai(ne,h)},onBeforeAppear(ne){io($e,[ne]),ai(ne,b),ai(ne,C)},onEnter:ze(!1),onAppear:ze(!0),onLeave(ne,je){ne._isLeaving=!0;const ie=()=>ye(ne,je);ai(ne,M),ne._enterCancelled?(ai(ne,R),jl(ne)):(jl(ne),ai(ne,R)),Ul(()=>{ne._isLeaving&&(oo(ne,M),ai(ne,B),Bl(fe)||Vl(ne,l,he,ie))}),io(fe,[ne,ie])},onEnterCancelled(ne){_e(ne,!1,void 0,!0),io(Te,[ne])},onAppearCancelled(ne){_e(ne,!0,void 0,!0),io(Ge,[ne])},onLeaveCancelled(ne){ye(ne),io(Ue,[ne])}})}function vh(t){if(t==null)return null;if(ht(t))return[cr(t.enter),cr(t.leave)];{const i=cr(t);return[i,i]}}function cr(t){return gd(t)}function ai(t,i){i.split(/\s+/).forEach(s=>s&&t.classList.add(s)),(t[Ns]||(t[Ns]=new Set)).add(i)}function oo(t,i){i.split(/\s+/).forEach(l=>l&&t.classList.remove(l));const s=t[Ns];s&&(s.delete(i),s.size||(t[Ns]=void 0))}function Ul(t){requestAnimationFrame(()=>{requestAnimationFrame(t)})}let _h=0;function Vl(t,i,s,l){const u=t._endId=++_h,d=()=>{u===t._endId&&l()};if(s!=null)return setTimeout(d,s);const{type:h,timeout:v,propCount:b}=bh(t,i);if(!h)return l();const C=h+"end";let T=0;const M=()=>{t.removeEventListener(C,R),d()},R=B=>{B.target===t&&++T>=b&&M()};setTimeout(()=>{T<b&&M()},v+1),t.addEventListener(C,R)}function bh(t,i){const s=window.getComputedStyle(t),l=Z=>(s[Z]||"").split(", "),u=l(`${Mi}Delay`),d=l(`${Mi}Duration`),h=Zl(u,d),v=l(`${gs}Delay`),b=l(`${gs}Duration`),C=Zl(v,b);let T=null,M=0,R=0;i===Mi?h>0&&(T=Mi,M=h,R=d.length):i===gs?C>0&&(T=gs,M=C,R=b.length):(M=Math.max(h,C),T=M>0?h>C?Mi:gs:null,R=T?T===Mi?d.length:b.length:0);const B=T===Mi&&/\b(?:transform|all)(?:,|$)/.test(l(`${Mi}Property`).toString());return{type:T,timeout:M,propCount:R,hasTransform:B}}function Zl(t,i){for(;t.length<i.length;)t=t.concat(t);return Math.max(...i.map((s,l)=>Hl(s)+Hl(t[l])))}function Hl(t){return t==="auto"?0:Number(t.slice(0,-1).replace(",","."))*1e3}function jl(t){return(t?t.ownerDocument:document).body.offsetHeight}function yh(t,i,s){const l=t[Ns];l&&(i=(i?[i,...l]:[...l]).join(" ")),i==null?t.removeAttribute("class"):s?t.setAttribute("class",i):t.className=i}const ka=Symbol("_vod"),zc=Symbol("_vsh"),xh={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 im=xs.exports,pu;function om(){return pu||(pu=1,(function(t,i){(function(s,l){l(i)})(im,(function(s){var l="1.9.4";function u(e){var n,o,a,c;for(o=1,a=arguments.length;o<a;o++){c=arguments[o];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 o=Array.prototype.slice;if(e.bind)return e.bind.apply(e,o.call(arguments,1));var a=o.call(arguments,2);return function(){return e.apply(n,a.length?a.concat(o.call(arguments)):arguments)}}var v=0;function b(e){return"_leaflet_id"in e||(e._leaflet_id=++v),e._leaflet_id}function C(e,n,o){var a,c,m,P;return P=function(){a=!1,c&&(m.apply(o,c),c=!1)},m=function(){a?c=arguments:(e.apply(o,arguments),setTimeout(P,n),a=!0)},m}function T(e,n,o){var a=n[1],c=n[0],m=a-c;return e===a&&o?e:((e-c)%m+m)%m+c}function M(){return!1}function R(e,n){if(n===!1)return e;var o=Math.pow(10,n===void 0?6:n);return Math.round(e*o)/o}function B(e){return e.trim?e.trim():e.replace(/^\s+|\s+$/g,"")}function Z(e){return B(e).split(/\s+/)}function F(e,n){Object.prototype.hasOwnProperty.call(e,"options")||(e.options=e.options?d(e.options):{});for(var o in n)e.options[o]=n[o];return e.options}function he(e,n,o){var a=[];for(var c in e)a.push(encodeURIComponent(o?c.toUpperCase():c)+"="+encodeURIComponent(e[c]));return(!n||n.indexOf("?")===-1?"?":"&")+a.join("&")}var pe=/\{ *([\w_ -]+) *\}/g;function q(e,n){return e.replace(pe,function(o,a){var c=n[a];if(c===void 0)throw new Error("No value provided for variable "+o);return typeof c=="function"&&(c=c(n)),c})}var Te=Array.isArray||function(e){return Object.prototype.toString.call(e)==="[object Array]"};function fe(e,n){for(var o=0;o<e.length;o++)if(e[o]===n)return o;return-1}var Ue="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=";function $e(e){return window["webkit"+e]||window["moz"+e]||window["ms"+e]}var Ie=0;function Ge(e){var n=+new Date,o=Math.max(0,16-(n-Ie));return Ie=n+o,window.setTimeout(e,o)}var _e=window.requestAnimationFrame||$e("RequestAnimationFrame")||Ge,ye=window.cancelAnimationFrame||$e("CancelAnimationFrame")||$e("CancelRequestAnimationFrame")||function(e){window.clearTimeout(e)};function ze(e,n,o){if(o&&_e===Ge)e.call(n);else return _e.call(window,h(e,n))}function ne(e){e&&ye.call(window,e)}var je={__proto__:null,extend:u,create:d,bind:h,get lastId(){return v},stamp:b,throttle:C,wrapNum:T,falseFn:M,formatNum:R,trim:B,splitWords:Z,setOptions:F,getParamString:he,template:q,isArray:Te,indexOf:fe,emptyImageUrl:Ue,requestFn:_e,cancelFn:ye,requestAnimFrame:ze,cancelAnimFrame:ne};function ie(){}ie.extend=function(e){var n=function(){F(this),this.initialize&&this.initialize.apply(this,arguments),this.callInitHooks()},o=n.__super__=this.prototype,a=d(o);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&&(We(e.includes),u.apply(null,[a].concat(e.includes))),u(a,e),delete a.statics,delete a.includes,a.options&&(a.options=o.options?d(o.options):{},u(a.options,e.options)),a._initHooks=[],a.callInitHooks=function(){if(!this._initHooksCalled){o.callInitHooks&&o.callInitHooks.call(this),this._initHooksCalled=!0;for(var m=0,P=a._initHooks.length;m<P;m++)a._initHooks[m].call(this)}},n},ie.include=function(e){var n=this.prototype.options;return u(this.prototype,e),e.options&&(this.prototype.options=n,this.mergeOptions(e.options)),this},ie.mergeOptions=function(e){return u(this.prototype.options,e),this},ie.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 We(e){if(!(typeof L>"u"||!L||!L.Mixin)){e=Te(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 le={on:function(e,n,o){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,o)}return this},off:function(e,n,o){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,P=e.length;m<P;m++)c?this._off(e[m]):this._off(e[m],n,o)}return this},_on:function(e,n,o,a){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 c={fn:n,ctx:o};a&&(c.once=!0),this._events=this._events||{},this._events[e]=this._events[e]||[],this._events[e].push(c)}},_off:function(e,n,o){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=M;delete this._events[e];return}if(typeof n!="function"){console.warn("wrong listener type:Line truncated
|
||||
-20
@@ -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 Mr(t){const i=Object.create(null);for(const o of t.split(","))i[o]=1;return o=>o in i}const mt={},Ms=[],Un=()=>{},_u=()=>!1,wa=t=>t.charCodeAt(0)===111&&t.charCodeAt(1)===110&&(t.charCodeAt(2)>122||t.charCodeAt(2)<97),ka=t=>t.startsWith("onUpdate:"),It=Object.assign,Er=(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,Es=t=>$o(t)==="[object Map]",Rs=t=>$o(t)==="[object Set]",gl=t=>$o(t)==="[object Date]",We=t=>typeof t=="function",xt=t=>typeof t=="string",Ln=t=>typeof t=="symbol",dt=t=>t!==null&&typeof t=="object",yu=t=>(dt(t)||We(t))&&We(t.then)&&We(t.catch),bu=Object.prototype.toString,$o=t=>bu.call(t),dd=t=>$o(t).slice(8,-1),xu=t=>$o(t)==="[object Object]",Or=t=>xt(t)&&t!=="NaN"&&t[0]!=="-"&&""+parseInt(t,10)===t,yo=Mr(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),Sa=t=>{const i=Object.create(null);return(o=>i[o]||(i[o]=t(o)))},fd=/-\w/g,Pn=Sa(t=>t.replace(fd,i=>i.slice(1).toUpperCase())),hd=/\B([A-Z])/g,zi=Sa(t=>t.replace(hd,"-$1").toLowerCase()),wu=Sa(t=>t.charAt(0).toUpperCase()+t.slice(1)),Qa=Sa(t=>t?`on${wu(t)}`:""),Vn=(t,i)=>!Object.is(t,i),la=(t,...i)=>{for(let o=0;o<t.length;o++)t[o](...i)},ku=(t,i,o,l=!1)=>{Object.defineProperty(t,i,{configurable:!0,enumerable:!1,writable:l,value:o})},Ta=t=>{const i=parseFloat(t);return isNaN(i)?t:i},pd=t=>{const i=xt(t)?Number(t):NaN;return isNaN(i)?t:i};let vl;const Pa=()=>vl||(vl=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function Is(t){if(De(t)){const i={};for(let o=0;o<t.length;o++){const l=t[o],u=xt(l)?_d(l):Is(l);if(u)for(const d in u)i[d]=u[d]}return i}else if(xt(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 Ee(t){let i="";if(xt(t))i=t;else if(De(t))for(let o=0;o<t.length;o++){const l=Ee(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=Mr(yd);function Su(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=Mi(t[l],i[l]);return o}function Mi(t,i){if(t===i)return!0;let o=gl(t),l=gl(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 v=t.hasOwnProperty(h),y=i.hasOwnProperty(h);if(v&&!y||!v&&y||!Mi(t[h],i[h]))return!1}}return String(t)===String(i)}function zr(t,i){return t.findIndex(o=>Mi(o,i))}const Tu=t=>!!(t&&t.__v_isRef===!0),S=t=>xt(t)?t:t==null?"":De(t)||dt(t)&&(t.toString===bu||!We(t.toString))?Tu(t)?S(t.value):JSON.stringify(t,Pu,2):String(t),Pu=(t,i)=>Tu(i)?Pu(t,i.value):Es(i)?{[`Map(${i.size})`]:[...i.entries()].reduce((o,[l,u],d)=>(o[er(l,d)+" =>"]=u,o),{})}:Rs(i)?{[`Set(${i.size})`]:[...i.values()].map(o=>er(o))}:Ln(i)?er(i):dt(i)&&!De(i)&&!xu(i)?String(i):i,er=(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 Rt;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&&Rt&&(Rt.active?(this.parent=Rt,this.index=(Rt.scopes||(Rt.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=Rt;try{return Rt=this,i()}finally{Rt=o}}}on(){++this._on===1&&(this.prevScope=Rt,Rt=this)}off(){if(this._on>0&&--this._on===0){if(Rt===this)Rt=this.prevScope;else{let i=Rt;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 Rt}let gt;const tr=new WeakSet;class Cu{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,Rt&&(Rt.active?Rt.effects.push(this):this.flags&=-2)}pause(){this.flags|=64}resume(){this.flags&64&&(this.flags&=-65,tr.has(this)&&(tr.delete(this),this.trigger()))}notify(){this.flags&2&&!(this.flags&32)||this.flags&8||Mu(this)}run(){if(!(this.flags&1))return this.fn();this.flags|=2,_l(this),Eu(this);const i=gt,o=Cn;gt=this,Cn=!0;try{return this.fn()}finally{Ou(this),gt=i,Cn=o,this.flags&=-3}}stop(){if(this.flags&1){for(let i=this.deps;i;i=i.nextDep)Ir(i);this.deps=this.depsTail=void 0,_l(this),this.onStop&&this.onStop(),this.flags&=-2}}trigger(){this.flags&64?tr.add(this):this.scheduler?this.scheduler():this.runIfDirty()}runIfDirty(){fr(this)&&this.run()}get dirty(){return fr(this)}}let Lu=0,bo,xo;function Mu(t,i=!1){if(t.flags|=8,i){t.next=xo,xo=t;return}t.next=bo,bo=t}function Ar(){Lu++}function $r(){if(--Lu>0)return;if(xo){let i=xo;for(xo=void 0;i;){const o=i.next;i.next=void 0,i.flags&=-9,i=o}}let t;for(;bo;){let i=bo;for(bo=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 Eu(t){for(let i=t.deps;i;i=i.nextDep)i.version=-1,i.prevActiveLink=i.dep.activeLink,i.dep.activeLink=i}function Ou(t){let i,o=t.depsTail,l=o;for(;l;){const u=l.prevDep;l.version===-1?(l===o&&(o=u),Ir(l),Sd(l)):i=l,l.dep.activeLink=l.prevActiveLink,l.prevActiveLink=void 0,l=u}t.deps=i,t.depsTail=o}function fr(t){for(let i=t.deps;i;i=i.nextDep)if(i.dep.version!==i.version||i.dep.computed&&(zu(i.dep.computed)||i.dep.version!==i.version))return!0;return!!t._dirty}function zu(t){if(t.flags&4&&!(t.flags&16)||(t.flags&=-17,t.globalVersion===Po)||(t.globalVersion=Po,!t.isSSR&&t.flags&128&&(!t.deps&&!t._dirty||!fr(t))))return;t.flags|=2;const i=t.dep,o=gt,l=Cn;gt=t,Cn=!0;try{Eu(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{gt=o,Cn=l,Ou(t),t.flags&=-3}}function Ir(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)Ir(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 Au=[];function Zn(){Au.push(Cn),Cn=!1}function Hn(){const t=Au.pop();Cn=t===void 0?!0:t}function _l(t){const{cleanup:i}=t;if(t.cleanup=void 0,i){const o=gt;gt=void 0;try{i()}finally{gt=o}}}let Po=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 Dr{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(!gt||!Cn||gt===this.computed)return;let o=this.activeLink;if(o===void 0||o.sub!==gt)o=this.activeLink=new Td(gt,this),gt.deps?(o.prevDep=gt.depsTail,gt.depsTail.nextDep=o,gt.depsTail=o):gt.deps=gt.depsTail=o,$u(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=gt.depsTail,o.nextDep=void 0,gt.depsTail.nextDep=o,gt.depsTail=o,gt.deps===o&&(gt.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 Io(t,i,o,l){try{return l?t(...l):t()}catch(u){La(u,i,o)}}function Sn(t,i,o,l){if(We(t)){const u=Io(t,i,o,l);return u&&yu(u)&&u.catch(d=>{La(d,i,o)}),u}if(De(t)){const u=[];for(let d=0;d<t.length;d++)u.push(Sn(t[d],i,o,l));return u}}function La(t,i,o,l=!0){const u=i?i.vnode:null,{errorHandler:d,throwUnhandledErrorInProduction:h}=i&&i.appContext.config||mt;if(i){let v=i.parent;const y=i.proxy,C=`https://vuejs.org/error-reference/#runtime-${o}`;for(;v;){const T=v.ec;if(T){for(let O=0;O<T.length;O++)if(T[O](t,y,C)===!1)return}v=v.parent}if(d){Zn(),Io(d,null,10,[t,y,C]),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 Jt=[];let Rn=-1;const Os=[];let Li=null,Ls=0;const Uu=Promise.resolve();let da=null;function Zu(t){const i=da||Uu;return t?i.then(this?t.bind(this):t):i}function Jd(t){let i=Rn+1,o=Jt.length;for(;i<o;){const l=i+o>>>1,u=Jt[l],d=Lo(u);d<t||d===t&&u.flags&2?i=l+1:o=l}return i}function Br(t){if(!(t.flags&1)){const i=Lo(t),o=Jt[Jt.length-1];!o||!(t.flags&2)&&i>=Lo(o)?Jt.push(t):Jt.splice(Jd(i),0,t),t.flags|=1,Hu()}}function Hu(){da||(da=Uu.then(Wu))}function Xd(t){De(t)?Os.push(...t):Li&&t.id===-1?Li.splice(Ls+1,0,t):t.flags&1||(Os.push(t),t.flags|=1),Hu()}function bl(t,i,o=Rn+1){for(;o<Jt.length;o++){const l=Jt[o];if(l&&l.flags&2){if(t&&l.id!==t.uid)continue;Jt.splice(o,1),o--,l.flags&4&&(l.flags&=-2),l(),l.flags&4||(l.flags&=-2)}}}function ju(t){if(Os.length){const i=[...new Set(Os)].sort((o,l)=>Lo(o)-Lo(l));if(Os.length=0,Li){Li.push(...i);return}for(Li=i,Ls=0;Ls<Li.length;Ls++){const o=Li[Ls];o.flags&4&&(o.flags&=-2),o.flags&8||o(),o.flags&=-2}Li=null,Ls=0}}const Lo=t=>t.id==null?t.flags&2?-1:1/0:t.id;function Wu(t){try{for(Rn=0;Rn<Jt.length;Rn++){const i=Jt[Rn];i&&!(i.flags&8)&&(i.flags&4&&(i.flags&=-2),Io(i,i.i,i.i?15:14),i.flags&4||(i.flags&=-2))}}finally{for(;Rn<Jt.length;Rn++){const i=Jt[Rn];i&&(i.flags&=-2)}Rn=-1,Jt.length=0,ju(),da=null,(Jt.length||Os.length)&&Wu()}}let jt=null,Ku=null;function fa(t){const i=jt;return jt=t,Ku=t&&t.type.__scopeId||null,i}function Ce(t,i=jt,o){if(!i||t._n)return t;const l=(...u)=>{l._d&&ma(-1);const d=fa(i);let h;try{h=t(...u)}finally{fa(d),l._d&&ma(1)}return h};return l._n=!0,l._c=!0,l._d=!0,l}function oe(t,i){if(jt===null)return t;const o=Aa(jt),l=t.dirs||(t.dirs=[]);for(let u=0;u<i.length;u++){let[d,h,v,y=mt]=i[u];d&&(We(d)&&(d={mounted:d,updated:d}),d.deep&&ui(h),l.push({dir:d,instance:o,value:h,oldValue:void 0,arg:v,modifiers:y}))}return t}function Xi(t,i,o,l){const u=t.dirs,d=i&&i.dirs;for(let h=0;h<u.length;h++){const v=u[h];d&&(v.oldValue=d[h].value);let y=v.dir[l];y&&(Zn(),Sn(y,o,8,[t.el,v,t,i]),Hn())}}function Gu(t,i){if(Xt){let o=Xt.provides;const l=Xt.parent&&Xt.parent.provides;l===o&&(o=Xt.provides=Object.create(l)),o[t]=i}}function wo(t,i,o=!1){const l=Pc();if(l||As){let u=As?As._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&&We(i)?i.call(l&&l.proxy):i}}const Qd=Symbol.for("v-scx"),ef=()=>wo(Qd);function $t(t,i,o){return qu(t,i,o)}function qu(t,i,o=mt){const{immediate:l,deep:u,flush:d,once:h}=o,v=It({},o),y=i&&l||!i&&d!=="post";let C;if(zo){if(d==="sync"){const V=ef();C=V.__watcherHandles||(V.__watcherHandles=[])}else if(!y){const V=()=>{};return V.stop=Un,V.resume=Un,V.pause=Un,V}}const T=Xt;v.call=(V,H,F)=>Sn(V,T,H,F);let O=!1;d==="post"?v.scheduler=V=>{Yt(V,T&&T.suspense)}:d!=="sync"&&(O=!0,v.scheduler=(V,H)=>{H?V():Br(V)}),v.augmentJob=V=>{i&&(V.flags|=4),O&&(V.flags|=2,T&&(V.id=T.uid,V.i=T))};const B=qd(t,i,v);return zo&&(C?C.push(B):y&&B()),B}function tf(t,i,o){const l=this.proxy,u=xt(t)?t.includes(".")?Yu(l,t):()=>l[t]:t.bind(l,l);let d;We(i)?d=i:(d=i.handler,o=i);const h=Do(this),v=qu(u,d.bind(l),o);return h(),v}function Yu(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 Ci=new WeakMap,Ju=Symbol("_vte"),Xu=t=>t.__isTeleport,is=t=>t&&(t.disabled||t.disabled===""),nf=t=>t&&(t.defer||t.defer===""),xl=t=>typeof SVGElement<"u"&&t instanceof SVGElement,wl=t=>typeof MathMLElement=="function"&&t instanceof MathMLElement,vr=(t,i)=>{const o=t&&t.to;return xt(o)?i?i(o):null:o},sf={name:"Teleport",__isTeleport:!0,process(t,i,o,l,u,d,h,v,y,C){const{mc:T,pc:O,pbc:B,o:{insert:V,querySelector:H,createText:F,createComment:fe,parentNode:ve}}=C,Y=is(i.props);let{dynamicChildren:Pe}=i;const he=(Ie,Ve,pe)=>{Ie.shapeFlag&16&&T(Ie.children,Ve,pe,u,d,h,v,y)},ye=(Ie=i)=>{const Ve=is(Ie.props),pe=Ie.target=vr(Ie.props,H),ze=_r(pe,Ie,F,V);pe&&(h!=="svg"&&xl(pe)?h="svg":h!=="mathml"&&wl(pe)&&(h="mathml"),u&&u.isCE&&(u.ce._teleportTargets||(u.ce._teleportTargets=new Set)).add(pe),Ve||(he(Ie,pe,ze),mo(Ie,!1)))},Ne=Ie=>{const Ve=()=>{if(Ci.get(Ie)===Ve){if(Ci.delete(Ie),is(Ie.props)){const pe=ve(Ie.el)||o;he(Ie,pe,Ie.anchor),mo(Ie,!0)}ye(Ie)}};Ci.set(Ie,Ve),Yt(Ve,d)};if(t==null){const Ie=i.el=F(""),Ve=i.anchor=F("");if(V(Ie,o,l),V(Ve,o,l),nf
Line truncated
|
||||
* @vue/runtime-dom v3.5.39
|
||||
* (c) 2018-present Yuxi (Evan) You and Vue contributors
|
||||
* @license MIT
|
||||
**/let Tr;const Dl=typeof window<"u"&&window.trustedTypes;if(Dl)try{Tr=Dl.createPolicy("vue",{createHTML:t=>t})}catch{}const Mc=Tr?t=>Tr.createHTML(t):t=>t,lh="http://www.w3.org/2000/svg",uh="http://www.w3.org/1998/Math/MathML",ai=typeof document<"u"?document:null,Nl=ai&&ai.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"?ai.createElementNS(lh,t):i==="mathml"?ai.createElementNS(uh,t):o?ai.createElement(t,{is:o}):ai.createElement(t);return t==="select"&&l&&l.multiple!=null&&u.setAttribute("multiple",l.multiple),u},createText:t=>ai.createTextNode(t),createComment:t=>ai.createComment(t),setText:(t,i)=>{t.nodeValue=i},setElementText:(t,i)=>{t.textContent=i},parentNode:t=>t.parentNode,nextSibling:t=>t.nextSibling,querySelector:t=>ai.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{Nl.innerHTML=Mc(l==="svg"?`<svg>${t}</svg>`:l==="mathml"?`<math>${t}</math>`:t);const v=Nl.content;if(l==="svg"||l==="mathml"){const y=v.firstChild;for(;y.firstChild;)v.appendChild(y.firstChild);v.removeChild(y)}i.insertBefore(v,o)}return[h?h.nextSibling:i.firstChild,o?o.previousSibling:i.lastChild]}},Ti="transition",ho="animation",Ao=Symbol("_vtc"),Ec={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=It({},Qu,Ec),fh=t=>(t.displayName="Transition",t.props=dh,t),hh=fh((t,{slots:i})=>ah(uf,ph(t),i)),es=(t,i=[])=>{De(t)?t.forEach(o=>o(...i)):t&&t(...i)},Rl=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 Ec||(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:v=`${o}-enter-to`,appearFromClass:y=d,appearActiveClass:C=h,appearToClass:T=v,leaveFromClass:O=`${o}-leave-from`,leaveActiveClass:B=`${o}-leave-active`,leaveToClass:V=`${o}-leave-to`}=t,H=mh(u),F=H&&H[0],fe=H&&H[1],{onBeforeEnter:ve,onEnter:Y,onEnterCancelled:Pe,onLeave:he,onLeaveCancelled:ye,onBeforeAppear:Ne=ve,onAppear:Ie=Y,onAppearCancelled:Ve=Pe}=i,pe=(te,de,_e,be)=>{te._enterCancelled=be,ts(te,de?T:v),ts(te,de?C:h),_e&&_e()},ze=(te,de)=>{te._isLeaving=!1,ts(te,O),ts(te,V),ts(te,B),de&&de()},Te=te=>(de,_e)=>{const be=te?Ie:Y,ae=()=>pe(de,te,_e);es(be,[de,ae]),Fl(()=>{ts(de,te?y:d),oi(de,te?T:v),Rl(be)||Bl(de,l,F,ae)})};return It(i,{onBeforeEnter(te){es(ve,[te]),oi(te,d),oi(te,h)},onBeforeAppear(te){es(Ne,[te]),oi(te,y),oi(te,C)},onEnter:Te(!1),onAppear:Te(!0),onLeave(te,de){te._isLeaving=!0;const _e=()=>ze(te,de);oi(te,O),te._enterCancelled?(oi(te,B),Zl(te)):(Zl(te),oi(te,B)),Fl(()=>{te._isLeaving&&(ts(te,O),oi(te,V),Rl(he)||Bl(te,l,fe,_e))}),es(he,[te,_e])},onEnterCancelled(te){pe(te,!1,void 0,!0),es(Pe,[te])},onAppearCancelled(te){pe(te,!0,void 0,!0),es(Ve,[te])},onLeaveCancelled(te){ze(te),es(ye,[te])}})}function mh(t){if(t==null)return null;if(dt(t))return[lr(t.enter),lr(t.leave)];{const i=lr(t);return[i,i]}}function lr(t){return pd(t)}function oi(t,i){i.split(/\s+/).forEach(o=>o&&t.classList.add(o)),(t[Ao]||(t[Ao]=new Set)).add(i)}function ts(t,i){i.split(/\s+/).forEach(l=>l&&t.classList.remove(l));const o=t[Ao];o&&(o.delete(i),o.size||(t[Ao]=void 0))}function Fl(t){requestAnimationFrame(()=>{requestAnimationFrame(t)})}let gh=0;function Bl(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:v,propCount:y}=vh(t,i);if(!h)return l();const C=h+"end";let T=0;const O=()=>{t.removeEventListener(C,B),d()},B=V=>{V.target===t&&++T>=y&&O()};setTimeout(()=>{T<y&&O()},v+1),t.addEventListener(C,B)}function vh(t,i){const o=window.getComputedStyle(t),l=H=>(o[H]||"").split(", "),u=l(`${Ti}Delay`),d=l(`${Ti}Duration`),h=Vl(u,d),v=l(`${ho}Delay`),y=l(`${ho}Duration`),C=Vl(v,y);let T=null,O=0,B=0;i===Ti?h>0&&(T=Ti,O=h,B=d.length):i===ho?C>0&&(T=ho,O=C,B=y.length):(O=Math.max(h,C),T=O>0?h>C?Ti:ho:null,B=T?T===Ti?d.length:y.length:0);const V=T===Ti&&/\b(?:transform|all)(?:,|$)/.test(l(`${Ti}Property`).toString());return{type:T,timeout:O,propCount:B,hasTransform:V}}function Vl(t,i){for(;t.length<i.length;)t=t.concat(t);return Math.max(...i.map((o,l)=>Ul(o)+Ul(t[l])))}function Ul(t){return t==="auto"?0:Number(t.slice(0,-1).replace(",","."))*1e3}function Zl(t){return(t?t.ownerDocument:document).body.offsetHeight}function _h(t,i,o){const l=t[Ao];l&&(i=(i?[i,...l]:[...l]).join(" ")),i==null?t.removeAttribute("class"):o?t.setAttribute("class",i):t.className=i}const _a=Symbol("_vod"),Oc=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=_o.exports,fu;function nm(){return fu||(fu=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 v=0;function y(e){return"_leaflet_id"in e||(e._leaflet_id=++v),e._leaflet_id}function C(e,n,s){var a,c,m,P;return P=function(){a=!1,c&&(m.apply(s,c),c=!1)},m=function(){a?c=arguments:(e.apply(s,arguments),setTimeout(P,n),a=!0)},m}function T(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 H(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 Y(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 Pe=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 ye="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=";function Ne(e){return window["webkit"+e]||window["moz"+e]||window["ms"+e]}var Ie=0;function Ve(e){var n=+new Date,s=Math.max(0,16-(n-Ie));return Ie=n+s,window.setTimeout(e,s)}var pe=window.requestAnimationFrame||Ne("RequestAnimationFrame")||Ve,ze=window.cancelAnimationFrame||Ne("CancelAnimationFrame")||Ne("CancelRequestAnimationFrame")||function(e){window.clearTimeout(e)};function Te(e,n,s){if(s&&pe===Ve)e.call(n);else return pe.call(window,h(e,n))}function te(e){e&&ze.call(window,e)}var de={__proto__:null,extend:u,create:d,bind:h,get lastId(){return v},stamp:y,throttle:C,wrapNum:T,falseFn:O,formatNum:B,trim:V,splitWords:H,setOptions:F,getParamString:fe,template:Y,isArray:Pe,indexOf:he,emptyImageUrl:ye,requestFn:pe,cancelFn:ze,requestAnimFrame:Te,cancelAnimFrame:te};function _e(){}_e.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&&(be(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,P=a._initHooks.length;m<P;m++)a._initHooks[m].call(this)}},n},_e.include=function(e){var n=this.prototype.options;return u(this.prototype,e),e.options&&(this.prototype.options=n,this.mergeOptions(e.options)),this},_e.mergeOptions=function(e){return u(this.prototype.options,e),this},_e.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 be(e){if(!(typeof L>"u"||!L||!L.Mixin)){e=Pe(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=H(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=H(e);for(var c=arguments.length===1,m=0,P=e.length;m<P;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
|
||||
Vendored
+1
-1
@@ -1 +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
|
||||
: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
|
||||
Vendored
+2
-2
@@ -35,8 +35,8 @@
|
||||
})()
|
||||
</script>
|
||||
<title>PilotVault — Control Panel</title>
|
||||
<script type="module" crossorigin src="./assets/index-CznFJTz4.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="./assets/index-D0ghlckk.css">
|
||||
<script type="module" crossorigin src="./assets/index-BSx6Lf8i.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="./assets/index-FLz21UuE.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
@@ -166,14 +166,16 @@ export async function testOpenSky() {
|
||||
return { ok: r.ok, status: r.status, body: await r.json().catch(() => ({})) }
|
||||
}
|
||||
|
||||
// Live aircraft positions (OpenSky state vectors) within the caller's resolved
|
||||
// bounding box, for plotting on the Live map. Returns { states, unavailable?,
|
||||
// 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() {
|
||||
// Live aircraft positions (OpenSky state vectors) for plotting on the Live map.
|
||||
// Pass an optional `bbox` ("lamin,lomin,lamax,lomax") to override the caller's
|
||||
// configured area — used by the auto cascade (drone/device/region location).
|
||||
// Returns { states, unavailable?, 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(bbox) {
|
||||
try {
|
||||
const r = await fetch('/bff/integrations/opensky/states')
|
||||
const qs = bbox ? `?bbox=${encodeURIComponent(bbox)}` : ''
|
||||
const r = await fetch(`/bff/integrations/opensky/states${qs}`)
|
||||
if (!r.ok) return { states: [], unavailable: true, detail: 'OpenSky unavailable' }
|
||||
const d = await r.json()
|
||||
return {
|
||||
|
||||
@@ -9,6 +9,7 @@ import Documents from './Documents.vue'
|
||||
import Toggle from './settings/Toggle.vue'
|
||||
import { getDevices, sendCommand, getOpenSkyStates } from '../api.js'
|
||||
import { formatTime, prefs } from '../prefs.js'
|
||||
import { countryForPoint, bboxForCountry } from '../countries.js'
|
||||
|
||||
const props = defineProps({
|
||||
email: { type: String, default: '' },
|
||||
@@ -50,9 +51,72 @@ const airIntervalSeconds = computed(() => {
|
||||
return Number.isFinite(n) && n > 0 ? n : 30
|
||||
})
|
||||
|
||||
// Europe — the ultimate fallback for the auto cascade (matches the server default).
|
||||
const EUROPE_BBOX = '34,-25,72,45'
|
||||
|
||||
// Cached browser geolocation: { lat, lng } once granted, false once denied/failed,
|
||||
// null before we've asked. Requested lazily and at most once per session.
|
||||
const browserGeo = ref(null)
|
||||
let browserGeoPending = false
|
||||
function requestBrowserGeo() {
|
||||
if (browserGeoPending || browserGeo.value !== null) return
|
||||
if (typeof navigator === 'undefined' || !navigator.geolocation) { browserGeo.value = false; return }
|
||||
browserGeoPending = true
|
||||
navigator.geolocation.getCurrentPosition(
|
||||
(pos) => { browserGeo.value = { lat: pos.coords.latitude, lng: pos.coords.longitude }; browserGeoPending = false },
|
||||
() => { browserGeo.value = false; browserGeoPending = false }, // denied/unavailable — fall through to Region
|
||||
{ timeout: 8000, maximumAge: 600000 },
|
||||
)
|
||||
}
|
||||
|
||||
// A device's position from telemetry, or null. `key` picks drone vs phone GPS.
|
||||
function devicePoint(d, latKey, lngKey) {
|
||||
const t = (d && d.telemetry) || {}
|
||||
const lat = t[latKey]
|
||||
const lng = t[lngKey]
|
||||
return typeof lat === 'number' && typeof lng === 'number' && (lat || lng) ? { lat, lng } : null
|
||||
}
|
||||
|
||||
// Resolve the live-map bounding box from the location cascade (auto mode):
|
||||
// 1. drone GPS (selected device, else any device with a fix)
|
||||
// 2. user location: phone GPS (from the Fly App) else browser geolocation
|
||||
// 3. Region country from User Settings
|
||||
// 4. Europe
|
||||
// Each location step maps a point to its country's bbox via countries.js.
|
||||
function resolveAutoBbox() {
|
||||
// 1. Drone telemetry position.
|
||||
const drone =
|
||||
devicePoint(sel.value, 'latitude', 'longitude') ||
|
||||
ids.value.map((id) => devicePoint(devices[id], 'latitude', 'longitude')).find(Boolean)
|
||||
if (drone) {
|
||||
const c = countryForPoint(drone.lat, drone.lng)
|
||||
if (c) return c.bbox
|
||||
}
|
||||
// 2a. Phone GPS reported by the Fly App (rides on telemetry).
|
||||
const phone =
|
||||
devicePoint(sel.value, 'phoneLatitude', 'phoneLongitude') ||
|
||||
ids.value.map((id) => devicePoint(devices[id], 'phoneLatitude', 'phoneLongitude')).find(Boolean)
|
||||
if (phone) {
|
||||
const c = countryForPoint(phone.lat, phone.lng)
|
||||
if (c) return c.bbox
|
||||
}
|
||||
// 2b. Browser geolocation (asks once; ignored until granted).
|
||||
requestBrowserGeo()
|
||||
if (browserGeo.value) {
|
||||
const c = countryForPoint(browserGeo.value.lat, browserGeo.value.lng)
|
||||
if (c) return c.bbox
|
||||
}
|
||||
// 3. Region country fallback.
|
||||
const regionBbox = bboxForCountry(prefs.region)
|
||||
if (regionBbox) return regionBbox
|
||||
// 4. Europe.
|
||||
return EUROPE_BBOX
|
||||
}
|
||||
|
||||
async function refreshAirspace() {
|
||||
if (!prefs.showAirTraffic) return
|
||||
const { states, unavailable, detail, plan, recommendedInterval } = await getOpenSkyStates()
|
||||
const bbox = prefs.autoBbox ? resolveAutoBbox() : undefined
|
||||
const { states, unavailable, detail, plan, recommendedInterval } = await getOpenSkyStates(bbox)
|
||||
aircraft.value = states
|
||||
airspace.unavailable = unavailable
|
||||
airspace.detail = detail
|
||||
|
||||
@@ -6,6 +6,7 @@ import Segmented from './settings/Segmented.vue'
|
||||
import Row from './settings/Row.vue'
|
||||
import { themeMode, setThemeMode } from '../theme.js'
|
||||
import { prefs, formatDateTime, importPrefs, applyFontSize, applyReduceMotion } from '../prefs.js'
|
||||
import { europeanCountries, regionOptions } from '../countries.js'
|
||||
import {
|
||||
getUsers, createUser, updateUser, deleteUser,
|
||||
getOrgs, createOrg, updateOrg, deleteOrg,
|
||||
@@ -112,9 +113,10 @@ const TIME_OPTS = [
|
||||
const LANGS = [
|
||||
['en', 'English'], ['es', 'Español'], ['de', 'Deutsch'], ['fr', 'Français'], ['pl', 'Polski'], ['ja', '日本語'],
|
||||
]
|
||||
const REGIONS = [
|
||||
['US', 'United States'], ['GB', 'United Kingdom'], ['EU', 'European Union'], ['CA', 'Canada'], ['AU', 'Australia'], ['JP', 'Japan'],
|
||||
]
|
||||
// All countries of the world (also the final fallback for the auto bounding box).
|
||||
const REGIONS = regionOptions()
|
||||
// Display name of the currently selected Region (for the auto-bbox helper text).
|
||||
const regionName = computed(() => (REGIONS.find(([v]) => v === prefs.region) || [null, prefs.region])[1])
|
||||
const DATE_FMTS = [
|
||||
['MDY', 'MM/DD/YYYY'], ['DMY', 'DD/MM/YYYY'], ['YMD', 'YYYY/MM/DD'], ['ISO', 'YYYY-MM-DD'],
|
||||
]
|
||||
@@ -207,8 +209,8 @@ const OS_SCOPE_OPTS = [
|
||||
]
|
||||
|
||||
// Predefined bounding boxes (lamin,lomin,lamax,lomax). The picker offers these
|
||||
// plus a "Custom…" option that reveals the free-text field for manual entry.
|
||||
// Europe is the default (kept in sync with the API Server's defaultBBox).
|
||||
// plus "Automatic" (the location cascade) and "Custom…" (manual coordinates).
|
||||
// European countries come from the shared dataset in countries.js.
|
||||
const OS_BBOX_GROUPS = [
|
||||
{ label: 'World', options: [
|
||||
{ value: '-90,-180,90,180', label: 'World' },
|
||||
@@ -221,15 +223,12 @@ const OS_BBOX_GROUPS = [
|
||||
{ value: '-56,-82,13,-34', label: 'South America' },
|
||||
{ value: '-48,110,-10,180', label: 'Oceania' },
|
||||
] },
|
||||
{ label: 'Countries', options: [
|
||||
{ value: '49,14.1,54.9,24.2', label: 'Poland' },
|
||||
{ value: '50.5,3.2,53.7,7.3', label: 'Netherlands' },
|
||||
{ value: '47.2,5.8,55.1,15.1', label: 'Germany' },
|
||||
{ value: '41.3,-5.2,51.1,9.6', label: 'France' },
|
||||
{ value: '49.9,-8.7,59,1.8', label: 'United Kingdom' },
|
||||
{ value: '35.9,-9.6,43.8,3.4', label: 'Spain' },
|
||||
{ value: '36.6,6.6,47.1,18.6', label: 'Italy' },
|
||||
{ label: 'European countries', options: europeanCountries() },
|
||||
{ label: 'Other countries', options: [
|
||||
{ value: '24,-125,49.5,-66.5', label: 'United States' },
|
||||
{ value: '41.7,-141,83.1,-52.6', label: 'Canada' },
|
||||
{ value: '-43.6,113.3,-10.7,153.6', label: 'Australia' },
|
||||
{ value: '24,122.9,45.5,145.8', label: 'Japan' },
|
||||
] },
|
||||
]
|
||||
const OS_BBOX_FLAT = OS_BBOX_GROUPS.flatMap((g) => g.options)
|
||||
@@ -253,20 +252,32 @@ function osBboxLabel(v) {
|
||||
// Manual-entry toggle: sticky once the user picks "Custom…", and implied when
|
||||
// the current value doesn't match any preset.
|
||||
const osBboxCustom = ref(false)
|
||||
// The picker's value. "__auto__" is the location cascade (a personal client
|
||||
// preference, prefs.autoBbox — not part of the server config, so it's only
|
||||
// offered in the personal scope). "__custom__" reveals the coordinate field.
|
||||
const osBboxPreset = computed({
|
||||
get() {
|
||||
if (!osEditingOrg.value && prefs.autoBbox) return '__auto__'
|
||||
if (osBboxCustom.value) return '__custom__'
|
||||
const norm = osNormBbox(osForm.bbox)
|
||||
const match = norm && OS_BBOX_FLAT.find((o) => osNormBbox(o.value) === norm)
|
||||
return match ? match.value : '__custom__'
|
||||
},
|
||||
set(v) {
|
||||
if (v === '__auto__') {
|
||||
if (!osEditingOrg.value) prefs.autoBbox = true
|
||||
osBboxCustom.value = false
|
||||
return
|
||||
}
|
||||
// Any explicit choice leaves auto mode (personal scope only).
|
||||
if (!osEditingOrg.value) prefs.autoBbox = false
|
||||
if (v === '__custom__') { osBboxCustom.value = true; return }
|
||||
osBboxCustom.value = false
|
||||
osForm.bbox = v
|
||||
},
|
||||
})
|
||||
const osBboxManual = computed(() => osBboxPreset.value === '__custom__')
|
||||
const osBboxIsAuto = computed(() => osBboxPreset.value === '__auto__')
|
||||
|
||||
// Superadmin edits the global layer in the API panel — read-only in the Web App.
|
||||
const osReadOnly = computed(() => os.isSuperadmin)
|
||||
@@ -1497,7 +1508,7 @@ onBeforeUnmount(() => {
|
||||
</Row>
|
||||
|
||||
<!-- bounding box -->
|
||||
<Row title="Default bounding box" desc="Pick a region, or choose Custom to enter lamin,lomin,lamax,lomax by hand — used for live queries and the health probe." keywords="bounding box bbox area region country continent world europe custom coordinates">
|
||||
<Row title="Default bounding box" desc="Automatic follows your location; or pick a region, or enter lamin,lomin,lamax,lomax by hand." keywords="bounding box bbox area region country continent world europe custom coordinates automatic location drone">
|
||||
<template v-if="osLocked('bbox')">
|
||||
<span class="inline-flex items-center gap-2 font-mono text-sm text-ink">
|
||||
{{ osBboxLabel(osField('bbox').effective) || osField('bbox').effective || '—' }}
|
||||
@@ -1506,11 +1517,15 @@ onBeforeUnmount(() => {
|
||||
</template>
|
||||
<div v-else class="flex flex-col items-end gap-2">
|
||||
<select v-model="osBboxPreset" class="field w-64">
|
||||
<option v-if="!osEditingOrg" value="__auto__">Automatic (by location)</option>
|
||||
<optgroup v-for="g in OS_BBOX_GROUPS" :key="g.label" :label="g.label">
|
||||
<option v-for="o in g.options" :key="o.value" :value="o.value">{{ o.label }}</option>
|
||||
</optgroup>
|
||||
<option value="__custom__">Custom…</option>
|
||||
</select>
|
||||
<p v-if="osBboxIsAuto" class="w-64 text-right text-[11px] leading-snug text-ink-muted">
|
||||
Live map follows drone location → your device location → your Region ({{ regionName }}).
|
||||
</p>
|
||||
<input v-if="osBboxManual" v-model="osForm.bbox" class="field w-64 font-mono" placeholder="50.5,3.2,53.7,7.3" />
|
||||
</div>
|
||||
</Row>
|
||||
|
||||
@@ -0,0 +1,257 @@
|
||||
// PilotVault country reference data.
|
||||
//
|
||||
// One record per country: ISO 3166-1 alpha-2 `code`, display `name`, `continent`
|
||||
// (EU | AS | AF | NA | SA | OC), and a `bbox` string "lamin,lomin,lamax,lomax"
|
||||
// (min lat, min lon, max lat, max lon). Bounding boxes are approximate — good
|
||||
// enough to pick a default map area and to resolve a point to a country offline,
|
||||
// without any external geocoding call.
|
||||
//
|
||||
// Consumed by:
|
||||
// - the OpenSky "Default bounding box" picker (European presets),
|
||||
// - the User Settings "Region" list (all countries),
|
||||
// - the live-map auto cascade (point -> country -> bbox).
|
||||
|
||||
export const COUNTRIES = [
|
||||
// ---- Europe ----
|
||||
{ code: 'AL', name: 'Albania', continent: 'EU', bbox: '39.6,19.3,42.7,21.1' },
|
||||
{ code: 'AD', name: 'Andorra', continent: 'EU', bbox: '42.4,1.4,42.7,1.8' },
|
||||
{ code: 'AT', name: 'Austria', continent: 'EU', bbox: '46.4,9.5,49.0,17.2' },
|
||||
{ code: 'BY', name: 'Belarus', continent: 'EU', bbox: '51.2,23.2,56.2,32.8' },
|
||||
{ code: 'BE', name: 'Belgium', continent: 'EU', bbox: '49.5,2.5,51.5,6.4' },
|
||||
{ code: 'BA', name: 'Bosnia and Herzegovina', continent: 'EU', bbox: '42.6,15.7,45.3,19.6' },
|
||||
{ code: 'BG', name: 'Bulgaria', continent: 'EU', bbox: '41.2,22.4,44.2,28.6' },
|
||||
{ code: 'HR', name: 'Croatia', continent: 'EU', bbox: '42.4,13.5,46.6,19.4' },
|
||||
{ code: 'CY', name: 'Cyprus', continent: 'EU', bbox: '34.6,32.3,35.7,34.6' },
|
||||
{ code: 'CZ', name: 'Czechia', continent: 'EU', bbox: '48.6,12.1,51.1,18.9' },
|
||||
{ code: 'DK', name: 'Denmark', continent: 'EU', bbox: '54.6,8.1,57.8,12.7' },
|
||||
{ code: 'EE', name: 'Estonia', continent: 'EU', bbox: '57.5,21.8,59.7,28.2' },
|
||||
{ code: 'FI', name: 'Finland', continent: 'EU', bbox: '59.8,20.6,70.1,31.6' },
|
||||
{ code: 'FR', name: 'France', continent: 'EU', bbox: '41.3,-5.2,51.1,9.6' },
|
||||
{ code: 'DE', name: 'Germany', continent: 'EU', bbox: '47.2,5.8,55.1,15.1' },
|
||||
{ code: 'GR', name: 'Greece', continent: 'EU', bbox: '34.8,19.4,41.8,28.3' },
|
||||
{ code: 'HU', name: 'Hungary', continent: 'EU', bbox: '45.7,16.1,48.6,22.9' },
|
||||
{ code: 'IS', name: 'Iceland', continent: 'EU', bbox: '63.3,-24.6,66.6,-13.5' },
|
||||
{ code: 'IE', name: 'Ireland', continent: 'EU', bbox: '51.4,-10.6,55.4,-6.0' },
|
||||
{ code: 'IT', name: 'Italy', continent: 'EU', bbox: '36.6,6.6,47.1,18.6' },
|
||||
{ code: 'XK', name: 'Kosovo', continent: 'EU', bbox: '41.8,20.0,43.3,21.8' },
|
||||
{ code: 'LV', name: 'Latvia', continent: 'EU', bbox: '55.7,20.9,58.1,28.2' },
|
||||
{ code: 'LI', name: 'Liechtenstein', continent: 'EU', bbox: '47.0,9.4,47.3,9.6' },
|
||||
{ code: 'LT', name: 'Lithuania', continent: 'EU', bbox: '53.9,20.9,56.5,26.9' },
|
||||
{ code: 'LU', name: 'Luxembourg', continent: 'EU', bbox: '49.4,5.7,50.2,6.5' },
|
||||
{ code: 'MT', name: 'Malta', continent: 'EU', bbox: '35.8,14.1,36.1,14.6' },
|
||||
{ code: 'MD', name: 'Moldova', continent: 'EU', bbox: '45.4,26.6,48.5,30.2' },
|
||||
{ code: 'MC', name: 'Monaco', continent: 'EU', bbox: '43.72,7.40,43.75,7.44' },
|
||||
{ code: 'ME', name: 'Montenegro', continent: 'EU', bbox: '41.8,18.4,43.6,20.4' },
|
||||
{ code: 'NL', name: 'Netherlands', continent: 'EU', bbox: '50.7,3.3,53.7,7.2' },
|
||||
{ code: 'MK', name: 'North Macedonia', continent: 'EU', bbox: '40.8,20.4,42.4,23.0' },
|
||||
{ code: 'NO', name: 'Norway', continent: 'EU', bbox: '57.9,4.6,71.2,31.1' },
|
||||
{ code: 'PL', name: 'Poland', continent: 'EU', bbox: '49.0,14.1,54.9,24.2' },
|
||||
{ code: 'PT', name: 'Portugal', continent: 'EU', bbox: '36.9,-9.5,42.2,-6.2' },
|
||||
{ code: 'RO', name: 'Romania', continent: 'EU', bbox: '43.6,20.2,48.3,29.7' },
|
||||
{ code: 'SM', name: 'San Marino', continent: 'EU', bbox: '43.89,12.40,43.99,12.52' },
|
||||
{ code: 'RS', name: 'Serbia', continent: 'EU', bbox: '42.2,18.8,46.2,23.0' },
|
||||
{ code: 'SK', name: 'Slovakia', continent: 'EU', bbox: '47.7,16.8,49.6,22.6' },
|
||||
{ code: 'SI', name: 'Slovenia', continent: 'EU', bbox: '45.4,13.4,46.9,16.6' },
|
||||
{ code: 'ES', name: 'Spain', continent: 'EU', bbox: '35.9,-9.4,43.8,3.4' },
|
||||
{ code: 'SE', name: 'Sweden', continent: 'EU', bbox: '55.3,11.1,69.1,24.2' },
|
||||
{ code: 'CH', name: 'Switzerland', continent: 'EU', bbox: '45.8,5.9,47.8,10.5' },
|
||||
{ code: 'UA', name: 'Ukraine', continent: 'EU', bbox: '44.4,22.1,52.4,40.2' },
|
||||
{ code: 'GB', name: 'United Kingdom', continent: 'EU', bbox: '49.9,-8.7,60.9,1.8' },
|
||||
{ code: 'VA', name: 'Vatican City', continent: 'EU', bbox: '41.900,12.445,41.908,12.458' },
|
||||
{ code: 'RU', name: 'Russia', continent: 'EU', bbox: '41.2,19.6,81.9,180' },
|
||||
{ code: 'TR', name: 'Turkey', continent: 'EU', bbox: '35.8,25.7,42.3,44.8' },
|
||||
|
||||
// ---- Asia ----
|
||||
{ code: 'AF', name: 'Afghanistan', continent: 'AS', bbox: '29.4,60.5,38.5,74.9' },
|
||||
{ code: 'AM', name: 'Armenia', continent: 'AS', bbox: '38.8,43.4,41.3,46.6' },
|
||||
{ code: 'AZ', name: 'Azerbaijan', continent: 'AS', bbox: '38.4,44.8,41.9,50.4' },
|
||||
{ code: 'BH', name: 'Bahrain', continent: 'AS', bbox: '25.8,50.4,26.3,50.7' },
|
||||
{ code: 'BD', name: 'Bangladesh', continent: 'AS', bbox: '20.7,88.0,26.6,92.7' },
|
||||
{ code: 'BT', name: 'Bhutan', continent: 'AS', bbox: '26.7,88.7,28.3,92.1' },
|
||||
{ code: 'BN', name: 'Brunei', continent: 'AS', bbox: '4.0,114.0,5.1,115.4' },
|
||||
{ code: 'KH', name: 'Cambodia', continent: 'AS', bbox: '10.4,102.3,14.7,107.6' },
|
||||
{ code: 'CN', name: 'China', continent: 'AS', bbox: '18.2,73.5,53.6,134.8' },
|
||||
{ code: 'GE', name: 'Georgia', continent: 'AS', bbox: '41.0,40.0,43.6,46.7' },
|
||||
{ code: 'IN', name: 'India', continent: 'AS', bbox: '6.7,68.1,35.5,97.4' },
|
||||
{ code: 'ID', name: 'Indonesia', continent: 'AS', bbox: '-11.0,95.0,6.1,141.0' },
|
||||
{ code: 'IR', name: 'Iran', continent: 'AS', bbox: '25.0,44.0,39.8,63.3' },
|
||||
{ code: 'IQ', name: 'Iraq', continent: 'AS', bbox: '29.1,38.8,37.4,48.6' },
|
||||
{ code: 'IL', name: 'Israel', continent: 'AS', bbox: '29.5,34.2,33.3,35.9' },
|
||||
{ code: 'JP', name: 'Japan', continent: 'AS', bbox: '24.0,122.9,45.5,145.8' },
|
||||
{ code: 'JO', name: 'Jordan', continent: 'AS', bbox: '29.2,34.9,33.4,39.3' },
|
||||
{ code: 'KZ', name: 'Kazakhstan', continent: 'AS', bbox: '40.6,46.5,55.4,87.3' },
|
||||
{ code: 'KW', name: 'Kuwait', continent: 'AS', bbox: '28.5,46.5,30.1,48.4' },
|
||||
{ code: 'KG', name: 'Kyrgyzstan', continent: 'AS', bbox: '39.2,69.3,43.3,80.3' },
|
||||
{ code: 'LA', name: 'Laos', continent: 'AS', bbox: '13.9,100.1,22.5,107.7' },
|
||||
{ code: 'LB', name: 'Lebanon', continent: 'AS', bbox: '33.0,35.1,34.7,36.6' },
|
||||
{ code: 'MY', name: 'Malaysia', continent: 'AS', bbox: '0.9,99.6,7.4,119.3' },
|
||||
{ code: 'MV', name: 'Maldives', continent: 'AS', bbox: '-0.7,72.7,7.1,73.7' },
|
||||
{ code: 'MN', name: 'Mongolia', continent: 'AS', bbox: '41.6,87.7,52.1,119.9' },
|
||||
{ code: 'MM', name: 'Myanmar', continent: 'AS', bbox: '9.8,92.2,28.5,101.2' },
|
||||
{ code: 'NP', name: 'Nepal', continent: 'AS', bbox: '26.3,80.1,30.4,88.2' },
|
||||
{ code: 'KP', name: 'North Korea', continent: 'AS', bbox: '37.7,124.2,43.0,130.7' },
|
||||
{ code: 'OM', name: 'Oman', continent: 'AS', bbox: '16.6,52.0,26.4,59.8' },
|
||||
{ code: 'PK', name: 'Pakistan', continent: 'AS', bbox: '23.7,60.9,37.1,77.8' },
|
||||
{ code: 'PH', name: 'Philippines', continent: 'AS', bbox: '4.6,116.9,21.1,126.6' },
|
||||
{ code: 'QA', name: 'Qatar', continent: 'AS', bbox: '24.5,50.7,26.2,51.6' },
|
||||
{ code: 'SA', name: 'Saudi Arabia', continent: 'AS', bbox: '16.4,34.6,32.2,55.7' },
|
||||
{ code: 'SG', name: 'Singapore', continent: 'AS', bbox: '1.2,103.6,1.5,104.1' },
|
||||
{ code: 'KR', name: 'South Korea', continent: 'AS', bbox: '33.1,125.9,38.6,129.6' },
|
||||
{ code: 'LK', name: 'Sri Lanka', continent: 'AS', bbox: '5.9,79.7,9.8,81.9' },
|
||||
{ code: 'SY', name: 'Syria', continent: 'AS', bbox: '32.3,35.7,37.3,42.4' },
|
||||
{ code: 'TW', name: 'Taiwan', continent: 'AS', bbox: '21.9,120.0,25.3,122.0' },
|
||||
{ code: 'TJ', name: 'Tajikistan', continent: 'AS', bbox: '36.7,67.4,41.0,75.2' },
|
||||
{ code: 'TH', name: 'Thailand', continent: 'AS', bbox: '5.6,97.3,20.5,105.6' },
|
||||
{ code: 'TL', name: 'Timor-Leste', continent: 'AS', bbox: '-9.5,124.0,-8.1,127.3' },
|
||||
{ code: 'TM', name: 'Turkmenistan', continent: 'AS', bbox: '35.1,52.4,42.8,66.7' },
|
||||
{ code: 'AE', name: 'United Arab Emirates', continent: 'AS', bbox: '22.6,51.5,26.1,56.4' },
|
||||
{ code: 'UZ', name: 'Uzbekistan', continent: 'AS', bbox: '37.2,55.9,45.6,73.1' },
|
||||
{ code: 'VN', name: 'Vietnam', continent: 'AS', bbox: '8.2,102.1,23.4,109.5' },
|
||||
{ code: 'YE', name: 'Yemen', continent: 'AS', bbox: '12.1,42.5,19.0,54.5' },
|
||||
|
||||
// ---- Africa ----
|
||||
{ code: 'DZ', name: 'Algeria', continent: 'AF', bbox: '18.9,-8.7,37.1,12.0' },
|
||||
{ code: 'AO', name: 'Angola', continent: 'AF', bbox: '-18.0,11.6,-4.4,24.1' },
|
||||
{ code: 'BJ', name: 'Benin', continent: 'AF', bbox: '6.2,0.8,12.4,3.9' },
|
||||
{ code: 'BW', name: 'Botswana', continent: 'AF', bbox: '-26.9,20.0,-17.8,29.4' },
|
||||
{ code: 'BF', name: 'Burkina Faso', continent: 'AF', bbox: '9.4,-5.5,15.1,2.4' },
|
||||
{ code: 'BI', name: 'Burundi', continent: 'AF', bbox: '-4.5,29.0,-2.3,30.8' },
|
||||
{ code: 'CV', name: 'Cabo Verde', continent: 'AF', bbox: '14.8,-25.4,17.2,-22.7' },
|
||||
{ code: 'CM', name: 'Cameroon', continent: 'AF', bbox: '1.7,8.5,13.1,16.2' },
|
||||
{ code: 'CF', name: 'Central African Republic', continent: 'AF', bbox: '2.2,14.4,11.0,27.5' },
|
||||
{ code: 'TD', name: 'Chad', continent: 'AF', bbox: '7.4,13.5,23.4,24.0' },
|
||||
{ code: 'KM', name: 'Comoros', continent: 'AF', bbox: '-12.4,43.2,-11.4,44.5' },
|
||||
{ code: 'CG', name: 'Congo', continent: 'AF', bbox: '-5.0,11.1,3.7,18.6' },
|
||||
{ code: 'CD', name: 'DR Congo', continent: 'AF', bbox: '-13.5,12.2,5.4,31.3' },
|
||||
{ code: 'DJ', name: 'Djibouti', continent: 'AF', bbox: '10.9,41.7,12.7,43.4' },
|
||||
{ code: 'EG', name: 'Egypt', continent: 'AF', bbox: '22.0,25.0,31.7,36.9' },
|
||||
{ code: 'GQ', name: 'Equatorial Guinea', continent: 'AF', bbox: '0.9,9.3,3.8,11.4' },
|
||||
{ code: 'ER', name: 'Eritrea', continent: 'AF', bbox: '12.4,36.4,18.0,43.1' },
|
||||
{ code: 'SZ', name: 'Eswatini', continent: 'AF', bbox: '-27.3,30.8,-25.7,32.1' },
|
||||
{ code: 'ET', name: 'Ethiopia', continent: 'AF', bbox: '3.4,33.0,14.9,48.0' },
|
||||
{ code: 'GA', name: 'Gabon', continent: 'AF', bbox: '-4.0,8.7,2.3,14.5' },
|
||||
{ code: 'GM', name: 'Gambia', continent: 'AF', bbox: '13.1,-16.8,13.8,-13.8' },
|
||||
{ code: 'GH', name: 'Ghana', continent: 'AF', bbox: '4.7,-3.3,11.2,1.2' },
|
||||
{ code: 'GN', name: 'Guinea', continent: 'AF', bbox: '7.2,-15.1,12.7,-7.6' },
|
||||
{ code: 'GW', name: 'Guinea-Bissau', continent: 'AF', bbox: '10.9,-16.7,12.7,-13.6' },
|
||||
{ code: 'CI', name: 'Ivory Coast', continent: 'AF', bbox: '4.4,-8.6,10.7,-2.5' },
|
||||
{ code: 'KE', name: 'Kenya', continent: 'AF', bbox: '-4.7,33.9,5.5,41.9' },
|
||||
{ code: 'LS', name: 'Lesotho', continent: 'AF', bbox: '-30.7,27.0,-28.6,29.5' },
|
||||
{ code: 'LR', name: 'Liberia', continent: 'AF', bbox: '4.3,-11.5,8.6,-7.4' },
|
||||
{ code: 'LY', name: 'Libya', continent: 'AF', bbox: '19.5,9.3,33.2,25.2' },
|
||||
{ code: 'MG', name: 'Madagascar', continent: 'AF', bbox: '-25.6,43.2,-11.9,50.5' },
|
||||
{ code: 'MW', name: 'Malawi', continent: 'AF', bbox: '-17.1,32.7,-9.4,35.9' },
|
||||
{ code: 'ML', name: 'Mali', continent: 'AF', bbox: '10.1,-12.3,25.0,4.3' },
|
||||
{ code: 'MR', name: 'Mauritania', continent: 'AF', bbox: '14.7,-17.1,27.3,-4.8' },
|
||||
{ code: 'MU', name: 'Mauritius', continent: 'AF', bbox: '-20.5,57.3,-19.9,57.8' },
|
||||
{ code: 'MA', name: 'Morocco', continent: 'AF', bbox: '27.7,-13.2,35.9,-1.0' },
|
||||
{ code: 'MZ', name: 'Mozambique', continent: 'AF', bbox: '-26.9,30.2,-10.5,40.8' },
|
||||
{ code: 'NA', name: 'Namibia', continent: 'AF', bbox: '-28.9,11.7,-16.9,25.3' },
|
||||
{ code: 'NE', name: 'Niger', continent: 'AF', bbox: '11.7,0.2,23.5,16.0' },
|
||||
{ code: 'NG', name: 'Nigeria', continent: 'AF', bbox: '4.3,2.7,13.9,14.7' },
|
||||
{ code: 'RW', name: 'Rwanda', continent: 'AF', bbox: '-2.8,28.9,-1.1,30.9' },
|
||||
{ code: 'SN', name: 'Senegal', continent: 'AF', bbox: '12.3,-17.5,16.7,-11.4' },
|
||||
{ code: 'SL', name: 'Sierra Leone', continent: 'AF', bbox: '6.9,-13.3,10.0,-10.3' },
|
||||
{ code: 'SO', name: 'Somalia', continent: 'AF', bbox: '-1.7,40.9,12.0,51.4' },
|
||||
{ code: 'ZA', name: 'South Africa', continent: 'AF', bbox: '-34.8,16.5,-22.1,32.9' },
|
||||
{ code: 'SS', name: 'South Sudan', continent: 'AF', bbox: '3.5,24.1,12.2,35.9' },
|
||||
{ code: 'SD', name: 'Sudan', continent: 'AF', bbox: '8.7,21.8,22.2,38.6' },
|
||||
{ code: 'TZ', name: 'Tanzania', continent: 'AF', bbox: '-11.7,29.3,-1.0,40.4' },
|
||||
{ code: 'TG', name: 'Togo', continent: 'AF', bbox: '6.1,-0.1,11.1,1.8' },
|
||||
{ code: 'TN', name: 'Tunisia', continent: 'AF', bbox: '30.2,7.5,37.5,11.6' },
|
||||
{ code: 'UG', name: 'Uganda', continent: 'AF', bbox: '-1.5,29.6,4.2,35.0' },
|
||||
{ code: 'ZM', name: 'Zambia', continent: 'AF', bbox: '-18.1,21.9,-8.2,33.7' },
|
||||
{ code: 'ZW', name: 'Zimbabwe', continent: 'AF', bbox: '-22.4,25.2,-15.6,33.1' },
|
||||
|
||||
// ---- North America ----
|
||||
{ code: 'CA', name: 'Canada', continent: 'NA', bbox: '41.7,-141.0,83.1,-52.6' },
|
||||
{ code: 'US', name: 'United States', continent: 'NA', bbox: '24.4,-125.0,49.4,-66.9' },
|
||||
{ code: 'MX', name: 'Mexico', continent: 'NA', bbox: '14.5,-118.4,32.7,-86.7' },
|
||||
{ code: 'GT', name: 'Guatemala', continent: 'NA', bbox: '13.7,-92.2,17.8,-88.2' },
|
||||
{ code: 'BZ', name: 'Belize', continent: 'NA', bbox: '15.9,-89.2,18.5,-87.8' },
|
||||
{ code: 'SV', name: 'El Salvador', continent: 'NA', bbox: '13.1,-90.1,14.4,-87.7' },
|
||||
{ code: 'HN', name: 'Honduras', continent: 'NA', bbox: '12.9,-89.4,16.5,-83.1' },
|
||||
{ code: 'NI', name: 'Nicaragua', continent: 'NA', bbox: '10.7,-87.7,15.0,-83.1' },
|
||||
{ code: 'CR', name: 'Costa Rica', continent: 'NA', bbox: '8.0,-85.9,11.2,-82.5' },
|
||||
{ code: 'PA', name: 'Panama', continent: 'NA', bbox: '7.2,-83.1,9.6,-77.2' },
|
||||
{ code: 'CU', name: 'Cuba', continent: 'NA', bbox: '19.8,-85.0,23.3,-74.1' },
|
||||
{ code: 'DO', name: 'Dominican Republic', continent: 'NA', bbox: '17.5,-72.0,19.9,-68.3' },
|
||||
{ code: 'HT', name: 'Haiti', continent: 'NA', bbox: '18.0,-74.5,20.1,-71.6' },
|
||||
{ code: 'JM', name: 'Jamaica', continent: 'NA', bbox: '17.7,-78.4,18.5,-76.2' },
|
||||
{ code: 'BS', name: 'Bahamas', continent: 'NA', bbox: '20.9,-79.0,27.3,-72.7' },
|
||||
{ code: 'TT', name: 'Trinidad and Tobago', continent: 'NA', bbox: '10.0,-61.9,11.4,-60.5' },
|
||||
|
||||
// ---- South America ----
|
||||
{ code: 'AR', name: 'Argentina', continent: 'SA', bbox: '-55.1,-73.6,-21.8,-53.6' },
|
||||
{ code: 'BO', name: 'Bolivia', continent: 'SA', bbox: '-22.9,-69.6,-9.7,-57.5' },
|
||||
{ code: 'BR', name: 'Brazil', continent: 'SA', bbox: '-33.8,-74.0,5.3,-34.8' },
|
||||
{ code: 'CL', name: 'Chile', continent: 'SA', bbox: '-55.9,-75.6,-17.5,-66.4' },
|
||||
{ code: 'CO', name: 'Colombia', continent: 'SA', bbox: '-4.2,-79.0,12.5,-66.9' },
|
||||
{ code: 'EC', name: 'Ecuador', continent: 'SA', bbox: '-5.0,-81.1,1.4,-75.2' },
|
||||
{ code: 'GY', name: 'Guyana', continent: 'SA', bbox: '1.2,-61.4,8.6,-56.5' },
|
||||
{ code: 'PY', name: 'Paraguay', continent: 'SA', bbox: '-27.6,-62.6,-19.3,-54.3' },
|
||||
{ code: 'PE', name: 'Peru', continent: 'SA', bbox: '-18.4,-81.3,0.0,-68.7' },
|
||||
{ code: 'SR', name: 'Suriname', continent: 'SA', bbox: '1.8,-58.1,6.0,-54.0' },
|
||||
{ code: 'UY', name: 'Uruguay', continent: 'SA', bbox: '-35.0,-58.4,-30.1,-53.1' },
|
||||
{ code: 'VE', name: 'Venezuela', continent: 'SA', bbox: '0.6,-73.4,12.2,-59.8' },
|
||||
|
||||
// ---- Oceania ----
|
||||
{ code: 'AU', name: 'Australia', continent: 'OC', bbox: '-43.6,113.3,-10.7,153.6' },
|
||||
{ code: 'NZ', name: 'New Zealand', continent: 'OC', bbox: '-47.3,166.4,-34.4,178.6' },
|
||||
{ code: 'PG', name: 'Papua New Guinea', continent: 'OC', bbox: '-11.7,140.8,-1.3,155.9' },
|
||||
{ code: 'FJ', name: 'Fiji', continent: 'OC', bbox: '-19.2,177.0,-16.0,180.0' },
|
||||
]
|
||||
|
||||
// Quick lookups.
|
||||
const BY_CODE = new Map(COUNTRIES.map((c) => [c.code, c]))
|
||||
|
||||
// Parse a "lamin,lomin,lamax,lomax" bbox into numbers, or null if malformed.
|
||||
function parseBbox(s) {
|
||||
const p = String(s || '').split(',').map((x) => Number(x.trim()))
|
||||
if (p.length !== 4 || p.some((n) => Number.isNaN(n))) return null
|
||||
return p // [lamin, lomin, lamax, lomax]
|
||||
}
|
||||
|
||||
// bbox string for an ISO country code, or '' when unknown.
|
||||
export function bboxForCountry(code) {
|
||||
const c = BY_CODE.get(code)
|
||||
return c ? c.bbox : ''
|
||||
}
|
||||
|
||||
// Resolve a lat/lon point to the country whose bbox contains it with the
|
||||
// smallest area — this disambiguates overlapping boxes (e.g. Vatican inside
|
||||
// Italy) by preferring the tighter, more specific one. Returns the record or null.
|
||||
export function countryForPoint(lat, lon) {
|
||||
if (typeof lat !== 'number' || typeof lon !== 'number' || Number.isNaN(lat) || Number.isNaN(lon)) {
|
||||
return null
|
||||
}
|
||||
let best = null
|
||||
let bestArea = Infinity
|
||||
for (const c of COUNTRIES) {
|
||||
const b = parseBbox(c.bbox)
|
||||
if (!b) continue
|
||||
const [laMin, loMin, laMax, loMax] = b
|
||||
if (lat < laMin || lat > laMax || lon < loMin || lon > loMax) continue
|
||||
const area = Math.abs(laMax - laMin) * Math.abs(loMax - loMin)
|
||||
if (area < bestArea) {
|
||||
bestArea = area
|
||||
best = c
|
||||
}
|
||||
}
|
||||
return best
|
||||
}
|
||||
|
||||
// European countries as picker options ({ value: bbox, label: name }), A→Z.
|
||||
export function europeanCountries() {
|
||||
return COUNTRIES.filter((c) => c.continent === 'EU')
|
||||
.slice()
|
||||
.sort((a, b) => a.name.localeCompare(b.name))
|
||||
.map((c) => ({ value: c.bbox, label: c.name }))
|
||||
}
|
||||
|
||||
// All countries as [code, name] pairs for the Region <select>, A→Z.
|
||||
export function regionOptions() {
|
||||
return COUNTRIES.slice()
|
||||
.sort((a, b) => a.name.localeCompare(b.name))
|
||||
.map((c) => [c.code, c.name])
|
||||
}
|
||||
@@ -29,6 +29,10 @@ const defaults = {
|
||||
// Live map: overlay live OpenSky air traffic (client-side toggle; the OpenSky
|
||||
// integration itself is still gated in Settings → Integrations).
|
||||
showAirTraffic: true,
|
||||
// Auto bounding box: when true, the live map resolves its area from the
|
||||
// location cascade (drone telemetry → phone/browser location → Region country
|
||||
// → Europe) instead of the fixed OpenSky config bbox. See countries.js.
|
||||
autoBbox: 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',
|
||||
|
||||
Reference in new issue
Block a user