@rr0/ufoathome 0.55.2 → 0.55.3

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.
@@ -6115,4 +6115,4 @@ void main() {
6115
6115
  }
6116
6116
  `;let Uo;function Nw(){if(Uo)return Uo;const s=128,e=document.createElement("canvas");e.width=s,e.height=s;const t=e.getContext("2d"),n=t.createRadialGradient(s/2,s/2,0,s/2,s/2,s/2);return n.addColorStop(0,"rgba(255,255,255,1)"),n.addColorStop(.4,"rgba(255,255,255,0.35)"),n.addColorStop(1,"rgba(255,255,255,0)"),t.fillStyle=n,t.fillRect(0,0,s,s),Uo=new _i(e),Uo}function Ow(s){const t=document.createElement("canvas");t.width=128,t.height=128;const n=t.getContext("2d"),i=128/2-2,r=128/2,a=128/2,o="#2e2b26",c="#f4f1e2";n.fillStyle=o,n.beginPath(),n.arc(r,a,i,0,Math.PI*2),n.fill();const l=dc(s.illuminatedFraction,0,1),h=s.phaseFraction<.5,u=i*Math.abs(1-2*l),d=l<.5;return n.save(),n.beginPath(),n.arc(r,a,i,0,Math.PI*2),n.clip(),n.fillStyle=c,n.beginPath(),h?(n.arc(r,a,i,-Math.PI/2,Math.PI/2,!1),n.ellipse(r,a,u,i,0,Math.PI/2,-Math.PI/2,d)):(n.arc(r,a,i,Math.PI/2,-Math.PI/2,!1),n.ellipse(r,a,u,i,0,-Math.PI/2,Math.PI/2,d)),n.fill(),n.restore(),new _i(t)}function Uw(s){const e=document.createElement("canvas");e.width=128,e.height=128;const t=e.getContext("2d");return t.fillStyle="rgba(0, 0, 0, 0.55)",t.beginPath(),t.arc(64,64,60,0,Math.PI*2),t.fill(),t.fillStyle="#ffffff",t.font="bold 52px sans-serif",t.textAlign="center",t.textBaseline="middle",t.fillText(s,64,68),new _i(e)}function Ul(s){let e=s;return function(){e|=0,e=e+1831565813|0;let n=Math.imul(e^e>>>15,1|e);return n=n+Math.imul(n^n>>>7,61|n)^n,((n^n>>>14)>>>0)/4294967296}}const Fl=7.5,kl=9;class oi{static cache=new Map;static load(e){let t=oi.cache.get(e);return t||(t=fetch(e).then(n=>n.arrayBuffer()).then(n=>oi.parse(n)),oi.cache.set(e,t)),t}static upTo(e,t){const n=e.filter((a,o)=>o===0||e[o-1].magnitudeLimit<t);if(n.length<=1)return oi.load(e[0].url);const i=n.map(a=>a.url).join(`
