@rr0/ufoathome 0.144.1 → 0.146.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-embed-scene/rr0-scene.mjs +331 -652
- package/dist-embed-scene/{sightingSchema-t3YCF0eV.js → sightingSchema-BpEpb5Vc.js} +1 -1
- package/dist-embed-sighting/SightingMessages_es-CLihvSau.js +1 -0
- package/dist-embed-sighting/SightingMessages_fr-1Wf0tZCS.js +1 -0
- package/dist-embed-sighting/SightingMessages_it-BBpNT9oj.js +1 -0
- package/dist-embed-sighting/rr0-sighting.mjs +317 -638
- package/dist-embed-sighting/{sightingSchema-t3YCF0eV.js → sightingSchema-BpEpb5Vc.js} +1 -1
- package/dist-embed-sighting-editor/AdsbLolArchiveProvider-RNAaE2P_.js +1 -0
- package/dist-embed-sighting-editor/{BeamEditor-Bko8HBqB.js → BeamEditor-qZfCSNrr.js} +1 -1
- package/dist-embed-sighting-editor/{BeamSystem-DibQnDQt.js → BeamSystem-CrrOjNqD.js} +1 -1
- package/dist-embed-sighting-editor/{BodyEditor-3Pv5hYe4.js → BodyEditor-XZ5oo20k.js} +2 -2
- package/dist-embed-sighting-editor/{ContrailSystem-CnMn7-P3.js → ContrailSystem-CXR_fe3m.js} +1 -1
- package/dist-embed-sighting-editor/{CoverageAssessor-ZPfl-pIr.js → CoverageAssessor-B8gBscye.js} +1 -1
- package/dist-embed-sighting-editor/{GLTFLoader-BwKeFCRw.js → GLTFLoader-DHQ7X9p5.js} +1 -1
- package/dist-embed-sighting-editor/{HeadlightSystem-CoBP2hn0.js → HeadlightSystem-CPbn_3dw.js} +1 -1
- package/dist-embed-sighting-editor/{HynekAssessor-kTvEbabz.js → HynekAssessor-BopK5jfz.js} +1 -1
- package/dist-embed-sighting-editor/{InterviewEditorElement-DBuxtdMB.js → InterviewEditorElement-CpK8gAgI.js} +2 -2
- package/dist-embed-sighting-editor/LanternEditor-D2yl5PH3.js +9 -0
- package/dist-embed-sighting-editor/LanternEditorMessages_en-3XzIx2c4.js +1 -0
- package/dist-embed-sighting-editor/LanternEditorMessages_es-BwzbSSd3.js +1 -0
- package/dist-embed-sighting-editor/LanternEditorMessages_fr-Cf444dJM.js +1 -0
- package/dist-embed-sighting-editor/LanternEditorMessages_it-Bhk0A4Ug.js +1 -0
- package/dist-embed-sighting-editor/{LaserBeam-BuHV0CAP.js → LaserBeam-D6hhHu5-.js} +1 -1
- package/dist-embed-sighting-editor/{LaunchEditor-B-i5uD19.js → LaunchEditor-Dry3DiMo.js} +1 -1
- package/dist-embed-sighting-editor/{ModelSource-DvO3GvYu.js → ModelSource-n0nZrWMU.js} +1 -1
- package/dist-embed-sighting-editor/{ModelThumbnails-T8FwtOCM.js → ModelThumbnails-Bj4DwXU0.js} +1 -1
- package/dist-embed-sighting-editor/{ModelViewer-s4OyekVX.js → ModelViewer-YecYa7OI.js} +1 -1
- package/dist-embed-sighting-editor/{RailwaySystem-BgkkxR-M.js → RailwaySystem-DMCp5YHT.js} +4 -4
- package/dist-embed-sighting-editor/{ReferenceSystem-D30Dc7NR.js → ReferenceSystem-BeFpOHFl.js} +1 -1
- package/dist-embed-sighting-editor/{RoadMarkings-BME7pFh2.js → RoadMarkings-GCEFUqp7.js} +1 -1
- package/dist-embed-sighting-editor/{SceneNames_es-CYEwepgA.js → SceneNames_es-Bxqb_rVs.js} +1 -1
- package/dist-embed-sighting-editor/{SceneNames_fr-DcmXYPbm.js → SceneNames_fr-B5y3B23j.js} +1 -1
- package/dist-embed-sighting-editor/{SceneNames_it-Doviz6zH.js → SceneNames_it-DBmk3NDJ.js} +1 -1
- package/dist-embed-sighting-editor/{SightingEditorMessages_es-BXrXCsmJ.js → SightingEditorMessages_es-8tTlDrVR.js} +1 -1
- package/dist-embed-sighting-editor/{SightingEditorMessages_fr-DtMIkYvz.js → SightingEditorMessages_fr-B6HG_PkP.js} +1 -1
- package/dist-embed-sighting-editor/{SightingEditorMessages_it-Cii6z1Lk.js → SightingEditorMessages_it-BwIheqwp.js} +1 -1
- package/dist-embed-sighting-editor/{SightingFileEditor-DDAzzasL.js → SightingFileEditor-IEZGobI0.js} +1 -1
- package/dist-embed-sighting-editor/{TraceSystem-BGF0P9zl.js → TraceSystem-lNFPtyqy.js} +2 -2
- package/dist-embed-sighting-editor/{WaterSystem-BKoFKdK_.js → WaterSystem-KGutPogf.js} +1 -1
- package/dist-embed-sighting-editor/rr0-sighting-editor.mjs +325 -637
- package/dist-embed-sighting-editor/{sightingSchema-t3YCF0eV.js → sightingSchema-BpEpb5Vc.js} +1 -1
- package/dist-embed-sighting-editor/trafficRuntime-ZmzuyzhR.js +2 -0
- package/package.json +1 -1
- package/dist-embed-sighting/SightingMessages_es-DBRW6jG0.js +0 -1
- package/dist-embed-sighting/SightingMessages_fr-Dwkll3ZY.js +0 -1
- package/dist-embed-sighting/SightingMessages_it-CS1pKPSh.js +0 -1
- package/dist-embed-sighting-editor/AdsbLolArchiveProvider-CtHllfL6.js +0 -1
- package/dist-embed-sighting-editor/trafficRuntime-BoN9h4Uo.js +0 -2
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{Y as lt,Z as ht,$ as z,R as L,a0 as F,a1 as ut,j as q}from"./rr0-sighting-editor.mjs";import{a2 as Ht}from"./rr0-sighting-editor.mjs";import{C as Z}from"./ContrailGrowth-DwHS8If9.js";class E{static OCTAVES=[63,125,250,500,1e3,2e3,4e3,8e3];static STANDARD={temperatureC:15,relativeHumidity:.7,pressureKPa:101.325};static REFERENCE_PRESSURE_KPA=101.325;static REFERENCE_TEMPERATURE_K=293.15;static TRIPLE_POINT_K=273.16;static speedOfSound(t){return 20.0468*Math.sqrt(t+273.15)}static absorptionDbPerKm(t,e=E.STANDARD){const a=e.temperatureC+273.15,n=E.REFERENCE_TEMPERATURE_K,i=e.pressureKPa/E.REFERENCE_PRESSURE_KPA,o=10**(-6.8346*(E.TRIPLE_POINT_K/a)**1.261+4.6151),s=e.relativeHumidity*100*o/i,r=i*(24+40400*s*(.02+s)/(.391+s)),u=i*(a/n)**-.5*(9+280*s*Math.exp(-4.17*((a/n)**(-1/3)-1))),c=t*t;return 8.686*c*(184e-13*(1/i)*Math.sqrt(a/n)+(a/n)**-2.5*(.01275*Math.exp(-2239.1/a)/(r+c/r)+.1068*Math.exp(-3352/a)/(u+c/u)))*1e3}static aWeightingDb(t){const e=t*t,a=12194**2*e*e/((e+20.6**2)*Math.sqrt((e+107.7**2)*(e+737.9**2))*(e+12194**2));return 20*Math.log10(a)+2}static sumDb(t){return 10*Math.log10(t.reduce((e,a)=>e+10**(a/10),0))}}const dt=.25,x=.4,Q=6,K=12,pt=3,tt=.2,gt=.2,mt=24,Et=3,At=12,et=1,Mt=.7,ft=1.5,bt=.8,St=1.3,at=.9,nt=5,Dt=25,Rt=.5,Ot=.12,it=[.13,.31],vt=.16,Tt=1.6,Bt=3.6,st=1.1,It=.3,_t=1e3,rt=.7;class Y{context;noiseBuffer;roughBuffers=new Map;voices=new Map;bus;reverb;reverbOut;level=1;master;paused=!0;requested=[];headingDeg=0;resume(){if(!this.context){if(typeof AudioContext>"u")return;try{this.context=new AudioContext}catch(t){console.warn("AircraftAudio: Web Audio unavailable, aircraft stay silent:",t);return}}lt.unlock(this.context),this.apply()}setLevel(t){this.level=t,this.master&&(this.master.gain.value=t)}setPaused(t){t!==this.paused&&(this.paused=t,this.apply())}setVoices(t,e=0){this.requested=t,this.headingDeg=e,this.apply()}dispose(){for(const t of[...this.voices.keys()])this.release(t);this.context?.close(),this.context=void 0,this.master=void 0,this.bus=void 0}apply(){const t=this.context;if(!t)return;const e=this.paused?[]:this.requested,a=new Set(e.map(n=>n.id));for(const n of[...this.voices.keys()])a.has(n)||this.release(n);for(const n of e){const i=this.voices.get(n.id)??this.build(t,n);this.retarget(t,i,n)}}build(t,e){const a=t.createGain();a.gain.value=0;let n;const i=this.busOf(t);typeof t.createStereoPanner=="function"?(n=t.createStereoPanner(),a.connect(n).connect(i)):a.connect(i);const o=t.createGain(),s=e.character?.modulationDepth??0;o.gain.value=1-s/2;const r=t.createOscillator();r.type="sine";const u=t.createGain();u.gain.value=s/2,r.connect(u).connect(o.gain),o.connect(a);const c=t.createBufferSource();c.buffer=this.noise(t),c.loop=!0,c.loopStart=Math.random()*Q*.5;const d=[],l=[],h=[];for(const v of E.OCTAVES){const B=t.createBiquadFilter();B.type="bandpass",B.frequency.value=v,B.Q.value=et;const N=t.createBiquadFilter();N.type="bandpass",N.frequency.value=v,N.Q.value=et;const y=t.createGain();y.gain.value=0,c.connect(B).connect(N).connect(y).connect(o),d.push(B),l.push(N),h.push(y)}const p=[];for(const[v,B]of[[e.character?.toneHz,e.character?.toneShare],[e.character?.humHz,e.character?.humShare]])if(v!==void 0)for(let N=1;N<=Et;N++){const y=t.createOscillator();y.type="sine",y.frequency.value=v*N;const X=t.createGain();X.gain.value=0,y.connect(X).connect(a),p.push({oscillator:y,gain:X,harmonic:N,baseHz:v,share:B??0})}const g=t.createGain();g.gain.value=0,g.connect(a.gain);const M=it.map(v=>{const B=t.createOscillator();return B.type="sine",B.frequency.value=v,B.connect(g),B}),b=t.createGain();b.gain.value=e.character?.roughness??tt;const R=t.createBufferSource();R.buffer=this.roughTable(t,pt),R.loop=!0,R.loopStart=Math.random()*K*.5,R.connect(b).connect(o.gain);const S=t.createGain();S.gain.value=(e.character?.roughness??tt)*gt;const f=t.createBufferSource();f.buffer=this.roughTable(t,mt),f.loop=!0,f.loopStart=Math.random()*K*.5,f.connect(S).connect(o.gain);let I;const j=this.busOf(t)&&this.reverb;j&&(I=t.createGain(),I.gain.value=0,a.connect(I).connect(j));const V=[c,R,f,r,...p.map(v=>v.oscillator),...M];for(const v of V)v.start();const J={nodes:[a,o,u,b,S,g,...p.map(v=>v.gain),...d,...l,...h,...I?[I]:[],...n?[n]:[],...V],sources:V,filters:d,seconds:l,gains:h,tones:p,lfo:r,lfoDepth:u,wander:M,wanderDepth:g,roughDepth:b,crackleDepth:S,beat:o,output:a,panner:n,send:I};return this.voices.set(e.id,J),J}retarget(t,e,a){const n=t.currentTime,i=(p,g)=>p.setTargetAtTime(g,n,dt),o=Math.min(ft,Math.max(Mt,a.dopplerRatio)),s=Math.min(St,Math.max(bt,Math.sqrt(a.dopplerRatio))),r=t.sampleRate*.45,u=a.bandAmplitudes.map((p,g)=>p*Y.unweighting(E.OCTAVES[g])),c=Math.sqrt(u.reduce((p,g)=>p+g*g,0)),d=Math.min(1,Math.max(0,(a.distanceKm-nt)/(Dt-nt)));E.OCTAVES.forEach((p,g)=>{i(e.filters[g].frequency,Math.min(r,p*s)),i(e.seconds[g].frequency,Math.min(r,p*s)),i(e.gains[g].gain,u[g]*Math.sqrt(_t/p))});const l=a.character;for(const{oscillator:p,gain:g,harmonic:M,baseHz:b,share:R}of e.tones){const S=b*M;i(p.frequency,S*o);const f=S*o;i(g.gain,f<r?R*vt*u[Y.bandOf(f)]/M:0)}l?.modulationHz!==void 0&&i(e.lfo.frequency,l.modulationHz*o);const h=c>0?rt*(1-Math.exp(-c/rt))/c:1;if(i(e.output.gain,h*(1-It*d)),i(e.wanderDepth.gain,h*Ot*d/it.length),e.send&&i(e.send.gain,Tt*d),e.panner){const p=(a.azimuthDeg-this.headingDeg)*Math.PI/180;i(e.panner.pan,Math.max(-at,Math.min(at,Math.sin(p)))*(1-Rt*d))}}static unweighting(t){return 10**(Math.min(At,Math.max(0,-E.aWeightingDb(t)))/20)}static bandOf(t){let e=0;return E.OCTAVES.forEach((a,n)=>{Math.abs(Math.log(t/a))<Math.abs(Math.log(t/E.OCTAVES[e]))&&(e=n)}),e}roughTable(t,e){const a=this.roughBuffers.get(e);if(a)return a;const n=Math.floor(t.sampleRate*K),i=t.createBuffer(1,n,t.sampleRate),o=i.getChannelData(0),s=Array.from({length:K*e},()=>(Math.random()*2-1)**3),r=t.sampleRate/e;for(let u=0;u<o.length;u++){const c=u/r,d=Math.floor(c),l=c-d,h=l*l*(3-2*l);o[u]=s[d%s.length]*(1-h)+s[(d+1)%s.length]*h}return this.roughBuffers.set(e,i),i}roomImpulse(t){const e=Math.floor(t.sampleRate*Bt),a=t.createBuffer(2,e,t.sampleRate);for(let n=0;n<2;n++){const i=a.getChannelData(n);let o=0;for(let s=0;s<e;s++){const r=s/t.sampleRate,u=.6*Math.exp(-r/(st*2))+.04;o+=u*(Math.random()*2-1-o),i[s]=o*Math.exp(-r/st)}}return a}busOf(t){if(this.bus)return this.bus;const e=t.createGain();if(e.gain.value=this.level,e.connect(t.destination),this.master=e,typeof t.createConvolver=="function"){const a=t.createConvolver();a.buffer=this.roomImpulse(t);const n=t.createGain();n.gain.value=.9,a.connect(n),this.reverb=a,this.reverbOut=n}if(typeof t.createDynamicsCompressor=="function"){const a=t.createDynamicsCompressor();a.threshold.value=-6,a.knee.value=3,a.ratio.value=4,a.attack.value=.005,a.release.value=.25,a.connect(e),this.bus=a}else this.bus=e;return this.reverbOut?.connect(this.bus),this.bus}release(t){const e=this.voices.get(t);if(!e)return;this.voices.delete(t);const a=this.context;a&&(e.output.gain.setTargetAtTime(0,a.currentTime,x/3),setTimeout(()=>{for(const n of e.sources)try{n.stop()}catch{}for(const n of e.nodes)n.disconnect()},x*1e3*3))}noise(t){if(this.noiseBuffer)return this.noiseBuffer;const e=t.createBuffer(1,t.sampleRate*Q,t.sampleRate),a=e.getChannelData(0);for(let n=0;n<a.length;n++)a[n]=Math.random()*2-1;return this.noiseBuffer=e,e}}class _{static BASE_DB_A=30;static WIND_DB_A=[[0,10],[1,28],[2,36],[3,40],[5,46],[8,52],[12,58],[20,66]];static RAIN_DB_A=[[0,0],[.1,42],[.3,50],[.6,58],[1,65]];static BED_RMS=.2;static MINIMUM_REFERENCE=.008;static WIND_BED_MIN_MS=1;static WIND_BED_FULL_MS=20;static dbA(t){const e=[_.BASE_DB_A,_.along(_.WIND_DB_A,t.windSpeed)];return(t.precipitationType==="rain"||t.precipitationType==="hail")&&e.push(_.along(_.RAIN_DB_A,t.precipitationIntensity)),10*Math.log10(e.filter(a=>a>0).reduce((a,n)=>a+10**(n/10),0))}static bedVolume(t){const e=t.windSpeed>_.WIND_BED_MIN_MS?Math.min(t.windSpeed/_.WIND_BED_FULL_MS,1):0,a=t.precipitationType==="hail"?Math.min(1,t.precipitationIntensity*1.3+.2):t.precipitationType==="rain"?t.precipitationIntensity:0;return Math.hypot(e,a)}static referenceAmplitude(t){return Math.max(_.BED_RMS*_.bedVolume(t),_.MINIMUM_REFERENCE)}static along(t,e){if(e<=t[0][0])return t[0][1];for(let a=1;a<t.length;a++)if(e<=t[a][0]){const[n,i]=t[a-1],[o,s]=t[a];return i+(s-i)*(e-n)/(o-n)}return t[t.length-1][1]}}class k{static TYPES={A318:["Airbus A318","airliner-narrow",34.1,31.4],A319:["Airbus A319","airliner-narrow",34.1,33.8],A320:["Airbus A320","airliner-narrow",34.1,37.6],A321:["Airbus A321","airliner-narrow",34.1,44.5],A19N:["Airbus A319neo","airliner-narrow",35.8,33.8],A20N:["Airbus A320neo","airliner-narrow",35.8,37.6],A21N:["Airbus A321neo","airliner-narrow",35.8,44.5],B737:["Boeing 737-700","airliner-narrow",34.3,33.6],B738:["Boeing 737-800","airliner-narrow",35.8,39.5],B739:["Boeing 737-900","airliner-narrow",35.8,42.1],B38M:["Boeing 737 MAX 8","airliner-narrow",35.9,39.5],B39M:["Boeing 737 MAX 9","airliner-narrow",35.9,42.2],B752:["Boeing 757-200","airliner-narrow",38,47.3],B753:["Boeing 757-300","airliner-narrow",38,54.4],B762:["Boeing 767-200","airliner-wide",47.6,48.5],B763:["Boeing 767-300","airliner-wide",47.6,54.9],B764:["Boeing 767-400","airliner-wide",51.9,61.4],B772:["Boeing 777-200","airliner-wide",60.9,63.7],B77L:["Boeing 777-200LR","airliner-wide",64.8,63.7],B77W:["Boeing 777-300ER","airliner-wide",64.8,73.9],B788:["Boeing 787-8","airliner-wide",60.1,56.7],B789:["Boeing 787-9","airliner-wide",60.1,62.8],B78X:["Boeing 787-10","airliner-wide",60.1,68.3],B744:["Boeing 747-400","airliner-wide",64.4,70.7],B748:["Boeing 747-8","airliner-wide",68.4,76.3],A306:["Airbus A300-600","airliner-wide",44.8,54.1],A310:["Airbus A310","airliner-wide",43.9,46.7],A332:["Airbus A330-200","airliner-wide",60.3,58.8],A333:["Airbus A330-300","airliner-wide",60.3,63.7],A338:["Airbus A330-800","airliner-wide",64,58.8],A339:["Airbus A330-900","airliner-wide",64,63.7],A343:["Airbus A340-300","airliner-wide",60.3,63.7],A346:["Airbus A340-600","airliner-wide",63.5,75.4],A359:["Airbus A350-900","airliner-wide",64.8,66.8],A35K:["Airbus A350-1000","airliner-wide",64.8,73.8],A388:["Airbus A380-800","airliner-wide",79.8,72.7],E170:["Embraer 170","regional-jet",26,29.9],E75L:["Embraer 175","regional-jet",26,31.7],E75S:["Embraer 175","regional-jet",26,31.7],E190:["Embraer 190","regional-jet",28.7,36.2],E195:["Embraer 195","regional-jet",28.7,38.7],E290:["Embraer 190-E2","regional-jet",33.7,36.2],E295:["Embraer 195-E2","regional-jet",33.7,41.5],CRJ2:["Bombardier CRJ200","regional-jet",21.2,26.8],CRJ7:["Bombardier CRJ700","regional-jet",23.2,32.3],CRJ9:["Bombardier CRJ900","regional-jet",24.9,36.2],CRJX:["Bombardier CRJ1000","regional-jet",26.2,39.1],AT72:["ATR 72","regional-turboprop",27.1,27.2],AT76:["ATR 72-600","regional-turboprop",27.1,27.2],AT45:["ATR 42","regional-turboprop",24.6,22.7],DH8D:["Dash 8 Q400","regional-turboprop",28.4,32.8],DH8C:["Dash 8-300","regional-turboprop",27.4,25.7],SF34:["Saab 340","regional-turboprop",21.4,19.7],B190:["Beechcraft 1900","regional-turboprop",17.7,17.6],C25A:["Cessna CitationJet CJ2","business-jet",14.3,14.4],C56X:["Cessna Citation Excel","business-jet",17.2,16],C68A:["Cessna Citation Latitude","business-jet",22,18.9],C550:["Cessna Citation II","business-jet",15.8,14.4],E55P:["Embraer Phenom 300","business-jet",15.9,15.6],E50P:["Embraer Phenom 100","business-jet",12.3,12.8],GLF5:["Gulfstream G550","business-jet",28.5,29.4],FA7X:["Dassault Falcon 7X","business-jet",26.2,23.4],CL60:["Bombardier Challenger 600","business-jet",19.6,20.9],LJ45:["Learjet 45","business-jet",14.6,17.7],H25B:["Hawker 800","business-jet",15.7,15.6],C172:["Cessna 172","light-piston",11,8.3],C152:["Cessna 152","light-piston",10.2,7.3],C182:["Cessna 182","light-piston",10.9,8.8],P28A:["Piper Cherokee","light-piston",10.7,7.2],PA34:["Piper Seneca","light-piston",11.8,8.7],SR20:["Cirrus SR20","light-piston",10.9,7.9],SR22:["Cirrus SR22","light-piston",11.7,7.9],S22T:["Cirrus SR22T","light-piston",11.7,7.9],DA40:["Diamond DA40","light-piston",11.6,8.1],DA42:["Diamond DA42","light-piston",13.4,8.6],BE20:["Beechcraft King Air 200","turboprop-light",16.6,13.3],BE58:["Beechcraft Baron","light-piston",11.5,9.1],C208:["Cessna Caravan","turboprop-light",15.9,11.5],PC12:["Pilatus PC-12","turboprop-light",16.3,14.4],TBM9:["Daher TBM 900","turboprop-light",12.8,10.7],EC35:["Airbus H135","helicopter-light",10.2,12.1],EC45:["Airbus H145","helicopter-medium",11,13.6],AS50:["Airbus H125","helicopter-light",10.7,12.9],EC30:["Airbus H130","helicopter-light",10.7,12.6],B407:["Bell 407","helicopter-light",10.7,12.7],B06:["Bell 206","helicopter-light",10.2,12],B429:["Bell 429","helicopter-medium",10.9,13],B505:["Bell 505","helicopter-light",10.4,11.9],R44:["Robinson R44","helicopter-light",10.1,11.7],R22:["Robinson R22","helicopter-light",7.7,8.8],A109:["Agusta A109","helicopter-medium",11,13],A139:["Leonardo AW139","helicopter-medium",13.8,16.7],S92:["Sikorsky S-92","helicopter-heavy",17.2,20.9],H60:["Sikorsky UH-60 Black Hawk","helicopter-heavy",16.4,19.8],T38:["Northrop T-38 Talon","military-jet",7.7,14.1],HAWK:["BAE Hawk","military-jet",9.4,11.9],GLID:["Glider","glider",17,7],BALL:["Balloon","balloon",15,20],ULAC:["Ultralight","ultralight",9.5,6],C42:["Ikarus C42","ultralight",9.4,6.3],DRON:["Drone","unmanned",1,.6]};static CATEGORIES={A1:["Light aircraft","light-piston",11,8.3],A2:["Small aircraft","business-jet",15,15],A3:["Large aircraft","airliner-narrow",34.1,37.6],A4:["High-vortex large aircraft","airliner-narrow",38,47.3],A5:["Heavy aircraft","airliner-wide",60.3,63.7],A6:["High-performance aircraft","military-jet",8,14],A7:["Rotorcraft","helicopter-medium",10.7,12.7],B1:["Glider","glider",17,7],B2:["Lighter-than-air","balloon",15,20],B4:["Ultralight","ultralight",9.5,6],B6:["Unmanned aircraft","unmanned",1.5,1]};static GENERIC={name:"Airliner",kind:"airliner-narrow",spanM:34.1,lengthM:37.6,basis:"nothing"};static of(t){const e=t?.type?.toUpperCase(),a=e?k.TYPES[e]:void 0;if(a)return{code:e,name:a[0],kind:a[1],spanM:a[2],lengthM:a[3],basis:"type"};const n=t?.category?k.CATEGORIES[t.category]:void 0;return n?{name:n[0],kind:n[1],spanM:n[2],lengthM:n[3],basis:"category"}:{...k.GENERIC}}static isHelicopter(t){return t.kind.startsWith("helicopter")}}class P{static DUSK_SUN_ELEVATION_DEG=-.83;static ALWAYS=new Set(["airliner-narrow","airliner-wide","regional-turboprop","regional-jet","business-jet"]);static NONE=new Set(["glider","balloon"]);static BRIGHTNESS={"light-piston":[.5,.2,.5],"turboprop-light":[.7,.4,.8],ultralight:[.4,.2,.4],unmanned:[0,.05,0],"helicopter-light":[1,1,1],"helicopter-medium":[1,1,1],"helicopter-heavy":[1,1,1],"military-jet":[1,1,1]};static lampsOn(t,e){if(P.NONE.has(t))return{navigation:!1,beacon:!1,strobes:!1};if(P.ALWAYS.has(t))return{navigation:!0,beacon:!0,strobes:!0};const a=e<P.DUSK_SUN_ELEVATION_DEG;return t==="unmanned"?{navigation:!1,beacon:!1,strobes:a}:{navigation:a,beacon:a,strobes:a}}static lights(t,e){const a=P.lampsOn(t.kind,e),n=t.kind.startsWith("helicopter"),i=ht.find(h=>h.id===(n?"helicopter":"airliner")).create(),[o,s]=n?[5,7]:[17,18],r=t.spanM/2/o,u=t.lengthM/2/s,[c,d,l]=P.BRIGHTNESS[t.kind]??[1,1,1];return i.filter(h=>h.id.startsWith("nav")?a.navigation:h.id.startsWith("strobe")?a.strobes:h.id.startsWith("beacon")?a.beacon:!0).filter(h=>!(h.id.startsWith("beacon")&&!a.beacon)).map(h=>{const p=h.id.startsWith("nav")?c:h.id.startsWith("strobe")?d:l;return{...h,offsetM:{x:h.offsetM.x*r,y:h.offsetM.y,z:h.offsetM.z*u},intensity:(h.intensity??1)*p}}).filter(h=>(h.intensity??1)>0)}static bodyColor(t){return t.kind==="military-jet"?"#8a8e94":t.kind.startsWith("helicopter")?"#c8ccd1":t.kind==="unmanned"?"#2c2e33":"#dde0e4"}}class U{static FAMILIES={"amvlab-a320":["A318","A319","A320","A321","A19N","A20N","A21N"],"amvlab-b737":["B732","B733","B734","B735","B736","B737","B738","B739","B37M","B38M","B39M","B3XM"],"amvlab-a350":["A359","A35K"],"amvlab-a380":["A388"],"amvlab-b787":["B788","B789","B78X"]};static BY_TYPE=new Map(Object.entries(U.FAMILIES).flatMap(([t,e])=>e.map(a=>[a,t])));static idOf(t){return t?U.BY_TYPE.get(t.toUpperCase()):void 0}}class D{static ID_PREFIX=z.ID_PREFIX;static MAX_OBJECTS=40;static FT_TO_M=.3048;static DEG=Math.PI/180;static from(t,e,a,n=D.MAX_OBJECTS,i={}){return new Nt(t,e,a,n,i).build()}static idOf(t,e){return z.idOf(t,e)}static keyOf(t){return z.keyOf(t)}static HEIGHT_OVER_LENGTH=.29;static sizeOf(t){return{widthM:t.spanM,lengthM:t.lengthM,heightM:t.lengthM*D.HEIGHT_OVER_LENGTH}}static offsetOf(t,e){const a=L.seenFrom(t,{lat:e.lat,lng:e.lng,heightM:e.altitudeFt*D.FT_TO_M}),n=a.distanceKm*1e3,i=n*Math.cos(a.altitudeDeg*D.DEG);return{eastM:i*Math.sin(a.azimuthDeg*D.DEG),northM:i*Math.cos(a.azimuthDeg*D.DEG),upM:n*Math.sin(a.altitudeDeg*D.DEG),altitudeDeg:a.altitudeDeg,distanceKm:a.distanceKm}}static segments(t){const e=[];let a=[];for(const n of t.points){const i=a[a.length-1];i&&n.t-i.t>F.MAX_GAP_S*1e3&&(e.push(a),a=[]),a.push(n)}return e.push(a),e.filter(n=>n.length>=2)}static bearingDeg(t,e){return(Math.atan2(e.eastM-t.eastM,e.northM-t.northM)/D.DEG+360)%360}}class Nt{constructor(t,e,a,n,i){this.tracks=t,this.observer=e,this.startMs=a,this.maxObjects=n,this.options=i}build(){const t=[];for(const a of this.tracks){const n=D.keyOf(a),i=this.options.models?.get(n)??k.of(void 0);D.segments(a).forEach((o,s)=>{const r=o.map(h=>({point:h,at:D.offsetOf(this.observer,h)}));if(!r.some(h=>h.at.altitudeDeg>=0))return;const u=r.map((h,p)=>({t:h.point.t-this.startMs,eastM:h.at.eastM,northM:h.at.northM,altitudeM:h.at.upM,headingDeg:h.point.trackDeg??(p+1<r.length?D.bearingDeg(h.at,r[p+1].at):D.bearingDeg(r[p-1].at,h.at))})),c=D.idOf(a,s),d=r[Math.floor(r.length/2)].point,l=this.options.sunElevationAt?.(d)??90;t.push({object:{id:c,kind:"aircraft",eastM:u[0].eastM,northM:u[0].northM,headingDeg:u[0].headingDeg,sizeM:D.sizeOf(i),model:U.idOf(i.code)?{id:U.idOf(i.code)}:void 0,color:P.bodyColor(i),lights:P.lights(i,l),track:u},presence:{fromMs:u[0].t,untilMs:u[u.length-1].t},flight:{icao:a.icao,nonIcao:a.nonIcao,points:o},closestKm:Math.min(...r.map(h=>h.at.distanceKm))})})}t.sort((a,n)=>a.closestKm-n.closestKm);const e=t.slice(0,this.maxObjects);return{objects:e.map(a=>a.object),presence:new Map(e.map(a=>[a.object.id,a.presence])),flights:new Map(e.map(a=>[a.object.id,a.flight])),total:t.length,shown:e.length}}}const ct=[{id:"turbofan-narrow-body",name:"Turbofan airliner, narrow-body",kinds:["airliner-narrow"],totalDbA:148,shapeDb:[-32,-17,-9,-6,-5,-7,-12,-22],character:{toneHz:1800,toneShare:.3,humHz:90,humShare:.7}},{id:"turbofan-wide-body",name:"Turbofan airliner, wide-body",kinds:["airliner-wide"],totalDbA:151,shapeDb:[-28,-14,-7,-4,-3,-6,-12,-22],character:{toneHz:1200,toneShare:.3,humHz:70,humShare:.7}},{id:"regional-jet",name:"Regional jet",kinds:["regional-jet"],totalDbA:144,shapeDb:[-32,-17,-9,-5,-4,-6,-11,-21],character:{toneHz:1900,toneShare:.3,humHz:95,humShare:.7}},{id:"business-jet",name:"Business jet",kinds:["business-jet"],totalDbA:141,shapeDb:[-30,-15,-8,-4,-3,-4,-9,-19],character:{toneHz:2500,toneShare:.25,humHz:110,humShare:.7}},{id:"turboprop",name:"Turboprop",kinds:["regional-turboprop","turboprop-light"],totalDbA:138,shapeDb:[-14,-9,-8,-6,-8,-13,-20,-28],character:{toneHz:80,toneShare:.5}},{id:"light-piston",name:"Light piston aircraft",kinds:["light-piston"],totalDbA:130,shapeDb:[-18,-9,-5,-4,-8,-14,-22,-30],character:{toneHz:80,toneShare:.4}},{id:"ultralight",name:"Ultralight",kinds:["ultralight"],totalDbA:124,shapeDb:[-16,-8,-5,-4,-9,-15,-23,-31],character:{toneHz:140,toneShare:.4}},{id:"helicopter-light",name:"Light helicopter",kinds:["helicopter-light"],totalDbA:134,shapeDb:[-15,-8,-4,-3,-6,-10,-16,-24],character:{modulationHz:20,modulationDepth:.5}},{id:"helicopter-medium",name:"Medium helicopter",kinds:["helicopter-medium"],totalDbA:138,shapeDb:[-14,-7,-4,-3,-6,-10,-16,-24],character:{modulationHz:22,modulationDepth:.5}},{id:"helicopter-heavy",name:"Heavy helicopter",kinds:["helicopter-heavy"],totalDbA:144,shapeDb:[-12,-6,-4,-4,-7,-11,-17,-25],character:{modulationHz:17,modulationDepth:.5}},{id:"military-jet",name:"Military jet",kinds:["military-jet"],totalDbA:152,shapeDb:[-26,-12,-6,-3,-2,-3,-7,-15]},{id:"glider",name:"Glider",kinds:["glider"],totalDbA:85,shapeDb:[-30,-22,-15,-10,-8,-8,-14,-22]},{id:"balloon",name:"Hot-air balloon",kinds:["balloon"],totalDbA:100,shapeDb:[-25,-15,-9,-5,-3,-6,-12,-20]},{id:"unmanned",name:"Unmanned aircraft",kinds:["unmanned"],totalDbA:88,shapeDb:[-40,-30,-20,-12,-6,-3,-3,-8],character:{toneHz:450,toneShare:1}}],ot=ct.map(w=>({id:w.id,name:w.name,soundPowerA:w.shapeDb.map(t=>t+w.totalDbA-E.sumDb(w.shapeDb)),character:w.character}));class m{static DEFAULT_AMBIENT_DB_A=35;static DETECTION_MARGIN_DB=3;static AMBIENT_SHAPE_DB=[-12,-7,-5,-5,-7,-11,-17,-25];static HEARING_FLOOR_DB_A=0;static ITERATIONS=30;static CONVERGED_MS=.5;static VELOCITY_STEP_MS=500;static noiseOfKind(t){const e=ct.find(a=>a.kinds.includes(t));return ot.find(a=>a.id===(e?.id??"turbofan-narrow-body"))}static bandsAt(t,e,a=E.STANDARD){const n=20*Math.log10(Math.max(e*1e3,1))+11;return E.OCTAVES.map((i,o)=>t.soundPowerA[o]-n-E.absorptionDbPerKm(i,a)*e)}static couldBeHeard(t,e,a=m.DEFAULT_AMBIENT_DB_A,n=E.STANDARD){const i=m.ambientBands(a);return m.bandsAt(t,e,n).some((o,s)=>o>=Math.max(i[s]+m.DETECTION_MARGIN_DB,m.HEARING_FLOOR_DB_A))}static ambientBands(t){const e=m.AMBIENT_SHAPE_DB,a=E.sumDb(e);return e.map(n=>t+n-a)}static heardAt(t,e,a,n={}){const i=n.air??E.STANDARD,o=E.speedOfSound(i.temperatureC),s=t.points[t.points.length-1]?.t;if(s===void 0)return;let r=Math.min(a,s),u=F.positionAt(t,r);if(!u)return;let c=L.seenFrom(e,u.geo);for(let f=0;f<m.ITERATIONS;f++){const I=a-c.distanceKm*1e3*1e3/o,j=Math.abs(I-r);if(r=I,u=F.positionAt(t,r),!u)return;if(c=L.seenFrom(e,u.geo),j<m.CONVERGED_MS)break}const d=F.positionAt(t,a),l=d?L.seenFrom(e,d.geo):c,h=n.noise??ot[0],p=n.ambientDbA??m.DEFAULT_AMBIENT_DB_A,g=m.ambientBands(p),M=m.bandsAt(h,c.distanceKm,i),b=M.map((f,I)=>f>=Math.max(g[I]+m.DETECTION_MARGIN_DB,m.HEARING_FLOOR_DB_A)),R=M.indexOf(Math.max(...M)),S=b.lastIndexOf(!0);return{track:t,audible:b.some(Boolean),levelDbA:E.sumDb(M),bandsDbA:M,ambientDbA:p,delayS:(a-r)/1e3,emittedAtMs:r,sound:c,seen:l,lagDeg:m.angleBetween(c,l),dopplerRatio:m.doppler(t,e,r,o),dominantHz:E.OCTAVES[R],cutoffHz:S<0?void 0:E.OCTAVES[S]}}static profile(t,e,a,n,i=2e3,o={}){const s=[];let r,u,c=a;for(let d=a;d<=n;d+=i){const l=m.heardAt(t,e,d,o);l&&(!u||l.levelDbA>u.levelDbA)&&(u=l,c=d),l?.audible?r?r.untilMs=d:s.push(r={fromMs:d,untilMs:d}):r=void 0}return{track:t,audible:s,peakDbA:u?.levelDbA??-1/0,peakAtMs:c,peakDelayS:u?.delayS??0}}static angleBetween(t,e){const a=c=>{const d=c.altitudeDeg*Math.PI/180,l=c.azimuthDeg*Math.PI/180;return[Math.cos(d)*Math.sin(l),Math.cos(d)*Math.cos(l),Math.sin(d)]},[n,i,o]=a(t),[s,r,u]=a(e);return Math.acos(Math.min(1,Math.max(-1,n*s+i*r+o*u)))*180/Math.PI}static doppler(t,e,a,n){const i=m.VELOCITY_STEP_MS,o=F.positionAt(t,a-i),s=F.positionAt(t,a+i);if(!o||!s)return 1;const r=L.seenFrom(e,o.geo).distanceKm*1e3,u=L.seenFrom(e,s.geo).distanceKm*1e3;return 1/(1-(r-u)/(2*i/1e3)/n)}}class wt{static at(t,e,a,n,i={}){const o=F.seenFrom(t,a,n);if(!o)return;const s=k.of(e),r=m.heardAt(t,a,n,{noise:m.noiseOfKind(s.kind),...i});return{hex:`${t.nonIcao?"~":""}${t.icao.toString(16).padStart(6,"0")}`,registration:e?.registration,typeCode:s.code??e?.type,name:s.basis==="nothing"?void 0:s.name,kind:s.kind,basis:s.basis,military:e?.military===!0,restricted:e?.restricted===!0,altitudeFt:o.altitudeFt,groundSpeedKt:o.groundSpeedKt,trackDeg:o.trackDeg,sky:o.sky,angularRateDegPerS:o.angularRateDegPerS,hearing:r&&{audible:r.audible,levelDbA:r.levelDbA,ambientDbA:r.ambientDbA,delayS:r.delayS,lagDeg:r.lagDeg,dopplerRatio:r.dopplerRatio,cutoffHz:r.cutoffHz,dominantHz:r.dominantHz}}}}class O{static REFERENCE_AMPLITUDE=.02;static MASKING_RANGE_DB=6;static KNEE_DB=20;static COMPRESSION_RATIO=1.5;static EXPANSION_RATIO=1.8;static DEFAULT_MAX_VOICES=4;static candidates(t,e,a,n,i={}){const o=new Set;for(const[s,r]of t){const u=m.noiseOfKind(k.of(e.get(a(r))).kind);let c=1/0;for(const d of r.points)c=Math.min(c,L.seenFrom(n,{lat:d.lat,lng:d.lng,heightM:d.altitudeFt*.3048}).distanceKm);m.couldBeHeard(u,c,i.ambientDbA,i.air)&&o.add(s)}return o}static voices(t,e,a,n,i,o,s={}){const r=[];for(const u of t){const c=e.get(u);if(!c||s.only?.(u)===!1)continue;const d=s.kindOf?.(u)??k.of(a.get(n(c))).kind,l=s.noiseOf?.(u)??m.noiseOfKind(d),h=m.heardAt(c,i,o,{...s,noise:l});h?.audible&&r.push({id:u,kind:d,bandAmplitudes:O.bandAmplitudes(h.bandsDbA,h.ambientDbA,s.referenceAmplitude),levelDbA:h.levelDbA,distanceKm:h.sound.distanceKm,dopplerRatio:h.dopplerRatio,azimuthDeg:h.sound.azimuthDeg,elevationDeg:h.sound.altitudeDeg,character:l.character})}return r.sort((u,c)=>c.levelDbA-u.levelDbA).slice(0,s.maxVoices??O.DEFAULT_MAX_VOICES)}static bandAmplitudes(t,e,a=O.REFERENCE_AMPLITUDE){const n=m.ambientBands(e),i=m.DETECTION_MARGIN_DB,o=E.sumDb(t),s=o-e,r=s>=O.KNEE_DB?O.KNEE_DB+(s-O.KNEE_DB)/O.COMPRESSION_RATIO:O.KNEE_DB-(O.KNEE_DB-s)*O.EXPANSION_RATIO,u=a*10**(r/20);return t.map((c,d)=>{const l=Math.min(1,Math.max(0,(c-n[d]-i+O.MASKING_RANGE_DB)/(2*O.MASKING_RANGE_DB)));return l*l*(3-2*l)*u*10**((c-o)/20)})}static BANDS_HZ=E.OCTAVES}class W{static ENGLISH={unnamed:"Aircraft {hex}",altitude:"{value} ft",speed:"{value} kt",heading:"heading {value}°",position:"{distance} km away, {elevation}° above the horizon, {bearing}",heard:"Heard at {level} dB(A), left the aircraft {delay} s ago, {lag}° behind it: {character}{pitch}",rumble:"a low rumble, nothing above {cutoff} Hz",muffled:"a dull noise, nothing above {cutoff} Hz",broad:"a broad roar",pitchHigher:", pitch {percent} % higher",pitchLower:", pitch {percent} % lower",inaudible:"Not audible here: {level} dB(A) against {ambient} dB(A) of ambient noise",soundUnknown:"Its sound cannot be worked out: the aircraft was not recorded yet when it left",contrailPersistent:"Leaves a trail that lasts: the air is supersaturated over ice ({rhi} % over ice)",contrailShort:"Leaves a short-lived trail: the air is dry over ice ({rhi} % over ice)",military:"military",restricted:"identity withheld by its owner",candidate:"A compatible candidate, not an identification"};static RUMBLE_BELOW_HZ=500;static DULL_BELOW_HZ=2e3;static PITCH_NOTICED=.03;static text(t,e,a,n){const i=(l,h=0)=>l.toLocaleString(n,{maximumFractionDigits:h}),o=(l,h)=>l.replace(/\{(\w+)\}/g,(p,g)=>h[g]??`{${g}}`),s=[],r=[t.registration,t.name].filter(Boolean).join(" · ");s.push(r||o(e.unnamed,{hex:t.hex}));const u=[o(e.altitude,{value:i(Math.round(t.altitudeFt/100)*100)}),t.groundSpeedKt===void 0?void 0:o(e.speed,{value:i(Math.round(t.groundSpeedKt))}),t.trackDeg===void 0?void 0:o(e.heading,{value:i(Math.round(t.trackDeg))})].filter(Boolean);s.push(u.join(" · ")),s.push(o(e.position,{distance:i(t.sky.distanceKm,t.sky.distanceKm<10?1:0),elevation:i(Math.round(t.sky.altitudeDeg)),bearing:a(t.sky.azimuthDeg)}));const c=t.hearing;if(!c)s.push(e.soundUnknown);else if(!c.audible)s.push(o(e.inaudible,{level:i(Math.round(c.levelDbA)),ambient:i(Math.round(c.ambientDbA))}));else{const l=c.cutoffHz??0,h=l<=W.RUMBLE_BELOW_HZ?e.rumble:l<=W.DULL_BELOW_HZ?e.muffled:e.broad,p=c.dopplerRatio-1,g=Math.abs(p)<W.PITCH_NOTICED?"":o(p>0?e.pitchHigher:e.pitchLower,{percent:i(Math.round(Math.abs(p)*100))});s.push(o(e.heard,{level:i(Math.round(c.levelDbA)),delay:i(Math.round(c.delayS)),lag:i(Math.round(c.lagDeg)),character:o(h,{cutoff:i(l)}),pitch:g}))}t.contrail&&s.push(o(t.contrail.persistent?e.contrailPersistent:e.contrailShort,{rhi:i(Math.round(t.contrail.iceRelativeHumidity*100))}));const d=[t.military?e.military:void 0,t.restricted?e.restricted:void 0].filter(Boolean);return d.length>0&&s.push(d.join(" · ")),s.push(e.candidate),s.join(`
|
|
2
|
+
`)}}class ${static EFFICIENCY={"airliner-narrow":.34,"airliner-wide":.38,"regional-jet":.32,"business-jet":.3,"military-jet":.22,unknown:.34};static efficiencyOf(t){return $.EFFICIENCY[t]}}class A{static EMISSION_INDEX_WATER=1.25;static COMBUSTION_HEAT=432e5;static AIR_HEAT_CAPACITY=1004;static MOLAR_MASS_RATIO=.622;static FT_TO_M=.3048;static TROPOPAUSE_M=11e3;static TROPOPAUSE_HPA=226.32;static ISOTHERMAL_SCALE_HEIGHT_M=6341.62;static pressureAtAltitudeFt(t){const e=t*A.FT_TO_M;return e<=A.TROPOPAUSE_M?1013.25*(1-225577e-10*e)**5.25588:A.TROPOPAUSE_HPA*Math.exp(-(e-A.TROPOPAUSE_M)/A.ISOTHERMAL_SCALE_HEIGHT_M)}static saturationOverWaterPa(t){const e=t+273.15;return Math.exp(54.842763-6763.22/e-4.21*Math.log(e)+367e-6*e+Math.tanh(.0415*(e-218.8))*(53.878-1331.22/e-9.44523*Math.log(e)+.014025*e))}static saturationOverIcePa(t){const e=t+273.15;return Math.exp(9.550426-5723.265/e+3.53068*Math.log(e)-.00728332*e)}static iceRelativeHumidity(t,e){return e*A.saturationOverWaterPa(t)/A.saturationOverIcePa(t)}static mixingSlope(t,e){return A.EMISSION_INDEX_WATER*A.AIR_HEAT_CAPACITY*t*100/(A.MOLAR_MASS_RATIO*A.COMBUSTION_HEAT*(1-e))}static criticalTemperatureC(t,e){const a=Math.log(A.mixingSlope(t,e)-.053);return-46.46+9.43*a+.72*a*a}static requiredHumidity(t,e,a){const n=A.criticalTemperatureC(t,e);return(A.mixingSlope(t,e)*(a-n)+A.saturationOverWaterPa(n))/A.saturationOverWaterPa(a)}static evaluate(t,e){const a=A.criticalTemperatureC(t.pressureHpa,e),n=A.requiredHumidity(t.pressureHpa,e,t.temperatureC),i=A.iceRelativeHumidity(t.temperatureC,t.relativeHumidity),o=t.temperatureC<a&&t.relativeHumidity>=n;return{forms:o,persistent:o&&i>=1,criticalTemperatureC:a,requiredHumidity:n,iceRelativeHumidity:i}}}class C{static HOLD_MS=36e5;static DEG=Math.PI/180;static GAS_CONSTANT_OVER_GRAVITY=287.05/9.80665;static at(t,e,a){if(t.length===0)return;const n=t[0],i=t[t.length-1];if(e<n.t-C.HOLD_MS||e>i.t+C.HOLD_MS)return;const o=t.findIndex(h=>h.t>e),s=o===0?t[0]:t[(o===-1?t.length:o)-1],r=o===-1||o===0?s:t[o],u=C.atLevel(s,a),c=C.atLevel(r,a);if(!u||!c)return;const d=r.t>s.t?Math.min(1,Math.max(0,(e-s.t)/(r.t-s.t))):0,l=(h,p)=>h+(p-h)*d;return{pressureHpa:a,temperatureC:l(u.temperatureC,c.temperatureC),relativeHumidity:l(u.relativeHumidity,c.relativeHumidity),driftEastMs:l(u.driftEastMs,c.driftEastMs),driftNorthMs:l(u.driftNorthMs,c.driftNorthMs),shearPerS:l(u.shearPerS,c.shearPerS)}}static atLevel(t,e){const a=t.levels;for(let n=0;n+1<a.length;n++){const i=a[n],o=a[n+1];if(e>i.pressureHpa||e<o.pressureHpa)continue;const s=(Math.log(i.pressureHpa)-Math.log(e))/(Math.log(i.pressureHpa)-Math.log(o.pressureHpa)),r=(h,p)=>h+(p-h)*s,u=h=>{const p=h.windFromDeg*C.DEG;return{east:-h.windSpeedMs*Math.sin(p),north:-h.windSpeedMs*Math.cos(p)}},c=u(i),d=u(o),l=C.GAS_CONSTANT_OVER_GRAVITY*((i.temperatureC+o.temperatureC)/2+273.15)*Math.log(i.pressureHpa/o.pressureHpa);return{pressureHpa:e,temperatureC:r(i.temperatureC,o.temperatureC),relativeHumidity:r(i.relativeHumidity,o.relativeHumidity),driftEastMs:r(c.east,d.east),driftNorthMs:r(c.north,d.north),shearPerS:Math.hypot(d.east-c.east,d.north-c.north)/l}}}}class H{static MIN_ALTITUDE_FT=2e4;static DENSE_MS=3e5;static SPARSE_STEP_MS=6e4;static SATURATION_HORIZON_MS=3*36e5;static SATURATION_STEP_MS=6e5;static PRESSURE_STEP_HPA=5;static plan(t,e,a,n){if(a.length===0)return[];const i=[],o=new Map,s=(r,u,c)=>{const d=Math.round(u/H.PRESSURE_STEP_HPA)*H.PRESSURE_STEP_HPA,l=H.SATURATION_STEP_MS,h=Math.floor(r/l)*l,p=`${d}|${h}`,g=o.get(p);if(g!==void 0)return g+(h-r)/1e3;let M=1/0;for(let b=l;b<=H.SATURATION_HORIZON_MS;b+=l){const R=C.at(a,h+b,d);if(!R)break;if(A.evaluate(R,c).iceRelativeHumidity<1){M=b/1e3;break}}return o.set(p,M),M+(h-r)/1e3};for(const r of t.objects){const u=t.flights.get(r.id),c=r.track;if(!u||!c||c.length!==u.points.length)continue;const d=e?.get(z.keyOf(u))??k.of(void 0),l=$.efficiencyOf(d.kind);if(l===void 0)continue;const h=[];let p=-1/0;c.forEach((g,M)=>{if(g.t<-H.DENSE_MS&&M+1<c.length&&g.t-p<H.SPARSE_STEP_MS)return;p=g.t;const b=u.points[M],R=A.pressureAtAltitudeFt(b.altitudeFt),S=C.at(a,n+g.t,R),f=S&&A.evaluate(S,l);h.push({tMs:g.t,eastM:g.eastM,northM:g.northM,upM:g.altitudeM??0,forms:f?.forms??!1,persistent:f?.persistent??!1,lifetimeS:f?Z.lifetimeS(f.iceRelativeHumidity):0,driftEastMs:S?.driftEastMs??0,driftNorthMs:S?.driftNorthMs??0,shearPerS:S?.shearPerS??Z.TYPICAL_SHEAR_PER_S,iceRelativeHumidity:f?.iceRelativeHumidity??0,saturatedForS:f?.persistent?s(n+g.t,R,l):0})}),h.some((g,M)=>g.forms&&h[M+1]?.forms)&&i.push({id:r.id,spanM:d.spanM,points:h})}return i}}class T{static DEFAULT_KIND="airliner-narrow";static STEP_MS=1e3;static LEAD_MS=12e4;static FT_PER_M=1/.3048;static ID_PREFIX="decor:";tracks=new Map;static kindOf(t,e){if(t.kind!=="aircraft"||!T.flies(t))return;const a=t.aircraftSound??e??T.DEFAULT_KIND;return a==="silent"?void 0:a}static flies(t){return(t.track??[]).some(e=>(e.altitudeM??0)>0)}voices(t,e,a,n={},i=()=>{}){const o=t.event.place?.[0];if(!o)return[];const s=new Map,r=new Map,u=Math.max(t.observerTrack.duration,(t.event.durationSeconds??0)*1e3);for(const c of t.decor){const d=T.kindOf(c,i(c));if(!d)continue;const l=`${T.ID_PREFIX}${c.id}`;s.set(l,this.trackOf(c,l,o,u)),r.set(l,d)}for(const c of this.tracks.keys())s.has(c)||this.tracks.delete(c);return s.size===0?[]:O.voices(new Set(s.keys()),s,new Map,c=>String(c.icao),a,e,{...n,kindOf:c=>r.get(c)})}trackOf(t,e,a,n){const i=JSON.stringify([t.track,t.eastM,t.northM,t.headingDeg,a.lat,a.lng,n]),o=this.tracks.get(e);if(o?.key===i)return o.track;const s=[];for(let l=0;l<=n;l+=T.STEP_MS)s.push(T.pointAt(t,l,a));(s.length===0||s[s.length-1].t<n)&&s.push(T.pointAt(t,n,a));const r=s[0],u=s[1]??r,c=l=>(u[l]-r[l])/(u.t-r.t||1);for(let l=T.STEP_MS*10;l<=T.LEAD_MS;l+=T.STEP_MS*10)s.unshift({t:-l,lat:r.lat-c("lat")*l,lng:r.lng-c("lng")*l,altitudeFt:Math.max(0,r.altitudeFt-c("altitudeFt")*l)});const d={icao:T.hash(e),nonIcao:!0,points:s};return this.tracks.set(e,{key:i,track:d}),d}static pointAt(t,e,a){const n=ut(t,e),i=q(n.eastM,-n.northM,a.lat,a.lng);return{t:e,lat:i.lat,lng:i.lng,altitudeFt:n.altitudeM*T.FT_PER_M}}static hash(t){let e=0;for(let a=0;a<t.length;a++)e=e*31+t.charCodeAt(a)>>>0;return e}}class G{static STEP_MS=250;static FT_PER_M=1/.3048;static ID_PREFIX="body:";tracks=new Map;static noiseOf(t){const e=m.noiseOfKind(t.kind),a=t.quieterDb??0;return a===0?e:{...e,id:`${e.id}-${a}dB`,soundPowerA:e.soundPowerA.map(n=>n-a)}}voices(t,e,a,n,i,o,s={}){const r=new Map,u=new Map,c=new Map;for(const l of t){if(!l.sound)continue;const h=`${G.ID_PREFIX}${l.id}`,p=this.trackOf(l,h,e,n,o);p&&(r.set(h,p),u.set(h,l.sound.kind),c.set(h,G.noiseOf(l.sound)))}for(const l of this.tracks.keys())r.has(l)||this.tracks.delete(l);if(r.size===0)return[];const d=q(a.eastM,-a.northM,n.lat,n.lng);return O.voices(new Set(r.keys()),r,new Map,l=>String(l.icao),{lat:d.lat,lng:d.lng,heightM:a.upM},i,{...s,kindOf:l=>u.get(l),noiseOf:l=>c.get(l)})}trackOf(t,e,a,n,i){const o=`${n.lat},${n.lng},${i}`,s=this.tracks.get(e);if(s&&s.body===t&&s.origin===o)return s.track;const r=[];for(let c=-12e4;c<=i;c+=G.STEP_MS){const d=a(t,c);if(!d)continue;const l=q(d.eastM,-d.northM,n.lat,n.lng);r.push({t:c,lat:l.lat,lng:l.lng,altitudeFt:d.upM*G.FT_PER_M})}if(r.length<2)return;const u={icao:G.hash(e),nonIcao:!0,points:r};return this.tracks.set(e,{body:t,origin:o,track:u}),u}static hash(t){let e=0;for(let a=0;a<t.length;a++)e=e*31+t.charCodeAt(a)>>>0;return e}}export{Y as AircraftAudio,H as AircraftContrails,k as AircraftModels,_ as AmbientNoise,G as BodyHearing,T as DecorAircraftHearing,D as TrafficDecor,wt as TrafficInfos,O as TrafficSound,W as TrafficTooltip,Ht as UPPER_AIR_SOURCES};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rr0/ufoathome",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.146.0",
|
|
5
5
|
"description": "UFO@home — record and replay a UFO sighting's shape, movement and appearance",
|
|
6
6
|
"author": "Jérôme Beau <rr0@rr0.org> (https://rr0.org)",
|
|
7
7
|
"license": "MIT",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const e={color:"Color",transparency:"Transparencia",halo:"Halo",blur:"Desenfoque",brightness:"Brillo",shapeTitle:"Nombre",utcOffset:"Zona horaria",cloudBase:"Base de las nubes",elevation:"Altitud",heightAboveGround:"Altura sobre el suelo",duration:"Duración",placeName:"Lugar",latitude:"Latitud",longitude:"Longitud",heading:"Orientación",pitch:"Inclinación",roll:"Alabeo",sway:"Vaivén en reposo",swayTitle:"Cuánto mueve la vista el cuerpo que sostiene el instrumento cuando no camina: 1 para una persona de pie, 0 para un trípode. Vacío: 1 (0 si el relato dice que el observador estaba paralizado)",referenceGhosts:"Reflejos en la foto",referenceFindGhosts:"Buscar reflejos",referenceGhostsSearching:"Buscando…",referenceGhostsFound:"{count} reflejos encontrados, cada uno al otro lado de su luz respecto al eje del objetivo.",referenceGhostsFoundScaled:"{count} reflejos encontrados, cada uno a {scale} veces la distancia de su luz al eje del objetivo.",referenceGhostsLow:"Quizá {count} reflejo(s): demasiado pocos para estar seguro.",referenceGhostsNone:"Ningún reflejo encontrado: ninguna mancha débil está al otro lado de una luz respecto a un mismo punto.",referenceGhostsCropped:"El eje del objetivo está desplazado del centro de la imagen: la foto fue recortada.",lensGlass:"A través de",lensGlassNone:"el objetivo solo",lensGlassFilter:"un filtro en el objetivo",lensGlassWindow:"una ventana",lensGlassWindscreen:"un parabrisas",lensDrops:"Gotas en el cristal",lensDropsTitle:"0 a 1: qué parte del cristal exterior cubren las gotas de agua. Vacío: según la lluvia o la nieve que cae, salvo si el cristal está a cubierto",lensCondensation:"Vaho",lensCondensationTitle:"0 a 1: vaho en el cristal, como en un objetivo que pasa del calor al frío. Vacío: ninguno",lensDirt:"Suciedad",lensDirtTitle:"0 a 1: suciedad, grasa o huellas en el cristal. Vacío: ninguna",lensSheltered:"A cubierto de la lluvia",lensShelteredTitle:"El cristal exterior estaba fuera de la lluvia o la nieve: bajo un techo, o tras un parabrisas con los limpiaparabrisas en marcha",lightPollution:"Cielo nocturno",lightPollutionTitle:"El cenit de una noche sin Luna en este lugar, en magnitudes por segundo de arco cuadrado, tal como lo lee un Sky Quality Meter o lo da el atlas mundial del brillo artificial del cielo (Falchi et al. 2016, lightpollutionmap.info, «SQM»). 22 es un cielo natural; un suburbio ronda 19, el centro de una ciudad 17. Vacío: un cielo natural",observationTime:"Inicio de la observación",observationEndTime:"Fin de la observación",assessmentGroup:"Evaluación",assessmentNames:{coverage:"Datos del observador"},assessmentVerdicts:{"hynek.nl":"NL — luz nocturna","hynek.dd":"DD — disco diurno","hynek.rv":"RV — radar-visual","hynek.ce1":"EC1 — encuentro cercano","hynek.ce2":"EC2 — con huella física","hynek.ce3":"EC3 — con entidades"},timeQualifierApproximate:"Aproximada",timeQualifierUncertain:"Incierta",timeQualifierBoth:"Incierta y aproximada",timeSeasonSpring:"Primavera",timeSeasonSummer:"Verano",timeSeasonAutumn:"Otoño",timeSeasonWinter:"Invierno",summaryGroups:{observation:"Observación",location:"Posición",temporal:"Tiempo",weather:"Clima",sound:"Sonido"},summaryGroup:"Resumen",summaryDescription:"Descripción",closeDescription:"Cerrar la descripción",observerGroup:"Observador",observerId:"ID",observerTitle:"Tratamiento",observerLastName:"Apellidos",observerFirstNames:"Nombres",sightingId:"ID",tags:"Etiquetas",cloudCover:"Nubosidad",highCloudCover:"Nubes de hielo (cirros)",focalLength:"Distancia focal",fieldOfView:"Campo de visión",aperture:"Apertura",exposure:"Exposición",focusDistance:"Enfocado a",iceCrystalAlignment:"Alineación de los cristales",rareIceCrystals:"Cristales raros",cloudDarkness:"Oscuridad de las nubes",precipitationType:"Precipitación",precipitationNone:"Ninguna",precipitationRain:"Lluvia",precipitationSnow:"Nieve",precipitationHail:"Granizo",precipitationIntensity:"Intensidad",windDirection:"Dirección del viento",windSpeed:"Velocidad del viento",storm:"Tormenta",cloudsGroup:"Nubes",precipitationGroup:"Precipitación",windGroup:"Viento",soundKind:"Sonido",soundNone:"Ninguno (silencioso)",soundHum:"Zumbido",soundWhistle:"Silbido",soundRumble:"Retumbo",soundCrackle:"Crepitación",soundVolume:"Volumen",soundPitch:"Tono",soundSrc:"Grabación",instrument:"Observado con",filter:"Delante",filterNone:"nada",filterSolarVisual:"un filtro solar para el ojo (gafas de eclipse, densidad 5)",filterSolarPhoto:"una película solar para cámara (densidad 3,8)",decorAircraft:"Aeronave",decorEntity:"Ser",decorAltitude:"Altitud",decorLights:"Luces",decorLightsNone:"ninguna",decor:"Entorno",decorBuilding:"Edificio",decorTree:"Árbol",decorShrub:"Arbusto",decorBridge:"Puente",decorWire:"Línea aérea",decorCrop:"Hilera de cultivo",decorTerrace:"Bancal (terraza)",decorMound:"Montón de piedras",decorWall:"Muro de piedra seca",decorStreetlight:"Farola",decorTrafficLight:"Semáforo",decorCrossing:"Paso de peatones",decorRoadSign:"Señal de tráfico",decorVehicle:"Vehículo",decorObserver:"Otro observador",decorEast:"Distancia al este",decorNorth:"Distancia al norte",decorHeading:"Orientación",decorColor:"Color",decorLit:"Encendido",decorTitle:"Nombre",milestones:"Momentos",milestoneLabel:"Etiqueta",milestoneNote:"Qué ocurre",addMilestone:"Nombrar este momento",deleteMilestone:"Eliminar momento",goToMilestone:"Ir a este momento",decorWidth:"Anchura",decorLength:"Longitud",decorHeight:"Altura",decorModel:"Modelo 3D",decorModelAdvanced:"Modelo desde una dirección",decorModelUrl:"Dirección glTF/GLB",decorModelTitle:"Nombre del modelo",decorModelAuthor:"Autor",decorModelLicense:"Licencia",decorModelSource:"Procedencia",decorObserverSide:"Ubicación del observador",decorObserverSideNone:"No presente",decorSideFront:"Delante",decorSideBehind:"Detrás",decorSideLeft:"Izquierda",decorSideRight:"Derecha",decorSideFrontLeft:"Delante a la izquierda",decorSideFrontRight:"Delante a la derecha",decorSideBehindLeft:"Detrás a la izquierda",decorSideBehindRight:"Detrás a la derecha"},o={...e,accountBy:"Relato de",unnamedObserver:"Observador {n}",about:"Acerca de",close:"Cerrar",observation:"Observación",date:"Fecha",location:"Lugar",case:"Caso",description:"Descripción",source:"Fuente",basis:{measured:"medido",stated:"declarado",derived:"deducido",assumed:"supuesto"},credits:"Créditos",editThisObservation:"Editar esta observación",share:"Compartir",embedObservation:"Insertar la observación",back:"Volver",shareScope:"Compartir",shareScopeCase:"El caso entero",shareOpensOn:"Se abre en",shareStartAt:"Empezar en",shareOptionLabels:"Mostrar los chips",shareOptionMap:"Abrir el mapa",shareOptionMilestones:"Mostrar los momentos",shareOptionCompare:"Comparar con el relato",showLabels:"Mostrar lo que indica",interpretation:"Interpretación",account:"Relato",interpretationBy:"{title}, por {by}",confrontation:"Frente al relato",confrontationDirection:"desvío de {deg}°",confrontationWidth:"anchura ×{ratio}",confrontationHeight:"altura ×{ratio}",showComparison:"Comparar con el relato",hideComparison:"Dejar de comparar con el relato",hideLabels:"Ocultar lo que indica",variant:"Variante: {name}",verdicts:{consolidated:"compatible con sesgos consolidados",contested:"solo invocando sesgos discutidos",incompatible:"incompatible incluso en los límites"},variantFields:{time:"Hora",heading:"Dirección",elevation:"Altura",size:"Tamaño",duration:"Duración",sweep:"Recorrido en el cielo"},variantReadings:{grouped:"luces leídas como un solo cuerpo","still-seen-moving":"una luz fija vista en movimiento","moving-seen-still":"una luz en movimiento vista inmóvil","brightening-as-approach":"un brillo creciente leído como un acercamiento"}};export{o as sightingMessages_es};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const e={color:"Couleur",transparency:"Transparence",halo:"Halo",blur:"Flou",brightness:"Éclat",shapeTitle:"Nom",utcOffset:"Fuseau horaire",cloudBase:"Base des nuages",elevation:"Altitude",heightAboveGround:"Hauteur au-dessus du sol",duration:"Durée",placeName:"Lieu",latitude:"Latitude",longitude:"Longitude",heading:"Orientation",pitch:"Inclinaison",roll:"Roulis",sway:"Bougé au repos",swayTitle:"Combien le corps qui tient l'instrument fait bouger la vue hors de la marche : 1 pour une personne debout, 0 pour un trépied. Vide : 1 (0 si le compte rendu dit l'observateur paralysé)",referenceGhosts:"Reflets dans la photo",referenceFindGhosts:"Chercher les reflets",referenceGhostsSearching:"Recherche…",referenceGhostsFound:"{count} reflets trouvés, chacun à l'opposé de sa lumière par rapport à l'axe de l'objectif.",referenceGhostsFoundScaled:"{count} reflets trouvés, chacun à {scale} fois l'écart de sa lumière à l'axe de l'objectif.",referenceGhostsLow:"Peut-être {count} reflet(s) : trop peu pour être sûr.",referenceGhostsNone:"Aucun reflet trouvé : aucune tache faible n'est à l'opposé d'une lumière par rapport à un même point.",referenceGhostsCropped:"L'axe de l'objectif est décalé du centre de l'image : la photo a été recadrée.",lensGlass:"À travers",lensGlassNone:"l'objectif seul",lensGlassFilter:"un filtre sur l'objectif",lensGlassWindow:"une vitre",lensGlassWindscreen:"un pare-brise",lensDrops:"Gouttes sur le verre",lensDropsTitle:"0 à 1 : quelle part du verre extérieur les gouttes d'eau couvrent. Vide : d'après la pluie ou la neige qui tombe, sauf si le verre est à l'abri",lensCondensation:"Buée",lensCondensationTitle:"0 à 1 : buée sur le verre, comme sur un objectif passé du chaud au froid. Vide : aucune",lensDirt:"Saleté",lensDirtTitle:"0 à 1 : saleté, gras ou traces de doigts sur le verre. Vide : aucune",lensSheltered:"À l'abri de la pluie",lensShelteredTitle:"Le verre extérieur était hors de la pluie ou de la neige : sous un toit, ou derrière un pare-brise dont les essuie-glaces marchent",lightPollution:"Ciel nocturne",lightPollutionTitle:"Le zénith d'une nuit sans Lune en ce lieu, en magnitudes par seconde d'arc carrée, tel qu'un Sky Quality Meter le lit ou que l'atlas mondial de la brillance artificielle du ciel (Falchi et al. 2016, lightpollutionmap.info, « SQM ») le donne. 22 est un ciel naturel ; une banlieue est vers 19, un centre-ville vers 17. Vide : un ciel naturel",observationTime:"Début de l'observation",observationEndTime:"Fin de l'observation",assessmentGroup:"Évaluation",assessmentNames:{coverage:"Infos de l'observateur"},assessmentVerdicts:{"hynek.nl":"NL — lumière nocturne","hynek.dd":"DD — disque diurne","hynek.rv":"RV — radar-visuel","hynek.ce1":"RR1 — rencontre rapprochée","hynek.ce2":"RR2 — avec trace physique","hynek.ce3":"RR3 — avec occupants"},timeQualifierApproximate:"Approximative",timeQualifierUncertain:"Incertaine",timeQualifierBoth:"Incertaine et approximative",timeSeasonSpring:"Printemps",timeSeasonSummer:"Été",timeSeasonAutumn:"Automne",timeSeasonWinter:"Hiver",summaryGroups:{observation:"Observation",location:"Position",temporal:"Moment",weather:"Météo",sound:"Son"},summaryGroup:"Résumé",summaryDescription:"Description",closeDescription:"Fermer la description",observerGroup:"Observateur",observerId:"ID",observerTitle:"Titre",observerLastName:"Nom de famille",observerFirstNames:"Prénoms",sightingId:"ID",tags:"Mots-clés",cloudCover:"Couverture nuageuse",highCloudCover:"Nuages de glace (cirrus)",focalLength:"Focale",fieldOfView:"Champ de vision",aperture:"Diaphragme",exposure:"Temps de pose",focusDistance:"Mise au point à",iceCrystalAlignment:"Alignement des cristaux",rareIceCrystals:"Cristaux rares",cloudDarkness:"Obscurité des nuages",precipitationType:"Précipitations",precipitationNone:"Aucune",precipitationRain:"Pluie",precipitationSnow:"Neige",precipitationHail:"Grêle",precipitationIntensity:"Intensité",windDirection:"Direction du vent",windSpeed:"Force du vent",storm:"Orage",cloudsGroup:"Nuages",precipitationGroup:"Précipitations",windGroup:"Vent",soundKind:"Son",soundNone:"Aucun (silencieux)",soundHum:"Bourdonnement",soundWhistle:"Sifflement",soundRumble:"Grondement",soundCrackle:"Crépitement",soundVolume:"Intensité sonore",soundPitch:"Hauteur",soundSrc:"Enregistrement",instrument:"Observé avec",filter:"Devant lui",filterNone:"rien",filterSolarVisual:"un filtre solaire pour l'œil (lunettes d'éclipse, densité 5)",filterSolarPhoto:"un film solaire pour appareil photo (densité 3,8)",decorAircraft:"Aéronef",decorEntity:"Être",decorAltitude:"Altitude",decorLights:"Feux",decorLightsNone:"aucun",decor:"Décor",decorBuilding:"Bâtiment",decorTree:"Arbre",decorShrub:"Buisson",decorBridge:"Pont",decorWire:"Ligne aérienne",decorCrop:"Rang de culture",decorTerrace:"Restanque (terrasse)",decorMound:"Tas de pierres",decorWall:"Muret de pierres sèches",decorStreetlight:"Lampadaire",decorTrafficLight:"Feu de circulation",decorCrossing:"Passage piéton",decorRoadSign:"Panneau de signalisation",decorVehicle:"Véhicule",decorObserver:"Autre observateur",decorEast:"Distance à l'est",decorNorth:"Distance au nord",decorHeading:"Orientation",decorColor:"Couleur",decorLit:"Allumé",decorTitle:"Nom",milestones:"Moments",milestoneLabel:"Repère",milestoneNote:"Ce qui se passe",addMilestone:"Nommer cet instant",deleteMilestone:"Supprimer le moment",goToMilestone:"Aller à ce moment",decorWidth:"Largeur",decorLength:"Longueur",decorHeight:"Hauteur",decorModel:"Modèle 3D",decorModelAdvanced:"Modèle depuis une adresse",decorModelUrl:"Adresse glTF/GLB",decorModelTitle:"Nom du modèle",decorModelAuthor:"Auteur",decorModelLicense:"Licence",decorModelSource:"Provenance",decorObserverSide:"Emplacement de l'observateur",decorObserverSideNone:"Non présent",decorSideFront:"Avant",decorSideBehind:"Arrière",decorSideLeft:"Gauche",decorSideRight:"Droite",decorSideFrontLeft:"Avant-gauche",decorSideFrontRight:"Avant-droit",decorSideBehindLeft:"Arrière-gauche",decorSideBehindRight:"Arrière-droit"},r={...e,accountBy:"Compte rendu de",unnamedObserver:"Observateur {n}",about:"À propos",close:"Fermer",observation:"Observation",date:"Date",location:"Lieu",case:"Dossier",description:"Description",source:"Source",basis:{measured:"mesuré",stated:"énoncé",derived:"déduit",assumed:"supposé"},credits:"Crédits",editThisObservation:"Éditer cette observation",share:"Partager",embedObservation:"Intégrer l'observation",back:"Retour",shareScope:"Partager",shareScopeCase:"Le dossier entier",shareOpensOn:"S'ouvre sur",shareStartAt:"Commencer à",shareOptionLabels:"Afficher les chips",shareOptionMap:"Ouvrir la carte",shareOptionMilestones:"Afficher les moments",shareOptionCompare:"Comparer au compte rendu",showLabels:"Afficher ce qu'elle indique",interpretation:"Interprétation",account:"Compte rendu",interpretationBy:"{title}, par {by}",confrontation:"Face au compte rendu",confrontationDirection:"écart de {deg}°",confrontationWidth:"largeur ×{ratio}",confrontationHeight:"hauteur ×{ratio}",showComparison:"Comparer au compte rendu",hideComparison:"Ne plus comparer au compte rendu",hideLabels:"Masquer ce qu'elle indique",variant:"Variante : {name}",verdicts:{consolidated:"compatible avec des biais consolidés",contested:"seulement en invoquant des biais contestés",incompatible:"incompatible même aux bornes"},variantFields:{time:"Heure",heading:"Direction",elevation:"Hauteur",size:"Taille",duration:"Durée",sweep:"Balayage dans le ciel"},variantReadings:{grouped:"des lumières lues comme un seul corps","still-seen-moving":"une lumière fixe vue en mouvement","moving-seen-still":"une lumière en mouvement vue immobile","brightening-as-approach":"un éclat croissant lu comme un rapprochement"}};export{r as sightingMessages_fr};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const e={color:"Colore",transparency:"Trasparenza",halo:"Alone",blur:"Sfocatura",brightness:"Brillantezza",shapeTitle:"Nome",utcOffset:"Fuso orario",cloudBase:"Base delle nuvole",elevation:"Altitudine",heightAboveGround:"Altezza dal suolo",duration:"Durata",placeName:"Luogo",latitude:"Latitudine",longitude:"Longitudine",heading:"Orientamento",pitch:"Inclinazione",roll:"Rollio",sway:"Oscillazione a riposo",swayTitle:"Quanto il corpo che regge lo strumento muove la vista quando non cammina: 1 per una persona in piedi, 0 per un treppiede. Vuoto: 1 (0 se il resoconto dice che l'osservatore era paralizzato)",referenceGhosts:"Riflessi nella foto",referenceFindGhosts:"Cerca i riflessi",referenceGhostsSearching:"Ricerca…",referenceGhostsFound:"{count} riflessi trovati, ciascuno dalla parte opposta della sua luce rispetto all'asse dell'obiettivo.",referenceGhostsFoundScaled:"{count} riflessi trovati, ciascuno a {scale} volte la distanza della sua luce dall'asse dell'obiettivo.",referenceGhostsLow:"Forse {count} riflesso/i: troppo pochi per esserne sicuri.",referenceGhostsNone:"Nessun riflesso trovato: nessuna macchia debole sta dalla parte opposta di una luce rispetto a uno stesso punto.",referenceGhostsCropped:"L'asse dell'obiettivo è spostato dal centro dell'immagine: la foto è stata ritagliata.",lensGlass:"Attraverso",lensGlassNone:"il solo obiettivo",lensGlassFilter:"un filtro sull'obiettivo",lensGlassWindow:"una finestra",lensGlassWindscreen:"un parabrezza",lensDrops:"Gocce sul vetro",lensDropsTitle:"Da 0 a 1: quanta parte del vetro esterno coprono le gocce d'acqua. Vuoto: secondo la pioggia o la neve che cade, salvo se il vetro è al riparo",lensCondensation:"Condensa",lensCondensationTitle:"Da 0 a 1: condensa sul vetro, come su un obiettivo passato dal caldo al freddo. Vuoto: nessuna",lensDirt:"Sporco",lensDirtTitle:"Da 0 a 1: sporco, unto o impronte sul vetro. Vuoto: nessuno",lensSheltered:"Al riparo dalla pioggia",lensShelteredTitle:"Il vetro esterno era fuori dalla pioggia o dalla neve: sotto un tetto, o dietro un parabrezza con i tergicristalli in funzione",lightPollution:"Cielo notturno",lightPollutionTitle:"Lo zenit di una notte senza Luna in questo luogo, in magnitudini per secondo d'arco quadrato, come lo legge uno Sky Quality Meter o lo dà l'atlante mondiale della brillanza artificiale del cielo (Falchi et al. 2016, lightpollutionmap.info, «SQM»). 22 è un cielo naturale; una periferia è intorno a 19, un centro città a 17. Vuoto: un cielo naturale",observationTime:"Inizio dell'osservazione",observationEndTime:"Fine dell'osservazione",assessmentGroup:"Valutazione",assessmentNames:{coverage:"Dati dell'osservatore"},assessmentVerdicts:{"hynek.nl":"NL — luce notturna","hynek.dd":"DD — disco diurno","hynek.rv":"RV — radar-visivo","hynek.ce1":"IR1 — incontro ravvicinato","hynek.ce2":"IR2 — con traccia fisica","hynek.ce3":"IR3 — con entità"},timeQualifierApproximate:"Approssimativa",timeQualifierUncertain:"Incerta",timeQualifierBoth:"Incerta e approssimativa",timeSeasonSpring:"Primavera",timeSeasonSummer:"Estate",timeSeasonAutumn:"Autunno",timeSeasonWinter:"Inverno",summaryGroups:{observation:"Osservazione",location:"Posizione",temporal:"Tempo",weather:"Meteo",sound:"Suono"},summaryGroup:"Riepilogo",summaryDescription:"Descrizione",closeDescription:"Chiudi la descrizione",observerGroup:"Osservatore",observerId:"ID",observerTitle:"Titolo",observerLastName:"Cognome",observerFirstNames:"Nomi",sightingId:"ID",tags:"Etichette",cloudCover:"Copertura nuvolosa",highCloudCover:"Nubi di ghiaccio (cirri)",focalLength:"Lunghezza focale",fieldOfView:"Campo visivo",aperture:"Apertura",exposure:"Esposizione",focusDistance:"Messa a fuoco a",iceCrystalAlignment:"Allineamento dei cristalli",rareIceCrystals:"Cristalli rari",cloudDarkness:"Oscurità delle nuvole",precipitationType:"Precipitazioni",precipitationNone:"Nessuna",precipitationRain:"Pioggia",precipitationSnow:"Neve",precipitationHail:"Grandine",precipitationIntensity:"Intensità",windDirection:"Direzione del vento",windSpeed:"Velocità del vento",storm:"Temporale",cloudsGroup:"Nuvole",precipitationGroup:"Precipitazioni",windGroup:"Vento",soundKind:"Suono",soundNone:"Nessuno (silenzioso)",soundHum:"Ronzio",soundWhistle:"Fischio",soundRumble:"Rombo",soundCrackle:"Crepitio",soundVolume:"Volume",soundPitch:"Tono",soundSrc:"Registrazione",instrument:"Osservato con",filter:"Davanti",filterNone:"niente",filterSolarVisual:"un filtro solare per l'occhio (occhiali da eclissi, densità 5)",filterSolarPhoto:"una pellicola solare per fotocamera (densità 3,8)",decorAircraft:"Aeromobile",decorEntity:"Essere",decorAltitude:"Altitudine",decorLights:"Luci",decorLightsNone:"nessuna",decor:"Ambiente",decorBuilding:"Edificio",decorTree:"Albero",decorShrub:"Cespuglio",decorBridge:"Ponte",decorWire:"Linea aerea",decorCrop:"Filare di coltura",decorTerrace:"Terrazzamento",decorMound:"Mucchio di pietre",decorWall:"Muretto a secco",decorStreetlight:"Lampione",decorTrafficLight:"Semaforo",decorCrossing:"Attraversamento pedonale",decorRoadSign:"Segnale stradale",decorVehicle:"Veicolo",decorObserver:"Altro osservatore",decorEast:"Distanza a est",decorNorth:"Distanza a nord",decorHeading:"Orientamento",decorColor:"Colore",decorLit:"Acceso",decorTitle:"Nome",milestones:"Momenti",milestoneLabel:"Etichetta",milestoneNote:"Cosa succede",addMilestone:"Dai un nome a questo momento",deleteMilestone:"Elimina momento",goToMilestone:"Vai a questo momento",decorWidth:"Larghezza",decorLength:"Lunghezza",decorHeight:"Altezza",decorModel:"Modello 3D",decorModelAdvanced:"Modello da un indirizzo",decorModelUrl:"Indirizzo glTF/GLB",decorModelTitle:"Nome del modello",decorModelAuthor:"Autore",decorModelLicense:"Licenza",decorModelSource:"Provenienza",decorObserverSide:"Posizione dell'osservatore",decorObserverSideNone:"Non presente",decorSideFront:"Davanti",decorSideBehind:"Dietro",decorSideLeft:"Sinistra",decorSideRight:"Destra",decorSideFrontLeft:"Davanti a sinistra",decorSideFrontRight:"Davanti a destra",decorSideBehindLeft:"Dietro a sinistra",decorSideBehindRight:"Dietro a destra"},o={...e,accountBy:"Resoconto di",unnamedObserver:"Osservatore {n}",about:"Informazioni",close:"Chiudi",observation:"Osservazione",date:"Data",location:"Luogo",case:"Caso",description:"Descrizione",source:"Fonte",basis:{measured:"misurato",stated:"dichiarato",derived:"dedotto",assumed:"supposto"},credits:"Crediti",editThisObservation:"Modifica questa osservazione",share:"Condividi",embedObservation:"Incorpora l'osservazione",back:"Indietro",shareScope:"Condividi",shareScopeCase:"Il caso intero",shareOpensOn:"Si apre su",shareStartAt:"Inizia a",shareOptionLabels:"Mostra i chip",shareOptionMap:"Apri la mappa",shareOptionMilestones:"Mostra i momenti",shareOptionCompare:"Confronta col resoconto",showLabels:"Mostra ciò che indica",interpretation:"Interpretazione",account:"Resoconto",interpretationBy:"{title}, di {by}",confrontation:"A confronto con il resoconto",confrontationDirection:"scarto di {deg}°",confrontationWidth:"larghezza ×{ratio}",confrontationHeight:"altezza ×{ratio}",showComparison:"Confronta con il resoconto",hideComparison:"Smetti di confrontare con il resoconto",hideLabels:"Nascondi ciò che indica",variant:"Variante: {name}",verdicts:{consolidated:"compatibile con distorsioni consolidate",contested:"solo invocando distorsioni contestate",incompatible:"incompatibile anche ai limiti"},variantFields:{time:"Ora",heading:"Direzione",elevation:"Altezza",size:"Dimensione",duration:"Durata",sweep:"Percorso nel cielo"},variantReadings:{grouped:"luci lette come un solo corpo","still-seen-moving":"una luce ferma vista muoversi","moving-seen-still":"una luce in moto vista immobile","brightening-as-approach":"una luminosità crescente letta come un avvicinamento"}};export{o as sightingMessages_it};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{a0 as M,a1 as y,Y as I}from"./rr0-sighting-editor.mjs";class d{static RECORD_BYTES=20;static NON_ICAO_FLAG=1<<24;static UNKNOWN=65535;static MAX_DT=35999;static decode(t){if(t.length%d.RECORD_BYTES!==0)throw new Error(`An aircraft tile is a multiple of ${d.RECORD_BYTES} bytes, not ${t.length}`);const e=new DataView(t.buffer,t.byteOffset,t.byteLength),c=[];for(let n=0;n<t.length;n+=d.RECORD_BYTES){const s=e.getUint32(n,!0),a=e.getUint16(n+16,!0),r=e.getUint16(n+18,!0);c.push({icao:s&16777215,nonIcao:(s&d.NON_ICAO_FLAG)!==0,secondsInHour:e.getUint16(n+4,!0)/10,lat:e.getInt32(n+6,!0)/1e5,lng:e.getInt32(n+10,!0)/1e5,altitudeFt:e.getInt16(n+14,!0)*25,groundSpeedKt:a===d.UNKNOWN?void 0:a/10,trackDeg:r===d.UNKNOWN?void 0:r/10})}return c}}const w="https://ufoathome.org/aircraft/index.json";class f{citation=M;static DEFAULT_RADIUS_KM=150;static FLAG_MILITARY=1;static FLAG_PIA=4;static FLAG_LADD=8;static KM_PER_DEG=111.32;static HOUR_MS=36e5;fetchImpl;indexUrls;index;hours=new Map;tiles=new Map;shards=new Map;constructor(t={}){this.fetchImpl=t.fetchImpl??fetch.bind(globalThis),this.indexUrls=t.indexUrls??f.defaultIndexUrls()}static defaultIndexUrls(){const t=[];return typeof location<"u"&&/^https?:$/.test(location.protocol)&&t.push(new URL("/aircraft/index.json",location.href).href),t.includes(w)||t.push(w),t}mayCover(t){return y.mayCover(t)}async between(t,e,c,n=f.DEFAULT_RADIUS_KM){const s=await this.loadIndex();if(!s)return{status:"failed"};const a=[];for(let o=Math.floor(e/f.HOUR_MS);o<=Math.floor(c/f.HOUR_MS);o++)a.push(o);if(!a.every(o=>s.index.days.includes(f.dayOf(o))))return{status:"outside"};const r=f.tilesAround(t,n);try{const o=(await Promise.all(a.flatMap(u=>r.map(i=>this.tileOf(s.base,u,i))))).flat();return{status:"found",tracks:f.merge(o,t,e,c,n)}}catch{return{status:"failed"}}}async describe(t,e){const c=await this.loadIndex();if(!c)return;const n=t.icao.toString(16).padStart(6,"0"),s=t.nonIcao?"non-icao":n.slice(0,2),a=`${e}/${s}`;let r=this.shards.get(a);r||(r=this.fetchImpl(new URL(`${e}/aircraft/${s}.json`,c.base).href).then(g=>g.ok?g.json():{}).catch(()=>({})),this.shards.set(a,r));const o=(await r)[t.nonIcao?`~${n}`:n];if(!o)return;const[u,i,l,h=0]=o,p={registration:u||void 0,type:i||void 0,category:l||void 0,military:(h&f.FLAG_MILITARY)!==0||void 0,restricted:(h&(f.FLAG_PIA|f.FLAG_LADD))!==0||void 0};return Object.values(p).some(g=>g!==void 0)?p:void 0}static tilesAround(t,e){const c=e/f.KM_PER_DEG,n=Math.max(-90,t.lat-c),s=Math.min(90,t.lat+c),a=Math.cos(Math.max(Math.abs(n),Math.abs(s))*Math.PI/180),r=a<1e-6?180:e/(f.KM_PER_DEG*a),o=new Set;if(r>=180)for(let i=-180;i<180;i++)o.add(i);else for(let i=Math.floor(t.lng-r);i<=Math.floor(t.lng+r);i++)o.add(I.wrapLongitude(i));const u=[];for(let i=Math.floor(n);i<=Math.min(89,Math.floor(s));i++)for(const l of o)u.push(`${i}_${l}`);return u}static dayOf(t){return new Date(t*f.HOUR_MS).toISOString().slice(0,10)}static merge(t,e,c,n,s){const a=new Map;for(const o of t){const u=o.points.filter(h=>h.t>=c&&h.t<=n&&I.groundDistanceKm(e,h)<=s);if(u.length===0)continue;const i=`${o.nonIcao?"~":""}${o.icao}`,l=a.get(i);l?l.points.push(...u):a.set(i,{icao:o.icao,nonIcao:o.nonIcao,points:u})}const r=[...a.values()];for(const o of r)o.points.sort((u,i)=>u.t-i.t);return r.sort((o,u)=>o.icao-u.icao)}loadIndex(){return this.index??=(async()=>{for(const t of this.indexUrls)try{const e=await this.fetchImpl(t);if(e.ok)return{index:await e.json(),base:t}}catch{}})(),this.index}tileOf(t,e,c){const n=f.dayOf(e),s=String(e%24).padStart(2,"0"),a=`${n}/${s}/${c}`;let r=this.tiles.get(a);return r||(r=this.hourIndex(t,n,s).then(async o=>{const u=o[c];if(!u)return[];const[i,l]=u,h=await this.fetchImpl(new URL(`${n}/${s}.pack`,t).href,{headers:{Range:`bytes=${i}-${i+l-1}`}});if(!h.ok)throw new Error(`The pack of ${n} ${s} h answered ${h.status}`);const p=new Uint8Array(await h.arrayBuffer()),g=h.status===206?p:p.subarray(i,i+l);return f.tracksOf(await f.gunzip(g),e)}),r.catch(()=>this.tiles.delete(a)),this.tiles.set(a,r)),r}hourIndex(t,e,c){const n=`${e}/${c}`;let s=this.hours.get(n);return s||(s=this.fetchImpl(new URL(`${e}/${c}.json`,t).href).then(a=>{if(a.status===404)return{};if(!a.ok)throw new Error(`The index of ${e} ${c} h answered ${a.status}`);return a.json()}),s.catch(()=>this.hours.delete(n)),this.hours.set(n,s)),s}static async gunzip(t){const e=new Blob([t]).stream().pipeThrough(new DecompressionStream("gzip"));return new Uint8Array(await new Response(e).arrayBuffer())}static tracksOf(t,e){const c=new Map;for(const n of d.decode(t)){const s=`${n.nonIcao?"~":""}${n.icao}`;let a=c.get(s);a||c.set(s,a={icao:n.icao,nonIcao:n.nonIcao,points:[]}),a.points.push({t:e*f.HOUR_MS+n.secondsInHour*1e3,lat:n.lat,lng:n.lng,altitudeFt:n.altitudeFt,groundSpeedKt:n.groundSpeedKt,trackDeg:n.trackDeg})}return[...c.values()]}}export{f as AdsbLolArchiveProvider,w as UFOATHOME_AIRCRAFT_INDEX_URL};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{K as lt,N as ht,X as z,R as L,Y as F,Z as ut,j as q}from"./rr0-sighting-editor.mjs";import{$ as Ht}from"./rr0-sighting-editor.mjs";import{C as Z}from"./ContrailGrowth-DwHS8If9.js";class E{static OCTAVES=[63,125,250,500,1e3,2e3,4e3,8e3];static STANDARD={temperatureC:15,relativeHumidity:.7,pressureKPa:101.325};static REFERENCE_PRESSURE_KPA=101.325;static REFERENCE_TEMPERATURE_K=293.15;static TRIPLE_POINT_K=273.16;static speedOfSound(t){return 20.0468*Math.sqrt(t+273.15)}static absorptionDbPerKm(t,e=E.STANDARD){const a=e.temperatureC+273.15,n=E.REFERENCE_TEMPERATURE_K,i=e.pressureKPa/E.REFERENCE_PRESSURE_KPA,o=10**(-6.8346*(E.TRIPLE_POINT_K/a)**1.261+4.6151),s=e.relativeHumidity*100*o/i,r=i*(24+40400*s*(.02+s)/(.391+s)),u=i*(a/n)**-.5*(9+280*s*Math.exp(-4.17*((a/n)**(-1/3)-1))),c=t*t;return 8.686*c*(184e-13*(1/i)*Math.sqrt(a/n)+(a/n)**-2.5*(.01275*Math.exp(-2239.1/a)/(r+c/r)+.1068*Math.exp(-3352/a)/(u+c/u)))*1e3}static aWeightingDb(t){const e=t*t,a=12194**2*e*e/((e+20.6**2)*Math.sqrt((e+107.7**2)*(e+737.9**2))*(e+12194**2));return 20*Math.log10(a)+2}static sumDb(t){return 10*Math.log10(t.reduce((e,a)=>e+10**(a/10),0))}}const dt=.25,x=.4,Q=6,j=12,pt=3,tt=.2,gt=.2,mt=24,Et=3,At=12,et=1,Mt=.7,ft=1.5,bt=.8,St=1.3,at=.9,nt=5,Dt=25,Rt=.5,Ot=.12,it=[.13,.31],vt=.16,Tt=1.6,Bt=3.6,st=1.1,It=.3,_t=1e3,rt=.7;class Y{context;noiseBuffer;roughBuffers=new Map;voices=new Map;bus;reverb;reverbOut;level=1;master;paused=!0;requested=[];headingDeg=0;resume(){if(!this.context){if(typeof AudioContext>"u")return;try{this.context=new AudioContext}catch(t){console.warn("AircraftAudio: Web Audio unavailable, aircraft stay silent:",t);return}}lt.unlock(this.context),this.apply()}setLevel(t){this.level=t,this.master&&(this.master.gain.value=t)}setPaused(t){t!==this.paused&&(this.paused=t,this.apply())}setVoices(t,e=0){this.requested=t,this.headingDeg=e,this.apply()}dispose(){for(const t of[...this.voices.keys()])this.release(t);this.context?.close(),this.context=void 0,this.master=void 0,this.bus=void 0}apply(){const t=this.context;if(!t)return;const e=this.paused?[]:this.requested,a=new Set(e.map(n=>n.id));for(const n of[...this.voices.keys()])a.has(n)||this.release(n);for(const n of e){const i=this.voices.get(n.id)??this.build(t,n);this.retarget(t,i,n)}}build(t,e){const a=t.createGain();a.gain.value=0;let n;const i=this.busOf(t);typeof t.createStereoPanner=="function"?(n=t.createStereoPanner(),a.connect(n).connect(i)):a.connect(i);const o=t.createGain(),s=e.character?.modulationDepth??0;o.gain.value=1-s/2;const r=t.createOscillator();r.type="sine";const u=t.createGain();u.gain.value=s/2,r.connect(u).connect(o.gain),o.connect(a);const c=t.createBufferSource();c.buffer=this.noise(t),c.loop=!0,c.loopStart=Math.random()*Q*.5;const d=[],l=[],h=[];for(const v of E.OCTAVES){const B=t.createBiquadFilter();B.type="bandpass",B.frequency.value=v,B.Q.value=et;const N=t.createBiquadFilter();N.type="bandpass",N.frequency.value=v,N.Q.value=et;const y=t.createGain();y.gain.value=0,c.connect(B).connect(N).connect(y).connect(o),d.push(B),l.push(N),h.push(y)}const p=[];for(const[v,B]of[[e.character?.toneHz,e.character?.toneShare],[e.character?.humHz,e.character?.humShare]])if(v!==void 0)for(let N=1;N<=Et;N++){const y=t.createOscillator();y.type="sine",y.frequency.value=v*N;const X=t.createGain();X.gain.value=0,y.connect(X).connect(a),p.push({oscillator:y,gain:X,harmonic:N,baseHz:v,share:B??0})}const g=t.createGain();g.gain.value=0,g.connect(a.gain);const M=it.map(v=>{const B=t.createOscillator();return B.type="sine",B.frequency.value=v,B.connect(g),B}),b=t.createGain();b.gain.value=e.character?.roughness??tt;const R=t.createBufferSource();R.buffer=this.roughTable(t,pt),R.loop=!0,R.loopStart=Math.random()*j*.5,R.connect(b).connect(o.gain);const S=t.createGain();S.gain.value=(e.character?.roughness??tt)*gt;const f=t.createBufferSource();f.buffer=this.roughTable(t,mt),f.loop=!0,f.loopStart=Math.random()*j*.5,f.connect(S).connect(o.gain);let I;const U=this.busOf(t)&&this.reverb;U&&(I=t.createGain(),I.gain.value=0,a.connect(I).connect(U));const V=[c,R,f,r,...p.map(v=>v.oscillator),...M];for(const v of V)v.start();const J={nodes:[a,o,u,b,S,g,...p.map(v=>v.gain),...d,...l,...h,...I?[I]:[],...n?[n]:[],...V],sources:V,filters:d,seconds:l,gains:h,tones:p,lfo:r,lfoDepth:u,wander:M,wanderDepth:g,roughDepth:b,crackleDepth:S,beat:o,output:a,panner:n,send:I};return this.voices.set(e.id,J),J}retarget(t,e,a){const n=t.currentTime,i=(p,g)=>p.setTargetAtTime(g,n,dt),o=Math.min(ft,Math.max(Mt,a.dopplerRatio)),s=Math.min(St,Math.max(bt,Math.sqrt(a.dopplerRatio))),r=t.sampleRate*.45,u=a.bandAmplitudes.map((p,g)=>p*Y.unweighting(E.OCTAVES[g])),c=Math.sqrt(u.reduce((p,g)=>p+g*g,0)),d=Math.min(1,Math.max(0,(a.distanceKm-nt)/(Dt-nt)));E.OCTAVES.forEach((p,g)=>{i(e.filters[g].frequency,Math.min(r,p*s)),i(e.seconds[g].frequency,Math.min(r,p*s)),i(e.gains[g].gain,u[g]*Math.sqrt(_t/p))});const l=a.character;for(const{oscillator:p,gain:g,harmonic:M,baseHz:b,share:R}of e.tones){const S=b*M;i(p.frequency,S*o);const f=S*o;i(g.gain,f<r?R*vt*u[Y.bandOf(f)]/M:0)}l?.modulationHz!==void 0&&i(e.lfo.frequency,l.modulationHz*o);const h=c>0?rt*(1-Math.exp(-c/rt))/c:1;if(i(e.output.gain,h*(1-It*d)),i(e.wanderDepth.gain,h*Ot*d/it.length),e.send&&i(e.send.gain,Tt*d),e.panner){const p=(a.azimuthDeg-this.headingDeg)*Math.PI/180;i(e.panner.pan,Math.max(-at,Math.min(at,Math.sin(p)))*(1-Rt*d))}}static unweighting(t){return 10**(Math.min(At,Math.max(0,-E.aWeightingDb(t)))/20)}static bandOf(t){let e=0;return E.OCTAVES.forEach((a,n)=>{Math.abs(Math.log(t/a))<Math.abs(Math.log(t/E.OCTAVES[e]))&&(e=n)}),e}roughTable(t,e){const a=this.roughBuffers.get(e);if(a)return a;const n=Math.floor(t.sampleRate*j),i=t.createBuffer(1,n,t.sampleRate),o=i.getChannelData(0),s=Array.from({length:j*e},()=>(Math.random()*2-1)**3),r=t.sampleRate/e;for(let u=0;u<o.length;u++){const c=u/r,d=Math.floor(c),l=c-d,h=l*l*(3-2*l);o[u]=s[d%s.length]*(1-h)+s[(d+1)%s.length]*h}return this.roughBuffers.set(e,i),i}roomImpulse(t){const e=Math.floor(t.sampleRate*Bt),a=t.createBuffer(2,e,t.sampleRate);for(let n=0;n<2;n++){const i=a.getChannelData(n);let o=0;for(let s=0;s<e;s++){const r=s/t.sampleRate,u=.6*Math.exp(-r/(st*2))+.04;o+=u*(Math.random()*2-1-o),i[s]=o*Math.exp(-r/st)}}return a}busOf(t){if(this.bus)return this.bus;const e=t.createGain();if(e.gain.value=this.level,e.connect(t.destination),this.master=e,typeof t.createConvolver=="function"){const a=t.createConvolver();a.buffer=this.roomImpulse(t);const n=t.createGain();n.gain.value=.9,a.connect(n),this.reverb=a,this.reverbOut=n}if(typeof t.createDynamicsCompressor=="function"){const a=t.createDynamicsCompressor();a.threshold.value=-6,a.knee.value=3,a.ratio.value=4,a.attack.value=.005,a.release.value=.25,a.connect(e),this.bus=a}else this.bus=e;return this.reverbOut?.connect(this.bus),this.bus}release(t){const e=this.voices.get(t);if(!e)return;this.voices.delete(t);const a=this.context;a&&(e.output.gain.setTargetAtTime(0,a.currentTime,x/3),setTimeout(()=>{for(const n of e.sources)try{n.stop()}catch{}for(const n of e.nodes)n.disconnect()},x*1e3*3))}noise(t){if(this.noiseBuffer)return this.noiseBuffer;const e=t.createBuffer(1,t.sampleRate*Q,t.sampleRate),a=e.getChannelData(0);for(let n=0;n<a.length;n++)a[n]=Math.random()*2-1;return this.noiseBuffer=e,e}}class _{static BASE_DB_A=30;static WIND_DB_A=[[0,10],[1,28],[2,36],[3,40],[5,46],[8,52],[12,58],[20,66]];static RAIN_DB_A=[[0,0],[.1,42],[.3,50],[.6,58],[1,65]];static BED_RMS=.2;static MINIMUM_REFERENCE=.008;static WIND_BED_MIN_MS=1;static WIND_BED_FULL_MS=20;static dbA(t){const e=[_.BASE_DB_A,_.along(_.WIND_DB_A,t.windSpeed)];return(t.precipitationType==="rain"||t.precipitationType==="hail")&&e.push(_.along(_.RAIN_DB_A,t.precipitationIntensity)),10*Math.log10(e.filter(a=>a>0).reduce((a,n)=>a+10**(n/10),0))}static bedVolume(t){const e=t.windSpeed>_.WIND_BED_MIN_MS?Math.min(t.windSpeed/_.WIND_BED_FULL_MS,1):0,a=t.precipitationType==="hail"?Math.min(1,t.precipitationIntensity*1.3+.2):t.precipitationType==="rain"?t.precipitationIntensity:0;return Math.hypot(e,a)}static referenceAmplitude(t){return Math.max(_.BED_RMS*_.bedVolume(t),_.MINIMUM_REFERENCE)}static along(t,e){if(e<=t[0][0])return t[0][1];for(let a=1;a<t.length;a++)if(e<=t[a][0]){const[n,i]=t[a-1],[o,s]=t[a];return i+(s-i)*(e-n)/(o-n)}return t[t.length-1][1]}}class k{static TYPES={A318:["Airbus A318","airliner-narrow",34.1,31.4],A319:["Airbus A319","airliner-narrow",34.1,33.8],A320:["Airbus A320","airliner-narrow",34.1,37.6],A321:["Airbus A321","airliner-narrow",34.1,44.5],A19N:["Airbus A319neo","airliner-narrow",35.8,33.8],A20N:["Airbus A320neo","airliner-narrow",35.8,37.6],A21N:["Airbus A321neo","airliner-narrow",35.8,44.5],B737:["Boeing 737-700","airliner-narrow",34.3,33.6],B738:["Boeing 737-800","airliner-narrow",35.8,39.5],B739:["Boeing 737-900","airliner-narrow",35.8,42.1],B38M:["Boeing 737 MAX 8","airliner-narrow",35.9,39.5],B39M:["Boeing 737 MAX 9","airliner-narrow",35.9,42.2],B752:["Boeing 757-200","airliner-narrow",38,47.3],B753:["Boeing 757-300","airliner-narrow",38,54.4],B762:["Boeing 767-200","airliner-wide",47.6,48.5],B763:["Boeing 767-300","airliner-wide",47.6,54.9],B764:["Boeing 767-400","airliner-wide",51.9,61.4],B772:["Boeing 777-200","airliner-wide",60.9,63.7],B77L:["Boeing 777-200LR","airliner-wide",64.8,63.7],B77W:["Boeing 777-300ER","airliner-wide",64.8,73.9],B788:["Boeing 787-8","airliner-wide",60.1,56.7],B789:["Boeing 787-9","airliner-wide",60.1,62.8],B78X:["Boeing 787-10","airliner-wide",60.1,68.3],B744:["Boeing 747-400","airliner-wide",64.4,70.7],B748:["Boeing 747-8","airliner-wide",68.4,76.3],A306:["Airbus A300-600","airliner-wide",44.8,54.1],A310:["Airbus A310","airliner-wide",43.9,46.7],A332:["Airbus A330-200","airliner-wide",60.3,58.8],A333:["Airbus A330-300","airliner-wide",60.3,63.7],A338:["Airbus A330-800","airliner-wide",64,58.8],A339:["Airbus A330-900","airliner-wide",64,63.7],A343:["Airbus A340-300","airliner-wide",60.3,63.7],A346:["Airbus A340-600","airliner-wide",63.5,75.4],A359:["Airbus A350-900","airliner-wide",64.8,66.8],A35K:["Airbus A350-1000","airliner-wide",64.8,73.8],A388:["Airbus A380-800","airliner-wide",79.8,72.7],E170:["Embraer 170","regional-jet",26,29.9],E75L:["Embraer 175","regional-jet",26,31.7],E75S:["Embraer 175","regional-jet",26,31.7],E190:["Embraer 190","regional-jet",28.7,36.2],E195:["Embraer 195","regional-jet",28.7,38.7],E290:["Embraer 190-E2","regional-jet",33.7,36.2],E295:["Embraer 195-E2","regional-jet",33.7,41.5],CRJ2:["Bombardier CRJ200","regional-jet",21.2,26.8],CRJ7:["Bombardier CRJ700","regional-jet",23.2,32.3],CRJ9:["Bombardier CRJ900","regional-jet",24.9,36.2],CRJX:["Bombardier CRJ1000","regional-jet",26.2,39.1],AT72:["ATR 72","regional-turboprop",27.1,27.2],AT76:["ATR 72-600","regional-turboprop",27.1,27.2],AT45:["ATR 42","regional-turboprop",24.6,22.7],DH8D:["Dash 8 Q400","regional-turboprop",28.4,32.8],DH8C:["Dash 8-300","regional-turboprop",27.4,25.7],SF34:["Saab 340","regional-turboprop",21.4,19.7],B190:["Beechcraft 1900","regional-turboprop",17.7,17.6],C25A:["Cessna CitationJet CJ2","business-jet",14.3,14.4],C56X:["Cessna Citation Excel","business-jet",17.2,16],C68A:["Cessna Citation Latitude","business-jet",22,18.9],C550:["Cessna Citation II","business-jet",15.8,14.4],E55P:["Embraer Phenom 300","business-jet",15.9,15.6],E50P:["Embraer Phenom 100","business-jet",12.3,12.8],GLF5:["Gulfstream G550","business-jet",28.5,29.4],FA7X:["Dassault Falcon 7X","business-jet",26.2,23.4],CL60:["Bombardier Challenger 600","business-jet",19.6,20.9],LJ45:["Learjet 45","business-jet",14.6,17.7],H25B:["Hawker 800","business-jet",15.7,15.6],C172:["Cessna 172","light-piston",11,8.3],C152:["Cessna 152","light-piston",10.2,7.3],C182:["Cessna 182","light-piston",10.9,8.8],P28A:["Piper Cherokee","light-piston",10.7,7.2],PA34:["Piper Seneca","light-piston",11.8,8.7],SR20:["Cirrus SR20","light-piston",10.9,7.9],SR22:["Cirrus SR22","light-piston",11.7,7.9],S22T:["Cirrus SR22T","light-piston",11.7,7.9],DA40:["Diamond DA40","light-piston",11.6,8.1],DA42:["Diamond DA42","light-piston",13.4,8.6],BE20:["Beechcraft King Air 200","turboprop-light",16.6,13.3],BE58:["Beechcraft Baron","light-piston",11.5,9.1],C208:["Cessna Caravan","turboprop-light",15.9,11.5],PC12:["Pilatus PC-12","turboprop-light",16.3,14.4],TBM9:["Daher TBM 900","turboprop-light",12.8,10.7],EC35:["Airbus H135","helicopter-light",10.2,12.1],EC45:["Airbus H145","helicopter-medium",11,13.6],AS50:["Airbus H125","helicopter-light",10.7,12.9],EC30:["Airbus H130","helicopter-light",10.7,12.6],B407:["Bell 407","helicopter-light",10.7,12.7],B06:["Bell 206","helicopter-light",10.2,12],B429:["Bell 429","helicopter-medium",10.9,13],B505:["Bell 505","helicopter-light",10.4,11.9],R44:["Robinson R44","helicopter-light",10.1,11.7],R22:["Robinson R22","helicopter-light",7.7,8.8],A109:["Agusta A109","helicopter-medium",11,13],A139:["Leonardo AW139","helicopter-medium",13.8,16.7],S92:["Sikorsky S-92","helicopter-heavy",17.2,20.9],H60:["Sikorsky UH-60 Black Hawk","helicopter-heavy",16.4,19.8],T38:["Northrop T-38 Talon","military-jet",7.7,14.1],HAWK:["BAE Hawk","military-jet",9.4,11.9],GLID:["Glider","glider",17,7],BALL:["Balloon","balloon",15,20],ULAC:["Ultralight","ultralight",9.5,6],C42:["Ikarus C42","ultralight",9.4,6.3],DRON:["Drone","unmanned",1,.6]};static CATEGORIES={A1:["Light aircraft","light-piston",11,8.3],A2:["Small aircraft","business-jet",15,15],A3:["Large aircraft","airliner-narrow",34.1,37.6],A4:["High-vortex large aircraft","airliner-narrow",38,47.3],A5:["Heavy aircraft","airliner-wide",60.3,63.7],A6:["High-performance aircraft","military-jet",8,14],A7:["Rotorcraft","helicopter-medium",10.7,12.7],B1:["Glider","glider",17,7],B2:["Lighter-than-air","balloon",15,20],B4:["Ultralight","ultralight",9.5,6],B6:["Unmanned aircraft","unmanned",1.5,1]};static GENERIC={name:"Airliner",kind:"airliner-narrow",spanM:34.1,lengthM:37.6,basis:"nothing"};static of(t){const e=t?.type?.toUpperCase(),a=e?k.TYPES[e]:void 0;if(a)return{code:e,name:a[0],kind:a[1],spanM:a[2],lengthM:a[3],basis:"type"};const n=t?.category?k.CATEGORIES[t.category]:void 0;return n?{name:n[0],kind:n[1],spanM:n[2],lengthM:n[3],basis:"category"}:{...k.GENERIC}}static isHelicopter(t){return t.kind.startsWith("helicopter")}}class P{static DUSK_SUN_ELEVATION_DEG=-.83;static ALWAYS=new Set(["airliner-narrow","airliner-wide","regional-turboprop","regional-jet","business-jet"]);static NONE=new Set(["glider","balloon"]);static BRIGHTNESS={"light-piston":[.5,.2,.5],"turboprop-light":[.7,.4,.8],ultralight:[.4,.2,.4],unmanned:[0,.05,0],"helicopter-light":[1,1,1],"helicopter-medium":[1,1,1],"helicopter-heavy":[1,1,1],"military-jet":[1,1,1]};static lampsOn(t,e){if(P.NONE.has(t))return{navigation:!1,beacon:!1,strobes:!1};if(P.ALWAYS.has(t))return{navigation:!0,beacon:!0,strobes:!0};const a=e<P.DUSK_SUN_ELEVATION_DEG;return t==="unmanned"?{navigation:!1,beacon:!1,strobes:a}:{navigation:a,beacon:a,strobes:a}}static lights(t,e){const a=P.lampsOn(t.kind,e),n=t.kind.startsWith("helicopter"),i=ht.find(h=>h.id===(n?"helicopter":"airliner")).create(),[o,s]=n?[5,7]:[17,18],r=t.spanM/2/o,u=t.lengthM/2/s,[c,d,l]=P.BRIGHTNESS[t.kind]??[1,1,1];return i.filter(h=>h.id.startsWith("nav")?a.navigation:h.id.startsWith("strobe")?a.strobes:h.id.startsWith("beacon")?a.beacon:!0).filter(h=>!(h.id.startsWith("beacon")&&!a.beacon)).map(h=>{const p=h.id.startsWith("nav")?c:h.id.startsWith("strobe")?d:l;return{...h,offsetM:{x:h.offsetM.x*r,y:h.offsetM.y,z:h.offsetM.z*u},intensity:(h.intensity??1)*p}}).filter(h=>(h.intensity??1)>0)}static bodyColor(t){return t.kind==="military-jet"?"#8a8e94":t.kind.startsWith("helicopter")?"#c8ccd1":t.kind==="unmanned"?"#2c2e33":"#dde0e4"}}class K{static FAMILIES={"amvlab-a320":["A318","A319","A320","A321","A19N","A20N","A21N"],"amvlab-b737":["B732","B733","B734","B735","B736","B737","B738","B739","B37M","B38M","B39M","B3XM"],"amvlab-a350":["A359","A35K"],"amvlab-a380":["A388"],"amvlab-b787":["B788","B789","B78X"]};static BY_TYPE=new Map(Object.entries(K.FAMILIES).flatMap(([t,e])=>e.map(a=>[a,t])));static idOf(t){return t?K.BY_TYPE.get(t.toUpperCase()):void 0}}class D{static ID_PREFIX=z.ID_PREFIX;static MAX_OBJECTS=40;static FT_TO_M=.3048;static DEG=Math.PI/180;static from(t,e,a,n=D.MAX_OBJECTS,i={}){return new Nt(t,e,a,n,i).build()}static idOf(t,e){return z.idOf(t,e)}static keyOf(t){return z.keyOf(t)}static HEIGHT_OVER_LENGTH=.29;static sizeOf(t){return{widthM:t.spanM,lengthM:t.lengthM,heightM:t.lengthM*D.HEIGHT_OVER_LENGTH}}static offsetOf(t,e){const a=L.seenFrom(t,{lat:e.lat,lng:e.lng,heightM:e.altitudeFt*D.FT_TO_M}),n=a.distanceKm*1e3,i=n*Math.cos(a.altitudeDeg*D.DEG);return{eastM:i*Math.sin(a.azimuthDeg*D.DEG),northM:i*Math.cos(a.azimuthDeg*D.DEG),upM:n*Math.sin(a.altitudeDeg*D.DEG),altitudeDeg:a.altitudeDeg,distanceKm:a.distanceKm}}static segments(t){const e=[];let a=[];for(const n of t.points){const i=a[a.length-1];i&&n.t-i.t>F.MAX_GAP_S*1e3&&(e.push(a),a=[]),a.push(n)}return e.push(a),e.filter(n=>n.length>=2)}static bearingDeg(t,e){return(Math.atan2(e.eastM-t.eastM,e.northM-t.northM)/D.DEG+360)%360}}class Nt{constructor(t,e,a,n,i){this.tracks=t,this.observer=e,this.startMs=a,this.maxObjects=n,this.options=i}build(){const t=[];for(const a of this.tracks){const n=D.keyOf(a),i=this.options.models?.get(n)??k.of(void 0);D.segments(a).forEach((o,s)=>{const r=o.map(h=>({point:h,at:D.offsetOf(this.observer,h)}));if(!r.some(h=>h.at.altitudeDeg>=0))return;const u=r.map((h,p)=>({t:h.point.t-this.startMs,eastM:h.at.eastM,northM:h.at.northM,altitudeM:h.at.upM,headingDeg:h.point.trackDeg??(p+1<r.length?D.bearingDeg(h.at,r[p+1].at):D.bearingDeg(r[p-1].at,h.at))})),c=D.idOf(a,s),d=r[Math.floor(r.length/2)].point,l=this.options.sunElevationAt?.(d)??90;t.push({object:{id:c,kind:"aircraft",eastM:u[0].eastM,northM:u[0].northM,headingDeg:u[0].headingDeg,sizeM:D.sizeOf(i),model:K.idOf(i.code)?{id:K.idOf(i.code)}:void 0,color:P.bodyColor(i),lights:P.lights(i,l),track:u},presence:{fromMs:u[0].t,untilMs:u[u.length-1].t},flight:{icao:a.icao,nonIcao:a.nonIcao,points:o},closestKm:Math.min(...r.map(h=>h.at.distanceKm))})})}t.sort((a,n)=>a.closestKm-n.closestKm);const e=t.slice(0,this.maxObjects);return{objects:e.map(a=>a.object),presence:new Map(e.map(a=>[a.object.id,a.presence])),flights:new Map(e.map(a=>[a.object.id,a.flight])),total:t.length,shown:e.length}}}const ct=[{id:"turbofan-narrow-body",name:"Turbofan airliner, narrow-body",kinds:["airliner-narrow"],totalDbA:148,shapeDb:[-32,-17,-9,-6,-5,-7,-12,-22],character:{toneHz:1800,toneShare:.3,humHz:90,humShare:.7}},{id:"turbofan-wide-body",name:"Turbofan airliner, wide-body",kinds:["airliner-wide"],totalDbA:151,shapeDb:[-28,-14,-7,-4,-3,-6,-12,-22],character:{toneHz:1200,toneShare:.3,humHz:70,humShare:.7}},{id:"regional-jet",name:"Regional jet",kinds:["regional-jet"],totalDbA:144,shapeDb:[-32,-17,-9,-5,-4,-6,-11,-21],character:{toneHz:1900,toneShare:.3,humHz:95,humShare:.7}},{id:"business-jet",name:"Business jet",kinds:["business-jet"],totalDbA:141,shapeDb:[-30,-15,-8,-4,-3,-4,-9,-19],character:{toneHz:2500,toneShare:.25,humHz:110,humShare:.7}},{id:"turboprop",name:"Turboprop",kinds:["regional-turboprop","turboprop-light"],totalDbA:138,shapeDb:[-14,-9,-8,-6,-8,-13,-20,-28],character:{toneHz:80,toneShare:.5}},{id:"light-piston",name:"Light piston aircraft",kinds:["light-piston"],totalDbA:130,shapeDb:[-18,-9,-5,-4,-8,-14,-22,-30],character:{toneHz:80,toneShare:.4}},{id:"ultralight",name:"Ultralight",kinds:["ultralight"],totalDbA:124,shapeDb:[-16,-8,-5,-4,-9,-15,-23,-31],character:{toneHz:140,toneShare:.4}},{id:"helicopter-light",name:"Light helicopter",kinds:["helicopter-light"],totalDbA:134,shapeDb:[-15,-8,-4,-3,-6,-10,-16,-24],character:{modulationHz:20,modulationDepth:.5}},{id:"helicopter-medium",name:"Medium helicopter",kinds:["helicopter-medium"],totalDbA:138,shapeDb:[-14,-7,-4,-3,-6,-10,-16,-24],character:{modulationHz:22,modulationDepth:.5}},{id:"helicopter-heavy",name:"Heavy helicopter",kinds:["helicopter-heavy"],totalDbA:144,shapeDb:[-12,-6,-4,-4,-7,-11,-17,-25],character:{modulationHz:17,modulationDepth:.5}},{id:"military-jet",name:"Military jet",kinds:["military-jet"],totalDbA:152,shapeDb:[-26,-12,-6,-3,-2,-3,-7,-15]},{id:"glider",name:"Glider",kinds:["glider"],totalDbA:85,shapeDb:[-30,-22,-15,-10,-8,-8,-14,-22]},{id:"balloon",name:"Hot-air balloon",kinds:["balloon"],totalDbA:100,shapeDb:[-25,-15,-9,-5,-3,-6,-12,-20]},{id:"unmanned",name:"Unmanned aircraft",kinds:["unmanned"],totalDbA:88,shapeDb:[-40,-30,-20,-12,-6,-3,-3,-8],character:{toneHz:450,toneShare:1}}],ot=ct.map(w=>({id:w.id,name:w.name,soundPowerA:w.shapeDb.map(t=>t+w.totalDbA-E.sumDb(w.shapeDb)),character:w.character}));class m{static DEFAULT_AMBIENT_DB_A=35;static DETECTION_MARGIN_DB=3;static AMBIENT_SHAPE_DB=[-12,-7,-5,-5,-7,-11,-17,-25];static HEARING_FLOOR_DB_A=0;static ITERATIONS=30;static CONVERGED_MS=.5;static VELOCITY_STEP_MS=500;static noiseOfKind(t){const e=ct.find(a=>a.kinds.includes(t));return ot.find(a=>a.id===(e?.id??"turbofan-narrow-body"))}static bandsAt(t,e,a=E.STANDARD){const n=20*Math.log10(Math.max(e*1e3,1))+11;return E.OCTAVES.map((i,o)=>t.soundPowerA[o]-n-E.absorptionDbPerKm(i,a)*e)}static couldBeHeard(t,e,a=m.DEFAULT_AMBIENT_DB_A,n=E.STANDARD){const i=m.ambientBands(a);return m.bandsAt(t,e,n).some((o,s)=>o>=Math.max(i[s]+m.DETECTION_MARGIN_DB,m.HEARING_FLOOR_DB_A))}static ambientBands(t){const e=m.AMBIENT_SHAPE_DB,a=E.sumDb(e);return e.map(n=>t+n-a)}static heardAt(t,e,a,n={}){const i=n.air??E.STANDARD,o=E.speedOfSound(i.temperatureC),s=t.points[t.points.length-1]?.t;if(s===void 0)return;let r=Math.min(a,s),u=F.positionAt(t,r);if(!u)return;let c=L.seenFrom(e,u.geo);for(let f=0;f<m.ITERATIONS;f++){const I=a-c.distanceKm*1e3*1e3/o,U=Math.abs(I-r);if(r=I,u=F.positionAt(t,r),!u)return;if(c=L.seenFrom(e,u.geo),U<m.CONVERGED_MS)break}const d=F.positionAt(t,a),l=d?L.seenFrom(e,d.geo):c,h=n.noise??ot[0],p=n.ambientDbA??m.DEFAULT_AMBIENT_DB_A,g=m.ambientBands(p),M=m.bandsAt(h,c.distanceKm,i),b=M.map((f,I)=>f>=Math.max(g[I]+m.DETECTION_MARGIN_DB,m.HEARING_FLOOR_DB_A)),R=M.indexOf(Math.max(...M)),S=b.lastIndexOf(!0);return{track:t,audible:b.some(Boolean),levelDbA:E.sumDb(M),bandsDbA:M,ambientDbA:p,delayS:(a-r)/1e3,emittedAtMs:r,sound:c,seen:l,lagDeg:m.angleBetween(c,l),dopplerRatio:m.doppler(t,e,r,o),dominantHz:E.OCTAVES[R],cutoffHz:S<0?void 0:E.OCTAVES[S]}}static profile(t,e,a,n,i=2e3,o={}){const s=[];let r,u,c=a;for(let d=a;d<=n;d+=i){const l=m.heardAt(t,e,d,o);l&&(!u||l.levelDbA>u.levelDbA)&&(u=l,c=d),l?.audible?r?r.untilMs=d:s.push(r={fromMs:d,untilMs:d}):r=void 0}return{track:t,audible:s,peakDbA:u?.levelDbA??-1/0,peakAtMs:c,peakDelayS:u?.delayS??0}}static angleBetween(t,e){const a=c=>{const d=c.altitudeDeg*Math.PI/180,l=c.azimuthDeg*Math.PI/180;return[Math.cos(d)*Math.sin(l),Math.cos(d)*Math.cos(l),Math.sin(d)]},[n,i,o]=a(t),[s,r,u]=a(e);return Math.acos(Math.min(1,Math.max(-1,n*s+i*r+o*u)))*180/Math.PI}static doppler(t,e,a,n){const i=m.VELOCITY_STEP_MS,o=F.positionAt(t,a-i),s=F.positionAt(t,a+i);if(!o||!s)return 1;const r=L.seenFrom(e,o.geo).distanceKm*1e3,u=L.seenFrom(e,s.geo).distanceKm*1e3;return 1/(1-(r-u)/(2*i/1e3)/n)}}class wt{static at(t,e,a,n,i={}){const o=F.seenFrom(t,a,n);if(!o)return;const s=k.of(e),r=m.heardAt(t,a,n,{noise:m.noiseOfKind(s.kind),...i});return{hex:`${t.nonIcao?"~":""}${t.icao.toString(16).padStart(6,"0")}`,registration:e?.registration,typeCode:s.code??e?.type,name:s.basis==="nothing"?void 0:s.name,kind:s.kind,basis:s.basis,military:e?.military===!0,restricted:e?.restricted===!0,altitudeFt:o.altitudeFt,groundSpeedKt:o.groundSpeedKt,trackDeg:o.trackDeg,sky:o.sky,angularRateDegPerS:o.angularRateDegPerS,hearing:r&&{audible:r.audible,levelDbA:r.levelDbA,ambientDbA:r.ambientDbA,delayS:r.delayS,lagDeg:r.lagDeg,dopplerRatio:r.dopplerRatio,cutoffHz:r.cutoffHz,dominantHz:r.dominantHz}}}}class O{static REFERENCE_AMPLITUDE=.02;static MASKING_RANGE_DB=6;static KNEE_DB=20;static COMPRESSION_RATIO=1.5;static EXPANSION_RATIO=1.8;static DEFAULT_MAX_VOICES=4;static candidates(t,e,a,n,i={}){const o=new Set;for(const[s,r]of t){const u=m.noiseOfKind(k.of(e.get(a(r))).kind);let c=1/0;for(const d of r.points)c=Math.min(c,L.seenFrom(n,{lat:d.lat,lng:d.lng,heightM:d.altitudeFt*.3048}).distanceKm);m.couldBeHeard(u,c,i.ambientDbA,i.air)&&o.add(s)}return o}static voices(t,e,a,n,i,o,s={}){const r=[];for(const u of t){const c=e.get(u);if(!c||s.only?.(u)===!1)continue;const d=s.kindOf?.(u)??k.of(a.get(n(c))).kind,l=s.noiseOf?.(u)??m.noiseOfKind(d),h=m.heardAt(c,i,o,{...s,noise:l});h?.audible&&r.push({id:u,kind:d,bandAmplitudes:O.bandAmplitudes(h.bandsDbA,h.ambientDbA,s.referenceAmplitude),levelDbA:h.levelDbA,distanceKm:h.sound.distanceKm,dopplerRatio:h.dopplerRatio,azimuthDeg:h.sound.azimuthDeg,elevationDeg:h.sound.altitudeDeg,character:l.character})}return r.sort((u,c)=>c.levelDbA-u.levelDbA).slice(0,s.maxVoices??O.DEFAULT_MAX_VOICES)}static bandAmplitudes(t,e,a=O.REFERENCE_AMPLITUDE){const n=m.ambientBands(e),i=m.DETECTION_MARGIN_DB,o=E.sumDb(t),s=o-e,r=s>=O.KNEE_DB?O.KNEE_DB+(s-O.KNEE_DB)/O.COMPRESSION_RATIO:O.KNEE_DB-(O.KNEE_DB-s)*O.EXPANSION_RATIO,u=a*10**(r/20);return t.map((c,d)=>{const l=Math.min(1,Math.max(0,(c-n[d]-i+O.MASKING_RANGE_DB)/(2*O.MASKING_RANGE_DB)));return l*l*(3-2*l)*u*10**((c-o)/20)})}static BANDS_HZ=E.OCTAVES}class W{static ENGLISH={unnamed:"Aircraft {hex}",altitude:"{value} ft",speed:"{value} kt",heading:"heading {value}°",position:"{distance} km away, {elevation}° above the horizon, {bearing}",heard:"Heard at {level} dB(A), left the aircraft {delay} s ago, {lag}° behind it: {character}{pitch}",rumble:"a low rumble, nothing above {cutoff} Hz",muffled:"a dull noise, nothing above {cutoff} Hz",broad:"a broad roar",pitchHigher:", pitch {percent} % higher",pitchLower:", pitch {percent} % lower",inaudible:"Not audible here: {level} dB(A) against {ambient} dB(A) of ambient noise",soundUnknown:"Its sound cannot be worked out: the aircraft was not recorded yet when it left",contrailPersistent:"Leaves a trail that lasts: the air is supersaturated over ice ({rhi} % over ice)",contrailShort:"Leaves a short-lived trail: the air is dry over ice ({rhi} % over ice)",military:"military",restricted:"identity withheld by its owner",candidate:"A compatible candidate, not an identification"};static RUMBLE_BELOW_HZ=500;static DULL_BELOW_HZ=2e3;static PITCH_NOTICED=.03;static text(t,e,a,n){const i=(l,h=0)=>l.toLocaleString(n,{maximumFractionDigits:h}),o=(l,h)=>l.replace(/\{(\w+)\}/g,(p,g)=>h[g]??`{${g}}`),s=[],r=[t.registration,t.name].filter(Boolean).join(" · ");s.push(r||o(e.unnamed,{hex:t.hex}));const u=[o(e.altitude,{value:i(Math.round(t.altitudeFt/100)*100)}),t.groundSpeedKt===void 0?void 0:o(e.speed,{value:i(Math.round(t.groundSpeedKt))}),t.trackDeg===void 0?void 0:o(e.heading,{value:i(Math.round(t.trackDeg))})].filter(Boolean);s.push(u.join(" · ")),s.push(o(e.position,{distance:i(t.sky.distanceKm,t.sky.distanceKm<10?1:0),elevation:i(Math.round(t.sky.altitudeDeg)),bearing:a(t.sky.azimuthDeg)}));const c=t.hearing;if(!c)s.push(e.soundUnknown);else if(!c.audible)s.push(o(e.inaudible,{level:i(Math.round(c.levelDbA)),ambient:i(Math.round(c.ambientDbA))}));else{const l=c.cutoffHz??0,h=l<=W.RUMBLE_BELOW_HZ?e.rumble:l<=W.DULL_BELOW_HZ?e.muffled:e.broad,p=c.dopplerRatio-1,g=Math.abs(p)<W.PITCH_NOTICED?"":o(p>0?e.pitchHigher:e.pitchLower,{percent:i(Math.round(Math.abs(p)*100))});s.push(o(e.heard,{level:i(Math.round(c.levelDbA)),delay:i(Math.round(c.delayS)),lag:i(Math.round(c.lagDeg)),character:o(h,{cutoff:i(l)}),pitch:g}))}t.contrail&&s.push(o(t.contrail.persistent?e.contrailPersistent:e.contrailShort,{rhi:i(Math.round(t.contrail.iceRelativeHumidity*100))}));const d=[t.military?e.military:void 0,t.restricted?e.restricted:void 0].filter(Boolean);return d.length>0&&s.push(d.join(" · ")),s.push(e.candidate),s.join(`
|
|
2
|
-
`)}}class ${static EFFICIENCY={"airliner-narrow":.34,"airliner-wide":.38,"regional-jet":.32,"business-jet":.3,"military-jet":.22,unknown:.34};static efficiencyOf(t){return $.EFFICIENCY[t]}}class A{static EMISSION_INDEX_WATER=1.25;static COMBUSTION_HEAT=432e5;static AIR_HEAT_CAPACITY=1004;static MOLAR_MASS_RATIO=.622;static FT_TO_M=.3048;static TROPOPAUSE_M=11e3;static TROPOPAUSE_HPA=226.32;static ISOTHERMAL_SCALE_HEIGHT_M=6341.62;static pressureAtAltitudeFt(t){const e=t*A.FT_TO_M;return e<=A.TROPOPAUSE_M?1013.25*(1-225577e-10*e)**5.25588:A.TROPOPAUSE_HPA*Math.exp(-(e-A.TROPOPAUSE_M)/A.ISOTHERMAL_SCALE_HEIGHT_M)}static saturationOverWaterPa(t){const e=t+273.15;return Math.exp(54.842763-6763.22/e-4.21*Math.log(e)+367e-6*e+Math.tanh(.0415*(e-218.8))*(53.878-1331.22/e-9.44523*Math.log(e)+.014025*e))}static saturationOverIcePa(t){const e=t+273.15;return Math.exp(9.550426-5723.265/e+3.53068*Math.log(e)-.00728332*e)}static iceRelativeHumidity(t,e){return e*A.saturationOverWaterPa(t)/A.saturationOverIcePa(t)}static mixingSlope(t,e){return A.EMISSION_INDEX_WATER*A.AIR_HEAT_CAPACITY*t*100/(A.MOLAR_MASS_RATIO*A.COMBUSTION_HEAT*(1-e))}static criticalTemperatureC(t,e){const a=Math.log(A.mixingSlope(t,e)-.053);return-46.46+9.43*a+.72*a*a}static requiredHumidity(t,e,a){const n=A.criticalTemperatureC(t,e);return(A.mixingSlope(t,e)*(a-n)+A.saturationOverWaterPa(n))/A.saturationOverWaterPa(a)}static evaluate(t,e){const a=A.criticalTemperatureC(t.pressureHpa,e),n=A.requiredHumidity(t.pressureHpa,e,t.temperatureC),i=A.iceRelativeHumidity(t.temperatureC,t.relativeHumidity),o=t.temperatureC<a&&t.relativeHumidity>=n;return{forms:o,persistent:o&&i>=1,criticalTemperatureC:a,requiredHumidity:n,iceRelativeHumidity:i}}}class C{static HOLD_MS=36e5;static DEG=Math.PI/180;static GAS_CONSTANT_OVER_GRAVITY=287.05/9.80665;static at(t,e,a){if(t.length===0)return;const n=t[0],i=t[t.length-1];if(e<n.t-C.HOLD_MS||e>i.t+C.HOLD_MS)return;const o=t.findIndex(h=>h.t>e),s=o===0?t[0]:t[(o===-1?t.length:o)-1],r=o===-1||o===0?s:t[o],u=C.atLevel(s,a),c=C.atLevel(r,a);if(!u||!c)return;const d=r.t>s.t?Math.min(1,Math.max(0,(e-s.t)/(r.t-s.t))):0,l=(h,p)=>h+(p-h)*d;return{pressureHpa:a,temperatureC:l(u.temperatureC,c.temperatureC),relativeHumidity:l(u.relativeHumidity,c.relativeHumidity),driftEastMs:l(u.driftEastMs,c.driftEastMs),driftNorthMs:l(u.driftNorthMs,c.driftNorthMs),shearPerS:l(u.shearPerS,c.shearPerS)}}static atLevel(t,e){const a=t.levels;for(let n=0;n+1<a.length;n++){const i=a[n],o=a[n+1];if(e>i.pressureHpa||e<o.pressureHpa)continue;const s=(Math.log(i.pressureHpa)-Math.log(e))/(Math.log(i.pressureHpa)-Math.log(o.pressureHpa)),r=(h,p)=>h+(p-h)*s,u=h=>{const p=h.windFromDeg*C.DEG;return{east:-h.windSpeedMs*Math.sin(p),north:-h.windSpeedMs*Math.cos(p)}},c=u(i),d=u(o),l=C.GAS_CONSTANT_OVER_GRAVITY*((i.temperatureC+o.temperatureC)/2+273.15)*Math.log(i.pressureHpa/o.pressureHpa);return{pressureHpa:e,temperatureC:r(i.temperatureC,o.temperatureC),relativeHumidity:r(i.relativeHumidity,o.relativeHumidity),driftEastMs:r(c.east,d.east),driftNorthMs:r(c.north,d.north),shearPerS:Math.hypot(d.east-c.east,d.north-c.north)/l}}}}class H{static MIN_ALTITUDE_FT=2e4;static DENSE_MS=3e5;static SPARSE_STEP_MS=6e4;static SATURATION_HORIZON_MS=3*36e5;static SATURATION_STEP_MS=6e5;static PRESSURE_STEP_HPA=5;static plan(t,e,a,n){if(a.length===0)return[];const i=[],o=new Map,s=(r,u,c)=>{const d=Math.round(u/H.PRESSURE_STEP_HPA)*H.PRESSURE_STEP_HPA,l=H.SATURATION_STEP_MS,h=Math.floor(r/l)*l,p=`${d}|${h}`,g=o.get(p);if(g!==void 0)return g+(h-r)/1e3;let M=1/0;for(let b=l;b<=H.SATURATION_HORIZON_MS;b+=l){const R=C.at(a,h+b,d);if(!R)break;if(A.evaluate(R,c).iceRelativeHumidity<1){M=b/1e3;break}}return o.set(p,M),M+(h-r)/1e3};for(const r of t.objects){const u=t.flights.get(r.id),c=r.track;if(!u||!c||c.length!==u.points.length)continue;const d=e?.get(z.keyOf(u))??k.of(void 0),l=$.efficiencyOf(d.kind);if(l===void 0)continue;const h=[];let p=-1/0;c.forEach((g,M)=>{if(g.t<-H.DENSE_MS&&M+1<c.length&&g.t-p<H.SPARSE_STEP_MS)return;p=g.t;const b=u.points[M],R=A.pressureAtAltitudeFt(b.altitudeFt),S=C.at(a,n+g.t,R),f=S&&A.evaluate(S,l);h.push({tMs:g.t,eastM:g.eastM,northM:g.northM,upM:g.altitudeM??0,forms:f?.forms??!1,persistent:f?.persistent??!1,lifetimeS:f?Z.lifetimeS(f.iceRelativeHumidity):0,driftEastMs:S?.driftEastMs??0,driftNorthMs:S?.driftNorthMs??0,shearPerS:S?.shearPerS??Z.TYPICAL_SHEAR_PER_S,iceRelativeHumidity:f?.iceRelativeHumidity??0,saturatedForS:f?.persistent?s(n+g.t,R,l):0})}),h.some((g,M)=>g.forms&&h[M+1]?.forms)&&i.push({id:r.id,spanM:d.spanM,points:h})}return i}}class T{static DEFAULT_KIND="airliner-narrow";static STEP_MS=1e3;static LEAD_MS=12e4;static FT_PER_M=1/.3048;static ID_PREFIX="decor:";tracks=new Map;static kindOf(t,e){if(t.kind!=="aircraft"||!T.flies(t))return;const a=t.aircraftSound??e??T.DEFAULT_KIND;return a==="silent"?void 0:a}static flies(t){return(t.track??[]).some(e=>(e.altitudeM??0)>0)}voices(t,e,a,n={},i=()=>{}){const o=t.event.place?.[0];if(!o)return[];const s=new Map,r=new Map,u=Math.max(t.observerTrack.duration,(t.event.durationSeconds??0)*1e3);for(const c of t.decor){const d=T.kindOf(c,i(c));if(!d)continue;const l=`${T.ID_PREFIX}${c.id}`;s.set(l,this.trackOf(c,l,o,u)),r.set(l,d)}for(const c of this.tracks.keys())s.has(c)||this.tracks.delete(c);return s.size===0?[]:O.voices(new Set(s.keys()),s,new Map,c=>String(c.icao),a,e,{...n,kindOf:c=>r.get(c)})}trackOf(t,e,a,n){const i=JSON.stringify([t.track,t.eastM,t.northM,t.headingDeg,a.lat,a.lng,n]),o=this.tracks.get(e);if(o?.key===i)return o.track;const s=[];for(let l=0;l<=n;l+=T.STEP_MS)s.push(T.pointAt(t,l,a));(s.length===0||s[s.length-1].t<n)&&s.push(T.pointAt(t,n,a));const r=s[0],u=s[1]??r,c=l=>(u[l]-r[l])/(u.t-r.t||1);for(let l=T.STEP_MS*10;l<=T.LEAD_MS;l+=T.STEP_MS*10)s.unshift({t:-l,lat:r.lat-c("lat")*l,lng:r.lng-c("lng")*l,altitudeFt:Math.max(0,r.altitudeFt-c("altitudeFt")*l)});const d={icao:T.hash(e),nonIcao:!0,points:s};return this.tracks.set(e,{key:i,track:d}),d}static pointAt(t,e,a){const n=ut(t,e),i=q(n.eastM,-n.northM,a.lat,a.lng);return{t:e,lat:i.lat,lng:i.lng,altitudeFt:n.altitudeM*T.FT_PER_M}}static hash(t){let e=0;for(let a=0;a<t.length;a++)e=e*31+t.charCodeAt(a)>>>0;return e}}class G{static STEP_MS=250;static FT_PER_M=1/.3048;static ID_PREFIX="body:";tracks=new Map;static noiseOf(t){const e=m.noiseOfKind(t.kind),a=t.quieterDb??0;return a===0?e:{...e,id:`${e.id}-${a}dB`,soundPowerA:e.soundPowerA.map(n=>n-a)}}voices(t,e,a,n,i,o,s={}){const r=new Map,u=new Map,c=new Map;for(const l of t){if(!l.sound)continue;const h=`${G.ID_PREFIX}${l.id}`,p=this.trackOf(l,h,e,n,o);p&&(r.set(h,p),u.set(h,l.sound.kind),c.set(h,G.noiseOf(l.sound)))}for(const l of this.tracks.keys())r.has(l)||this.tracks.delete(l);if(r.size===0)return[];const d=q(a.eastM,-a.northM,n.lat,n.lng);return O.voices(new Set(r.keys()),r,new Map,l=>String(l.icao),{lat:d.lat,lng:d.lng,heightM:a.upM},i,{...s,kindOf:l=>u.get(l),noiseOf:l=>c.get(l)})}trackOf(t,e,a,n,i){const o=`${n.lat},${n.lng},${i}`,s=this.tracks.get(e);if(s&&s.body===t&&s.origin===o)return s.track;const r=[];for(let c=-12e4;c<=i;c+=G.STEP_MS){const d=a(t,c);if(!d)continue;const l=q(d.eastM,-d.northM,n.lat,n.lng);r.push({t:c,lat:l.lat,lng:l.lng,altitudeFt:d.upM*G.FT_PER_M})}if(r.length<2)return;const u={icao:G.hash(e),nonIcao:!0,points:r};return this.tracks.set(e,{body:t,origin:o,track:u}),u}static hash(t){let e=0;for(let a=0;a<t.length;a++)e=e*31+t.charCodeAt(a)>>>0;return e}}export{Y as AircraftAudio,H as AircraftContrails,k as AircraftModels,_ as AmbientNoise,G as BodyHearing,T as DecorAircraftHearing,D as TrafficDecor,wt as TrafficInfos,O as TrafficSound,W as TrafficTooltip,Ht as UPPER_AIR_SOURCES};
|