PageSourceSearch

https://www.orchaerospace.com/_next/static/chunks/350.eef4607b90c4b2e2.js

js orchaerospace.com collected 2026-10-01 14:23:21 UTC 46,301 bytes, 1 lines download raw bytes

1(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[350],{7350:function(e,t,r){"use strict";r.r(t),r.d(t,{default:function(){return x}});var a=r(3323),l=r(7979),i=r(4299),o=r.n(i);r(2524);var n=r(3617),s=r(4267);let c="https://elevation-tiles-prod.s3.amazonaws.com/terrarium/{z}/{x}/{y}.png",u={vfr:{label:"VFR",url:"https://tiles.arcgis.com/tiles/ssFJjBXIUyZDrSYZ/arcgis/rest/services/VFR_Sectional/MapServer/tile/{z}/{y}/{x}"},ifrLow:{label:"IFR-L",url:"https://tiles.arcgis.com/tiles/ssFJjBXIUyZDrSYZ/arcgis/rest/services/IFR_AreaLow/MapServer/tile/{z}/{y}/{x}"},ifrHigh:{label:"IFR-H",url:"https://tiles.arcgis.com/tiles/ssFJjBXIUyZDrSYZ/arcgis/rest/services/IFR_High/MapServer/tile/{z}/{y}/{x}"},sat:{label:"Sat",url:"https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}"},topo:{label:"Topo",url:"https://tile.opentopomap.org/{z}/{x}/{y}.png"}};function d(e){if("7500"===e.squawk||"7600"===e.squawk||"7700"===e.squawk)return 15680580;let t=e.altFt;return t<3e3?3462041:t<1e4?16436245:t<24e3?3718648:12616956}function p(e,t){let r=e[0]*Math.PI/180,a=t[0]*Math.PI/180,l=(t[0]-e[0])*Math.PI/180,i=(t[1]-e[1])*Math.PI/180;return 6880.13*Math.asin(Math.min(1,Math.sqrt(Math.sin(l/2)**2+Math.cos(r)*Math.cos(a)*Math.sin(i/2)**2)))}function f(e,t){let r=e[0]*Math.PI/180,a=t[0]*Math.PI/180,l=(t[1]-e[1])*Math.PI/180;return(180*Math.atan2(Math.sin(l)*Math.cos(a),Math.cos(r)*Math.sin(a)-Math.sin(r)*Math.cos(a)*Math.cos(l))/Math.PI+360)%360}function h(e,t,r,a){let l=a*Math.PI/180;return[t+r/60*Math.sin(l)/Math.cos(e*Math.PI/180),e+r/60*Math.cos(l)]}function g(e,t,r){let a=o().MercatorCoordinate.fromLngLat([e,t],.3048*r);return{x:a.x,y:a.y,z:a.z,s:a.meterInMercatorCoordinateUnits()}}function x(e){let{variant:t="efb"}=e,i=(0,l.useRef)(null),x=(0,l.useRef)(null),m=(0,l.useRef)(!1),y=(0,l.useRef)(null),[b,w]=(0,l.useState)([]),[v,M]=(0,l.useState)([]),[F,S]=(0,l.useState)([]),[k,j]=(0,l.useState)([]),[N,L]=(0,l.useState)([]),[z,C]=(0,l.useState)([]),[R,A]=(0,l.useState)(null),[T,P]=(0,l.useState)(null),[I,E]=(0,l.useState)(null),[D,B]=(0,l.useState)(!1),[V,W]=(0,l.useState)(null),[G,O]=(0,l.useState)(null),[_,K]=(0,l.useState)(!1),[q,U]=(0,l.useState)(null),Z=(0,l.useRef)(null),H=(0,l.useRef)(null),[X,J]=(0,l.useState)(0),Y=(0,l.useRef)(new Map),Q=(0,l.useRef)(!1);(0,l.useEffect)(()=>{Q.current=_;let e=x.current;if(e&&(e.getCanvas().style.cursor=_?"crosshair":""),!_){Z.current=null,H.current=null,U(null);let t=null==e?void 0:e.getSource("ruler");null==t||t.setData({type:"FeatureCollection",features:[]})}},[_]);let[$,ee]=(0,l.useState)(null),[et]=(0,l.useState)(!0),[er,ea]=(0,l.useState)(!1),[el,ei]=(0,l.useState)("sat"),[eo,en]=(0,l.useState)({airspaces:!0,airways:!0,navaids:!0,fixes:!0,airports:!0,procedures:!1,traffic:!0,wx:!0,rings:!1,metar:!1,wind:!0,circuit:!1,peaks:!0,ceilings:!1,flow:!1}),es=(0,l.useRef)(null),ec=(0,l.useRef)(null),[eu,ed]=(0,l.useState)([]),[ep,ef]=(0,l.useState)(!1),[eh,eg]=(0,l.useState)(1.35),[ex,em]=(0,l.useState)(1),[ey,eb]=(0,l.useState)(9e3),ew=function(){let[e,t]=(0,l.useState)({lat:45.4706,lon:-73.7408,source:"default",track:0,altFt:null,gsKt:null});return(0,l.useEffect)(()=>{let e=!1,a=null;if(r.e(640).then(r.bind(r,1640)).then(r=>{let{subscribeQtPosition:l}=r;return l(r=>{e||t({lat:r.lat,lon:r.lon,source:"qt",track:r.trackDegrees,altFt:null,gsKt:null})}).then(t=>{e?t():a=t})}).catch(()=>{}),!navigator.geolocation)return fetch("/api/ip-location").then(e=>e.json()).then(r=>{!e&&r.lat&&r.lon&&t({lat:r.lat,lon:r.lon,source:"ip",track:0,altFt:null,gsKt:null})}).catch(()=>{}),()=>{e=!0,null==a||a()};let l=r=>{var a;e||t({lat:r.coords.latitude,lon:r.coords.longitude,source:"gps",track:null!==(a=r.coords.heading)&&void 0!==a?a:0,altFt:Number.isFinite(r.coords.altitude)?r.coords.altitude/.3048:null,gsKt:Number.isFinite(r.coords.speed)?1.94384*r.coords.speed:null})};navigator.geolocation.getCurrentPosition(l,()=>{fetch("/api/ip-location").then(e=>e.json()).then(r=>{!e&&r.lat&&r.lon&&t({lat:r.lat,lon:r.lon,source:"ip",track:0,altFt:null,gsKt:null})}).catch(()=>{})},{enableHighAccuracy:!0,maximumAge:3e4,timeout:8e3});let i=navigator.geolocation.watchPosition(l,()=>{},{enableHighAccuracy:!0,maximumAge:5e3});return()=>{e=!0,navigator.geolocation.clearWatch(i),null==a||a()}},[]),e}(),ev=(0,s.kf)(),eM=(0,l.useRef)(new Map),eF=(0,l.useRef)({traffic:[],trails:eM.current,selected:null,showTraffic:!0,sizeScale:1,version:0,lastMatrix:null,wxOn:!1,wxTexUrl:null,wxBounds:null,wxAltFt:9e3,wxVersion:0,ceilings:[],ceilVersion:0});(0,l.useEffect)(()=>{let e=[fetch("/navdata/airports.json").then(e=>e.json()).catch(()=>[]),fetch("/navdata/navaids.json").then(e=>e.json()).catch(()=>[]),fetch("/navdata/cifp/fixes.json").then(e=>e.json()).catch(()=>[]),fetch("/navdata/peaks.json").then(e=>e.json()).catch(()=>({}))],r="efb"===t?[fetch("/navdata/airspace.json").then(e=>e.json()).catch(()=>[]),fetch("/navdata/cifp/airways.json").then(e=>e.json()).catch(()=>[]),fetch("/navdata/cifp/procedures.json").then(e=>e.json()).catch(()=>null)]:[Promise.resolve([]),Promise.resolve([]),Promise.resolve(null)];Promise.all([...e,...r]).then(e=>{var t;let[r,a,l,i,o,n,s]=e;w(r),M(a),j(l),ed((null!==(t=null==i?void 0:i.peaks)&&void 0!==t?t:[]).filter(e=>Number.isFinite(e.lat)&&Number.isFinite(e.lon)&&Number.isFinite(e.elev_ft)).map(e=>({lat:e.lat,lon:e.lon,elevFt:e.elev_ft,type:e.type}))),S(o),L(n),ee(s)})},[t]),(0,l.useEffect)(()=>{let e=!1,r=async()=>{try{var r,a,l,i,o;let n=[];if("sim"===t){let e=await fetch("/api/vatsim").then(e=>e.json());n=(null!==(r=null==e?void 0:e.pilots)&&void 0!==r?r:[]).map(e=>({icao:e.callsign,flight:e.callsign,lat:e.lat,lon:e.lon,altFt:null!==(a=e.altitude)&&void 0!==a?a:0,gsKt:null!==(l=e.groundspeed)&&void 0!==l?l:0,trackDeg:null!==(i=e.heading)&&void 0!==i?i:0})).filter(e=>Number.isFinite(e.lat)&&Number.isFinite(e.lon))}else{let e="lat=".concat(ew.lat.toFixed(3),"&lon=").concat(ew.lon.toFixed(3),"&dist=250"),t=await fetch("/api/traffic?".concat(e)).then(e=>e.json());Array.isArray(null==t?void 0:t.aircraft)&&(n=t.aircraft)}if(e)return;n.length>1e3&&(n=n.slice(0,1e3)),C(n);let s=Date.now(),c=eM.current;for(let e of n){let t=null!==(o=c.get(e.icao))&&void 0!==o?o:[],r=t[t.length-1];(!r||Math.abs(r.lat-e.lat)>8e-4||Math.abs(r.lon-e.lon)>8e-4)&&t.push({lat:e.lat,lon:e.lon,altFt:e.altFt,ts:s}),t.length>80&&t.splice(0,t.length-80),c.set(e.icao,t)}c.forEach((e,t)=>{e.length&&s-e[e.length-1].ts>3e5&&c.delete(t)})}catch(e){}};r();let a=setInterval(r,"sim"===t?2e4:15e3);return()=>{e=!0,clearInterval(a)}},[t,ew.lat,ew.lon]),(0,l.useEffect)(()=>{var e,t;let r=eF.current;r.traffic=z,r.selected=null!==(t=null==R?void 0:R.icao)&&void 0!==t?t:null,r.showTraffic=eo.traffic&&et,r.version+=1,null===(e=x.current)||void 0===e||e.triggerRepaint()},[z,R,eo.traffic,et]),(0,l.useEffect)(()=>{let e=x.current;if(!e||!m.current)return;let t=e.getSource("traffic");if(!t)return;let r=e=>"#"+d(e).toString(16).padStart(6,"0");t.setData({type:"FeatureCollection",features:z.filter(e=>Number.isFinite(e.lat)&&Number.isFinite(e.lon)).map(e=>
1({type:"Feature",properties:{icao:e.icao,color:r(e)},geometry:{type:"Point",coordinates:[e.lon,e.lat]}}))})},[z]),(0,l.useEffect)(()=>{let e=x.current;if(!e||!m.current)return;let t=e.getSource("trail");if(!t)return;let r=R?eM.current.get(R.icao):null;t.setData(r&&r.length>=2?{type:"FeatureCollection",features:[{type:"Feature",properties:{},geometry:{type:"LineString",coordinates:r.map(e=>[e.lon,e.lat])}}]}:{type:"FeatureCollection",features:[]})},[R,z]),(0,l.useEffect)(()=>{let e=x.current;if(!e||!m.current)return;let t=eo.traffic&&!et;e.getLayer("traffic-dot")&&e.setLayoutProperty("traffic-dot","visibility",t?"visible":"none"),e.getLayer("trail-line")&&e.setLayoutProperty("trail-line","visibility",t?"visible":"none");let r=!!e.getLayer("traffic-3d");if(et&&eo.traffic&&!r)try{e.addLayer(function(e){let t;let r=new n.Scene,a=new n.Camera,l=new n.Group,i=new n.Group,o=new n.Group,s=new n.Group;r.add(l),r.add(i),r.add(o),r.add(s),r.add(new n.AmbientLight(16777215,1));let c=-1,u=null,p=-1,f=-1;function h(e){e.traverse(e=>{var t,r,a;!e.geometry||(null===(t=e.geometry.userData)||void 0===t?void 0:t.shared)||e.isSprite||e.geometry.dispose();let l=e.material;l&&(null===(r=l.map)||void 0===r||null===(a=r.dispose)||void 0===a||a.call(r),l.dispose())}),e.clear()}let x=new n.Shape;x.moveTo(0,-2),x.lineTo(1.25,1.4),x.lineTo(0,.6),x.lineTo(-1.25,1.4),x.closePath();let m=new n.ShapeGeometry(x);function y(e){let t=document.createElement("canvas");t.width=360,t.height=24+46*e.length;let r=t.getContext("2d");r.textAlign="center",r.textBaseline="middle",r.lineWidth=7,r.strokeStyle="rgba(0,0,0,0.9)",e.forEach((e,t)=>{r.font=0===t?"bold 40px monospace":"bold 33px monospace",r.fillStyle=0===t?"#ffffff":"#cbd5e1";let a=12+46*t+23;r.strokeText(e,180,a),r.fillText(e,180,a)});let a=new n.CanvasTexture(t),l=new n.Sprite(new n.SpriteMaterial({map:a,depthTest:!1,transparent:!0}));return l.userData.aspect=t.width/t.height,l}function b(){h(l);let{traffic:t,selected:r,showTraffic:a}=e.current;if(!a)return;let i=0;for(let a of t){if(!Number.isFinite(a.lat)||!Number.isFinite(a.lon))continue;let t=g(a.lon,a.lat,a.altFt),s=g(a.lon,a.lat,0),c=d(a),u=r===a.icao,p=(u?900:650)*t.s*e.current.sizeScale,f=new n.Mesh(m,new n.MeshBasicMaterial({color:c,side:n.DoubleSide,depthTest:!1,depthWrite:!1}));f.position.set(t.x,t.y,t.z),f.scale.set(p,p,p),f.renderOrder=2,f.rotation.z=-(a.trackDeg*Math.PI)/180,l.add(f);let h=new n.BufferGeometry().setFromPoints([new n.Vector3(s.x,s.y,0),new n.Vector3(t.x,t.y,t.z)]),x=new n.Line(h,new n.LineBasicMaterial({color:c,transparent:!0,opacity:u?.8:.35,depthTest:!1,depthWrite:!1}));if(x.renderOrder=1,l.add(x),i++<400){var o;let r=((null===(o=a.flight)||void 0===o?void 0:o.trim())||a.icao||"").toUpperCase(),i=[r];a.aircraftType&&i.push(a.aircraftType.toUpperCase()),i.push("HDG "+Math.round(a.trackDeg).toString().padStart(3,"0")+"\xb0"),i.push(Math.round(a.altFt).toLocaleString()+" ft");let n=y(i),s=g(a.lon,a.lat,a.altFt+1500);n.position.set(s.x,s.y,s.z);let c=(u?1500:1150)*t.s*e.current.sizeScale,d=c*i.length;n.scale.set(d*n.userData.aspect,d,1),l.add(n)}}}m.userData.shared=!0;let w=new n.CircleGeometry(1,24);return w.userData.shared=!0,{id:"traffic-3d",type:"custom",renderingMode:"3d",onAdd(e,r){(t=new n.WebGLRenderer({canvas:e.getCanvas(),context:r,antialias:!0})).autoClear=!1},render(l,d){var x;let m=Array.isArray(d)?d:null==d?void 0:null===(x=d.defaultProjectionData)||void 0===x?void 0:x.mainMatrix;if(!m)return;e.current.lastMatrix=m;let v=e.current;try{v.version!==c&&(b(),c=v.version,u=v.selected),v.selected!==u&&(b(),function(){i.clear();let{selected:t,trails:r}=e.current;if(!t)return;let a=r.get(t);if(!a||a.length<2)return;let l=a.map(e=>{let t=g(e.lon,e.lat,e.altFt);return new n.Vector3(t.x,t.y,t.z)}),o=new n.BufferGeometry().setFromPoints(l),s=new n.Line(o,new n.LineBasicMaterial({color:3718648,linewidth:2,depthTest:!1,depthWrite:!1}));s.renderOrder=1,i.add(s)}(),u=v.selected),v.wxVersion!==p&&(function(){h(o);let{wxOn:t,wxBounds:r,wxTexUrl:a,wxAltFt:l}=e.current;if(!t||!r||!a)return;let{minLon:i,minLat:s,maxLon:c,maxLat:u}=r,d=g(i,s,l),p=g(c,s,l),f=g(c,u,l),x=g(i,u,l),m=new n.BufferGeometry;m.setAttribute("position",new n.BufferAttribute(new Float32Array([d.x,d.y,d.z,p.x,p.y,p.z,f.x,f.y,f.z,d.x,d.y,d.z,f.x,f.y,f.z,x.x,x.y,x.z]),3)),m.setAttribute("uv",new n.BufferAttribute(new Float32Array([0,1,1,1,1,0,0,1,1,0,0,0]),2));let y=new n.TextureLoader().load(a);
1y.colorSpace=n.SRGBColorSpace;let b=new n.MeshBasicMaterial({map:y,transparent:!0,opacity:.6,depthWrite:!1,side:n.DoubleSide});o.add(new n.Mesh(m,b))}(),p=v.wxVersion),v.ceilVersion!==f&&(function(){for(let t of(h(s),e.current.ceilings)){let e=g(t.lon,t.lat,t.mslFt),r=g(t.lon,t.lat,0),a=new n.Mesh(w,new n.MeshBasicMaterial({color:9741240,transparent:!0,opacity:.22,side:n.DoubleSide,depthWrite:!1}));a.position.set(e.x,e.y,e.z);let l=2600*e.s;a.scale.set(l,l,l),s.add(a);let i=new n.BufferGeometry().setFromPoints([new n.Vector3(r.x,r.y,0),new n.Vector3(e.x,e.y,e.z)]);s.add(new n.Line(i,new n.LineBasicMaterial({color:9741240,transparent:!0,opacity:.4})));let o=y(["CIG",t.label]),c=g(t.lon,t.lat,t.mslFt+900);o.position.set(c.x,c.y,c.z);let u=2e3*e.s;o.scale.set(u*o.userData.aspect,u,1),s.add(o)}}(),f=v.ceilVersion),a.projectionMatrix=new n.Matrix4().fromArray(m),r.traverse(e=>{e.frustumCulled=!1}),t.resetState(),t.clearDepth(),t.render(r,a)}catch(e){}}}}(eF))}catch(e){}else if((!et||!eo.traffic)&&r)try{e.removeLayer("traffic-3d")}catch(e){}eF.current.showTraffic=eo.traffic&&et,eF.current.version+=1,e.triggerRepaint()},[eo.traffic,et,D]),(0,l.useEffect)(()=>{let e=x.current;if(e&&m.current)for(let[t,r]of Object.entries({airspaces:["airspaces-3d","airspaces-fill","airspaces-line","airspaces-label"],airways:["airways-line"],navaids:["navaids-dot","navaids-label"],fixes:["fixes-dot","fixes-label"],airports:["airports-dot","airports-label"],procedures:["proc-line"],wind:["wind-arrow","wind-label"],circuit:["circuit-line"],peaks:["peaks-sym","peaks-label","spotelev-label"],rings:["rings-line"]})){let a=eo[t]?"visible":"none";for(let t of r)e.getLayer(t)&&e.setLayoutProperty(t,"visibility",a)}},[eo]),(0,l.useEffect)(()=>{var e,t;W(null);let r=null!==(t=null==R?void 0:null===(e=R.icao)||void 0===e?void 0:e.toLowerCase())&&void 0!==t?t:"";if(!/^[a-f0-9]{6}$/.test(r))return;let a=!1;return(async()=>{try{var e,t;let l=await fetch("/api/aircraft/photo?hex=".concat(r));if(!l.ok)return;let i=await l.json(),o=null===(e=i.photos)||void 0===e?void 0:e[0];!a&&(null==o?void 0:null===(t=o.thumbnail_large)||void 0===t?void 0:t.src)&&W({url:o.thumbnail_large.src,photographer:o.photographer,link:o.link})}catch(e){}})(),()=>{a=!0}},[R]),(0,l.useEffect)(()=>{var e;let t=x.current;if(!t||!m.current)return;let r=t.getSource("basemap"),a=null===(e=u[el])||void 0===e?void 0:e.url;r&&a&&"function"==typeof r.setTiles&&r.setTiles([a])},[el]),(0,l.useEffect)(()=>{let e=x.current;if(e&&m.current&&et)try{e.setTerrain({source:"dem",exaggeration:eh})}catch(e){}},[eh,et]),(0,l.useEffect)(()=>{var e;eF.current.sizeScale=ex,eF.current.version+=1,null===(e=x.current)||void 0===e||e.triggerRepaint()},[ex]),(0,l.useEffect)(()=>{let e=x.current;if(!e)return;let t=eF.current,r=()=>{if(!m.current)return;let r=eo.wx&&et&&e.getZoom()>=9;if(e.getLayer("wx-raster")&&e.setLayoutProperty("wx-raster","visibility",eo.wx&&!r?"visible":"none"),r){let r=e.getBounds();t.wxBounds={minLon:r.getWest(),minLat:r.getSouth(),maxLon:r.getEast(),maxLat:r.getNorth()},t.wxTexUrl="/api/weather/nexrad?bbox=".concat(r.getWest().toFixed(3),",").concat(r.getSouth().toFixed(3),",").concat(r.getEast().toFixed(3),",").concat(r.getNorth().toFixed(3),"&w=1024&h=1024"),t.wxAltFt=ey,t.wxOn=!0,t.wxVersion+=1,e.triggerRepaint()}else t.wxOn&&(t.wxOn=!1,t.wxVersion+=1,e.triggerRepaint())};return m.current?r():e.once("load",r),e.on("moveend",r),()=>{e.off("moveend",r)}},[D,eo.wx,et,ey]),(0,l.useEffect)(()=>{let e=x.current;e&&e.easeTo({bearing:er?ew.track:0,duration:500})},[er,ew.track]),(0,l.useEffect)(()=>{let e=x.current;if(!e||!m.current)return;let t=e.getSource("rings");if(!t)return;let r=e=>{let t=e/3440.065,r=ew.lat*Math.PI/180,a=ew.lon*Math.PI/180,l=[];for(let e=0;e<=64;e++){let i=2*Math.PI*e/64,o=Math.asin(Math.sin(r)*Math.cos(t)+Math.cos(r)*Math.sin(t)*Math.cos(i)),n=a+Math.atan2(Math.sin(i)*Math.sin(t)*Math.cos(r),Math.cos(t)-Math.sin(r)*Math.sin(o));l.push([180*n/Math.PI,180*o/Math.PI])}return l};t.setData({type:"FeatureCollection",features:[10,25,50].map(e=>({type:"Feature",properties:{nm:e},geometry:{type:"LineString",coordinates:r(e)}}))})},[ew.lat,ew.lon]),(0,l.useEffect)(()=>
1{if(!i.current||x.current)return;let e=new(o()).Map({container:i.current,center:[ew.lon,ew.lat],zoom:8,pitch:65,bearing:0,maxPitch:85,attributionControl:{compact:!0},style:{version:8,glyphs:"/fonts/{fontstack}/{range}.pbf",sources:{basemap:{type:"raster",tiles:["https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}"],tileSize:256,attribution:"\xa9 Esri \xb7 Maxar"},dem:{type:"raster-dem",tiles:[c],tileSize:256,encoding:"terrarium",maxzoom:15,attribution:"\xa9 AWS Terrain Tiles"},"dem-hs":{type:"raster-dem",tiles:[c],tileSize:256,encoding:"terrarium",maxzoom:15}},layers:[{id:"bg",type:"background",paint:{"background-color":"#05070d"}},{id:"basemap",type:"raster",source:"basemap"},{id:"hillshade",type:"hillshade",source:"dem-hs",paint:{"hillshade-exaggeration":.5,"hillshade-shadow-color":"#000000","hillshade-accent-color":"#1e3a5f","hillshade-highlight-color":"#93c5fd"}}]}});return x.current=e,e.addControl(new(o()).NavigationControl({visualizePitch:!0}),"top-right"),e.on("error",t=>{let r=t&&t.error&&t.error.message?t.error.message:"map error";if(console.warn("[Map3DView]",r,null==t?void 0:t.error),/terrain|dem|elevation/i.test(r))try{e.setTerrain(null)}catch(e){}else m.current||E(r)}),e.on("load",()=>{m.current=!0,B(!0),requestAnimationFrame(()=>e.resize());try{e.setTerrain({source:"dem",exaggeration:eh})}catch(e){}try{e.setSky({"sky-color":"#0a1224","horizon-color":"#25406b","fog-color":"#0a0f1a","sky-horizon-blend":.6,"horizon-fog-blend":.6,"fog-ground-blend":.4,"atmosphere-blend":.7})}catch(e){}e.addSource("wx",{type:"raster",tiles:["https://mesonet.agron.iastate.edu/cache/tile.py/1.0.0/nexrad-n0q-900913/{z}/{x}/{y}.png"],tileSize:256,attribution:"NOAA \xb7 Iowa Mesonet"}),e.addLayer({id:"wx-raster",type:"raster",source:"wx",layout:{visibility:"none"},paint:{"raster-opacity":["interpolate",["linear"],["zoom"],4,.7,7,.4,9,.18,11,.08]}});let t={type:"FeatureCollection",features:[]};for(let r of["airspaces","airways","proc","circuit","fpl","directto","ruler","peaks","spotelev","airports","navaids","fixes","wind","rings","traffic","trail"])e.addSource(r,{type:"geojson",data:t});e.addLayer({id:"spotelev-label",type:"symbol",source:"spotelev",minzoom:9,layout:{"text-field":["get","label"],"text-font":["Barlow Regular"],"text-size":10,"text-allow-overlap":!1,"text-optional":!0,"symbol-sort-key":["-",0,["get","elev"]]},paint:{"text-color":"#e5e7eb","text-halo-color":"#000","text-halo-width":1.3}}),e.addLayer({id:"peaks-sym",type:"symbol",source:"peaks",minzoom:7,layout:{"text-field":"▲","text-font":["Symbols"],"text-size":10,"text-allow-overlap":!0},paint:{"text-color":"#e5e7eb","text-halo-color":"#000","text-halo-width":1.4}}),e.addLayer({id:"peaks-label",type:"symbol",source:"peaks",minzoom:7,layout:{"text-field":["get","label"],"text-font":["Barlow Regular"],"text-size":10,"text-offset":[0,-.9],"text-anchor":"bottom","text-allow-overlap":!0},paint:{"text-color":"#e5e7eb","text-halo-color":"#000","text-halo-width":1.4}}),e.addLayer({id:"circuit-line",type:"line",source:"circuit",minzoom:9,layout:{visibility:"none"},paint:{"line-color":"#38bdf8","line-width":1.5,"line-opacity":.7,"line-dasharray":[3,2]}}),e.addLayer({id:"wind-arrow",type:"symbol",source:"wind",minzoom:7,layout:{"text-field":"↑","text-font":["Symbols"],"text-size":18,"text-rotate":["get","toDir"],"text-rotation-alignment":"map","text-allow-overlap":!0},paint:{"text-color":"#67e8f9","text-halo-color":"#000","text-halo-width":1.2}}),e.addLayer({id:"wind-label",type:"symbol",source:"wind",minzoom:8,layout:{"text-field":["get","label"],"text-font":["Barlow Regular"],"text-size":9,"text-offset":[0,1.6],"text-allow-overlap":!0},paint:{"text-color":"#a5f3fc","text-halo-color":"#000","text-halo-width":1}}),e.addSource("plate",{type:"image",url:"data:image/gif;base64,R0lGODlhAQABAAAAACwAAAAAAQABAAA=",coordinates:[[-.001,.001],[.001,.001],[.001,-.001],[-.001,-.001]]}),e.addLayer({id:"plate-raster",type:"raster",source:"plate",layout:{visibility:"none"},paint:{"raster-opacity":.5}}),e.addLayer({id:"directto-line",type:"line",source:"directto",paint:{"line-color":"#d946ef","line-width":2.5,"line-opacity":.95}}),e.addLayer({id:"ruler-line",type:"line",source:"ruler",paint:{"line-color":"#fbbf24","line-width":2,"line-dasharray":[2,2]}}
1),e.addLayer({id:"ruler-pts",type:"circle",source:"ruler",filter:["==",["geometry-type"],"Point"],paint:{"circle-radius":4,"circle-color":"#fbbf24","circle-stroke-color":"#000","circle-stroke-width":1.5}}),e.addLayer({id:"rings-line",type:"line",source:"rings",layout:{visibility:"none"},paint:{"line-color":"#94a3b8","line-width":1,"line-opacity":.5,"line-dasharray":[3,3]}}),e.addLayer({id:"airspaces-3d",type:"fill-extrusion",source:"airspaces",paint:{"fill-extrusion-color":["get","color"],"fill-extrusion-base":["get","baseM"],"fill-extrusion-height":["get","topM"],"fill-extrusion-opacity":.08}}),e.addLayer({id:"airspaces-fill",type:"fill",source:"airspaces",paint:{"fill-color":["get","color"],"fill-opacity":.045}}),e.addLayer({id:"airspaces-line",type:"line",source:"airspaces",paint:{"line-color":["get","color"],"line-width":2,"line-opacity":1}}),e.addLayer({id:"airspaces-label",type:"symbol",source:"airspaces",minzoom:6,layout:{"text-field":["get","label"],"text-font":["Barlow Regular"],"text-size":10,"symbol-placement":"point"},paint:{"text-color":["get","color"],"text-halo-color":"#000","text-halo-width":1.4}}),e.addLayer({id:"airways-line",type:"line",source:"airways",minzoom:6,paint:{"line-color":"#38bdf8","line-width":1.1,"line-opacity":.55,"line-dasharray":[3,2]}}),e.addLayer({id:"proc-line",type:"line",source:"proc",layout:{visibility:"none"},paint:{"line-color":"#e879f9","line-width":1.4,"line-opacity":.7,"line-dasharray":[1.5,1.5]}}),e.addLayer({id:"fpl-line",type:"line",source:"fpl",paint:{"line-color":"#38bdf8","line-width":3,"line-opacity":.9}}),e.addLayer({id:"fixes-dot",type:"symbol",source:"fixes",minzoom:7,layout:{"text-field":"▽","text-font":["Symbols"],"text-size":9,"text-allow-overlap":!0},paint:{"text-color":"#a78bfa","text-halo-color":"#000","text-halo-width":.8}}),e.addLayer({id:"fixes-label",type:"symbol",source:"fixes",minzoom:8,layout:{"text-field":["get","ident"],"text-font":["Barlow Regular"],"text-size":10,"text-offset":[0,.9]},paint:{"text-color":"#a78bfa","text-halo-color":"#000","text-halo-width":1}}),e.addLayer({id:"navaids-dot",type:"circle",source:"navaids",minzoom:6,paint:{"circle-radius":3,"circle-color":"#22d3ee"}}),e.addLayer({id:"navaids-label",type:"symbol",source:"navaids",minzoom:7,layout:{"text-field":["get","ident"],"text-font":["Barlow Regular"],"text-size":10,"text-offset":[0,.9]},paint:{"text-color":"#67e8f9","text-halo-color":"#000","text-halo-width":1}}),e.addLayer({id:"airports-dot",type:"symbol",source:"airports",minzoom:5,layout:{"text-field":"▲","text-font":["Symbols"],"text-size":["interpolate",["linear"],["zoom"],5,9,10,15],"text-allow-overlap":!0},paint:{"text-color":["match",["get","cat"],"VFR","#22c55e","MVFR","#3b82f6","IFR","#ef4444","LIFR","#d946ef","#cbd5e1"],"text-halo-color":"#0a0f1a","text-halo-width":1}}),e.addLayer({id:"airports-label",type:"symbol",source:"airports",minzoom:7,layout:{"text-field":["get","icao"],"text-font":["Barlow Regular"],"text-size":11,"text-offset":[0,1]},paint:{"text-color":"#e2e8f0","text-halo-color":"#000","text-halo-width":1.2}}),e.addLayer({id:"trail-line",type:"line",source:"trail",paint:{"line-color":"#38bdf8","line-width":2,"line-opacity":.8}}),e.addLayer({id:"traffic-dot",type:"circle",source:"traffic",paint:{"circle-radius":["interpolate",["linear"],["zoom"],4,3,10,6],"circle-color":["get","color"],"circle-stroke-color":"#0a0f1a","circle-stroke-width":1}});let r=document.createElement("div");r.innerHTML='<svg width="30" height="30" viewBox="0 0 28 28"><path d="M14 2 L23 24 L14 18 L5 24 Z" fill="#38bdf8" stroke="#fff" stroke-width="1.5" stroke-linejoin="round"/></svg>',y.current=new(o()).Marker({element:r,rotationAlignment:"map"}).setLngLat([ew.lon,ew.lat]).addTo(e),ek()}),e.on("mouseenter","airports-dot",()=>{e.getCanvas().style.cursor="pointer"}),e.on("mouseleave","airports-dot",()=>{e.getCanvas().style.cursor=""}),e.on("mousemove",t=>{if(!Q.current)return;let r=Z.current;if(!r||H.current)return;let a=e.getSource("ruler");if(!a)return;let l=[t.lngLat.lng,t.lngLat.lat];a.setData({type:"FeatureCollection",features:[{type:"Feature",properties:{},geometry:{type:"Point",coordinates:l}},{type:"Feature",properties:{},geometry:{type:"Point",coordinates:r}},{type:"Feature",properties:{},geometry:{type:"LineString",coordinates:[r,l]}}]}),U({nm:p([r[1],r[0]],[l[1],l[0]]),brg:f([r[1],r[0]],[l[1],l[0]])})}),e.on("click",t=>{if(Q.current){let r=e.getSource("ruler"),a=[t.lngLat.lng,t.lngLat.lat],l=Z.current,i=H.current;l&&!i?(H.current=a,U({nm:p([l[1],l[0]],[a[1],a[0]]),brg:f([l[1],l[0]],[a[1],a[0]])}),null==r||r.setData({type:"FeatureCollection",features:[{type:"Feature",properties:{},geometry:{type:"Point",coordinates:l}},{type:"Feature",properties:{},geometry:{type:"Point",coordinates:a}},{type:"Feature",properties:{},geometry:{type:"LineString",coordinates:[l,a]}}]})):(Z.current=a,H.current=null,U(null),null==r||r.setData({type:"FeatureCollection",features:[{type:"Feature",properties:{},geometry:{type:"Point",coordinates:a}}]}));return}let r=e.queryRenderedFeatures(t.point,{layers:["airports-dot"]}
1)[0];if(r){let e=r.properties;A(null),P({icao:e.icao,name:e.name,lat:e.lat,lon:e.lon});return}P(null);let a=eF.current,l=e.getLayer("traffic-dot")?e.queryRenderedFeatures(t.point,{layers:["traffic-dot"]})[0]:void 0;if(l){let e=l.properties.icao,t=a.traffic.find(t=>t.icao===e);if(t){A(t);return}}let i=a.lastMatrix;if(!i||0===a.traffic.length){A(null);return}let o=new n.Matrix4().fromArray(i),{width:s,height:c}={width:e.getCanvas().clientWidth,height:e.getCanvas().clientHeight},u=null,d=22;for(let e of a.traffic){let r=g(e.lon,e.lat,e.altFt),a=new n.Vector4(r.x,r.y,r.z,1).applyMatrix4(o);if(a.w<=0)continue;let l=(a.x/a.w*.5+.5)*s,i=(1-(a.y/a.w*.5+.5))*c,p=Math.hypot(l-t.point.x,i-t.point.y);p<d&&(d=p,u=e)}A(u)}),()=>{e.remove(),x.current=null,m.current=!1}},[]);let eS=(0,l.useMemo)(()=>{let e=new Map;for(let t of k)e.set(t.ident,{lat:t.lat,lon:t.lon});for(let t of v)e.has(t.ident)||e.set(t.ident,{lat:t.lat,lon:t.lon});return e},[k,v]);function ek(){var e,t,r,a;let l=x.current;if(!l||!m.current)return;let i=e=>({type:"FeatureCollection",features:e}),o=(e,t)=>{let r=l.getSource(e);null==r||r.setData(i(t))},n=e=>null==e?"":0===e?"SFC":String(e);o("airspaces",F.filter(e=>Array.isArray(e.polygon)&&e.polygon.length>=3).map(r=>({type:"Feature",properties:{color:function(e){switch(e){case"B":return"#3b82f6";case"C":return"#a855f7";case"D":return"#22d3ee";case"E":return"#9ca3af";case"MOA":case"TRSA":case"RESTRICTED":return"#ef4444";default:return"#6b7280"}}(r.class),icao:r.icao,baseM:(null!==(e=r.floorFt)&&void 0!==e?e:0)*.3048,topM:(null!==(t=r.ceilingFt)&&void 0!==t?t:1e4)*.3048,label:"".concat(r.class," ").concat(n(r.ceilingFt),"/").concat(n(r.floorFt))},geometry:{type:"Polygon",coordinates:[r.polygon.map(e=>{let[t,r]=e;return[r,t]})]}}))),o("airways",N.map(e=>{let t=[];for(let r of e.fixes){let e=eS.get(r);e&&t.push([e.lon,e.lat])}return t.length>=2?{type:"Feature",properties:{id:e.id},geometry:{type:"LineString",coordinates:t}}:null}).filter(Boolean)),o("airports",b.filter(e=>Number.isFinite(e.lat)&&Number.isFinite(e.lon)).map(e=>{var t;return{type:"Feature",properties:{icao:e.icao,name:null!==(r=e.name)&&void 0!==r?r:"",lat:e.lat,lon:e.lon,cat:null!==(a=null===(t=Y.current.get(e.icao))||void 0===t?void 0:t.cat)&&void 0!==a?a:""},geometry:{type:"Point",coordinates:[e.lon,e.lat]}}})),o("navaids",v.filter(e=>Number.isFinite(e.lat)&&Number.isFinite(e.lon)).map(e=>({type:"Feature",properties:{ident:e.ident},geometry:{type:"Point",coordinates:[e.lon,e.lat]}}))),o("fixes",k.filter(e=>Number.isFinite(e.lat)&&Number.isFinite(e.lon)).map(e=>({type:"Feature",properties:{ident:e.ident},geometry:{type:"Point",coordinates:[e.lon,e.lat]}})));let s=[],c=[];for(let e of b){if(!Number.isFinite(e.lat)||!Number.isFinite(e.lon))continue;let t=Y.current.get(e.icao);t&&t.wspd>0&&t.wdir>=0&&s.push({type:"Feature",properties:{toDir:(t.wdir+180)%360,label:"".concat(t.wdir.toString().padStart(3,"0"),"\xb0/").concat(Math.round(t.wspd),"kt")},geometry:{type:"Point",coordinates:[e.lon,e.lat]}});let r=t&&t.wdir>=0?t.wdir:360,a=h(e.lat,e.lon,1.1,r),l=h(e.lat,e.lon,1.1,(r+180)%360),i=h(a[1],a[0],1.1,(r+270)%360),o=h(l[1],l[0],1.1,(r+270)%360);c.push({type:"Feature",properties:{icao:e.icao},geometry:{type:"LineString",coordinates:[a,i,o,l,a]}})}if(o("wind",s),o("circuit",c),o("peaks",[...eu].sort((e,t)=>t.elevFt-e.elevFt).slice(0,1200).map(e=>({type:"Feature",properties:{label:"".concat(Math.round(e.elevFt).toLocaleString()," ft")},geometry:{type:"Point",coordinates:[e.lon,e.lat]}}))),$){let e=new Map;for(let t of b)e.set(t.icao,[t.lon,t.lat]);let t=[],r=r=>{if(r)for(let a of Object.keys(r)){let l=e.get(a);if(l){for(let e of r[a]){let r=[l];for(let t of e.fixes)Number.isFinite(t.lat)&&Number.isFinite(t.lon)&&r.push([t.lon,t.lat]);r.length>=2&&t.push({type:"Feature",properties:{name:e.name},geometry:{type:"LineString",coordinates:r}})}if(t.length>=800)break}}};r($.sid),r($.star),o("proc",t)}let u=[];for(let e of ev.route){let t=ev.airports[e];t&&Number.isFinite(t.lat)&&u.push([t.lon,t.lat])}o("fpl",u.length>=2?[{type:"Feature",properties:{},geometry:{type:"LineString",coordinates:u}}]:[])}(0,l.useEffect)(()=>{ek()},[D,b,v,k,F,N,$,eu,eS,ev.route,ev.airports,X]),(0,l.useEffect)(()=>{let e=x.current;if(!e||!m.current)return;let t=e.getSource("directto");t&&t.setData(G?{type:"FeatureCollection",features:[{type:"Feature",properties:{},geometry:{type:"LineString",coordinates:[[ew.lon,ew.lat],[G.lon,G.lat]]}}]}:{type:"FeatureCollection",features:[]})},[G,ew.lat,ew.lon]),(0,l.useEffect)(()=>{let e=x.current;if(!e)return;if(!eo.metar&&!eo.wind&&!eo.ceilings){Y.current.clear(),J(e=>e+1);return}let t=!1,r=e=>{var t;let r=1/0;for(let a of null!==(t=e.clouds)&&void 0!==t?t:[])("BKN"===a.cover||"OVC"===a.cover||"OVX"===a.cover)&&Number.isFinite(a.base)&&(r=Math.min(r,a.base));return Number.isFinite(r)?r:-1},a=e=>{var t;if(e.fltCat)return e.fltCat;let a="number"==typeof e.visib?e.visib:parseFloat(String(null!==(t=e.visib)&&void 0!==t?t:"10"));Number.isFinite(a)||(a=10);let l=0>r(e)?1/0:r(e);
1return l<500||a<1?"LIFR":l<1e3||a<3?"IFR":l<=3e3||a<=5?"MVFR":"VFR"},l=async()=>{if(!m.current)return;let l=e.getBounds();try{let e=await fetch("/api/weather/metar?format=json&bbox=".concat(l.getSouth().toFixed(2),",").concat(l.getWest().toFixed(2),",").concat(l.getNorth().toFixed(2),",").concat(l.getEast().toFixed(2))),i=await e.json();if(t||!Array.isArray(i))return;for(let e of i){if(!(null==e?void 0:e.icaoId))continue;let t="number"==typeof e.wdir?e.wdir:Number.NaN;Y.current.set(e.icaoId,{cat:a(e),wdir:Number.isFinite(t)?t:-1,wspd:Number(e.wspd)||0,ceilFt:r(e)})}J(e=>e+1)}catch(e){}};l(),e.on("moveend",l);let i=setInterval(l,3e5);return()=>{t=!0,e.off("moveend",l),clearInterval(i)}},[D,eo.metar,eo.wind,eo.ceilings]),(0,l.useEffect)(()=>{var e,t,r;let a=eF.current;if(!eo.ceilings){a.ceilings=[],a.ceilVersion+=1,null===(t=x.current)||void 0===t||t.triggerRepaint();return}let l=new Map;for(let e of b)Number.isFinite(e.lat)&&Number.isFinite(e.lon)&&l.set(e.icao,{lon:e.lon,lat:e.lat,elev:null!==(r=e.elevation_ft)&&void 0!==r?r:0});let i=[];Y.current.forEach((e,t)=>{if(e.ceilFt<0)return;let r=l.get(t);r&&i.push({lon:r.lon,lat:r.lat,mslFt:r.elev+e.ceilFt,label:"".concat(Math.round(e.ceilFt).toLocaleString()," ft")})}),a.ceilings=i.slice(0,400),a.ceilVersion+=1,null===(e=x.current)||void 0===e||e.triggerRepaint()},[eo.ceilings,X,b]),(0,l.useEffect)(()=>{let e=x.current;if(!e||!D)return;let t=()=>e.getSource("spotelev");if(!eo.peaks){var r;null===(r=t())||void 0===r||r.setData({type:"FeatureCollection",features:[]});return}let a=()=>{let r=t();if(!r)return;if(9>e.getZoom()){r.setData({type:"FeatureCollection",features:[]});return}let a=e.getCanvas().clientWidth,l=e.getCanvas().clientHeight,i=[],o=[];for(let t=0;t<=22;t++){i[t]=[],o[t]=[];for(let r=0;r<=16;r++){let n=r/16*a,s=t/22*l,c=e.unproject([n,s]);o[t][r]={lng:c.lng,lat:c.lat};let u=e.queryTerrainElevation?e.queryTerrainElevation([c.lng,c.lat]):null;i[t][r]=null!=u&&Number.isFinite(u)?u/(eh||1):null}}let n=[];for(let e=1;e<22;e++)for(let t=1;t<16;t++){let r=i[e][t];if(null==r||r<30)continue;let a=!0;for(let l=-1;l<=1&&a;l++)for(let o=-1;o<=1;o++){if(!l&&!o)continue;let n=i[e+l][t+o];if(null!=n&&n>=r){a=!1;break}}if(!a)continue;let l=r/.3048;n.push({type:"Feature",properties:{label:"".concat(Math.round(l).toLocaleString()," ft"),elev:Math.round(l)},geometry:{type:"Point",coordinates:[o[e][t].lng,o[e][t].lat]}})}r.setData({type:"FeatureCollection",features:n})},l=()=>{a(),setTimeout(a,600)};return l(),e.on("moveend",l),()=>{e.off("moveend",l)}},[D,eo.peaks,eh]),(0,l.useEffect)(()=>{let e=x.current,t=es.current;if(!e||!t)return;if(!eo.flow){let e=t.getContext("2d");null==e||e.clearRect(0,0,t.width,t.height);return}let r=!1,a=(e,t)=>{let r=ec.current;if(!r)return null;let[a,l,i,o]=r.bbox,n=r.n,s=Math.min(n-1,Math.max(0,(e-a)/(i-a)*(n-1))),c=Math.min(n-1,Math.max(0,(t-l)/(o-l)*(n-1))),u=Math.floor(s),d=Math.floor(c),p=Math.min(n-1,u+1),f=Math.min(n-1,d+1),h=s-u,g=c-d,x=(e,t)=>r.grid[t*n+e],m=x(u,d),y=x(p,d),b=x(u,f),w=x(p,f);if(!m||!y||!b||!w)return null;let v=(m.u*(1-h)+y.u*h)*(1-g)+(b.u*(1-h)+w.u*h)*g,M=(m.v*(1-h)+y.v*h)*(1-g)+(b.v*(1-h)+w.v*h)*g;return{u:v,v:M}},l=()=>{let r=t.getContext("2d");if(!r||!m.current)return;let l=e.getCanvas().clientWidth,i=e.getCanvas().clientHeight,o=window.devicePixelRatio||1;if((t.width!==l*o||t.height!==i*o)&&(t.width=l*o,t.height=i*o),r.setTransform(o,0,0,o,0,0),r.clearRect(0,0,l,i),!ec.current)return;r.lineWidth=1.3,r.lineCap="round",r.lineJoin="round";let n=9e-4*Math.pow(2,(9-e.getZoom())*.35);for(let t=34;t<i;t+=68)for(let i=34;i<l;i+=68){let l=e.unproject([i,t]),o=l.lng,s=l.lat,c=[[i,t]],u=0;for(let t=0;t<16;t++){let t=a(o,s);if(!t)break;u=Math.max(u,Math.hypot(t.u,t.v));let r=Math.cos(s*Math.PI/180)||1e-6;o+=t.u*n/r,s+=t.v*n;let l=e.project([o,s]);c.push([l.x,l.y])}if(c.length<2)continue;let d=Math.min(1,u/25);r.strokeStyle="rgba(".concat(170+85*d,",").concat(235-40*d,",255,0.85)"),r.beginPath(),r.moveTo(c[0][0],c[0][1]);for(let e=1;e<c.length;e++)r.lineTo(c[e][0],c[e][1]);r.stroke();let[p,f]=c[c.length-1],[h,g]=c[c.length-2],x=Math.atan2(f-g,p-h);r.beginPath(),r.moveTo(p,f),r.lineTo(p-5*Math.cos(x-.4),f-5*Math.sin(x-.4)),r.moveTo(p,f),r.lineTo(p-5*Math.cos(x+.4),f-5*Math.sin(x+.4)),r.stroke()}},i=async()=>
1{if(!m.current)return;let t=e.getBounds();try{let e=await fetch("/api/weather/wind-grid?bbox=".concat(t.getWest().toFixed(2),",").concat(t.getSouth().toFixed(2),",").concat(t.getEast().toFixed(2),",").concat(t.getNorth().toFixed(2),"&n=6")),a=await e.json();!r&&Array.isArray(a.grid)&&a.grid.length&&(ec.current=a)}catch(e){}r||l()};return ec.current&&l(),i(),e.on("moveend",i),()=>{r=!0,e.off("moveend",i);let a=t.getContext("2d");null==a||a.clearRect(0,0,t.width,t.height)}},[eo.flow,D]);let ej=(0,l.useRef)(!1);(0,l.useEffect)(()=>{var e;let t=x.current;t&&(null===(e=y.current)||void 0===e||e.setLngLat([ew.lon,ew.lat]),y.current&&y.current.setRotation(ew.track),ej.current||"default"===ew.source||(ej.current=!0,t.flyTo({center:[ew.lon,ew.lat],zoom:"ip"===ew.source?7:9,pitch:65,duration:1600})))},[ew.lat,ew.lon,ew.track,ew.source]),(0,l.useEffect)(()=>{let e=i.current;if(!e||"undefined"==typeof ResizeObserver)return;let t=new ResizeObserver(()=>{var e;return null===(e=x.current)||void 0===e?void 0:e.resize()});return t.observe(e),()=>t.disconnect()},[]);let[eN,eL]=(0,l.useState)(null),ez=async()=>{let e=x.current;if(!e||eN)return;let t=e.getBounds(),r=Math.round(e.getZoom()),a=[r-1,r,r+1,r+2].filter(e=>e>=3&&e<=14),l=(e,t)=>Math.floor((e+180)/360*2**t),i=(e,t)=>{let r=e*Math.PI/180;return Math.floor((1-Math.log(Math.tan(r)+1/Math.cos(r))/Math.PI)/2*2**t)},o=(e,t,r,a)=>e.replace("{z}",String(t)).replace("{x}",String(r)).replace("{y}",String(a)).replace("{r}",""),n=new Set;for(let e of a){let r=l(t.getWest(),e),a=l(t.getEast(),e),s=i(t.getNorth(),e),d=i(t.getSouth(),e);for(let t=Math.min(r,a);t<=Math.max(r,a);t++)for(let r=Math.min(s,d);r<=Math.max(s,d)&&(n.add(o(u[el].url,e,t,r)),n.add(o(c,e,t,r)),!(n.size>1600));r++);}let s=Array.from(n);eL({done:0,total:s.length});let d=0;for(let e=0;e<s.length;e+=8)await Promise.all(s.slice(e,e+8).map(e=>fetch(e).catch(()=>{}).finally(()=>{eL({done:++d,total:s.length})})));await Promise.all(["airports","navaids","airspace","peaks","cifp/fixes","cifp/airways","cifp/procedures"].map(e=>fetch("/navdata/".concat(e,".json")).catch(()=>{}))),setTimeout(()=>eL(null),1500)},[eC,eR]=(0,l.useState)(!1),[eA,eT]=(0,l.useState)(null),eP=async e=>{let t=x.current;if(t){eR(!0);try{var a;let l=await fetch("/api/charts/index?icao=".concat(encodeURIComponent(e))),i=await l.json();if(!l.ok)throw Error("index");let o=i.groups.flatMap(e=>e.items),n=null!==(a=o.find(e=>"APD"===e.code&&e.georef))&&void 0!==a?a:o.find(e=>e.georef);if(!(null==n?void 0:n.georef))throw Error("no georef plate");let{renderPlateToDataUrl:s}=await r.e(66).then(r.bind(r,797)),c=await s("".concat(i.pdfBase).concat(n.pdf)),u=n.georef,d=t.getSource("plate");d.updateImage({url:c,coordinates:[[u.lonLeft,u.latTop],[u.lonRight,u.latTop],[u.lonRight,u.latBottom],[u.lonLeft,u.latBottom]]}),t.setLayoutProperty("plate-raster","visibility","visible"),eT(e)}catch(e){}finally{eR(!1)}}},eI=e=>"px-2 py-1 rounded-md text-[10px] font-semibold uppercase tracking-wider transition-colors ".concat(e?"bg-sky-500 text-white":"bg-black/60 text-white/60 ring-1 ring-white/15 hover:text-white");return(0,a.jsxs)("div",{className:"absolute inset-0",children:[(0,a.jsx)("div",{ref:i,className:"h-full w-full"}),(0,a.jsx)("canvas",{ref:es,className:"absolute inset-0 pointer-events-none",style:{zIndex:1}}),!D&&!I&&(0,a.jsx)("div",{className:"absolute inset-0 grid place-items-center text-white/50 text-sm tracking-widest uppercase pointer-events-none",children:"Loading 3D terrain…"}),I&&(0,a.jsxs)("div",{className:"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 z-20 max-w-[80%] rounded-lg bg-red-950/80 ring-1 ring-red-500/40 px-4 py-3 text-center text-red-200 text-xs",children:["Map error: ",I]}),(0,a.jsxs)("div",{className:"absolute top-3 left-3 z-10 flex flex-col gap-2",children:[(0,a.jsxs)("div",{className:"flex gap-1.5 items-stretch",children:[(0,a.jsx)("button",{className:eI(er),onClick:()=>ea(e=>!e),children:er?"TRK-UP":"N-UP"}),(0,a.jsx)("button",{className:eI(!1),onClick:()=>{var e;null===(e=x.current)||void 0===e||e.flyTo({center:[ew.lon,ew.lat],zoom:9,pitch:et?65:0,duration:900})},title:"Recenter on ownship",children:"◎"}),(0,a.jsx)("button",{className:eI(_),onClick:()=>K(e=>!e),title:"Measure",children:"RULER"}
1),(0,a.jsx)("button",{className:eI(!!eN),onClick:ez,title:"Download this region for offline",children:"⬇"}),(0,a.jsx)("button",{className:eI(ep),onClick:()=>ef(e=>!e),title:"Tune",children:"⚙"})]}),(0,a.jsx)("div",{className:"flex flex-wrap gap-1.5 max-w-[70vw]",children:Object.entries(u).map(e=>{let[t,r]=e;return(0,a.jsx)("button",{className:eI(el===t),onClick:()=>ei(t),children:r.label},t)})}),ep&&(0,a.jsx)("div",{className:"rounded-lg bg-black/70 backdrop-blur p-3 ring-1 ring-white/15 space-y-3 w-56",children:[["Terrain",eh,0,2.5,.05,eg,e=>e.toFixed(2)+"\xd7"],["Traffic size",ex,.3,3,.1,em,e=>e.toFixed(1)+"\xd7"],["WX altitude",ey,0,45e3,500,eb,e=>Math.round(e).toLocaleString()+" ft"]].map(e=>{let[t,r,l,i,o,n,s]=e;return(0,a.jsxs)("label",{className:"block",children:[(0,a.jsxs)("span",{className:"flex justify-between text-[10px] uppercase tracking-wider text-white/60",children:[(0,a.jsx)("span",{children:t}),(0,a.jsx)("span",{className:"font-mono text-white/80",children:s(r)})]}),(0,a.jsx)("input",{type:"range",min:l,max:i,step:o,value:r,onChange:e=>n(Number(e.target.value)),className:"w-full accent-sky-500"})]},t)})}),(0,a.jsx)("div",{className:"flex flex-wrap gap-1.5 max-w-[70vw]",children:[["airspaces","AIRSPACE"],["airways","AWY"],["navaids","NAVAID"],["fixes","FIX"],["airports","ARPT"],["procedures","SID/STAR"],["traffic","TFC"],["wx","WX"],["metar","METAR"],["wind","WIND"],["flow","FLOW"],["ceilings","CIG"],["circuit","CIRCUIT"],["peaks","PEAKS"],["rings","RINGS"]].filter(e=>{let[r]=e;return"efb"===t||"airspaces"!==r&&"airways"!==r&&"procedures"!==r}).map(e=>{let[t,r]=e;return(0,a.jsx)("button",{className:eI(eo[t]),onClick:()=>en(e=>({...e,[t]:!e[t]})),children:r},t)})})]}),R&&(0,a.jsxs)("div",{className:"absolute bottom-16 left-3 z-10 rounded-xl bg-black/80 backdrop-blur px-4 py-3 text-white ring-1 ring-white/15 max-w-[70%]",children:[(0,a.jsxs)("div",{className:"flex items-center justify-between gap-4",children:[(0,a.jsx)("span",{className:"font-mono font-semibold",children:R.flight||R.icao}),(0,a.jsx)("button",{onClick:()=>A(null),className:"text-white/60 hover:text-white text-lg leading-none",children:"\xd7"})]}),(0,a.jsxs)("div",{className:"mt-1 grid grid-cols-3 gap-x-4 gap-y-0.5 text-xs font-mono text-white/80",children:[(0,a.jsxs)("span",{children:["ALT ",Math.round(R.altFt).toLocaleString()," ft"]}),(0,a.jsxs)("span",{children:["GS ",Math.round(R.gsKt)," kt"]}),(0,a.jsxs)("span",{children:["TRK ",Math.round(R.trackDeg).toString().padStart(3,"0"),"\xb0"]}),R.registration&&(0,a.jsx)("span",{children:R.registration}),R.aircraftType&&(0,a.jsx)("span",{children:R.aircraftType}),R.squawk&&(0,a.jsxs)("span",{children:["SQ ",R.squawk]})]}),V&&(0,a.jsxs)("a",{href:V.link,target:"_blank",rel:"noopener noreferrer",className:"mt-2 block overflow-hidden rounded-lg",children:[(0,a.jsx)("img",{src:V.url,alt:"aircraft",className:"w-full max-w-[240px] h-auto"}),V.photographer&&(0,a.jsxs)("span",{className:"block text-[9px] text-white/40 mt-0.5",children:["\xa9 ",V.photographer," \xb7 planespotters.net"]})]}),(0,a.jsx)("p",{className:"mt-1 text-[10px] text-white/40",children:"Trajectory shown in 3D"})]}),T&&(0,a.jsxs)("div",{className:"absolute bottom-16 left-3 z-10 rounded-xl bg-black/80 backdrop-blur px-4 py-3 text-white ring-1 ring-white/15 max-w-[70%]",children:[(0,a.jsxs)("div",{className:"flex items-center justify-between gap-4",children:[(0,a.jsx)("span",{className:"font-mono font-semibold",children:T.icao}),(0,a.jsx)("button",{onClick:()=>P(null),className:"text-white/60 hover:text-white text-lg leading-none",children:"\xd7"})]}),T.name&&(0,a.jsx)("p",{className:"text-xs text-white/70 mt-0.5",children:T.name}),(0,a.jsxs)("div",{className:"mt-2 flex gap-2",children:[(0,a.jsx)("button",{onClick:()=>{ev.addWaypoint(T.icao),P(null)},className:"px-3 py-1.5 rounded-lg bg-sky-500 hover:bg-sky-400 text-white text-xs font-semibold transition-colors",children:"+ Flight plan"}),(0,a.jsx)("button",{onClick:()=>{O({icao:T.icao,lat:T.lat,lon:T.lon}),P(null)},className:"px-3 py-1.5 rounded-lg text-white text-xs font-semibold transition-colors",style:{background:"#c026d3"},children:"→ Direct-To"}),(0,a.jsx)("button",{onClick:()=>eP(T.icao),disabled:eC,className:"px-3 py-1.5 rounded-lg bg-white/10 hover:bg-white/20 text-white text-xs font-semibold transition-colors disabled:opacity-50",children:eC?"…":"▦ Plate"})]})]}),eA&&(0,a.jsxs)("button",{onClick:()=>{let e=x.current;(null==e?void 0:e.getLayer("plate-raster"))&&e.setLayoutProperty("plate-raster","visibility","none"),eT(null)},className:"absolute top-3 right-40 z-20 rounded-lg bg-black/80 backdrop-blur px-3 py-2 text-white ring-1 ring-white/15 text-xs hover:bg-black",children:["▦ Plate: ",eA," \xb7 hide"]}),G&&(0,a.jsx)("div",{className:"absolute top-3 right-14 z-20 rounded-lg bg-black/80 backdrop-blur px-3 py-2 text-white ring-1 ring-fuchsia-500/40 text-xs",children:(0,a.jsxs)("div",{className:"flex items-center gap-3",children:[(0,a.jsxs)("span",{className:"font-mono font-semibold",style:{color:"#e879f9"},children:["→ ",G.icao]}),(0,a.jsxs)("span",{className:"font-mono",children:[Math.round(p([ew.lat,ew.lon],[G.lat,G.lon]))," nm"]}
1),(0,a.jsxs)("span",{className:"font-mono",children:[Math.round(f([ew.lat,ew.lon],[G.lat,G.lon])).toString().padStart(3,"0"),"\xb0"]}),(0,a.jsx)("button",{onClick:()=>O(null),className:"text-white/60 hover:text-white leading-none",children:"\xd7"})]})}),_&&(0,a.jsx)("div",{className:"absolute top-28 left-3 z-20 rounded-lg bg-black/80 backdrop-blur px-3 py-2 text-amber-200 ring-1 ring-amber-500/40 text-xs font-mono",children:q?"".concat(Math.round(q.nm)," nm \xb7 ").concat(Math.round(q.brg).toString().padStart(3,"0"),"\xb0"):"Click to set start, move to measure"}),eN&&(0,a.jsx)("div",{className:"absolute top-3 left-1/2 -translate-x-1/2 z-20 rounded-lg bg-black/85 backdrop-blur px-4 py-2 text-white ring-1 ring-sky-500/40 text-xs",children:eN.done<eN.total?(0,a.jsxs)(a.Fragment,{children:["Downloading region… ",eN.done,"/",eN.total," tiles ",(0,a.jsx)("div",{className:"mt-1 h-1 w-40 rounded-full bg-white/15 overflow-hidden",children:(0,a.jsx)("div",{className:"h-full bg-sky-400",style:{width:"".concat(Math.round(eN.done/Math.max(1,eN.total)*100),"%")}})})]}):(0,a.jsx)(a.Fragment,{children:"✓ Region cached for offline"})}),eo.traffic&&(0,a.jsxs)("div",{className:"absolute bottom-16 right-3 z-10 rounded-lg bg-black/60 backdrop-blur px-3 py-2 ring-1 ring-white/10",children:[(0,a.jsx)("p",{className:"text-[8px] uppercase tracking-widest text-white/40 mb-1",children:"Traffic alt"}),[["#34d399","< 3k"],["#facc15","3–10k"],["#38bdf8","10–24k"],["#c084fc","> 24k"],["#ef4444","EMER"]].map(e=>{let[t,r]=e;return(0,a.jsxs)("div",{className:"flex items-center gap-1.5",children:[(0,a.jsx)("span",{className:"inline-block w-2.5 h-2.5 rounded-sm",style:{background:t}}),(0,a.jsx)("span",{className:"text-[9px] font-mono text-white/70",children:r})]},r)})]}),(0,a.jsx)("div",{className:"absolute bottom-3 left-1/2 -translate-x-1/2 z-10 flex gap-6 rounded-xl bg-black/70 backdrop-blur px-6 py-2 text-white ring-1 ring-white/10",children:[["GS",null==ew.gsKt?"--":Math.round(ew.gsKt)+" kt"],["ALT",null==ew.altFt?"--":Math.round(ew.altFt).toLocaleString()+" ft"],["TRK","default"===ew.source?"--":Math.round(ew.track).toString().padStart(3,"0")+"\xb0"],["TFC",String(z.length)],["VIEW",et?"3D":"2D"]].map(e=>{let[t,r]=e;return(0,a.jsxs)("div",{className:"text-center",children:[(0,a.jsx)("p",{className:"text-[9px] uppercase tracking-widest text-white/40",children:t}),(0,a.jsx)("p",{className:"text-sm font-mono",children:r})]},t)})})]})}},2524:function(){}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.