6117
6117
  `);let r=oi.cache.get(i);return r||(r=Promise.all(n.map(a=>oi.load(a.url))).then(a=>a.reduce((o,c)=>oi.concat(o,c))),oi.cache.set(i,r)),r}static parse(e){const t=e.byteLength/(4*Float32Array.BYTES_PER_ELEMENT),n=t*Float32Array.BYTES_PER_ELEMENT;return{count:t,ra:new Float32Array(e,0*n,t),dec:new Float32Array(e,1*n,t),mag:new Float32Array(e,2*n,t),ci:new Float32Array(e,3*n,t)}}static concat(e,t){const n=(i,r)=>{const a=new Float32Array(i.length+r.length);return a.set(i,0),a.set(r,i.length),a};return{count:e.count+t.count,ra:n(e.ra,t.ra),dec:n(e.dec,t.dec),mag:n(e.mag,t.mag),ci:n(e.ci,t.ci)}}}const Fw=new URL(""+new URL("rain-BvWZrB9h.ogg",import.meta.url).href,import.meta.url).href,kw=new URL(""+new URL("wind-BjklexY7.ogg",import.meta.url).href,import.meta.url).href,zw=new URL(""+new URL("thunder-DA48qs_v.wav",import.meta.url).href,import.meta.url).href,Bw=20,Hw=1;class Gw{context;buffers=new Map;ambientSource;ambientGain;ambientKey="none";ambientToken=0;ambientVolume=0;windSource;windGain;windActive=!1;windToken=0;windVolume=0;paused=!0;requested={type:"none",intensity:0,windSpeed:0};resume(){if(!this.context){if(typeof AudioContext>"u")return;try{this.context=new AudioContext}catch(e){console.warn("WeatherAudio: Web Audio unavailable, weather sounds disabled:",e);return}}this.context.state==="suspended"&&this.context.resume()}setAmbient(e,t,n){if(this.requested={type:e,intensity:t,windSpeed:n},!this.context)return;this.paused&&(e="none",t=0,n=0);const i=e==="rain"||e==="hail"?e:"none";if(this.ambientVolume=i==="hail"?Math.min(1,t*1.3+.2):i==="rain"?t:0,i!==this.ambientKey){this.ambientKey=i;const a=++this.ambientToken;this.stopSource(this.ambientSource,this.ambientGain),this.ambientSource=void 0,this.ambientGain=void 0,i!=="none"&&this.startLoop(Fw,this.ambientVolume).then(o=>this.applyIfCurrent(o,a,()=>this.ambientToken,c=>{this.ambientSource=c?.source,this.ambientGain=c?.gain,c&&(c.gain.gain.value=this.ambientVolume)}))}else this.ambientGain&&(this.ambientGain.gain.value=this.ambientVolume);this.windVolume=Math.min(n/Bw,1);const r=n>Hw;if(r!==this.windActive){this.windActive=r;const a=++this.windToken;this.stopSource(this.windSource,this.windGain),this.windSource=void 0,this.windGain=void 0,r&&this.startLoop(kw,this.windVolume).then(o=>this.applyIfCurrent(o,a,()=>this.windToken,c=>{this.windSource=c?.source,this.windGain=c?.gain,c&&(c.gain.gain.value=this.windVolume)}))}else this.windGain&&(this.windGain.gain.value=this.windVolume)}setPaused(e){if(e===this.paused)return;this.paused=e;const{type:t,intensity:n,windSpeed:i}=this.requested;this.setAmbient(t,n,i)}playThunder(){!this.context||this.paused||this.playOneShot(zw,.9)}dispose(){this.ambientToken++,this.windToken++,this.stopSource(this.ambientSource,this.ambientGain),this.stopSource(this.windSource,this.windGain),this.ambientSource=void 0,this.ambientGain=void 0,this.windSource=void 0,this.windGain=void 0,this.context?.close(),this.context=void 0,this.buffers.clear()}applyIfCurrent(e,t,n,i){if(t!==n()){e?.source.stop();return}i(e)}async startLoop(e,t){const n=this.context;if(n)try{const i=await this.getBuffer(e),r=n.createBufferSource();r.buffer=i,r.loop=!0;const a=n.createGain();return a.gain.value=t,r.connect(a).connect(n.destination),r.start(),{source:r,gain:a}}catch(i){console.warn("Weather ambient sound failed to load, staying silent:",i);return}}async playOneShot(e,t){const n=this.context;if(n)try{const i=await this.getBuffer(e),r=n.createBufferSource();r.buffer=i;const a=n.createGain();a.gain.value=t,r.connect(a).connect(n.destination),r.start()}catch(i){console.warn("Thunder sound failed to load:",i)}}async getBuffer(e){const t=this.context;if(!t)throw new Error("WeatherAudio: AudioContext not ready — resume() must be called first");let n=this.buffers.get(e);return n||(n=fetch(e).then(i=>{if(!i.ok)throw new Error(`Audio fetch failed (${i.status}): ${e}`);return i.arrayBuffer()}).then(i=>t.decodeAudioData(i)),this.buffers.set(e,n)),n}stopSource(e,t){try{e?.stop()}catch{}e?.disconnect(),t?.disconnect()}}class Ci{constructor(e){this.elements=e;const{eccentricity:t,perihelionAu:n}=e,[i,r]=this.perifocalAxes(),a=Math.sqrt(Ci.SUN_GM_AU3_PER_DAY2*(1+t)/n);this.perihelionPosition=this.scale(i,n),this.perihelionVelocity=this.scale(r,a),this.inverseSemiMajorAxis=(1-t)/n}static SUN_GM_AU3_PER_DAY2=.0002959122082855911;static MAX_ITERATIONS=200;perihelionPosition;perihelionVelocity;inverseSemiMajorAxis;positionAt(e){const t=e-this.elements.perihelionJd,n=this.universalAnomaly(t),i=this.inverseSemiMajorAxis*n*n,r=this.elements.perihelionAu,a=1-n*n/r*Ci.stumpffC(i),o=t-n*n*n/Math.sqrt(Ci.SUN_GM_AU3_PER_DAY2)*Ci.stumpffS(i);return{x:a*this.perihelionPosition.x+o*this.perihelionVelocity.x,y:a*this.perihelionPosition.y+o*this.perihelionVelocity.y,z:a*this.perihelionPosition.z+o*this.perihelionVelocity.z}}heliocentricDistanceAt(e){const t=this.positionAt(e);return Math.hypot(t.x,t.y,t.z)}universalAnomaly(e){if(e===0)return 0;const t=Math.sign(e),n=Math.sqrt(Ci.SUN_GM_AU3_PER_DAY2)*Math.abs(e),i=o=>{const c=this.inverseSemiMajorAxis*o*o,l=this.elements.perihelionAu;return(1-this.inverseSemiMajorAxis*l)*o*o*o*Ci.stumpffS(c)+l*o};let r=Math.max(1,n/this.elements.perihelionAu);for(;i(r)<n;)r*=2;let a=0;for(let o=0;o<Ci.MAX_ITERATIONS&&r-a>1e-13*Math.max(1,r);o++){const c=(a+r)/2;i(c)<n?a=c:r=c}return t*(a+r)/2}perifocalAxes(){const e=this.elements.ascendingNodeDeg*Math.PI/180,t=this.elements.argumentOfPerihelionDeg*Math.PI/180,n=this.elements.inclinationDeg*Math.PI/180,i=Math.cos(e),r=Math.sin(e),a=Math.cos(t),o=Math.sin(t),c=Math.cos(n),l=Math.sin(n);return[{x:i*a-r*o*c,y:r*a+i*o*c,z:o*l},{x:-i*o-r*a*c,y:-r*o+i*a*c,z:a*l}]}scale(e,t){return{x:e.x*t,y:e.y*t,z:e.z*t}}static stumpffC(e){if(Math.abs(e)<1e-6)return 1/2-e/24+e*e/720;if(e>0)return(1-Math.cos(Math.sqrt(e)))/e;const t=Math.sqrt(-e);return(Math.cosh(t)-1)/-e}static stumpffS(e){if(Math.abs(e)<1e-6)return 1/6-e/120+e*e/5040;if(e>0){const n=Math.sqrt(e);return(n-Math.sin(n))/(n*n*n)}const t=Math.sqrt(-e);return(Math.sinh(t)-t)/(t*t*t)}}const Gm=[{id:"halley-1910",designation:"1P/Halley",name:{en:"Halley's Comet",fr:"comète de Halley"},orbit:{eccentricity:.9672960498922706,perihelionAu:.5872100477652511,inclinationDeg:162.218798367122,ascendingNodeDeg:58.56208298700436,argumentOfPerihelionDeg:111.7366940639061,perihelionJd:2.4187816784171113e6},peakMagnitude:0,peakOn:"1910-05-20",absoluteMagnitude:4.72,activityExponent:4,tailLengthDeg:100,tailLengthAu:.1638,note:"Passed 0.15 au from Earth on 20 May 1910, and the Earth crossed the outer tail the day before — the apparition that produced a genuine public panic."},{id:"brooks-1911",designation:"C/1911 O1",name:{en:"Comet Brooks",fr:"comète Brooks"},orbit:{eccentricity:.9876404970138669,perihelionAu:.4898172916113738,inclinationDeg:33.34043866978714,ascendingNodeDeg:293.7022074981857,argumentOfPerihelionDeg:153.5578007321686,perihelionJd:2.4193378856140426e6},peakMagnitude:2,peakOn:"1911-10-25",absoluteMagnitude:5.59,activityExponent:4},{id:"skjellerup-maristany-1927",designation:"C/1927 X1",name:{en:"Comet Skjellerup-Maristany",fr:"comète Skjellerup-Maristany"},orbit:{eccentricity:.999839726885059,perihelionAu:.1761569619628186,inclinationDeg:85.1125991950808,ascendingNodeDeg:78.24360172472711,argumentOfPerihelionDeg:47.15877857390136,perihelionJd:2.4252326808989984e6},peakMagnitude:-6,peakOn:"1927-12-15",absoluteMagnitude:1.19,activityExponent:4,note:"One of the few comets of the century seen in full daylight."},{id:"de-kock-paraskevopoulos-1941",designation:"C/1941 B2",name:{en:"Comet de Kock-Paraskevopoulos",fr:"comète de Kock-Paraskevopoulos"},orbit:{eccentricity:.9991026715181549,perihelionAu:.7900329662827822,inclinationDeg:168.2039226531089,ascendingNodeDeg:43.10609347214336,argumentOfPerihelionDeg:268.6990344196369,perihelionJd:2430022157765061e-9},peakMagnitude:2,peakOn:"1941-02-05",absoluteMagnitude:5.01,activityExponent:4},{id:"southern-1947",designation:"C/1947 X1",name:{en:"the Southern Comet",fr:"comète australe"},orbit:{eccentricity:.9998424430916737,perihelionAu:.1100045955093761,inclinationDeg:138.5113919632757,ascendingNodeDeg:337.3114969669252,argumentOfPerihelionDeg:196.1820121395961,perihelionJd:2.4325220864727003e6},peakMagnitude:-3,peakOn:"1947-12-08",absoluteMagnitude:3.01,activityExponent:4,note:"A bright southern-hemisphere comet of December 1947, the month the American sighting wave of that year was still being argued over."},{id:"eclipse-1948",designation:"C/1948 V1",name:{en:"the Eclipse Comet",fr:"comète de l'éclipse"},orbit:{eccentricity:.9999130678247334,perihelionAu:.1354437057263306,inclinationDeg:23.11668597152911,ascendingNodeDeg:211.0454985994762,argumentOfPerihelionDeg:107.2474157073104,perihelionJd:2.4328519265329437e6},peakMagnitude:-2,peakOn:"1948-11-01",absoluteMagnitude:4.79,activityExponent:4,note:"Found during the total solar eclipse of 1 November 1948, which is how a comet that bright had gone unnoticed: it had been hidden in the Sun's glare."},{id:"arend-roland-1957",designation:"C/1956 R1",name:{en:"Comet Arend-Roland",fr:"comète Arend-Roland"},orbit:{eccentricity:1.0002570255357,perihelionAu:.3160532361485914,inclinationDeg:119.9440863251822,ascendingNodeDeg:215.8548157717755,argumentOfPerihelionDeg:308.775920364167,perihelionJd:2.4359365327396123e6},peakMagnitude:.5,peakOn:"1957-04-25",absoluteMagnitude:3.96,activityExponent:4,note:"Showed a spike pointing back TOWARD the Sun in late April 1957 — a real anti-tail, and much reported at the time."},{id:"mrkos-1957",designation:"C/1957 P1",name:{en:"Comet Mrkos",fr:"comète Mrkos"},orbit:{eccentricity:.9993521583504134,perihelionAu:.3549238508212375,inclinationDeg:93.9433042053929,ascendingNodeDeg:68.32441518619923,argumentOfPerihelionDeg:40.31823675802871,perihelionJd:243605193752228e-8},peakMagnitude:1,peakOn:"1957-08-05",absoluteMagnitude:5.07,activityExponent:4,note:"The second bright naked-eye comet of 1957, four months after Arend-Roland."},{id:"seki-lines-1962",designation:"C/1962 C1",name:{en:"Comet Seki-Lines",fr:"comète Seki-Lines"},orbit:{eccentricity:1.000003791331562,perihelionAu:.03139689112215131,inclinationDeg:65.01487186102287,ascendingNodeDeg:304.6776602796538,argumentOfPerihelionDeg:11.47295326312573,perihelionJd:2437756163010178e-9},peakMagnitude:-2.5,peakOn:"1962-04-01",absoluteMagnitude:9.3,activityExponent:4},{id:"ikeya-seki-1965",designation:"C/1965 S1",name:{en:"Comet Ikeya-Seki",fr:"comète Ikeya-Seki"},orbit:{eccentricity:.9999141178248997,perihelionAu:.007785966366889336,inclinationDeg:141.8642315267051,ascendingNodeDeg:346.9951764632611,argumentOfPerihelionDeg:69.04909813996062,perihelionJd:2.4390546837018197e6},peakMagnitude:-10,peakOn:"1965-10-21",alsoRecordedMagnitude:2,alsoRecordedOn:"1965-10-30",absoluteMagnitude:5.26,activityExponent:4.002,tailLengthDeg:25,tailLengthAu:.5048,note:"A sungrazer that passed 450 000 km above the Sun's surface and was seen beside it in broad daylight — the brightest comet of the twentieth century. It then stood in the dawn sky for a fortnight with a tail some 25 degrees long, which is the second magnitude recorded here."},{id:"bennett-1970",designation:"C/1969 Y1",name:{en:"Comet Bennett",fr:"comète Bennett"},orbit:{eccentricity:.9962979048768408,perihelionAu:.5376209981502136,inclinationDeg:90.03975717147327,ascendingNodeDeg:224.6576652531314,argumentOfPerihelionDeg:354.1494209173161,perihelionJd:2.4406655455270996e6},peakMagnitude:0,peakOn:"1970-03-26",absoluteMagnitude:3.36,activityExponent:4},{id:"white-ortiz-bolelli-1970",designation:"C/1970 K1",name:{en:"Comet White-Ortiz-Bolelli",fr:"comète White-Ortiz-Bolelli"},orbit:{eccentricity:.9999488875801225,perihelionAu:.00884411465256722,inclinationDeg:138.9520738221631,ascendingNodeDeg:336.8194095816687,argumentOfPerihelionDeg:61.10224765396615,perihelionJd:2.4407209807728203e6},peakMagnitude:1,peakOn:"1970-05-22",absoluteMagnitude:4.35,activityExponent:4},{id:"kohoutek-1973",designation:"C/1973 E1",name:{en:"Comet Kohoutek",fr:"comète Kohoutek"},orbit:{eccentricity:1.000007152175185,perihelionAu:.1424250377812859,inclinationDeg:14.30414984159355,ascendingNodeDeg:258.4893339663974,argumentOfPerihelionDeg:37.79772760699667,perihelionJd:2442044930687027e-9},peakMagnitude:0,peakOn:"1974-01-05",absoluteMagnitude:4.89,activityExponent:4,note:"Announced in advance as the comet of the century and remembered for disappointing: it was an ordinary naked-eye object, not the spectacle the press had promised."},{id:"west-1976",designation:"C/1975 V1",name:{en:"Comet West",fr:"comète West"},orbit:{eccentricity:1.000017859625611,perihelionAu:.1966006188461085,inclinationDeg:43.07319920579427,ascendingNodeDeg:118.9189245655447,argumentOfPerihelionDeg:358.4315101259072,perihelionJd:2442833721841768e-9},peakMagnitude:-3,peakOn:"1976-02-25",absoluteMagnitude:4.41,activityExponent:4,tailLengthDeg:30,tailLengthAu:.4325,note:"Broke into four pieces at perihelion. Barely reported at the time — the press had been burned by Kohoutek two years earlier."},{id:"iras-araki-alcock-1983",designation:"C/1983 H1",name:{en:"Comet IRAS-Araki-Alcock",fr:"comète IRAS-Araki-Alcock"},orbit:{eccentricity:.9898409731606003,perihelionAu:.9913412593828502,inclinationDeg:73.25000846947029,ascendingNodeDeg:49.10235754476374,argumentOfPerihelionDeg:192.8506176754439,perihelionJd:2.4454757545235856e6},peakMagnitude:1.7,peakOn:"1983-05-11",absoluteMagnitude:9.04,activityExponent:4,note:"Passed 0.031 au from Earth on 11 May 1983, one of the closest cometary approaches on record: it crossed a quarter of the sky in a night, which no other comet in this list did."},{id:"halley-1986",designation:"1P/Halley",name:{en:"Halley's Comet",fr:"comète de Halley"},orbit:{eccentricity:.9672792271749998,perihelionAu:.5871034488173393,inclinationDeg:162.2422242700916,ascendingNodeDeg:58.85993640671803,argumentOfPerihelionDeg:111.8655480539208,perihelionJd:2.4464709589610207e6},peakMagnitude:2.1,peakOn:"1986-03-10",absoluteMagnitude:2.71,activityExponent:4,note:"The worst-placed return in two thousand years — famous, expected, and for most observers a faint smudge."},{id:"hyakutake-1996",designation:"C/1996 B2",name:{en:"Comet Hyakutake",fr:"comète Hyakutake"},orbit:{eccentricity:.9997295133739305,perihelionAu:.2302272039470452,inclinationDeg:124.923592343765,ascendingNodeDeg:188.0454295899424,argumentOfPerihelionDeg:130.1724036582639,perihelionJd:2.4502048946148166e6},peakMagnitude:0,peakOn:"1996-03-25",absoluteMagnitude:4.75,activityExponent:4,tailLengthDeg:80,tailLengthAu:1,note:"Passed 0.10 au from Earth in March 1996, five weeks BEFORE perihelion, with a tail measured at some 80 degrees — the longest of the modern era."},{id:"hale-bopp-1997",designation:"C/1995 O1",name:{en:"Comet Hale-Bopp",fr:"comète Hale-Bopp"},orbit:{eccentricity:.9951314746156615,perihelionAu:.9141695067003724,inclinationDeg:89.43017155012492,ascendingNodeDeg:282.470602866853,argumentOfPerihelionDeg:130.5872524854533,perihelionJd:2450539633099368e-9},peakMagnitude:-.8,peakOn:"1997-04-01",absoluteMagnitude:-1.06,activityExponent:4,tailLengthDeg:20,tailLengthAu:.9938,note:"Visible to the naked eye for about eighteen months, longer than any comet on record."},{id:"mcnaught-2007",designation:"C/2006 P1",name:{en:"Comet McNaught",fr:"comète McNaught"},orbit:{eccentricity:1.00001811603225,perihelionAu:.1707325614080681,inclinationDeg:77.83726446452654,ascendingNodeDeg:267.4149080498975,argumentOfPerihelionDeg:155.9756130642756,perihelionJd:2454113298753579e-9},peakMagnitude:-5.5,peakOn:"2007-01-13",absoluteMagnitude:2.53,activityExponent:4,tailLengthDeg:35,tailLengthAu:.5009,note:"The brightest comet since Ikeya-Seki, seen in daylight beside the Sun in January 2007."},{id:"lovejoy-2011",designation:"C/2011 W3",name:{en:"Comet Lovejoy",fr:"comète Lovejoy"},orbit:{eccentricity:.999915056276912,perihelionAu:.005553783989325053,inclinationDeg:134.3558712062691,ascendingNodeDeg:326.3693517957772,argumentOfPerihelionDeg:53.50991655176601,perihelionJd:2455911511809431e-9},peakMagnitude:-3,peakOn:"2011-12-16",alsoRecordedMagnitude:1.5,alsoRecordedOn:"2011-12-22",absoluteMagnitude:3.51,activityExponent:1.194,note:"A sungrazer that was expected to be destroyed at perihelion and came out the other side, to stand in the southern dawn sky for the rest of December — which is the second magnitude recorded here."},{id:"panstarrs-2013",designation:"C/2011 L4",name:{en:"Comet PANSTARRS",fr:"comète PANSTARRS"},orbit:{eccentricity:1.000032542889696,perihelionAu:.301544229714915,inclinationDeg:84.2081978367921,ascendingNodeDeg:65.66588626213694,argumentOfPerihelionDeg:333.6516444379993,perihelionJd:2456361669960698e-9},peakMagnitude:1,peakOn:"2013-03-10",absoluteMagnitude:5.98,activityExponent:4},{id:"neowise-2020",designation:"C/2020 F3",name:{en:"Comet NEOWISE",fr:"comète NEOWISE"},orbit:{eccentricity:.9991782081129224,perihelionAu:.2946512466331692,inclinationDeg:128.9375043020912,ascendingNodeDeg:61.01042991771634,argumentOfPerihelionDeg:37.2786526292898,perihelionJd:2.4590341788972816e6},peakMagnitude:.9,peakOn:"2020-07-08",absoluteMagnitude:5.79,activityExponent:4,tailLengthDeg:10,tailLengthAu:.1808,note:"The first comet since Hale-Bopp that ordinary observers in the northern hemisphere saw without being told where to look."},{id:"tsuchinshan-atlas-2024",designation:"C/2023 A3",name:{en:"Comet Tsuchinshan-ATLAS",fr:"comète Tsuchinshan-ATLAS"},orbit:{eccentricity:1.000020192843226,perihelionAu:.3914228969475176,inclinationDeg:139.1105462619479,ascendingNodeDeg:21.55945689078845,argumentOfPerihelionDeg:308.4913086299446,perihelionJd:2460581242087108e-9},peakMagnitude:0,peakOn:"2024-10-14",absoluteMagnitude:3.97,activityExponent:4,tailLengthDeg:20,tailLengthAu:.1902,note:"Briefly reported far brighter around 9 October 2024, when it stood almost between the observer and the Sun and forward-scattered the light through its own dust — a geometry this catalog's brightness model does not attempt, so what is stored is the ordinary evening-sky peak a few days later."}];class Vw{static WINDOW_DAYS=200;static TWILIGHT_ELONGATION_DEG=15;static LIGHT_SPEED_AU_PER_DAY=173.144632674;static orbits=new Map;static aroundDate(e){const t=this.julianDayOf(e);return Gm.filter(n=>Math.abs(t-n.orbit.perihelionJd)<=this.WINDOW_DAYS)}static brightestAt(e,t){return this.aroundDate(e).map(n=>this.appearanceOf(n,e,t)).sort((n,i)=>n.magnitude-i.magnitude)[0]}static appearanceOf(e,t,n){const i=Vt(t),r=this.earthPositionAt(i),a=this.apparentPositionOf(e,2451545+i.tt,r),o=this.subtract(a,r),c=this.length(a),l=this.length(o),h=this.tailEndAt(e,a,r,c,i,t,n),u=this.horizontalOf(o,i,t,n);return{apparition:e,position:u,...h,heliocentricDistanceAu:c,earthDistanceAu:l,elongationDeg:this.angleBetween(o,this.subtract({x:0,y:0,z:0},r)),magnitude:this.magnitudeAt(e,c,l)}}static magnitudeAt(e,t,n){const i=e.absoluteMagnitude+5*Math.log10(n)+2.5*e.activityExponent*Math.log10(t);return Math.max(i,e.peakMagnitude)}static tailEndAt(e,t,n,i,r,a,o){if(e.tailLengthAu===void 0)return{};const c=1+e.tailLengthAu/i,l=this.subtract({x:t.x*c,y:t.y*c,z:t.z*c},n),h=this.subtract(t,n);return{tailEnd:this.horizontalOf(l,r,a,o),tailLengthDeg:this.angleBetween(h,l)}}static apparentPositionOf(e,t,n){const i=this.orbitOf(e);let r=i.positionAt(t);for(let a=0;a<2;a++){const o=this.length(this.subtract(r,n))/this.LIGHT_SPEED_AU_PER_DAY;r=i.positionAt(t-o)}return r}static horizontalOf(e,t,n,i){const r=qo(kS(),new gt(e.x,e.y,e.z,t)),a=qo(zS(t),r),o=mS(t,new Gu(i.lat,i.lng,i.elevationM)),c=new gt(a.x-o.x,a.y-o.y,a.z-o.z,t),l=Tm(c);return Ir(l.ra,l.dec,n,i)}static earthPositionAt(e){return qo(FS(),ls(Se.Earth,e))}static julianDayOf(e){return 2451545+Vt(e).tt}static orbitOf(e){const t=this.orbits.get(e.id);if(t)return t;const n=new Ci(e.orbit);return this.orbits.set(e.id,n),n}static subtract(e,t){return{x:e.x-t.x,y:e.y-t.y,z:e.z-t.z}}static length(e){return Math.hypot(e.x,e.y,e.z)}static angleBetween(e,t){const n=(e.x*t.x+e.y*t.y+e.z*t.z)/(this.length(e)*this.length(t)||1);return Math.acos(Math.min(1,Math.max(-1,n)))*180/Math.PI}}const Ww=[{id:"quadrantids",code:"QUA",name:{en:"Quadrantids",fr:"Quadrantides"},radiantRaHours:15.33,radiantDecDeg:49.7,start:{month:12,day:28},peak:{month:1,day:3},end:{month:1,day:12},peakZhr:110,velocityKmS:41,populationIndex:2.1},{id:"lyrids",code:"LYR",name:{en:"April Lyrids",fr:"Lyrides d'avril"},radiantRaHours:18.13,radiantDecDeg:33.3,start:{month:4,day:16},peak:{month:4,day:22},end:{month:4,day:25},peakZhr:18,velocityKmS:49,populationIndex:2.1},{id:"eta-aquariids",code:"ETA",name:{en:"eta Aquariids",fr:"Êta Aquarides"},radiantRaHours:22.53,radiantDecDeg:-1,start:{month:4,day:19},peak:{month:5,day:6},end:{month:5,day:28},peakZhr:50,velocityKmS:66,populationIndex:2.4},{id:"alpha-capricornids",code:"CAP",name:{en:"alpha Capricornids",fr:"Alpha Capricornides"},radiantRaHours:20.47,radiantDecDeg:-9.2,start:{month:7,day:3},peak:{month:7,day:30},end:{month:8,day:15},peakZhr:5,velocityKmS:23,populationIndex:2.5},{id:"southern-delta-aquariids",code:"SDA",name:{en:"Southern delta Aquariids",fr:"Delta Aquarides du Sud"},radiantRaHours:22.67,radiantDecDeg:-16.4,start:{month:7,day:12},peak:{month:7,day:30},end:{month:8,day:23},peakZhr:25,velocityKmS:41,populationIndex:3.2},{id:"perseids",code:"PER",name:{en:"Perseids",fr:"Perséides"},radiantRaHours:3.22,radiantDecDeg:58,start:{month:7,day:17},peak:{month:8,day:12},end:{month:8,day:24},peakZhr:100,velocityKmS:59,populationIndex:2.2},{id:"southern-taurids",code:"STA",name:{en:"Southern Taurids",fr:"Taurides du Sud"},radiantRaHours:3.47,radiantDecDeg:13,start:{month:9,day:10},peak:{month:10,day:10},end:{month:11,day:20},peakZhr:5,velocityKmS:27,populationIndex:2.3},{id:"draconids",code:"DRA",name:{en:"October Draconids",fr:"Draconides d'octobre"},radiantRaHours:17.47,radiantDecDeg:54,start:{month:10,day:6},peak:{month:10,day:8},end:{month:10,day:10},peakZhr:10,velocityKmS:20,populationIndex:2.6},{id:"orionids",code:"ORI",name:{en:"Orionids",fr:"Orionides"},radiantRaHours:6.35,radiantDecDeg:15.6,start:{month:10,day:2},peak:{month:10,day:21},end:{month:11,day:7},peakZhr:20,velocityKmS:66,populationIndex:2.5},{id:"northern-taurids",code:"NTA",name:{en:"Northern Taurids",fr:"Taurides du Nord"},radiantRaHours:3.87,radiantDecDeg:22,start:{month:10,day:20},peak:{month:11,day:12},end:{month:12,day:10},peakZhr:5,velocityKmS:29,populationIndex:2.3},{id:"leonids",code:"LEO",name:{en:"Leonids",fr:"Léonides"},radiantRaHours:10.13,radiantDecDeg:21.6,start:{month:11,day:6},peak:{month:11,day:17},end:{month:11,day:30},peakZhr:15,velocityKmS:71,populationIndex:2.5},{id:"geminids",code:"GEM",name:{en:"Geminids",fr:"Géminides"},radiantRaHours:7.47,radiantDecDeg:32.3,start:{month:12,day:4},peak:{month:12,day:14},end:{month:12,day:17},peakZhr:150,velocityKmS:35,populationIndex:2.6},{id:"ursids",code:"URS",name:{en:"Ursids",fr:"Ursides"},radiantRaHours:14.47,radiantDecDeg:75.3,start:{month:12,day:17},peak:{month:12,day:22},end:{month:12,day:26},peakZhr:10,velocityKmS:33,populationIndex:3}],fc=6.5;class zl{static activeAt(e){return Ww.flatMap(t=>{const n=this.nearness(t,e);return n<=0?[]:[{shower:t,zhr:t.peakZhr*n,nearness:n}]})}static nearness(e,t){const n=this.dayOfYear(t),i=this.dayOfYear(this.asDate(e.start)),r=this.dayOfYear(this.asDate(e.peak)),a=this.dayOfYear(this.asDate(e.end)),o=this.wrappedDelta(n,r),c=this.wrappedDelta(r,i),l=this.wrappedDelta(a,r);return o<0?o<-c?0:1+o/c:o>0?o>l?0:1-o/l:1}static observedRatePerHour(e,t,n,i=fc){if(t<=0)return 0;const r=fc-i;return e*Math.sin(t*Math.PI/180)/Math.pow(n,r)}static radiantPosition(e,t,n){return Ir(e.radiantRaHours,e.radiantDecDeg,t,n)}static dayOfYear(e){const t=Date.UTC(e.getUTCFullYear(),0,1);return Math.floor((Date.UTC(e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDate())-t)/864e5)+1}static asDate(e){return new Date(Date.UTC(2001,e.month-1,e.day))}static wrappedDelta(e,t){const n=e-t;return n>182?n-365:n<-182?n+365:n}}class Rt{static QUIET_RATE_PER_HOUR=2;static APEX_RATE_PER_HOUR=8;static POPULATION_INDEX=3;static apexPosition(e,t){const n=Vt(e),i=new Bu(0,fS(e).elon-90,1),r=qo(BS(n),Am(i,n)),a=Tm(r);return Ir(a.ra,a.dec,e,t)}static observedRatePerHour(e,t=fc){const n=Rt.APEX_RATE_PER_HOUR*Math.max(0,Math.sin(e*Math.PI/180)),i=fc-t;return(Rt.QUIET_RATE_PER_HOUR+n)/Math.pow(Rt.POPULATION_INDEX,i)}static schedule(e){const t=new Dm(e.seed^1542469173);return Is.schedule(e).map(n=>{const i=Rt.toCartesian({altitudeDeg:Math.asin(t.next())*180/Math.PI,azimuthDeg:t.between(0,360)}),r=n.fromRadiantDeg*Math.PI/180,a=Rt.turnAround(i,t.between(0,360)),o={x:i.x*Math.cos(r)+a.x*Math.sin(r),y:i.y*Math.cos(r)+a.y*Math.sin(r),z:i.z*Math.cos(r)+a.z*Math.sin(r)};return{...n,radiant:Rt.toHorizontal(o),bearingDeg:Rt.bearingFrom(o,i)}})}static turnAround(e,t){const[n,i]=Rt.basisAround(e),r=t*Math.PI/180;return{x:n.x*Math.cos(r)+i.x*Math.sin(r),y:n.y*Math.cos(r)+i.y*Math.sin(r),z:n.z*Math.cos(r)+i.z*Math.sin(r)}}static bearingFrom(e,t){const[n,i]=Rt.basisAround(e),r=e.x*t.x+e.y*t.y+e.z*t.z,a=Rt.normalise({x:t.x-e.x*r,y:t.y-e.y*r,z:t.z-e.z*r});return(Math.atan2(a.x*i.x+a.y*i.y+a.z*i.z,a.x*n.x+a.y*n.y+a.z*n.z)*180/Math.PI%360+360)%360}static basisAround(e){const t=Math.abs(e.y)<.9?{x:0,y:1,z:0}:{x:1,y:0,z:0},n=Rt.normalise(Rt.cross(e,t));return[n,Rt.normalise(Rt.cross(e,n))]}static toHorizontal(e){const t=Math.hypot(e.x,e.y,e.z)||1;return{altitudeDeg:Math.asin(Math.min(1,Math.max(-1,e.y/t)))*180/Math.PI,azimuthDeg:(Math.atan2(e.x,-e.z)*180/Math.PI%360+360)%360}}static appearanceOf(e){const t=Rt.toCartesian(e.radiant??{altitudeDeg:90,azimuthDeg:0}),n=Rt.turnAround(t,e.bearingDeg),i=e.fromRadiantDeg*Math.PI/180;return Rt.toHorizontal({x:t.x*Math.cos(i)+n.x*Math.sin(i),y:t.y*Math.cos(i)+n.y*Math.sin(i),z:t.z*Math.cos(i)+n.z*Math.sin(i)})}static toCartesian(e){const t=e.altitudeDeg*Math.PI/180,n=e.azimuthDeg*Math.PI/180,i=Math.cos(t);return{x:i*Math.sin(n),y:Math.sin(t),z:-i*Math.cos(n)}}static cross(e,t){return{x:e.y*t.z-e.z*t.y,y:e.z*t.x-e.x*t.z,z:e.x*t.y-e.y*t.x}}static normalise(e){const t=Math.hypot(e.x,e.y,e.z)||1;return{x:e.x/t,y:e.y/t,z:e.z/t}}static TYPICAL_VELOCITY_KM_S=40}class Xw{lowerM;upperM;add(e,t){if(!(e<=0)){if(t.behindM!==void 0){const n=mt.sizeMAt(t.behindM,e);this.lowerM=this.lowerM===void 0?n:Math.max(this.lowerM,n)}if(t.inFrontM!==void 0){const n=mt.sizeMAt(t.inFrontM,e);this.upperM=this.upperM===void 0?n:Math.min(this.upperM,n)}}}get sizeRange(){return{minM:this.lowerM,maxM:this.upperM}}get empty(){return this.lowerM===void 0&&this.upperM===void 0}get contradictory(){return this.lowerM!==void 0&&this.upperM!==void 0&&this.lowerM>this.upperM}distanceRangeAt(e){return e<=0?{}:{minM:this.lowerM===void 0?void 0:mt.distanceMAt(this.lowerM,e),maxM:this.upperM===void 0?void 0:mt.distanceMAt(this.upperM,e)}}clear(){this.lowerM=void 0,this.upperM=void 0}}class Er{static DEG_PER_SECOND=360/86164.0905;static degOver(e){return Math.max(0,e)*Er.DEG_PER_SECOND}static instants(e,t){if(!(t>0))return 1;const n=Er.degOver(e)/t;return n<1?1:Math.min(Er.MAX_INSTANTS,Math.max(2,Math.ceil(n)))}static MAX_INSTANTS=64}class on{static EYE={apertureMm:7,exposureSeconds:.1,resolutionArcsec:60};static WAVELENGTH_M=55e-8;static ARCSEC_PER_RADIAN=180*3600/Math.PI;static UNKNOWN_CAMERA_FOCAL_MM=50;static UNKNOWN_CAMERA_DETAIL_UM=20;static get skyDriftArcsecPerSecond(){return Er.DEG_PER_SECOND*3600}static graspOf(e,t={}){const n=t.exposureSeconds??e.exposureSeconds,i=t.fNumber??e.fNumber;if(n===void 0||i===void 0||!(n>0)||!(i>0))return on.EYE;const r=t.focalLengthMm??e.frame?.focalLengthMm??on.UNKNOWN_CAMERA_FOCAL_MM,a=r/i,o=on.resolutionArcsec(e,r,a);return{apertureMm:a,exposureSeconds:Math.min(n,on.trailLimitedSeconds(o)),resolutionArcsec:o}}static resolutionArcsec(e,t,n){const r=(e.detailUm??on.UNKNOWN_CAMERA_DETAIL_UM)/1e3/t*on.ARCSEC_PER_RADIAN,a=1.22*on.WAVELENGTH_M/(n/1e3)*on.ARCSEC_PER_RADIAN;return Math.max(r,a)}static trailLimitedSeconds(e){return e/on.skyDriftArcsecPerSecond}static gainOverEye(e,t={}){const n=on.graspOf(e,t),i=on.EYE,r=(n.apertureMm/i.apertureMm)**2,a=n.exposureSeconds/i.exposureSeconds,o=(i.resolutionArcsec/n.resolutionArcsec)**2;return 1.25*Math.log10(r*a*o)}static gainFor(e,t){const n=t.fieldOfViewDeg===void 0?void 0:Lt.focalLengthMmFor(e,t.fieldOfViewDeg);return on.gainOverEye(e,{fNumber:t.fNumber,focalLengthMm:n,exposureSeconds:t.exposureSeconds})}}class Di{static PIXELS_PER_INSTANT=2;static INSTANTS_PER_FLASH=2;static MAX_INSTANTS=512;static instants(e,t,n,i,r){if(!(i>0))return 1;const a=r>0?Di.travelDegOver(e,t,n,n+i*1e3)/r/Di.PIXELS_PER_INSTANT:0,o=Di.flashesOver(e,i)*Di.INSTANTS_PER_FLASH,c=Math.ceil(Math.max(a,o));return c<2?1:Math.min(Di.MAX_INSTANTS,c)}static travelDegOver(e,t,n,i){let r=0;for(const a of e){if(!a.track||a.track.length<2)continue;const o=Di.directionAt(a,t,n),c=Di.directionAt(a,t,i),l=Math.min(1,Math.max(-1,o.x*c.x+o.y*c.y+o.z*c.z));r=Math.max(r,Math.acos(l)*180/Math.PI)}return r}static flashesOver(e,t){let n=0;for(const i of e)for(const r of i.lights??[])r.pattern.kind==="flash"&&(n=Math.max(n,r.pattern.perMinute));return n/60*t}static directionAt(e,t,n){const i=gc(e,n),r=i.eastM,a=i.altitudeM-t,o=i.northM,c=Math.hypot(r,a,o);return c===0?{x:0,y:1,z:0}:{x:r/c,y:a/c,z:o/c}}}const ep=111320,na=Math.PI/180,qw=1.02,Yw=1;class ma{static of(e,t){const n=ma.sightings(e,t);if(n.length<2)return;const i=ma.baseline(n);if(!i)return;const{near:r,far:a,closedM:o}=i,c=Math.tan(a.widthDeg/2*na)===0?0:Math.tan(r.widthDeg/2*na)/Math.tan(a.widthDeg/2*na);if(c<qw)return;const l=o/(c-1),h=mt.sizeMAt(l,r.widthDeg),u=n.map(d=>({t:d.t,m:mt.distanceMAt(h,d.widthDeg)}));return{widthM:h,distanceM:u,nearestM:Math.min(...u.map(d=>d.m)),fromT:a.t,toT:r.t,closedM:o}}static sightings(e,t){return e.timeline.allKeyframes.flatMap(n=>{const i=n.shapes.find(o=>o.sourceId===t)?.shape,r=i?.angular?.widthDeg,a=Kt(e,n.t);return r===void 0||r<=0||a?.lat===void 0||a.lng===void 0?[]:[{t:n.t,widthDeg:r,lat:a.lat,lng:a.lng,sightAzimuthDeg:i?.aim?.azimuthDeg??a.headingDeg}]}).sort((n,i)=>n.t-i.t)}static baseline(e){let t;for(const n of e)for(const i of e){if(n.t>=i.t)continue;const r=ma.closedAlongSight(n,i),[a,o,c]=r>=0?[i,n,r]:[n,i,-r];c<Yw||a.widthDeg<=o.widthDeg||(!t||c>t.closedM)&&(t={near:a,far:o,closedM:c})}return t}static closedAlongSight(e,t){const n=(t.lat-e.lat)*ep,i=(t.lng-e.lng)*ep*Math.cos(e.lat*na),r=(e.sightAzimuthDeg??0)*na;return n*Math.cos(r)+i*Math.sin(r)}}class an{static CONVENTIONAL_M=5;static NEAREST_M=.2;static MARGIN=1.1;static resolve(e){if(e.statedM!==void 0&&e.statedM>0)return{distanceM:an.atLeastNearest(e.statedM),basis:"stated"};if(e.hypothesisM!==void 0&&e.hypothesisM>0)return{distanceM:an.atLeastNearest(e.hypothesisM),basis:"hypothesis"};if(e.derivedM!==void 0&&e.derivedM>0)return{distanceM:an.atLeastNearest(e.derivedM),basis:"derived"};const t=an.largest(e.range?.minM,e.crossing?.behindM),n=an.smallest(e.range?.maxM,e.crossing?.inFrontM),i=t===void 0?void 0:t*an.MARGIN,r=n===void 0?void 0:n/an.MARGIN;return i!==void 0&&r!==void 0?{distanceM:an.atLeastNearest(i<=r?Math.sqrt(i*r):i),basis:"bounded"}:i!==void 0?{distanceM:an.atLeastNearest(i),basis:"bounded"}:r!==void 0&&r<an.CONVENTIONAL_M?{distanceM:an.atLeastNearest(r),basis:"bounded"}:{distanceM:an.CONVENTIONAL_M,basis:"conventional"}}static atLeastNearest(e){return Math.max(an.NEAREST_M,e)}static largest(...e){const t=e.filter(n=>n!==void 0&&n>0);return t.length===0?void 0:Math.max(...t)}static smallest(...e){const t=e.filter(n=>n!==void 0&&n>0);return t.length===0?void 0:Math.min(...t)}}Sp();const Kw={sun:{en:"Sun",fr:"Soleil"},moon:{en:"Moon",fr:"Lune"},Venus:{en:"Venus",fr:"Vénus"},Mars:{en:"Mars",fr:"Mars"},Jupiter:{en:"Jupiter",fr:"Jupiter"},Saturn:{en:"Saturn",fr:"Saturne"}},$w=["en","fr"],Zw={en:"{name} — mag {mag}, {alt}° above the horizon",fr:"{name} — mag {mag}, {alt}° au-dessus de l'horizon"},Jw={en:"{name} — mag {mag}, {alt}° below the horizontal",fr:"{name} — mag {mag}, {alt}° sous l'horizontale"},tp="comet:",jw={building:{en:"Building",fr:"Bâtiment"},tree:{en:"Tree",fr:"Arbre"},crop:{en:"Crop row",fr:"Rang de culture"},mound:{en:"Stone heap",fr:"Tas de pierres"},streetlight:{en:"Streetlight",fr:"Lampadaire"},vehicle:{en:"Vehicle",fr:"Véhicule"},witness:{en:"Witness",fr:"Témoin"},aircraft:{en:"Aircraft",fr:"Aéronef"},entity:{en:"Being",fr:"Être"}},Qw=new URL(""+new URL("stars-mag7.5-B43R6Wvg.bin",import.meta.url).href,import.meta.url).href,eE=new URL(""+new URL("stars-mag7.5-9-BLV2tFmZ.bin",import.meta.url).href,import.meta.url).href,tE=-18,nE={sun:{altitudeDeg:-3,azimuthDeg:180,magnitude:-26.7},moon:{altitudeDeg:-90,azimuthDeg:0,phase:{phaseFraction:0,illuminatedFraction:0},magnitude:-12.7},planets:[]},Bl={lat:0,lng:0,elevationM:0,headingDeg:void 0,pitchDeg:0,fovDeg:60};class iE extends HTMLElement{static get observedAttributes(){return["src","star-catalog-src","deep-star-catalog-src","show-compass",Oi,Ui]}shadow;stageElement;frameElement;sceneCanvas;ufoElement;sceneRenderer;hoverTooltip;resizeObserver;sizeEstimates=new Map;sizeEstimatesFor;distanceHypotheses=new Map;depths=new Map;directionScratch=new P;meteorScheduleFor;lastTimeMs=0;lastSkyKey;starCatalog;starCatalogRequest=0;starCatalogDepth=0;weatherAudio=new Gw;animateWhilePausedValue=!1;set animateWhilePaused(e){e!==this.animateWhilePausedValue&&(this.animateWhilePausedValue=e,this.syncAnimationsToPlayback())}get animateWhilePaused(){return this.animateWhilePausedValue}thunderTimeoutId;handleFullscreenChange=()=>this.resizeToStage();handlePointerMove=e=>{this.sceneRenderer.setCompassHovered(!0);const t=this.ufoElement.canvasElement,n=t.getBoundingClientRect();if(n.width===0||n.height===0)return;const i=(e.clientX-n.left)/n.width*t.width,r=(e.clientY-n.top)/n.height*t.height;if(this.ufoElement.hasVisibleShapeAt(i,r)){this.hoverTooltip.hidden=!0;return}const a=(e.clientX-n.left)/n.width*2-1,o=-((e.clientY-n.top)/n.height*2-1),c=vc(Ar.preferencesFor(this),$w),l=this.sceneRenderer.pickBodyAt(a,o);if(l){this.showHoverTooltip(e,this.bodyName(l,c));return}const h=this.sceneRenderer.pickDecorAt(a,o),u=h?this.ufoElement.sighting.decor.find(f=>f.id===h):void 0;if(u){this.showHoverTooltip(e,this.said.read(u.title)||jw[u.kind][c]);return}const d=this.sceneRenderer.pickStarAt(a,o);if(d){const f=d.star.mag,g=d.altitudeDeg,v=(g<0?Jw:Zw)[c];this.showHoverTooltip(e,v.replace("{name}",d.star.name[c]).replace("{mag}",f.toLocaleString(void 0,{maximumFractionDigits:Math.abs(f)<1?2:1})).replace("{alt}",String(Math.round(Math.abs(g)))));return}this.hoverTooltip.hidden=!0};bodyName(e,t){const n=e.startsWith(tp)?e.slice(tp.length):void 0;return(n?Gm.find(r=>r.id===n):void 0)?.name[t]??Kw[e]?.[t]??e}showHoverTooltip(e,t){this.hoverTooltip.textContent=t,this.hoverTooltip.hidden=!1;const n=this.stageElement.getBoundingClientRect();this.hoverTooltip.style.left=`${e.clientX-n.left+12}px`,this.hoverTooltip.style.top=`${e.clientY-n.top+12}px`}handlePointerLeave=()=>{this.hoverTooltip.hidden=!0,this.sceneRenderer.setCompassHovered(!1)};handleLightningFlash=()=>{clearTimeout(this.thunderTimeoutId);const e=(.5+Math.random()*3.5)*1e3;this.thunderTimeoutId=window.setTimeout(()=>this.weatherAudio.playThunder(),e)};handleFirstInteraction=()=>{this.weatherAudio.resume(),this.setWeather(Gl(this.ufoElement.sighting,this.lastTimeMs))};handleTimeUpdate=e=>{this.lastTimeMs=e.detail.time,this.syncAnimationsToPlayback(),this.updateAstronomy(this.lastTimeMs)};syncAnimationsToPlayback(){const e=this.ufoElement.playbackState==="playing"||this.animateWhilePaused;this.sceneRenderer.setAnimationsRunning(e),this.weatherAudio.setPaused(!e),e||clearTimeout(this.thunderTimeoutId)}constructor(){super(),this.shadow=this.attachShadow({mode:"open"});const e=document.createElement("template");e.innerHTML=`<style>${Ag}</style>${Eg}`,this.shadow.appendChild(e.content.cloneNode(!0)),this.stageElement=this.shadow.getElementById("stage"),this.frameElement=this.shadow.getElementById("frame"),this.sceneCanvas=this.shadow.getElementById("scene-canvas"),this.sceneRenderer=new ai(this.sceneCanvas,void 0,this.handleLightningFlash),this.hoverTooltip=this.shadow.getElementById("hover-tooltip"),this.ufoElement=document.createElement(Xl),this.ufoElement.classList.add("ufo-overlay"),this.ufoElement.paintsShapes=!1,this.forwardPlayerAttributes(),this.ufoElement.addEventListener("lookat",t=>this.lookToward(t.detail)),this.ufoElement.style.setProperty("--ufo-canvas-background","transparent"),this.ufoElement.style.setProperty("--ufo-canvas-border","none"),this.ufoElement.fullscreenTarget=this.stageElement,this.shadow.getElementById("ufo-slot").replaceWith(this.ufoElement),this.ufoElement.addEventListener("timeupdate",this.handleTimeUpdate),this.ufoElement.canvasElement.addEventListener("pointermove",this.handlePointerMove),this.ufoElement.canvasElement.addEventListener("pointerleave",this.handlePointerLeave),this.ufoElement.canvasElement.addEventListener("pointerdown",this.handleFirstInteraction,{once:!0})}get said(){return this.saidTexts??=new fi(Ar.preferencesFor(this))}saidTexts;connectedCallback(){this.saidTexts=void 0,this.resizeToStage(),this.updateAstronomy(this.lastTimeMs),this.loadStars(),this.resizeObserver=new ResizeObserver(()=>this.resizeToStage()),this.resizeObserver.observe(this.frameElement),document.addEventListener("fullscreenchange",this.handleFullscreenChange);const e=this.getAttribute("src");e&&this.loadFromSrc(e)}disconnectedCallback(){this.resizeObserver?.disconnect(),document.removeEventListener("fullscreenchange",this.handleFullscreenChange),this.sceneRenderer.stopTwinkle(),clearTimeout(this.thunderTimeoutId),this.weatherAudio.dispose()}attributeChangedCallback(e,t,n){e==="src"&&n&&n!==t&&this.isConnected&&this.loadFromSrc(n),(e==="star-catalog-src"||e==="deep-star-catalog-src")&&n!==t&&this.isConnected&&this.loadStars(),e==="show-compass"&&n!==t&&this.sceneRenderer.setShowCompass(this.hasAttribute("show-compass")),(e===Oi||e===Ui)&&n!==t&&this.forwardPlayerAttributes()}forwardPlayerAttributes(){for(const e of[Oi,Ui])this.ufoElement.toggleAttribute(e,this.hasAttribute(e))}setCompassForced(e){this.sceneRenderer.setCompassForced(e)}lookToward(e){const t=Kt(this.ufoElement.sighting,this.lastTimeMs);if(e.kind==="witness"||t?.lat===void 0||t.lng===void 0||t.headingDeg===void 0){this.setLookOffset(0,0);return}const{x:n,z:i}=un(e.lat,e.lng,t.lat,t.lng);if(Math.hypot(n,i)<1)return this.setLookOffset(0,0);const r=(Math.atan2(n,-i)*180/Math.PI+360)%360;this.setLookOffset(((r-t.headingDeg)%360+540)%360-180,-t.pitchDeg)}setLookOffset(e,t){this.sceneRenderer.setLookOffset(e,t),this.ufoElement.setLookOffset(e,t),this.updateAstronomy(this.lastTimeMs)}setIndoorLook(e,t){this.sceneRenderer.setIndoorLook(e,t)}setWeather(e){this.sceneRenderer.setWeather(e),this.weatherAudio.setAmbient(e.precipitationType,e.precipitationIntensity,e.windSpeed)}pickDecorAt(e,t){return this.sceneRenderer.pickDecorAt(e,t)}resumeWeatherAudio(){this.weatherAudio.resume()}async loadFromSrc(e){this.sightingData=await Yo.json(e)}get sightingData(){return this.ufoElement.sightingData}set sightingData(e){this.ufoElement.sightingData=e,this.applyFrameFormat(),this.lastTimeMs=0,this.updateAstronomy(0)}get currentTerrainAttribution(){return this.sceneRenderer.currentTerrainAttribution}setTerrainProviders(e){this.sceneRenderer.setTerrainProviders(e)}setDecorModelProvider(e){this.sceneRenderer.setDecorModelProvider(e)}get decorModelCredits(){return this.sceneRenderer.currentDecorModelCredits}applyFrameFormat(){const e=this.ufoElement.sighting.instrument,t=mt.CANVAS_HEIGHT_PX,n=Lt.frameWidthPx(e,t);this.frameElement.style.setProperty("--frame-aspect",`${n} / ${t}`)}resizeToStage(){const e=this.frameElement.getBoundingClientRect(),t=Math.max(1,Math.round(e.width)),n=Math.max(1,Math.round(e.height));this.sceneCanvas.width=t,this.sceneCanvas.height=n,this.sceneRenderer.resize(t,n)}async loadStars(){const e=[{magnitudeLimit:Fl,url:this.getAttribute("star-catalog-src")??Qw},{magnitudeLimit:kl,url:this.getAttribute("deep-star-catalog-src")??eE}],t=this.instrumentReach(),n=++this.starCatalogRequest;this.starCatalogDepth=t>Fl?kl:Fl;const i=await oi.upTo(e,t);n===this.starCatalogRequest&&(this.starCatalog=i,this.updateAstronomy(this.lastTimeMs))}ensureStarsDeepEnough(){!this.starCatalog||this.starCatalogDepth>=kl||this.instrumentReach()<=this.starCatalogDepth||this.loadStars()}instrumentReach(){const e=this.ufoElement.sighting,t=on.gainFor(e.instrument,{fNumber:Kt(e,0)?.fNumber,fieldOfViewDeg:Un.fovOf(e,0),exposureSeconds:e.exposure});return am(tE,t)}updateAstronomy(e){this.ensureStarsDeepEnough(),this.applySceneAt(e);const t=this.exposureSeconds(),n=this.degreesPerPixelAt(e),i=Er.instants(t,n),r=Math.max(i,this.ufoElement.exposureTimes(e).length,Di.instants(this.ufoElement.sighting.decor,Kt(this.ufoElement.sighting,e)?.elevationM??0,e,t,n));if(r<=1){this.sceneRenderer.setExposure(1);return}const a=t*1e3;this.sceneRenderer.setExposure(r,o=>this.applySceneAt(e+a*o/r,{sky:Math.floor(o*i/r)!==Math.floor((o-1)*i/r),stepMs:a/r}))}exposureSeconds(){return this.ufoElement.sighting.exposure??0}degreesPerPixelAt(e){const t=this.sceneCanvas.height;return t<=0?0:Un.fovOf(this.ufoElement.sighting,e)/t}applySceneAt(e,t){const n=this.ufoElement.sighting;this.setWeather(Gl(n,e)),this.sceneRenderer.setInstrument(n.instrument),this.updateMeteorShower(n,e),this.sceneRenderer.setDecor(n.decor);const i=Kt(n,e);if(this.sceneRenderer.setObserverPose(i??Bl),this.sceneRenderer.setLensOptics(this.lensOpticsAt(e)),this.sceneRenderer.setInstrumentGain(on.gainFor(n.instrument,{fNumber:i?.fNumber,fieldOfViewDeg:Un.fovOf(n,e),exposureSeconds:n.exposure})),this.sceneRenderer.setGait(kt.of(n)?.offsetAt(e)??kt.STILL),this.sceneRenderer.updateDecorAnchoring(Kt(n,0),i,e),this.sceneRenderer.updateDecorLitState(e,t?.stepMs??0),this.sceneRenderer.setTerrainOrigin(i?.lat,i?.lng),this.pushPhenomenaAt(e),t&&!t.sky)return;const r=i?.lat??Bl.lat,a=i?.lng??Bl.lng,o=su(n.event.time??{},a,n.event.utcOffsetHours);if(!o){this.sceneRenderer.setAstronomy(nE);return}const c=new Date(o.getTime()+e),l={lat:r,lng:a,elevationM:i?.elevationM??0},h=`${c.getTime()}|${r}|${a}|${l.elevationM}|${this.starCatalog?this.starCatalogDepth:0}`;if(h===this.lastSkyKey){this.sceneRenderer.render();return}this.lastSkyKey=h;const u={..._l("Sun",c,l),magnitude:yl("Sun",c)},d={..._l("Moon",c,l),phase:GS(c),magnitude:yl("Moon",c)},f=HS.map(g=>({body:g,position:_l(g,c,l),magnitude:yl(g,c)}));this.sceneRenderer.setAstronomy({sun:u,moon:d,planets:f,comet:this.cometAt(c,l),stars:this.starCatalog?{catalog:this.starCatalog,date:c,observer:l}:void 0,frame:{date:c,observer:l}}),this.ufoElement.setSunAltitude(u.altitudeDeg)}cometAt(e,t){const n=Vw.brightestAt(e,t);if(n)return{id:n.apparition.id,position:n.position,tailEnd:n.tailEnd,magnitude:n.magnitude}}pushPhenomenaAt(e){const t=this.ufoElement.sighting;t!==this.sizeEstimatesFor&&(this.sizeEstimates.clear(),this.distanceHypotheses.clear(),this.sizeEstimatesFor=t);const n=t.timeline,i=this.ufoElement.canvasElement,r=this.ufoElement.frameShiftPx,a=this.projectionAt(e),o=new Map,c=new Map,l=new Set;for(const v of n.sourceIds){const p=n.getInterpolatedShapeAt(e,v);if(!p)continue;const m={...p,bounds:{...p.bounds,x:p.bounds.x+r.x,y:p.bounds.y+r.y}};o.set(v,m);const b=p.aim?this.sceneRenderer.screenPointOf(Xn.directionOf(p.aim,this.directionScratch)):{ndcX:(m.bounds.x+m.bounds.width/2)/i.width*2-1,ndcY:-((m.bounds.y+m.bounds.height/2)/i.height*2-1)},w=b!==void 0&&Math.abs(b.ndcX)<=1&&Math.abs(b.ndcY)<=1,_=w?this.sceneRenderer.decorDistancesAt(b.ndcX,b.ndcY,v):{};l.add(v),(w||p.aim)&&l.delete(v);const S=p.angular?.widthDeg??a.pxToDeg(p.bounds.width),E=this.sizeEstimateOf(v);E.add(S,_);const R=ma.of(t,v);c.set(v,an.resolve({hypothesisM:this.distanceHypotheses.get(v),derivedM:R&&S>0?mt.distanceMAt(R.widthM,S):void 0,range:E.distanceRangeAt(S),crossing:_}))}for(const[v,p]of o)for(const[m,b]of o){if(m===v||b.transparency>=1||b.bounds.width*b.bounds.height<=p.bounds.width*p.bounds.height||!(p.bounds.x>=b.bounds.x&&p.bounds.y>=b.bounds.y&&p.bounds.x+p.bounds.width<=b.bounds.x+b.bounds.width&&p.bounds.y+p.bounds.height<=b.bounds.y+b.bounds.height))continue;const _=c.get(m);_&&c.set(v,{distanceM:_.distanceM*.999,basis:_.basis});break}this.depths=c;const h=n.sourceIds,u=this.sceneRenderer.lowerCloudUp,d=[];for(const[v,p]of o)d.push({sourceId:v,shape:p,distanceM:c.get(v).distanceM,renderOrder:h.indexOf(v),aim:p.aim,hidden:p.behindCloud===!0&&u||l.has(v)});const g=(Kt(t,e)?.rollDeg??0)+(kt.of(t)?.offsetAt(e)??kt.STILL).rollDeg;this.sceneRenderer.setPhenomena(d,{projection:a,canvasWidthPx:i.width,canvasHeightPx:i.height,scale:Math.max(1,this.sceneCanvas.height/Math.max(1,i.height)),starPoints:Lt.starPointsOf(t.instrument),rollRad:g*Math.PI/180})}setDistanceHypothesis(e,t){t===void 0||!(t>0)?this.distanceHypotheses.delete(e):this.distanceHypotheses.set(e,t),this.updateAstronomy(this.lastTimeMs)}depthOf(e){return this.depths.get(e)}sizeRangeOf(e){return this.sizeEstimateOf(e).sizeRange}distanceRangeAt(e,t){const n=this.ufoElement.sighting.timeline.getInterpolatedShapeAt(t,e);if(!n)return{};const i=n.angular?.widthDeg??this.projectionAt(t).pxToDeg(n.bounds.width);return this.sizeEstimateOf(e).distanceRangeAt(i)}sizeContradictory(e){return this.sizeEstimateOf(e).contradictory}updateMeteorShower(e,t){this.ensureMeteorSchedule(e),this.sceneRenderer.updateMeteors(t)}ensureMeteorSchedule(e){const t=this.meteorInputsOf(e);t!==this.meteorScheduleFor&&(this.meteorScheduleFor=t,this.scheduleMeteors(e))}meteorInputsOf(e){const t=e.event.place?.[0],n=e.event.time;return JSON.stringify([t?.lat,t?.lng,n?.year,n?.month,n?.day,n?.hour,n?.minute,e.event.utcOffsetHours,e.event.durationSeconds,e.timeline.duration])}scheduleMeteors(e){const t=e.event.place?.[0],n=e.event.time,i=t?.lat!==void 0&&t.lng!==void 0&&n?.year!==void 0?su(n,t.lng,e.event.utcOffsetHours):void 0;if(!i||t?.lat===void 0||t.lng===void 0){this.sceneRenderer.setMeteorShower([],0,0);return}const r={lat:t.lat,lng:t.lng,elevationM:0},a=(e.event.durationSeconds??0)*1e3||e.timeline.duration||2e4,o=Math.round(i.getTime()/1e3)+Math.round(t.lat*1e3),c=Rt.schedule({ratePerHour:Rt.observedRatePerHour(Rt.apexPosition(i,r).altitudeDeg),durationMs:a,velocityKmS:Rt.TYPICAL_VELOCITY_KM_S,seed:o}),l=zl.activeAt(i).map(u=>{const d=zl.radiantPosition(u.shower,i,r);return{entry:u,position:d,rate:zl.observedRatePerHour(u.zhr,d.altitudeDeg,u.shower.populationIndex)}}).sort((u,d)=>d.rate-u.rate)[0];if(!l||l.rate<=0){this.sceneRenderer.setMeteorShower(c,0,0);return}const h=Is.schedule({ratePerHour:l.rate,durationMs:a,velocityKmS:l.entry.shower.velocityKmS,seed:o+1});this.sceneRenderer.setMeteorShower([...h,...c],l.position.altitudeDeg,l.position.azimuthDeg)}meteorByRank(e){this.ensureMeteorSchedule(this.ufoElement.sighting);const t=[...this.sceneRenderer.meteorSchedule].filter(r=>r.t+r.durationMs<=this.ufoElement.seekableDuration).sort((r,a)=>a.brightness-r.brightness);if(t.length===0)return;const n=t[e%t.length],i=this.sceneRenderer.meteorMidpoint(n);if(i)return{t:Math.round(n.t+n.durationMs*.45),...i}}lensOpticsAt(e){const t=this.ufoElement.sighting,n=t.instrument,i=n.frame,r=Kt(t,e),a=r?.fNumber??n.fNumber;if(!i||a===void 0)return;const o=Lt.focalLengthMmFor(n,Un.fovOf(t,e));if(o!==void 0)return{focalLengthMm:o,fNumber:a,focusDistance:r?.focusDistanceM??0,frameHeightMm:i.heightMm}}projectionAt(e){const t=this.ufoElement.sighting;return Li.of(t.instrument,mt.CANVAS_HEIGHT_PX,Un.fovOf(t,e))}sizeEstimateOf(e){let t=this.sizeEstimates.get(e);return t||(t=new Xw,this.sizeEstimates.set(e,t)),t}}const hu="rr0-scene";function Vm(){Sp(),customElements.get(hu)||customElements.define(hu,iE)}const sE={color:"Color",transparency:"Transparency",halo:"Halo",blur:"Blur",brightness:"Brilliance",shapeTitle:"Name",utcOffset:"Time zone",cloudBase:"Cloud base",elevation:"Altitude",heightAboveGround:"Height above ground",duration:"Duration",placeName:"Place",latitude:"Latitude",longitude:"Longitude",heading:"Heading",pitch:"Tilt",roll:"Roll",observationTime:"Observation start",observationEndTime:"Observation end",assessmentGroup:"Assessment",assessmentNames:{coverage:"Witness info"},assessmentVerdicts:{"hynek.nl":"NL — nocturnal light","hynek.dd":"DD — daylight disc","hynek.rv":"RV — radar-visual","hynek.ce1":"CE1 — close encounter","hynek.ce2":"CE2 — with a physical trace","hynek.ce3":"CE3 — with entities"},witnessGroup:"Witness",witnessId:"ID",witnessTitle:"Title",witnessLastName:"Last name",witnessFirstNames:"First names",caseId:"Case ID",tags:"Tags",cloudCover:"Cloud cover",highCloudCover:"Ice cloud (cirrus)",focalLength:"Focal length",fieldOfView:"Field of view",aperture:"Aperture",exposure:"Exposure",focusDistance:"Focused at",iceCrystalAlignment:"Crystal alignment",cloudDarkness:"Cloud darkness",precipitationType:"Precipitation",precipitationNone:"None",precipitationRain:"Rain",precipitationSnow:"Snow",precipitationHail:"Hail",precipitationIntensity:"Intensity",windDirection:"Wind direction",windSpeed:"Wind speed",storm:"Storm",soundKind:"Sound",soundNone:"None (silent)",soundHum:"Hum",soundWhistle:"Whistle",soundRumble:"Rumble",soundCrackle:"Crackle",soundVolume:"Loudness",soundPitch:"Pitch",soundSrc:"Recording",instrument:"Observed through",decorAircraft:"Aircraft",decorEntity:"Being",decorAltitude:"Altitude",decorLights:"Lights",decorLightsNone:"none",decor:"Environment",decorBuilding:"Building",decorTree:"Tree",decorCrop:"Crop row",decorMound:"Stone heap",decorStreetlight:"Streetlight",decorVehicle:"Vehicle",decorWitness:"Other witness",decorEast:"Distance east",decorNorth:"Distance north",decorHeading:"Heading",decorColor:"Colour",decorLit:"Lit",decorTitle:"Name",milestones:"Moments",milestoneLabel:"Label",milestoneNote:"What happens",addMilestone:"Name this moment",deleteMilestone:"Delete moment",confirmAccept:"Delete",confirmDecline:"Cancel",decorWidth:"Width",decorLength:"Length",decorHeight:"Height",decorModel:"3D model",decorModelNone:"Built-in shape",decorModelAdvanced:"Model from an address",decorModelUrl:"glTF/GLB address",decorModelTitle:"Model name",decorModelAuthor:"Author",decorModelLicense:"Licence",decorModelSource:"Where it came from",decorFloors:"Floors",decorOccupiedFloor:"Occupied floor",decorWitnessSide:"Witness location",decorWitnessSideNone:"Not present",decorWindows:"Windows",decorSideFront:"Front",decorSideBehind:"Behind",decorSideLeft:"Left",decorSideRight:"Right",decorSideFrontLeft:"Front-left",decorSideFrontRight:"Front-right",decorSideBehindLeft:"Behind-left",decorSideBehindRight:"Behind-right"},uu={...sE,testimonyBy:"Testimony by",unnamedWitness:"Witness {n}",about:"About",close:"Close",observation:"Observation",date:"Date",location:"Location",case:"Case",description:"Description",credits:"Credits",editThisObservation:"Edit this observation",embed:"Embed",embedReplay:"Replay",embedEdit:"Editor",embedCopy:"Copy",embedCopied:"Copied",showLabels:"Show what it states",hideLabels:"Hide what it states"},rE=Object.freeze(Object.defineProperty({__proto__:null,sightingMessages_en:uu},Symbol.toStringTag,{value:"Module"}));Vm();const aE="“Thunder” by Jerimee",oE="https://creativecommons.org/licenses/by/3.0/",cE="CC BY 3.0",lE="https://ufoathome.org",np=`${lE}/edit/`;class Wm extends HTMLElement{static get observedAttributes(){return["src","show-labels",Oi,Ui]}shadow;sceneElement;toolbarElement;testimonyElement;testimonyPrefix;witnessText;witnessSelect;infoButton;infoPanel;infoAppLink;infoObservationHeading;infoObservationList;infoCreditsToggle;infoCreditsList;infoCloseButton;infoEmbedToggle;infoEmbedPanel;embedReplayRadio;embedEditRadio;labelEmbedReplay;labelEmbedEdit;embedMarkup;embedCopyButton;labelsToggle;paramSummary;summaryBuilder=new ad(uu,"en",new fi(["en"]),new Fo({}));summarySignature="";assessmentEntries=[];assessmentToken=0;supportsPopover=typeof HTMLElement.prototype.showPopover=="function";entries=[];currentSrc;infoOpen=!1;creditsOpen=!1;embedOpen=!1;labelsShown=!1;language="en";messages=uu;constructor(){super(),this.shadow=this.attachShadow({mode:"open"});const e=document.createElement("template");e.innerHTML=`<style>${Qm}</style>${jm}`,this.shadow.appendChild(e.content.cloneNode(!0)),this.sceneElement=document.createElement(hu),this.forwardPlayerAttributes(),this.sceneElement.ufoElement.creditShownExternally=!0,this.shadow.getElementById("ufo-slot").replaceWith(this.sceneElement),this.toolbarElement=this.shadow.getElementById("toolbar"),this.testimonyElement=this.shadow.getElementById("testimony"),this.testimonyPrefix=this.shadow.getElementById("testimony-prefix"),this.witnessText=this.shadow.getElementById("witness-text"),this.witnessSelect=this.shadow.getElementById("witness"),this.infoButton=this.shadow.getElementById("info-button"),this.infoPanel=this.shadow.getElementById("info-panel"),this.infoAppLink=this.shadow.getElementById("info-app-link"),this.infoObservationHeading=this.shadow.getElementById("info-observation-heading"),this.infoObservationList=this.shadow.getElementById("info-observation-list"),this.infoCreditsToggle=this.shadow.getElementById("info-credits-toggle"),this.infoCreditsList=this.shadow.getElementById("info-credits-list"),this.infoCloseButton=this.shadow.getElementById("info-close"),this.labelsToggle=this.shadow.getElementById("info-labels-toggle"),this.paramSummary=this.shadow.getElementById("param-summary"),this.labelsToggle.addEventListener("click",()=>{this.showLabels=!this.showLabels}),this.infoEmbedToggle=this.shadow.getElementById("info-embed-toggle"),this.infoEmbedPanel=this.shadow.getElementById("info-embed"),this.embedReplayRadio=this.shadow.getElementById("embed-kind-replay"),this.embedEditRadio=this.shadow.getElementById("embed-kind-edit"),this.labelEmbedReplay=this.shadow.getElementById("label-embed-replay"),this.labelEmbedEdit=this.shadow.getElementById("label-embed-edit"),this.embedMarkup=this.shadow.getElementById("embed-markup"),this.embedCopyButton=this.shadow.getElementById("embed-copy"),this.witnessSelect.addEventListener("change",()=>this.selectWitness(this.witnessSelect.value)),this.sceneElement.ufoElement.addEventListener("timeupdate",()=>this.refreshParamSummary()),this.supportsPopover?(this.infoPanel.setAttribute("popover","auto"),this.infoPanel.removeAttribute("hidden"),this.infoButton.setAttribute("popovertarget","info-panel"),this.infoPanel.addEventListener("beforetoggle",t=>{t.newState==="open"&&(this.populateInfoPanel(),this.bringInfoButtonIntoView())}),this.infoPanel.addEventListener("toggle",t=>this.syncInfoOpen(t.newState==="open"))):this.infoButton.addEventListener("click",()=>this.toggleInfoPanel()),this.infoCloseButton.addEventListener("click",()=>this.toggleInfoPanel()),this.infoCreditsToggle.addEventListener("click",()=>this.toggleCredits()),this.infoEmbedToggle.addEventListener("click",()=>this.toggleEmbed());for(const t of[this.embedReplayRadio,this.embedEditRadio])t.addEventListener("change",()=>this.refreshEmbedMarkup());this.embedCopyButton.addEventListener("click",()=>void this.copyEmbedMarkup()),this.loadLocaleMessages()}get scene(){return this.sceneElement}async loadLocaleMessages(){this.language=vc(Ar.preferencesFor(this),pp),this.language!=="en"&&(this.messages=await Wg(this.language),this.testimonyPrefix.textContent=this.messages.testimonyBy,this.infoButton.title=this.messages.about,this.infoButton.setAttribute("aria-label",this.messages.about),this.infoCloseButton.setAttribute("aria-label",this.messages.close),this.infoObservationHeading.textContent=this.messages.observation,this.infoCreditsToggle.textContent=this.messages.credits,this.tags=new Fo(await Xg(this.language)),this.summaryBuilder=new ad(this.messages,this.language==="fr"?"fr":"en",this.said,this.tags),this.syncLabelsToggle(),this.refreshParamSummary(),this.currentSrc&&this.runAssessments(),this.infoEmbedToggle.textContent=this.messages.embed,this.labelEmbedReplay.textContent=this.messages.embedReplay,this.labelEmbedEdit.textContent=this.messages.embedEdit,this.embedCopyButton.textContent=this.messages.embedCopy,this.infoOpen&&this.populateInfoPanel(),this.updateTestimonyLine())}get said(){return this.saidTexts??=new fi(Ar.preferencesFor(this))}saidTexts;tags=new Fo({});connectedCallback(){this.saidTexts=void 0;const e=this.getAttribute("src");e&&this.loadFromSrc(e)}disconnectedCallback(){document.removeEventListener("click",this.handleOutsideClick)}attributeChangedCallback(e,t,n){e==="src"&&n&&n!==t&&this.isConnected&&this.loadFromSrc(n),e==="show-labels"&&this.applyLabels(this.hasAttribute("show-labels")),(e===Oi||e===Ui)&&this.forwardPlayerAttributes()}forwardPlayerAttributes(){for(const e of[Oi,Ui])this.sceneElement.toggleAttribute(e,this.hasAttribute(e))}async loadFromSrc(e){const t=await Yo.json(e);Array.isArray(t)?await this.loadWitnessUrls(t.map(n=>new URL(n,new URL(e,location.href)).href)):this.setEntries([{src:e,sighting:t}])}get sightingData(){return this.entries.find(e=>e.src===this.currentSrc)?.sighting}set sightingData(e){this.currentSrc="",this.setEntries([{src:"",sighting:e}])}get witnessUrls(){return this.entries.map(e=>e.src)}set witnessUrls(e){this.loadWitnessUrls(e)}async loadWitnessUrls(e){const t=await Promise.all(e.map(async n=>({src:n,sighting:await Yo.json(n)})));this.setEntries(t)}setEntries(e){this.entries=e,this.warnOnMismatchedCaseIds(e),this.toolbarElement.hidden=e.length===0;const t=e.length>1;this.witnessSelect.hidden=!t,this.witnessText.hidden=t,this.witnessSelect.innerHTML="";for(const i of e){const r=document.createElement("option");r.value=i.src,r.textContent=this.witnessDisplayName(i.sighting.witness)??this.messages.unnamedWitness.replace("{n}",String(e.indexOf(i)+1)),this.witnessSelect.appendChild(r)}const n=e.find(i=>i.src===this.currentSrc)??e[0];n?this.selectWitness(n.src):this.updateTestimonyLine()}editorUrl(){if(!this.currentSrc)return np;const e=new URL(this.currentSrc,location.href);return`${np}?sighting=${encodeURIComponent(e.href)}`}embedMarkupFor(e){const t=e==="edit"?"rr0-sighting-editor":"rr0-sighting",n=new URL(`${t}.mjs`,import.meta.url).href,i=this.currentSrc?new URL(this.currentSrc,location.href).href:"";return`<script type="module" src="${n}"><\/script>
6118
- <${t} src="${i}"></${t}>`}refreshEmbedMarkup(){this.embedMarkup.value=this.embedMarkupFor(this.embedEditRadio.checked?"edit":"replay")}async copyEmbedMarkup(){try{await navigator.clipboard.writeText(this.embedMarkup.value),this.embedCopyButton.textContent=this.messages.embedCopied,window.setTimeout(()=>this.embedCopyButton.textContent=this.messages.embedCopy,1500)}catch{this.embedMarkup.select()}}warnOnMismatchedCaseIds(e){const t=new Set(e.map(n=>n.sighting.caseId).filter(n=>n!==void 0));t.size>1&&console.warn(`<rr0-sighting>: witnesses declare different case ids (${[...t].join(", ")}) — they may not belong to the same case.`)}selectWitness(e){const t=this.entries.find(n=>n.src===e);t&&(this.currentSrc=e,this.witnessSelect.value=e,this.sceneElement.sightingData=t.sighting,this.updateTestimonyLine(),this.refreshParamSummary(),this.runAssessments(),this.infoOpen&&this.populateInfoPanel())}async runAssessments(){const e=++this.assessmentToken,t=await new wg(this.messages).read(this.sceneElement.ufoElement.sighting);e===this.assessmentToken&&(this.assessmentEntries=t.entries,this.refreshParamSummary())}updateTestimonyLine(){const e=this.entries.find(i=>i.src===this.currentSrc),t=e?this.witnessDisplayName(e.sighting.witness):void 0,n=t!==void 0||this.entries.length>1;this.testimonyElement.hidden=!n,this.witnessText.textContent=t??""}witnessDisplayName(e){if(!e)return;const t=[...e.firstNames??[],e.lastName].filter(Boolean).join(" ");return e.title||t||e.id||e.dirName}formatDate(e){const t=e.place?.[0],n=su(e.time??{},t?.lng??0,e.utcOffsetHours);if(!n)return;const i=n.getTime()+this.utcOffsetHoursOf(e,t?.lng??0)*36e5;return new Intl.DateTimeFormat(this.language==="fr"?"fr-FR":"en-US",{dateStyle:"long",timeStyle:"short",timeZone:"UTC"}).format(new Date(i))}utcOffsetHoursOf(e,t){return e.utcOffsetHours??Math.round(t/15)}formatLocation(e){const t=e.place?.[0];if(t)return`${t.lat.toFixed(4)}, ${t.lng.toFixed(4)}`}toggleInfoPanel(){const e=!this.infoOpen;if(this.supportsPopover){const t=this.infoPanel.matches(":popover-open");e&&!t?this.infoPanel.showPopover():!e&&t&&this.infoPanel.hidePopover();return}e&&this.bringInfoButtonIntoView(),this.syncInfoOpen(e),this.infoPanel.hidden=!e,e?document.addEventListener("click",this.handleOutsideClick):document.removeEventListener("click",this.handleOutsideClick)}bringInfoButtonIntoView(){const e=this.infoButton.getBoundingClientRect(),t=window.innerHeight||document.documentElement.clientHeight;e.top>=0&&e.bottom<=t||this.infoButton.scrollIntoView({block:"center"})}syncInfoOpen(e){e!==this.infoOpen&&(this.infoOpen=e,this.infoButton.setAttribute("aria-expanded",String(e)),e?this.supportsPopover||this.populateInfoPanel():(this.creditsOpen=!1,this.infoCreditsList.hidden=!0,this.infoCreditsToggle.setAttribute("aria-expanded","false"),this.embedOpen=!1,this.infoEmbedPanel.hidden=!0,this.infoEmbedToggle.setAttribute("aria-expanded","false")))}handleOutsideClick=e=>{const t=e.composedPath();!t.includes(this.infoPanel)&&!t.includes(this.infoButton)&&this.toggleInfoPanel()};toggleCredits(){this.creditsOpen=!this.creditsOpen,this.infoCreditsList.hidden=!this.creditsOpen,this.infoCreditsToggle.setAttribute("aria-expanded",String(this.creditsOpen)),this.creditsOpen&&this.revealInPanel(this.infoCreditsList)}toggleEmbed(){this.embedOpen=!this.embedOpen,this.infoEmbedPanel.hidden=!this.embedOpen,this.infoEmbedToggle.setAttribute("aria-expanded",String(this.embedOpen)),this.embedOpen&&(this.refreshEmbedMarkup(),this.revealInPanel(this.infoEmbedPanel))}revealInPanel(e){e.scrollIntoView?.({block:"nearest"})}get showLabels(){return this.labelsShown}set showLabels(e){this.toggleAttribute("show-labels",e)}applyLabels(e){this.labelsShown=e,this.syncLabelsToggle(),this.refreshParamSummary(),this.populateInfoPanel()}syncLabelsToggle(){this.labelsToggle.textContent=this.labelsShown?this.messages.hideLabels:this.messages.showLabels,this.labelsToggle.setAttribute("aria-pressed",String(this.labelsShown))}refreshParamSummary(){if(this.paramSummary.hidden=!this.labelsShown,!this.labelsShown){this.paramSummary.replaceChildren(),this.summarySignature="";return}const e=this.sceneElement.ufoElement.sighting,t=[...this.summaryBuilder.entriesFor(e,this.sceneElement.ufoElement.currentTime),...this.assessmentEntries],n=t.map(a=>`${a.field}=${a.label}=${a.value}${a.unit}${a.fromSource?"*":""}`).join("|");if(n===this.summarySignature)return;this.summarySignature=n;const i=[];let r;for(const a of t){r&&r.group!==a.group&&(r=void 0);const o=a.group==="witness"?this.messages.witnessGroup:a.group==="assessment"?this.messages.assessmentGroup:void 0;if(o!==void 0&&!r){const l=document.createElement("span");l.className="param-nest";const h=document.createElement("span");h.className="param-nest-label",h.textContent=o,l.append(h),r={group:a.group,element:l},i.push(l)}const c=this.paramItem(a);r?r.element.append(c):i.push(c)}this.paramSummary.replaceChildren(...i)}paramItem(e){const t=document.createElement("span");t.className=e.fromSource?"param-label from-source":"param-label";const n=document.createElement("span");if(n.className="param-label-label",n.textContent=`${e.label} `,t.append(n),e.color!==void 0){const r=document.createElement("span");r.className="param-label-swatch",r.style.background=e.color,t.append(r)}const i=document.createElement("span");return i.className="param-label-value",i.textContent=e.unit===""?e.value:`${e.value} ${e.unit}`,t.append(i),t}populateInfoPanel(){const e=this.entries.find(a=>a.src===this.currentSrc);if(this.infoObservationList.innerHTML="",e){if(!this.labelsShown){const o=this.formatDate(e.sighting);o&&this.appendInfoRow(this.infoObservationList,this.messages.date,o);const c=this.formatLocation(e.sighting);c&&this.appendInfoRow(this.infoObservationList,this.messages.location,c),e.sighting.caseId&&this.appendInfoRow(this.infoObservationList,this.messages.case,e.sighting.caseId)}const a=this.said.read(e.sighting.description);a&&this.appendInfoRow(this.infoObservationList,this.messages.description,a),!this.labelsShown&&e.sighting.tags&&e.sighting.tags.length>0&&this.appendInfoRow(this.infoObservationList,this.messages.tags,e.sighting.tags.map(o=>this.tags.name(o)).join(", "))}this.refreshEmbedMarkup(),this.infoAppLink.href=this.editorUrl(),this.infoAppLink.textContent="UFO@home v0.55.2",this.infoAppLink.title=this.messages.editThisObservation,this.infoAppLink.setAttribute("aria-label",this.messages.editThisObservation),this.infoCreditsList.innerHTML="";const t=this.sceneElement.currentTerrainAttribution;if(t){const a=document.createElement("li");a.textContent=t,this.infoCreditsList.appendChild(a)}const n=this.sceneElement.ufoElement.witnessMapCredit;if(n&&!t?.includes(n)){const a=document.createElement("li");a.textContent=n,this.infoCreditsList.appendChild(a)}for(const a of this.sceneElement.decorModelCredits){const o=document.createElement("li"),c=a.author?` — ${a.author}`:"";if(a.sourceUrl){const l=document.createElement("a");l.href=a.sourceUrl,l.target="_blank",l.rel="noopener",l.textContent=a.title,o.append(l,document.createTextNode(`${c} (${a.license})`))}else o.textContent=`${a.title}${c} (${a.license})`;this.infoCreditsList.appendChild(o)}const i=document.createElement("li");i.textContent=`${aE} (`;const r=document.createElement("a");r.href=oE,r.target="_blank",r.rel="noopener",r.textContent=cE,i.appendChild(r),i.appendChild(document.createTextNode(")")),this.infoCreditsList.appendChild(i)}appendInfoRow(e,t,n){const i=document.createElement("dt");i.textContent=t;const r=document.createElement("dd");r.textContent=n,e.appendChild(i),e.appendChild(r)}}const ip="rr0-sighting",sp="rr0-eyewitness";class hE extends Wm{}function uE(){Vm(),customElements.get(ip)||customElements.define(ip,Wm),customElements.get(sp)||customElements.define(sp,hE)}uE();export{mE as $,qn as A,dt as B,ve as C,h2 as D,ki as E,SE as F,ct as G,bt as H,vE as I,gE as J,$e as K,Ca as L,_E as M,Ha as N,Mt as O,c2 as P,fs as Q,Zo as R,ma as S,dE as T,xE as U,Pe as V,Vp as W,ME as X,Vo as Y,tn as Z,yn as _,pE as a,Ur as a0,Gp as a1,yE as a2,Dv as a3,Qo as a4,Ih as a5,sc as a6,Zt as a7,$p as a8,Du as a9,Pu as aa,je as ab,us as ac,Ra as ad,Mi as ae,Hi as af,fE as b,_l as c,EE as d,tc as e,Rn as f,wE as g,Xe as h,P as i,s0 as j,bE as k,AE as l,Av as m,Cs as n,Ic as o,kg as p,D1 as q,yt as r,su as s,Bt as t,th as u,dn as v,Wp as w,Gi as x,Uv as y,Vv as z};
6118
+ <${t} src="${i}"></${t}>`}refreshEmbedMarkup(){this.embedMarkup.value=this.embedMarkupFor(this.embedEditRadio.checked?"edit":"replay")}async copyEmbedMarkup(){try{await navigator.clipboard.writeText(this.embedMarkup.value),this.embedCopyButton.textContent=this.messages.embedCopied,window.setTimeout(()=>this.embedCopyButton.textContent=this.messages.embedCopy,1500)}catch{this.embedMarkup.select()}}warnOnMismatchedCaseIds(e){const t=new Set(e.map(n=>n.sighting.caseId).filter(n=>n!==void 0));t.size>1&&console.warn(`<rr0-sighting>: witnesses declare different case ids (${[...t].join(", ")}) — they may not belong to the same case.`)}selectWitness(e){const t=this.entries.find(n=>n.src===e);t&&(this.currentSrc=e,this.witnessSelect.value=e,this.sceneElement.sightingData=t.sighting,this.updateTestimonyLine(),this.refreshParamSummary(),this.runAssessments(),this.infoOpen&&this.populateInfoPanel())}async runAssessments(){const e=++this.assessmentToken,t=await new wg(this.messages).read(this.sceneElement.ufoElement.sighting);e===this.assessmentToken&&(this.assessmentEntries=t.entries,this.refreshParamSummary())}updateTestimonyLine(){const e=this.entries.find(i=>i.src===this.currentSrc),t=e?this.witnessDisplayName(e.sighting.witness):void 0,n=t!==void 0||this.entries.length>1;this.testimonyElement.hidden=!n,this.witnessText.textContent=t??""}witnessDisplayName(e){if(!e)return;const t=[...e.firstNames??[],e.lastName].filter(Boolean).join(" ");return e.title||t||e.id||e.dirName}formatDate(e){const t=e.place?.[0],n=su(e.time??{},t?.lng??0,e.utcOffsetHours);if(!n)return;const i=n.getTime()+this.utcOffsetHoursOf(e,t?.lng??0)*36e5;return new Intl.DateTimeFormat(this.language==="fr"?"fr-FR":"en-US",{dateStyle:"long",timeStyle:"short",timeZone:"UTC"}).format(new Date(i))}utcOffsetHoursOf(e,t){return e.utcOffsetHours??Math.round(t/15)}formatLocation(e){const t=e.place?.[0];if(t)return`${t.lat.toFixed(4)}, ${t.lng.toFixed(4)}`}toggleInfoPanel(){const e=!this.infoOpen;if(this.supportsPopover){const t=this.infoPanel.matches(":popover-open");e&&!t?this.infoPanel.showPopover():!e&&t&&this.infoPanel.hidePopover();return}e&&this.bringInfoButtonIntoView(),this.syncInfoOpen(e),this.infoPanel.hidden=!e,e?document.addEventListener("click",this.handleOutsideClick):document.removeEventListener("click",this.handleOutsideClick)}bringInfoButtonIntoView(){const e=this.infoButton.getBoundingClientRect(),t=window.innerHeight||document.documentElement.clientHeight;e.top>=0&&e.bottom<=t||this.infoButton.scrollIntoView({block:"center"})}syncInfoOpen(e){e!==this.infoOpen&&(this.infoOpen=e,this.infoButton.setAttribute("aria-expanded",String(e)),e?this.supportsPopover||this.populateInfoPanel():(this.creditsOpen=!1,this.infoCreditsList.hidden=!0,this.infoCreditsToggle.setAttribute("aria-expanded","false"),this.embedOpen=!1,this.infoEmbedPanel.hidden=!0,this.infoEmbedToggle.setAttribute("aria-expanded","false")))}handleOutsideClick=e=>{const t=e.composedPath();!t.includes(this.infoPanel)&&!t.includes(this.infoButton)&&this.toggleInfoPanel()};toggleCredits(){this.creditsOpen=!this.creditsOpen,this.infoCreditsList.hidden=!this.creditsOpen,this.infoCreditsToggle.setAttribute("aria-expanded",String(this.creditsOpen)),this.creditsOpen&&this.revealInPanel(this.infoCreditsList)}toggleEmbed(){this.embedOpen=!this.embedOpen,this.infoEmbedPanel.hidden=!this.embedOpen,this.infoEmbedToggle.setAttribute("aria-expanded",String(this.embedOpen)),this.embedOpen&&(this.refreshEmbedMarkup(),this.revealInPanel(this.infoEmbedPanel))}revealInPanel(e){e.scrollIntoView?.({block:"nearest"})}get showLabels(){return this.labelsShown}set showLabels(e){this.toggleAttribute("show-labels",e)}applyLabels(e){this.labelsShown=e,this.syncLabelsToggle(),this.refreshParamSummary(),this.populateInfoPanel()}syncLabelsToggle(){this.labelsToggle.textContent=this.labelsShown?this.messages.hideLabels:this.messages.showLabels,this.labelsToggle.setAttribute("aria-pressed",String(this.labelsShown))}refreshParamSummary(){if(this.paramSummary.hidden=!this.labelsShown,!this.labelsShown){this.paramSummary.replaceChildren(),this.summarySignature="";return}const e=this.sceneElement.ufoElement.sighting,t=[...this.summaryBuilder.entriesFor(e,this.sceneElement.ufoElement.currentTime),...this.assessmentEntries],n=t.map(a=>`${a.field}=${a.label}=${a.value}${a.unit}${a.fromSource?"*":""}`).join("|");if(n===this.summarySignature)return;this.summarySignature=n;const i=[];let r;for(const a of t){r&&r.group!==a.group&&(r=void 0);const o=a.group==="witness"?this.messages.witnessGroup:a.group==="assessment"?this.messages.assessmentGroup:void 0;if(o!==void 0&&!r){const l=document.createElement("span");l.className="param-nest";const h=document.createElement("span");h.className="param-nest-label",h.textContent=o,l.append(h),r={group:a.group,element:l},i.push(l)}const c=this.paramItem(a);r?r.element.append(c):i.push(c)}this.paramSummary.replaceChildren(...i)}paramItem(e){const t=document.createElement("span");t.className=e.fromSource?"param-label from-source":"param-label";const n=document.createElement("span");if(n.className="param-label-label",n.textContent=`${e.label} `,t.append(n),e.color!==void 0){const r=document.createElement("span");r.className="param-label-swatch",r.style.background=e.color,t.append(r)}const i=document.createElement("span");return i.className="param-label-value",i.textContent=e.unit===""?e.value:`${e.value} ${e.unit}`,t.append(i),t}populateInfoPanel(){const e=this.entries.find(a=>a.src===this.currentSrc);if(this.infoObservationList.innerHTML="",e){if(!this.labelsShown){const o=this.formatDate(e.sighting);o&&this.appendInfoRow(this.infoObservationList,this.messages.date,o);const c=this.formatLocation(e.sighting);c&&this.appendInfoRow(this.infoObservationList,this.messages.location,c),e.sighting.caseId&&this.appendInfoRow(this.infoObservationList,this.messages.case,e.sighting.caseId)}const a=this.said.read(e.sighting.description);a&&this.appendInfoRow(this.infoObservationList,this.messages.description,a),!this.labelsShown&&e.sighting.tags&&e.sighting.tags.length>0&&this.appendInfoRow(this.infoObservationList,this.messages.tags,e.sighting.tags.map(o=>this.tags.name(o)).join(", "))}this.refreshEmbedMarkup(),this.infoAppLink.href=this.editorUrl(),this.infoAppLink.textContent="UFO@home v0.55.3",this.infoAppLink.title=this.messages.editThisObservation,this.infoAppLink.setAttribute("aria-label",this.messages.editThisObservation),this.infoCreditsList.innerHTML="";const t=this.sceneElement.currentTerrainAttribution;if(t){const a=document.createElement("li");a.textContent=t,this.infoCreditsList.appendChild(a)}const n=this.sceneElement.ufoElement.witnessMapCredit;if(n&&!t?.includes(n)){const a=document.createElement("li");a.textContent=n,this.infoCreditsList.appendChild(a)}for(const a of this.sceneElement.decorModelCredits){const o=document.createElement("li"),c=a.author?` — ${a.author}`:"";if(a.sourceUrl){const l=document.createElement("a");l.href=a.sourceUrl,l.target="_blank",l.rel="noopener",l.textContent=a.title,o.append(l,document.createTextNode(`${c} (${a.license})`))}else o.textContent=`${a.title}${c} (${a.license})`;this.infoCreditsList.appendChild(o)}const i=document.createElement("li");i.textContent=`${aE} (`;const r=document.createElement("a");r.href=oE,r.target="_blank",r.rel="noopener",r.textContent=cE,i.appendChild(r),i.appendChild(document.createTextNode(")")),this.infoCreditsList.appendChild(i)}appendInfoRow(e,t,n){const i=document.createElement("dt");i.textContent=t;const r=document.createElement("dd");r.textContent=n,e.appendChild(i),e.appendChild(r)}}const ip="rr0-sighting",sp="rr0-eyewitness";class hE extends Wm{}function uE(){Vm(),customElements.get(ip)||customElements.define(ip,Wm),customElements.get(sp)||customElements.define(sp,hE)}uE();export{mE as $,qn as A,dt as B,ve as C,h2 as D,ki as E,SE as F,ct as G,bt as H,vE as I,gE as J,$e as K,Ca as L,_E as M,Ha as N,Mt as O,c2 as P,fs as Q,Zo as R,ma as S,dE as T,xE as U,Pe as V,Vp as W,ME as X,Vo as Y,tn as Z,yn as _,pE as a,Ur as a0,Gp as a1,yE as a2,Dv as a3,Qo as a4,Ih as a5,sc as a6,Zt as a7,$p as a8,Du as a9,Pu as aa,je as ab,us as ac,Ra as ad,Mi as ae,Hi as af,fE as b,_l as c,EE as d,tc as e,Rn as f,wE as g,Xe as h,P as i,s0 as j,bE as k,AE as l,Av as m,Cs as n,Ic as o,kg as p,D1 as q,yt as r,su as s,Bt as t,th as u,dn as v,Wp as w,Gi as x,Uv as y,Vv as z};
@@ -0,0 +1 @@
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",observationTime:"Début de l'observation",observationEndTime:"Fin de l'observation",assessmentGroup:"Évaluation",assessmentNames:{coverage:"Infos du témoin"},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"},witnessGroup:"Témoin",witnessId:"ID",witnessTitle:"Titre",witnessLastName:"Nom de famille",witnessFirstNames:"Prénoms",caseId:"ID de l'affaire",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",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",soundKind:"Son",soundNone:"Aucun (silencieux)",soundHum:"Bourdonnement",soundWhistle:"Sifflement",soundRumble:"Grondement",soundCrackle:"Crépitement",soundVolume:"Intensité sonore",soundPitch:"Hauteur",soundSrc:"Enregistrement",instrument:"Observé avec",decorAircraft:"Aéronef",decorEntity:"Être",decorAltitude:"Altitude",decorLights:"Feux",decorLightsNone:"aucun",decor:"Environnement",decorBuilding:"Bâtiment",decorTree:"Arbre",decorCrop:"Rang de culture",decorMound:"Tas de pierres",decorStreetlight:"Lampadaire",decorVehicle:"Véhicule",decorWitness:"Autre témoin",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",confirmAccept:"Supprimer",confirmDecline:"Annuler",decorWidth:"Largeur",decorLength:"Longueur",decorHeight:"Hauteur",decorModel:"Modèle 3D",decorModelNone:"Forme intégrée",decorModelAdvanced:"Modèle depuis une adresse",decorModelUrl:"Adresse glTF/GLB",decorModelTitle:"Nom du modèle",decorModelAuthor:"Auteur",decorModelLicense:"Licence",decorModelSource:"Provenance",decorFloors:"Étages",decorOccupiedFloor:"Étage occupé",decorWitnessSide:"Emplacement du témoin",decorWitnessSideNone:"Non présent",decorWindows:"Fenêtres",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,oval:"Ovale",polygon:"Polygone",addVertex:"Ajouter un sommet",deleteVertex:"Supprimer le sommet",notAPolygon:"Sélectionnez une seule forme polygonale",tooFewVertices:"Une forme a besoin d'au moins 3 points",shape:"Forme",apparentWidth:"Largeur apparente",realWidth:"Largeur réelle",distance:"Distance",sizeLock:"Maintenir",lockNone:"rien",lockApparent:"la largeur apparente",lockReal:"la largeur réelle",lockDistance:"la distance",apparentSize:"{moons}× la Lune",utcOffsetPlaceholder:"d'après la longitude",realSizeBetween:"La scène borne cette largeur : entre {min} et {max} m, d'après ce qu'il croise",realSizeAtLeast:"La scène borne cette largeur : au moins {min} m, d'après ce qu'il passe derrière",realSizeAtMost:"La scène borne cette largeur : au plus {max} m, d'après ce qu'il passe devant",realSizeUnknown:"Rien dans la scène ne borne cette largeur : elle ne fait que découler de la distance",realSizeOutside:" — la largeur ci-dessus en sort",blurBound:"Flou à travers cet objectif : plus près que {max} m",blurBoundNoInstrument:"Le flou à l'œil nu ne borne aucune distance — un œil n'a pas de diaphragme dont sortir",blurBoundNotAtInfinity:"Le flou ne borne une distance que pour une mise au point à l'infini : celle-ci est à {focus} m, qui floute des deux côtés",realSizeContradiction:"Contradiction : les passages déclarés ne peuvent pas être vrais ensemble",realDistanceHere:" — soit ici entre {min} et {max} m",clearDistanceHypothesis:"Retirer l'hypothèse de distance",clearDistanceHypothesisTitle:"Revenir à ce que l'enregistrement établit",depthStated:"Dessiné à {m} m, comme l'enregistrement l'énonce",depthHypothesis:"Dessiné à {m} m : votre hypothèse — ce que le décor en cache est ce qu'une chose à cette distance perdrait",depthDerived:"Dessiné à {m} m, d'après la marche du témoin",depthBounded:"Dessiné à {m} m, d'après ce qu'il passe derrière et devant",depthConventional:"Dessiné à {m} m par convention : rien dans l'enregistrement n'établit de distance",addShape:"Ajouter une forme",deleteShape:"Supprimer la forme",play:"Lecture",pause:"Pause",noDuration:"Aucune durée d'observation",autoReplay:"Lecture automatique",group:"Grouper",ungroup:"Dégrouper",bringToFront:"Placer devant",sendToBack:"Placer derrière",contextMenuDelete:"Supprimer",confirmDeleteShape:"Supprimer {name} ? Cette action est irréversible.",confirmDeleteShapes:"Supprimer {count} formes ? Cette action est irréversible.",confirmDeleteMilestone:"Ne plus nommer le moment {name} ? L'enregistrement lui-même est inchangé.",onlyOneShape:"Il n'y a qu'une seule forme",alreadyAtFront:"Cette forme est déjà la plus en avant",alreadyAtBack:"Cette forme est déjà la plus en arrière",needTwoShapesToGroup:"Sélectionnez au moins deux formes pour les grouper",notGrouped:"Cette forme ne fait pas partie d'un groupe",multipleShapesSelected:"Plusieurs formes sélectionnées — sélectionnez-en une seule pour modifier ceci",samplingRate:"Échantillonnage",currentPosition:"Position actuelle",switchToElapsed:"cliquer pour afficher la durée écoulée",switchToClockTime:"cliquer pour afficher l'heure de l'observation",durationPlaceholder:"durée de l'observation",durationImprecise:"Ces dates ne permettent pas de déterminer précisément une durée — saisissez-la manuellement.",export:"Exporter",importFile:"Charger un fichier JSON",importUrl:"Ou charger depuis une URL",importUrlPlaceholder:"https://…/sighting.json",importButton:"Charger",importError:"Impossible de charger cet enregistrement — vérifiez le fichier ou l'URL et réessayez.",importErrorCors:"Cette adresse répond, mais le navigateur n'a pas le droit de la lire depuis cette page. Le fichier lui-même est bon : c'est son serveur qui doit envoyer l'en-tête « Access-Control-Allow-Origin: * » avec. Si ce serveur n'est pas le vôtre, c'est ce qu'il faut demander à son administrateur.",importErrorMixedContent:"Une page sécurisée ne peut pas charger une adresse commençant par http://. Utilisez https:// si ce serveur le propose.",importErrorUnreachable:"Rien n'a répondu à cette adresse. Vérifiez l'orthographe, et que vous êtes connecté.",importErrorStatus:"Ce serveur a répondu par une erreur ({status}). L'adresse est probablement fausse, ou le fichier a été déplacé.",importErrorMalformed:"Cette adresse a répondu, mais ce qui revient n'est pas un enregistrement.",record:"Enregistrer",stop:"Arrêter",according:"selon",sourceElevation:"Relief",sourceImagery:"Imagerie",placeNamePlaceholder:"Valensole, France",searchPlace:"Localiser",placeMatch:"Correspondances",placeSearching:"Recherche du lieu…",placeMatchFound:"lieu trouvé",placeMatchesFound:"lieux trouvés",placeNotFound:"Aucun lieu de ce nom",placeSearchFailed:"Recherche de lieu momentanément indisponible",utcOffsetImplausible:"Ce fuseau ne correspond pas à la longitude saisie, dont l'heure solaire est UTC{solar} — la scène et le relevé météo obéissent pourtant à ce qui est déclaré ici. Videz le champ pour le déduire de la longitude.",timeZoneManual:"décalage saisi",altitudeAboveSeaLevel:"Altitude du témoin au-dessus du niveau de la mer — le sol du lieu saisi en fixe le minimum : un témoin dans les Alpes n'est pas à 0 m.",groundAt:"sol à {m} m",headingPlaceholder:"inconnu",edtfInvalid:"Date/heure EDTF invalide (ex. 1965-07-01T05:00, 2025-06?, 2025~).",edtfPlaceholder:"AAAA-MM-JJThh:mm[?~%] ou hh:mm",observationTimeHint:"EDTF — ex. 1965-07-01T05:00, 2025-06? (incertain), 2025~ (approximatif), ou juste 05:00 si la date est inconnue",observationEndTimeHint:"EDTF — ex. 1965-07-01T05:10, 2025-06? (incertain), 2025~ (approximatif), ou juste 05:10 si la date est inconnue",presetsGroupLabel:"Forme de l'ovni",witnessDirName:"Répertoire",description:"Description",tagsPlaceholder:"séparés par des virgules",weather:"Météo",shapeGroup:"Phénomène",soundGroup:"Son",temporalGroup:"Moment",timeQualifierExact:"Exacte",timeQualifierApproximate:"Approximative",timeQualifierUncertain:"Incertaine",timeQualifierBoth:"Incertaine et approximative",edtfModeTitle:"Saisir plutôt une date imprécise : une année seule, un mois, une heure sans date",locationGroup:"Lieu",observationGroup:"Observation",weatherWhilePlaying:"Mettez la lecture en pause pour décrire le temps — pendant qu'elle tourne, l'instant où ceci s'écrirait se déplace",weatherInferred:"D'après les relevés",weatherInferredTitle:"La météo n'est pas un témoignage : c'est un fait mesurable, relevé pour la date, l'heure et le lieu de l'observation. Décochez pour saisir les conditions rapportées par le témoin, qui priment alors sur le relevé.",weatherLookingUp:"Recherche du relevé…",weatherNeedsDateAndPlace:"Date complète et lieu requis pour retrouver le relevé",weatherNoRecord:"Aucun relevé pour cette date et ce lieu",weatherLookupFailed:"Relevés météo momentanément inaccessibles",instrumentOutOfPeriod:"{name} — hors de son époque",unitMillimetres:"mm",unitDegrees:"°",soundSrcPlaceholder:"URL d'un enregistrement réel",skyLine:"Ciel : {parts}",skyStarsEye:"étoiles jusqu'à la magnitude {limit}, ce que l'œil atteignait sous ce ciel",skyStarsDeeper:"étoiles jusqu'à la magnitude {limit} à travers un {device} — {gain} magnitudes au-delà des {eye} qu'atteignaient les yeux du témoin",skyStarsShallower:"étoiles jusqu'à la magnitude {limit} à travers un {device} — {gain} magnitudes en deçà des {eye} qu'atteignaient les yeux du témoin",skyStarsCatalogue:", dessinées jusqu'à {catalogue}, où s'arrête le catalogue de ce projet",skyStarsNone:"aucune étoile ne se détachait d'un ciel aussi clair",skyDetails:"Voir le détail des relevés",skyDetailsHide:"Masquer le détail des relevés",skyShowerActive:"{name} — radiant à {altitude}° de hauteur, {bearing} — environ {rate}/h sous ce ciel, sur un fond sporadique de {sporadic}/h",skyShowerBelowHorizon:"{name} est actif, mais son radiant est sous l'horizon — il n'a rien pu produire",skyNothingActive:"aucune pluie de météores active à cette date — un fond sporadique d'environ {sporadic}/h",showMeteor:"Montrer un météore",skyComet:"La {name}, magnitude {magnitude}, à {altitude}° de hauteur {bearing}, queue longue de {tail}°",skyCometNoTail:"La {name}, magnitude {magnitude}, à {altitude}° de hauteur {bearing}",skyCometBelowHorizon:"La {name} était là, magnitude {magnitude}, mais sous l'horizon — personne ici ne l'a vue",skyCometInDaylight:"La {name}, magnitude {magnitude}, à {altitude}° de hauteur {bearing} — mais à {elongation}° du Soleil seulement",showComet:"Montrer la comète",skyOpticsPossible:"nuages de glace suffisants, autour {source}, pour {forms}",skyOpticsAlignment:" — tout sauf les halos exige des cristaux tombant à plat, ici supposés alignés à {alignment} %, qu'aucun relevé ne donne",skyOpticsHalo22:"un halo à {angle}°",skyOpticsHalo46:"un halo à {angle}°",skyOpticsParhelia:"des parhélies à {angle}° de part et d'autre",skyOpticsTangentArc:"un arc tangent au sommet",skyOpticsParhelicCircle:"un cercle parhélique blanc faisant le tour du ciel à sa hauteur",skyOpticsCircumzenithal:"un arc circumzénithal à {angle}° de hauteur",skyOpticsCircumhorizontal:"un arc circumhorizontal très au-dessous",skyOpticsPillar:"un pilier dressé au-dessus",skyOpticsNoIce:"aucun nuage de glace : ni halo ni parhélie",skyOpticsHidden:"des nuages de glace en altitude, mais une couche plus basse les cache",skyOpticsSun:"du Soleil",skyOpticsMoon:"de la Lune",skyBowPossible:"pluie et soleil suffisants pour {forms}",skyBowMoon:"pluie sous une Lune éclairée à {lit} %, de quoi former {forms} — un arc-en-ciel lunaire, que l'œil voit blanc",skyGlowBand:"la Voie lactée à {contrast}× le fond du ciel, à {altitude}° de hauteur {bearing}",skyGlowCone:"la lumière zodiacale à {contrast}× le fond du ciel, à {altitude}° de hauteur {bearing}, à {elongation}° du Soleil — un cône penché, sans bord, disparu dans l'heure",skyGlowZodiacalBand:"la bande zodiacale à {contrast}× le fond du ciel, à {altitude}° de hauteur {bearing} — toute l'écliptique faiblement allumée, ce qui n'est pas ce que les gens rapportent",skyGlowMoon:"ni Voie lactée ni lumière zodiacale : une Lune éclairée à {lit} % tenait le ciel à {sky} magnitudes par seconde d'arc, là où il leur en faut 22",skyGlowTwilight:"ni Voie lactée ni lumière zodiacale : le crépuscule tenait encore le ciel à {sky} magnitudes par seconde d'arc, là où il leur en faut 22",skyGlowNothingUp:"ciel assez noir ({sky} magnitudes par seconde d'arc), mais ni le plan de la Galaxie ni l'écliptique ne s'y tenaient assez haut",skyBowPrimary:"un arc de {radius}° de rayon, dont le sommet montait à {top}°",skyBowSecondary:"un second, plus pâle, à {radius}°, aux couleurs inversées",skyBowSourceTooHigh:"pluie, mais l'astre à {altitude}° de hauteur : aucun arc ne pouvait dépasser l'horizon, ils se tiennent à {radius}° du point opposé",skyBowHidden:"pluie, mais une couche continue entre elle et la lumière : aucun arc",skyBowNoSource:"pluie, et rien d'allumé pour en tirer un arc",skySatellitesLit:"l'ombre de la Terre montait à {height} km au-dessus du témoin, l'orbite basse était donc encore éclairée — {count} objets suivis étaient en orbite ce mois-là",skySatellitesLitWith:"l'ombre de la Terre montait à {height} km au-dessus du témoin, l'orbite basse était donc encore éclairée — {count} objets suivis étaient en orbite ce mois-là, dont {eras}",skySatellitesShadowed:"l'ombre de la Terre montait à {height} km au-dessus du témoin : sur les {count} objets suivis en orbite ce mois-là, rien en orbite basse n'était éclairé",skySatellitesNotYet:"rien n'était encore en orbite",skySatellitesDaylight:"tout ce qui est en orbite était éclairé, comme toujours de jour, et {eras} pouvaient l'emporter même sur ce ciel",skySatellitesDaylightOne:"tout ce qui est en orbite était éclairé, comme toujours de jour, et {eras} pouvait l'emporter même sur ce ciel",skyUnknown:"indéterminable sans date ni lieu",lookAtDecor:"Regarder cet élément",addDecor:"Ajouter",deleteDecor:"Supprimer l'élément de décor",decorSightingUrl:"URL de son propre enregistrement",viewTestimony:"Voir le témoignage",noWitnessRecording:"Aucune URL d'enregistrement définie pour ce témoin",masks:"Masque",addWitness:"Ajouter un témoin",narrativePlaceholder:"Ce que le témoin a rapporté, dans ses propres mots",narrativeKey:"Clé d'API {source}",narrativeNeedsKey:"Saisissez votre propre clé d'API {source} pour générer la reconstitution d'après le récit",narrativeKeyUnlikely:"Cela ne ressemble pas à une clé d'API Claude : elles commencent par sk-ant-",narrativeWorkspace:"Espace de travail",narrativeWorkspacePlaceholder:"seulement si votre clé en couvre plusieurs",narrativeWorkspaceHint:"Seulement pour une clé dont la portée est l'organisation entière. Plus simple : laissez vide et créez une clé de portée « espace de travail ».",narrativeNeedsAsk:"Rien à envoyer pour l'instant",narrativeRemember:"Retenir sur cet appareil",narrativeDraft:"Générer la reconstitution",narrativeStop:"Arrêter",narrativeWorking:"Lecture du récit…",narrativeApplied:"{count} champs écrits dans l'éditeur",narrativeUnchanged:"Le récit n'énonce rien que l'enregistrement sache encore porter",narrativeStated:"Ce que le témoin a dit",narrativeDerived:"Déduit du récit",narrativeAssumed:"Supposé, pour que la reconstitution tourne : à vérifier",narrativeGaps:"Ce que rien n'a pu trancher",narrativeErrorCredential:"Pas de clé, ou une clé refusée : vérifiez-la sur console.anthropic.com",narrativeErrorRateLimited:"Trop de requêtes sur votre compte : patientez un instant et redemandez",narrativeErrorRefused:"Le récit n'a pas reçu de réponse. Le reformuler peut aider, le redemander non",narrativeErrorMalformed:"La réponse n'était pas un brouillon exploitable : cela vaut la peine de redemander",narrativeErrorUnreachable:"Rien n'a répondu : vérifiez la connexion",narrativeErrorRejected:"Refusé : {detail}",witnessAge:"Âge alors",witnessOccupation:"Profession",testimonySource:"Récit recueilli",testimonySourceUnknown:"on ne sait pas",testimonySourceOnSite:"enquête sur site",testimonySourceInterview:"entretien en personne",testimonySourceTelephone:"par téléphone",testimonySourceQuestionnaire:"questionnaire",testimonySourceLetter:"écrit par le témoin",testimonySourcePress:"presse ou radiodiffusion",testimonyFollowedUp:"Recontacté",testimonyUnknown:"on ne sait pas",testimonyYes:"oui",testimonyNo:"non",questionUnanswered:"Rien dans cet enregistrement ne répond à l'une des questions qu'une reconstitution doit trancher",durationRequired:"L'observation a besoin d'une longueur pour être rejouée — indiquez-la, ou une heure de fin, qui peut être approximative",questionsUnanswered:"{count} des questions auxquelles une reconstitution complète répond restent sans réponse ici"};export{r as sightingEditorMessages_fr};
@@ -1756,7 +1756,7 @@ input[type=range] {
1756
1756
  pointer-events: none;
1757
1757
  white-space: nowrap;
1758
1758
  }
1759
- `,cm=Math.PI/180,El=111320;function gn(s,e,t,n){const i=El*Math.cos(t*cm),a=(s-t)*El;return{x:(e-n)*i,z:-a}}function zi(s,e,t,n){const i=El*Math.cos(t*cm),a=-e,r=s;return{lat:t+a/El,lng:n+r/i}}class Wr{constructor(e){this.points=e}static STATIONARY_M=5;static of(e){const t=[];for(const n of e.witnessTrack.allKeyframes){const{lat:i,lng:a,headingDeg:r}=n.pose;i===void 0||a===void 0||t.push({t:n.t,lat:i,lng:a,headingDeg:r})}if(t.length===0){const n=e.event.place?.[0];if(!n)return;t.push({t:0,lat:n.lat,lng:n.lng})}return new Wr(t)}get moved(){return this.spanM>Wr.STATIONARY_M}get spanM(){const e=this.box,t=(e.south+e.north)/2,n=(e.west+e.east)/2;return Math.max(Math.abs(gn(t,e.east,t,e.west).x),Math.abs(gn(e.north,n,e.south,n).z))}get center(){const e=this.box;return{lat:(e.south+e.north)/2,lng:(e.west+e.east)/2}}boundsAround(e,t){const{lat:n,lng:i}=this.center,a=Math.max(this.spanM*(1+t),e)/2;return{north:zi(0,-a,n,i).lat,south:zi(0,a,n,i).lat,east:zi(a,0,n,i).lng,west:zi(-a,0,n,i).lng}}get box(){const e=this.points.map(n=>n.lat),t=this.points.map(n=>n.lng);return{south:Math.min(...e),north:Math.max(...e),west:Math.min(...t),east:Math.max(...t)}}}class Gt{constructor(e,t){this.stretches=e,this.rotationPassed=t}static REFERENCE_SPEED_M_PER_S=1.4;static REFERENCE_STEP_HZ=1.9;static CADENCE_EXPONENT=.43;static RISE_M_PER_M_PER_S=.0175;static SWAY_M=.0175;static SLOWEST_WALK_M_PER_S=.2;static FASTEST_WALK_M_PER_S=2.2;static HEAD_ROLL_DEG=1.5;static HEAD_PITCH_DEG=1.25;static HEAD_YAW_DEG=1;static STILL=Object.freeze({eastM:0,northM:0,upM:0,rollDeg:0,pitchDeg:0,yawDeg:0});static of(e){const t=Wr.of(e);if(!t||t.points.length<2)return;const n=[];let i=0;for(let a=1;a<t.points.length;a++){const r=t.points[a-1],o=t.points[a],l=(o.t-r.t)/1e3;if(l<=0)continue;const c=gn(o.lat,o.lng,r.lat,r.lng),h=c.x,d=-c.z,u=Math.hypot(h,d),f=u/l,g=Gt.stepHzFor(f);n.push({startMs:r.t,endMs:o.t,speedMPerS:f,eastUnit:u>0?h/u:0,northUnit:u>0?d/u:0,stepHz:g,stepsBefore:i,rampsIn:!0,rampsOut:!0}),i+=g*l}for(let a=0;a<n.length;a++){const r=n[a-1],o=n[a+1];n[a].rampsIn=r===void 0||r.stepHz===0,n[a].rampsOut=o===void 0||o.stepHz===0}if(n.some(a=>a.stepHz>0))return new Gt(n,1-(e.instrument.stabilization??0))}static stepHzFor(e){return e<Gt.SLOWEST_WALK_M_PER_S||e>Gt.FASTEST_WALK_M_PER_S?0:Gt.REFERENCE_STEP_HZ*Math.pow(e/Gt.REFERENCE_SPEED_M_PER_S,Gt.CADENCE_EXPONENT)}offsetAt(e){const t=this.stretches.find(l=>e>=l.startMs&&e<=l.endMs);if(!t||t.stepHz===0)return Gt.STILL;const n=t.stepsBefore+t.stepHz*(e-t.startMs)/1e3,i=2*Math.PI*n,a=this.amplitudeAt(t,e),r=Gt.SWAY_M*a*Math.cos(i/2),o=a*this.rotationPassed*t.speedMPerS/Gt.REFERENCE_SPEED_M_PER_S;return{eastM:r*t.northUnit,northM:-r*t.eastUnit,upM:Gt.RISE_M_PER_M_PER_S*t.speedMPerS*a*Math.cos(i),rollDeg:Gt.HEAD_ROLL_DEG*o*Math.cos(i/2),pitchDeg:-1.25*o*Math.cos(i),yawDeg:Gt.HEAD_YAW_DEG*o*Math.cos(i/2)}}amplitudeAt(e,t){const n=1e3/e.stepHz,i=Math.min(n,(e.endMs-e.startMs)/2);if(i<=0)return 1;const a=t-e.startMs,r=e.endMs-t,o=Math.min(e.rampsIn?a/i:1,e.rampsOut?r/i:1,1);return(1-Math.cos(Math.PI*Math.max(o,0)))/2}}class O1{constructor(e,t){this.timeline=e,this.onFrame=t}rafId=null;state="stopped";currentT=0;lastWallTime=0;playbackRate=1;loop=!1;onEnded;durationOverrideMs=0;get seekableDuration(){return Math.max(this.timeline.duration,this.durationOverrideMs)}play(){if(this.state==="playing")return;this.currentT>=this.seekableDuration&&(this.currentT=0,this.resolveFrame(0)),this.state="playing",this.lastWallTime=performance.now();const e=()=>{if(this.state!=="playing")return;const t=performance.now();if(this.currentT+=(t-this.lastWallTime)*this.playbackRate,this.lastWallTime=t,this.currentT>=this.seekableDuration){if(this.loop&&this.seekableDuration>0){this.currentT%=this.seekableDuration,this.resolveFrame(this.currentT),this.rafId=requestAnimationFrame(e);return}this.currentT=this.seekableDuration,this.stop(),this.resolveFrame(this.currentT),this.onEnded?.();return}this.resolveFrame(this.currentT),this.rafId=requestAnimationFrame(e)};this.rafId=requestAnimationFrame(e)}pause(){this.state==="playing"&&(this.state="paused",this.rafId!==null&&(cancelAnimationFrame(this.rafId),this.rafId=null))}stop(){this.state="stopped",this.rafId!==null&&(cancelAnimationFrame(this.rafId),this.rafId=null)}seek(e){this.currentT=Math.max(0,Math.min(e,this.seekableDuration)),this.resolveFrame(this.currentT)}get playbackState(){return this.state}get time(){return this.currentT}resolveFrame(e){const t=new Map;for(const n of this.timeline.sourceIds){const i=this.timeline.getInterpolatedShapeAt(e,n);i&&t.set(n,i)}this.onFrame(e,t)}}const nf=.05,sf=.08,af=2,rf=3,k1=14,U1=.02;class F1{context;voice;voiceToken=0;buffers=new Map;noiseBuffer;crackleBuffer;requested;resume(){if(!this.context){if(typeof AudioContext>"u")return;try{this.context=new AudioContext}catch(e){console.warn("SightingAudio: Web Audio unavailable, the sighting stays silent:",e);return}}this.context.state==="suspended"&&this.context.resume()}setSound(e){if(this.requested=e,!this.context)return;const t=this.keyFor(e);if(!t){this.silence();return}if(this.voice?.key!==t){this.stopVoice();const n=++this.voiceToken;t.startsWith("src:")?this.buildRecordedVoice(e.src,t,n):this.voice=this.buildSynthesizedVoice(e,t)}this.applyTo(this.voice,e)}silence(){this.voiceToken++,this.stopVoice()}dispose(){this.silence(),this.context?.close(),this.context=void 0,this.buffers.clear(),this.noiseBuffer=void 0,this.crackleBuffer=void 0}keyFor(e){if(!(e.volume<=0))return e.src?`src:${e.src}`:e.kind==="none"?void 0:e.kind}applyTo(e,t){const n=this.context;if(!e||!n)return;const i=n.currentTime;e.volumeParam.setTargetAtTime(Math.max(0,Math.min(1,t.volume))*e.gainScale,i,nf);for(const{param:a,ratio:r}of e.pitch)a.setTargetAtTime(Math.min(t.pitchHz*r,n.sampleRate/2-1),i,nf)}buildSynthesizedVoice(e,t){const n=this.context;if(n)switch(e.kind){case"hum":return this.buildHum(n,t);case"whistle":return this.buildWhistle(n,t);case"rumble":return this.buildRumble(n,t);case"crackle":return this.buildCrackle(n,t);default:return}}buildHum(e,t){const n=e.createOscillator();n.type="sawtooth";const i=e.createOscillator();i.type="sawtooth";const a=e.createBiquadFilter();a.type="lowpass",a.Q.value=1;const r=e.createGain();return r.gain.value=0,n.connect(a),i.connect(a),a.connect(r).connect(e.destination),n.start(),i.start(),{key:t,nodes:[a,r],sources:[n,i],volumeParam:r.gain,gainScale:.16,pitch:[{param:n.frequency,ratio:1},{param:i.frequency,ratio:1.006},{param:a.frequency,ratio:6}]}}buildWhistle(e,t){const n=e.createOscillator();n.type="sine";const i=e.createOscillator();i.type="sine",i.frequency.value=5;const a=e.createGain(),r=e.createGain();return r.gain.value=0,i.connect(a).connect(n.frequency),n.connect(r).connect(e.destination),n.start(),i.start(),{key:t,nodes:[a,r],sources:[n,i],volumeParam:r.gain,gainScale:.22,pitch:[{param:n.frequency,ratio:1},{param:a.gain,ratio:.012}]}}buildRumble(e,t){const n=e.createBufferSource();n.buffer=this.brownNoise(e),n.loop=!0;const i=e.createBiquadFilter();i.type="lowpass",i.Q.value=.8;const a=e.createGain();return a.gain.value=0,n.connect(i).connect(a).connect(e.destination),n.start(),{key:t,nodes:[i,a],sources:[n],volumeParam:a.gain,gainScale:1.4,pitch:[{param:i.frequency,ratio:1}]}}buildCrackle(e,t){const n=e.createBufferSource();n.buffer=this.whiteNoise(e),n.loop=!0;const i=e.createBiquadFilter();i.type="bandpass",i.Q.value=1.2;const a=e.createGain();a.gain.value=0;const r=e.createBufferSource();r.buffer=this.crackleEnvelope(e),r.loop=!0;const o=e.createGain();return o.gain.value=0,r.connect(o).connect(a.gain),n.connect(i).connect(a).connect(e.destination),n.start(),r.start(),{key:t,nodes:[i,a,o],sources:[n,r],volumeParam:o.gain,gainScale:.9,pitch:[{param:i.frequency,ratio:4}]}}async buildRecordedVoice(e,t,n){const i=this.context;if(!i)return;let a;try{a=await this.getBuffer(e)}catch(l){console.warn("SightingAudio: the recorded sound failed to load, staying silent:",l);return}if(n!==this.voiceToken||!this.context)return;const r=i.createBufferSource();r.buffer=a,r.loop=!0;const o=i.createGain();o.gain.value=0,r.connect(o).connect(i.destination),r.start(),this.voice={key:t,nodes:[o],sources:[r],volumeParam:o.gain,gainScale:1,pitch:[]},this.requested&&this.applyTo(this.voice,this.requested)}async getBuffer(e){const t=this.context;if(!t)throw new Error("SightingAudio: AudioContext not ready — resume() must be called first");let n=this.buffers.get(e);return n||(n=fetch(e).then(i=>{if(!i.ok)throw new Error(`Audio fetch failed (${i.status}): ${e}`);return i.arrayBuffer()}).then(i=>t.decodeAudioData(i)),this.buffers.set(e,n)),n}whiteNoise(e){if(!this.noiseBuffer){const t=e.createBuffer(1,Math.floor(e.sampleRate*af),e.sampleRate),n=t.getChannelData(0);for(let i=0;i<n.length;i++)n[i]=Math.random()*2-1;this.noiseBuffer=t}return this.noiseBuffer}brownNoise(e){const t=e.createBuffer(1,Math.floor(e.sampleRate*af),e.sampleRate),n=t.getChannelData(0);let i=0,a=0;for(let r=0;r<n.length;r++)i=(i+.02*(Math.random()*2-1))/1.02,n[r]=i,a=Math.max(a,Math.abs(i));if(a>0)for(let r=0;r<n.length;r++)n[r]/=a;return t}crackleEnvelope(e){if(!this.crackleBuffer){const t=e.createBuffer(1,Math.floor(e.sampleRate*rf),e.sampleRate),n=t.getChannelData(0),i=Math.max(1,Math.floor(U1*e.sampleRate)),a=Math.round(rf*k1);for(let r=0;r<a;r++){const o=Math.floor(Math.random()*n.length),l=.4+Math.random()*.6;for(let c=0;c<i&&o+c<n.length;c++)n[o+c]=Math.max(n[o+c],l*(1-c/i))}this.crackleBuffer=t}return this.crackleBuffer}stopVoice(){const e=this.voice,t=this.context;if(this.voice=void 0,!e||!t)return;const n=t.currentTime;e.volumeParam.cancelScheduledValues(n),e.volumeParam.setTargetAtTime(0,n,sf/3);const i=n+sf;for(const a of e.sources){a.onended=()=>{a.disconnect();for(const r of e.nodes)r.disconnect()};try{a.stop(i)}catch{a.disconnect();for(const r of e.nodes)r.disconnect()}}}}function $a(s){return[...s].sort((e,t)=>e.t-t.t)}function of(s,e){let t;for(const n of $a(s)){if(n.t>e)break;t=n}return t}const ac=Math.PI/180,ho=180/Math.PI;class Qn{constructor(e,t,n){this.kind=e,this.canvasHeightPx=t,this.fovDeg=n;const i=n*ac/2;this.focalPx=e==="equidistant"?t/2/i:t/2/Math.tan(i)}focalPx;static of(e,t,n){return new Qn(e.projection,t,n)}degToPx(e){const t=e*ac;return this.kind==="equidistant"?this.focalPx*t:2*this.focalPx*Math.tan(t/2)}pxToDeg(e){return this.kind==="equidistant"?e/this.focalPx*ho:2*Math.atan(e/(2*this.focalPx))*ho}angleDegToRadiusPx(e){const t=e*ac;return this.kind==="equidistant"?this.focalPx*t:this.focalPx*Math.tan(t)}halfWidthAngleDeg(e){return this.radiusPxToAngleDeg(this.canvasHeightPx*e/2)}radiusPxToAngleDeg(e){return this.kind==="equidistant"?e/this.focalPx*ho:Math.atan(e/this.focalPx)*ho}ofBounds(e){return{widthDeg:this.pxToDeg(e.width),heightDeg:this.pxToDeg(e.height)}}toBoundsSize(e){return{width:this.degToPx(e.widthDeg),height:this.degToPx(e.heightDeg)}}widthPx(e){return this.degToPx(et.angularWidthDeg(e))}}class en{static fovOf(e,t){return bt(e,t)?.fovDeg??st.fieldOfViewDeg(e.instrument)}static toAngular(e){this.eachKeyframe(e,(t,n)=>({...t,angular:n.ofBounds(t.bounds)}))}static toBounds(e){this.eachKeyframe(e,(t,n)=>{if(!t.angular)return t;const{width:i,height:a}=n.toBoundsSize(t.angular),r={x:t.bounds.x+(t.bounds.width-i)/2,y:t.bounds.y+(t.bounds.height-a)/2,width:i,height:a};if(t.kind!=="polygon")return{...t,bounds:r};const o=t.bounds.width===0?1:i/t.bounds.width,l=t.bounds.height===0?1:a/t.bounds.height;return{...t,bounds:r,points:t.points.map(c=>({x:c.x*o,y:c.y*l}))}})}static toAim(e){this.eachKeyframe(e,(t,n,i)=>{const a=this.aimFrom(e,n,i,t.bounds);return a?{...t,aim:a}:t})}static aimOf(e,t,n){const i=Qn.of(e.instrument,et.CANVAS_HEIGHT_PX,this.fovOf(e,t));return this.aimFrom(e,i,bt(e,t),n)}static aimFrom(e,t,n,i){if(n?.headingDeg===void 0)return;const a=this.frameCentre(e),r=t.radiusPxToAngleDeg(i.x+i.width/2-a.x),o=t.radiusPxToAngleDeg(a.y-(i.y+i.height/2));return{azimuthDeg:((n.headingDeg+r)%360+360)%360,altitudeDeg:n.pitchDeg+o}}static toPosition(e){this.eachKeyframe(e,(t,n,i)=>{if(!t.aim||i?.headingDeg===void 0)return t;const a=this.frameCentre(e),r=this.shortestArc(t.aim.azimuthDeg-i.headingDeg),o=t.aim.altitudeDeg-i.pitchDeg,l=a.x+this.offAxisPx(n,r)-t.bounds.width/2,c=a.y-this.offAxisPx(n,o)-t.bounds.height/2;return{...t,bounds:{...t.bounds,x:l,y:c}}})}static frameCentre(e){return{x:st.frameWidthPx(e.instrument,et.CANVAS_HEIGHT_PX)/2,y:et.CANVAS_HEIGHT_PX/2}}static shortestArc(e){return(e%360+540)%360-180}static offAxisPx(e,t){return Math.abs(t)>=en.OFF_CANVAS_DEG?Math.sign(t)*en.OFF_CANVAS_PX:e.angleDegToRadiusPx(t)}static OFF_CANVAS_DEG=89;static OFF_CANVAS_PX=1e5;static reproject(e,t,n){const i=st.frameWidthPx(t,et.CANVAS_HEIGHT_PX)/2,a=st.frameWidthPx(e.instrument,et.CANVAS_HEIGHT_PX)/2,r=et.CANVAS_HEIGHT_PX/2;for(const o of[...e.timeline.allKeyframes]){const l=this.fovOf(e,o.t),c=n?.get(o.t)??l,h=Qn.of(t,et.CANVAS_HEIGHT_PX,c),d=Qn.of(e.instrument,et.CANVAS_HEIGHT_PX,l);e.timeline.addKeyframe(o.t,o.shapes.map(u=>{const{bounds:f}=u.shape,g=f.x+f.width/2-i,v=f.y+f.height/2-r,p=Math.hypot(g,v),m=p===0?1:d.angleDegToRadiusPx(h.radiusPxToAngleDeg(p))/p,S={...f,x:a+g*m-f.width/2,y:r+v*m-f.height/2};return{...u,shape:{...u.shape,bounds:S}}}))}this.toBounds(e)}static eachKeyframe(e,t){const{timeline:n}=e;for(const i of[...n.allKeyframes]){const a=bt(e,i.t),r=this.fovOf(e,i.t),o=Qn.of(e.instrument,et.CANVAS_HEIGHT_PX,r);n.addKeyframe(i.t,i.shapes.map(l=>({...l,shape:t(l.shape,o,a)})))}}}function B1(s){return Pn.restore(Ih(s),s.provenance)}function Ih(s){return en.toAngular(s),en.toAim(s),{version:1,time:s.event.time,endTime:s.event.endTime,durationSeconds:s.event.durationSeconds,utcOffsetHours:s.event.utcOffsetHours,timeZone:s.event.timeZone,place:s.event.place,witness:s.witness,testimony:s.testimony,caseId:s.caseId,description:s.event.description,tags:s.event.tags,timeline:s.timeline.toJSON(),witnessTrack:s.witnessTrack.toJSON(),weatherTrack:s.weatherTrack.toJSON(),soundTrack:s.soundTrack.toJSON(),weather:s.weather,decor:s.decor,milestones:s.milestones.length>0?s.milestones:void 0,weatherSource:s.weatherSource,instrument:s.instrumentId,exposureSeconds:s.exposureSeconds}}function z1(s){const{recording:e,provenance:t}=Pn.strip(s),n=H1(e);return n.provenance=t,n}function H1(s){const e=new Xl({eventType:"sighting",time:s.time,endTime:s.endTime,durationSeconds:s.durationSeconds,utcOffsetHours:s.utcOffsetHours,timeZone:s.timeZone,place:s.place,description:s.description,tags:s.tags},Wl.fromJSON(s.timeline),s.witnessTrack?Hr.fromJSON(s.witnessTrack):new Hr,s.weatherTrack?Gr.fromJSON(s.weatherTrack):new Gr,s.soundTrack?Vr.fromJSON(s.soundTrack):new Vr,s.witness,s.caseId,s.weather,s.decor??[],s.weatherSource,s.instrument,s.exposureSeconds??s.witnessTrack?.keyframes.map(t=>t.pose.exposureSeconds).find(t=>t!==void 0),$a(s.milestones??[]));return e.testimony=s.testimony,en.toBounds(e),en.toPosition(e),e}function Xr(s,e){for(const t of s){const n=t.toLowerCase().split("-")[0];if(e.includes(n))return n}return"en"}class Vs{static preferencesFor(e){const t=navigator.languages??[],n=this.declaredFor(e);return n?[n,...t]:t}static declaredFor(e){for(let t=e;t;){const n=t.closest("[lang]")?.getAttribute("lang")?.trim();if(n)return n;const i=t.getRootNode();t=i instanceof ShadowRoot?i.host:void 0}}}class Fi{constructor(e){this.preferences=e}read(e){if(e===void 0||typeof e=="string")return e===""?void 0:e;for(const n of this.preferences){const i=e[n]??e[Fi.base(n)];if(i)return i}const t=new Set(this.preferences.map(n=>Fi.base(n)));for(const[n,i]of Object.entries(e))if(i&&t.has(Fi.base(n)))return i;return Object.values(e).find(n=>n)??void 0}write(e,t,n){const i=t?.trim()?t.trim():void 0;if(e===void 0||typeof e=="string")return i;const a={...e},r=Object.keys(a).find(o=>o===n)??Object.keys(a).find(o=>Fi.base(o)===Fi.base(n))??n;return i===void 0?delete a[r]:a[r]=i,Object.keys(a).length===0?void 0:a}static base(e){return e.toLowerCase().split("-")[0]}}const hm=["en","fr"],G1={en:()=>ei(()=>Promise.resolve().then(()=>Y1),void 0,import.meta.url).then(s=>s.ufoMessages_en),fr:()=>ei(()=>import("./UfoMessages_fr-BJPYHN17.js"),[],import.meta.url).then(s=>s.ufoMessages_fr)};function V1(s){return G1[s]()}const W1={en:()=>ei(()=>Promise.resolve().then(()=>NT),void 0,import.meta.url).then(s=>s.sightingEditorMessages_en),fr:()=>ei(()=>import("./SightingEditorMessages_fr-CBPyMrE5.js"),[],import.meta.url).then(s=>s.sightingEditorMessages_fr)};function X1(s){return W1[s]()}function q1(s){return s==="fr"?ei(()=>import("./TagNames_fr-Dnqq6HQ5.js"),[],import.meta.url).then(e=>e.tagNames_fr):Promise.resolve({})}const dm={play:"Play",pause:"Pause",noDuration:"No observation duration",autoReplay:"Auto-replay",currentPosition:"Current position",duration:"Duration",switchToElapsed:"click to show elapsed time",switchToClockTime:"click to show the time of day",fullscreen:"Fullscreen",exitFullscreen:"Exit fullscreen",showWitnessMap:"Show where the witness was",hideWitnessMap:"Hide where the witness was",mapImageryUnavailable:"Aerial imagery unavailable",showMilestones:"Show the account's moments",hideMilestones:"Hide the account's moments",witnessHere:"The witness, here",decorHere:"Scenery"},Y1=Object.freeze(Object.defineProperty({__proto__:null,ufoMessages_en:dm},Symbol.toStringTag,{value:"Module"})),um=Math.PI/180,K1=180/Math.PI,$1=256,Z1=19;function J1(s,e){return 156543.03392*Math.cos(s*um)/2**e}function j1(s,e){return J1(s,e)*$1}function fm(s,e){let t=0;for(;t<Z1&&j1(s,t+1)>=e;)t++;return t}function hl(s){const e=s*um;return(1-Math.log(Math.tan(e)+1/Math.cos(e))/Math.PI)/2}function pm(s,e,t){const n=2**t;return{x:(s+180)/360*n,y:hl(e)*n}}function mm(s,e,t){const n=hl(s.north),i=hl(s.south);return{x:(e-s.west)/(s.east-s.west),y:(hl(t)-n)/(i-n)}}function Q1(s,e,t){const{x:n,y:i}=pm(s,e,t);return{x:Math.floor(n),y:Math.floor(i),z:t}}function ev(s){const e=2**s.z,t=s.x/e*360-180,n=(s.x+1)/e*360-180,i=lf(s.y,e);return{south:lf(s.y+1,e),north:i,west:t,east:n}}function lf(s,e){const t=s/e;return Math.atan(Math.sinh(Math.PI*(1-2*t)))*K1}function gm(s,e,t,n){const i=Q1(s,e,t),a=Math.floor(n/2),r=[];for(let c=-a;c<=a;c++)for(let h=-a;h<=a;h++)r.push({x:i.x+h,y:i.y+c,z:t});const o=r.map(ev),l={south:Math.min(...o.map(c=>c.south)),north:Math.max(...o.map(c=>c.north)),west:Math.min(...o.map(c=>c.west)),east:Math.max(...o.map(c=>c.east))};return{tiles:r,bounds:l}}class Ls{constructor(e){this.ctx=e}static SCALE_STEPS_M=[5e3,2e3,1e3,500,200,100,50,20,10,5];static MARKER_RADIUS_PX=8.5;static ON_MARKER_M=3;targets=[];hitTest(e,t){let n,i=1/0;for(const a of this.targets){const r=Math.hypot(a.x-e,a.y-t);r>a.radius||r>i||(n=a,i=r)}return n}get width(){return this.ctx.canvas.width}get height(){return this.ctx.canvas.height}paint(e){const{ctx:t}=this;t.save(),this.targets=[],t.clearRect(0,0,this.width,this.height),this.paintGround(e),this.paintNight(e.nightFraction),this.paintPath(e),e.position?(this.paintCone(e,e.position),this.paintDecor(e),this.paintMarkers(e),this.paintWitness(e,e.position)):(this.paintDecor(e),this.paintMarkers(e)),this.paintNorth(),this.paintFooter(e.bounds,e.attribution),t.restore()}toCanvas(e,t,n){const i=mm(e,n,t);return{x:i.x*this.width,y:i.y*this.height}}paintGround(e){const{ctx:t}=this;t.fillStyle="#1d2321",t.fillRect(0,0,this.width,this.height);const n=e.imagery;if(!n)return;const i=this.toCanvas(e.bounds,n.bounds.north,n.bounds.west),a=this.toCanvas(e.bounds,n.bounds.south,n.bounds.east);t.drawImage(n.source,i.x,i.y,a.x-i.x,a.y-i.y)}paintNight(e=0){if(e<=0)return;const{ctx:t}=this;t.save(),t.fillStyle=`rgba(6, 12, 30, ${Math.min(e,1)*.78})`,t.fillRect(0,0,this.width,this.height),t.restore()}paintDecor(e){const{ctx:t}=this;for(const n of e.decor){const i=this.toCanvas(e.bounds,n.lat,n.lng);if(n.label&&this.targets.push({kind:"decor",label:n.label,lat:n.lat,lng:n.lng,x:i.x,y:i.y,radius:7}),t.beginPath(),t.rect(i.x-3.5,i.y-3.5,7,7),t.fillStyle="rgba(120, 220, 255, 0.85)",t.fill(),t.lineWidth=1.5,t.strokeStyle="rgba(0, 0, 0, 0.7)",t.stroke(),n.headingDeg===void 0)continue;const a=(n.headingDeg-90)*Math.PI/180;t.beginPath(),t.moveTo(i.x,i.y),t.lineTo(i.x+Math.cos(a)*10,i.y+Math.sin(a)*10),t.lineWidth=3,t.strokeStyle="rgba(0, 0, 0, 0.6)",t.stroke(),t.lineWidth=1.5,t.strokeStyle="rgba(120, 220, 255, 0.9)",t.stroke()}}paintPath(e){if(!e.path.moved)return;const{ctx:t}=this,n=e.path.points.map(i=>this.toCanvas(e.bounds,i.lat,i.lng));t.beginPath(),t.moveTo(n[0].x,n[0].y);for(const i of n.slice(1))t.lineTo(i.x,i.y);t.lineJoin="round",t.lineCap="round",t.strokeStyle="rgba(0, 0, 0, 0.65)",t.lineWidth=5,t.stroke(),t.strokeStyle="rgba(255, 255, 255, 0.9)",t.lineWidth=2,t.stroke()}paintCone(e,t){const{headingDeg:n,coneHalfAngleDeg:i}=e;if(n===void 0||i===void 0)return;const{ctx:a}=this,r=this.toCanvas(e.bounds,t.lat,t.lng),o=Math.hypot(this.width,this.height),l=(n-90)*Math.PI/180,c=i*Math.PI/180;a.save(),a.beginPath(),a.moveTo(r.x,r.y),a.arc(r.x,r.y,o,l-c,l+c),a.closePath();const h=a.createRadialGradient(r.x,r.y,0,r.x,r.y,o);h.addColorStop(0,"rgba(255, 224, 130, 0.55)"),h.addColorStop(.35,"rgba(255, 224, 130, 0.22)"),h.addColorStop(1,"rgba(255, 224, 130, 0)"),a.fillStyle=h,a.fill(),a.restore()}paintMarkers(e){const{ctx:t}=this;t.textAlign="center",t.textBaseline="middle",t.font="bold 10px sans-serif";for(const n of[...e.markers].sort((i,a)=>Number(i.current)-Number(a.current))){const i=this.toCanvas(e.bounds,n.lat,n.lng);this.targets.push({kind:"milestone",label:n.note?`${n.label} — ${n.note}`:n.label,lat:n.lat,lng:n.lng,t:n.t,x:i.x,y:i.y,radius:Ls.MARKER_RADIUS_PX}),t.beginPath(),t.arc(i.x,i.y,Ls.MARKER_RADIUS_PX,0,Math.PI*2),t.fillStyle=n.current?"rgba(255, 224, 130, 0.95)":"rgba(0, 0, 0, 0.55)",t.fill(),t.lineWidth=2,t.strokeStyle="rgba(255, 255, 255, 0.9)",t.stroke(),t.fillStyle=n.current?"#1d2321":"#fff",t.fillText(n.label,i.x,i.y)}}paintWitness(e,t){const{ctx:n}=this,i=this.toCanvas(e.bounds,t.lat,t.lng);e.witnessLabel&&this.targets.push({kind:"witness",label:e.witnessLabel,lat:t.lat,lng:t.lng,x:i.x,y:i.y,radius:8});const a=e.markers.some(r=>{if(!r.current)return!1;const o=gn(r.lat,r.lng,t.lat,t.lng);return Math.hypot(o.x,o.z)<=Ls.ON_MARKER_M});n.beginPath(),n.arc(i.x,i.y,a?Ls.MARKER_RADIUS_PX+2.5:5.5,0,Math.PI*2),a||(n.fillStyle="#ff5a3c",n.fill()),n.lineWidth=4,n.strokeStyle="rgba(0, 0, 0, 0.5)",n.stroke(),n.lineWidth=a?3:2.5,n.strokeStyle=a?"#ff5a3c":"#fff",n.stroke()}paintNorth(){const{ctx:e}=this,t=this.width-14,n=16;e.beginPath(),e.moveTo(t,n-9),e.lineTo(t-4.5,n+5),e.lineTo(t,n+2),e.lineTo(t+4.5,n+5),e.closePath(),e.fillStyle="rgba(255, 255, 255, 0.92)",e.strokeStyle="rgba(0, 0, 0, 0.6)",e.lineWidth=1,e.fill(),e.stroke(),e.font="bold 9px sans-serif",e.textAlign="center",e.textBaseline="top",e.strokeText("N",t,n+6),e.fillText("N",t,n+6)}paintFooter(e,t){const{ctx:n}=this;n.font="9px sans-serif",n.textBaseline="bottom";const i=t?this.wrap(t,this.width-20):[];let a=this.height-4;n.textAlign="right";for(const f of i.slice().reverse())this.paintOutlinedText(f,this.width-6,a),a-=11;const r=(e.south+e.north)/2,l=Math.abs(gn(r,e.east,r,e.west).x)/this.width,c=Ls.SCALE_STEPS_M.find(f=>f/l<=this.width/3);if(c===void 0)return;const h=c/l,d=8,u=a-3;n.lineWidth=3,n.strokeStyle="rgba(0, 0, 0, 0.6)",n.beginPath(),n.moveTo(d,u),n.lineTo(d+h,u),n.stroke(),n.lineWidth=1.5,n.strokeStyle="rgba(255, 255, 255, 0.95)",n.stroke(),n.textAlign="left",this.paintOutlinedText(c>=1e3?`${c/1e3} km`:`${c} m`,d,u-3)}paintOutlinedText(e,t,n){const{ctx:i}=this;i.lineWidth=3,i.strokeStyle="rgba(0, 0, 0, 0.75)",i.strokeText(e,t,n),i.fillStyle="#fff",i.fillText(e,t,n)}wrap(e,t){const n=[];let i="";for(const a of e.split(" ")){const r=i?`${i} ${a}`:a;i&&this.ctx.measureText(r).width>t?(n.push(i),i=a):i=r}return i&&n.push(i),n}}const Fn=256,cf=3,tv=32768;class vm{fetchImpl;tileUrlTemplate;constructor(e={}){this.fetchImpl=e.fetchImpl??fetch.bind(globalThis),this.tileUrlTemplate=e.tileUrlTemplate??"https://s3.amazonaws.com/elevation-tiles-prod/terrarium/{z}/{x}/{y}.png"}async getElevationGrid(e,t){const n=(e.south+e.north)/2,i=(e.west+e.east)/2,a=Math.abs(gn(n,e.east,n,e.west).x),r=Math.abs(gn(e.north,i,e.south,i).z),o=fm(n,Math.max(a,r)),{tiles:l}=gm(i,n,o,cf),c=cf*Fn,h=new Float32Array(c*c),d=l[0];await Promise.all(l.map(f=>this.decodeTileInto(f,d,h,c)));const u=new Float32Array(t.width*t.height);for(let f=0;f<t.height;f++){const g=e.north+(e.south-e.north)*(f/(t.height-1));for(let v=0;v<t.width;v++){const p=e.west+(e.east-e.west)*(v/(t.width-1));u[f*t.width+v]=this.sampleAt(g,p,o,d,h,c)}}return{heights:u,width:t.width,height:t.height,bounds:e}}async decodeTileInto(e,t,n,i){const a=this.tileUrlTemplate.replace("{z}",String(e.z)).replace("{x}",String(e.x)).replace("{y}",String(e.y)),r=await this.fetchImpl(a);if(!r.ok)throw new Error(`Elevation tile fetch failed (${r.status}): ${a}`);const o=await createImageBitmap(await r.blob()),l=document.createElement("canvas");l.width=Fn,l.height=Fn;const c=l.getContext("2d");if(!c)throw new Error("2D canvas context unavailable");c.drawImage(o,0,0);const{data:h}=c.getImageData(0,0,Fn,Fn),d=(e.x-t.x)*Fn,u=(e.y-t.y)*Fn;for(let f=0;f<Fn;f++)for(let g=0;g<Fn;g++){const v=(f*Fn+g)*4,p=h[v]*256+h[v+1]+h[v+2]/256-tv,m=d+g,S=u+f;n[S*i+m]=p}}sampleAt(e,t,n,i,a,r){const{x:o,y:l}=pm(t,e,n),c=(o-i.x)*Fn,h=(l-i.y)*Fn,d=Math.max(0,Math.min(r-1,Math.floor(c))),u=Math.max(0,Math.min(r-1,Math.floor(h))),f=Math.min(r-1,d+1),g=Math.min(r-1,u+1),v=c-d,p=h-u,m=a[u*r+d],S=a[u*r+f],_=a[g*r+d],x=a[g*r+f],M=m+(S-m)*v,E=_+(x-_)*v;return M+(E-M)*p}}const rc=256,hf=3;async function ym(s,e,t,n){const i=(s.south+s.north)/2,a=(s.west+s.east)/2,r=Math.abs(gn(i,s.east,i,s.west).x),o=Math.abs(gn(s.north,a,s.south,a).z),l=fm(i,Math.max(r,o)/2),{tiles:c,bounds:h}=gm(a,i,l,hf),d=hf*rc,u=document.createElement("canvas");u.width=d,u.height=d;const f=u.getContext("2d");if(!f)throw new Error("2D canvas context unavailable");const g=c[0];await Promise.all(c.map(async m=>{const S=t(m),_=await n(S);if(!_.ok)throw new Error(`Imagery tile fetch failed (${_.status}): ${S}`);const x=await createImageBitmap(await _.blob());f.drawImage(x,(m.x-g.x)*rc,(m.y-g.y)*rc)}));const v=document.createElement("canvas");v.width=e.width,v.height=e.height;const p=v.getContext("2d");if(!p)throw new Error("2D canvas context unavailable");return p.drawImage(u,0,0,d,d,0,0,e.width,e.height),{source:v,width:e.width,height:e.height,bounds:h}}class bm{attribution="Imagery © Esri, Maxar, Earthstar Geographics, and the GIS User Community";fetchImpl;tileUrlTemplate;constructor(e={}){this.fetchImpl=e.fetchImpl??fetch.bind(globalThis),this.tileUrlTemplate=e.tileUrlTemplate??"https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}"}async getImageryTexture(e,t){return ym(e,t,n=>this.tileUrlTemplate.replace("{z}",String(n.z)).replace("{y}",String(n.y)).replace("{x}",String(n.x)),this.fetchImpl)}}function nv(){return{elevation:new vm,imagery:xm()}}function xm(){return new bm}const iv=new Set,Ws="show-witness-map",ka="hide-milestones";class zn extends HTMLElement{static get observedAttributes(){return["src",Ws,ka]}shadow;stageElement;canvas;canvasRenderer;tooltip;toolbar;playPauseButton;loopButton;static WITNESS_MAP_MIN_SPAN_M=400;static WITNESS_MAP_MARGIN=.6;static WITNESS_MAP_IMAGERY_PX=768;fullscreenButton;cornerButtons;witnessMapButton;milestonesButton;witnessMapPanel;witnessMapCanvas;witnessMapRenderer;seekInput;milestoneMarks;milestoneCaption;timeStartLabel;timeEndLabel;witnessPath;witnessMapBounds;witnessMapImagery;witnessMapImageryRequested=!1;witnessMapImageryCredit;witnessMapImageryFailed=!1;creditShownExternally=!1;lookYawDeg=0;lookPitchDeg=0;milestonesShown=!0;currentSighting=Xl.create();sightingAudio=new F1;soundPreview;player;loopEnabled=!0;playbackBeforeClick;highlightedSourceIds=new Set;paintsShapes=!0;enableClickToPlay=!0;fullscreenTarget;messages=dm;realDurationMs;realStartMs;showClockTime=!0;handleFullscreenChange=()=>{this.updateFullscreenButton(),this.resizeWitnessMap()};witnessMapResizeObserver=typeof ResizeObserver>"u"?void 0:new ResizeObserver(()=>this.resizeWitnessMap());resizeWitnessMap(){this.witnessMapPanel.hidden||(this.sizeWitnessMapCanvas(),this.paintWitnessMap(this.currentTime))}simulatedFullscreen=!1;styleBeforeSimulatedFullscreen;bodyOverflowBeforeSimulatedFullscreen;handleSimulatedFullscreenKey=e=>{e.key==="Escape"&&this.exitSimulatedFullscreen()};handlePointerMove=e=>{const t=this.canvasPointFromEvent(e),n=t&&this.shapeAt(t.x,t.y),i=this.said.read(n?.shape.title);if(!i){this.tooltip.hidden=!0;return}this.tooltip.textContent=i,this.tooltip.hidden=!1;const a=this.stageElement.getBoundingClientRect();this.tooltip.style.left=`${e.clientX-a.left+12}px`,this.tooltip.style.top=`${e.clientY-a.top+12}px`};handleWitnessMapPointerMove=e=>{const t=this.witnessMapTargetFrom(e);if(!t){this.tooltip.hidden=!0,this.witnessMapCanvas.style.cursor="default";return}this.witnessMapCanvas.style.cursor="pointer",this.tooltip.textContent=t.label,this.tooltip.hidden=!1;const n=this.stageElement.getBoundingClientRect();this.tooltip.style.left=`${e.clientX-n.left+12}px`,this.tooltip.style.top=`${e.clientY-n.top+12}px`};handleWitnessMapClick=e=>{const t=this.witnessMapTargetFrom(e);if(t){if(t.kind==="milestone"&&t.t!==void 0){this.player.seek(t.t);return}this.dispatchEvent(new CustomEvent("lookat",{detail:{lat:t.lat,lng:t.lng,kind:t.kind},bubbles:!0,composed:!0}))}};witnessMapTargetFrom(e){const t=this.witnessMapCanvas.getBoundingClientRect();if(!(t.width===0||t.height===0))return this.witnessMapRenderer.hitTest((e.clientX-t.left)/t.width*this.witnessMapCanvas.width,(e.clientY-t.top)/t.height*this.witnessMapCanvas.height)}handlePointerLeave=()=>{this.tooltip.hidden=!0};constructor(){super(),this.shadow=this.attachShadow({mode:"open"});const e=document.createElement("template");e.innerHTML=`<style>${N1}</style>${L1}`,this.shadow.appendChild(e.content.cloneNode(!0)),this.stageElement=this.shadow.getElementById("stage"),this.canvas=this.shadow.getElementById("canvas"),this.canvasRenderer=new wh(this.canvas.getContext("2d")),this.tooltip=this.shadow.getElementById("tooltip"),this.toolbar=this.shadow.getElementById("toolbar"),this.playPauseButton=this.shadow.getElementById("play-pause"),this.loopButton=this.shadow.getElementById("loop"),this.fullscreenButton=this.shadow.getElementById("fullscreen"),this.cornerButtons=this.shadow.getElementById("corner-buttons"),this.witnessMapButton=this.shadow.getElementById("witness-map"),this.milestonesButton=this.shadow.getElementById("milestones"),this.witnessMapPanel=this.shadow.getElementById("witness-map-panel"),this.witnessMapCanvas=this.shadow.getElementById("witness-map-canvas"),this.witnessMapRenderer=new Ls(this.witnessMapCanvas.getContext("2d")),this.seekInput=this.shadow.getElementById("seek"),this.milestoneMarks=this.shadow.getElementById("milestone-marks"),this.milestoneCaption=this.shadow.getElementById("milestone-caption"),this.timeStartLabel=this.shadow.getElementById("time-start"),this.timeEndLabel=this.shadow.getElementById("time-end");for(const t of[this.timeStartLabel,this.timeEndLabel])t.addEventListener("click",()=>this.toggleTimeDisplay()),t.addEventListener("keydown",n=>{n.key!=="Enter"&&n.key!==" "||(n.preventDefault(),this.toggleTimeDisplay())});this.fullscreenTarget=this.stageElement,this.playPauseButton.addEventListener("click",()=>this.togglePlayPause()),this.loopButton.addEventListener("click",()=>this.toggleLoop()),this.fullscreenButton.addEventListener("click",()=>this.toggleFullscreen()),this.witnessMapButton.addEventListener("click",()=>this.toggleWitnessMap()),this.milestonesButton.addEventListener("click",()=>this.toggleMilestones()),this.witnessMapCanvas.addEventListener("pointermove",this.handleWitnessMapPointerMove),this.witnessMapCanvas.addEventListener("pointerleave",this.handlePointerLeave),this.witnessMapCanvas.addEventListener("click",this.handleWitnessMapClick),this.seekInput.addEventListener("input",()=>this.player.seek(Number(this.seekInput.value))),this.canvas.addEventListener("click",t=>{this.enableClickToPlay&&(t.detail<=1&&(this.playbackBeforeClick={state:this.playbackState,time:this.currentTime}),this.togglePlayPause())}),this.canvas.addEventListener("dblclick",t=>{this.enableClickToPlay&&(t.preventDefault(),this.restorePlayback(),this.toggleFullscreen())}),this.canvas.addEventListener("pointermove",this.handlePointerMove),this.canvas.addEventListener("pointerleave",this.handlePointerLeave),document.addEventListener("fullscreenchange",this.handleFullscreenChange),this.witnessMapResizeObserver?.observe(this.witnessMapPanel),this.player=this.createPlayer(),this.updateTimeLabels(),this.updatePlayPauseButton(),this.updateFullscreenButton(),this.updateWitnessMapButton(),this.updateMilestonesButton(),this.refresh(),this.loadLocaleMessages()}connectedCallback(){this.saidTexts=void 0;const e=this.getAttribute("src");e&&this.loadFromSrc(e)}disconnectedCallback(){document.removeEventListener("fullscreenchange",this.handleFullscreenChange),this.witnessMapResizeObserver?.disconnect(),this.exitSimulatedFullscreen(),this.sightingAudio.dispose()}attributeChangedCallback(e,t,n){e==="src"&&n&&n!==t&&this.isConnected&&this.loadFromSrc(n),e===Ws&&this.applyWitnessMapDefault(),e===ka&&this.setMilestonesShown(!this.hasAttribute(ka))}async loadFromSrc(e){this.sightingData=await Kd.json(e)}get sightingData(){return B1(this.currentSighting)}set sightingData(e){this.player.stop(),this.soundPreview=void 0,this.sightingAudio.silence(),this.currentSighting=z1(e),this.player=this.createPlayer(),this.updateTimeLabels(),this.updatePlayPauseButton(),this.refresh(),this.applyWitnessMapDefault()}get sighting(){return this.currentSighting}previewSound(e){this.soundPreview=e,this.sightingAudio.resume(),this.sightingAudio.setSound(e)}stopSoundPreview(){this.soundPreview=void 0,this.sightingAudio.silence()}get canvasElement(){return this.canvas}get renderer(){return this.canvasRenderer}get currentTime(){return this.player.time}set currentTime(e){this.player.seek(e)}get seekableDuration(){return this.player.seekableDuration}get autoReplayEnabled(){return this.loopEnabled}set autoReplayEnabled(e){e!==this.loopEnabled&&this.toggleLoop()}play(){this.player.seekableDuration<=0||this.playbackState==="playing"||this.togglePlayPause()}pause(){this.playbackState==="playing"&&this.togglePlayPause()}get positionLabel(){return this.timeStartLabel.textContent??""}get durationLabel(){return this.timeEndLabel.textContent??""}get showingClockTime(){return this.canShowClockTime}get canSwitchTimeDisplay(){return this.realStartMs!==void 0}toggleTimeDisplay(){this.canSwitchTimeDisplay&&(this.showClockTime=!this.showClockTime,this.updateTimeLabels(),this.updateTimeLabelTitles(),this.dispatchEvent(new CustomEvent("timedisplaychange",{bubbles:!0,composed:!0})))}get canShowClockTime(){return this.realStartMs!==void 0&&this.showClockTime}set showToolbar(e){this.toolbar.classList.toggle("hidden",!e)}get playbackState(){return this.player.playbackState}get selectedSourceIds(){return this.highlightedSourceIds}get durationSeconds(){return this.currentSighting.event.durationSeconds}set durationSeconds(e){this.currentSighting.event.durationSeconds=e,this.updateTimeLabels(),this.refresh(),this.updatePlayPauseButton()}set selectedSourceIds(e){const t=new Set(e);t.size===this.highlightedSourceIds.size&&[...t].every(i=>this.highlightedSourceIds.has(i))||(this.highlightedSourceIds=t,this.refresh())}hasVisibleShapeAt(e,t){return this.shapeAt(e,t)!==void 0}refresh(){this.applyFrameFormat(),this.updateTimeLabels(),this.seekInput.max=String(this.player.seekableDuration),this.refreshMilestoneMarks(),this.updateMilestonesButton(),this.updateWitnessMap(),this.player.seek(this.player.time)}refreshMilestoneMarks(){const e=this.player.seekableDuration,t=e>0?$a(this.sighting.milestones):[];this.milestoneMarks.replaceChildren(...t.map(n=>{const i=document.createElement("button");i.type="button",i.className="milestone-mark",i.style.left=`${Math.min(Math.max(n.t/e,0),1)*100}%`;const a=this.said.read(n.label)??"",r=this.said.read(n.note),o=r?`${a} — ${r}`:a;return i.title=o,i.setAttribute("aria-label",o),i.addEventListener("click",()=>this.player.seek(n.t)),i}))}showMilestoneAt(e){const t=this.milestonesShown&&this.sighting.milestones.length>0?of(this.sighting.milestones,e):void 0;if(this.milestoneCaption.hidden=t===void 0,!t)return;const n=document.createElement("b");n.textContent=this.said.read(t.label)??"";const i=this.said.read(t.note),a=i?` — ${i}`:"";this.milestoneCaption.replaceChildren(n,document.createTextNode(a))}exposureInstants(e){const t=this.exposureTimes(e),n=1/t.length;return t.map(i=>({shapes:this.shapesAt(i),share:n}))}exposureTimes(e=this.currentTime){const t=(this.currentSighting.exposure??0)*1e3;if(t<zn.SHORTEST_VISIBLE_EXPOSURE_MS)return[e];const n=Math.min(zn.MAX_EXPOSURE_STEPS,Math.max(2,Math.round(t/zn.SHORTEST_VISIBLE_EXPOSURE_MS))),i=Math.ceil(this.travelPxOver(e,t)/zn.EXPOSURE_STEP_PX),a=Math.min(zn.MAX_TRAVEL_STEPS,Math.max(n,i)),r=[];for(let o=0;o<a;o++)r.push(e+t*o/a);return r}travelPxOver(e,t){const n=this.shapesAt(e),i=this.shapesAt(e+t);let a=0;for(const[r,o]of n){const l=i.get(r);if(!l)continue;const c=l.bounds.x+l.bounds.width/2-(o.bounds.x+o.bounds.width/2),h=l.bounds.y+l.bounds.height/2-(o.bounds.y+o.bounds.height/2);a=Math.max(a,Math.hypot(c,h))}return a}shapeAt(e,t,n){for(const i of this.exposureTimes()){const a=this.currentSighting.timeline.hitTest(i,e,t,n);if(a)return a}}shapesAt(e){const t=new Map;for(const n of this.currentSighting.timeline.sourceIds){const i=this.currentSighting.timeline.getInterpolatedShapeAt(e,n);i&&t.set(n,i)}return t}static SHORTEST_VISIBLE_EXPOSURE_MS=20;static MAX_EXPOSURE_STEPS=48;static EXPOSURE_STEP_PX=2;static MAX_TRAVEL_STEPS=320;applyFrameFormat(){const e=st.frameWidthPx(this.currentSighting.instrument,this.canvas.height);if(this.canvas.width===e)return;this.canvas.width=e,this.canvas.parentElement?.style.setProperty("--frame-aspect",`${e} / ${this.canvas.height}`)}canvasPointFromEvent(e){const t=this.canvas.getBoundingClientRect();if(!(t.width===0||t.height===0))return{x:(e.clientX-t.left)/t.width*this.canvas.width,y:(e.clientY-t.top)/t.height*this.canvas.height}}onFrame(e,t){this.canvasRenderer.clear(this.canvas.width,this.canvas.height);const n=this.playbackState!=="playing"?this.highlightedSourceIds:iv;this.canvasRenderer.setStarPoints(st.starPointsOf(this.sighting.instrument));const i=(bt(this.sighting,e)?.rollDeg??0)+this.gaitAt(e).rollDeg;this.canvasRenderer.setRoll(i*Math.PI/180);const a=this.exposureInstants(e),r=this.frameShift;if(this.paintsShapes)for(const o of a)for(const[,l]of o.shapes){const c=o.share,h=c===1?l:{...l,transparency:1-(1-l.transparency)*c};this.canvasRenderer.paintShape(this.shifted(h,r))}for(const[o,l]of a[0].shapes)n.has(o)&&(this.paintsShapes?n.size===1?this.canvasRenderer.paintShape({...l,selected:!0}):this.canvasRenderer.paintMemberOutline(l):this.canvasRenderer.paintSelectionOnly(this.shifted(l,r)));if(n.size>1){const o=it.groupBoundsFor([...t].filter(([l])=>n.has(l)).map(([,l])=>l.bounds));this.canvasRenderer.paintGroupHandles(o)}this.keepWitnessMapClear(a[0].shapes),this.seekInput.value=String(e),this.timeStartLabel.textContent=this.formatPosition(e),this.showMilestoneAt(e),this.paintWitnessMap(e),this.playbackState==="playing"?(this.soundPreview=void 0,this.sightingAudio.setSound(Jd(this.currentSighting,e))):this.soundPreview?this.sightingAudio.setSound(this.soundPreview):this.sightingAudio.silence(),this.updatePlayPauseButton(),this.dispatchEvent(new CustomEvent("timeupdate",{detail:{time:e}}))}shifted(e,t){return t.x===0&&t.y===0?e:{...e,bounds:{...e.bounds,x:e.bounds.x+t.x,y:e.bounds.y+t.y}}}createPlayer(){const e=new O1(this.currentSighting.timeline,(t,n)=>this.onFrame(t,n));return e.loop=this.loopEnabled,e.onEnded=()=>{this.updatePlayPauseButton(),this.dispatchEvent(new CustomEvent("ended",{bubbles:!0,composed:!0}))},e}togglePlayPause(){this.player.seekableDuration<=0||(this.player.playbackState==="playing"?(this.player.pause(),this.soundPreview=void 0,this.sightingAudio.silence(),this.refresh()):(this.sightingAudio.resume(),this.player.play()),this.updatePlayPauseButton())}updatePlayPauseButton(){const e=this.player.playbackState==="playing";this.playPauseButton.textContent=e?"⏸":"▶";const t=this.player.seekableDuration>0;this.playPauseButton.disabled=!t;const n=t?e?this.messages.pause:this.messages.play:this.messages.noDuration;this.playPauseButton.title=n,this.playPauseButton.setAttribute("aria-label",n),this.toolbar.classList.toggle("auto-hide",e),this.cornerButtons.classList.toggle("auto-hide",e)}toggleLoop(){this.loopEnabled=!this.loopEnabled,this.loopButton.setAttribute("aria-pressed",String(this.loopEnabled)),this.player.loop=this.loopEnabled}restorePlayback(){const e=this.playbackBeforeClick;e&&(this.currentTime=e.time,e.state==="playing"?this.play():this.pause())}get canUseNativeFullscreen(){return typeof this.fullscreenTarget.requestFullscreen=="function"&&document.fullscreenEnabled}toggleFullscreen(){if(!this.canUseNativeFullscreen){this.simulatedFullscreen?this.exitSimulatedFullscreen():this.enterSimulatedFullscreen();return}document.fullscreenElement?document.exitFullscreen():this.fullscreenTarget.requestFullscreen().catch(e=>{console.error("<rr0-ufo>: requestFullscreen() failed —",e)})}enterSimulatedFullscreen(){const e=this.fullscreenTarget;this.styleBeforeSimulatedFullscreen=e.getAttribute("style")??"",this.bodyOverflowBeforeSimulatedFullscreen=document.body.style.overflow;const t=e.style;t.setProperty("position","fixed"),t.setProperty("inset","0"),t.setProperty("margin","0"),t.setProperty("max-width","none"),t.setProperty("max-height","none"),t.setProperty("aspect-ratio","auto"),t.setProperty("z-index","2147483647"),t.setProperty("background","#000"),t.setProperty("width","100vw"),t.setProperty("width","100dvw"),t.setProperty("height","100vh"),t.setProperty("height","100dvh"),document.body.style.overflow="hidden",this.simulatedFullscreen=!0,document.addEventListener("keydown",this.handleSimulatedFullscreenKey),this.updateFullscreenButton()}exitSimulatedFullscreen(){if(!this.simulatedFullscreen)return;const e=this.fullscreenTarget;this.styleBeforeSimulatedFullscreen?e.setAttribute("style",this.styleBeforeSimulatedFullscreen):e.removeAttribute("style"),document.body.style.overflow=this.bodyOverflowBeforeSimulatedFullscreen??"",this.simulatedFullscreen=!1,document.removeEventListener("keydown",this.handleSimulatedFullscreenKey),this.updateFullscreenButton()}toggleWitnessMap(){this.setWitnessMapOpen(this.witnessMapPanel.hidden)}applyWitnessMapDefault(){this.setWitnessMapOpen(this.hasAttribute(Ws)&&this.witnessPath!==void 0)}setWitnessMapOpen(e){this.witnessMapPanel.hidden=!e,this.witnessMapPanel.removeAttribute("title"),this.witnessMapButton.setAttribute("aria-pressed",String(e)),this.updateWitnessMapButton(),e&&(this.sizeWitnessMapCanvas(),this.loadWitnessMapImagery(),this.paintWitnessMap(this.currentTime))}updateWitnessMapButton(){const t=!this.witnessMapPanel.hidden?this.messages.hideWitnessMap:this.messages.showWitnessMap;this.witnessMapButton.title=t,this.witnessMapButton.setAttribute("aria-label",t)}updateWitnessMap(){const e=this.witnessPath!==void 0;if(this.witnessPath=Wr.of(this.currentSighting),this.witnessMapButton.hidden=this.witnessPath===void 0,!e&&this.witnessPath&&this.applyWitnessMapDefault(),!this.witnessPath){this.setWitnessMapOpen(!1),this.witnessMapBounds=void 0;return}const t=this.witnessPath.boundsAround(zn.WITNESS_MAP_MIN_SPAN_M,zn.WITNESS_MAP_MARGIN);(!this.witnessMapBounds||!this.sameGround(this.witnessMapBounds,t))&&(this.witnessMapBounds=t,this.witnessMapImagery=void 0,this.witnessMapImageryCredit=void 0,this.witnessMapImageryFailed=!1,this.witnessMapImageryRequested=!1,this.witnessMapPanel.hidden||this.loadWitnessMapImagery())}sameGround(e,t){const n=Math.abs(e.east-e.west)/20;return Math.abs(e.north-t.north)<n&&Math.abs(e.south-t.south)<n&&Math.abs(e.west-t.west)<n&&Math.abs(e.east-t.east)<n}async loadWitnessMapImagery(){if(this.witnessMapImageryRequested||!this.witnessMapBounds)return;this.witnessMapImageryRequested=!0;const e=xm(),t=this.witnessMapBounds;try{const n=await e.getImageryTexture(t,{width:zn.WITNESS_MAP_IMAGERY_PX,height:zn.WITNESS_MAP_IMAGERY_PX});if(this.witnessMapBounds!==t)return;this.witnessMapImagery=n,this.witnessMapImageryCredit=e.attribution}catch{this.witnessMapImageryFailed=!0}this.paintWitnessMap(this.currentTime)}get witnessMapCredit(){return this.witnessMapImageryCredit}get witnessMapFooterLine(){return this.witnessMapImageryFailed?this.messages.mapImageryUnavailable:this.creditShownExternally?void 0:this.witnessMapImageryCredit}keepWitnessMapClear(e){if(this.witnessMapPanel.hidden)return;const t=this.witnessMapBoxPx;if(!t)return;const n=(o,l,c)=>{for(const h of e.values())if(!(h.transparency>=1)&&!(h.bounds.x+h.bounds.width<o-c||h.bounds.x>l+c)&&!(h.bounds.y>t.bottom+c||h.bounds.y+h.bounds.height<t.top-c))return!0;return!1},i=[this.canvas.width-t.width,this.canvas.width],a=[0,t.width],r=zn.WITNESS_MAP_CLEARANCE_PX;if(this.witnessMapPanel.classList.contains("on-the-left")){n(i[0],i[1],r)||this.witnessMapPanel.classList.remove("on-the-left");return}n(i[0],i[1],0)&&!n(a[0],a[1],0)&&this.witnessMapPanel.classList.add("on-the-left")}witnessMapBoxPx;static WITNESS_MAP_CLEARANCE_PX=24;sizeWitnessMapCanvas(){const e=this.witnessMapPanel.clientWidth;if(e===0)return;const t=Math.round(e*(globalThis.devicePixelRatio??1));this.measureWitnessMapBox(),this.witnessMapCanvas.width!==t&&(this.witnessMapCanvas.width=t,this.witnessMapCanvas.height=t)}measureWitnessMapBox(){const e=this.witnessMapPanel.getBoundingClientRect(),t=this.canvas.getBoundingClientRect();if(t.width===0||t.height===0)return;const n=this.canvas.width/t.width,i=this.canvas.height/t.height;this.witnessMapBoxPx={width:e.width*n,top:(e.top-t.top)*i,bottom:(e.bottom-t.top)*i}}paintWitnessMap(e){if(this.witnessMapPanel.hidden||!this.witnessPath||!this.witnessMapBounds)return;const t=bt(this.currentSighting,e),n=this.currentSighting.instrument,i=[],a=this.currentSighting.milestones.length>0?of(this.currentSighting.milestones,e):void 0;for(const r of this.milestonesShown?$a(this.currentSighting.milestones):[]){const o=bt(this.currentSighting,r.t);o?.lat===void 0||o.lng===void 0||i.push({label:this.said.read(r.label)??"",note:this.said.read(r.note),t:r.t,lat:o.lat,lng:o.lng,current:r===a})}this.witnessMapRenderer.paint({bounds:this.witnessMapBounds,imagery:this.witnessMapImagery,path:this.witnessPath,position:t?.lat!==void 0&&t.lng!==void 0?{lat:t.lat,lng:t.lng}:void 0,headingDeg:t?.headingDeg===void 0?void 0:t.headingDeg+this.lookYawDeg,coneHalfAngleDeg:t?Qn.of(n,this.canvas.height,t.fovDeg).halfWidthAngleDeg(st.aspectOf(n)):void 0,markers:i,decor:this.witnessMapDecorAt(e),witnessLabel:this.said.read(this.currentSighting.witness?.title)??this.messages.witnessHere,nightFraction:this.witnessMapNightFraction,attribution:this.witnessMapFooterLine})}toggleMilestones(){this.setMilestonesShown(!this.milestonesShown)}setMilestonesShown(e){this.milestonesShown=e,this.milestoneMarks.hidden=!e,this.milestonesButton.setAttribute("aria-pressed",String(e)),this.updateMilestonesButton(),this.showMilestoneAt(this.currentTime),this.paintWitnessMap(this.currentTime)}updateMilestonesButton(){this.milestonesButton.hidden=this.currentSighting.milestones.length===0;const e=this.milestonesShown?this.messages.hideMilestones:this.messages.showMilestones;this.milestonesButton.title=e,this.milestonesButton.setAttribute("aria-label",e)}witnessMapDecorAt(e){const t=bt(this.currentSighting,0);return t?.lat===void 0||t.lng===void 0?[]:this.currentSighting.decor.filter(n=>n.kind!=="crop").map(n=>{const i=Ya(n,e),{lat:a,lng:r}=zi(i.eastM,-i.northM,t.lat,t.lng);return{lat:a,lng:r,headingDeg:i.headingDeg,label:this.said.read(n.title)??this.messages.decorHere}})}witnessMapNightFraction;setSunAltitude(e){const t=e===void 0?void 0:Math.max(0,Math.min(1,-e/12));t!==this.witnessMapNightFraction&&(this.witnessMapNightFraction=t,this.paintWitnessMap(this.currentTime))}setLookOffset(e,t){e===this.lookYawDeg&&t===this.lookPitchDeg||(this.lookYawDeg=e,this.lookPitchDeg=t,this.refresh())}get frameShiftPx(){return this.frameShift}get frameShift(){const e=this.gaitAt(this.currentTime),t=this.lookYawDeg+e.yawDeg,n=this.lookPitchDeg+e.pitchDeg;if(t===0&&n===0)return{x:0,y:0};const i=bt(this.currentSighting,this.currentTime),a=Qn.of(this.currentSighting.instrument,this.canvas.height,i?.fovDeg??60);return{x:-a.angleDegToRadiusPx(t),y:a.angleDegToRadiusPx(n)}}gaitAt(e){return Gt.of(this.currentSighting)?.offsetAt(e)??Gt.STILL}updateFullscreenButton(){const e=this.simulatedFullscreen||document.fullscreenElement===this.fullscreenTarget;this.fullscreenButton.title=e?this.messages.exitFullscreen:this.messages.fullscreen,this.fullscreenButton.setAttribute("aria-label",this.fullscreenButton.title)}get said(){return this.saidTexts??=new Fi(Vs.preferencesFor(this))}saidTexts;async loadLocaleMessages(){const e=Xr(Vs.preferencesFor(this),hm);e!=="en"&&this.applyMessages(await V1(e))}updateTimeLabelTitles(){const e=this.showClockTime?this.messages.switchToElapsed:this.messages.switchToClockTime,t=this.canSwitchTimeDisplay?` — ${e}`:"";this.timeStartLabel.title=this.messages.currentPosition+t,this.timeEndLabel.title=this.messages.duration+t;for(const n of[this.timeStartLabel,this.timeEndLabel])n.classList.toggle("switchable",this.canSwitchTimeDisplay),this.canSwitchTimeDisplay?(n.setAttribute("role","button"),n.setAttribute("tabindex","0")):(n.removeAttribute("role"),n.removeAttribute("tabindex"))}applyMessages(e){this.messages=e,this.updateTimeLabelTitles(),this.loopButton.title=e.autoReplay,this.loopButton.setAttribute("aria-label",e.autoReplay),this.updatePlayPauseButton(),this.updateFullscreenButton(),this.updateWitnessMapButton(),this.updateMilestonesButton()}updateTimeLabels(){const e=this.currentSighting.event,t=Ka(e);this.realDurationMs=t!==void 0&&t>0?t:void 0,this.realStartMs=e.time?Eh(e.time):void 0;const n=this.currentSighting.timeline.duration;this.player.playbackRate=this.realDurationMs!==void 0&&n>0?n/this.realDurationMs:1,this.player.durationOverrideMs=n>0?0:this.realDurationMs??0,this.timeEndLabel.textContent=this.formatEndOfTimeline(),this.timeStartLabel.textContent=this.formatPosition(this.player.time),this.updateTimeLabelTitles()}formatPosition(e){if(this.realDurationMs===void 0)return uo(e);const t=this.currentSighting.timeline.duration,n=t>0&&e<=t?e/t*this.realDurationMs:e;return this.canShowClockTime?uf(df(this.realStartMs+n)):uo(n)}formatEndOfTimeline(){return this.realDurationMs===void 0?uo(this.currentSighting.timeline.duration):this.canShowClockTime?uf(df(this.realStartMs+this.realDurationMs)):uo(this.realDurationMs)}}function df(s){const e=new Date(s);return{hour:e.getUTCHours(),minute:e.getUTCMinutes(),second:e.getUTCSeconds()}}function uf(s){if(s.hour===void 0)return"0:00";const e=t=>String(t).padStart(2,"0");return s.second?`${e(s.hour)}:${e(s.minute??0)}:${e(s.second)}`:`${e(s.hour)}:${e(s.minute??0)}`}function uo(s){const e=Math.round(s/1e3),t=Math.floor(e/60),n=e%60;return`${t}:${String(n).padStart(2,"0")}`}const Dh="rr0-ufo";function ql(){customElements.get(Dh)||customElements.define(Dh,zn)}const sv=`
1759
+ `,cm=Math.PI/180,El=111320;function gn(s,e,t,n){const i=El*Math.cos(t*cm),a=(s-t)*El;return{x:(e-n)*i,z:-a}}function zi(s,e,t,n){const i=El*Math.cos(t*cm),a=-e,r=s;return{lat:t+a/El,lng:n+r/i}}class Wr{constructor(e){this.points=e}static STATIONARY_M=5;static of(e){const t=[];for(const n of e.witnessTrack.allKeyframes){const{lat:i,lng:a,headingDeg:r}=n.pose;i===void 0||a===void 0||t.push({t:n.t,lat:i,lng:a,headingDeg:r})}if(t.length===0){const n=e.event.place?.[0];if(!n)return;t.push({t:0,lat:n.lat,lng:n.lng})}return new Wr(t)}get moved(){return this.spanM>Wr.STATIONARY_M}get spanM(){const e=this.box,t=(e.south+e.north)/2,n=(e.west+e.east)/2;return Math.max(Math.abs(gn(t,e.east,t,e.west).x),Math.abs(gn(e.north,n,e.south,n).z))}get center(){const e=this.box;return{lat:(e.south+e.north)/2,lng:(e.west+e.east)/2}}boundsAround(e,t){const{lat:n,lng:i}=this.center,a=Math.max(this.spanM*(1+t),e)/2;return{north:zi(0,-a,n,i).lat,south:zi(0,a,n,i).lat,east:zi(a,0,n,i).lng,west:zi(-a,0,n,i).lng}}get box(){const e=this.points.map(n=>n.lat),t=this.points.map(n=>n.lng);return{south:Math.min(...e),north:Math.max(...e),west:Math.min(...t),east:Math.max(...t)}}}class Gt{constructor(e,t){this.stretches=e,this.rotationPassed=t}static REFERENCE_SPEED_M_PER_S=1.4;static REFERENCE_STEP_HZ=1.9;static CADENCE_EXPONENT=.43;static RISE_M_PER_M_PER_S=.0175;static SWAY_M=.0175;static SLOWEST_WALK_M_PER_S=.2;static FASTEST_WALK_M_PER_S=2.2;static HEAD_ROLL_DEG=1.5;static HEAD_PITCH_DEG=1.25;static HEAD_YAW_DEG=1;static STILL=Object.freeze({eastM:0,northM:0,upM:0,rollDeg:0,pitchDeg:0,yawDeg:0});static of(e){const t=Wr.of(e);if(!t||t.points.length<2)return;const n=[];let i=0;for(let a=1;a<t.points.length;a++){const r=t.points[a-1],o=t.points[a],l=(o.t-r.t)/1e3;if(l<=0)continue;const c=gn(o.lat,o.lng,r.lat,r.lng),h=c.x,d=-c.z,u=Math.hypot(h,d),f=u/l,g=Gt.stepHzFor(f);n.push({startMs:r.t,endMs:o.t,speedMPerS:f,eastUnit:u>0?h/u:0,northUnit:u>0?d/u:0,stepHz:g,stepsBefore:i,rampsIn:!0,rampsOut:!0}),i+=g*l}for(let a=0;a<n.length;a++){const r=n[a-1],o=n[a+1];n[a].rampsIn=r===void 0||r.stepHz===0,n[a].rampsOut=o===void 0||o.stepHz===0}if(n.some(a=>a.stepHz>0))return new Gt(n,1-(e.instrument.stabilization??0))}static stepHzFor(e){return e<Gt.SLOWEST_WALK_M_PER_S||e>Gt.FASTEST_WALK_M_PER_S?0:Gt.REFERENCE_STEP_HZ*Math.pow(e/Gt.REFERENCE_SPEED_M_PER_S,Gt.CADENCE_EXPONENT)}offsetAt(e){const t=this.stretches.find(l=>e>=l.startMs&&e<=l.endMs);if(!t||t.stepHz===0)return Gt.STILL;const n=t.stepsBefore+t.stepHz*(e-t.startMs)/1e3,i=2*Math.PI*n,a=this.amplitudeAt(t,e),r=Gt.SWAY_M*a*Math.cos(i/2),o=a*this.rotationPassed*t.speedMPerS/Gt.REFERENCE_SPEED_M_PER_S;return{eastM:r*t.northUnit,northM:-r*t.eastUnit,upM:Gt.RISE_M_PER_M_PER_S*t.speedMPerS*a*Math.cos(i),rollDeg:Gt.HEAD_ROLL_DEG*o*Math.cos(i/2),pitchDeg:-1.25*o*Math.cos(i),yawDeg:Gt.HEAD_YAW_DEG*o*Math.cos(i/2)}}amplitudeAt(e,t){const n=1e3/e.stepHz,i=Math.min(n,(e.endMs-e.startMs)/2);if(i<=0)return 1;const a=t-e.startMs,r=e.endMs-t,o=Math.min(e.rampsIn?a/i:1,e.rampsOut?r/i:1,1);return(1-Math.cos(Math.PI*Math.max(o,0)))/2}}class O1{constructor(e,t){this.timeline=e,this.onFrame=t}rafId=null;state="stopped";currentT=0;lastWallTime=0;playbackRate=1;loop=!1;onEnded;durationOverrideMs=0;get seekableDuration(){return Math.max(this.timeline.duration,this.durationOverrideMs)}play(){if(this.state==="playing")return;this.currentT>=this.seekableDuration&&(this.currentT=0,this.resolveFrame(0)),this.state="playing",this.lastWallTime=performance.now();const e=()=>{if(this.state!=="playing")return;const t=performance.now();if(this.currentT+=(t-this.lastWallTime)*this.playbackRate,this.lastWallTime=t,this.currentT>=this.seekableDuration){if(this.loop&&this.seekableDuration>0){this.currentT%=this.seekableDuration,this.resolveFrame(this.currentT),this.rafId=requestAnimationFrame(e);return}this.currentT=this.seekableDuration,this.stop(),this.resolveFrame(this.currentT),this.onEnded?.();return}this.resolveFrame(this.currentT),this.rafId=requestAnimationFrame(e)};this.rafId=requestAnimationFrame(e)}pause(){this.state==="playing"&&(this.state="paused",this.rafId!==null&&(cancelAnimationFrame(this.rafId),this.rafId=null))}stop(){this.state="stopped",this.rafId!==null&&(cancelAnimationFrame(this.rafId),this.rafId=null)}seek(e){this.currentT=Math.max(0,Math.min(e,this.seekableDuration)),this.resolveFrame(this.currentT)}get playbackState(){return this.state}get time(){return this.currentT}resolveFrame(e){const t=new Map;for(const n of this.timeline.sourceIds){const i=this.timeline.getInterpolatedShapeAt(e,n);i&&t.set(n,i)}this.onFrame(e,t)}}const nf=.05,sf=.08,af=2,rf=3,k1=14,U1=.02;class F1{context;voice;voiceToken=0;buffers=new Map;noiseBuffer;crackleBuffer;requested;resume(){if(!this.context){if(typeof AudioContext>"u")return;try{this.context=new AudioContext}catch(e){console.warn("SightingAudio: Web Audio unavailable, the sighting stays silent:",e);return}}this.context.state==="suspended"&&this.context.resume()}setSound(e){if(this.requested=e,!this.context)return;const t=this.keyFor(e);if(!t){this.silence();return}if(this.voice?.key!==t){this.stopVoice();const n=++this.voiceToken;t.startsWith("src:")?this.buildRecordedVoice(e.src,t,n):this.voice=this.buildSynthesizedVoice(e,t)}this.applyTo(this.voice,e)}silence(){this.voiceToken++,this.stopVoice()}dispose(){this.silence(),this.context?.close(),this.context=void 0,this.buffers.clear(),this.noiseBuffer=void 0,this.crackleBuffer=void 0}keyFor(e){if(!(e.volume<=0))return e.src?`src:${e.src}`:e.kind==="none"?void 0:e.kind}applyTo(e,t){const n=this.context;if(!e||!n)return;const i=n.currentTime;e.volumeParam.setTargetAtTime(Math.max(0,Math.min(1,t.volume))*e.gainScale,i,nf);for(const{param:a,ratio:r}of e.pitch)a.setTargetAtTime(Math.min(t.pitchHz*r,n.sampleRate/2-1),i,nf)}buildSynthesizedVoice(e,t){const n=this.context;if(n)switch(e.kind){case"hum":return this.buildHum(n,t);case"whistle":return this.buildWhistle(n,t);case"rumble":return this.buildRumble(n,t);case"crackle":return this.buildCrackle(n,t);default:return}}buildHum(e,t){const n=e.createOscillator();n.type="sawtooth";const i=e.createOscillator();i.type="sawtooth";const a=e.createBiquadFilter();a.type="lowpass",a.Q.value=1;const r=e.createGain();return r.gain.value=0,n.connect(a),i.connect(a),a.connect(r).connect(e.destination),n.start(),i.start(),{key:t,nodes:[a,r],sources:[n,i],volumeParam:r.gain,gainScale:.16,pitch:[{param:n.frequency,ratio:1},{param:i.frequency,ratio:1.006},{param:a.frequency,ratio:6}]}}buildWhistle(e,t){const n=e.createOscillator();n.type="sine";const i=e.createOscillator();i.type="sine",i.frequency.value=5;const a=e.createGain(),r=e.createGain();return r.gain.value=0,i.connect(a).connect(n.frequency),n.connect(r).connect(e.destination),n.start(),i.start(),{key:t,nodes:[a,r],sources:[n,i],volumeParam:r.gain,gainScale:.22,pitch:[{param:n.frequency,ratio:1},{param:a.gain,ratio:.012}]}}buildRumble(e,t){const n=e.createBufferSource();n.buffer=this.brownNoise(e),n.loop=!0;const i=e.createBiquadFilter();i.type="lowpass",i.Q.value=.8;const a=e.createGain();return a.gain.value=0,n.connect(i).connect(a).connect(e.destination),n.start(),{key:t,nodes:[i,a],sources:[n],volumeParam:a.gain,gainScale:1.4,pitch:[{param:i.frequency,ratio:1}]}}buildCrackle(e,t){const n=e.createBufferSource();n.buffer=this.whiteNoise(e),n.loop=!0;const i=e.createBiquadFilter();i.type="bandpass",i.Q.value=1.2;const a=e.createGain();a.gain.value=0;const r=e.createBufferSource();r.buffer=this.crackleEnvelope(e),r.loop=!0;const o=e.createGain();return o.gain.value=0,r.connect(o).connect(a.gain),n.connect(i).connect(a).connect(e.destination),n.start(),r.start(),{key:t,nodes:[i,a,o],sources:[n,r],volumeParam:o.gain,gainScale:.9,pitch:[{param:i.frequency,ratio:4}]}}async buildRecordedVoice(e,t,n){const i=this.context;if(!i)return;let a;try{a=await this.getBuffer(e)}catch(l){console.warn("SightingAudio: the recorded sound failed to load, staying silent:",l);return}if(n!==this.voiceToken||!this.context)return;const r=i.createBufferSource();r.buffer=a,r.loop=!0;const o=i.createGain();o.gain.value=0,r.connect(o).connect(i.destination),r.start(),this.voice={key:t,nodes:[o],sources:[r],volumeParam:o.gain,gainScale:1,pitch:[]},this.requested&&this.applyTo(this.voice,this.requested)}async getBuffer(e){const t=this.context;if(!t)throw new Error("SightingAudio: AudioContext not ready — resume() must be called first");let n=this.buffers.get(e);return n||(n=fetch(e).then(i=>{if(!i.ok)throw new Error(`Audio fetch failed (${i.status}): ${e}`);return i.arrayBuffer()}).then(i=>t.decodeAudioData(i)),this.buffers.set(e,n)),n}whiteNoise(e){if(!this.noiseBuffer){const t=e.createBuffer(1,Math.floor(e.sampleRate*af),e.sampleRate),n=t.getChannelData(0);for(let i=0;i<n.length;i++)n[i]=Math.random()*2-1;this.noiseBuffer=t}return this.noiseBuffer}brownNoise(e){const t=e.createBuffer(1,Math.floor(e.sampleRate*af),e.sampleRate),n=t.getChannelData(0);let i=0,a=0;for(let r=0;r<n.length;r++)i=(i+.02*(Math.random()*2-1))/1.02,n[r]=i,a=Math.max(a,Math.abs(i));if(a>0)for(let r=0;r<n.length;r++)n[r]/=a;return t}crackleEnvelope(e){if(!this.crackleBuffer){const t=e.createBuffer(1,Math.floor(e.sampleRate*rf),e.sampleRate),n=t.getChannelData(0),i=Math.max(1,Math.floor(U1*e.sampleRate)),a=Math.round(rf*k1);for(let r=0;r<a;r++){const o=Math.floor(Math.random()*n.length),l=.4+Math.random()*.6;for(let c=0;c<i&&o+c<n.length;c++)n[o+c]=Math.max(n[o+c],l*(1-c/i))}this.crackleBuffer=t}return this.crackleBuffer}stopVoice(){const e=this.voice,t=this.context;if(this.voice=void 0,!e||!t)return;const n=t.currentTime;e.volumeParam.cancelScheduledValues(n),e.volumeParam.setTargetAtTime(0,n,sf/3);const i=n+sf;for(const a of e.sources){a.onended=()=>{a.disconnect();for(const r of e.nodes)r.disconnect()};try{a.stop(i)}catch{a.disconnect();for(const r of e.nodes)r.disconnect()}}}}function $a(s){return[...s].sort((e,t)=>e.t-t.t)}function of(s,e){let t;for(const n of $a(s)){if(n.t>e)break;t=n}return t}const ac=Math.PI/180,ho=180/Math.PI;class Qn{constructor(e,t,n){this.kind=e,this.canvasHeightPx=t,this.fovDeg=n;const i=n*ac/2;this.focalPx=e==="equidistant"?t/2/i:t/2/Math.tan(i)}focalPx;static of(e,t,n){return new Qn(e.projection,t,n)}degToPx(e){const t=e*ac;return this.kind==="equidistant"?this.focalPx*t:2*this.focalPx*Math.tan(t/2)}pxToDeg(e){return this.kind==="equidistant"?e/this.focalPx*ho:2*Math.atan(e/(2*this.focalPx))*ho}angleDegToRadiusPx(e){const t=e*ac;return this.kind==="equidistant"?this.focalPx*t:this.focalPx*Math.tan(t)}halfWidthAngleDeg(e){return this.radiusPxToAngleDeg(this.canvasHeightPx*e/2)}radiusPxToAngleDeg(e){return this.kind==="equidistant"?e/this.focalPx*ho:Math.atan(e/this.focalPx)*ho}ofBounds(e){return{widthDeg:this.pxToDeg(e.width),heightDeg:this.pxToDeg(e.height)}}toBoundsSize(e){return{width:this.degToPx(e.widthDeg),height:this.degToPx(e.heightDeg)}}widthPx(e){return this.degToPx(et.angularWidthDeg(e))}}class en{static fovOf(e,t){return bt(e,t)?.fovDeg??st.fieldOfViewDeg(e.instrument)}static toAngular(e){this.eachKeyframe(e,(t,n)=>({...t,angular:n.ofBounds(t.bounds)}))}static toBounds(e){this.eachKeyframe(e,(t,n)=>{if(!t.angular)return t;const{width:i,height:a}=n.toBoundsSize(t.angular),r={x:t.bounds.x+(t.bounds.width-i)/2,y:t.bounds.y+(t.bounds.height-a)/2,width:i,height:a};if(t.kind!=="polygon")return{...t,bounds:r};const o=t.bounds.width===0?1:i/t.bounds.width,l=t.bounds.height===0?1:a/t.bounds.height;return{...t,bounds:r,points:t.points.map(c=>({x:c.x*o,y:c.y*l}))}})}static toAim(e){this.eachKeyframe(e,(t,n,i)=>{const a=this.aimFrom(e,n,i,t.bounds);return a?{...t,aim:a}:t})}static aimOf(e,t,n){const i=Qn.of(e.instrument,et.CANVAS_HEIGHT_PX,this.fovOf(e,t));return this.aimFrom(e,i,bt(e,t),n)}static aimFrom(e,t,n,i){if(n?.headingDeg===void 0)return;const a=this.frameCentre(e),r=t.radiusPxToAngleDeg(i.x+i.width/2-a.x),o=t.radiusPxToAngleDeg(a.y-(i.y+i.height/2));return{azimuthDeg:((n.headingDeg+r)%360+360)%360,altitudeDeg:n.pitchDeg+o}}static toPosition(e){this.eachKeyframe(e,(t,n,i)=>{if(!t.aim||i?.headingDeg===void 0)return t;const a=this.frameCentre(e),r=this.shortestArc(t.aim.azimuthDeg-i.headingDeg),o=t.aim.altitudeDeg-i.pitchDeg,l=a.x+this.offAxisPx(n,r)-t.bounds.width/2,c=a.y-this.offAxisPx(n,o)-t.bounds.height/2;return{...t,bounds:{...t.bounds,x:l,y:c}}})}static frameCentre(e){return{x:st.frameWidthPx(e.instrument,et.CANVAS_HEIGHT_PX)/2,y:et.CANVAS_HEIGHT_PX/2}}static shortestArc(e){return(e%360+540)%360-180}static offAxisPx(e,t){return Math.abs(t)>=en.OFF_CANVAS_DEG?Math.sign(t)*en.OFF_CANVAS_PX:e.angleDegToRadiusPx(t)}static OFF_CANVAS_DEG=89;static OFF_CANVAS_PX=1e5;static reproject(e,t,n){const i=st.frameWidthPx(t,et.CANVAS_HEIGHT_PX)/2,a=st.frameWidthPx(e.instrument,et.CANVAS_HEIGHT_PX)/2,r=et.CANVAS_HEIGHT_PX/2;for(const o of[...e.timeline.allKeyframes]){const l=this.fovOf(e,o.t),c=n?.get(o.t)??l,h=Qn.of(t,et.CANVAS_HEIGHT_PX,c),d=Qn.of(e.instrument,et.CANVAS_HEIGHT_PX,l);e.timeline.addKeyframe(o.t,o.shapes.map(u=>{const{bounds:f}=u.shape,g=f.x+f.width/2-i,v=f.y+f.height/2-r,p=Math.hypot(g,v),m=p===0?1:d.angleDegToRadiusPx(h.radiusPxToAngleDeg(p))/p,S={...f,x:a+g*m-f.width/2,y:r+v*m-f.height/2};return{...u,shape:{...u.shape,bounds:S}}}))}this.toBounds(e)}static eachKeyframe(e,t){const{timeline:n}=e;for(const i of[...n.allKeyframes]){const a=bt(e,i.t),r=this.fovOf(e,i.t),o=Qn.of(e.instrument,et.CANVAS_HEIGHT_PX,r);n.addKeyframe(i.t,i.shapes.map(l=>({...l,shape:t(l.shape,o,a)})))}}}function B1(s){return Pn.restore(Ih(s),s.provenance)}function Ih(s){return en.toAngular(s),en.toAim(s),{version:1,time:s.event.time,endTime:s.event.endTime,durationSeconds:s.event.durationSeconds,utcOffsetHours:s.event.utcOffsetHours,timeZone:s.event.timeZone,place:s.event.place,witness:s.witness,testimony:s.testimony,caseId:s.caseId,description:s.event.description,tags:s.event.tags,timeline:s.timeline.toJSON(),witnessTrack:s.witnessTrack.toJSON(),weatherTrack:s.weatherTrack.toJSON(),soundTrack:s.soundTrack.toJSON(),weather:s.weather,decor:s.decor,milestones:s.milestones.length>0?s.milestones:void 0,weatherSource:s.weatherSource,instrument:s.instrumentId,exposureSeconds:s.exposureSeconds}}function z1(s){const{recording:e,provenance:t}=Pn.strip(s),n=H1(e);return n.provenance=t,n}function H1(s){const e=new Xl({eventType:"sighting",time:s.time,endTime:s.endTime,durationSeconds:s.durationSeconds,utcOffsetHours:s.utcOffsetHours,timeZone:s.timeZone,place:s.place,description:s.description,tags:s.tags},Wl.fromJSON(s.timeline),s.witnessTrack?Hr.fromJSON(s.witnessTrack):new Hr,s.weatherTrack?Gr.fromJSON(s.weatherTrack):new Gr,s.soundTrack?Vr.fromJSON(s.soundTrack):new Vr,s.witness,s.caseId,s.weather,s.decor??[],s.weatherSource,s.instrument,s.exposureSeconds??s.witnessTrack?.keyframes.map(t=>t.pose.exposureSeconds).find(t=>t!==void 0),$a(s.milestones??[]));return e.testimony=s.testimony,en.toBounds(e),en.toPosition(e),e}function Xr(s,e){for(const t of s){const n=t.toLowerCase().split("-")[0];if(e.includes(n))return n}return"en"}class Vs{static preferencesFor(e){const t=navigator.languages??[],n=this.declaredFor(e);return n?[n,...t]:t}static declaredFor(e){for(let t=e;t;){const n=t.closest("[lang]")?.getAttribute("lang")?.trim();if(n)return n;const i=t.getRootNode();t=i instanceof ShadowRoot?i.host:void 0}}}class Fi{constructor(e){this.preferences=e}read(e){if(e===void 0||typeof e=="string")return e===""?void 0:e;for(const n of this.preferences){const i=e[n]??e[Fi.base(n)];if(i)return i}const t=new Set(this.preferences.map(n=>Fi.base(n)));for(const[n,i]of Object.entries(e))if(i&&t.has(Fi.base(n)))return i;return Object.values(e).find(n=>n)??void 0}write(e,t,n){const i=t?.trim()?t.trim():void 0;if(e===void 0||typeof e=="string")return i;const a={...e},r=Object.keys(a).find(o=>o===n)??Object.keys(a).find(o=>Fi.base(o)===Fi.base(n))??n;return i===void 0?delete a[r]:a[r]=i,Object.keys(a).length===0?void 0:a}static base(e){return e.toLowerCase().split("-")[0]}}const hm=["en","fr"],G1={en:()=>ei(()=>Promise.resolve().then(()=>Y1),void 0,import.meta.url).then(s=>s.ufoMessages_en),fr:()=>ei(()=>import("./UfoMessages_fr-BJPYHN17.js"),[],import.meta.url).then(s=>s.ufoMessages_fr)};function V1(s){return G1[s]()}const W1={en:()=>ei(()=>Promise.resolve().then(()=>NT),void 0,import.meta.url).then(s=>s.sightingEditorMessages_en),fr:()=>ei(()=>import("./SightingEditorMessages_fr-DnwHxbSq.js"),[],import.meta.url).then(s=>s.sightingEditorMessages_fr)};function X1(s){return W1[s]()}function q1(s){return s==="fr"?ei(()=>import("./TagNames_fr-Dnqq6HQ5.js"),[],import.meta.url).then(e=>e.tagNames_fr):Promise.resolve({})}const dm={play:"Play",pause:"Pause",noDuration:"No observation duration",autoReplay:"Auto-replay",currentPosition:"Current position",duration:"Duration",switchToElapsed:"click to show elapsed time",switchToClockTime:"click to show the time of day",fullscreen:"Fullscreen",exitFullscreen:"Exit fullscreen",showWitnessMap:"Show where the witness was",hideWitnessMap:"Hide where the witness was",mapImageryUnavailable:"Aerial imagery unavailable",showMilestones:"Show the account's moments",hideMilestones:"Hide the account's moments",witnessHere:"The witness, here",decorHere:"Scenery"},Y1=Object.freeze(Object.defineProperty({__proto__:null,ufoMessages_en:dm},Symbol.toStringTag,{value:"Module"})),um=Math.PI/180,K1=180/Math.PI,$1=256,Z1=19;function J1(s,e){return 156543.03392*Math.cos(s*um)/2**e}function j1(s,e){return J1(s,e)*$1}function fm(s,e){let t=0;for(;t<Z1&&j1(s,t+1)>=e;)t++;return t}function hl(s){const e=s*um;return(1-Math.log(Math.tan(e)+1/Math.cos(e))/Math.PI)/2}function pm(s,e,t){const n=2**t;return{x:(s+180)/360*n,y:hl(e)*n}}function mm(s,e,t){const n=hl(s.north),i=hl(s.south);return{x:(e-s.west)/(s.east-s.west),y:(hl(t)-n)/(i-n)}}function Q1(s,e,t){const{x:n,y:i}=pm(s,e,t);return{x:Math.floor(n),y:Math.floor(i),z:t}}function ev(s){const e=2**s.z,t=s.x/e*360-180,n=(s.x+1)/e*360-180,i=lf(s.y,e);return{south:lf(s.y+1,e),north:i,west:t,east:n}}function lf(s,e){const t=s/e;return Math.atan(Math.sinh(Math.PI*(1-2*t)))*K1}function gm(s,e,t,n){const i=Q1(s,e,t),a=Math.floor(n/2),r=[];for(let c=-a;c<=a;c++)for(let h=-a;h<=a;h++)r.push({x:i.x+h,y:i.y+c,z:t});const o=r.map(ev),l={south:Math.min(...o.map(c=>c.south)),north:Math.max(...o.map(c=>c.north)),west:Math.min(...o.map(c=>c.west)),east:Math.max(...o.map(c=>c.east))};return{tiles:r,bounds:l}}class Ls{constructor(e){this.ctx=e}static SCALE_STEPS_M=[5e3,2e3,1e3,500,200,100,50,20,10,5];static MARKER_RADIUS_PX=8.5;static ON_MARKER_M=3;targets=[];hitTest(e,t){let n,i=1/0;for(const a of this.targets){const r=Math.hypot(a.x-e,a.y-t);r>a.radius||r>i||(n=a,i=r)}return n}get width(){return this.ctx.canvas.width}get height(){return this.ctx.canvas.height}paint(e){const{ctx:t}=this;t.save(),this.targets=[],t.clearRect(0,0,this.width,this.height),this.paintGround(e),this.paintNight(e.nightFraction),this.paintPath(e),e.position?(this.paintCone(e,e.position),this.paintDecor(e),this.paintMarkers(e),this.paintWitness(e,e.position)):(this.paintDecor(e),this.paintMarkers(e)),this.paintNorth(),this.paintFooter(e.bounds,e.attribution),t.restore()}toCanvas(e,t,n){const i=mm(e,n,t);return{x:i.x*this.width,y:i.y*this.height}}paintGround(e){const{ctx:t}=this;t.fillStyle="#1d2321",t.fillRect(0,0,this.width,this.height);const n=e.imagery;if(!n)return;const i=this.toCanvas(e.bounds,n.bounds.north,n.bounds.west),a=this.toCanvas(e.bounds,n.bounds.south,n.bounds.east);t.drawImage(n.source,i.x,i.y,a.x-i.x,a.y-i.y)}paintNight(e=0){if(e<=0)return;const{ctx:t}=this;t.save(),t.fillStyle=`rgba(6, 12, 30, ${Math.min(e,1)*.78})`,t.fillRect(0,0,this.width,this.height),t.restore()}paintDecor(e){const{ctx:t}=this;for(const n of e.decor){const i=this.toCanvas(e.bounds,n.lat,n.lng);if(n.label&&this.targets.push({kind:"decor",label:n.label,lat:n.lat,lng:n.lng,x:i.x,y:i.y,radius:7}),t.beginPath(),t.rect(i.x-3.5,i.y-3.5,7,7),t.fillStyle="rgba(120, 220, 255, 0.85)",t.fill(),t.lineWidth=1.5,t.strokeStyle="rgba(0, 0, 0, 0.7)",t.stroke(),n.headingDeg===void 0)continue;const a=(n.headingDeg-90)*Math.PI/180;t.beginPath(),t.moveTo(i.x,i.y),t.lineTo(i.x+Math.cos(a)*10,i.y+Math.sin(a)*10),t.lineWidth=3,t.strokeStyle="rgba(0, 0, 0, 0.6)",t.stroke(),t.lineWidth=1.5,t.strokeStyle="rgba(120, 220, 255, 0.9)",t.stroke()}}paintPath(e){if(!e.path.moved)return;const{ctx:t}=this,n=e.path.points.map(i=>this.toCanvas(e.bounds,i.lat,i.lng));t.beginPath(),t.moveTo(n[0].x,n[0].y);for(const i of n.slice(1))t.lineTo(i.x,i.y);t.lineJoin="round",t.lineCap="round",t.strokeStyle="rgba(0, 0, 0, 0.65)",t.lineWidth=5,t.stroke(),t.strokeStyle="rgba(255, 255, 255, 0.9)",t.lineWidth=2,t.stroke()}paintCone(e,t){const{headingDeg:n,coneHalfAngleDeg:i}=e;if(n===void 0||i===void 0)return;const{ctx:a}=this,r=this.toCanvas(e.bounds,t.lat,t.lng),o=Math.hypot(this.width,this.height),l=(n-90)*Math.PI/180,c=i*Math.PI/180;a.save(),a.beginPath(),a.moveTo(r.x,r.y),a.arc(r.x,r.y,o,l-c,l+c),a.closePath();const h=a.createRadialGradient(r.x,r.y,0,r.x,r.y,o);h.addColorStop(0,"rgba(255, 224, 130, 0.55)"),h.addColorStop(.35,"rgba(255, 224, 130, 0.22)"),h.addColorStop(1,"rgba(255, 224, 130, 0)"),a.fillStyle=h,a.fill(),a.restore()}paintMarkers(e){const{ctx:t}=this;t.textAlign="center",t.textBaseline="middle",t.font="bold 10px sans-serif";for(const n of[...e.markers].sort((i,a)=>Number(i.current)-Number(a.current))){const i=this.toCanvas(e.bounds,n.lat,n.lng);this.targets.push({kind:"milestone",label:n.note?`${n.label} — ${n.note}`:n.label,lat:n.lat,lng:n.lng,t:n.t,x:i.x,y:i.y,radius:Ls.MARKER_RADIUS_PX}),t.beginPath(),t.arc(i.x,i.y,Ls.MARKER_RADIUS_PX,0,Math.PI*2),t.fillStyle=n.current?"rgba(255, 224, 130, 0.95)":"rgba(0, 0, 0, 0.55)",t.fill(),t.lineWidth=2,t.strokeStyle="rgba(255, 255, 255, 0.9)",t.stroke(),t.fillStyle=n.current?"#1d2321":"#fff",t.fillText(n.label,i.x,i.y)}}paintWitness(e,t){const{ctx:n}=this,i=this.toCanvas(e.bounds,t.lat,t.lng);e.witnessLabel&&this.targets.push({kind:"witness",label:e.witnessLabel,lat:t.lat,lng:t.lng,x:i.x,y:i.y,radius:8});const a=e.markers.some(r=>{if(!r.current)return!1;const o=gn(r.lat,r.lng,t.lat,t.lng);return Math.hypot(o.x,o.z)<=Ls.ON_MARKER_M});n.beginPath(),n.arc(i.x,i.y,a?Ls.MARKER_RADIUS_PX+2.5:5.5,0,Math.PI*2),a||(n.fillStyle="#ff5a3c",n.fill()),n.lineWidth=4,n.strokeStyle="rgba(0, 0, 0, 0.5)",n.stroke(),n.lineWidth=a?3:2.5,n.strokeStyle=a?"#ff5a3c":"#fff",n.stroke()}paintNorth(){const{ctx:e}=this,t=this.width-14,n=16;e.beginPath(),e.moveTo(t,n-9),e.lineTo(t-4.5,n+5),e.lineTo(t,n+2),e.lineTo(t+4.5,n+5),e.closePath(),e.fillStyle="rgba(255, 255, 255, 0.92)",e.strokeStyle="rgba(0, 0, 0, 0.6)",e.lineWidth=1,e.fill(),e.stroke(),e.font="bold 9px sans-serif",e.textAlign="center",e.textBaseline="top",e.strokeText("N",t,n+6),e.fillText("N",t,n+6)}paintFooter(e,t){const{ctx:n}=this;n.font="9px sans-serif",n.textBaseline="bottom";const i=t?this.wrap(t,this.width-20):[];let a=this.height-4;n.textAlign="right";for(const f of i.slice().reverse())this.paintOutlinedText(f,this.width-6,a),a-=11;const r=(e.south+e.north)/2,l=Math.abs(gn(r,e.east,r,e.west).x)/this.width,c=Ls.SCALE_STEPS_M.find(f=>f/l<=this.width/3);if(c===void 0)return;const h=c/l,d=8,u=a-3;n.lineWidth=3,n.strokeStyle="rgba(0, 0, 0, 0.6)",n.beginPath(),n.moveTo(d,u),n.lineTo(d+h,u),n.stroke(),n.lineWidth=1.5,n.strokeStyle="rgba(255, 255, 255, 0.95)",n.stroke(),n.textAlign="left",this.paintOutlinedText(c>=1e3?`${c/1e3} km`:`${c} m`,d,u-3)}paintOutlinedText(e,t,n){const{ctx:i}=this;i.lineWidth=3,i.strokeStyle="rgba(0, 0, 0, 0.75)",i.strokeText(e,t,n),i.fillStyle="#fff",i.fillText(e,t,n)}wrap(e,t){const n=[];let i="";for(const a of e.split(" ")){const r=i?`${i} ${a}`:a;i&&this.ctx.measureText(r).width>t?(n.push(i),i=a):i=r}return i&&n.push(i),n}}const Fn=256,cf=3,tv=32768;class vm{fetchImpl;tileUrlTemplate;constructor(e={}){this.fetchImpl=e.fetchImpl??fetch.bind(globalThis),this.tileUrlTemplate=e.tileUrlTemplate??"https://s3.amazonaws.com/elevation-tiles-prod/terrarium/{z}/{x}/{y}.png"}async getElevationGrid(e,t){const n=(e.south+e.north)/2,i=(e.west+e.east)/2,a=Math.abs(gn(n,e.east,n,e.west).x),r=Math.abs(gn(e.north,i,e.south,i).z),o=fm(n,Math.max(a,r)),{tiles:l}=gm(i,n,o,cf),c=cf*Fn,h=new Float32Array(c*c),d=l[0];await Promise.all(l.map(f=>this.decodeTileInto(f,d,h,c)));const u=new Float32Array(t.width*t.height);for(let f=0;f<t.height;f++){const g=e.north+(e.south-e.north)*(f/(t.height-1));for(let v=0;v<t.width;v++){const p=e.west+(e.east-e.west)*(v/(t.width-1));u[f*t.width+v]=this.sampleAt(g,p,o,d,h,c)}}return{heights:u,width:t.width,height:t.height,bounds:e}}async decodeTileInto(e,t,n,i){const a=this.tileUrlTemplate.replace("{z}",String(e.z)).replace("{x}",String(e.x)).replace("{y}",String(e.y)),r=await this.fetchImpl(a);if(!r.ok)throw new Error(`Elevation tile fetch failed (${r.status}): ${a}`);const o=await createImageBitmap(await r.blob()),l=document.createElement("canvas");l.width=Fn,l.height=Fn;const c=l.getContext("2d");if(!c)throw new Error("2D canvas context unavailable");c.drawImage(o,0,0);const{data:h}=c.getImageData(0,0,Fn,Fn),d=(e.x-t.x)*Fn,u=(e.y-t.y)*Fn;for(let f=0;f<Fn;f++)for(let g=0;g<Fn;g++){const v=(f*Fn+g)*4,p=h[v]*256+h[v+1]+h[v+2]/256-tv,m=d+g,S=u+f;n[S*i+m]=p}}sampleAt(e,t,n,i,a,r){const{x:o,y:l}=pm(t,e,n),c=(o-i.x)*Fn,h=(l-i.y)*Fn,d=Math.max(0,Math.min(r-1,Math.floor(c))),u=Math.max(0,Math.min(r-1,Math.floor(h))),f=Math.min(r-1,d+1),g=Math.min(r-1,u+1),v=c-d,p=h-u,m=a[u*r+d],S=a[u*r+f],_=a[g*r+d],x=a[g*r+f],M=m+(S-m)*v,E=_+(x-_)*v;return M+(E-M)*p}}const rc=256,hf=3;async function ym(s,e,t,n){const i=(s.south+s.north)/2,a=(s.west+s.east)/2,r=Math.abs(gn(i,s.east,i,s.west).x),o=Math.abs(gn(s.north,a,s.south,a).z),l=fm(i,Math.max(r,o)/2),{tiles:c,bounds:h}=gm(a,i,l,hf),d=hf*rc,u=document.createElement("canvas");u.width=d,u.height=d;const f=u.getContext("2d");if(!f)throw new Error("2D canvas context unavailable");const g=c[0];await Promise.all(c.map(async m=>{const S=t(m),_=await n(S);if(!_.ok)throw new Error(`Imagery tile fetch failed (${_.status}): ${S}`);const x=await createImageBitmap(await _.blob());f.drawImage(x,(m.x-g.x)*rc,(m.y-g.y)*rc)}));const v=document.createElement("canvas");v.width=e.width,v.height=e.height;const p=v.getContext("2d");if(!p)throw new Error("2D canvas context unavailable");return p.drawImage(u,0,0,d,d,0,0,e.width,e.height),{source:v,width:e.width,height:e.height,bounds:h}}class bm{attribution="Imagery © Esri, Maxar, Earthstar Geographics, and the GIS User Community";fetchImpl;tileUrlTemplate;constructor(e={}){this.fetchImpl=e.fetchImpl??fetch.bind(globalThis),this.tileUrlTemplate=e.tileUrlTemplate??"https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}"}async getImageryTexture(e,t){return ym(e,t,n=>this.tileUrlTemplate.replace("{z}",String(n.z)).replace("{y}",String(n.y)).replace("{x}",String(n.x)),this.fetchImpl)}}function nv(){return{elevation:new vm,imagery:xm()}}function xm(){return new bm}const iv=new Set,Ws="show-witness-map",ka="hide-milestones";class zn extends HTMLElement{static get observedAttributes(){return["src",Ws,ka]}shadow;stageElement;canvas;canvasRenderer;tooltip;toolbar;playPauseButton;loopButton;static WITNESS_MAP_MIN_SPAN_M=400;static WITNESS_MAP_MARGIN=.6;static WITNESS_MAP_IMAGERY_PX=768;fullscreenButton;cornerButtons;witnessMapButton;milestonesButton;witnessMapPanel;witnessMapCanvas;witnessMapRenderer;seekInput;milestoneMarks;milestoneCaption;timeStartLabel;timeEndLabel;witnessPath;witnessMapBounds;witnessMapImagery;witnessMapImageryRequested=!1;witnessMapImageryCredit;witnessMapImageryFailed=!1;creditShownExternally=!1;lookYawDeg=0;lookPitchDeg=0;milestonesShown=!0;currentSighting=Xl.create();sightingAudio=new F1;soundPreview;player;loopEnabled=!0;playbackBeforeClick;highlightedSourceIds=new Set;paintsShapes=!0;enableClickToPlay=!0;fullscreenTarget;messages=dm;realDurationMs;realStartMs;showClockTime=!0;handleFullscreenChange=()=>{this.updateFullscreenButton(),this.resizeWitnessMap()};witnessMapResizeObserver=typeof ResizeObserver>"u"?void 0:new ResizeObserver(()=>this.resizeWitnessMap());resizeWitnessMap(){this.witnessMapPanel.hidden||(this.sizeWitnessMapCanvas(),this.paintWitnessMap(this.currentTime))}simulatedFullscreen=!1;styleBeforeSimulatedFullscreen;bodyOverflowBeforeSimulatedFullscreen;handleSimulatedFullscreenKey=e=>{e.key==="Escape"&&this.exitSimulatedFullscreen()};handlePointerMove=e=>{const t=this.canvasPointFromEvent(e),n=t&&this.shapeAt(t.x,t.y),i=this.said.read(n?.shape.title);if(!i){this.tooltip.hidden=!0;return}this.tooltip.textContent=i,this.tooltip.hidden=!1;const a=this.stageElement.getBoundingClientRect();this.tooltip.style.left=`${e.clientX-a.left+12}px`,this.tooltip.style.top=`${e.clientY-a.top+12}px`};handleWitnessMapPointerMove=e=>{const t=this.witnessMapTargetFrom(e);if(!t){this.tooltip.hidden=!0,this.witnessMapCanvas.style.cursor="default";return}this.witnessMapCanvas.style.cursor="pointer",this.tooltip.textContent=t.label,this.tooltip.hidden=!1;const n=this.stageElement.getBoundingClientRect();this.tooltip.style.left=`${e.clientX-n.left+12}px`,this.tooltip.style.top=`${e.clientY-n.top+12}px`};handleWitnessMapClick=e=>{const t=this.witnessMapTargetFrom(e);if(t){if(t.kind==="milestone"&&t.t!==void 0){this.player.seek(t.t);return}this.dispatchEvent(new CustomEvent("lookat",{detail:{lat:t.lat,lng:t.lng,kind:t.kind},bubbles:!0,composed:!0}))}};witnessMapTargetFrom(e){const t=this.witnessMapCanvas.getBoundingClientRect();if(!(t.width===0||t.height===0))return this.witnessMapRenderer.hitTest((e.clientX-t.left)/t.width*this.witnessMapCanvas.width,(e.clientY-t.top)/t.height*this.witnessMapCanvas.height)}handlePointerLeave=()=>{this.tooltip.hidden=!0};constructor(){super(),this.shadow=this.attachShadow({mode:"open"});const e=document.createElement("template");e.innerHTML=`<style>${N1}</style>${L1}`,this.shadow.appendChild(e.content.cloneNode(!0)),this.stageElement=this.shadow.getElementById("stage"),this.canvas=this.shadow.getElementById("canvas"),this.canvasRenderer=new wh(this.canvas.getContext("2d")),this.tooltip=this.shadow.getElementById("tooltip"),this.toolbar=this.shadow.getElementById("toolbar"),this.playPauseButton=this.shadow.getElementById("play-pause"),this.loopButton=this.shadow.getElementById("loop"),this.fullscreenButton=this.shadow.getElementById("fullscreen"),this.cornerButtons=this.shadow.getElementById("corner-buttons"),this.witnessMapButton=this.shadow.getElementById("witness-map"),this.milestonesButton=this.shadow.getElementById("milestones"),this.witnessMapPanel=this.shadow.getElementById("witness-map-panel"),this.witnessMapCanvas=this.shadow.getElementById("witness-map-canvas"),this.witnessMapRenderer=new Ls(this.witnessMapCanvas.getContext("2d")),this.seekInput=this.shadow.getElementById("seek"),this.milestoneMarks=this.shadow.getElementById("milestone-marks"),this.milestoneCaption=this.shadow.getElementById("milestone-caption"),this.timeStartLabel=this.shadow.getElementById("time-start"),this.timeEndLabel=this.shadow.getElementById("time-end");for(const t of[this.timeStartLabel,this.timeEndLabel])t.addEventListener("click",()=>this.toggleTimeDisplay()),t.addEventListener("keydown",n=>{n.key!=="Enter"&&n.key!==" "||(n.preventDefault(),this.toggleTimeDisplay())});this.fullscreenTarget=this.stageElement,this.playPauseButton.addEventListener("click",()=>this.togglePlayPause()),this.loopButton.addEventListener("click",()=>this.toggleLoop()),this.fullscreenButton.addEventListener("click",()=>this.toggleFullscreen()),this.witnessMapButton.addEventListener("click",()=>this.toggleWitnessMap()),this.milestonesButton.addEventListener("click",()=>this.toggleMilestones()),this.witnessMapCanvas.addEventListener("pointermove",this.handleWitnessMapPointerMove),this.witnessMapCanvas.addEventListener("pointerleave",this.handlePointerLeave),this.witnessMapCanvas.addEventListener("click",this.handleWitnessMapClick),this.seekInput.addEventListener("input",()=>this.player.seek(Number(this.seekInput.value))),this.canvas.addEventListener("click",t=>{this.enableClickToPlay&&(t.detail<=1&&(this.playbackBeforeClick={state:this.playbackState,time:this.currentTime}),this.togglePlayPause())}),this.canvas.addEventListener("dblclick",t=>{this.enableClickToPlay&&(t.preventDefault(),this.restorePlayback(),this.toggleFullscreen())}),this.canvas.addEventListener("pointermove",this.handlePointerMove),this.canvas.addEventListener("pointerleave",this.handlePointerLeave),document.addEventListener("fullscreenchange",this.handleFullscreenChange),this.witnessMapResizeObserver?.observe(this.witnessMapPanel),this.player=this.createPlayer(),this.updateTimeLabels(),this.updatePlayPauseButton(),this.updateFullscreenButton(),this.updateWitnessMapButton(),this.updateMilestonesButton(),this.refresh(),this.loadLocaleMessages()}connectedCallback(){this.saidTexts=void 0;const e=this.getAttribute("src");e&&this.loadFromSrc(e)}disconnectedCallback(){document.removeEventListener("fullscreenchange",this.handleFullscreenChange),this.witnessMapResizeObserver?.disconnect(),this.exitSimulatedFullscreen(),this.sightingAudio.dispose()}attributeChangedCallback(e,t,n){e==="src"&&n&&n!==t&&this.isConnected&&this.loadFromSrc(n),e===Ws&&this.applyWitnessMapDefault(),e===ka&&this.setMilestonesShown(!this.hasAttribute(ka))}async loadFromSrc(e){this.sightingData=await Kd.json(e)}get sightingData(){return B1(this.currentSighting)}set sightingData(e){this.player.stop(),this.soundPreview=void 0,this.sightingAudio.silence(),this.currentSighting=z1(e),this.player=this.createPlayer(),this.updateTimeLabels(),this.updatePlayPauseButton(),this.refresh(),this.applyWitnessMapDefault()}get sighting(){return this.currentSighting}previewSound(e){this.soundPreview=e,this.sightingAudio.resume(),this.sightingAudio.setSound(e)}stopSoundPreview(){this.soundPreview=void 0,this.sightingAudio.silence()}get canvasElement(){return this.canvas}get renderer(){return this.canvasRenderer}get currentTime(){return this.player.time}set currentTime(e){this.player.seek(e)}get seekableDuration(){return this.player.seekableDuration}get autoReplayEnabled(){return this.loopEnabled}set autoReplayEnabled(e){e!==this.loopEnabled&&this.toggleLoop()}play(){this.player.seekableDuration<=0||this.playbackState==="playing"||this.togglePlayPause()}pause(){this.playbackState==="playing"&&this.togglePlayPause()}get positionLabel(){return this.timeStartLabel.textContent??""}get durationLabel(){return this.timeEndLabel.textContent??""}get showingClockTime(){return this.canShowClockTime}get canSwitchTimeDisplay(){return this.realStartMs!==void 0}toggleTimeDisplay(){this.canSwitchTimeDisplay&&(this.showClockTime=!this.showClockTime,this.updateTimeLabels(),this.updateTimeLabelTitles(),this.dispatchEvent(new CustomEvent("timedisplaychange",{bubbles:!0,composed:!0})))}get canShowClockTime(){return this.realStartMs!==void 0&&this.showClockTime}set showToolbar(e){this.toolbar.classList.toggle("hidden",!e)}get playbackState(){return this.player.playbackState}get selectedSourceIds(){return this.highlightedSourceIds}get durationSeconds(){return this.currentSighting.event.durationSeconds}set durationSeconds(e){this.currentSighting.event.durationSeconds=e,this.updateTimeLabels(),this.refresh(),this.updatePlayPauseButton()}set selectedSourceIds(e){const t=new Set(e);t.size===this.highlightedSourceIds.size&&[...t].every(i=>this.highlightedSourceIds.has(i))||(this.highlightedSourceIds=t,this.refresh())}hasVisibleShapeAt(e,t){return this.shapeAt(e,t)!==void 0}refresh(){this.applyFrameFormat(),this.updateTimeLabels(),this.seekInput.max=String(this.player.seekableDuration),this.refreshMilestoneMarks(),this.updateMilestonesButton(),this.updateWitnessMap(),this.player.seek(this.player.time)}refreshMilestoneMarks(){const e=this.player.seekableDuration,t=e>0?$a(this.sighting.milestones):[];this.milestoneMarks.replaceChildren(...t.map(n=>{const i=document.createElement("button");i.type="button",i.className="milestone-mark",i.style.left=`${Math.min(Math.max(n.t/e,0),1)*100}%`;const a=this.said.read(n.label)??"",r=this.said.read(n.note),o=r?`${a} — ${r}`:a;return i.title=o,i.setAttribute("aria-label",o),i.addEventListener("click",()=>this.player.seek(n.t)),i}))}showMilestoneAt(e){const t=this.milestonesShown&&this.sighting.milestones.length>0?of(this.sighting.milestones,e):void 0;if(this.milestoneCaption.hidden=t===void 0,!t)return;const n=document.createElement("b");n.textContent=this.said.read(t.label)??"";const i=this.said.read(t.note),a=i?` — ${i}`:"";this.milestoneCaption.replaceChildren(n,document.createTextNode(a))}exposureInstants(e){const t=this.exposureTimes(e),n=1/t.length;return t.map(i=>({shapes:this.shapesAt(i),share:n}))}exposureTimes(e=this.currentTime){const t=(this.currentSighting.exposure??0)*1e3;if(t<zn.SHORTEST_VISIBLE_EXPOSURE_MS)return[e];const n=Math.min(zn.MAX_EXPOSURE_STEPS,Math.max(2,Math.round(t/zn.SHORTEST_VISIBLE_EXPOSURE_MS))),i=Math.ceil(this.travelPxOver(e,t)/zn.EXPOSURE_STEP_PX),a=Math.min(zn.MAX_TRAVEL_STEPS,Math.max(n,i)),r=[];for(let o=0;o<a;o++)r.push(e+t*o/a);return r}travelPxOver(e,t){const n=this.shapesAt(e),i=this.shapesAt(e+t);let a=0;for(const[r,o]of n){const l=i.get(r);if(!l)continue;const c=l.bounds.x+l.bounds.width/2-(o.bounds.x+o.bounds.width/2),h=l.bounds.y+l.bounds.height/2-(o.bounds.y+o.bounds.height/2);a=Math.max(a,Math.hypot(c,h))}return a}shapeAt(e,t,n){for(const i of this.exposureTimes()){const a=this.currentSighting.timeline.hitTest(i,e,t,n);if(a)return a}}shapesAt(e){const t=new Map;for(const n of this.currentSighting.timeline.sourceIds){const i=this.currentSighting.timeline.getInterpolatedShapeAt(e,n);i&&t.set(n,i)}return t}static SHORTEST_VISIBLE_EXPOSURE_MS=20;static MAX_EXPOSURE_STEPS=48;static EXPOSURE_STEP_PX=2;static MAX_TRAVEL_STEPS=320;applyFrameFormat(){const e=st.frameWidthPx(this.currentSighting.instrument,this.canvas.height);if(this.canvas.width===e)return;this.canvas.width=e,this.canvas.parentElement?.style.setProperty("--frame-aspect",`${e} / ${this.canvas.height}`)}canvasPointFromEvent(e){const t=this.canvas.getBoundingClientRect();if(!(t.width===0||t.height===0))return{x:(e.clientX-t.left)/t.width*this.canvas.width,y:(e.clientY-t.top)/t.height*this.canvas.height}}onFrame(e,t){this.canvasRenderer.clear(this.canvas.width,this.canvas.height);const n=this.playbackState!=="playing"?this.highlightedSourceIds:iv;this.canvasRenderer.setStarPoints(st.starPointsOf(this.sighting.instrument));const i=(bt(this.sighting,e)?.rollDeg??0)+this.gaitAt(e).rollDeg;this.canvasRenderer.setRoll(i*Math.PI/180);const a=this.exposureInstants(e),r=this.frameShift;if(this.paintsShapes)for(const o of a)for(const[,l]of o.shapes){const c=o.share,h=c===1?l:{...l,transparency:1-(1-l.transparency)*c};this.canvasRenderer.paintShape(this.shifted(h,r))}for(const[o,l]of a[0].shapes)n.has(o)&&(this.paintsShapes?n.size===1?this.canvasRenderer.paintShape({...l,selected:!0}):this.canvasRenderer.paintMemberOutline(l):this.canvasRenderer.paintSelectionOnly(this.shifted(l,r)));if(n.size>1){const o=it.groupBoundsFor([...t].filter(([l])=>n.has(l)).map(([,l])=>l.bounds));this.canvasRenderer.paintGroupHandles(o)}this.keepWitnessMapClear(a[0].shapes),this.seekInput.value=String(e),this.timeStartLabel.textContent=this.formatPosition(e),this.showMilestoneAt(e),this.paintWitnessMap(e),this.playbackState==="playing"?(this.soundPreview=void 0,this.sightingAudio.setSound(Jd(this.currentSighting,e))):this.soundPreview?this.sightingAudio.setSound(this.soundPreview):this.sightingAudio.silence(),this.updatePlayPauseButton(),this.dispatchEvent(new CustomEvent("timeupdate",{detail:{time:e}}))}shifted(e,t){return t.x===0&&t.y===0?e:{...e,bounds:{...e.bounds,x:e.bounds.x+t.x,y:e.bounds.y+t.y}}}createPlayer(){const e=new O1(this.currentSighting.timeline,(t,n)=>this.onFrame(t,n));return e.loop=this.loopEnabled,e.onEnded=()=>{this.updatePlayPauseButton(),this.dispatchEvent(new CustomEvent("ended",{bubbles:!0,composed:!0}))},e}togglePlayPause(){this.player.seekableDuration<=0||(this.player.playbackState==="playing"?(this.player.pause(),this.soundPreview=void 0,this.sightingAudio.silence(),this.refresh()):(this.sightingAudio.resume(),this.player.play()),this.updatePlayPauseButton())}updatePlayPauseButton(){const e=this.player.playbackState==="playing";this.playPauseButton.textContent=e?"⏸":"▶";const t=this.player.seekableDuration>0;this.playPauseButton.disabled=!t;const n=t?e?this.messages.pause:this.messages.play:this.messages.noDuration;this.playPauseButton.title=n,this.playPauseButton.setAttribute("aria-label",n),this.toolbar.classList.toggle("auto-hide",e),this.cornerButtons.classList.toggle("auto-hide",e)}toggleLoop(){this.loopEnabled=!this.loopEnabled,this.loopButton.setAttribute("aria-pressed",String(this.loopEnabled)),this.player.loop=this.loopEnabled}restorePlayback(){const e=this.playbackBeforeClick;e&&(this.currentTime=e.time,e.state==="playing"?this.play():this.pause())}get canUseNativeFullscreen(){return typeof this.fullscreenTarget.requestFullscreen=="function"&&document.fullscreenEnabled}toggleFullscreen(){if(!this.canUseNativeFullscreen){this.simulatedFullscreen?this.exitSimulatedFullscreen():this.enterSimulatedFullscreen();return}document.fullscreenElement?document.exitFullscreen():this.fullscreenTarget.requestFullscreen().catch(e=>{console.error("<rr0-ufo>: requestFullscreen() failed —",e)})}enterSimulatedFullscreen(){const e=this.fullscreenTarget;this.styleBeforeSimulatedFullscreen=e.getAttribute("style")??"",this.bodyOverflowBeforeSimulatedFullscreen=document.body.style.overflow;const t=e.style;t.setProperty("position","fixed"),t.setProperty("inset","0"),t.setProperty("margin","0"),t.setProperty("max-width","none"),t.setProperty("max-height","none"),t.setProperty("aspect-ratio","auto"),t.setProperty("z-index","2147483647"),t.setProperty("background","#000"),t.setProperty("width","100vw"),t.setProperty("width","100dvw"),t.setProperty("height","100vh"),t.setProperty("height","100dvh"),document.body.style.overflow="hidden",this.simulatedFullscreen=!0,document.addEventListener("keydown",this.handleSimulatedFullscreenKey),this.updateFullscreenButton()}exitSimulatedFullscreen(){if(!this.simulatedFullscreen)return;const e=this.fullscreenTarget;this.styleBeforeSimulatedFullscreen?e.setAttribute("style",this.styleBeforeSimulatedFullscreen):e.removeAttribute("style"),document.body.style.overflow=this.bodyOverflowBeforeSimulatedFullscreen??"",this.simulatedFullscreen=!1,document.removeEventListener("keydown",this.handleSimulatedFullscreenKey),this.updateFullscreenButton()}toggleWitnessMap(){this.setWitnessMapOpen(this.witnessMapPanel.hidden)}applyWitnessMapDefault(){this.setWitnessMapOpen(this.hasAttribute(Ws)&&this.witnessPath!==void 0)}setWitnessMapOpen(e){this.witnessMapPanel.hidden=!e,this.witnessMapPanel.removeAttribute("title"),this.witnessMapButton.setAttribute("aria-pressed",String(e)),this.updateWitnessMapButton(),e&&(this.sizeWitnessMapCanvas(),this.loadWitnessMapImagery(),this.paintWitnessMap(this.currentTime))}updateWitnessMapButton(){const t=!this.witnessMapPanel.hidden?this.messages.hideWitnessMap:this.messages.showWitnessMap;this.witnessMapButton.title=t,this.witnessMapButton.setAttribute("aria-label",t)}updateWitnessMap(){const e=this.witnessPath!==void 0;if(this.witnessPath=Wr.of(this.currentSighting),this.witnessMapButton.hidden=this.witnessPath===void 0,!e&&this.witnessPath&&this.applyWitnessMapDefault(),!this.witnessPath){this.setWitnessMapOpen(!1),this.witnessMapBounds=void 0;return}const t=this.witnessPath.boundsAround(zn.WITNESS_MAP_MIN_SPAN_M,zn.WITNESS_MAP_MARGIN);(!this.witnessMapBounds||!this.sameGround(this.witnessMapBounds,t))&&(this.witnessMapBounds=t,this.witnessMapImagery=void 0,this.witnessMapImageryCredit=void 0,this.witnessMapImageryFailed=!1,this.witnessMapImageryRequested=!1,this.witnessMapPanel.hidden||this.loadWitnessMapImagery())}sameGround(e,t){const n=Math.abs(e.east-e.west)/20;return Math.abs(e.north-t.north)<n&&Math.abs(e.south-t.south)<n&&Math.abs(e.west-t.west)<n&&Math.abs(e.east-t.east)<n}async loadWitnessMapImagery(){if(this.witnessMapImageryRequested||!this.witnessMapBounds)return;this.witnessMapImageryRequested=!0;const e=xm(),t=this.witnessMapBounds;try{const n=await e.getImageryTexture(t,{width:zn.WITNESS_MAP_IMAGERY_PX,height:zn.WITNESS_MAP_IMAGERY_PX});if(this.witnessMapBounds!==t)return;this.witnessMapImagery=n,this.witnessMapImageryCredit=e.attribution}catch{this.witnessMapImageryFailed=!0}this.paintWitnessMap(this.currentTime)}get witnessMapCredit(){return this.witnessMapImageryCredit}get witnessMapFooterLine(){return this.witnessMapImageryFailed?this.messages.mapImageryUnavailable:this.creditShownExternally?void 0:this.witnessMapImageryCredit}keepWitnessMapClear(e){if(this.witnessMapPanel.hidden)return;const t=this.witnessMapBoxPx;if(!t)return;const n=(o,l,c)=>{for(const h of e.values())if(!(h.transparency>=1)&&!(h.bounds.x+h.bounds.width<o-c||h.bounds.x>l+c)&&!(h.bounds.y>t.bottom+c||h.bounds.y+h.bounds.height<t.top-c))return!0;return!1},i=[this.canvas.width-t.width,this.canvas.width],a=[0,t.width],r=zn.WITNESS_MAP_CLEARANCE_PX;if(this.witnessMapPanel.classList.contains("on-the-left")){n(i[0],i[1],r)||this.witnessMapPanel.classList.remove("on-the-left");return}n(i[0],i[1],0)&&!n(a[0],a[1],0)&&this.witnessMapPanel.classList.add("on-the-left")}witnessMapBoxPx;static WITNESS_MAP_CLEARANCE_PX=24;sizeWitnessMapCanvas(){const e=this.witnessMapPanel.clientWidth;if(e===0)return;const t=Math.round(e*(globalThis.devicePixelRatio??1));this.measureWitnessMapBox(),this.witnessMapCanvas.width!==t&&(this.witnessMapCanvas.width=t,this.witnessMapCanvas.height=t)}measureWitnessMapBox(){const e=this.witnessMapPanel.getBoundingClientRect(),t=this.canvas.getBoundingClientRect();if(t.width===0||t.height===0)return;const n=this.canvas.width/t.width,i=this.canvas.height/t.height;this.witnessMapBoxPx={width:e.width*n,top:(e.top-t.top)*i,bottom:(e.bottom-t.top)*i}}paintWitnessMap(e){if(this.witnessMapPanel.hidden||!this.witnessPath||!this.witnessMapBounds)return;const t=bt(this.currentSighting,e),n=this.currentSighting.instrument,i=[],a=this.currentSighting.milestones.length>0?of(this.currentSighting.milestones,e):void 0;for(const r of this.milestonesShown?$a(this.currentSighting.milestones):[]){const o=bt(this.currentSighting,r.t);o?.lat===void 0||o.lng===void 0||i.push({label:this.said.read(r.label)??"",note:this.said.read(r.note),t:r.t,lat:o.lat,lng:o.lng,current:r===a})}this.witnessMapRenderer.paint({bounds:this.witnessMapBounds,imagery:this.witnessMapImagery,path:this.witnessPath,position:t?.lat!==void 0&&t.lng!==void 0?{lat:t.lat,lng:t.lng}:void 0,headingDeg:t?.headingDeg===void 0?void 0:t.headingDeg+this.lookYawDeg,coneHalfAngleDeg:t?Qn.of(n,this.canvas.height,t.fovDeg).halfWidthAngleDeg(st.aspectOf(n)):void 0,markers:i,decor:this.witnessMapDecorAt(e),witnessLabel:this.said.read(this.currentSighting.witness?.title)??this.messages.witnessHere,nightFraction:this.witnessMapNightFraction,attribution:this.witnessMapFooterLine})}toggleMilestones(){this.setMilestonesShown(!this.milestonesShown)}setMilestonesShown(e){this.milestonesShown=e,this.milestoneMarks.hidden=!e,this.milestonesButton.setAttribute("aria-pressed",String(e)),this.updateMilestonesButton(),this.showMilestoneAt(this.currentTime),this.paintWitnessMap(this.currentTime)}updateMilestonesButton(){this.milestonesButton.hidden=this.currentSighting.milestones.length===0;const e=this.milestonesShown?this.messages.hideMilestones:this.messages.showMilestones;this.milestonesButton.title=e,this.milestonesButton.setAttribute("aria-label",e)}witnessMapDecorAt(e){const t=bt(this.currentSighting,0);return t?.lat===void 0||t.lng===void 0?[]:this.currentSighting.decor.filter(n=>n.kind!=="crop").map(n=>{const i=Ya(n,e),{lat:a,lng:r}=zi(i.eastM,-i.northM,t.lat,t.lng);return{lat:a,lng:r,headingDeg:i.headingDeg,label:this.said.read(n.title)??this.messages.decorHere}})}witnessMapNightFraction;setSunAltitude(e){const t=e===void 0?void 0:Math.max(0,Math.min(1,-e/12));t!==this.witnessMapNightFraction&&(this.witnessMapNightFraction=t,this.paintWitnessMap(this.currentTime))}setLookOffset(e,t){e===this.lookYawDeg&&t===this.lookPitchDeg||(this.lookYawDeg=e,this.lookPitchDeg=t,this.refresh())}get frameShiftPx(){return this.frameShift}get frameShift(){const e=this.gaitAt(this.currentTime),t=this.lookYawDeg+e.yawDeg,n=this.lookPitchDeg+e.pitchDeg;if(t===0&&n===0)return{x:0,y:0};const i=bt(this.currentSighting,this.currentTime),a=Qn.of(this.currentSighting.instrument,this.canvas.height,i?.fovDeg??60);return{x:-a.angleDegToRadiusPx(t),y:a.angleDegToRadiusPx(n)}}gaitAt(e){return Gt.of(this.currentSighting)?.offsetAt(e)??Gt.STILL}updateFullscreenButton(){const e=this.simulatedFullscreen||document.fullscreenElement===this.fullscreenTarget;this.fullscreenButton.title=e?this.messages.exitFullscreen:this.messages.fullscreen,this.fullscreenButton.setAttribute("aria-label",this.fullscreenButton.title)}get said(){return this.saidTexts??=new Fi(Vs.preferencesFor(this))}saidTexts;async loadLocaleMessages(){const e=Xr(Vs.preferencesFor(this),hm);e!=="en"&&this.applyMessages(await V1(e))}updateTimeLabelTitles(){const e=this.showClockTime?this.messages.switchToElapsed:this.messages.switchToClockTime,t=this.canSwitchTimeDisplay?` — ${e}`:"";this.timeStartLabel.title=this.messages.currentPosition+t,this.timeEndLabel.title=this.messages.duration+t;for(const n of[this.timeStartLabel,this.timeEndLabel])n.classList.toggle("switchable",this.canSwitchTimeDisplay),this.canSwitchTimeDisplay?(n.setAttribute("role","button"),n.setAttribute("tabindex","0")):(n.removeAttribute("role"),n.removeAttribute("tabindex"))}applyMessages(e){this.messages=e,this.updateTimeLabelTitles(),this.loopButton.title=e.autoReplay,this.loopButton.setAttribute("aria-label",e.autoReplay),this.updatePlayPauseButton(),this.updateFullscreenButton(),this.updateWitnessMapButton(),this.updateMilestonesButton()}updateTimeLabels(){const e=this.currentSighting.event,t=Ka(e);this.realDurationMs=t!==void 0&&t>0?t:void 0,this.realStartMs=e.time?Eh(e.time):void 0;const n=this.currentSighting.timeline.duration;this.player.playbackRate=this.realDurationMs!==void 0&&n>0?n/this.realDurationMs:1,this.player.durationOverrideMs=n>0?0:this.realDurationMs??0,this.timeEndLabel.textContent=this.formatEndOfTimeline(),this.timeStartLabel.textContent=this.formatPosition(this.player.time),this.updateTimeLabelTitles()}formatPosition(e){if(this.realDurationMs===void 0)return uo(e);const t=this.currentSighting.timeline.duration,n=t>0&&e<=t?e/t*this.realDurationMs:e;return this.canShowClockTime?uf(df(this.realStartMs+n)):uo(n)}formatEndOfTimeline(){return this.realDurationMs===void 0?uo(this.currentSighting.timeline.duration):this.canShowClockTime?uf(df(this.realStartMs+this.realDurationMs)):uo(this.realDurationMs)}}function df(s){const e=new Date(s);return{hour:e.getUTCHours(),minute:e.getUTCMinutes(),second:e.getUTCSeconds()}}function uf(s){if(s.hour===void 0)return"0:00";const e=t=>String(t).padStart(2,"0");return s.second?`${e(s.hour)}:${e(s.minute??0)}:${e(s.second)}`:`${e(s.hour)}:${e(s.minute??0)}`}function uo(s){const e=Math.round(s/1e3),t=Math.floor(e/60),n=e%60;return`${t}:${String(n).padStart(2,"0")}`}const Dh="rr0-ufo";function ql(){customElements.get(Dh)||customElements.define(Dh,zn)}const sv=`
1760
1760
  <div class="stage" id="stage">
1761
1761
  <div class="frame" id="frame">
1762
1762
  <canvas id="scene-canvas"></canvas>
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@rr0/ufoathome",
3
3
  "type": "module",
4
- "version": "0.55.2",
4
+ "version": "0.55.3",
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:"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",observationTime:"Début de l'observation",observationEndTime:"Fin de l'observation",assessmentGroup:"Évaluation",assessmentNames:{coverage:"Infos du témoin"},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"},witnessGroup:"Témoin",witnessId:"ID",witnessTitle:"Titre",witnessLastName:"Nom de famille",witnessFirstNames:"Prénoms",caseId:"ID de l'affaire",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",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",soundKind:"Son",soundNone:"Aucun (silencieux)",soundHum:"Bourdonnement",soundWhistle:"Sifflement",soundRumble:"Grondement",soundCrackle:"Crépitement",soundVolume:"Intensité sonore",soundPitch:"Hauteur",soundSrc:"Enregistrement",instrument:"Observé avec",decorAircraft:"Aéronef",decorEntity:"Être",decorAltitude:"Altitude",decorLights:"Feux",decorLightsNone:"aucun",decor:"Environnement",decorBuilding:"Bâtiment",decorTree:"Arbre",decorCrop:"Rang de culture",decorMound:"Tas de pierres",decorStreetlight:"Lampadaire",decorVehicle:"Véhicule",decorWitness:"Autre témoin",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",confirmAccept:"Supprimer",confirmDecline:"Annuler",decorWidth:"Largeur",decorLength:"Longueur",decorHeight:"Hauteur",decorModel:"Modèle 3D",decorModelNone:"Forme intégrée",decorModelAdvanced:"Modèle depuis une adresse",decorModelUrl:"Adresse glTF/GLB",decorModelTitle:"Nom du modèle",decorModelAuthor:"Auteur",decorModelLicense:"Licence",decorModelSource:"Provenance",decorFloors:"Étages",decorOccupiedFloor:"Étage occupé",decorWitnessSide:"Emplacement du témoin",decorWitnessSideNone:"Non présent",decorWindows:"Fenêtres",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,oval:"Ovale",polygon:"Polygone",addVertex:"Ajouter un sommet",deleteVertex:"Supprimer le sommet",notAPolygon:"Sélectionnez une seule forme polygonale",tooFewVertices:"Une forme a besoin d'au moins 3 points",shape:"Forme",apparentWidth:"Largeur apparente",realWidth:"Largeur réelle",distance:"Distance",sizeLock:"Bloquer",lockNone:"rien",lockApparent:"la largeur apparente",lockReal:"la largeur réelle",lockDistance:"la distance",apparentSize:"{moons}× la Lune",utcOffsetPlaceholder:"d'après la longitude",realSizeBetween:"La scène borne cette largeur : entre {min} et {max} m, d'après ce qu'il croise",realSizeAtLeast:"La scène borne cette largeur : au moins {min} m, d'après ce qu'il passe derrière",realSizeAtMost:"La scène borne cette largeur : au plus {max} m, d'après ce qu'il passe devant",realSizeUnknown:"Rien dans la scène ne borne cette largeur : elle ne fait que découler de la distance",realSizeOutside:" — la largeur ci-dessus en sort",blurBound:"Flou à travers cet objectif : plus près que {max} m",blurBoundNoInstrument:"Le flou à l'œil nu ne borne aucune distance — un œil n'a pas de diaphragme dont sortir",blurBoundNotAtInfinity:"Le flou ne borne une distance que pour une mise au point à l'infini : celle-ci est à {focus} m, qui floute des deux côtés",realSizeContradiction:"Contradiction : les passages déclarés ne peuvent pas être vrais ensemble",realDistanceHere:" — soit ici entre {min} et {max} m",clearDistanceHypothesis:"Retirer l'hypothèse de distance",clearDistanceHypothesisTitle:"Revenir à ce que l'enregistrement établit",depthStated:"Dessiné à {m} m, comme l'enregistrement l'énonce",depthHypothesis:"Dessiné à {m} m : votre hypothèse — ce que le décor en cache est ce qu'une chose à cette distance perdrait",depthDerived:"Dessiné à {m} m, d'après la marche du témoin",depthBounded:"Dessiné à {m} m, d'après ce qu'il passe derrière et devant",depthConventional:"Dessiné à {m} m par convention : rien dans l'enregistrement n'établit de distance",addShape:"Ajouter une forme",deleteShape:"Supprimer la forme",play:"Lecture",pause:"Pause",noDuration:"Aucune durée d'observation",autoReplay:"Lecture automatique",group:"Grouper",ungroup:"Dégrouper",bringToFront:"Placer devant",sendToBack:"Placer derrière",contextMenuDelete:"Supprimer",confirmDeleteShape:"Supprimer {name} ? Cette action est irréversible.",confirmDeleteShapes:"Supprimer {count} formes ? Cette action est irréversible.",confirmDeleteMilestone:"Ne plus nommer le moment {name} ? L'enregistrement lui-même est inchangé.",onlyOneShape:"Il n'y a qu'une seule forme",alreadyAtFront:"Cette forme est déjà la plus en avant",alreadyAtBack:"Cette forme est déjà la plus en arrière",needTwoShapesToGroup:"Sélectionnez au moins deux formes pour les grouper",notGrouped:"Cette forme ne fait pas partie d'un groupe",multipleShapesSelected:"Plusieurs formes sélectionnées — sélectionnez-en une seule pour modifier ceci",samplingRate:"Échantillonnage",currentPosition:"Position actuelle",switchToElapsed:"cliquer pour afficher la durée écoulée",switchToClockTime:"cliquer pour afficher l'heure de l'observation",durationPlaceholder:"durée de l'observation",durationImprecise:"Ces dates ne permettent pas de déterminer précisément une durée — saisissez-la manuellement.",export:"Exporter",importFile:"Charger un fichier JSON",importUrl:"Ou charger depuis une URL",importUrlPlaceholder:"https://…/sighting.json",importButton:"Charger",importError:"Impossible de charger cet enregistrement — vérifiez le fichier ou l'URL et réessayez.",importErrorCors:"Cette adresse répond, mais le navigateur n'a pas le droit de la lire depuis cette page. Le fichier lui-même est bon : c'est son serveur qui doit envoyer l'en-tête « Access-Control-Allow-Origin: * » avec. Si ce serveur n'est pas le vôtre, c'est ce qu'il faut demander à son administrateur.",importErrorMixedContent:"Une page sécurisée ne peut pas charger une adresse commençant par http://. Utilisez https:// si ce serveur le propose.",importErrorUnreachable:"Rien n'a répondu à cette adresse. Vérifiez l'orthographe, et que vous êtes connecté.",importErrorStatus:"Ce serveur a répondu par une erreur ({status}). L'adresse est probablement fausse, ou le fichier a été déplacé.",importErrorMalformed:"Cette adresse a répondu, mais ce qui revient n'est pas un enregistrement.",record:"Enregistrer",stop:"Arrêter",according:"selon",sourceElevation:"Relief",sourceImagery:"Imagerie",placeNamePlaceholder:"Valensole, France",searchPlace:"Localiser",placeMatch:"Correspondances",placeSearching:"Recherche du lieu…",placeMatchFound:"lieu trouvé",placeMatchesFound:"lieux trouvés",placeNotFound:"Aucun lieu de ce nom",placeSearchFailed:"Recherche de lieu momentanément indisponible",utcOffsetImplausible:"Ce fuseau ne correspond pas à la longitude saisie, dont l'heure solaire est UTC{solar} — la scène et le relevé météo obéissent pourtant à ce qui est déclaré ici. Videz le champ pour le déduire de la longitude.",timeZoneManual:"décalage saisi",altitudeAboveSeaLevel:"Altitude du témoin au-dessus du niveau de la mer — le sol du lieu saisi en fixe le minimum : un témoin dans les Alpes n'est pas à 0 m.",groundAt:"sol à {m} m",headingPlaceholder:"inconnu",edtfInvalid:"Date/heure EDTF invalide (ex. 1965-07-01T05:00, 2025-06?, 2025~).",edtfPlaceholder:"AAAA-MM-JJThh:mm[?~%] ou hh:mm",observationTimeHint:"EDTF — ex. 1965-07-01T05:00, 2025-06? (incertain), 2025~ (approximatif), ou juste 05:00 si la date est inconnue",observationEndTimeHint:"EDTF — ex. 1965-07-01T05:10, 2025-06? (incertain), 2025~ (approximatif), ou juste 05:10 si la date est inconnue",presetsGroupLabel:"Forme de l'ovni",witnessDirName:"Répertoire",description:"Description",tagsPlaceholder:"séparés par des virgules",weather:"Météo",shapeGroup:"Phénomène",soundGroup:"Son",temporalGroup:"Moment",timeQualifierExact:"Exacte",timeQualifierApproximate:"Approximative",timeQualifierUncertain:"Incertaine",timeQualifierBoth:"Incertaine et approximative",edtfModeTitle:"Saisir plutôt une date imprécise : une année seule, un mois, une heure sans date",locationGroup:"Lieu",observationGroup:"Observation",weatherWhilePlaying:"Mettez la lecture en pause pour décrire le temps — pendant qu'elle tourne, l'instant où ceci s'écrirait se déplace",weatherInferred:"D'après les relevés",weatherInferredTitle:"La météo n'est pas un témoignage : c'est un fait mesurable, relevé pour la date, l'heure et le lieu de l'observation. Décochez pour saisir les conditions rapportées par le témoin, qui priment alors sur le relevé.",weatherLookingUp:"Recherche du relevé…",weatherNeedsDateAndPlace:"Date complète et lieu requis pour retrouver le relevé",weatherNoRecord:"Aucun relevé pour cette date et ce lieu",weatherLookupFailed:"Relevés météo momentanément inaccessibles",instrumentOutOfPeriod:"{name} — hors de son époque",unitMillimetres:"mm",unitDegrees:"°",soundSrcPlaceholder:"URL d'un enregistrement réel",skyLine:"Ciel : {parts}",skyStarsEye:"étoiles jusqu'à la magnitude {limit}, ce que l'œil atteignait sous ce ciel",skyStarsDeeper:"étoiles jusqu'à la magnitude {limit} à travers un {device} — {gain} magnitudes au-delà des {eye} qu'atteignaient les yeux du témoin",skyStarsShallower:"étoiles jusqu'à la magnitude {limit} à travers un {device} — {gain} magnitudes en deçà des {eye} qu'atteignaient les yeux du témoin",skyStarsCatalogue:", dessinées jusqu'à {catalogue}, où s'arrête le catalogue de ce projet",skyStarsNone:"aucune étoile ne se détachait d'un ciel aussi clair",skyDetails:"Voir le détail des relevés",skyDetailsHide:"Masquer le détail des relevés",skyShowerActive:"{name} — radiant à {altitude}° de hauteur, {bearing} — environ {rate}/h sous ce ciel, sur un fond sporadique de {sporadic}/h",skyShowerBelowHorizon:"{name} est actif, mais son radiant est sous l'horizon — il n'a rien pu produire",skyNothingActive:"aucune pluie de météores active à cette date — un fond sporadique d'environ {sporadic}/h",showMeteor:"Montrer un météore",skyComet:"La {name}, magnitude {magnitude}, à {altitude}° de hauteur {bearing}, queue longue de {tail}°",skyCometNoTail:"La {name}, magnitude {magnitude}, à {altitude}° de hauteur {bearing}",skyCometBelowHorizon:"La {name} était là, magnitude {magnitude}, mais sous l'horizon — personne ici ne l'a vue",skyCometInDaylight:"La {name}, magnitude {magnitude}, à {altitude}° de hauteur {bearing} — mais à {elongation}° du Soleil seulement",showComet:"Montrer la comète",skyOpticsPossible:"nuages de glace suffisants, autour {source}, pour {forms}",skyOpticsAlignment:" — tout sauf les halos exige des cristaux tombant à plat, ici supposés alignés à {alignment} %, qu'aucun relevé ne donne",skyOpticsHalo22:"un halo à {angle}°",skyOpticsHalo46:"un halo à {angle}°",skyOpticsParhelia:"des parhélies à {angle}° de part et d'autre",skyOpticsTangentArc:"un arc tangent au sommet",skyOpticsParhelicCircle:"un cercle parhélique blanc faisant le tour du ciel à sa hauteur",skyOpticsCircumzenithal:"un arc circumzénithal à {angle}° de hauteur",skyOpticsCircumhorizontal:"un arc circumhorizontal très au-dessous",skyOpticsPillar:"un pilier dressé au-dessus",skyOpticsNoIce:"aucun nuage de glace : ni halo ni parhélie",skyOpticsHidden:"des nuages de glace en altitude, mais une couche plus basse les cache",skyOpticsSun:"du Soleil",skyOpticsMoon:"de la Lune",skyBowPossible:"pluie et soleil suffisants pour {forms}",skyBowMoon:"pluie sous une Lune éclairée à {lit} %, de quoi former {forms} — un arc-en-ciel lunaire, que l'œil voit blanc",skyGlowBand:"la Voie lactée à {contrast}× le fond du ciel, à {altitude}° de hauteur {bearing}",skyGlowCone:"la lumière zodiacale à {contrast}× le fond du ciel, à {altitude}° de hauteur {bearing}, à {elongation}° du Soleil — un cône penché, sans bord, disparu dans l'heure",skyGlowZodiacalBand:"la bande zodiacale à {contrast}× le fond du ciel, à {altitude}° de hauteur {bearing} — toute l'écliptique faiblement allumée, ce qui n'est pas ce que les gens rapportent",skyGlowMoon:"ni Voie lactée ni lumière zodiacale : une Lune éclairée à {lit} % tenait le ciel à {sky} magnitudes par seconde d'arc, là où il leur en faut 22",skyGlowTwilight:"ni Voie lactée ni lumière zodiacale : le crépuscule tenait encore le ciel à {sky} magnitudes par seconde d'arc, là où il leur en faut 22",skyGlowNothingUp:"ciel assez noir ({sky} magnitudes par seconde d'arc), mais ni le plan de la Galaxie ni l'écliptique ne s'y tenaient assez haut",skyBowPrimary:"un arc de {radius}° de rayon, dont le sommet montait à {top}°",skyBowSecondary:"un second, plus pâle, à {radius}°, aux couleurs inversées",skyBowSourceTooHigh:"pluie, mais l'astre à {altitude}° de hauteur : aucun arc ne pouvait dépasser l'horizon, ils se tiennent à {radius}° du point opposé",skyBowHidden:"pluie, mais une couche continue entre elle et la lumière : aucun arc",skyBowNoSource:"pluie, et rien d'allumé pour en tirer un arc",skySatellitesLit:"l'ombre de la Terre montait à {height} km au-dessus du témoin, l'orbite basse était donc encore éclairée — {count} objets suivis étaient en orbite ce mois-là",skySatellitesLitWith:"l'ombre de la Terre montait à {height} km au-dessus du témoin, l'orbite basse était donc encore éclairée — {count} objets suivis étaient en orbite ce mois-là, dont {eras}",skySatellitesShadowed:"l'ombre de la Terre montait à {height} km au-dessus du témoin : sur les {count} objets suivis en orbite ce mois-là, rien en orbite basse n'était éclairé",skySatellitesNotYet:"rien n'était encore en orbite",skySatellitesDaylight:"tout ce qui est en orbite était éclairé, comme toujours de jour, et {eras} pouvaient l'emporter même sur ce ciel",skySatellitesDaylightOne:"tout ce qui est en orbite était éclairé, comme toujours de jour, et {eras} pouvait l'emporter même sur ce ciel",skyUnknown:"indéterminable sans date ni lieu",lookAtDecor:"Regarder cet élément",addDecor:"Ajouter",deleteDecor:"Supprimer l'élément de décor",decorSightingUrl:"URL de son propre enregistrement",viewTestimony:"Voir le témoignage",noWitnessRecording:"Aucune URL d'enregistrement définie pour ce témoin",masks:"Masque",addWitness:"Ajouter un témoin",narrativePlaceholder:"Ce que le témoin a rapporté, dans ses propres mots",narrativeKey:"Clé d'API {source}",narrativeNeedsKey:"Saisissez votre propre clé d'API {source} pour générer la reconstitution d'après le récit",narrativeKeyUnlikely:"Cela ne ressemble pas à une clé d'API Claude : elles commencent par sk-ant-",narrativeWorkspace:"Espace de travail",narrativeWorkspacePlaceholder:"seulement si votre clé en couvre plusieurs",narrativeWorkspaceHint:"Seulement pour une clé dont la portée est l'organisation entière. Plus simple : laissez vide et créez une clé de portée « espace de travail ».",narrativeNeedsAsk:"Rien à envoyer pour l'instant",narrativeRemember:"Retenir sur cet appareil",narrativeDraft:"Générer la reconstitution",narrativeStop:"Arrêter",narrativeWorking:"Lecture du récit…",narrativeApplied:"{count} champs écrits dans l'éditeur",narrativeUnchanged:"Le récit n'énonce rien que l'enregistrement sache encore porter",narrativeStated:"Ce que le témoin a dit",narrativeDerived:"Déduit du récit",narrativeAssumed:"Supposé, pour que la reconstitution tourne : à vérifier",narrativeGaps:"Ce que rien n'a pu trancher",narrativeErrorCredential:"Pas de clé, ou une clé refusée : vérifiez-la sur console.anthropic.com",narrativeErrorRateLimited:"Trop de requêtes sur votre compte : patientez un instant et redemandez",narrativeErrorRefused:"Le récit n'a pas reçu de réponse. Le reformuler peut aider, le redemander non",narrativeErrorMalformed:"La réponse n'était pas un brouillon exploitable : cela vaut la peine de redemander",narrativeErrorUnreachable:"Rien n'a répondu : vérifiez la connexion",narrativeErrorRejected:"Refusé : {detail}",witnessAge:"Âge alors",witnessOccupation:"Profession",testimonySource:"Récit recueilli",testimonySourceUnknown:"on ne sait pas",testimonySourceOnSite:"enquête sur site",testimonySourceInterview:"entretien en personne",testimonySourceTelephone:"par téléphone",testimonySourceQuestionnaire:"questionnaire",testimonySourceLetter:"écrit par le témoin",testimonySourcePress:"presse ou radiodiffusion",testimonyFollowedUp:"Recontacté",testimonyUnknown:"on ne sait pas",testimonyYes:"oui",testimonyNo:"non",questionUnanswered:"Rien dans cet enregistrement ne répond à l'une des questions qu'une reconstitution doit trancher",durationRequired:"L'observation a besoin d'une longueur pour être rejouée — indiquez-la, ou une heure de fin, qui peut être approximative",questionsUnanswered:"{count} des questions auxquelles une reconstitution complète répond restent sans réponse ici"};export{r as sightingEditorMessages_fr};