@rr0/ufoathome 0.104.1 → 0.105.1

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.
@@ -2179,8 +2179,8 @@ canvas[data-cursor="rotate"] {
2179
2179
  }
2180
2180
  `;class Fo{constructor(t){this.points=t}static STATIONARY_M=5;static of(t){const e=[];for(const i of t.observerTrack.allKeyframes){const{lat:n,lng:s,headingDeg:r}=i.pose;n===void 0||s===void 0||e.push({t:i.t,lat:n,lng:s,headingDeg:r})}if(e.length===0){const i=t.event.place?.[0];if(!i)return;e.push({t:0,lat:i.lat,lng:i.lng})}return new Fo(e)}static TRAVEL_M=50;get travels(){return this.spanM>Fo.TRAVEL_M}get moved(){return this.spanM>Fo.STATIONARY_M}get spanM(){const t=this.box,e=(t.south+t.north)/2,i=(t.west+t.east)/2;return Math.max(Math.abs(si(e,t.east,e,t.west).x),Math.abs(si(t.north,i,t.south,i).z))}get center(){const t=this.box;return{lat:(t.south+t.north)/2,lng:(t.west+t.east)/2}}boundsAround(t,e){const{lat:i,lng:n}=this.center,s=Math.max(this.spanM*(1+e),t)/2;return{north:Nn(0,-s,i,n).lat,south:Nn(0,s,i,n).lat,east:Nn(s,0,i,n).lng,west:Nn(-s,0,i,n).lng}}get box(){const t=this.points.map(i=>i.lat),e=this.points.map(i=>i.lng);return{south:Math.min(...t),north:Math.max(...t),west:Math.min(...e),east:Math.max(...e)}}}class Bn{constructor(t,e){this.rotationPassed=t,this.scale=e}static SWAY_M=.012;static BREATH_M=.003;static DRIFT_YAW_DEG=.5;static DRIFT_PITCH_DEG=.4;static DRIFT_ROLL_DEG=.3;static GAZE_DRIFT_SHARE=.35;static HAND_HELD_S=.5;static HZ=[.11,.23,.17,.29,.37,.07];static of(t){const e=t.event.tags?.includes("paralysis")||(t.exposure??0)>Bn.HAND_HELD_S,i=t.sway??(e?0:1);if(i>0)return new Bn(Math.max(1-(t.instrument.stabilization??0),Bn.GAZE_DRIFT_SHARE),i)}offsetAt(t){const e=t/1e3,i=this.scale,n=(u,d)=>Math.sin(2*Math.PI*u*e+d),[s,r,o,c,l,h]=Bn.HZ;return{eastM:i*Bn.SWAY_M*(.7*n(s,.3)+.3*n(c,1.9)),northM:i*Bn.SWAY_M*(.6*n(o,2.2)+.4*n(l,.8)),upM:i*Bn.BREATH_M*n(r,0),yawDeg:i*this.rotationPassed*Bn.DRIFT_YAW_DEG*(.6*n(h,1.1)+.4*n(c,2.7)),pitchDeg:i*this.rotationPassed*Bn.DRIFT_PITCH_DEG*(.5*n(r,1.6)+.5*n(o,.4)),rollDeg:i*this.rotationPassed*Bn.DRIFT_ROLL_DEG*n(s,2.9)}}}class Ce{constructor(t,e){this.stretches=t,this.rotationPassed=e}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 STOP_LURCH_M=.035;static STOP_PITCH_DEG=3;static START_LURCH_M=.015;static START_PITCH_DEG=1.2;static JOLT_HZ=1.4;static JOLT_DECAY_S=.35;static JOLT_LASTS_MS=1500;static STILL=Object.freeze({eastM:0,northM:0,upM:0,rollDeg:0,pitchDeg:0,yawDeg:0});static of(t){const e=Fo.of(t);if(!e||e.points.length<2)return;const i=[];let n=0;for(let s=1;s<e.points.length;s++){const r=e.points[s-1],o=e.points[s],c=(o.t-r.t)/1e3;if(c<=0)continue;const l=si(o.lat,o.lng,r.lat,r.lng),h=l.x,u=-l.z,d=Math.hypot(h,u),f=d/c,p=Ce.stepHzFor(f);i.push({startMs:r.t,endMs:o.t,speedMPerS:f,eastUnit:d>0?h/d:0,northUnit:d>0?u/d:0,stepHz:p,stepsBefore:n,rampsIn:!0,rampsOut:!0}),n+=p*c}for(let s=0;s<i.length;s++){const r=i[s-1],o=i[s+1];i[s].rampsIn=r===void 0||r.stepHz===0,i[s].rampsOut=o===void 0||o.stepHz===0}if(i.some(s=>s.stepHz>0))return new Ce(i,1-(t.instrument.stabilization??0))}static bodyAt(t,e,i=!1){const n=Ce.of(t)?.offsetAt(e)??Ce.STILL;return i?n:Ce.add(n,Bn.of(t)?.offsetAt(e))}static stepHzFor(t){return t<Ce.SLOWEST_WALK_M_PER_S||t>Ce.FASTEST_WALK_M_PER_S?0:Ce.REFERENCE_STEP_HZ*Math.pow(t/Ce.REFERENCE_SPEED_M_PER_S,Ce.CADENCE_EXPONENT)}offsetAt(t){return Ce.add(this.cycleAt(t),this.joltAt(t))}joltAt(t){for(const e of this.stretches){if(e.stepHz===0)continue;const i=e.speedMPerS/Ce.REFERENCE_SPEED_M_PER_S,n=(o,c,l,h)=>{if(o<0||o>Ce.JOLT_LASTS_MS)return;const u=o/1e3,d=Math.exp(-u/Ce.JOLT_DECAY_S)*Math.sin(2*Math.PI*Ce.JOLT_HZ*u),f=h*c*i*d;return{eastM:f*e.eastUnit,northM:f*e.northUnit,upM:-Math.abs(f)*.3,rollDeg:0,pitchDeg:-h*l*i*d*this.rotationPassed,yawDeg:0}},s=e.rampsOut?n(t-e.endMs,Ce.STOP_LURCH_M,Ce.STOP_PITCH_DEG,1):void 0;if(s)return s;const r=e.rampsIn?n(t-e.startMs,Ce.START_LURCH_M,Ce.START_PITCH_DEG,-1):void 0;if(r)return r}}static add(t,e){return e?{eastM:t.eastM+e.eastM,northM:t.northM+e.northM,upM:t.upM+e.upM,rollDeg:t.rollDeg+e.rollDeg,pitchDeg:t.pitchDeg+e.pitchDeg,yawDeg:t.yawDeg+e.yawDeg}:t}cycleAt(t){const e=this.stretches.find(c=>t>=c.startMs&&t<=c.endMs);if(!e||e.stepHz===0)return Ce.STILL;const i=e.stepsBefore+e.stepHz*(t-e.startMs)/1e3,n=2*Math.PI*i,s=this.amplitudeAt(e,t),r=Ce.SWAY_M*s*Math.cos(n/2),o=s*this.rotationPassed*e.speedMPerS/Ce.REFERENCE_SPEED_M_PER_S;return{eastM:r*e.northUnit,northM:-r*e.eastUnit,upM:Ce.RISE_M_PER_M_PER_S*e.speedMPerS*s*Math.cos(n),rollDeg:Ce.HEAD_ROLL_DEG*o*Math.cos(n/2),pitchDeg:-1.25*o*Math.cos(n),yawDeg:Ce.HEAD_YAW_DEG*o*Math.cos(n/2)}}amplitudeAt(t,e){const i=1e3/t.stepHz,n=Math.min(i,(t.endMs-t.startMs)/2);if(n<=0)return 1;const s=e-t.startMs,r=t.endMs-e,o=Math.min(t.rampsIn?s/n:1,t.rampsOut?r/n:1,1);return(1-Math.cos(Math.PI*Math.max(o,0)))/2}}class Zx{constructor(t,e){this.timeline=t,this.onFrame=e}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 t=()=>{if(this.state!=="playing")return;const e=performance.now();if(this.currentT+=(e-this.lastWallTime)*this.playbackRate,this.lastWallTime=e,this.currentT>=this.seekableDuration){if(this.loop&&this.seekableDuration>0){this.currentT%=this.seekableDuration,this.resolveFrame(this.currentT),this.rafId=requestAnimationFrame(t);return}this.currentT=this.seekableDuration,this.stop(),this.resolveFrame(this.currentT),this.onEnded?.();return}this.resolveFrame(this.currentT),this.rafId=requestAnimationFrame(t)};this.rafId=requestAnimationFrame(t)}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(t){this.currentT=Math.max(0,Math.min(t,this.seekableDuration)),this.resolveFrame(this.currentT)}get playbackState(){return this.state}get time(){return this.currentT}resolveFrame(t){const e=new Map;for(const i of this.timeline.sourceIds){const n=this.timeline.getInterpolatedShapeAt(t,i);n&&e.set(i,n)}this.onFrame(t,e)}}const xM=["nw","n","ne","e","se","s","sw","w"],Jx=24,Cl=8,jx=3,Qx=8;function Pl(a,t,e){const i=a.x-t.x,n=a.y-t.y,s=Math.cos(e),r=Math.sin(e);return{x:t.x+i*s-n*r,y:t.y+i*r+n*s}}function hc(a){return{x:a.x+a.width/2,y:a.y+a.height/2}}const tb={nw:{left:!0,top:!0},n:{top:!0},ne:{right:!0,top:!0},e:{right:!0},se:{right:!0,bottom:!0},s:{bottom:!0},sw:{left:!0,bottom:!0},w:{left:!0}};class Dn{static handlePointsFor(t){const{x:e,y:i,width:n,height:s}=t.bounds,r={nw:{x:e,y:i},n:{x:e+n/2,y:i},ne:{x:e+n,y:i},e:{x:e+n,y:i+s/2},se:{x:e+n,y:i+s},s:{x:e+n/2,y:i+s},sw:{x:e,y:i+s},w:{x:e,y:i+s/2},rotate:{x:e+n/2,y:i-Jx}},o=hc(t.bounds),c={};for(const l of Object.keys(r))c[l]=Pl(r[l],o,t.angle);return c}static hitTestHandle(t,e,i=8,n=[...xM,"rotate"]){const s=Dn.handlePointsFor(t);for(const r of n)if(Math.hypot(e.x-s[r].x,e.y-s[r].y)<=i)return r}static HANDLE_DIRECTION_DEG={e:0,se:45,s:90,sw:135,w:180,nw:225,n:270,ne:315};static resizeAxisFor(t,e){const n=((Dn.HANDLE_DIRECTION_DEG[t]+e*180/Math.PI)%180+180)%180/45,s=["ew","nwse","ns","nesw"];return s[Math.round(n)%s.length]}static resizeBounds(t,e,i,n){const s=hc(t),r=Pl(n,s,-e),{x:o,y:c,width:l,height:h}=t,u=tb[i];let d=o,f=c,p=o+l,v=c+h;return u.left&&(d=Math.min(r.x,p-Cl)),u.right&&(p=Math.max(r.x,d+Cl)),u.top&&(f=Math.min(r.y,v-Cl)),u.bottom&&(v=Math.max(r.y,f+Cl)),{x:d,y:f,width:p-d,height:v-f}}static resizeShape(t,e,i){if(e==="rotate")throw new Error("resizeShape does not accept the rotate handle");const{width:n,height:s}=t.bounds,r=Dn.resizeBounds(t.bounds,t.angle,e,i);if(t.kind==="oval")return{...t,bounds:r};const o=n===0?1:r.width/n,c=s===0?1:r.height/s;return{...t,bounds:r,points:t.points.map(l=>({x:l.x*o,y:l.y*c}))}}static rotateShape(t,e){const i=hc(t.bounds),n=Math.atan2(e.y-i.y,e.x-i.x)+Math.PI/2;return{...t,angle:n}}static groupBoundsFor(t){const e=Math.min(...t.map(r=>r.x)),i=Math.min(...t.map(r=>r.y)),n=Math.max(...t.map(r=>r.x+r.width)),s=Math.max(...t.map(r=>r.y+r.height));return{x:e,y:i,width:n-e,height:s-i}}static vertexPointsFor(t){const e=hc(t.bounds);return t.points.map(i=>Pl({x:t.bounds.x+i.x,y:t.bounds.y+i.y},e,t.angle))}static hitTestVertex(t,e,i=Qx){const n=Dn.vertexPointsFor(t);let s,r=i;return n.forEach((o,c)=>{const l=Math.hypot(e.x-o.x,e.y-o.y);l<=r&&(r=l,s=c)}),s}static toLocalPoint(t,e){const i=hc(t.bounds),n=Pl(e,i,-t.angle);return{x:n.x-t.bounds.x,y:n.y-t.bounds.y}}static moveVertex(t,e,i){const n=t.points.map((u,d)=>d===e?Dn.toLocalPoint(t,i):u),s=Math.min(...n.map(u=>u.x)),r=Math.min(...n.map(u=>u.y)),o=Math.max(...n.map(u=>u.x)),c=Math.max(...n.map(u=>u.y)),l={x:t.bounds.x+s,y:t.bounds.y+r,width:o-s,height:c-r},h=n.map(u=>({x:u.x-s,y:u.y-r}));return{...t,bounds:l,points:h}}static insertVertexNear(t,e){const i=Dn.toLocalPoint(t,e),{points:n}=t;let s=n.length-1,r=1/0;for(let c=0;c<n.length;c++){const l=n[c],h=n[(c+1)%n.length],u=Dn.distanceToSegment(i,l,h);u<r&&(r=u,s=c)}const o=[...n.slice(0,s+1),i,...n.slice(s+1)];return{...t,points:o}}static distanceToSegment(t,e,i){const n=i.x-e.x,s=i.y-e.y,r=n*n+s*s,o=r===0?0:Math.max(0,Math.min(1,((t.x-e.x)*n+(t.y-e.y)*s)/r)),c=e.x+o*n,l=e.y+o*s;return Math.hypot(t.x-c,t.y-l)}static deleteVertex(t,e){return t.points.length<=jx?t:{...t,points:t.points.filter((i,n)=>n!==e)}}}const $f=6,Ol=$f/2,ig=20,ng=24,sg=9,rg=6,ag=7,og=6,ys=4;class al{constructor(t){this.ctx=t}starPoints=0;roll=0;clear(t,e){this.ctx.clearRect(0,0,t,e)}static paintExtent(t){const{x:e,y:i,width:n,height:s}=t.bounds,r=e+n/2,o=i+s/2,c=t.angle%(2*Math.PI)!==0,l=Math.hypot(n,s)/2,h=c?l:n/2,u=c?l:s/2,d=Math.max(n,s)/2,f=t.brightness??0,p=f>0?Math.max(d*(1+sg*f),og*f)-d:0,v=f>0?d*(1+ag*f)-d:0,m=3*ng*(t.blur??0)+1.5*ig*t.haloScale,g=Math.max(p,v,0)+m+2;return{x:r-h-g,y:o-u-g,width:2*(h+g),height:2*(u+g)}}paintInto(t,e,i,n=!1){this.ctx.save(),this.ctx.scale(i,i),this.ctx.translate(-e.x,-e.y);const s=t.selected?{...t,selected:!1}:t;n?this.paintGhost(s,1.5):this.paintShape(s),this.ctx.restore()}paintShape(t){this.ctx.save(),this.ctx.globalAlpha=1-t.transparency;const e=t.blur??0;e>0&&(this.ctx.filter=`blur(${(ng*e).toFixed(2)}px)`);const i=t.brightness??0;i>0&&this.paintDazzle(t,i),t.haloScale>0&&this.paintHalo(t),this.paintBase(t),this.ctx.restore(),t.selected&&this.paintSelectionHandles(t)}setStarPoints(t){this.starPoints=Math.max(0,Math.floor(t))}setRoll(t){this.roll=t}paintDazzle(t,e){const{x:i,y:n,width:s,height:r}=t.bounds,o=i+s/2,c=n+r/2,l=Math.max(s,r)/2,h=Math.max(l*(1+sg*e),og*e);if(h<=0)return;this.ctx.save(),this.ctx.globalCompositeOperation="lighter";const u=this.ctx.createRadialGradient(o,c,0,o,c,h);for(let d=0;d<=rg;d++){const f=d/rg,p=1/(1+24*f*f);this.ctx.globalAlpha=1,u.addColorStop(f,this.withAlpha(t.color,p*e*.55))}if(this.ctx.fillStyle=u,this.ctx.beginPath(),this.ctx.arc(o,c,h,0,2*Math.PI),this.ctx.fill(),this.starPoints>0){const d=l*(1+ag*e);this.ctx.lineWidth=Math.max(1,l*.12),this.ctx.lineCap="round";for(let f=0;f<this.starPoints;f++){const p=f/this.starPoints*Math.PI*2+this.roll,v=o+Math.cos(p)*d,m=c+Math.sin(p)*d,g=this.ctx.createLinearGradient(o,c,v,m);g.addColorStop(0,this.withAlpha(t.color,e*.55)),g.addColorStop(.35,this.withAlpha(t.color,e*.22)),g.addColorStop(1,this.withAlpha(t.color,0)),this.ctx.strokeStyle=g,this.ctx.beginPath(),this.ctx.moveTo(o,c),this.ctx.lineTo(v,m),this.ctx.stroke()}}this.ctx.restore()}dazzledFill(t,e){if(e<=0)return t.color;const i=/^#([0-9a-f]{6})$/i.exec(t.color.trim());if(!i)return t.color;const n=Number.parseInt(i[1],16),s=r=>Math.round(r+(255-r)*e);return`rgb(${s(n>>16&255)}, ${s(n>>8&255)}, ${s(n&255)})`}withAlpha(t,e){const i=Math.max(0,Math.min(1,e)),n=/^#([0-9a-f]{6})$/i.exec(t.trim());if(!n)return t;const s=Number.parseInt(n[1],16);return`rgba(${s>>16&255}, ${s>>8&255}, ${s&255}, ${i.toFixed(3)})`}paintBase(t){this.ctx.fillStyle=this.dazzledFill(t,t.brightness??0),this.tracePath(t),this.ctx.fill()}paintGhost(t,e){this.ctx.save(),this.tracePath(t),this.ctx.setLineDash([e*3,e*2]),this.ctx.lineWidth=e,this.ctx.strokeStyle=t.color,this.ctx.stroke(),this.ctx.restore()}tracePath(t){if(this.ctx.beginPath(),t.kind==="oval"){const{x:e,y:i,width:n,height:s}=t.bounds,r=n/2,o=s/2;this.ctx.ellipse(e+r,i+o,r,o,t.angle,0,2*Math.PI)}else{const{x:e,y:i,width:n,height:s}=t.bounds;this.ctx.save(),this.ctx.translate(e+n/2,i+s/2),this.ctx.rotate(t.angle),this.ctx.translate(-n/2,-s/2),t.points.forEach((r,o)=>{o===0?this.ctx.moveTo(r.x,r.y):this.ctx.lineTo(r.x,r.y)}),this.ctx.closePath(),this.ctx.restore()}}paintHalo(t){this.ctx.save(),this.ctx.shadowColor=t.color,this.ctx.shadowBlur=ig*t.haloScale,this.paintBase(t),this.ctx.restore()}paintSelectionHandles(t){this.paintHandleFrame(Dn.handlePointsFor(t),{includeRotate:!0}),t.kind==="polygon"&&this.paintVertexHandles(t)}paintVertexHandles(t){this.ctx.fillStyle="#39f";for(const e of Dn.vertexPointsFor(t))this.ctx.beginPath(),this.ctx.ellipse(e.x,e.y,ys,ys,0,0,2*Math.PI),this.ctx.fill()}paintMemberOutline(t){this.paintOutline(Dn.handlePointsFor(t))}paintSelectionOnly(t){this.paintSelectionHandles(t)}paintPictureFrame(t,e,i){const n=this.ctx;if(n.save(),t&&t.length===4){n.strokeStyle="#39f",n.lineWidth=1.5,n.setLineDash([6,4]),n.beginPath(),n.moveTo(t[0].x,t[0].y);for(const s of t.slice(1))n.lineTo(s.x,s.y);n.closePath(),n.stroke(),n.setLineDash([])}for(const s of e){const r=al.landmarkColour(s.residualDeg),o=s.selected?3:2;s.selected&&(n.strokeStyle="#fff",n.lineWidth=o+3,n.beginPath(),n.ellipse(s.picture.x,s.picture.y,ys+2,ys+2,0,0,2*Math.PI),n.stroke()),s.scene&&(n.strokeStyle=r,n.lineWidth=1,n.beginPath(),n.moveTo(s.picture.x,s.picture.y),n.lineTo(s.scene.x,s.scene.y),n.stroke(),n.fillStyle=r,n.beginPath(),n.ellipse(s.scene.x,s.scene.y,ys,ys,0,0,2*Math.PI),n.fill()),n.strokeStyle=r,n.lineWidth=o,n.beginPath(),n.ellipse(s.picture.x,s.picture.y,ys+2,ys+2,0,0,2*Math.PI),n.stroke(),this.paintLabel(s.label,s.picture.x+ys+5,s.picture.y-ys-2,r)}i&&this.paintLabel(i,8,8,"#fff",13),n.restore()}static landmarkColour(t){return t===void 0?"#ffb000":t<=1?"#3c3":t<=3?"#ffb000":"#f33"}paintLabel(t,e,i,n,s=11){const r=this.ctx;r.save(),r.font=`${s}px system-ui, sans-serif`,r.textBaseline="top";const o=r.measureText(t).width;r.fillStyle="rgba(0, 0, 0, 0.6)",r.fillRect(e-3,i-2,o+6,s+4),r.fillStyle=n,r.fillText(t,e,i),r.restore()}paintGroupHandles(t){this.paintHandleFrame(Dn.handlePointsFor({bounds:t,angle:0}),{includeRotate:!0})}paintOutline(t){this.ctx.strokeStyle="lightgray",this.ctx.beginPath(),this.ctx.moveTo(t.nw.x,t.nw.y),this.ctx.lineTo(t.ne.x,t.ne.y),this.ctx.lineTo(t.se.x,t.se.y),this.ctx.lineTo(t.sw.x,t.sw.y),this.ctx.closePath(),this.ctx.stroke()}paintHandleFrame(t,{includeRotate:e}){this.paintOutline(t),this.ctx.fillStyle="lightgray";for(const i of xM){const n=t[i];this.ctx.fillRect(n.x-Ol,n.y-Ol,$f,$f)}e&&(this.ctx.beginPath(),this.ctx.moveTo(t.n.x,t.n.y),this.ctx.lineTo(t.rotate.x,t.rotate.y),this.ctx.stroke(),this.ctx.beginPath(),this.ctx.ellipse(t.rotate.x,t.rotate.y,Ol+1,Ol+1,0,0,2*Math.PI),this.ctx.fill())}}const cg=.05,lg=.08,hg=2,ug=3,eb=14,ib=.02;class nb{context;voice;voiceToken=0;buffers=new Map;noiseBuffer;crackleBuffer;requested;level=1;master;output(t){return this.master||(this.master=t.createGain(),this.master.gain.value=this.level,this.master.connect(t.destination)),this.master}setLevel(t){this.level=t,this.master&&(this.master.gain.value=t)}resume(){if(!this.context){if(typeof AudioContext>"u")return;try{this.context=new AudioContext}catch(t){console.warn("SightingAudio: Web Audio unavailable, the sighting stays silent:",t);return}}Oa.unlock(this.context)}setSound(t){if(this.requested=t,!this.context)return;const e=this.keyFor(t);if(!e){this.silence();return}if(this.voice?.key!==e){this.stopVoice();const i=++this.voiceToken;e.startsWith("src:")?this.buildRecordedVoice(t.src,e,i):this.voice=this.buildSynthesizedVoice(t,e)}this.applyTo(this.voice,t)}silence(){this.voiceToken++,this.stopVoice()}dispose(){this.silence(),this.context?.close(),this.context=void 0,this.master=void 0,this.buffers.clear(),this.noiseBuffer=void 0,this.crackleBuffer=void 0}keyFor(t){if(!(t.volume<=0))return t.src?`src:${t.src}`:t.kind==="none"?void 0:t.kind}applyTo(t,e){const i=this.context;if(!t||!i)return;const n=i.currentTime;t.volumeParam.setTargetAtTime(Math.max(0,Math.min(1,e.volume))*t.gainScale,n,cg);for(const{param:s,ratio:r}of t.pitch)s.setTargetAtTime(Math.min(e.pitchHz*r,i.sampleRate/2-1),n,cg)}buildSynthesizedVoice(t,e){const i=this.context;if(i)switch(t.kind){case"hum":return this.buildHum(i,e);case"whistle":return this.buildWhistle(i,e);case"rumble":return this.buildRumble(i,e);case"crackle":return this.buildCrackle(i,e);default:return}}buildHum(t,e){const i=t.createOscillator();i.type="sawtooth";const n=t.createOscillator();n.type="sawtooth";const s=t.createBiquadFilter();s.type="lowpass",s.Q.value=1;const r=t.createGain();return r.gain.value=0,i.connect(s),n.connect(s),s.connect(r).connect(this.output(t)),i.start(),n.start(),{key:e,nodes:[s,r],sources:[i,n],volumeParam:r.gain,gainScale:.16,pitch:[{param:i.frequency,ratio:1},{param:n.frequency,ratio:1.006},{param:s.frequency,ratio:6}]}}buildWhistle(t,e){const i=t.createOscillator();i.type="sine";const n=t.createOscillator();n.type="sine",n.frequency.value=5;const s=t.createGain(),r=t.createGain();return r.gain.value=0,n.connect(s).connect(i.frequency),i.connect(r).connect(this.output(t)),i.start(),n.start(),{key:e,nodes:[s,r],sources:[i,n],volumeParam:r.gain,gainScale:.22,pitch:[{param:i.frequency,ratio:1},{param:s.gain,ratio:.012}]}}buildRumble(t,e){const i=t.createBufferSource();i.buffer=this.brownNoise(t),i.loop=!0;const n=t.createBiquadFilter();n.type="lowpass",n.Q.value=.8;const s=t.createGain();return s.gain.value=0,i.connect(n).connect(s).connect(this.output(t)),i.start(),{key:e,nodes:[n,s],sources:[i],volumeParam:s.gain,gainScale:1.4,pitch:[{param:n.frequency,ratio:1}]}}buildCrackle(t,e){const i=t.createBufferSource();i.buffer=this.whiteNoise(t),i.loop=!0;const n=t.createBiquadFilter();n.type="bandpass",n.Q.value=1.2;const s=t.createGain();s.gain.value=0;const r=t.createBufferSource();r.buffer=this.crackleEnvelope(t),r.loop=!0;const o=t.createGain();return o.gain.value=0,r.connect(o).connect(s.gain),i.connect(n).connect(s).connect(this.output(t)),i.start(),r.start(),{key:e,nodes:[n,s,o],sources:[i,r],volumeParam:o.gain,gainScale:.9,pitch:[{param:n.frequency,ratio:4}]}}async buildRecordedVoice(t,e,i){const n=this.context;if(!n)return;let s;try{s=await this.getBuffer(t)}catch(c){console.warn("SightingAudio: the recorded sound failed to load, staying silent:",c);return}if(i!==this.voiceToken||!this.context)return;const r=n.createBufferSource();r.buffer=s,r.loop=!0;const o=n.createGain();o.gain.value=0,r.connect(o).connect(this.output(n)),r.start(),this.voice={key:e,nodes:[o],sources:[r],volumeParam:o.gain,gainScale:1,pitch:[]},this.requested&&this.applyTo(this.voice,this.requested)}async getBuffer(t){const e=this.context;if(!e)throw new Error("SightingAudio: AudioContext not ready — resume() must be called first");let i=this.buffers.get(t);return i||(i=fetch(t).then(n=>{if(!n.ok)throw new Error(`Audio fetch failed (${n.status}): ${t}`);return n.arrayBuffer()}).then(n=>e.decodeAudioData(n)),this.buffers.set(t,i)),i}whiteNoise(t){if(!this.noiseBuffer){const e=t.createBuffer(1,Math.floor(t.sampleRate*hg),t.sampleRate),i=e.getChannelData(0);for(let n=0;n<i.length;n++)i[n]=Math.random()*2-1;this.noiseBuffer=e}return this.noiseBuffer}brownNoise(t){const e=t.createBuffer(1,Math.floor(t.sampleRate*hg),t.sampleRate),i=e.getChannelData(0);let n=0,s=0;for(let r=0;r<i.length;r++)n=(n+.02*(Math.random()*2-1))/1.02,i[r]=n,s=Math.max(s,Math.abs(n));if(s>0)for(let r=0;r<i.length;r++)i[r]/=s;return e}crackleEnvelope(t){if(!this.crackleBuffer){const e=t.createBuffer(1,Math.floor(t.sampleRate*ug),t.sampleRate),i=e.getChannelData(0),n=Math.max(1,Math.floor(ib*t.sampleRate)),s=Math.round(ug*eb);for(let r=0;r<s;r++){const o=Math.floor(Math.random()*i.length),c=.4+Math.random()*.6;for(let l=0;l<n&&o+l<i.length;l++)i[o+l]=Math.max(i[o+l],c*(1-l/n))}this.crackleBuffer=e}return this.crackleBuffer}stopVoice(){const t=this.voice,e=this.context;if(this.voice=void 0,!t||!e)return;const i=e.currentTime;t.volumeParam.cancelScheduledValues(i),t.volumeParam.setTargetAtTime(0,i,lg/3);const n=i+lg;for(const s of t.sources){s.onended=()=>{s.disconnect();for(const r of t.nodes)r.disconnect()};try{s.stop(n)}catch{s.disconnect();for(const r of t.nodes)r.disconnect()}}}}function Wc(a){return[...a].sort((t,e)=>t.t-e.t)}function Md(a,t){let e;for(const i of Wc(a)){if(i.t>t)break;e=i}return e}const yd=Math.PI/180,Ll=180/Math.PI;class rr{constructor(t,e,i){this.kind=t,this.canvasHeightPx=e,this.fovDeg=i;const n=i*yd/2;this.focalPx=t==="equidistant"?e/2/n:e/2/Math.tan(n)}focalPx;static of(t,e,i){return new rr(t.projection,e,i)}degToPx(t){const e=t*yd;return this.kind==="equidistant"?this.focalPx*e:2*this.focalPx*Math.tan(e/2)}pxToDeg(t){return this.kind==="equidistant"?t/this.focalPx*Ll:2*Math.atan(t/(2*this.focalPx))*Ll}angleDegToRadiusPx(t){const e=t*yd;return this.kind==="equidistant"?this.focalPx*e:this.focalPx*Math.tan(e)}halfWidthAngleDeg(t){return this.radiusPxToAngleDeg(this.canvasHeightPx*t/2)}radiusPxToAngleDeg(t){return this.kind==="equidistant"?t/this.focalPx*Ll:Math.atan(t/this.focalPx)*Ll}ofBounds(t){return{widthDeg:this.pxToDeg(t.width),heightDeg:this.pxToDeg(t.height)}}toBoundsSize(t){return{width:this.degToPx(t.widthDeg),height:this.degToPx(t.heightDeg)}}widthPx(t){return this.degToPx(Fe.angularWidthDeg(t))}}class xn{static fovOf(t,e){return Ze(t,e)?.fovDeg??bi.fieldOfViewDeg(t.instrument)}static toAngular(t){this.eachKeyframe(t,(e,i)=>({...e,angular:i.ofBounds(e.bounds)}))}static toBounds(t){this.eachKeyframe(t,(e,i)=>{if(!e.angular)return e;const{width:n,height:s}=i.toBoundsSize(e.angular),r={x:e.bounds.x+(e.bounds.width-n)/2,y:e.bounds.y+(e.bounds.height-s)/2,width:n,height:s};if(e.kind!=="polygon")return{...e,bounds:r};const o=e.bounds.width===0?1:n/e.bounds.width,c=e.bounds.height===0?1:s/e.bounds.height;return{...e,bounds:r,points:e.points.map(l=>({x:l.x*o,y:l.y*c}))}})}static toAim(t){this.eachKeyframe(t,(e,i,n)=>{const s=e.aim&&this.positionOf(t,e.aim,e.bounds,i,n);if(s&&Math.abs(s.x-e.bounds.x)<xn.UNMOVED_PX&&Math.abs(s.y-e.bounds.y)<xn.UNMOVED_PX)return e;const r=this.aimFrom(t,i,n,e.bounds);return r?{...e,aim:r}:e})}static UNMOVED_PX=.01;static aimOf(t,e,i){const n=rr.of(t.instrument,Fe.CANVAS_HEIGHT_PX,this.fovOf(t,e));return this.aimFrom(t,n,Ze(t,e),i)}static aimFrom(t,e,i,n){if(i?.headingDeg===void 0)return;const s=this.frameCentre(t),r=e.radiusPxToAngleDeg(n.x+n.width/2-s.x),o=e.radiusPxToAngleDeg(s.y-(n.y+n.height/2));return{azimuthDeg:((i.headingDeg+r)%360+360)%360,altitudeDeg:i.pitchDeg+o}}static toPosition(t){this.eachKeyframe(t,(e,i,n)=>{const s=e.aim&&this.positionOf(t,e.aim,e.bounds,i,n);return s?{...e,bounds:{...e.bounds,...s}}:e})}static positionOf(t,e,i,n,s){if(s?.headingDeg===void 0)return;const r=this.frameCentre(t),o=this.shortestArc(e.azimuthDeg-s.headingDeg),c=e.altitudeDeg-s.pitchDeg;return{x:r.x+this.offAxisPx(n,o)-i.width/2,y:r.y-this.offAxisPx(n,c)-i.height/2}}static frameCentre(t){return{x:bi.frameWidthPx(t.instrument,Fe.CANVAS_HEIGHT_PX)/2,y:Fe.CANVAS_HEIGHT_PX/2}}static shortestArc(t){return(t%360+540)%360-180}static offAxisPx(t,e){return Math.abs(e)>=xn.OFF_CANVAS_DEG?Math.sign(e)*xn.OFF_CANVAS_PX:t.angleDegToRadiusPx(e)}static OFF_CANVAS_DEG=89;static OFF_CANVAS_PX=1e5;static reproject(t,e,i){const n=bi.frameWidthPx(e,Fe.CANVAS_HEIGHT_PX)/2,s=bi.frameWidthPx(t.instrument,Fe.CANVAS_HEIGHT_PX)/2,r=Fe.CANVAS_HEIGHT_PX/2;for(const o of[...t.timeline.allKeyframes]){const c=this.fovOf(t,o.t),l=i?.get(o.t)??c,h=rr.of(e,Fe.CANVAS_HEIGHT_PX,l),u=rr.of(t.instrument,Fe.CANVAS_HEIGHT_PX,c);t.timeline.addKeyframe(o.t,o.shapes.map(d=>{const{bounds:f}=d.shape,p=f.x+f.width/2-n,v=f.y+f.height/2-r,m=Math.hypot(p,v),g=m===0?1:u.angleDegToRadiusPx(h.radiusPxToAngleDeg(m))/m,b={...f,x:s+p*g-f.width/2,y:r+v*g-f.height/2};return{...d,shape:{...d.shape,bounds:b}}}))}this.toBounds(t)}static eachKeyframe(t,e){const{timeline:i}=t;for(const n of[...i.allKeyframes]){const s=Ze(t,n.t),r=this.fovOf(t,n.t),o=rr.of(t.instrument,Fe.CANVAS_HEIGHT_PX,r);i.addKeyframe(n.t,n.shapes.map(c=>({...c,shape:e(c.shape,o,s)})))}}}function sb(a){return hn.restore(rb(a),a.provenance)}function rb(a){return xn.toAngular(a),xn.toAim(a),{version:1,id:a.id,time:a.event.time,endTime:a.event.endTime,durationSeconds:a.event.durationSeconds,durationText:a.event.durationText,utcOffsetHours:a.event.utcOffsetHours,timeZone:a.event.timeZone,place:a.event.place,observer:a.observer,account:a.account,sources:a.sources?.length?a.sources:void 0,sway:a.sway,vehicle:a.vehicle,description:a.event.description,tags:a.event.tags,timeline:a.timeline.toJSON(),observerTrack:a.observerTrack.toJSON(),weatherTrack:a.weatherTrack.toJSON(),soundTrack:a.soundTrack.toJSON(),weather:a.weather,decor:a.decor,milestones:a.milestones.length>0?a.milestones:void 0,references:a.references.length>0?a.references:void 0,roads:a.roads.length>0?a.roads:void 0,traces:a.traces.length>0?a.traces:void 0,weatherSource:a.weatherSource,instrument:a.instrumentId,exposureSeconds:a.exposureSeconds,iso:a.iso,lightPollution:a.lightPollution,observerMap:a.observerMap,interpretation:a.interpretation}}function ab(a){const{recording:t,provenance:e}=hn.strip(a),i=ob(t);return i.provenance=e,i}function ob(a){const t=[],e=new td({eventType:"sighting",time:a.time,endTime:a.endTime,durationSeconds:a.durationSeconds,durationText:a.durationText,utcOffsetHours:a.utcOffsetHours,timeZone:a.timeZone,place:a.place,description:a.description,tags:a.tags},Ku.fromJSON(a.timeline,t),a.observerTrack?el.fromJSON(a.observerTrack):new el,a.weatherTrack?il.fromJSON(a.weatherTrack):new il,a.soundTrack?nl.fromJSON(a.soundTrack):new nl,a.observer&&{id:a.observer.id,title:a.observer.title,lastName:a.observer.lastName,firstNames:a.observer.firstNames},a.id,a.weather,a.decor??[],a.weatherSource,a.instrument,a.exposureSeconds??a.observerTrack?.keyframes.map(i=>i.pose.exposureSeconds).find(i=>i!==void 0),Wc(a.milestones??[]),a.references??[],a.roads??[],a.traces??[]);return e.account=a.account,e.sources=a.sources,e.sway=a.sway,e.iso=a.iso,e.lightPollution=a.lightPollution,e.observerMap=a.observerMap,e.vehicle=a.vehicle,e.interpretation=a.interpretation,e.loadIssues=t,xn.toBounds(e),xn.toPosition(e),e}class Zo{static EN={"unknown-key":"{path}: unknown key, ignored","wrong-type":"{path}: expected {expected}, found {found}","not-in-list":"{path}: {found} is not one of {expected}",defaulted:"{path}: missing, {expected} used",unplaced:"{path}: no aim (and no bounds), drawn at the middle of the view",unsized:"{path}: no angular size (and no bounds), drawn one pixel wide","pixels-over-angles":"{path}: bounds restated without aim or angular, so the shape follows the pixels"};static text(t,e=Zo.EN){return e[t.kind].replace("{path}",t.path).replace("{expected}",t.expected??"").replace("{found}",t.found??"")}static warn(t,e){if(t.length===0)return;const i=t.map(n=>` ${Zo.text(n)}`);console.warn(`UFO@home: ${t.length} problem(s) in ${e??"this recording"}:
2181
2181
  ${i.join(`
2182
- `)}`)}}class ts{constructor(t){this.format=t}issues(t){const e=[];return this.object(t,this.format,"",e),e}object(t,e,i,n){if(!ts.isObject(t)){n.push({kind:"wrong-type",path:i||"(the file)",expected:"object",found:ts.typeOf(t)});return}for(const[s,r]of Object.entries(t)){const o=i?`${i}.${s}`:s,c=e[s];c?this.field(r,c,o,n):n.push({kind:"unknown-key",path:o})}}field(t,e,i,n){if(ts.isStated(t)){this.field(t.value,e,i,n);return}if(!(e.loose||t===void 0||t===null))switch(e.type){case"enum":(typeof t!="string"||!e.values?.includes(t))&&n.push({kind:"not-in-list",path:i,expected:(e.values??[]).map(s=>`"${s}"`).join(", "),found:JSON.stringify(t)});return;case"object":e.fields?this.object(t,e.fields,i,n):ts.isObject(t)||n.push({kind:"wrong-type",path:i,expected:"object",found:ts.typeOf(t)});return;case"array":Array.isArray(t)?e.fields&&t.forEach((s,r)=>{const o=ts.isStated(s)?s.value:s;this.object(o,e.fields,`${i}.${r}`,n)}):n.push({kind:"wrong-type",path:i,expected:"array",found:ts.typeOf(t)});return;default:typeof t!==e.type&&n.push({kind:"wrong-type",path:i,expected:e.type,found:ts.typeOf(t)})}}static isObject(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}static isStated(t){return ts.isObject(t)&&"value"in t&&Object.keys(t).every(e=>e==="value"||e==="basis"||e==="rationale")}static typeOf(t){return Array.isArray(t)?"array":t===null?"null":typeof t}}class as{static PIXELS_PER_INSTANT=2;static INSTANTS_PER_FLASH=2;static MAX_INSTANTS=512;static windowEndingAt(t,e){const i=Number.isFinite(e)?Math.max(0,e):0,n=Math.max(0,t-i*1e3),s=Math.max(0,t-n);return{fromMs:n,toMs:t,ms:s,seconds:s/1e3}}static instants(t,e,i,n,s){if(!(n>0))return 1;const r=s>0?as.travelDegOver(t,e,i,i+n*1e3)/s/as.PIXELS_PER_INSTANT:0,o=as.flashesOver(t,n)*as.INSTANTS_PER_FLASH,c=Math.ceil(Math.max(r,o));return c<2?1:Math.min(as.MAX_INSTANTS,c)}static travelDegOver(t,e,i,n){let s=0;for(const r of t){if(!r.track||r.track.length<2)continue;const o=as.directionAt(r,e,i),c=as.directionAt(r,e,n),l=Math.min(1,Math.max(-1,o.x*c.x+o.y*c.y+o.z*c.z));s=Math.max(s,Math.acos(l)*180/Math.PI)}return s}static flashesOver(t,e){let i=0;for(const n of t)for(const s of n.lights??[])s.pattern.kind==="flash"&&(i=Math.max(i,s.pattern.perMinute));return i/60*e}static directionAt(t,e,i){const n=Hr(t,i),s=n.eastM,r=n.altitudeM-e,o=n.northM,c=Math.hypot(s,r,o);return c===0?{x:0,y:1,z:0}:{x:s/c,y:r/c,z:o/c}}}const Ap=["en","fr","es","it"],cb={en:()=>je(()=>Promise.resolve().then(()=>fb),void 0,import.meta.url).then(a=>a.ufoMessages_en),fr:()=>je(()=>import("./UfoMessages_fr-bJNAf-AU.js"),[],import.meta.url).then(a=>a.ufoMessages_fr),es:()=>je(()=>import("./UfoMessages_es-LFW_B5H2.js"),[],import.meta.url).then(a=>a.ufoMessages_es),it:()=>je(()=>import("./UfoMessages_it-B-jnc4M-.js"),[],import.meta.url).then(a=>a.ufoMessages_it)};function lb(a){return cb[a]()}const hb={en:()=>je(()=>Promise.resolve().then(()=>eI),void 0,import.meta.url).then(a=>a.sightingMessages_en),fr:()=>je(()=>import("./SightingMessages_fr-DXps3C_h.js"),[],import.meta.url).then(a=>a.sightingMessages_fr),es:()=>je(()=>import("./SightingMessages_es-DD2m_7j8.js"),[],import.meta.url).then(a=>a.sightingMessages_es),it:()=>je(()=>import("./SightingMessages_it-Du_Kn9cp.js"),[],import.meta.url).then(a=>a.sightingMessages_it)};function ub(a){return hb[a]()}function db(a){switch(a){case"fr":return je(()=>import("./TagNames_fr-Dnqq6HQ5.js"),[],import.meta.url).then(t=>t.tagNames_fr);case"es":return je(()=>import("./TagNames_es-BfnMpc3D.js"),[],import.meta.url).then(t=>t.tagNames_es);case"it":return je(()=>import("./TagNames_it-n6E4EGYO.js"),[],import.meta.url).then(t=>t.tagNames_it);default:return Promise.resolve({})}}function bM(a){switch(a){case"fr":return je(()=>import("./SceneNames_fr-BFN6x9Z7.js"),[],import.meta.url).then(t=>t.sceneNames_fr);case"es":return je(()=>import("./SceneNames_es-BuZsPlTw.js"),[],import.meta.url).then(t=>t.sceneNames_es);case"it":return je(()=>import("./SceneNames_it-BOuH3VIw.js"),[],import.meta.url).then(t=>t.sceneNames_it);default:return Promise.resolve(void 0)}}const SM={play:"Play",pause:"Pause",noDuration:"No observation duration",currentPosition:"Current position",duration:"Duration",switchToElapsed:"click to show elapsed time",switchToClockTime:"click to show the time of day",fullscreen:"Fullscreen",exitFullscreen:"Exit fullscreen",mute:"Mute",unmute:"Unmute",noSound:"No sound recorded",moments:"Moments",moreControls:"More controls",fewerControls:"Fewer controls",showObserverMap:"Show where the observer was",hideObserverMap:"Hide where the observer was",mapImageryUnavailable:"Aerial imagery unavailable",zoomMapIn:"Zoom in",zoomMapOut:"Zoom out",fitMap:"Back to the whole path",placeObserverHere:"Put the observer here",showReferences:"Show the pictures of the place",hideReferences:"Hide the pictures of the place",showTraces:"Show the investigator's lines",hideTraces:"Hide the investigator's lines",referenceOpacity:"Picture opacity",referencesMenu:"Pictures of the place",showMilestones:"Show the account's moments",hideMilestones:"Hide the account's moments",observerHere:"The observer, here",decorHere:"Scenery",recordingIssues:"{count} problem(s) in this recording: it may not play as its author meant",issueTemplates:Zo.EN},fb=Object.freeze(Object.defineProperty({__proto__:null,ufoMessages_en:SM},Symbol.toStringTag,{value:"Module"})),wM=Math.PI/180,pb=180/Math.PI,mb=256,_M=19,gb=1.25;function EM(a,t){return 156543.03392*Math.cos(a*wM)/2**t}function AM(a,t){return EM(a,t)*mb}function vb(a,t){let e=0;for(;e<_M&&AM(a,e+1)>=t;)e++;return e}function TM(a,t){return AM(a,t)}function Mb(a,t){const e=t*gb;let i=0;for(;i<_M&&EM(a,i)>e;)i++;return i}function Bh(a){const t=a*wM;return(1-Math.log(Math.tan(t)+1/Math.cos(t))/Math.PI)/2}function RM(a,t,e){const i=2**e;return{x:(a+180)/360*i,y:Bh(t)*i}}function DM(a,t,e){const i=Bh(a.north),n=Bh(a.south);return{x:(t-a.west)/(a.east-a.west),y:(Bh(e)-i)/(n-i)}}function yb(a,t,e){const{x:i,y:n}=RM(a,t,e);return{x:Math.floor(i),y:Math.floor(n),z:e}}function xb(a){const t=2**a.z,e=a.x/t*360-180,i=(a.x+1)/t*360-180,n=dg(a.y,t);return{south:dg(a.y+1,t),north:n,west:e,east:i}}function dg(a,t){const e=a/t;return Math.atan(Math.sinh(Math.PI*(1-2*e)))*pb}function IM(a,t,e,i){const n=yb(a,t,e),s=Math.floor(i/2),r=[];for(let l=-s;l<=s;l++)for(let h=-s;h<=s;h++)r.push({x:n.x+h,y:n.y+l,z:e});const o=r.map(xb),c={south:Math.min(...o.map(l=>l.south)),north:Math.max(...o.map(l=>l.north)),west:Math.min(...o.map(l=>l.west)),east:Math.max(...o.map(l=>l.east))};return{tiles:r,bounds:c}}const bb="#2ec4ff";class la{constructor(t){this.ctx=t}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(t,e){let i,n=1/0;for(const s of this.targets){const r=Math.hypot(s.x-t,s.y-e);r>s.radius||r>n||(i=s,n=r)}return i}get width(){return this.ctx.canvas.width}get height(){return this.ctx.canvas.height}paint(t){const{ctx:e}=this;e.save(),this.targets=[],e.clearRect(0,0,this.width,this.height),this.paintGround(t),this.paintNight(t.nightFraction),this.paintPath(t),this.paintTraces(t),t.position?(this.paintCone(t,t.position),this.paintDecor(t),this.paintMarkers(t),this.paintObserver(t,t.position)):(this.paintDecor(t),this.paintMarkers(t)),this.paintNorth(),this.paintFooter(t.bounds,t.attribution),e.restore()}toCanvas(t,e,i){const n=DM(t,i,e);return{x:n.x*this.width,y:n.y*this.height}}paintGround(t){const{ctx:e}=this;e.fillStyle="#1d2321",e.fillRect(0,0,this.width,this.height);const i=t.imagery;if(!i)return;const n=this.toCanvas(t.bounds,i.bounds.north,i.bounds.west),s=this.toCanvas(t.bounds,i.bounds.south,i.bounds.east);e.drawImage(i.source,n.x,n.y,s.x-n.x,s.y-n.y)}paintNight(t=0){if(t<=0)return;const{ctx:e}=this;e.save(),e.fillStyle=`rgba(6, 12, 30, ${Math.min(t,1)*.78})`,e.fillRect(0,0,this.width,this.height),e.restore()}paintDecor(t){const{ctx:e}=this;for(const i of t.decor){const n=this.toCanvas(t.bounds,i.lat,i.lng);if(i.label&&this.targets.push({kind:"decor",label:i.label,lat:i.lat,lng:i.lng,x:n.x,y:n.y,radius:7}),e.beginPath(),e.rect(n.x-3.5,n.y-3.5,7,7),e.fillStyle="rgba(120, 220, 255, 0.85)",e.fill(),e.lineWidth=1.5,e.strokeStyle="rgba(0, 0, 0, 0.7)",e.stroke(),i.headingDeg===void 0)continue;const s=(i.headingDeg-90)*Math.PI/180;e.beginPath(),e.moveTo(n.x,n.y),e.lineTo(n.x+Math.cos(s)*10,n.y+Math.sin(s)*10),e.lineWidth=3,e.strokeStyle="rgba(0, 0, 0, 0.6)",e.stroke(),e.lineWidth=1.5,e.strokeStyle="rgba(120, 220, 255, 0.9)",e.stroke()}}paintPath(t){if(!t.path.moved)return;const{ctx:e}=this,i=t.path.points.map(n=>this.toCanvas(t.bounds,n.lat,n.lng));e.beginPath(),e.moveTo(i[0].x,i[0].y);for(const n of i.slice(1))e.lineTo(n.x,n.y);e.lineJoin="round",e.lineCap="round",e.strokeStyle="rgba(0, 0, 0, 0.65)",e.lineWidth=5,e.stroke(),e.strokeStyle="rgba(255, 255, 255, 0.9)",e.lineWidth=2,e.stroke()}paintTraces(t){const{ctx:e}=this;for(const i of t.traces??[]){const n=i.points.map(r=>this.toCanvas(t.bounds,r.lat,r.lng));if(n.length===0)continue;const s=i.color??bb;if(i.kind==="point")e.beginPath(),e.moveTo(n[0].x,n[0].y-6),e.lineTo(n[0].x+6,n[0].y),e.lineTo(n[0].x,n[0].y+6),e.lineTo(n[0].x-6,n[0].y),e.closePath(),e.fillStyle=s,e.fill(),e.lineWidth=1.5,e.strokeStyle="rgba(0, 0, 0, 0.8)",e.stroke();else{e.beginPath(),e.moveTo(n[0].x,n[0].y);for(const r of n.slice(1))e.lineTo(r.x,r.y);i.kind==="polygon"&&e.closePath(),e.lineJoin="round",e.setLineDash([]),e.strokeStyle="rgba(0, 0, 0, 0.65)",e.lineWidth=4.5,e.stroke(),e.setLineDash([9,5]),e.strokeStyle=s,e.lineWidth=2.5,e.stroke(),e.setLineDash([])}if(i.label){e.font="11px sans-serif",e.textAlign="left",e.textBaseline="middle";let r=n[0];if(i.kind==="line"&&t.position){const o=this.toCanvas(t.bounds,t.position.lat,t.position.lng);r=n.reduce((c,l)=>Math.hypot(l.x-o.x,l.y-o.y)>Math.hypot(c.x-o.x,c.y-o.y)?l:c)}this.paintOutlinedText(i.label,r.x+9,r.y-9)}}}paintCone(t,e){const{headingDeg:i,coneHalfAngleDeg:n}=t;if(i===void 0||n===void 0)return;const{ctx:s}=this,r=this.toCanvas(t.bounds,e.lat,e.lng),o=Math.hypot(this.width,this.height),c=(i-90)*Math.PI/180,l=n*Math.PI/180;s.save(),s.beginPath(),s.moveTo(r.x,r.y),s.arc(r.x,r.y,o,c-l,c+l),s.closePath();const h=s.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)"),s.fillStyle=h,s.fill(),s.restore()}paintMarkers(t){const{ctx:e}=this;e.textAlign="center",e.textBaseline="middle",e.font="bold 10px sans-serif";for(const i of[...t.markers].sort((n,s)=>Number(n.current)-Number(s.current))){const n=this.toCanvas(t.bounds,i.lat,i.lng);this.targets.push({kind:"milestone",label:i.note?`${i.label} — ${i.note}`:i.label,lat:i.lat,lng:i.lng,t:i.t,x:n.x,y:n.y,radius:la.MARKER_RADIUS_PX}),e.beginPath(),e.arc(n.x,n.y,la.MARKER_RADIUS_PX,0,Math.PI*2),e.fillStyle=i.current?"rgba(255, 224, 130, 0.95)":"rgba(0, 0, 0, 0.55)",e.fill(),e.lineWidth=2,e.strokeStyle="rgba(255, 255, 255, 0.9)",e.stroke(),e.fillStyle=i.current?"#1d2321":"#fff",e.fillText(i.label,n.x,n.y)}}paintObserver(t,e){const{ctx:i}=this,n=this.toCanvas(t.bounds,e.lat,e.lng);t.observerLabel&&this.targets.push({kind:"observer",label:t.observerLabel,lat:e.lat,lng:e.lng,x:n.x,y:n.y,radius:8});const s=t.markers.some(r=>{if(!r.current)return!1;const o=si(r.lat,r.lng,e.lat,e.lng);return Math.hypot(o.x,o.z)<=la.ON_MARKER_M});i.beginPath(),i.arc(n.x,n.y,s?la.MARKER_RADIUS_PX+2.5:5.5,0,Math.PI*2),s||(i.fillStyle="#ff5a3c",i.fill()),i.lineWidth=4,i.strokeStyle="rgba(0, 0, 0, 0.5)",i.stroke(),i.lineWidth=s?3:2.5,i.strokeStyle=s?"#ff5a3c":"#fff",i.stroke()}paintNorth(){const{ctx:t}=this,e=this.width-14,i=16;t.beginPath(),t.moveTo(e,i-9),t.lineTo(e-4.5,i+5),t.lineTo(e,i+2),t.lineTo(e+4.5,i+5),t.closePath(),t.fillStyle="rgba(255, 255, 255, 0.92)",t.strokeStyle="rgba(0, 0, 0, 0.6)",t.lineWidth=1,t.fill(),t.stroke(),t.font="bold 9px sans-serif",t.textAlign="center",t.textBaseline="top",t.strokeText("N",e,i+6),t.fillText("N",e,i+6)}paintFooter(t,e){const{ctx:i}=this;i.font="9px sans-serif",i.textBaseline="bottom";const n=e?this.wrap(e,this.width-20):[];let s=this.height-4;i.textAlign="right";for(const f of n.slice().reverse())this.paintOutlinedText(f,this.width-6,s),s-=11;const r=(t.south+t.north)/2,c=Math.abs(si(r,t.east,r,t.west).x)/this.width,l=la.SCALE_STEPS_M.find(f=>f/c<=this.width/3);if(l===void 0)return;const h=l/c,u=8,d=s-3;i.lineWidth=3,i.strokeStyle="rgba(0, 0, 0, 0.6)",i.beginPath(),i.moveTo(u,d),i.lineTo(u+h,d),i.stroke(),i.lineWidth=1.5,i.strokeStyle="rgba(255, 255, 255, 0.95)",i.stroke(),i.textAlign="left",this.paintOutlinedText(l>=1e3?`${l/1e3} km`:`${l} m`,u,d-3)}paintOutlinedText(t,e,i){const{ctx:n}=this;n.lineWidth=3,n.strokeStyle="rgba(0, 0, 0, 0.75)",n.strokeText(t,e,i),n.fillStyle="#fff",n.fillText(t,e,i)}wrap(t,e){const i=[];let n="";for(const s of t.split(" ")){const r=n?`${n} ${s}`:s;n&&this.ctx.measureText(r).width>e?(i.push(n),n=s):n=r}return n&&i.push(n),i}}class ni{static MIN_ZOOM=.25;static MAX_ZOOM=64;zoom=1;centerX=.5;centerY=.5;get changed(){return this.zoom!==1||this.centerX!==.5||this.centerY!==.5}get zoomFactor(){return this.zoom}reset(){this.zoom=1,this.centerX=.5,this.centerY=.5}zoomAt(t,e,i){const n=Math.min(ni.MAX_ZOOM,Math.max(ni.MIN_ZOOM,this.zoom*i)),s=this.centerX+(t-.5)/this.zoom,r=this.centerY+(e-.5)/this.zoom;this.centerX=s-(t-.5)/n,this.centerY=r-(e-.5)/n,this.zoom=n}panBy(t,e){this.centerX-=t/this.zoom,this.centerY-=e/this.zoom}refit(t,e){if(!this.changed)return;const i=this.boundsWithin(t),n=ni.mercatorY01(e.north),s=ni.mercatorY01(e.south),r=ni.mercatorY01(i.north),o=ni.mercatorY01(i.south);this.zoom=(e.east-e.west)/(i.east-i.west),this.centerX=((i.west+i.east)/2-e.west)/(e.east-e.west),this.centerY=((r+o)/2-n)/(s-n)}keepInView(t,e,i){if(!this.changed)return!1;const n=this.boundsWithin(t),s=ni.mercatorY01(n.north),r=ni.mercatorY01(n.south),o=(e.lng-n.west)/(n.east-n.west),c=(ni.mercatorY01(e.lat)-s)/(r-s);return o>=i&&o<=1-i&&c>=i&&c<=1-i?!1:(this.panBy(.5-o,.5-c),!0)}boundsWithin(t){if(!this.changed)return t;const e=.5/this.zoom,i=ni.mercatorY01(t.north),n=ni.mercatorY01(t.south),s=t.east-t.west;return{west:t.west+(this.centerX-e)*s,east:t.west+(this.centerX+e)*s,north:ni.latitudeAt(i+(this.centerY-e)*(n-i)),south:ni.latitudeAt(i+(this.centerY+e)*(n-i))}}static including(t,e,i=3){const n=(t.north+t.south)/2,s=(t.east+t.west)/2,r=si(n,t.east,n,s).x;let o=r;for(const c of e){const{x:l,z:h}=si(c.lat,c.lng,n,s),u=Math.max(Math.abs(l),Math.abs(h));u<=r*i&&(o=Math.max(o,u*1.15))}return o<=r?t:{north:Nn(0,-o,n,s).lat,south:Nn(0,o,n,s).lat,east:Nn(o,0,n,s).lng,west:Nn(-o,0,n,s).lng}}static expand(t,e){const i=t.east-t.west,n=t.north-t.south;return{west:t.west-i*e,east:t.east+i*e,south:t.south-n*e,north:t.north+n*e}}static pointAt(t,e,i){const n=ni.mercatorY01(t.north),s=ni.mercatorY01(t.south);return{lat:ni.latitudeAt(n+i*(s-n)),lng:t.west+e*(t.east-t.west)}}static mercatorY01(t){const e=t*Math.PI/180;return(1-Math.log(Math.tan(e)+1/Math.cos(e))/Math.PI)/2}static latitudeAt(t){return Math.atan(Math.sinh(Math.PI*(1-2*t)))*180/Math.PI}}const Un=256,fg=3,Sb=32768;class wb{fetchImpl;tileUrlTemplate;constructor(t={}){this.fetchImpl=t.fetchImpl??fetch.bind(globalThis),this.tileUrlTemplate=t.tileUrlTemplate??"https://s3.amazonaws.com/elevation-tiles-prod/terrarium/{z}/{x}/{y}.png"}async getElevationGrid(t,e){const i=(t.south+t.north)/2,n=(t.west+t.east)/2,s=Math.abs(si(i,t.east,i,t.west).x),r=Math.abs(si(t.north,n,t.south,n).z),o=vb(i,Math.max(s,r)),{tiles:c}=IM(n,i,o,fg),l=fg*Un,h=new Float32Array(l*l),u=c[0];await Promise.all(c.map(f=>this.decodeTileInto(f,u,h,l)));const d=new Float32Array(e.width*e.height);for(let f=0;f<e.height;f++){const p=t.north+(t.south-t.north)*(f/(e.height-1));for(let v=0;v<e.width;v++){const m=t.west+(t.east-t.west)*(v/(e.width-1));d[f*e.width+v]=this.sampleAt(p,m,o,u,h,l)}}return{heights:d,width:e.width,height:e.height,bounds:t}}async decodeTileInto(t,e,i,n){const s=this.tileUrlTemplate.replace("{z}",String(t.z)).replace("{x}",String(t.x)).replace("{y}",String(t.y)),r=await this.fetchImpl(s);if(!r.ok)throw new Error(`Elevation tile fetch failed (${r.status}): ${s}`);const o=await createImageBitmap(await r.blob()),c=document.createElement("canvas");c.width=Un,c.height=Un;const l=c.getContext("2d");if(!l)throw new Error("2D canvas context unavailable");l.drawImage(o,0,0);const{data:h}=l.getImageData(0,0,Un,Un),u=(t.x-e.x)*Un,d=(t.y-e.y)*Un;for(let f=0;f<Un;f++)for(let p=0;p<Un;p++){const v=(f*Un+p)*4,m=h[v]*256+h[v+1]+h[v+2]/256-Sb,g=u+p,b=d+f;i[b*n+g]=m}}sampleAt(t,e,i,n,s,r){const{x:o,y:c}=RM(e,t,i),l=(o-n.x)*Un,h=(c-n.y)*Un,u=Math.max(0,Math.min(r-1,Math.floor(l))),d=Math.max(0,Math.min(r-1,Math.floor(h))),f=Math.min(r-1,u+1),p=Math.min(r-1,d+1),v=l-u,m=h-d,g=s[d*r+u],b=s[d*r+f],S=s[p*r+u],M=s[p*r+f],x=g+(b-g)*v,_=S+(M-S)*v;return x+(_-x)*m}}const Hh=256,_b=5;async function Eb(a,t,e,i){const n=(a.south+a.north)/2,s=(a.west+a.east)/2,r=Math.abs(si(n,a.east,n,a.west).x),o=Math.abs(si(a.north,s,a.south,s).z),c=Math.max(r,o),{zoom:l,gridSize:h}=Ab(n,c,Math.max(t.width,t.height)),{tiles:u,bounds:d}=IM(s,n,l,h),f=h*Hh,p=document.createElement("canvas");p.width=f,p.height=f;const v=p.getContext("2d");if(!v)throw new Error("2D canvas context unavailable");const m=u[0];await Promise.all(u.map(async M=>{const x=e(M),_=await i(x);if(!_.ok)throw new Error(`Imagery tile fetch failed (${_.status}): ${x}`);const A=await createImageBitmap(await _.blob());v.drawImage(A,(M.x-m.x)*Hh,(M.y-m.y)*Hh)}));const g=Math.min(Math.max(t.width,t.height),f);if(g===f)return{source:p,width:f,height:f,bounds:d};const b=document.createElement("canvas");b.width=g,b.height=g;const S=b.getContext("2d");if(!S)throw new Error("2D canvas context unavailable");return S.drawImage(p,0,0,f,f,0,0,g,g),{source:b,width:g,height:g,bounds:d}}function Ab(a,t,e){let i=Mb(a,t/Math.max(1,e)),n=pg(a,i,t);for(;n>_b&&i>0;)i--,n=pg(a,i,t);return{zoom:i,gridSize:n,mPerPixel:TM(a,i)/Hh}}function pg(a,t,e){const i=Math.ceil(e/2/TM(a,t));return Math.max(3,2*i+1)}class Tb{attribution="Imagery © Esri, Maxar, Earthstar Geographics, and the GIS User Community";fetchImpl;tileUrlTemplate;constructor(t={}){this.fetchImpl=t.fetchImpl??fetch.bind(globalThis),this.tileUrlTemplate=t.tileUrlTemplate??"https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}"}async getImageryTexture(t,e){return Eb(t,e,i=>this.tileUrlTemplate.replace("{z}",String(i.z)).replace("{y}",String(i.y)).replace("{x}",String(i.x)),this.fetchImpl)}}class es{attribution="Roads © OpenStreetMap contributors, as surveyed today";contemporary=!0;static DRIVABLE=["motorway","trunk","primary","secondary","tertiary","unclassified","residential","service","track","motorway_link","trunk_link","primary_link","secondary_link","tertiary_link"];static WIDTH_M={motorway:11,trunk:9,primary:8,secondary:7,tertiary:6.5,unclassified:5.5,residential:5.5,service:4,track:3.5};static DEFAULT_WIDTH_M=5;static ENDPOINTS=["https://overpass-api.de/api/interpreter","https://overpass.kumi.systems/api/interpreter","https://overpass.private.coffee/api/interpreter"];fetchImpl;endpoints;constructor(t={}){this.fetchImpl=t.fetchImpl??fetch.bind(globalThis),this.endpoints=t.endpoints??es.ENDPOINTS}static queue=Promise.resolve();static RETRY_MS=4e3;async getRoads(t){const e=`${t.south},${t.west},${t.north},${t.east}`,i=`[out:json][timeout:30];way["highway"~"^(${es.DRIVABLE.join("|")})$"](${e});out geom;`;return this.waysFrom(await this.queued(()=>this.ask(i)))}waysFrom(t){const e=[];for(const i of t.elements??[]){const n=i.geometry,s=i.tags;!s||!n||n.length<2||e.push({id:`osm-${i.id??e.length}`,name:s.name,surface:es.surfaceOf(s),widthM:es.widthOf(s),points:n.map(r=>({lat:r.lat,lng:r.lon}))})}return e}queued(t){const e=es.queue.then(t,t);return es.queue=e.catch(()=>{}),e}async ask(t){let e;for(const i of this.endpoints)for(let n=0;n<2;n++){try{const s=await this.fetchImpl(`${i}?data=${encodeURIComponent(t)}`);if(s.ok)return await s.json();if(e=new Error(`${new URL(i).host} refused (${s.status})`),s.status!==429&&s.status!==504)break}catch(s){e=new Error(`${new URL(i).host} unreachable (${String(s)})`);break}await new Promise(s=>setTimeout(s,es.RETRY_MS))}throw e??new Error("No Overpass instance answered")}static widthOf(t){const e=Number.parseFloat(t.width??t.est_width??"");if(Number.isFinite(e)&&e>0)return e;const i=Number.parseInt(t.lanes??"",10);return Number.isFinite(i)&&i>0?i*3.5:es.WIDTH_M[t.highway]??es.DEFAULT_WIDTH_M}static surfaceOf(t){const e=t.surface;return e==="dirt"||e==="earth"||e==="mud"?"dirt":e==="gravel"||e==="fine_gravel"||e==="compacted"||e==="ground"||e==="sand"||e==="unpaved"?"gravel":e?"paved":t.highway==="track"?"gravel":"paved"}}const xd="https://ufoathome.org/roads/index.json";class Do{attributionRead;contemporaryRead;fetchImpl;indexUrls;fallback;index;static shared=new Map;sharing;constructor(t={}){this.sharing=!t.fetchImpl,this.fetchImpl=t.fetchImpl??fetch.bind(globalThis),this.indexUrls=t.indexUrls??Do.defaultIndexUrls(),this.fallback=t.fallback}get attribution(){return this.attributionRead??this.fallback?.attribution??"Roads © OpenStreetMap contributors"}get contemporary(){return this.contemporaryRead??this.fallback?.contemporary??!0}async getRoads(t){const e=await this.held(t);if(e)return e;if(!this.fallback)return[];const i=await this.fallback.getRoads(t);return this.attributionRead=this.fallback.attribution,this.contemporaryRead=this.fallback.contemporary,i}async held(t){let e;try{e=await this.load()}catch{return}const i=e.find(({entry:n})=>n.north>=t.north&&n.south<=t.south&&n.east>=t.east&&n.west<=t.west);if(i)try{const n=await this.fetchImpl(new URL(i.entry.file,i.indexUrl).href);if(!n.ok)return;const s=await n.json();return Array.isArray(s?.ways)?(this.attributionRead=s.attribution,this.contemporaryRead=s.contemporary,s.ways):void 0}catch{return}}load(){if(this.index)return this.index;if(!this.sharing)return this.index=this.fetchFirstAvailable();const t=this.indexUrls.join(`
2183
- `);let e=Do.shared.get(t);return e||(e=this.fetchFirstAvailable(),Do.shared.set(t,e),e.then(i=>{i.length===0&&Do.shared.delete(t)})),this.index=e}async fetchFirstAvailable(){for(const t of this.indexUrls)try{const e=await this.fetchImpl(t);if(!e.ok)continue;const i=await e.json();if(Array.isArray(i?.entries))return i.entries.map(n=>({entry:n,indexUrl:t}))}catch{}return[]}static defaultIndexUrls(){const t=`?v=${encodeURIComponent("0.104.1")}`,e=typeof location>"u"?void 0:new URL("/roads/index.json",location.href).href;return(e&&e!==xd?[e,xd]:[xd]).map(i=>i+t)}}function Rb(){return{elevation:new wb,imagery:CM(),roads:Db()}}function CM(){return new Tb}function Db(){return new Do({fallback:new es})}const Ib=new Set,ks="show-observer-map",Fs="hide-milestones";class pe extends HTMLElement{static get observedAttributes(){return["src",ks,Fs]}shadow;stageElement;canvas;canvasRenderer;tooltip;toolbar;issuesBox;issuesButton;issuesPanel;playPauseButton;static OBSERVER_MAP_MIN_SPAN_M=400;static OBSERVER_MAP_MARGIN=.6;static OBSERVER_MAP_IMAGERY_PX=768;fullscreenButton;cornerButtons;observerMapButton;referencesButton;tracesButton;tracesShownState=!0;referenceOpacityInput;referencesShownState=!0;accountHidden=!1;referenceViews=new Map;referencesMenu;referenceOpacityTouched=!1;milestonesButton;observerMapPanel;observerMapCanvas;observerMapRenderer;mapZoomInButton;mapZoomOutButton;mapFitButton;observerMapView=new ni;observerMapDrag;suppressObserverMapClick=!1;observerMapImageryTimer;observerPlacing=!1;seekInput;playbackFlash;milestoneMarks;milestoneCaption;timeStartLabel;timeEndLabel;timePill;muteButton;volumeInput;controlsRow;momentsBox;momentsButton;momentsCurrent;momentsMenu;moreButton;controlsRight;seekSegments;seekDot;seekPreview;seekPreviewCanvas;seekPreviewTitle;seekPreviewTime;observerPath;observerMapBounds;observerMapImagery;observerMapImageryBounds;observerMapImageryViewWidth=0;observerMapImageryLoading=!1;observerMapImageryCredit;observerMapImageryFailed=!1;creditShownExternally=!1;lookYawDeg=0;lookPitchDeg=0;milestonesShown=!0;currentSighting=td.create();issues=[];issueCheck=0;sightingAudio=new nb;soundPreview;player;loopEnabled=!1;playbackBeforeClick;highlightedSourceIds=new Set;paintsShapes=!0;steadyObserver=!1;static LIVE_BODY_MAX_RATE=2;get steadyBody(){return this.steadyObserver||this.player.playbackState!=="playing"||this.player.playbackRate>pe.LIVE_BODY_MAX_RATE}selectionShown=!0;overlayPainter;enableClickToPlay=!0;fullscreenTarget;messages=SM;realDurationMs;realStartMs;showClockTime=!0;handleFullscreenChange=()=>{this.updateFullscreenButton(),this.updateMuteButton(),this.resizeObserverMap()};controlsFitObserver=typeof ResizeObserver>"u"?void 0:new ResizeObserver(()=>this.fitControls());controlsMutations;fitControls(){const t=this.controlsRow,e=t.classList.contains("more-open"),i=()=>t.scrollWidth>t.clientWidth+1,n=!this.momentsMenu.hidden;if(this.momentsMenu.hidden=!0,t.classList.remove("narrow","more-open","nomoments","compact","tiny"),t.clientWidth>0&&i()){t.classList.add("narrow");for(const s of["nomoments","compact","tiny"]){if(!i())break;t.classList.add(s)}e&&t.classList.add("more-open")}this.momentsMenu.hidden=!n,this.updateMoreButton()}setControlsFolded(t){this.controlsRow.classList.toggle("more-open",!t),this.updateMoreButton()}updateMoreButton(){const t=this.controlsRow.classList.contains("more-open");pe.setIcon(this.moreButton,t?Gt.UNFOLDED:Gt.FOLDED);const e=t?this.messages.fewerControls:this.messages.moreControls;this.moreButton.title=e,this.moreButton.setAttribute("aria-label",e),this.moreButton.setAttribute("aria-expanded",String(t))}addControl(t){this.controlsRight.insertBefore(t,this.fullscreenButton.parentElement===this.controlsRight?this.fullscreenButton:null),this.fitControls()}observerMapResizeObserver=typeof ResizeObserver>"u"?void 0:new ResizeObserver(()=>this.resizeObserverMap());resizeObserverMap(){this.observerMapPanel.hidden||(this.sizeObserverMapCanvas(),this.paintObserverMap(this.currentTime))}simulatedFullscreen=!1;styleBeforeSimulatedFullscreen;bodyOverflowBeforeSimulatedFullscreen;handleSimulatedFullscreenKey=t=>{t.key==="Escape"&&this.exitSimulatedFullscreen()};handlePointerMove=t=>{const e=this.canvasPointFromEvent(t),i=e&&this.shapeAt(e.x,e.y),n=this.said.read(i?.shape.title);if(!n){this.tooltip.hidden=!0;return}this.tooltip.textContent=n,this.tooltip.hidden=!1;const s=this.stageElement.getBoundingClientRect();this.tooltip.style.left=`${t.clientX-s.left+12}px`,this.tooltip.style.top=`${t.clientY-s.top+12}px`};handleObserverMapPointerMove=t=>{if(this.dragObserverMap(t))return;const e=this.observerMapTargetFrom(t);if(!e){if(!this.observerPlacing){this.tooltip.hidden=!0,this.observerMapCanvas.style.cursor="grab";return}this.observerMapCanvas.style.cursor="crosshair",this.showObserverMapTooltip(t,this.messages.placeObserverHere);return}this.observerMapCanvas.style.cursor="pointer",this.showObserverMapTooltip(t,e.label)};showObserverMapTooltip(t,e){this.tooltip.textContent=e,this.tooltip.hidden=!1;const i=this.stageElement.getBoundingClientRect();this.tooltip.style.left=`${t.clientX-i.left+12}px`,this.tooltip.style.top=`${t.clientY-i.top+12}px`}handleObserverMapClick=t=>{if(this.suppressObserverMapClick){this.suppressObserverMapClick=!1;return}const e=this.observerMapTargetFrom(t);if(!e){this.observerPlacing&&this.placeObserverFrom(t);return}if(e.kind==="milestone"&&e.t!==void 0){this.player.seek(e.t);return}this.dispatchEvent(new CustomEvent("lookat",{detail:{lat:e.lat,lng:e.lng,kind:e.kind},bubbles:!0,composed:!0}))};observerMapTargetFrom(t){const e=this.observerMapCanvas.getBoundingClientRect();if(!(e.width===0||e.height===0))return this.observerMapRenderer.hitTest((t.clientX-e.left)/e.width*this.observerMapCanvas.width,(t.clientY-e.top)/e.height*this.observerMapCanvas.height)}handlePointerLeave=()=>{this.tooltip.hidden=!0};handleObserverMapPointerDown=t=>{t.button===0&&(this.suppressObserverMapClick=!1,this.observerMapDrag={pointerId:t.pointerId,startX:t.clientX,startY:t.clientY,lastX:t.clientX,lastY:t.clientY,moved:!1})};handleObserverMapPointerUp=t=>{const e=this.observerMapDrag;!e||e.pointerId!==t.pointerId||(this.observerMapDrag=void 0,this.observerMapCanvas.classList.remove("dragging"),e.moved&&(this.suppressObserverMapClick=!0,this.paintObserverMap(this.currentTime),this.observerMapCanvas.hasPointerCapture?.(t.pointerId)&&this.observerMapCanvas.releasePointerCapture(t.pointerId)))};dragObserverMap(t){const e=this.observerMapDrag;if(!e||e.pointerId!==t.pointerId)return!1;if(!e.moved){if(Math.hypot(t.clientX-e.startX,t.clientY-e.startY)<pe.OBSERVER_MAP_DRAG_PX)return!1;e.moved=!0,this.tooltip.hidden=!0,this.observerMapCanvas.classList.add("dragging"),this.observerMapCanvas.setPointerCapture?.(t.pointerId)}const i=this.observerMapCanvas.getBoundingClientRect();return i.width>0&&i.height>0&&(this.observerMapView.panBy((t.clientX-e.lastX)/i.width,(t.clientY-e.lastY)/i.height),this.observerMapViewChanged()),e.lastX=t.clientX,e.lastY=t.clientY,!0}static OBSERVER_MAP_DRAG_PX=4;handleObserverMapWheel=t=>{t.preventDefault();const e=this.observerMapCanvas.getBoundingClientRect();if(e.width===0||e.height===0)return;const i=t.deltaMode===0?t.deltaY:t.deltaY*40;this.zoomObserverMap((t.clientX-e.left)/e.width,(t.clientY-e.top)/e.height,Math.exp(-i*.002))};zoomObserverMap(t,e,i){this.observerMapView.zoomAt(t,e,i),this.observerMapViewChanged()}observerMapViewChanged(){this.mapFitButton.hidden=!this.observerMapView.changed,this.mapZoomInButton.disabled=this.observerMapView.zoomFactor>=ni.MAX_ZOOM,this.mapZoomOutButton.disabled=this.observerMapView.zoomFactor<=ni.MIN_ZOOM,this.paintObserverMap(this.currentTime),this.scheduleObserverMapImagery()}scheduleObserverMapImagery(){this.observerMapImageryTimer===void 0&&(this.observerMapImageryTimer=setTimeout(()=>{this.observerMapImageryTimer=void 0,this.loadObserverMapImagery()},pe.OBSERVER_MAP_IMAGERY_DELAY_MS))}static OBSERVER_MAP_FOLLOW_MARGIN=.1;static OBSERVER_MAP_IMAGERY_DELAY_MS=300;get observerMapViewBounds(){return this.observerMapBounds&&this.observerMapView.boundsWithin(this.observerMapBounds)}placeObserverFrom(t){const e=this.observerMapViewBounds,i=this.observerMapCanvas.getBoundingClientRect();if(!e||i.width===0||i.height===0)return;const n=ni.pointAt(e,(t.clientX-i.left)/i.width,(t.clientY-i.top)/i.height);this.dispatchEvent(new CustomEvent("observerplace",{detail:n,bubbles:!0,composed:!0}))}constructor(){super(),this.shadow=this.attachShadow({mode:"open"});const t=document.createElement("template");t.innerHTML=`<style>${Kx}</style>${$x}`,this.shadow.appendChild(t.content.cloneNode(!0)),this.stageElement=this.shadow.getElementById("stage"),this.canvas=this.shadow.getElementById("canvas"),this.canvasRenderer=new al(this.canvas.getContext("2d")),this.tooltip=this.shadow.getElementById("tooltip"),this.toolbar=this.shadow.getElementById("toolbar"),this.issuesBox=this.shadow.getElementById("issues"),this.issuesButton=this.shadow.getElementById("issues-button"),this.issuesPanel=this.shadow.getElementById("issues-panel"),this.issuesButton.addEventListener("click",e=>{e.stopPropagation(),this.issuesPanel.hidden=!this.issuesPanel.hidden,this.issuesButton.setAttribute("aria-expanded",String(!this.issuesPanel.hidden))}),this.playPauseButton=this.shadow.getElementById("play-pause"),this.fullscreenButton=this.shadow.getElementById("fullscreen"),this.cornerButtons=this.shadow.getElementById("corner-buttons"),this.observerMapButton=this.shadow.getElementById("observer-map"),this.referencesButton=this.shadow.getElementById("references"),this.tracesButton=this.shadow.getElementById("traces"),this.referenceOpacityInput=this.shadow.getElementById("reference-opacity"),this.referencesMenu=this.shadow.getElementById("references-menu"),this.milestonesButton=this.shadow.getElementById("milestones"),this.observerMapPanel=this.shadow.getElementById("observer-map-panel"),this.observerMapCanvas=this.shadow.getElementById("observer-map-canvas"),this.observerMapRenderer=new la(this.observerMapCanvas.getContext("2d")),this.mapZoomInButton=this.shadow.getElementById("map-zoom-in"),this.mapZoomOutButton=this.shadow.getElementById("map-zoom-out"),this.mapFitButton=this.shadow.getElementById("map-fit"),this.seekInput=this.shadow.getElementById("seek"),this.playbackFlash=this.shadow.getElementById("playback-flash"),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"),this.timePill=this.shadow.getElementById("time"),this.muteButton=this.shadow.getElementById("mute"),this.controlsRight=this.shadow.getElementById("controls-right"),this.seekSegments=this.shadow.getElementById("seek-segments"),this.seekDot=this.shadow.getElementById("seek-dot"),this.seekPreview=this.shadow.getElementById("seek-preview"),this.seekPreviewCanvas=this.shadow.getElementById("seek-preview-canvas"),this.seekPreviewTitle=this.shadow.getElementById("seek-preview-title"),this.seekPreviewTime=this.shadow.getElementById("seek-preview-time"),this.timePill.addEventListener("click",()=>this.toggleTimeDisplay()),this.timePill.addEventListener("keydown",e=>{e.key!=="Enter"&&e.key!==" "||(e.preventDefault(),this.toggleTimeDisplay())}),this.volumeInput=this.shadow.getElementById("volume"),this.controlsRow=this.shadow.querySelector(".controls"),this.momentsBox=this.shadow.getElementById("moments"),this.momentsButton=this.shadow.getElementById("moments-button"),this.momentsCurrent=this.shadow.getElementById("moments-current"),this.momentsMenu=this.shadow.getElementById("moments-menu"),this.momentsButton.addEventListener("click",()=>this.toggleMomentsMenu()),this.moreButton=this.shadow.getElementById("controls-more"),this.moreButton.addEventListener("click",()=>this.setControlsFolded(this.controlsRow.classList.contains("more-open"))),this.muteButton.addEventListener("click",()=>this.toggleMuted()),this.volumeInput.addEventListener("input",()=>{this.setVolume(Number(this.volumeInput.value))}),this.fullscreenTarget=this.stageElement,this.playPauseButton.addEventListener("click",()=>this.togglePlayPause()),this.fullscreenButton.addEventListener("click",()=>this.toggleFullscreen()),this.addEventListener("keydown",this.handleFullscreenKey),this.observerMapButton.addEventListener("click",()=>this.toggleObserverMap()),this.referencesButton.addEventListener("click",()=>this.toggleReferences()),this.tracesButton.addEventListener("click",()=>this.toggleTraces()),this.referenceOpacityInput.addEventListener("input",()=>{this.referenceOpacityTouched=!0,this.dispatchReferenceView()}),this.milestonesButton.addEventListener("click",()=>this.toggleMilestones()),this.observerMapCanvas.addEventListener("pointermove",this.handleObserverMapPointerMove),this.observerMapCanvas.addEventListener("pointerleave",this.handlePointerLeave),this.observerMapCanvas.addEventListener("click",this.handleObserverMapClick),this.observerMapCanvas.addEventListener("pointerdown",this.handleObserverMapPointerDown),this.observerMapCanvas.addEventListener("pointerup",this.handleObserverMapPointerUp),this.observerMapCanvas.addEventListener("pointercancel",this.handleObserverMapPointerUp),this.observerMapCanvas.addEventListener("wheel",this.handleObserverMapWheel,{passive:!1}),this.mapZoomInButton.addEventListener("click",()=>this.zoomObserverMap(.5,.5,2)),this.mapZoomOutButton.addEventListener("click",()=>this.zoomObserverMap(.5,.5,.5)),this.mapFitButton.addEventListener("click",()=>{this.observerMapView.reset(),this.observerMapViewChanged()}),this.seekInput.addEventListener("input",()=>this.player.seek(this.snapSeekToMark(Number(this.seekInput.value)))),this.seekInput.addEventListener("pointerdown",e=>{this.suspendForScrub(),this.seekSnapArmed=!0,this.nameMarkUnder(e),this.beginTouchScrub(e)}),this.seekInput.addEventListener("pointerup",e=>{this.seekSnapArmed=!1,this.endTouchScrub(e)}),this.seekInput.addEventListener("pointercancel",e=>this.endTouchScrub(e)),this.seekInput.addEventListener("pointermove",e=>{this.nameMarkUnder(e),this.hoverSeek(e),this.touchScrub(e)}),this.seekInput.addEventListener("pointerleave",()=>{this.seekInput.removeAttribute("title"),this.leaveSeek()}),this.seekInput.addEventListener("keydown",this.handleSeekKey),this.stageElement.addEventListener("pointerdown",()=>{this.handlePointerDown(),this.touchedStage()},!0);for(const e of["touchend","click"])this.stageElement.addEventListener(e,()=>this.sightingAudio.resume(),!0);this.stageElement.addEventListener("pointermove",()=>this.touchedStage()),this.canvas.addEventListener("click",e=>{if(this.enableClickToPlay){if(this.tapRevealedOnly){this.tapRevealedOnly=!1;return}e.detail<=1&&(this.playbackBeforeClick={state:this.playbackState,time:this.currentTime}),this.togglePlayPause()}}),this.canvas.addEventListener("dblclick",e=>{this.enableClickToPlay&&(e.preventDefault(),this.restorePlayback(),this.toggleFullscreen())}),this.canvas.addEventListener("pointermove",this.handlePointerMove),this.canvas.addEventListener("pointerleave",this.handlePointerLeave),document.addEventListener("fullscreenchange",this.handleFullscreenChange),document.addEventListener("pointerdown",this.handleMomentsDismiss,!0),document.addEventListener("keydown",this.handleMomentsDismiss,!0),document.addEventListener("visibilitychange",this.handleVisibility),window.addEventListener("pagehide",this.handleHidden),document.addEventListener("pointerup",this.handlePointerRelease,!0),document.addEventListener("pointercancel",this.handlePointerRelease,!0),this.observerMapResizeObserver?.observe(this.observerMapPanel),this.controlsFitObserver?.observe(this.controlsRow),this.controlsFitObserver?.observe(this.controlsRow.querySelector(".controls-left")),typeof MutationObserver<"u"&&(this.controlsMutations=new MutationObserver(()=>this.fitControls()),this.controlsMutations.observe(this.controlsRight,{attributes:!0,attributeFilter:["hidden"],childList:!0,subtree:!0})),this.hostControls(void 0),this.player=this.createPlayer(),this.updateTimeLabels(),this.updatePlayPauseButton(),this.updateFullscreenButton(),this.updateMuteButton(),this.updateObserverMapButton(),this.updateReferencesButton(),this.updateTracesButton(),this.updateMilestonesButton(),this.refresh()}connectedCallback(){this.saidTexts=void 0,this.loadLocaleMessages();const t=this.getAttribute("src");t&&this.loadFromSrc(t)}disconnectedCallback(){document.removeEventListener("fullscreenchange",this.handleFullscreenChange),document.removeEventListener("pointerdown",this.handleMomentsDismiss,!0),document.removeEventListener("keydown",this.handleMomentsDismiss,!0),document.removeEventListener("visibilitychange",this.handleVisibility),window.removeEventListener("pagehide",this.handleHidden),document.removeEventListener("pointerup",this.handlePointerRelease,!0),document.removeEventListener("pointercancel",this.handlePointerRelease,!0),window.clearTimeout(this.controlsIdleTimer),this.observerMapResizeObserver?.disconnect(),this.controlsFitObserver?.disconnect(),this.controlsMutations?.disconnect(),this.exitSimulatedFullscreen(),this.sightingAudio.dispose()}attributeChangedCallback(t,e,i){t==="src"&&i&&i!==e&&this.isConnected&&this.loadFromSrc(i),t===ks&&this.applyObserverMapDefault(),t===Fs&&this.setMilestonesShown(!this.hasAttribute(Fs))}async loadFromSrc(t){this.sightingData=await Gc.json(t)}get sightingData(){return sb(this.currentSighting)}set sightingData(t){this.player.stop(),this.soundPreview=void 0,this.sightingAudio.silence(),this.currentSighting=ab(t),this.issuesPanel.hidden=!0,this.issuesButton.setAttribute("aria-expanded","false"),this.reportIssues(t,this.currentSighting),this.observerMapView.reset(),this.mapFitButton.hidden=!0,this.observerMapAsked=!1,this.player=this.createPlayer(),this.updateTimeLabels(),this.updatePlayPauseButton(),this.refresh(),this.applyObserverMapDefault()}get recordingIssues(){return this.issues}async reportIssues(t,e){const i=++this.issueCheck;let n=[];try{const{default:s}=await je(async()=>{const{default:r}=await import("./sightingSchema-5AlscPkV.js");return{default:r}},[],import.meta.url);n=new ts(s).issues(t)}catch{}i===this.issueCheck&&(this.issues=[...n,...e.loadIssues],Zo.warn(this.issues,e.id),this.renderIssues(),this.dispatchEvent(new CustomEvent(Cb,{detail:{issues:this.issues},bubbles:!0,composed:!0})))}renderIssues(){const t=this.issues.length;this.issuesBox.hidden=t===0,this.shadow.getElementById("issues-count").textContent=String(t);const e=this.messages.recordingIssues.replace("{count}",String(t));this.issuesButton.title=e,this.issuesButton.setAttribute("aria-label",e),this.shadow.getElementById("issues-title").textContent=e,this.shadow.getElementById("issues-list").replaceChildren(...this.issues.map(i=>{const n=document.createElement("li");return n.textContent=Zo.text(i,this.messages.issueTemplates),n}))}get sighting(){return this.currentSighting}previewSound(t){this.soundPreview=t,this.sightingAudio.resume(),this.sightingAudio.setSound(t)}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(t){this.player.seek(t)}get seekableDuration(){return this.player.seekableDuration}get autoReplayEnabled(){return this.loopEnabled}set autoReplayEnabled(t){t!==this.loopEnabled&&this.toggleLoop()}play(){if(!(this.player.seekableDuration<=0||this.playbackState==="playing")){if(this.clockHeld){this.playAfterHold=!0;return}this.togglePlayPause()}}clockHeld=!1;playAfterHold=!1;holdClock(t){if(t!==this.clockHeld){if(this.clockHeld=t,t){if(this.playbackState!=="playing")return;this.playAfterHold=!0,this.player.pause(),this.soundPreview=void 0,this.sightingAudio.silence(),this.refresh(),this.updatePlayPauseButton();return}this.playAfterHold&&(this.playAfterHold=!1,!(this.player.seekableDuration<=0||this.playbackState==="playing")&&(this.sightingAudio.resume(),this.player.play(),this.updatePlayPauseButton()))}}pause(){this.playAfterHold=!1,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(t){this.toolbar.classList.toggle("hidden",!t),t?this.controlsRight.appendChild(this.fullscreenButton):this.cornerButtons.appendChild(this.fullscreenButton)}get playbackState(){return this.player.playbackState}get selectedSourceIds(){return this.highlightedSourceIds}get durationSeconds(){return this.currentSighting.event.durationSeconds}set durationSeconds(t){this.currentSighting.event.durationSeconds=t,this.updateTimeLabels(),this.refresh(),this.updatePlayPauseButton()}set selectedSourceIds(t){const e=new Set(t);e.size===this.highlightedSourceIds.size&&[...e].every(n=>this.highlightedSourceIds.has(n))||(this.highlightedSourceIds=e,this.refresh())}hasVisibleShapeAt(t,e){return this.shapeAt(t,e)!==void 0}refresh(){this.applyFrameFormat(),this.updateMuteButton(),this.updateTimeLabels(),this.seekInput.max=String(this.player.seekableDuration),this.refreshMilestoneMarks(),this.updateMilestonesButton(),this.updateObserverMap(),this.updateReferences(),this.updateTracesButton(),this.player.seek(this.player.time)}hostControls(t){const e=[this.milestonesButton,this.referencesButton,this.referenceOpacityInput,this.tracesButton,this.observerMapButton];if(t)for(const i of e)t.appendChild(i);else{const i=this.fullscreenButton.parentElement===this.controlsRight?this.fullscreenButton:null;for(const n of e)this.controlsRight.insertBefore(n,i)}}get referencesShown(){return this.referencesShownState}get referenceOpacity(){return Number(this.referenceOpacityInput.value)}get severalReferences(){return this.currentSighting.references.length>1}toggleReferences(){if(this.severalReferences){this.toggleReferencesMenu();return}this.referencesShownState=!this.referencesShownState,this.updateReferencesButton(),this.dispatchReferenceView()}updateReferences(){const t=this.currentSighting.references;!this.referenceOpacityTouched&&t.length>0&&(this.referenceOpacityInput.value=String(t[0].opacity));for(const e of[...this.referenceViews.keys()])t.some(i=>i.id===e)||this.referenceViews.delete(e);this.severalReferences?this.referencesMenu.hidden||this.renderReferencesMenu():this.closeReferencesMenu(),this.updateReferencesButton(),this.severalReferences&&this.dispatchReferenceView()}viewOfReference(t){let e=this.referenceViews.get(t.id);return e||(e={shown:!0,opacity:t.opacity},this.referenceViews.set(t.id,e)),e}toggleReferencesMenu(){this.referencesMenu.hidden?this.openReferencesMenu():this.closeReferencesMenu()}openReferencesMenu(){this.renderReferencesMenu(),this.referencesMenu.hidden=!1,this.placeReferencesMenu(),this.referencesButton.setAttribute("aria-expanded","true"),document.addEventListener("pointerdown",this.handleReferencesMenuOutside,!0),document.addEventListener("keydown",this.handleReferencesMenuKey,!0)}closeReferencesMenu(){this.referencesMenu.hidden||(this.referencesMenu.hidden=!0,this.referencesButton.setAttribute("aria-expanded","false"),document.removeEventListener("pointerdown",this.handleReferencesMenuOutside,!0),document.removeEventListener("keydown",this.handleReferencesMenuKey,!0))}handleReferencesMenuOutside=t=>{const e=t.composedPath();e.includes(this.referencesMenu)||e.includes(this.referencesButton)||this.closeReferencesMenu()};handleReferencesMenuKey=t=>{t.key==="Escape"&&(this.closeReferencesMenu(),this.referencesButton.focus())};placeReferencesMenu(){const t=this.referencesButton.getBoundingClientRect(),e=this.referencesMenu,i=4;e.style.bottom=`${Math.max(i,window.innerHeight-t.top+i)}px`,e.style.top="auto";const n=e.getBoundingClientRect().width;e.style.left=`${Math.max(i,Math.min(t.left,window.innerWidth-n-i))}px`}renderReferencesMenu(){const t=this.currentSighting.references.map(e=>{const i=this.viewOfReference(e),n=this.said.read(e.title)??e.id,s=document.createElement("div");s.className="reference-row";const r=document.createElement("label"),o=document.createElement("input");o.type="checkbox",o.checked=i.shown;const c=document.createElement("span");c.textContent=n,c.title=n,r.append(o,c);const l=document.createElement("input");return l.type="range",l.min="0",l.max="1",l.step="0.05",l.value=String(i.opacity),l.title=this.messages.referenceOpacity,l.setAttribute("aria-label",`${this.messages.referenceOpacity}: ${n}`),l.disabled=!i.shown,o.addEventListener("change",()=>{i.shown=o.checked,l.disabled=!i.shown,this.updateReferencesButton(),this.dispatchReferenceView()}),l.addEventListener("input",()=>{i.opacity=Number(l.value),this.dispatchReferenceView()}),s.append(r,l),s});this.referencesMenu.setAttribute("aria-label",this.messages.referencesMenu),this.referencesMenu.replaceChildren(...t)}updateReferencesButton(){const t=this.currentSighting.references.length>0,e=this.severalReferences,i=e?this.currentSighting.references.some(s=>this.viewOfReference(s).shown):this.referencesShownState;this.referencesButton.hidden=!t,this.referenceOpacityInput.hidden=!t||!this.referencesShownState||e,this.referencesButton.setAttribute("aria-pressed",String(i)),e?this.referencesButton.setAttribute("aria-haspopup","true"):this.referencesButton.removeAttribute("aria-haspopup"),pe.setIcon(this.referencesButton,i?Gt.PICTURES_ON:Gt.PICTURES_OFF);const n=e?this.messages.referencesMenu:this.referencesShownState?this.messages.hideReferences:this.messages.showReferences;this.referencesButton.title=n,this.referencesButton.setAttribute("aria-label",n),this.referenceOpacityInput.title=this.messages.referenceOpacity,this.referenceOpacityInput.setAttribute("aria-label",this.messages.referenceOpacity)}get tracesShown(){return this.tracesShownState}toggleTraces(){this.tracesShownState=!this.tracesShownState,this.updateTracesButton(),this.updateObserverMap(),this.dispatchEvent(new CustomEvent("traceview",{detail:{shown:this.tracesShown}}))}updateTracesButton(){this.tracesButton.hidden=this.currentSighting.traces.length===0,this.tracesButton.setAttribute("aria-pressed",String(this.tracesShownState)),pe.setIcon(this.tracesButton,this.tracesShownState?Gt.TRACES_ON:Gt.TRACES_OFF);const t=this.tracesShownState?this.messages.hideTraces:this.messages.showTraces;this.tracesButton.title=t,this.tracesButton.setAttribute("aria-label",t)}dispatchReferenceView(){const t=this.severalReferences?Object.fromEntries(this.currentSighting.references.map(e=>[e.id,{...this.viewOfReference(e)}])):void 0;this.dispatchEvent(new CustomEvent("referenceview",{detail:{shown:this.referencesShown,opacity:this.referenceOpacity,views:t}}))}refreshMilestoneMarks(){const t=this.player.seekableDuration,e=t>0?Wc(this.sighting.milestones):[];this.milestoneMarks.replaceChildren(...e.map(i=>{const n=document.createElement("button");n.type="button",n.className="milestone-mark",n.style.left=`${Math.min(Math.max(i.t/t,0),1)*100}%`;const s=this.said.read(i.label)??"",r=this.said.read(i.note),o=r?`${s} — ${r}`:s;return n.title=o,n.setAttribute("aria-label",o),n.dataset.t=String(i.t),n.addEventListener("click",()=>this.player.seek(i.t)),n})),this.refreshSeekSegments(t,e.map(i=>i.t)),this.refreshMomentsPicker(e)}refreshMomentsPicker(t){const e=this.milestonesShown&&t.length>0;this.momentsBox.hidden=!e,this.closeMomentsMenu(),this.momentsMenu.replaceChildren(...t.map(i=>{const n=document.createElement("li"),s=document.createElement("button");s.type="button",s.dataset.t=String(i.t);const r=this.said.read(i.label)??"",o=this.said.read(i.note);return s.textContent=o?`${r} — ${o}`:r,s.addEventListener("click",()=>{this.player.seek(i.t),this.closeMomentsMenu()}),n.appendChild(s),n})),this.momentsButton.title=this.messages.moments,this.showCurrentMoment(void 0)}showCurrentMoment(t){const i=(t?this.said.read(t.label)??"":"")||this.messages.moments;this.momentsCurrent.textContent!==i&&(this.momentsCurrent.textContent=i);for(const n of this.momentsMenu.querySelectorAll("button")){const s=t!==void 0&&Number(n.dataset.t)===t.t;n.getAttribute("aria-current")==="true"!==s&&n.setAttribute("aria-current",String(s))}}toggleMomentsMenu(){this.momentsMenu.hidden?(this.momentsMenu.hidden=!1,this.momentsButton.setAttribute("aria-expanded","true")):this.closeMomentsMenu()}closeMomentsMenu(){this.momentsMenu.hidden=!0,this.momentsButton.setAttribute("aria-expanded","false")}handleMomentsDismiss=t=>{if(!this.momentsMenu.hidden){if(t instanceof KeyboardEvent){t.key==="Escape"&&this.closeMomentsMenu();return}t.composedPath().some(e=>e===this.momentsMenu||e===this.momentsButton)||this.closeMomentsMenu()}};seekSegmentList=[];refreshSeekSegments(t,e){const n=[0,...this.milestonesShown&&t>0?[...new Set(e.filter(r=>r>0&&r<t))].sort((r,o)=>r-o):[],Math.max(t,0)];this.seekSegmentList=[];const s=[];for(let r=0;r<n.length-1;r++){const o=document.createElement("div");o.className="seek-segment",o.style.flexGrow=String(Math.max(n[r+1]-n[r],1));const c=document.createElement("i");c.className="seek-hover";const l=document.createElement("i");l.className="seek-played",o.append(c,l),s.push(o),this.seekSegmentList.push({start:n[r],end:n[r+1],element:o,played:l,hover:c})}this.seekSegments.replaceChildren(...s),this.paintSeekProgress(this.player.time)}static fillOf(t,e){const i=t.end-t.start,n=i>0?(e-t.start)/i:e>=t.end?1:0;return`${Math.min(Math.max(n,0),1)*100}%`}paintSeekProgress(t){for(const i of this.seekSegmentList)i.played.style.width=pe.fillOf(i,t);const e=this.player.seekableDuration;this.seekDot.style.left=`${e>0?Math.min(Math.max(t/e,0),1)*100:0}%`}hoverSeek(t){const e=this.seekInput.getBoundingClientRect(),i=this.player.seekableDuration;if(e.width<=0||i<=0)return;const n=Math.min(Math.max((t.clientX-e.left)/e.width,0),1),s=n*i,r=this.seekSegmentList.length-1;this.seekSegmentList.forEach((f,p)=>{f.hover.style.width=pe.fillOf(f,s),f.element.classList.toggle("hovered",s>=f.start&&(s<f.end||p===r))});const o=this.milestonesShown?this.sighting.milestones:[],c=o.length>0?Md(o,s):void 0,l=c?this.said.read(c.label)??"":"",h=c?this.said.read(c.note):void 0,u=h?`${l} — ${h}`:l;this.seekPreviewTitle.textContent=u,this.seekPreviewTime.textContent=this.formatPosition(s),this.seekPreview.hidden=!1;const d=this.seekPreview.offsetWidth;this.seekPreview.style.left=`${Math.min(Math.max(n*e.width-d/2,0),Math.max(e.width-d,0))}px`,this.paintSeekPreview(s)}leaveSeek(){for(const t of this.seekSegmentList)t.hover.style.width="0",t.element.classList.remove("hovered");this.seekPreview.hidden=!0}seekPreviewPainter;paintSeekPreview(t){const e=this.seekPreviewPainter;this.seekPreviewCanvas.hidden=e===void 0,e?.(t,this.seekPreviewCanvas)}scrubbingPointer;beginTouchScrub(t){if(t.pointerType!=="mouse"){this.scrubbingPointer=t.pointerId;try{this.seekInput.setPointerCapture(t.pointerId)}catch{}this.seekToPointer(t)}}touchScrub(t){t.pointerId===this.scrubbingPointer&&this.seekToPointer(t)}endTouchScrub(t){t.pointerId===this.scrubbingPointer&&(this.scrubbingPointer=void 0,this.seekToPointer(t))}seekToPointer(t){const e=this.seekInput.getBoundingClientRect(),i=this.player.seekableDuration;if(e.width<=0||i<=0)return;const n=Math.min(Math.max((t.clientX-e.left)/e.width,0),1);this.player.seek(this.snapSeekToMark(n*i))}seekSnapArmed=!1;static MARK_SNAP_PX=6;markNear(t){const e=this.player.seekableDuration,i=this.seekInput.getBoundingClientRect().width;if(e<=0||i<=0)return;const n=pe.MARK_SNAP_PX/i*e;let s;for(const r of this.milestoneMarks.children){const o=Number(r.dataset.t);Math.abs(o-t)>n||(!s||Math.abs(o-t)<Math.abs(s.t-t))&&(s={t:o,name:r.title})}return s}snapSeekToMark(t){return this.seekSnapArmed?(this.seekSnapArmed=!1,this.markNear(t)?.t??t):t}nameMarkUnder(t){const e=this.seekInput.getBoundingClientRect(),i=this.player.seekableDuration;if(e.width<=0||i<=0)return;const n=(t.clientX-e.left)/e.width*i,s=this.markNear(n);s?this.seekInput.title=s.name:this.seekInput.removeAttribute("title")}showMilestoneAt(t){const e=this.milestonesShown&&this.sighting.milestones.length>0?Md(this.sighting.milestones,t):void 0;if(this.milestoneCaption.hidden=e===void 0,this.showCurrentMoment(e),!e)return;const i=document.createElement("b");i.textContent=this.said.read(e.label)??"";const n=this.said.read(e.note),s=n?` — ${n}`:"";this.milestoneCaption.replaceChildren(i,document.createTextNode(s))}exposureInstants(t){const e=this.exposureTimes(t),i=1/e.length;return e.map(n=>({shapes:this.shapesAt(n),share:i}))}exposureTimes(t=this.currentTime){const e=as.windowEndingAt(t,this.currentSighting.exposure??0);if(e.ms<pe.SHORTEST_VISIBLE_EXPOSURE_MS)return[t];const i=Math.min(pe.MAX_EXPOSURE_STEPS,Math.max(2,Math.round(e.ms/pe.SHORTEST_VISIBLE_EXPOSURE_MS))),n=Math.ceil(this.travelPxOver(e.fromMs,e.ms)/pe.EXPOSURE_STEP_PX),s=Math.min(pe.MAX_TRAVEL_STEPS,Math.max(i,n)),r=[];for(let o=0;o<s;o++)r.push(e.fromMs+e.ms*o/(s-1));return r}travelPxOver(t,e){const i=this.shapesAt(t),n=this.shapesAt(t+e);let s=0;for(const[r,o]of i){const c=n.get(r);if(!c)continue;const l=c.bounds.x+c.bounds.width/2-(o.bounds.x+o.bounds.width/2),h=c.bounds.y+c.bounds.height/2-(o.bounds.y+o.bounds.height/2);s=Math.max(s,Math.hypot(l,h))}return s}shapeAt(t,e,i){if(!this.accountHidden)for(const n of this.exposureTimes()){const s=this.currentSighting.timeline.hitTest(n,t,e,i);if(s)return s}}shapesAt(t){const e=new Map;for(const i of this.currentSighting.timeline.sourceIds){const n=this.currentSighting.timeline.getInterpolatedShapeAt(t,i);n&&e.set(i,n)}return e}static SHORTEST_VISIBLE_EXPOSURE_MS=20;static MAX_EXPOSURE_STEPS=48;static EXPOSURE_STEP_PX=2;static MAX_TRAVEL_STEPS=320;applyFrameFormat(){const t=bi.frameWidthPx(this.currentSighting.instrument,this.canvas.height);if(this.canvas.width===t)return;this.canvas.width=t,this.canvas.parentElement?.style.setProperty("--frame-aspect",`${t} / ${this.canvas.height}`)}canvasPointFromEvent(t){const e=this.canvas.getBoundingClientRect();if(!(e.width===0||e.height===0))return{x:(t.clientX-e.left)/e.width*this.canvas.width,y:(t.clientY-e.top)/e.height*this.canvas.height}}onFrame(t,e){this.canvasRenderer.clear(this.canvas.width,this.canvas.height);const i=this.playbackState!=="playing"?this.highlightedSourceIds:Ib;this.canvasRenderer.setStarPoints(bi.starPointsOf(this.sighting.instrument));const n=(Ze(this.sighting,t)?.rollDeg??0)+this.gaitAt(t).rollDeg;this.canvasRenderer.setRoll(n*Math.PI/180);const s=this.exposureInstants(t),r=this.frameShift;if(this.paintsShapes)for(const o of s)for(const[,c]of o.shapes){const l=o.share,h=l===1?c:{...c,transparency:1-(1-c.transparency)*l};this.canvasRenderer.paintShape(this.shifted(h,r))}for(const[o,c]of s[0].shapes)!this.selectionShown||!i.has(o)||(this.paintsShapes?i.size===1?this.canvasRenderer.paintShape({...c,selected:!0}):this.canvasRenderer.paintMemberOutline(c):this.canvasRenderer.paintSelectionOnly(this.shifted(c,r)));if(this.selectionShown&&i.size>1){const o=Dn.groupBoundsFor([...e].filter(([c])=>i.has(c)).map(([,c])=>c.bounds));this.canvasRenderer.paintGroupHandles(o)}this.overlayPainter?.(this.canvasRenderer),this.mapShapeBounds=s.flatMap(o=>[...o.shapes.values()].filter(c=>c.transparency<1).map(c=>this.shifted(c,r).bounds)),this.keepObserverMapClear(),this.seekInput.value=String(t),this.paintSeekProgress(t),this.timeStartLabel.textContent=this.formatPosition(t),this.showMilestoneAt(t),this.paintObserverMap(t),this.playbackState==="playing"?(this.soundPreview=void 0,this.sightingAudio.setSound(pM(this.currentSighting,t))):this.soundPreview?this.sightingAudio.setSound(this.soundPreview):this.sightingAudio.silence(),this.updatePlayPauseButton(),this.dispatchEvent(new CustomEvent("timeupdate",{detail:{time:t}}))}shifted(t,e){return e.x===0&&e.y===0?t:{...t,bounds:{...t.bounds,x:t.bounds.x+e.x,y:t.bounds.y+e.y}}}createPlayer(){const t=new Zx(this.currentSighting.timeline,(e,i)=>this.onFrame(e,i));return t.loop=this.loopEnabled,t.onEnded=()=>{this.updatePlayPauseButton(),this.dispatchEvent(new CustomEvent("ended",{bubbles:!0,composed:!0}))},t}static SEEK_KEY_STEP_MS=5e3;handleFullscreenKey=t=>{t.key.toLowerCase()!=="f"||t.altKey||t.ctrlKey||t.metaKey||!this.enableClickToPlay||t.composedPath().some(i=>i instanceof HTMLElement&&(i.isContentEditable||["INPUT","TEXTAREA","SELECT"].includes(i.tagName)&&i.type!=="range"))||(t.preventDefault(),this.toggleFullscreen())};handleSeekKey=t=>{if(t.altKey||t.ctrlKey||t.metaKey)return;const e=t.key==="ArrowLeft"?-1:t.key==="ArrowRight"?1:0;if(e){t.preventDefault();const i=this.player.seekableDuration;this.player.seek(Math.min(i,Math.max(0,this.player.time+e*pe.SEEK_KEY_STEP_MS)))}else t.key===" "&&(t.preventDefault(),this.togglePlayPause())};togglePlayPause(){if(!(this.player.seekableDuration<=0)){if(this.player.playbackState==="playing")this.player.pause(),this.soundPreview=void 0,this.sightingAudio.silence(),this.refresh();else if(this.clockHeld){this.playAfterHold=!this.playAfterHold;return}else this.sightingAudio.resume(),this.player.play();this.updatePlayPauseButton(),this.flashPlayback()}}flashPlayback(){const t=this.playbackFlash;t.innerHTML=this.player.playbackState==="playing"?Gt.PLAY:Gt.PAUSE,t.classList.remove("flashing"),t.offsetWidth,t.classList.add("flashing")}static icons=new WeakMap;static setIcon(t,e){pe.icons.get(t)!==e&&(pe.icons.set(t,e),t.innerHTML=e)}set captionHeld(t){this.stageElement.classList.toggle("caption-held",t)}static CONTROLS_IDLE_MS=3e3;controlsIdleTimer;wasPlaying=!1;quietControlsValue=!1;get quietControls(){return this.quietControlsValue}set quietControls(t){this.quietControlsValue=t,this.stageElement.classList.toggle("quiet",t)}tapRevealedOnly=!1;get hoverless(){return typeof matchMedia=="function"&&matchMedia("(hover: none)").matches}touchedStage(){if(!this.hoverless)return;this.player.playbackState==="playing"&&!this.stageElement.classList.contains("touched")&&(this.tapRevealedOnly=!0),this.revealControls()}pointerHeld=!1;handlePointerDown=()=>{this.pointerHeld=!0};resumeAfterScrub=!1;suspendForScrub(){this.player.playbackState==="playing"&&(this.resumeAfterScrub=!0,this.stopPlaying())}stopPlaying(){this.player.pause(),this.soundPreview=void 0,this.sightingAudio.silence(),this.refresh(),this.updatePlayPauseButton()}resumeFromScrub(){this.resumeAfterScrub&&(this.resumeAfterScrub=!1,this.sightingAudio.resume(),this.player.play(),this.updatePlayPauseButton())}handleHidden=()=>{this.player.playbackState==="playing"&&this.stopPlaying(),this.resumeAfterScrub=!1};handleVisibility=()=>{document.visibilityState==="hidden"&&this.handleHidden()};handlePointerRelease=()=>{this.resumeAfterScrub&&window.setTimeout(()=>this.resumeFromScrub(),0),this.pointerHeld&&(this.pointerHeld=!1,this.hoverless&&this.stageElement.classList.contains("touched")&&this.revealControls())};revealControls(){this.stageElement.classList.add("touched"),window.clearTimeout(this.controlsIdleTimer),this.player.playbackState==="playing"&&(this.pointerHeld||!this.momentsMenu.hidden||(this.controlsIdleTimer=window.setTimeout(()=>{this.stageElement.classList.remove("touched"),this.tapRevealedOnly=!1},pe.CONTROLS_IDLE_MS)))}updatePlayPauseButton(){const t=this.player.playbackState==="playing";this.stageElement.classList.toggle("paused",!t),t!==this.wasPlaying&&t&&this.hoverless&&(!this.quietControlsValue||this.stageElement.classList.contains("touched"))&&this.revealControls(),this.wasPlaying=t,pe.setIcon(this.playPauseButton,t?Gt.PAUSE:Gt.PLAY);const e=this.player.seekableDuration>0;this.playPauseButton.disabled=!e;const i=e?t?this.messages.pause:this.messages.play:this.messages.noDuration;this.playPauseButton.title=i,this.playPauseButton.setAttribute("aria-label",i)}toggleLoop(){this.loopEnabled=!this.loopEnabled,this.player.loop=this.loopEnabled}restorePlayback(){const t=this.playbackBeforeClick;t&&(this.currentTime=t.time,t.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(t=>{console.error("<rr0-ufo>: requestFullscreen() failed —",t)})}enterSimulatedFullscreen(){const t=this.fullscreenTarget;this.styleBeforeSimulatedFullscreen=t.getAttribute("style")??"",this.bodyOverflowBeforeSimulatedFullscreen=document.body.style.overflow;const e=t.style;e.setProperty("position","fixed"),e.setProperty("inset","0"),e.setProperty("margin","0"),e.setProperty("max-width","none"),e.setProperty("max-height","none"),e.setProperty("aspect-ratio","auto"),e.setProperty("z-index","2147483647"),e.setProperty("background","#000"),e.setProperty("width","100vw"),e.setProperty("width","100dvw"),e.setProperty("height","100vh"),e.setProperty("height","100dvh"),document.body.style.overflow="hidden",this.simulatedFullscreen=!0,document.addEventListener("keydown",this.handleSimulatedFullscreenKey),this.updateFullscreenButton(),this.updateMuteButton()}exitSimulatedFullscreen(){if(!this.simulatedFullscreen)return;const t=this.fullscreenTarget;this.styleBeforeSimulatedFullscreen?t.setAttribute("style",this.styleBeforeSimulatedFullscreen):t.removeAttribute("style"),document.body.style.overflow=this.bodyOverflowBeforeSimulatedFullscreen??"",this.simulatedFullscreen=!1,document.removeEventListener("keydown",this.handleSimulatedFullscreenKey),this.updateFullscreenButton(),this.updateMuteButton()}toggleObserverMap(){const t=this.observerMapPanel.hidden;this.observerMapAsked=t,this.setObserverMapOpen(t),this.keepObserverMapClear(),this.dispatchEvent(new CustomEvent("observermapchange",{bubbles:!0,composed:!0,detail:{open:t}}))}get observerMapOpen(){return!this.observerMapPanel.hidden}get milestonesVisible(){return this.milestonesShown}observerMapAsked=!1;applyObserverMapDefault(){const t=this.getAttribute(ks),e=t===null?this.sighting.observerMap??this.observerPath?.travels===!0:t!=="false";this.setObserverMapOpen(e&&this.observerPath!==void 0)}setObserverMapOpen(t){this.observerMapPanel.hidden=!t,this.observerMapPanel.removeAttribute("title"),this.observerMapButton.setAttribute("aria-pressed",String(t)),this.updateObserverMapButton(),t&&(this.sizeObserverMapCanvas(),this.loadObserverMapImagery(),this.paintObserverMap(this.currentTime))}updateObserverMapButton(){const t=!this.observerMapPanel.hidden;pe.setIcon(this.observerMapButton,t?Gt.MAP_ON:Gt.MAP_OFF);const e=t?this.messages.hideObserverMap:this.messages.showObserverMap;this.observerMapButton.title=e,this.observerMapButton.setAttribute("aria-label",e);const i=[[this.mapZoomInButton,this.messages.zoomMapIn],[this.mapZoomOutButton,this.messages.zoomMapOut],[this.mapFitButton,this.messages.fitMap]];for(const[n,s]of i)n.title=s,n.setAttribute("aria-label",s)}updateObserverMap(){const t=this.observerPath!==void 0;if(this.observerPath=Fo.of(this.currentSighting),this.observerMapButton.hidden=this.observerPath===void 0,!t&&this.observerPath&&this.applyObserverMapDefault(),!this.observerPath){this.setObserverMapOpen(!1),this.observerMapBounds=void 0;return}const e=this.tracesShownState?this.currentSighting.traces.flatMap(n=>n.points):[],i=ni.including(this.observerPath.boundsAround(pe.OBSERVER_MAP_MIN_SPAN_M,pe.OBSERVER_MAP_MARGIN),e);(!this.observerMapBounds||!this.sameGround(this.observerMapBounds,i))&&(this.observerMapBounds&&this.observerMapView.refit(this.observerMapBounds,i),this.observerMapBounds=i,this.observerMapImagery=void 0,this.observerMapImageryCredit=void 0,this.observerMapImageryFailed=!1,this.observerMapImageryBounds=void 0,this.observerMapImageryLoading=!1,this.observerMapPanel.hidden||this.loadObserverMapImagery())}sameGround(t,e){const i=Math.abs(t.east-t.west)/20;return Math.abs(t.north-e.north)<i&&Math.abs(t.south-e.south)<i&&Math.abs(t.west-e.west)<i&&Math.abs(t.east-e.east)<i}async loadObserverMapImagery(){const t=this.observerMapViewBounds;if(!t||this.observerMapPanel.hidden||this.observerMapImageryLoading||!this.observerMapImageryNeededFor(t))return;const e=this.observerMapView.changed,i=e?ni.expand(t,pe.OBSERVER_MAP_IMAGERY_AHEAD):t,n=pe.OBSERVER_MAP_IMAGERY_PX*(e?1+2*pe.OBSERVER_MAP_IMAGERY_AHEAD:1);this.observerMapImageryBounds=i,this.observerMapImageryViewWidth=t.east-t.west,this.observerMapImageryLoading=!0;const s=CM();try{const r=await s.getImageryTexture(i,{width:n,height:n});if(this.observerMapImageryBounds!==i)return;this.observerMapImagery=r,this.observerMapImageryCredit=s.attribution,this.observerMapImageryFailed=!1}catch{if(this.observerMapImageryBounds!==i)return;this.observerMapImageryFailed=this.observerMapImagery===void 0}finally{this.observerMapImageryBounds===i&&(this.observerMapImageryLoading=!1)}this.paintObserverMap(this.currentTime),this.scheduleObserverMapImagery()}static OBSERVER_MAP_IMAGERY_AHEAD=.5;static OBSERVER_MAP_IMAGERY_LOOKAHEAD=.25;observerMapImageryNeededFor(t){const e=this.observerMapImageryBounds;if(!e)return!0;const i=this.observerMapImagery?.bounds??e,n=this.observerMapView.changed?ni.expand(t,pe.OBSERVER_MAP_IMAGERY_LOOKAHEAD):t,s=n.west>=i.west&&n.east<=i.east&&n.south>=i.south&&n.north<=i.north,r=t.east-t.west>this.observerMapImageryViewWidth/2;return!s||!r}get observerMapCredit(){return this.observerMapImageryCredit}get observerMapFooterLine(){return this.observerMapImageryFailed?this.messages.mapImageryUnavailable:this.creditShownExternally?void 0:this.observerMapImageryCredit}mapShapeBounds=[];mapSceneBounds=[];setMapSubjectBounds(t){this.mapSceneBounds=t.map(e=>({x:e.x*this.canvas.width,y:e.y*this.canvas.height,width:e.width*this.canvas.width,height:e.height*this.canvas.height})),this.keepObserverMapClear()}keepObserverMapClear(){if(this.observerMapPanel.hidden)return;const t=this.observerMapBoxPx;if(!t)return;const e=[...this.mapShapeBounds,...this.mapSceneBounds],i=(l,h,u)=>{for(const d of e)if(!(d.x+d.width<l-u||d.x>h+u)&&!(d.y>t.bottom+u||d.y+d.height<t.top-u))return!0;return!1},n=[this.canvas.width-t.width,this.canvas.width],s=[0,t.width],r=pe.OBSERVER_MAP_CLEARANCE_PX,o=i(...n,0),c=i(...s,0);if(this.observerMapPanel.classList.toggle("subject-overlap",o&&c&&!this.observerMapAsked),this.observerMapPanel.classList.contains("on-the-left")){!o&&(c||!i(n[0],n[1],r))&&this.observerMapPanel.classList.remove("on-the-left");return}i(n[0],n[1],0)&&!i(s[0],s[1],0)&&this.observerMapPanel.classList.add("on-the-left")}observerMapBoxPx;static OBSERVER_MAP_CLEARANCE_PX=24;sizeObserverMapCanvas(){const t=this.observerMapPanel.clientWidth;if(t===0)return;const e=Math.round(t*(globalThis.devicePixelRatio??1));this.measureObserverMapBox(),this.observerMapCanvas.width!==e&&(this.observerMapCanvas.width=e,this.observerMapCanvas.height=e)}measureObserverMapBox(){const t=this.observerMapPanel.getBoundingClientRect(),e=this.canvas.getBoundingClientRect();if(e.width===0||e.height===0)return;const i=this.canvas.width/e.width,n=this.canvas.height/e.height;this.observerMapBoxPx={width:t.width*i,top:(t.top-e.top)*n,bottom:(t.bottom-e.top)*n}}paintObserverMap(t){if(this.observerMapPanel.hidden||!this.observerPath||!this.observerMapBounds)return;const e=Ze(this.currentSighting,t);e?.lat!==void 0&&e.lng!==void 0&&!this.observerMapDrag?.moved&&this.observerMapView.keepInView(this.observerMapBounds,{lat:e.lat,lng:e.lng},pe.OBSERVER_MAP_FOLLOW_MARGIN)&&this.scheduleObserverMapImagery();const i=this.currentSighting.instrument,n=[],s=this.currentSighting.milestones.length>0?Md(this.currentSighting.milestones,t):void 0;for(const r of this.milestonesShown?Wc(this.currentSighting.milestones):[]){const o=Ze(this.currentSighting,r.t);o?.lat===void 0||o.lng===void 0||n.push({label:this.said.read(r.label)??"",note:this.said.read(r.note),t:r.t,lat:o.lat,lng:o.lng,current:r===s})}this.observerMapRenderer.paint({bounds:this.observerMapViewBounds,imagery:this.observerMapImagery,path:this.observerPath,position:e?.lat!==void 0&&e.lng!==void 0?{lat:e.lat,lng:e.lng}:void 0,headingDeg:e?.headingDeg===void 0?void 0:e.headingDeg+this.lookYawDeg,coneHalfAngleDeg:e?rr.of(i,this.canvas.height,e.fovDeg).halfWidthAngleDeg(bi.aspectOf(i)):void 0,markers:n,traces:(this.tracesShownState?this.currentSighting.traces:[]).map(r=>({kind:r.kind,points:r.points,color:r.color,label:this.said.read(r.title)})),decor:this.observerMapDecorAt(t),observerLabel:this.said.read(this.currentSighting.observer?.title)??this.messages.observerHere,nightFraction:this.observerMapNightFraction,attribution:this.observerMapFooterLine})}toggleMilestones(){this.setMilestonesShown(!this.milestonesShown)}setMilestonesShown(t){this.milestonesShown=t,this.milestoneMarks.hidden=!t,this.momentsBox.hidden=!t||this.sighting.milestones.length===0,this.refreshSeekSegments(this.player.seekableDuration,Wc(this.sighting.milestones).map(e=>e.t)),this.milestonesButton.setAttribute("aria-pressed",String(t)),this.updateMilestonesButton(),this.showMilestoneAt(this.currentTime),this.paintObserverMap(this.currentTime)}updateMilestonesButton(){this.milestonesButton.hidden=this.currentSighting.milestones.length===0,this.momentsButton.title=this.messages.moments,pe.setIcon(this.milestonesButton,this.milestonesShown?Gt.MILESTONES_ON:Gt.MILESTONES_OFF);const t=this.milestonesShown?this.messages.hideMilestones:this.messages.showMilestones;this.milestonesButton.title=t,this.milestonesButton.setAttribute("aria-label",t)}observerMapDecorAt(t){const e=Ze(this.currentSighting,0);return e?.lat===void 0||e.lng===void 0?[]:this.currentSighting.decor.filter(i=>i.kind!=="crop").map(i=>{const n=Hr(i,t),{lat:s,lng:r}=Nn(n.eastM,-n.northM,e.lat,e.lng);return{lat:s,lng:r,headingDeg:n.headingDeg,label:this.said.read(i.title)??this.messages.decorHere}})}observerMapNightFraction;setSunAltitude(t){const e=t===void 0?void 0:Math.max(0,Math.min(1,-t/12));e!==this.observerMapNightFraction&&(this.observerMapNightFraction=e,this.paintObserverMap(this.currentTime))}setLookOffset(t,e){t===this.lookYawDeg&&e===this.lookPitchDeg||(this.lookYawDeg=t,this.lookPitchDeg=e,this.refresh())}get frameShiftPx(){return this.frameShift}get frameShift(){const t=this.gaitAt(this.currentTime),e=this.lookYawDeg+t.yawDeg,i=this.lookPitchDeg+t.pitchDeg;if(e===0&&i===0)return{x:0,y:0};const n=Ze(this.currentSighting,this.currentTime),s=rr.of(this.currentSighting.instrument,this.canvas.height,n?.fovDeg??60);return{x:-s.angleDegToRadiusPx(e),y:s.angleDegToRadiusPx(i)}}gaitAt(t){return Ce.bodyAt(this.currentSighting,t,this.steadyBody)}mutedState=!1;get muted(){return this.mutedState}set muted(t){t!==this.mutedState&&(this.mutedState=t,!t&&this.volumeState===0&&(this.volumeState=pe.RESTORED_VOLUME),this.applyLevel())}volumeState=1;static RESTORED_VOLUME=.5;get volume(){return this.volumeState}set volume(t){this.setVolume(t)}setVolume(t){this.volumeState=Math.min(Math.max(t,0),1),this.mutedState=this.volumeState===0,this.applyLevel()}get level(){return this.mutedState?0:this.volumeState}applyLevel(){this.sightingAudio.setLevel(this.level),this.updateMuteButton(),this.dispatchEvent(new CustomEvent("mutedchange",{bubbles:!0,composed:!0,detail:{muted:this.mutedState,volume:this.volumeState}}))}toggleMuted(){this.hasSound&&(this.muted=!this.mutedState)}ambientSound;get hasSound(){return this.currentSighting.soundTrack.allKeyframes.length>0||this.ambientSound?.(this.currentSighting)===!0}updateMuteButton(){const t=!this.hasSound;if(this.muteButton.disabled=t,this.volumeInput.hidden=t,t){pe.setIcon(this.muteButton,Gt.MUTED),this.muteButton.title=this.messages.noSound,this.muteButton.setAttribute("aria-label",this.messages.noSound),this.muteButton.setAttribute("aria-pressed","true");return}pe.setIcon(this.muteButton,this.mutedState?Gt.MUTED:Gt.VOLUME);const e=this.mutedState?this.messages.unmute:this.messages.mute;this.muteButton.title=e,this.muteButton.setAttribute("aria-label",e),this.muteButton.setAttribute("aria-pressed",String(this.mutedState)),this.volumeInput.value=String(this.level)}updateFullscreenButton(){const t=this.simulatedFullscreen||document.fullscreenElement===this.fullscreenTarget;pe.setIcon(this.fullscreenButton,t?Gt.EXIT_FULLSCREEN:Gt.ENTER_FULLSCREEN),this.fullscreenButton.title=t?this.messages.exitFullscreen:this.messages.fullscreen,this.fullscreenButton.setAttribute("aria-label",this.fullscreenButton.title)}get said(){return this.saidTexts??=new Yn(Gr.preferencesFor(this))}saidTexts;async loadLocaleMessages(){const t=Ep(Gr.preferencesFor(this),Ap);if(t===this.messagesLanguage||t==="en"&&this.messagesLanguage===void 0)return;this.messagesLanguage=t;const e=await lb(t);this.messagesLanguage===t&&this.applyMessages(e)}messagesLanguage;updateTimeLabelTitles(){const t=this.showClockTime?this.messages.switchToElapsed:this.messages.switchToClockTime,e=this.canSwitchTimeDisplay?` — ${t}`:"";this.timeStartLabel.title=this.messages.currentPosition+e,this.timeEndLabel.title=this.messages.duration+e,this.timePill.classList.toggle("switchable",this.canSwitchTimeDisplay),this.canSwitchTimeDisplay?(this.timePill.setAttribute("role","button"),this.timePill.setAttribute("tabindex","0")):(this.timePill.removeAttribute("role"),this.timePill.removeAttribute("tabindex"))}applyMessages(t){this.messages=t,this.updateTimeLabelTitles(),this.updatePlayPauseButton(),this.updateFullscreenButton(),this.updateMuteButton(),this.updateObserverMapButton(),this.updateReferencesButton(),this.updateTracesButton(),this.updateMilestonesButton(),this.renderIssues()}updateTimeLabels(){const t=this.currentSighting.event,e=fM(t);this.realDurationMs=e!==void 0&&e>0?e:void 0,this.realStartMs=t.time?Yf(t.time):void 0;const i=this.currentSighting.timeline.duration;this.player.playbackRate=this.realDurationMs!==void 0&&i>0?i/this.realDurationMs:1,this.player.durationOverrideMs=i>0?0:this.realDurationMs??0,this.timeEndLabel.textContent=this.formatEndOfTimeline(),this.timeStartLabel.textContent=this.formatPosition(this.player.time),this.updateTimeLabelTitles()}formatPosition(t){if(this.realDurationMs===void 0)return Nl(t);const e=this.currentSighting.timeline.duration,i=e>0&&t<=e?t/e*this.realDurationMs:t;return this.canShowClockTime?gg(mg(this.realStartMs+i)):Nl(i)}formatEndOfTimeline(){return this.realDurationMs===void 0?Nl(this.currentSighting.timeline.duration):this.canShowClockTime?gg(mg(this.realStartMs+this.realDurationMs)):Nl(this.realDurationMs)}}function mg(a){const t=new Date(a);return{hour:t.getUTCHours(),minute:t.getUTCMinutes(),second:t.getUTCSeconds()}}function gg(a){if(a.hour===void 0)return"0:00";const t=e=>String(e).padStart(2,"0");return a.second?`${t(a.hour)}:${t(a.minute??0)}:${t(a.second)}`:`${t(a.hour)}:${t(a.minute??0)}`}function Nl(a){const t=Math.round(a/1e3),e=Math.floor(t/60),i=t%60;return`${e}:${String(i).padStart(2,"0")}`}const Kf="rr0-ufo";function PM(){customElements.get(Kf)||customElements.define(Kf,pe)}const Cb="recordingissues";/**
2182
+ `)}`)}}class ts{constructor(t){this.format=t}issues(t){const e=[];return this.object(t,this.format,"",e),e}object(t,e,i,n){if(!ts.isObject(t)){n.push({kind:"wrong-type",path:i||"(the file)",expected:"object",found:ts.typeOf(t)});return}for(const[s,r]of Object.entries(t)){const o=i?`${i}.${s}`:s,c=e[s];c?this.field(r,c,o,n):n.push({kind:"unknown-key",path:o})}}field(t,e,i,n){if(ts.isStated(t)){this.field(t.value,e,i,n);return}if(!(e.loose||t===void 0||t===null))switch(e.type){case"enum":(typeof t!="string"||!e.values?.includes(t))&&n.push({kind:"not-in-list",path:i,expected:(e.values??[]).map(s=>`"${s}"`).join(", "),found:JSON.stringify(t)});return;case"object":e.fields?this.object(t,e.fields,i,n):ts.isObject(t)||n.push({kind:"wrong-type",path:i,expected:"object",found:ts.typeOf(t)});return;case"array":Array.isArray(t)?e.fields&&t.forEach((s,r)=>{const o=ts.isStated(s)?s.value:s;this.object(o,e.fields,`${i}.${r}`,n)}):n.push({kind:"wrong-type",path:i,expected:"array",found:ts.typeOf(t)});return;default:typeof t!==e.type&&n.push({kind:"wrong-type",path:i,expected:e.type,found:ts.typeOf(t)})}}static isObject(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}static isStated(t){return ts.isObject(t)&&"value"in t&&Object.keys(t).every(e=>e==="value"||e==="basis"||e==="rationale")}static typeOf(t){return Array.isArray(t)?"array":t===null?"null":typeof t}}class as{static PIXELS_PER_INSTANT=2;static INSTANTS_PER_FLASH=2;static MAX_INSTANTS=512;static windowEndingAt(t,e){const i=Number.isFinite(e)?Math.max(0,e):0,n=Math.max(0,t-i*1e3),s=Math.max(0,t-n);return{fromMs:n,toMs:t,ms:s,seconds:s/1e3}}static instants(t,e,i,n,s){if(!(n>0))return 1;const r=s>0?as.travelDegOver(t,e,i,i+n*1e3)/s/as.PIXELS_PER_INSTANT:0,o=as.flashesOver(t,n)*as.INSTANTS_PER_FLASH,c=Math.ceil(Math.max(r,o));return c<2?1:Math.min(as.MAX_INSTANTS,c)}static travelDegOver(t,e,i,n){let s=0;for(const r of t){if(!r.track||r.track.length<2)continue;const o=as.directionAt(r,e,i),c=as.directionAt(r,e,n),l=Math.min(1,Math.max(-1,o.x*c.x+o.y*c.y+o.z*c.z));s=Math.max(s,Math.acos(l)*180/Math.PI)}return s}static flashesOver(t,e){let i=0;for(const n of t)for(const s of n.lights??[])s.pattern.kind==="flash"&&(i=Math.max(i,s.pattern.perMinute));return i/60*e}static directionAt(t,e,i){const n=Hr(t,i),s=n.eastM,r=n.altitudeM-e,o=n.northM,c=Math.hypot(s,r,o);return c===0?{x:0,y:1,z:0}:{x:s/c,y:r/c,z:o/c}}}const Ap=["en","fr","es","it"],cb={en:()=>je(()=>Promise.resolve().then(()=>fb),void 0,import.meta.url).then(a=>a.ufoMessages_en),fr:()=>je(()=>import("./UfoMessages_fr-bJNAf-AU.js"),[],import.meta.url).then(a=>a.ufoMessages_fr),es:()=>je(()=>import("./UfoMessages_es-LFW_B5H2.js"),[],import.meta.url).then(a=>a.ufoMessages_es),it:()=>je(()=>import("./UfoMessages_it-B-jnc4M-.js"),[],import.meta.url).then(a=>a.ufoMessages_it)};function lb(a){return cb[a]()}const hb={en:()=>je(()=>Promise.resolve().then(()=>eI),void 0,import.meta.url).then(a=>a.sightingMessages_en),fr:()=>je(()=>import("./SightingMessages_fr-BC_g9MLr.js"),[],import.meta.url).then(a=>a.sightingMessages_fr),es:()=>je(()=>import("./SightingMessages_es-B5pZonER.js"),[],import.meta.url).then(a=>a.sightingMessages_es),it:()=>je(()=>import("./SightingMessages_it-CJRrig_B.js"),[],import.meta.url).then(a=>a.sightingMessages_it)};function ub(a){return hb[a]()}function db(a){switch(a){case"fr":return je(()=>import("./TagNames_fr-Dnqq6HQ5.js"),[],import.meta.url).then(t=>t.tagNames_fr);case"es":return je(()=>import("./TagNames_es-BfnMpc3D.js"),[],import.meta.url).then(t=>t.tagNames_es);case"it":return je(()=>import("./TagNames_it-n6E4EGYO.js"),[],import.meta.url).then(t=>t.tagNames_it);default:return Promise.resolve({})}}function bM(a){switch(a){case"fr":return je(()=>import("./SceneNames_fr-BFN6x9Z7.js"),[],import.meta.url).then(t=>t.sceneNames_fr);case"es":return je(()=>import("./SceneNames_es-BuZsPlTw.js"),[],import.meta.url).then(t=>t.sceneNames_es);case"it":return je(()=>import("./SceneNames_it-BOuH3VIw.js"),[],import.meta.url).then(t=>t.sceneNames_it);default:return Promise.resolve(void 0)}}const SM={play:"Play",pause:"Pause",noDuration:"No observation duration",currentPosition:"Current position",duration:"Duration",switchToElapsed:"click to show elapsed time",switchToClockTime:"click to show the time of day",fullscreen:"Fullscreen",exitFullscreen:"Exit fullscreen",mute:"Mute",unmute:"Unmute",noSound:"No sound recorded",moments:"Moments",moreControls:"More controls",fewerControls:"Fewer controls",showObserverMap:"Show where the observer was",hideObserverMap:"Hide where the observer was",mapImageryUnavailable:"Aerial imagery unavailable",zoomMapIn:"Zoom in",zoomMapOut:"Zoom out",fitMap:"Back to the whole path",placeObserverHere:"Put the observer here",showReferences:"Show the pictures of the place",hideReferences:"Hide the pictures of the place",showTraces:"Show the investigator's lines",hideTraces:"Hide the investigator's lines",referenceOpacity:"Picture opacity",referencesMenu:"Pictures of the place",showMilestones:"Show the account's moments",hideMilestones:"Hide the account's moments",observerHere:"The observer, here",decorHere:"Scenery",recordingIssues:"{count} problem(s) in this recording: it may not play as its author meant",issueTemplates:Zo.EN},fb=Object.freeze(Object.defineProperty({__proto__:null,ufoMessages_en:SM},Symbol.toStringTag,{value:"Module"})),wM=Math.PI/180,pb=180/Math.PI,mb=256,_M=19,gb=1.25;function EM(a,t){return 156543.03392*Math.cos(a*wM)/2**t}function AM(a,t){return EM(a,t)*mb}function vb(a,t){let e=0;for(;e<_M&&AM(a,e+1)>=t;)e++;return e}function TM(a,t){return AM(a,t)}function Mb(a,t){const e=t*gb;let i=0;for(;i<_M&&EM(a,i)>e;)i++;return i}function Bh(a){const t=a*wM;return(1-Math.log(Math.tan(t)+1/Math.cos(t))/Math.PI)/2}function RM(a,t,e){const i=2**e;return{x:(a+180)/360*i,y:Bh(t)*i}}function DM(a,t,e){const i=Bh(a.north),n=Bh(a.south);return{x:(t-a.west)/(a.east-a.west),y:(Bh(e)-i)/(n-i)}}function yb(a,t,e){const{x:i,y:n}=RM(a,t,e);return{x:Math.floor(i),y:Math.floor(n),z:e}}function xb(a){const t=2**a.z,e=a.x/t*360-180,i=(a.x+1)/t*360-180,n=dg(a.y,t);return{south:dg(a.y+1,t),north:n,west:e,east:i}}function dg(a,t){const e=a/t;return Math.atan(Math.sinh(Math.PI*(1-2*e)))*pb}function IM(a,t,e,i){const n=yb(a,t,e),s=Math.floor(i/2),r=[];for(let l=-s;l<=s;l++)for(let h=-s;h<=s;h++)r.push({x:n.x+h,y:n.y+l,z:e});const o=r.map(xb),c={south:Math.min(...o.map(l=>l.south)),north:Math.max(...o.map(l=>l.north)),west:Math.min(...o.map(l=>l.west)),east:Math.max(...o.map(l=>l.east))};return{tiles:r,bounds:c}}const bb="#2ec4ff";class la{constructor(t){this.ctx=t}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(t,e){let i,n=1/0;for(const s of this.targets){const r=Math.hypot(s.x-t,s.y-e);r>s.radius||r>n||(i=s,n=r)}return i}get width(){return this.ctx.canvas.width}get height(){return this.ctx.canvas.height}paint(t){const{ctx:e}=this;e.save(),this.targets=[],e.clearRect(0,0,this.width,this.height),this.paintGround(t),this.paintNight(t.nightFraction),this.paintPath(t),this.paintTraces(t),t.position?(this.paintCone(t,t.position),this.paintDecor(t),this.paintMarkers(t),this.paintObserver(t,t.position)):(this.paintDecor(t),this.paintMarkers(t)),this.paintNorth(),this.paintFooter(t.bounds,t.attribution),e.restore()}toCanvas(t,e,i){const n=DM(t,i,e);return{x:n.x*this.width,y:n.y*this.height}}paintGround(t){const{ctx:e}=this;e.fillStyle="#1d2321",e.fillRect(0,0,this.width,this.height);const i=t.imagery;if(!i)return;const n=this.toCanvas(t.bounds,i.bounds.north,i.bounds.west),s=this.toCanvas(t.bounds,i.bounds.south,i.bounds.east);e.drawImage(i.source,n.x,n.y,s.x-n.x,s.y-n.y)}paintNight(t=0){if(t<=0)return;const{ctx:e}=this;e.save(),e.fillStyle=`rgba(6, 12, 30, ${Math.min(t,1)*.78})`,e.fillRect(0,0,this.width,this.height),e.restore()}paintDecor(t){const{ctx:e}=this;for(const i of t.decor){const n=this.toCanvas(t.bounds,i.lat,i.lng);if(i.label&&this.targets.push({kind:"decor",label:i.label,lat:i.lat,lng:i.lng,x:n.x,y:n.y,radius:7}),e.beginPath(),e.rect(n.x-3.5,n.y-3.5,7,7),e.fillStyle="rgba(120, 220, 255, 0.85)",e.fill(),e.lineWidth=1.5,e.strokeStyle="rgba(0, 0, 0, 0.7)",e.stroke(),i.headingDeg===void 0)continue;const s=(i.headingDeg-90)*Math.PI/180;e.beginPath(),e.moveTo(n.x,n.y),e.lineTo(n.x+Math.cos(s)*10,n.y+Math.sin(s)*10),e.lineWidth=3,e.strokeStyle="rgba(0, 0, 0, 0.6)",e.stroke(),e.lineWidth=1.5,e.strokeStyle="rgba(120, 220, 255, 0.9)",e.stroke()}}paintPath(t){if(!t.path.moved)return;const{ctx:e}=this,i=t.path.points.map(n=>this.toCanvas(t.bounds,n.lat,n.lng));e.beginPath(),e.moveTo(i[0].x,i[0].y);for(const n of i.slice(1))e.lineTo(n.x,n.y);e.lineJoin="round",e.lineCap="round",e.strokeStyle="rgba(0, 0, 0, 0.65)",e.lineWidth=5,e.stroke(),e.strokeStyle="rgba(255, 255, 255, 0.9)",e.lineWidth=2,e.stroke()}paintTraces(t){const{ctx:e}=this;for(const i of t.traces??[]){const n=i.points.map(r=>this.toCanvas(t.bounds,r.lat,r.lng));if(n.length===0)continue;const s=i.color??bb;if(i.kind==="point")e.beginPath(),e.moveTo(n[0].x,n[0].y-6),e.lineTo(n[0].x+6,n[0].y),e.lineTo(n[0].x,n[0].y+6),e.lineTo(n[0].x-6,n[0].y),e.closePath(),e.fillStyle=s,e.fill(),e.lineWidth=1.5,e.strokeStyle="rgba(0, 0, 0, 0.8)",e.stroke();else{e.beginPath(),e.moveTo(n[0].x,n[0].y);for(const r of n.slice(1))e.lineTo(r.x,r.y);i.kind==="polygon"&&e.closePath(),e.lineJoin="round",e.setLineDash([]),e.strokeStyle="rgba(0, 0, 0, 0.65)",e.lineWidth=4.5,e.stroke(),e.setLineDash([9,5]),e.strokeStyle=s,e.lineWidth=2.5,e.stroke(),e.setLineDash([])}if(i.label){e.font="11px sans-serif",e.textAlign="left",e.textBaseline="middle";let r=n[0];if(i.kind==="line"&&t.position){const o=this.toCanvas(t.bounds,t.position.lat,t.position.lng);r=n.reduce((c,l)=>Math.hypot(l.x-o.x,l.y-o.y)>Math.hypot(c.x-o.x,c.y-o.y)?l:c)}this.paintOutlinedText(i.label,r.x+9,r.y-9)}}}paintCone(t,e){const{headingDeg:i,coneHalfAngleDeg:n}=t;if(i===void 0||n===void 0)return;const{ctx:s}=this,r=this.toCanvas(t.bounds,e.lat,e.lng),o=Math.hypot(this.width,this.height),c=(i-90)*Math.PI/180,l=n*Math.PI/180;s.save(),s.beginPath(),s.moveTo(r.x,r.y),s.arc(r.x,r.y,o,c-l,c+l),s.closePath();const h=s.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)"),s.fillStyle=h,s.fill(),s.restore()}paintMarkers(t){const{ctx:e}=this;e.textAlign="center",e.textBaseline="middle",e.font="bold 10px sans-serif";for(const i of[...t.markers].sort((n,s)=>Number(n.current)-Number(s.current))){const n=this.toCanvas(t.bounds,i.lat,i.lng);this.targets.push({kind:"milestone",label:i.note?`${i.label} — ${i.note}`:i.label,lat:i.lat,lng:i.lng,t:i.t,x:n.x,y:n.y,radius:la.MARKER_RADIUS_PX}),e.beginPath(),e.arc(n.x,n.y,la.MARKER_RADIUS_PX,0,Math.PI*2),e.fillStyle=i.current?"rgba(255, 224, 130, 0.95)":"rgba(0, 0, 0, 0.55)",e.fill(),e.lineWidth=2,e.strokeStyle="rgba(255, 255, 255, 0.9)",e.stroke(),e.fillStyle=i.current?"#1d2321":"#fff",e.fillText(i.label,n.x,n.y)}}paintObserver(t,e){const{ctx:i}=this,n=this.toCanvas(t.bounds,e.lat,e.lng);t.observerLabel&&this.targets.push({kind:"observer",label:t.observerLabel,lat:e.lat,lng:e.lng,x:n.x,y:n.y,radius:8});const s=t.markers.some(r=>{if(!r.current)return!1;const o=si(r.lat,r.lng,e.lat,e.lng);return Math.hypot(o.x,o.z)<=la.ON_MARKER_M});i.beginPath(),i.arc(n.x,n.y,s?la.MARKER_RADIUS_PX+2.5:5.5,0,Math.PI*2),s||(i.fillStyle="#ff5a3c",i.fill()),i.lineWidth=4,i.strokeStyle="rgba(0, 0, 0, 0.5)",i.stroke(),i.lineWidth=s?3:2.5,i.strokeStyle=s?"#ff5a3c":"#fff",i.stroke()}paintNorth(){const{ctx:t}=this,e=this.width-14,i=16;t.beginPath(),t.moveTo(e,i-9),t.lineTo(e-4.5,i+5),t.lineTo(e,i+2),t.lineTo(e+4.5,i+5),t.closePath(),t.fillStyle="rgba(255, 255, 255, 0.92)",t.strokeStyle="rgba(0, 0, 0, 0.6)",t.lineWidth=1,t.fill(),t.stroke(),t.font="bold 9px sans-serif",t.textAlign="center",t.textBaseline="top",t.strokeText("N",e,i+6),t.fillText("N",e,i+6)}paintFooter(t,e){const{ctx:i}=this;i.font="9px sans-serif",i.textBaseline="bottom";const n=e?this.wrap(e,this.width-20):[];let s=this.height-4;i.textAlign="right";for(const f of n.slice().reverse())this.paintOutlinedText(f,this.width-6,s),s-=11;const r=(t.south+t.north)/2,c=Math.abs(si(r,t.east,r,t.west).x)/this.width,l=la.SCALE_STEPS_M.find(f=>f/c<=this.width/3);if(l===void 0)return;const h=l/c,u=8,d=s-3;i.lineWidth=3,i.strokeStyle="rgba(0, 0, 0, 0.6)",i.beginPath(),i.moveTo(u,d),i.lineTo(u+h,d),i.stroke(),i.lineWidth=1.5,i.strokeStyle="rgba(255, 255, 255, 0.95)",i.stroke(),i.textAlign="left",this.paintOutlinedText(l>=1e3?`${l/1e3} km`:`${l} m`,u,d-3)}paintOutlinedText(t,e,i){const{ctx:n}=this;n.lineWidth=3,n.strokeStyle="rgba(0, 0, 0, 0.75)",n.strokeText(t,e,i),n.fillStyle="#fff",n.fillText(t,e,i)}wrap(t,e){const i=[];let n="";for(const s of t.split(" ")){const r=n?`${n} ${s}`:s;n&&this.ctx.measureText(r).width>e?(i.push(n),n=s):n=r}return n&&i.push(n),i}}class ni{static MIN_ZOOM=.25;static MAX_ZOOM=64;zoom=1;centerX=.5;centerY=.5;get changed(){return this.zoom!==1||this.centerX!==.5||this.centerY!==.5}get zoomFactor(){return this.zoom}reset(){this.zoom=1,this.centerX=.5,this.centerY=.5}zoomAt(t,e,i){const n=Math.min(ni.MAX_ZOOM,Math.max(ni.MIN_ZOOM,this.zoom*i)),s=this.centerX+(t-.5)/this.zoom,r=this.centerY+(e-.5)/this.zoom;this.centerX=s-(t-.5)/n,this.centerY=r-(e-.5)/n,this.zoom=n}panBy(t,e){this.centerX-=t/this.zoom,this.centerY-=e/this.zoom}refit(t,e){if(!this.changed)return;const i=this.boundsWithin(t),n=ni.mercatorY01(e.north),s=ni.mercatorY01(e.south),r=ni.mercatorY01(i.north),o=ni.mercatorY01(i.south);this.zoom=(e.east-e.west)/(i.east-i.west),this.centerX=((i.west+i.east)/2-e.west)/(e.east-e.west),this.centerY=((r+o)/2-n)/(s-n)}keepInView(t,e,i){if(!this.changed)return!1;const n=this.boundsWithin(t),s=ni.mercatorY01(n.north),r=ni.mercatorY01(n.south),o=(e.lng-n.west)/(n.east-n.west),c=(ni.mercatorY01(e.lat)-s)/(r-s);return o>=i&&o<=1-i&&c>=i&&c<=1-i?!1:(this.panBy(.5-o,.5-c),!0)}boundsWithin(t){if(!this.changed)return t;const e=.5/this.zoom,i=ni.mercatorY01(t.north),n=ni.mercatorY01(t.south),s=t.east-t.west;return{west:t.west+(this.centerX-e)*s,east:t.west+(this.centerX+e)*s,north:ni.latitudeAt(i+(this.centerY-e)*(n-i)),south:ni.latitudeAt(i+(this.centerY+e)*(n-i))}}static including(t,e,i=3){const n=(t.north+t.south)/2,s=(t.east+t.west)/2,r=si(n,t.east,n,s).x;let o=r;for(const c of e){const{x:l,z:h}=si(c.lat,c.lng,n,s),u=Math.max(Math.abs(l),Math.abs(h));u<=r*i&&(o=Math.max(o,u*1.15))}return o<=r?t:{north:Nn(0,-o,n,s).lat,south:Nn(0,o,n,s).lat,east:Nn(o,0,n,s).lng,west:Nn(-o,0,n,s).lng}}static expand(t,e){const i=t.east-t.west,n=t.north-t.south;return{west:t.west-i*e,east:t.east+i*e,south:t.south-n*e,north:t.north+n*e}}static pointAt(t,e,i){const n=ni.mercatorY01(t.north),s=ni.mercatorY01(t.south);return{lat:ni.latitudeAt(n+i*(s-n)),lng:t.west+e*(t.east-t.west)}}static mercatorY01(t){const e=t*Math.PI/180;return(1-Math.log(Math.tan(e)+1/Math.cos(e))/Math.PI)/2}static latitudeAt(t){return Math.atan(Math.sinh(Math.PI*(1-2*t)))*180/Math.PI}}const Un=256,fg=3,Sb=32768;class wb{fetchImpl;tileUrlTemplate;constructor(t={}){this.fetchImpl=t.fetchImpl??fetch.bind(globalThis),this.tileUrlTemplate=t.tileUrlTemplate??"https://s3.amazonaws.com/elevation-tiles-prod/terrarium/{z}/{x}/{y}.png"}async getElevationGrid(t,e){const i=(t.south+t.north)/2,n=(t.west+t.east)/2,s=Math.abs(si(i,t.east,i,t.west).x),r=Math.abs(si(t.north,n,t.south,n).z),o=vb(i,Math.max(s,r)),{tiles:c}=IM(n,i,o,fg),l=fg*Un,h=new Float32Array(l*l),u=c[0];await Promise.all(c.map(f=>this.decodeTileInto(f,u,h,l)));const d=new Float32Array(e.width*e.height);for(let f=0;f<e.height;f++){const p=t.north+(t.south-t.north)*(f/(e.height-1));for(let v=0;v<e.width;v++){const m=t.west+(t.east-t.west)*(v/(e.width-1));d[f*e.width+v]=this.sampleAt(p,m,o,u,h,l)}}return{heights:d,width:e.width,height:e.height,bounds:t}}async decodeTileInto(t,e,i,n){const s=this.tileUrlTemplate.replace("{z}",String(t.z)).replace("{x}",String(t.x)).replace("{y}",String(t.y)),r=await this.fetchImpl(s);if(!r.ok)throw new Error(`Elevation tile fetch failed (${r.status}): ${s}`);const o=await createImageBitmap(await r.blob()),c=document.createElement("canvas");c.width=Un,c.height=Un;const l=c.getContext("2d");if(!l)throw new Error("2D canvas context unavailable");l.drawImage(o,0,0);const{data:h}=l.getImageData(0,0,Un,Un),u=(t.x-e.x)*Un,d=(t.y-e.y)*Un;for(let f=0;f<Un;f++)for(let p=0;p<Un;p++){const v=(f*Un+p)*4,m=h[v]*256+h[v+1]+h[v+2]/256-Sb,g=u+p,b=d+f;i[b*n+g]=m}}sampleAt(t,e,i,n,s,r){const{x:o,y:c}=RM(e,t,i),l=(o-n.x)*Un,h=(c-n.y)*Un,u=Math.max(0,Math.min(r-1,Math.floor(l))),d=Math.max(0,Math.min(r-1,Math.floor(h))),f=Math.min(r-1,u+1),p=Math.min(r-1,d+1),v=l-u,m=h-d,g=s[d*r+u],b=s[d*r+f],S=s[p*r+u],M=s[p*r+f],x=g+(b-g)*v,_=S+(M-S)*v;return x+(_-x)*m}}const Hh=256,_b=5;async function Eb(a,t,e,i){const n=(a.south+a.north)/2,s=(a.west+a.east)/2,r=Math.abs(si(n,a.east,n,a.west).x),o=Math.abs(si(a.north,s,a.south,s).z),c=Math.max(r,o),{zoom:l,gridSize:h}=Ab(n,c,Math.max(t.width,t.height)),{tiles:u,bounds:d}=IM(s,n,l,h),f=h*Hh,p=document.createElement("canvas");p.width=f,p.height=f;const v=p.getContext("2d");if(!v)throw new Error("2D canvas context unavailable");const m=u[0];await Promise.all(u.map(async M=>{const x=e(M),_=await i(x);if(!_.ok)throw new Error(`Imagery tile fetch failed (${_.status}): ${x}`);const A=await createImageBitmap(await _.blob());v.drawImage(A,(M.x-m.x)*Hh,(M.y-m.y)*Hh)}));const g=Math.min(Math.max(t.width,t.height),f);if(g===f)return{source:p,width:f,height:f,bounds:d};const b=document.createElement("canvas");b.width=g,b.height=g;const S=b.getContext("2d");if(!S)throw new Error("2D canvas context unavailable");return S.drawImage(p,0,0,f,f,0,0,g,g),{source:b,width:g,height:g,bounds:d}}function Ab(a,t,e){let i=Mb(a,t/Math.max(1,e)),n=pg(a,i,t);for(;n>_b&&i>0;)i--,n=pg(a,i,t);return{zoom:i,gridSize:n,mPerPixel:TM(a,i)/Hh}}function pg(a,t,e){const i=Math.ceil(e/2/TM(a,t));return Math.max(3,2*i+1)}class Tb{attribution="Imagery © Esri, Maxar, Earthstar Geographics, and the GIS User Community";fetchImpl;tileUrlTemplate;constructor(t={}){this.fetchImpl=t.fetchImpl??fetch.bind(globalThis),this.tileUrlTemplate=t.tileUrlTemplate??"https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}"}async getImageryTexture(t,e){return Eb(t,e,i=>this.tileUrlTemplate.replace("{z}",String(i.z)).replace("{y}",String(i.y)).replace("{x}",String(i.x)),this.fetchImpl)}}class es{attribution="Roads © OpenStreetMap contributors, as surveyed today";contemporary=!0;static DRIVABLE=["motorway","trunk","primary","secondary","tertiary","unclassified","residential","service","track","motorway_link","trunk_link","primary_link","secondary_link","tertiary_link"];static WIDTH_M={motorway:11,trunk:9,primary:8,secondary:7,tertiary:6.5,unclassified:5.5,residential:5.5,service:4,track:3.5};static DEFAULT_WIDTH_M=5;static ENDPOINTS=["https://overpass-api.de/api/interpreter","https://overpass.kumi.systems/api/interpreter","https://overpass.private.coffee/api/interpreter"];fetchImpl;endpoints;constructor(t={}){this.fetchImpl=t.fetchImpl??fetch.bind(globalThis),this.endpoints=t.endpoints??es.ENDPOINTS}static queue=Promise.resolve();static RETRY_MS=4e3;async getRoads(t){const e=`${t.south},${t.west},${t.north},${t.east}`,i=`[out:json][timeout:30];way["highway"~"^(${es.DRIVABLE.join("|")})$"](${e});out geom;`;return this.waysFrom(await this.queued(()=>this.ask(i)))}waysFrom(t){const e=[];for(const i of t.elements??[]){const n=i.geometry,s=i.tags;!s||!n||n.length<2||e.push({id:`osm-${i.id??e.length}`,name:s.name,surface:es.surfaceOf(s),widthM:es.widthOf(s),points:n.map(r=>({lat:r.lat,lng:r.lon}))})}return e}queued(t){const e=es.queue.then(t,t);return es.queue=e.catch(()=>{}),e}async ask(t){let e;for(const i of this.endpoints)for(let n=0;n<2;n++){try{const s=await this.fetchImpl(`${i}?data=${encodeURIComponent(t)}`);if(s.ok)return await s.json();if(e=new Error(`${new URL(i).host} refused (${s.status})`),s.status!==429&&s.status!==504)break}catch(s){e=new Error(`${new URL(i).host} unreachable (${String(s)})`);break}await new Promise(s=>setTimeout(s,es.RETRY_MS))}throw e??new Error("No Overpass instance answered")}static widthOf(t){const e=Number.parseFloat(t.width??t.est_width??"");if(Number.isFinite(e)&&e>0)return e;const i=Number.parseInt(t.lanes??"",10);return Number.isFinite(i)&&i>0?i*3.5:es.WIDTH_M[t.highway]??es.DEFAULT_WIDTH_M}static surfaceOf(t){const e=t.surface;return e==="dirt"||e==="earth"||e==="mud"?"dirt":e==="gravel"||e==="fine_gravel"||e==="compacted"||e==="ground"||e==="sand"||e==="unpaved"?"gravel":e?"paved":t.highway==="track"?"gravel":"paved"}}const xd="https://ufoathome.org/roads/index.json";class Do{attributionRead;contemporaryRead;fetchImpl;indexUrls;fallback;index;static shared=new Map;sharing;constructor(t={}){this.sharing=!t.fetchImpl,this.fetchImpl=t.fetchImpl??fetch.bind(globalThis),this.indexUrls=t.indexUrls??Do.defaultIndexUrls(),this.fallback=t.fallback}get attribution(){return this.attributionRead??this.fallback?.attribution??"Roads © OpenStreetMap contributors"}get contemporary(){return this.contemporaryRead??this.fallback?.contemporary??!0}async getRoads(t){const e=await this.held(t);if(e)return e;if(!this.fallback)return[];const i=await this.fallback.getRoads(t);return this.attributionRead=this.fallback.attribution,this.contemporaryRead=this.fallback.contemporary,i}async held(t){let e;try{e=await this.load()}catch{return}const i=e.find(({entry:n})=>n.north>=t.north&&n.south<=t.south&&n.east>=t.east&&n.west<=t.west);if(i)try{const n=await this.fetchImpl(new URL(i.entry.file,i.indexUrl).href);if(!n.ok)return;const s=await n.json();return Array.isArray(s?.ways)?(this.attributionRead=s.attribution,this.contemporaryRead=s.contemporary,s.ways):void 0}catch{return}}load(){if(this.index)return this.index;if(!this.sharing)return this.index=this.fetchFirstAvailable();const t=this.indexUrls.join(`
2183
+ `);let e=Do.shared.get(t);return e||(e=this.fetchFirstAvailable(),Do.shared.set(t,e),e.then(i=>{i.length===0&&Do.shared.delete(t)})),this.index=e}async fetchFirstAvailable(){for(const t of this.indexUrls)try{const e=await this.fetchImpl(t);if(!e.ok)continue;const i=await e.json();if(Array.isArray(i?.entries))return i.entries.map(n=>({entry:n,indexUrl:t}))}catch{}return[]}static defaultIndexUrls(){const t=`?v=${encodeURIComponent("0.105.1")}`,e=typeof location>"u"?void 0:new URL("/roads/index.json",location.href).href;return(e&&e!==xd?[e,xd]:[xd]).map(i=>i+t)}}function Rb(){return{elevation:new wb,imagery:CM(),roads:Db()}}function CM(){return new Tb}function Db(){return new Do({fallback:new es})}const Ib=new Set,ks="show-observer-map",Fs="hide-milestones";class pe extends HTMLElement{static get observedAttributes(){return["src",ks,Fs]}shadow;stageElement;canvas;canvasRenderer;tooltip;toolbar;issuesBox;issuesButton;issuesPanel;playPauseButton;static OBSERVER_MAP_MIN_SPAN_M=400;static OBSERVER_MAP_MARGIN=.6;static OBSERVER_MAP_IMAGERY_PX=768;fullscreenButton;cornerButtons;observerMapButton;referencesButton;tracesButton;tracesShownState=!0;referenceOpacityInput;referencesShownState=!0;accountHidden=!1;referenceViews=new Map;referencesMenu;referenceOpacityTouched=!1;milestonesButton;observerMapPanel;observerMapCanvas;observerMapRenderer;mapZoomInButton;mapZoomOutButton;mapFitButton;observerMapView=new ni;observerMapDrag;suppressObserverMapClick=!1;observerMapImageryTimer;observerPlacing=!1;seekInput;playbackFlash;milestoneMarks;milestoneCaption;timeStartLabel;timeEndLabel;timePill;muteButton;volumeInput;controlsRow;momentsBox;momentsButton;momentsCurrent;momentsMenu;moreButton;controlsRight;seekSegments;seekDot;seekPreview;seekPreviewCanvas;seekPreviewTitle;seekPreviewTime;observerPath;observerMapBounds;observerMapImagery;observerMapImageryBounds;observerMapImageryViewWidth=0;observerMapImageryLoading=!1;observerMapImageryCredit;observerMapImageryFailed=!1;creditShownExternally=!1;lookYawDeg=0;lookPitchDeg=0;milestonesShown=!0;currentSighting=td.create();issues=[];issueCheck=0;sightingAudio=new nb;soundPreview;player;loopEnabled=!1;playbackBeforeClick;highlightedSourceIds=new Set;paintsShapes=!0;steadyObserver=!1;static LIVE_BODY_MAX_RATE=2;get steadyBody(){return this.steadyObserver||this.player.playbackState!=="playing"||this.player.playbackRate>pe.LIVE_BODY_MAX_RATE}selectionShown=!0;overlayPainter;enableClickToPlay=!0;fullscreenTarget;messages=SM;realDurationMs;realStartMs;showClockTime=!0;handleFullscreenChange=()=>{this.updateFullscreenButton(),this.updateMuteButton(),this.resizeObserverMap()};controlsFitObserver=typeof ResizeObserver>"u"?void 0:new ResizeObserver(()=>this.fitControls());controlsMutations;fitControls(){const t=this.controlsRow,e=t.classList.contains("more-open"),i=()=>t.scrollWidth>t.clientWidth+1,n=!this.momentsMenu.hidden;if(this.momentsMenu.hidden=!0,t.classList.remove("narrow","more-open","nomoments","compact","tiny"),t.clientWidth>0&&i()){t.classList.add("narrow");for(const s of["nomoments","compact","tiny"]){if(!i())break;t.classList.add(s)}e&&t.classList.add("more-open")}this.momentsMenu.hidden=!n,this.updateMoreButton()}setControlsFolded(t){this.controlsRow.classList.toggle("more-open",!t),this.updateMoreButton()}updateMoreButton(){const t=this.controlsRow.classList.contains("more-open");pe.setIcon(this.moreButton,t?Gt.UNFOLDED:Gt.FOLDED);const e=t?this.messages.fewerControls:this.messages.moreControls;this.moreButton.title=e,this.moreButton.setAttribute("aria-label",e),this.moreButton.setAttribute("aria-expanded",String(t))}addControl(t){this.controlsRight.insertBefore(t,this.fullscreenButton.parentElement===this.controlsRight?this.fullscreenButton:null),this.fitControls()}observerMapResizeObserver=typeof ResizeObserver>"u"?void 0:new ResizeObserver(()=>this.resizeObserverMap());resizeObserverMap(){this.observerMapPanel.hidden||(this.sizeObserverMapCanvas(),this.paintObserverMap(this.currentTime))}simulatedFullscreen=!1;styleBeforeSimulatedFullscreen;bodyOverflowBeforeSimulatedFullscreen;handleSimulatedFullscreenKey=t=>{t.key==="Escape"&&this.exitSimulatedFullscreen()};handlePointerMove=t=>{const e=this.canvasPointFromEvent(t),i=e&&this.shapeAt(e.x,e.y),n=this.said.read(i?.shape.title);if(!n){this.tooltip.hidden=!0;return}this.tooltip.textContent=n,this.tooltip.hidden=!1;const s=this.stageElement.getBoundingClientRect();this.tooltip.style.left=`${t.clientX-s.left+12}px`,this.tooltip.style.top=`${t.clientY-s.top+12}px`};handleObserverMapPointerMove=t=>{if(this.dragObserverMap(t))return;const e=this.observerMapTargetFrom(t);if(!e){if(!this.observerPlacing){this.tooltip.hidden=!0,this.observerMapCanvas.style.cursor="grab";return}this.observerMapCanvas.style.cursor="crosshair",this.showObserverMapTooltip(t,this.messages.placeObserverHere);return}this.observerMapCanvas.style.cursor="pointer",this.showObserverMapTooltip(t,e.label)};showObserverMapTooltip(t,e){this.tooltip.textContent=e,this.tooltip.hidden=!1;const i=this.stageElement.getBoundingClientRect();this.tooltip.style.left=`${t.clientX-i.left+12}px`,this.tooltip.style.top=`${t.clientY-i.top+12}px`}handleObserverMapClick=t=>{if(this.suppressObserverMapClick){this.suppressObserverMapClick=!1;return}const e=this.observerMapTargetFrom(t);if(!e){this.observerPlacing&&this.placeObserverFrom(t);return}if(e.kind==="milestone"&&e.t!==void 0){this.player.seek(e.t);return}this.dispatchEvent(new CustomEvent("lookat",{detail:{lat:e.lat,lng:e.lng,kind:e.kind},bubbles:!0,composed:!0}))};observerMapTargetFrom(t){const e=this.observerMapCanvas.getBoundingClientRect();if(!(e.width===0||e.height===0))return this.observerMapRenderer.hitTest((t.clientX-e.left)/e.width*this.observerMapCanvas.width,(t.clientY-e.top)/e.height*this.observerMapCanvas.height)}handlePointerLeave=()=>{this.tooltip.hidden=!0};handleObserverMapPointerDown=t=>{t.button===0&&(this.suppressObserverMapClick=!1,this.observerMapDrag={pointerId:t.pointerId,startX:t.clientX,startY:t.clientY,lastX:t.clientX,lastY:t.clientY,moved:!1})};handleObserverMapPointerUp=t=>{const e=this.observerMapDrag;!e||e.pointerId!==t.pointerId||(this.observerMapDrag=void 0,this.observerMapCanvas.classList.remove("dragging"),e.moved&&(this.suppressObserverMapClick=!0,this.paintObserverMap(this.currentTime),this.observerMapCanvas.hasPointerCapture?.(t.pointerId)&&this.observerMapCanvas.releasePointerCapture(t.pointerId)))};dragObserverMap(t){const e=this.observerMapDrag;if(!e||e.pointerId!==t.pointerId)return!1;if(!e.moved){if(Math.hypot(t.clientX-e.startX,t.clientY-e.startY)<pe.OBSERVER_MAP_DRAG_PX)return!1;e.moved=!0,this.tooltip.hidden=!0,this.observerMapCanvas.classList.add("dragging"),this.observerMapCanvas.setPointerCapture?.(t.pointerId)}const i=this.observerMapCanvas.getBoundingClientRect();return i.width>0&&i.height>0&&(this.observerMapView.panBy((t.clientX-e.lastX)/i.width,(t.clientY-e.lastY)/i.height),this.observerMapViewChanged()),e.lastX=t.clientX,e.lastY=t.clientY,!0}static OBSERVER_MAP_DRAG_PX=4;handleObserverMapWheel=t=>{t.preventDefault();const e=this.observerMapCanvas.getBoundingClientRect();if(e.width===0||e.height===0)return;const i=t.deltaMode===0?t.deltaY:t.deltaY*40;this.zoomObserverMap((t.clientX-e.left)/e.width,(t.clientY-e.top)/e.height,Math.exp(-i*.002))};zoomObserverMap(t,e,i){this.observerMapView.zoomAt(t,e,i),this.observerMapViewChanged()}observerMapViewChanged(){this.mapFitButton.hidden=!this.observerMapView.changed,this.mapZoomInButton.disabled=this.observerMapView.zoomFactor>=ni.MAX_ZOOM,this.mapZoomOutButton.disabled=this.observerMapView.zoomFactor<=ni.MIN_ZOOM,this.paintObserverMap(this.currentTime),this.scheduleObserverMapImagery()}scheduleObserverMapImagery(){this.observerMapImageryTimer===void 0&&(this.observerMapImageryTimer=setTimeout(()=>{this.observerMapImageryTimer=void 0,this.loadObserverMapImagery()},pe.OBSERVER_MAP_IMAGERY_DELAY_MS))}static OBSERVER_MAP_FOLLOW_MARGIN=.1;static OBSERVER_MAP_IMAGERY_DELAY_MS=300;get observerMapViewBounds(){return this.observerMapBounds&&this.observerMapView.boundsWithin(this.observerMapBounds)}placeObserverFrom(t){const e=this.observerMapViewBounds,i=this.observerMapCanvas.getBoundingClientRect();if(!e||i.width===0||i.height===0)return;const n=ni.pointAt(e,(t.clientX-i.left)/i.width,(t.clientY-i.top)/i.height);this.dispatchEvent(new CustomEvent("observerplace",{detail:n,bubbles:!0,composed:!0}))}constructor(){super(),this.shadow=this.attachShadow({mode:"open"});const t=document.createElement("template");t.innerHTML=`<style>${Kx}</style>${$x}`,this.shadow.appendChild(t.content.cloneNode(!0)),this.stageElement=this.shadow.getElementById("stage"),this.canvas=this.shadow.getElementById("canvas"),this.canvasRenderer=new al(this.canvas.getContext("2d")),this.tooltip=this.shadow.getElementById("tooltip"),this.toolbar=this.shadow.getElementById("toolbar"),this.issuesBox=this.shadow.getElementById("issues"),this.issuesButton=this.shadow.getElementById("issues-button"),this.issuesPanel=this.shadow.getElementById("issues-panel"),this.issuesButton.addEventListener("click",e=>{e.stopPropagation(),this.issuesPanel.hidden=!this.issuesPanel.hidden,this.issuesButton.setAttribute("aria-expanded",String(!this.issuesPanel.hidden))}),this.playPauseButton=this.shadow.getElementById("play-pause"),this.fullscreenButton=this.shadow.getElementById("fullscreen"),this.cornerButtons=this.shadow.getElementById("corner-buttons"),this.observerMapButton=this.shadow.getElementById("observer-map"),this.referencesButton=this.shadow.getElementById("references"),this.tracesButton=this.shadow.getElementById("traces"),this.referenceOpacityInput=this.shadow.getElementById("reference-opacity"),this.referencesMenu=this.shadow.getElementById("references-menu"),this.milestonesButton=this.shadow.getElementById("milestones"),this.observerMapPanel=this.shadow.getElementById("observer-map-panel"),this.observerMapCanvas=this.shadow.getElementById("observer-map-canvas"),this.observerMapRenderer=new la(this.observerMapCanvas.getContext("2d")),this.mapZoomInButton=this.shadow.getElementById("map-zoom-in"),this.mapZoomOutButton=this.shadow.getElementById("map-zoom-out"),this.mapFitButton=this.shadow.getElementById("map-fit"),this.seekInput=this.shadow.getElementById("seek"),this.playbackFlash=this.shadow.getElementById("playback-flash"),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"),this.timePill=this.shadow.getElementById("time"),this.muteButton=this.shadow.getElementById("mute"),this.controlsRight=this.shadow.getElementById("controls-right"),this.seekSegments=this.shadow.getElementById("seek-segments"),this.seekDot=this.shadow.getElementById("seek-dot"),this.seekPreview=this.shadow.getElementById("seek-preview"),this.seekPreviewCanvas=this.shadow.getElementById("seek-preview-canvas"),this.seekPreviewTitle=this.shadow.getElementById("seek-preview-title"),this.seekPreviewTime=this.shadow.getElementById("seek-preview-time"),this.timePill.addEventListener("click",()=>this.toggleTimeDisplay()),this.timePill.addEventListener("keydown",e=>{e.key!=="Enter"&&e.key!==" "||(e.preventDefault(),this.toggleTimeDisplay())}),this.volumeInput=this.shadow.getElementById("volume"),this.controlsRow=this.shadow.querySelector(".controls"),this.momentsBox=this.shadow.getElementById("moments"),this.momentsButton=this.shadow.getElementById("moments-button"),this.momentsCurrent=this.shadow.getElementById("moments-current"),this.momentsMenu=this.shadow.getElementById("moments-menu"),this.momentsButton.addEventListener("click",()=>this.toggleMomentsMenu()),this.moreButton=this.shadow.getElementById("controls-more"),this.moreButton.addEventListener("click",()=>this.setControlsFolded(this.controlsRow.classList.contains("more-open"))),this.muteButton.addEventListener("click",()=>this.toggleMuted()),this.volumeInput.addEventListener("input",()=>{this.setVolume(Number(this.volumeInput.value))}),this.fullscreenTarget=this.stageElement,this.playPauseButton.addEventListener("click",()=>this.togglePlayPause()),this.fullscreenButton.addEventListener("click",()=>this.toggleFullscreen()),this.addEventListener("keydown",this.handleFullscreenKey),this.observerMapButton.addEventListener("click",()=>this.toggleObserverMap()),this.referencesButton.addEventListener("click",()=>this.toggleReferences()),this.tracesButton.addEventListener("click",()=>this.toggleTraces()),this.referenceOpacityInput.addEventListener("input",()=>{this.referenceOpacityTouched=!0,this.dispatchReferenceView()}),this.milestonesButton.addEventListener("click",()=>this.toggleMilestones()),this.observerMapCanvas.addEventListener("pointermove",this.handleObserverMapPointerMove),this.observerMapCanvas.addEventListener("pointerleave",this.handlePointerLeave),this.observerMapCanvas.addEventListener("click",this.handleObserverMapClick),this.observerMapCanvas.addEventListener("pointerdown",this.handleObserverMapPointerDown),this.observerMapCanvas.addEventListener("pointerup",this.handleObserverMapPointerUp),this.observerMapCanvas.addEventListener("pointercancel",this.handleObserverMapPointerUp),this.observerMapCanvas.addEventListener("wheel",this.handleObserverMapWheel,{passive:!1}),this.mapZoomInButton.addEventListener("click",()=>this.zoomObserverMap(.5,.5,2)),this.mapZoomOutButton.addEventListener("click",()=>this.zoomObserverMap(.5,.5,.5)),this.mapFitButton.addEventListener("click",()=>{this.observerMapView.reset(),this.observerMapViewChanged()}),this.seekInput.addEventListener("input",()=>this.player.seek(this.snapSeekToMark(Number(this.seekInput.value)))),this.seekInput.addEventListener("pointerdown",e=>{this.suspendForScrub(),this.seekSnapArmed=!0,this.nameMarkUnder(e),this.beginTouchScrub(e)}),this.seekInput.addEventListener("pointerup",e=>{this.seekSnapArmed=!1,this.endTouchScrub(e)}),this.seekInput.addEventListener("pointercancel",e=>this.endTouchScrub(e)),this.seekInput.addEventListener("pointermove",e=>{this.nameMarkUnder(e),this.hoverSeek(e),this.touchScrub(e)}),this.seekInput.addEventListener("pointerleave",()=>{this.seekInput.removeAttribute("title"),this.leaveSeek()}),this.seekInput.addEventListener("keydown",this.handleSeekKey),this.stageElement.addEventListener("pointerdown",()=>{this.handlePointerDown(),this.touchedStage()},!0);for(const e of["touchend","click"])this.stageElement.addEventListener(e,()=>this.sightingAudio.resume(),!0);this.stageElement.addEventListener("pointermove",()=>this.touchedStage()),this.canvas.addEventListener("click",e=>{if(this.enableClickToPlay){if(this.tapRevealedOnly){this.tapRevealedOnly=!1;return}e.detail<=1&&(this.playbackBeforeClick={state:this.playbackState,time:this.currentTime}),this.togglePlayPause()}}),this.canvas.addEventListener("dblclick",e=>{this.enableClickToPlay&&(e.preventDefault(),this.restorePlayback(),this.toggleFullscreen())}),this.canvas.addEventListener("pointermove",this.handlePointerMove),this.canvas.addEventListener("pointerleave",this.handlePointerLeave),document.addEventListener("fullscreenchange",this.handleFullscreenChange),document.addEventListener("pointerdown",this.handleMomentsDismiss,!0),document.addEventListener("keydown",this.handleMomentsDismiss,!0),document.addEventListener("visibilitychange",this.handleVisibility),window.addEventListener("pagehide",this.handleHidden),document.addEventListener("pointerup",this.handlePointerRelease,!0),document.addEventListener("pointercancel",this.handlePointerRelease,!0),this.observerMapResizeObserver?.observe(this.observerMapPanel),this.controlsFitObserver?.observe(this.controlsRow),this.controlsFitObserver?.observe(this.controlsRow.querySelector(".controls-left")),typeof MutationObserver<"u"&&(this.controlsMutations=new MutationObserver(()=>this.fitControls()),this.controlsMutations.observe(this.controlsRight,{attributes:!0,attributeFilter:["hidden"],childList:!0,subtree:!0})),this.hostControls(void 0),this.player=this.createPlayer(),this.updateTimeLabels(),this.updatePlayPauseButton(),this.updateFullscreenButton(),this.updateMuteButton(),this.updateObserverMapButton(),this.updateReferencesButton(),this.updateTracesButton(),this.updateMilestonesButton(),this.refresh()}connectedCallback(){this.saidTexts=void 0,this.loadLocaleMessages();const t=this.getAttribute("src");t&&this.loadFromSrc(t)}disconnectedCallback(){document.removeEventListener("fullscreenchange",this.handleFullscreenChange),document.removeEventListener("pointerdown",this.handleMomentsDismiss,!0),document.removeEventListener("keydown",this.handleMomentsDismiss,!0),document.removeEventListener("visibilitychange",this.handleVisibility),window.removeEventListener("pagehide",this.handleHidden),document.removeEventListener("pointerup",this.handlePointerRelease,!0),document.removeEventListener("pointercancel",this.handlePointerRelease,!0),window.clearTimeout(this.controlsIdleTimer),this.observerMapResizeObserver?.disconnect(),this.controlsFitObserver?.disconnect(),this.controlsMutations?.disconnect(),this.exitSimulatedFullscreen(),this.sightingAudio.dispose()}attributeChangedCallback(t,e,i){t==="src"&&i&&i!==e&&this.isConnected&&this.loadFromSrc(i),t===ks&&this.applyObserverMapDefault(),t===Fs&&this.setMilestonesShown(!this.hasAttribute(Fs))}async loadFromSrc(t){this.sightingData=await Gc.json(t)}get sightingData(){return sb(this.currentSighting)}set sightingData(t){this.player.stop(),this.soundPreview=void 0,this.sightingAudio.silence(),this.currentSighting=ab(t),this.issuesPanel.hidden=!0,this.issuesButton.setAttribute("aria-expanded","false"),this.reportIssues(t,this.currentSighting),this.observerMapView.reset(),this.mapFitButton.hidden=!0,this.observerMapAsked=!1,this.player=this.createPlayer(),this.updateTimeLabels(),this.updatePlayPauseButton(),this.refresh(),this.applyObserverMapDefault()}get recordingIssues(){return this.issues}async reportIssues(t,e){const i=++this.issueCheck;let n=[];try{const{default:s}=await je(async()=>{const{default:r}=await import("./sightingSchema-5AlscPkV.js");return{default:r}},[],import.meta.url);n=new ts(s).issues(t)}catch{}i===this.issueCheck&&(this.issues=[...n,...e.loadIssues],Zo.warn(this.issues,e.id),this.renderIssues(),this.dispatchEvent(new CustomEvent(Cb,{detail:{issues:this.issues},bubbles:!0,composed:!0})))}renderIssues(){const t=this.issues.length;this.issuesBox.hidden=t===0,this.shadow.getElementById("issues-count").textContent=String(t);const e=this.messages.recordingIssues.replace("{count}",String(t));this.issuesButton.title=e,this.issuesButton.setAttribute("aria-label",e),this.shadow.getElementById("issues-title").textContent=e,this.shadow.getElementById("issues-list").replaceChildren(...this.issues.map(i=>{const n=document.createElement("li");return n.textContent=Zo.text(i,this.messages.issueTemplates),n}))}get sighting(){return this.currentSighting}previewSound(t){this.soundPreview=t,this.sightingAudio.resume(),this.sightingAudio.setSound(t)}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(t){this.player.seek(t)}get seekableDuration(){return this.player.seekableDuration}get autoReplayEnabled(){return this.loopEnabled}set autoReplayEnabled(t){t!==this.loopEnabled&&this.toggleLoop()}play(){if(!(this.player.seekableDuration<=0||this.playbackState==="playing")){if(this.clockHeld){this.playAfterHold=!0;return}this.togglePlayPause()}}clockHeld=!1;playAfterHold=!1;holdClock(t){if(t!==this.clockHeld){if(this.clockHeld=t,t){if(this.playbackState!=="playing")return;this.playAfterHold=!0,this.player.pause(),this.soundPreview=void 0,this.sightingAudio.silence(),this.refresh(),this.updatePlayPauseButton();return}this.playAfterHold&&(this.playAfterHold=!1,!(this.player.seekableDuration<=0||this.playbackState==="playing")&&(this.sightingAudio.resume(),this.player.play(),this.updatePlayPauseButton()))}}pause(){this.playAfterHold=!1,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(t){this.toolbar.classList.toggle("hidden",!t),t?this.controlsRight.appendChild(this.fullscreenButton):this.cornerButtons.appendChild(this.fullscreenButton)}get playbackState(){return this.player.playbackState}get selectedSourceIds(){return this.highlightedSourceIds}get durationSeconds(){return this.currentSighting.event.durationSeconds}set durationSeconds(t){this.currentSighting.event.durationSeconds=t,this.updateTimeLabels(),this.refresh(),this.updatePlayPauseButton()}set selectedSourceIds(t){const e=new Set(t);e.size===this.highlightedSourceIds.size&&[...e].every(n=>this.highlightedSourceIds.has(n))||(this.highlightedSourceIds=e,this.refresh())}hasVisibleShapeAt(t,e){return this.shapeAt(t,e)!==void 0}refresh(){this.applyFrameFormat(),this.updateMuteButton(),this.updateTimeLabels(),this.seekInput.max=String(this.player.seekableDuration),this.refreshMilestoneMarks(),this.updateMilestonesButton(),this.updateObserverMap(),this.updateReferences(),this.updateTracesButton(),this.player.seek(this.player.time)}hostControls(t){const e=[this.milestonesButton,this.referencesButton,this.referenceOpacityInput,this.tracesButton,this.observerMapButton];if(t)for(const i of e)t.appendChild(i);else{const i=this.fullscreenButton.parentElement===this.controlsRight?this.fullscreenButton:null;for(const n of e)this.controlsRight.insertBefore(n,i)}}get referencesShown(){return this.referencesShownState}get referenceOpacity(){return Number(this.referenceOpacityInput.value)}get severalReferences(){return this.currentSighting.references.length>1}toggleReferences(){if(this.severalReferences){this.toggleReferencesMenu();return}this.referencesShownState=!this.referencesShownState,this.updateReferencesButton(),this.dispatchReferenceView()}updateReferences(){const t=this.currentSighting.references;!this.referenceOpacityTouched&&t.length>0&&(this.referenceOpacityInput.value=String(t[0].opacity));for(const e of[...this.referenceViews.keys()])t.some(i=>i.id===e)||this.referenceViews.delete(e);this.severalReferences?this.referencesMenu.hidden||this.renderReferencesMenu():this.closeReferencesMenu(),this.updateReferencesButton(),this.severalReferences&&this.dispatchReferenceView()}viewOfReference(t){let e=this.referenceViews.get(t.id);return e||(e={shown:!0,opacity:t.opacity},this.referenceViews.set(t.id,e)),e}toggleReferencesMenu(){this.referencesMenu.hidden?this.openReferencesMenu():this.closeReferencesMenu()}openReferencesMenu(){this.renderReferencesMenu(),this.referencesMenu.hidden=!1,this.placeReferencesMenu(),this.referencesButton.setAttribute("aria-expanded","true"),document.addEventListener("pointerdown",this.handleReferencesMenuOutside,!0),document.addEventListener("keydown",this.handleReferencesMenuKey,!0)}closeReferencesMenu(){this.referencesMenu.hidden||(this.referencesMenu.hidden=!0,this.referencesButton.setAttribute("aria-expanded","false"),document.removeEventListener("pointerdown",this.handleReferencesMenuOutside,!0),document.removeEventListener("keydown",this.handleReferencesMenuKey,!0))}handleReferencesMenuOutside=t=>{const e=t.composedPath();e.includes(this.referencesMenu)||e.includes(this.referencesButton)||this.closeReferencesMenu()};handleReferencesMenuKey=t=>{t.key==="Escape"&&(this.closeReferencesMenu(),this.referencesButton.focus())};placeReferencesMenu(){const t=this.referencesButton.getBoundingClientRect(),e=this.referencesMenu,i=4;e.style.bottom=`${Math.max(i,window.innerHeight-t.top+i)}px`,e.style.top="auto";const n=e.getBoundingClientRect().width;e.style.left=`${Math.max(i,Math.min(t.left,window.innerWidth-n-i))}px`}renderReferencesMenu(){const t=this.currentSighting.references.map(e=>{const i=this.viewOfReference(e),n=this.said.read(e.title)??e.id,s=document.createElement("div");s.className="reference-row";const r=document.createElement("label"),o=document.createElement("input");o.type="checkbox",o.checked=i.shown;const c=document.createElement("span");c.textContent=n,c.title=n,r.append(o,c);const l=document.createElement("input");return l.type="range",l.min="0",l.max="1",l.step="0.05",l.value=String(i.opacity),l.title=this.messages.referenceOpacity,l.setAttribute("aria-label",`${this.messages.referenceOpacity}: ${n}`),l.disabled=!i.shown,o.addEventListener("change",()=>{i.shown=o.checked,l.disabled=!i.shown,this.updateReferencesButton(),this.dispatchReferenceView()}),l.addEventListener("input",()=>{i.opacity=Number(l.value),this.dispatchReferenceView()}),s.append(r,l),s});this.referencesMenu.setAttribute("aria-label",this.messages.referencesMenu),this.referencesMenu.replaceChildren(...t)}updateReferencesButton(){const t=this.currentSighting.references.length>0,e=this.severalReferences,i=e?this.currentSighting.references.some(s=>this.viewOfReference(s).shown):this.referencesShownState;this.referencesButton.hidden=!t,this.referenceOpacityInput.hidden=!t||!this.referencesShownState||e,this.referencesButton.setAttribute("aria-pressed",String(i)),e?this.referencesButton.setAttribute("aria-haspopup","true"):this.referencesButton.removeAttribute("aria-haspopup"),pe.setIcon(this.referencesButton,i?Gt.PICTURES_ON:Gt.PICTURES_OFF);const n=e?this.messages.referencesMenu:this.referencesShownState?this.messages.hideReferences:this.messages.showReferences;this.referencesButton.title=n,this.referencesButton.setAttribute("aria-label",n),this.referenceOpacityInput.title=this.messages.referenceOpacity,this.referenceOpacityInput.setAttribute("aria-label",this.messages.referenceOpacity)}get tracesShown(){return this.tracesShownState}toggleTraces(){this.tracesShownState=!this.tracesShownState,this.updateTracesButton(),this.updateObserverMap(),this.dispatchEvent(new CustomEvent("traceview",{detail:{shown:this.tracesShown}}))}updateTracesButton(){this.tracesButton.hidden=this.currentSighting.traces.length===0,this.tracesButton.setAttribute("aria-pressed",String(this.tracesShownState)),pe.setIcon(this.tracesButton,this.tracesShownState?Gt.TRACES_ON:Gt.TRACES_OFF);const t=this.tracesShownState?this.messages.hideTraces:this.messages.showTraces;this.tracesButton.title=t,this.tracesButton.setAttribute("aria-label",t)}dispatchReferenceView(){const t=this.severalReferences?Object.fromEntries(this.currentSighting.references.map(e=>[e.id,{...this.viewOfReference(e)}])):void 0;this.dispatchEvent(new CustomEvent("referenceview",{detail:{shown:this.referencesShown,opacity:this.referenceOpacity,views:t}}))}refreshMilestoneMarks(){const t=this.player.seekableDuration,e=t>0?Wc(this.sighting.milestones):[];this.milestoneMarks.replaceChildren(...e.map(i=>{const n=document.createElement("button");n.type="button",n.className="milestone-mark",n.style.left=`${Math.min(Math.max(i.t/t,0),1)*100}%`;const s=this.said.read(i.label)??"",r=this.said.read(i.note),o=r?`${s} — ${r}`:s;return n.title=o,n.setAttribute("aria-label",o),n.dataset.t=String(i.t),n.addEventListener("click",()=>this.player.seek(i.t)),n})),this.refreshSeekSegments(t,e.map(i=>i.t)),this.refreshMomentsPicker(e)}refreshMomentsPicker(t){const e=this.milestonesShown&&t.length>0;this.momentsBox.hidden=!e,this.closeMomentsMenu(),this.momentsMenu.replaceChildren(...t.map(i=>{const n=document.createElement("li"),s=document.createElement("button");s.type="button",s.dataset.t=String(i.t);const r=this.said.read(i.label)??"",o=this.said.read(i.note);return s.textContent=o?`${r} — ${o}`:r,s.addEventListener("click",()=>{this.player.seek(i.t),this.closeMomentsMenu()}),n.appendChild(s),n})),this.momentsButton.title=this.messages.moments,this.showCurrentMoment(void 0)}showCurrentMoment(t){const i=(t?this.said.read(t.label)??"":"")||this.messages.moments;this.momentsCurrent.textContent!==i&&(this.momentsCurrent.textContent=i);for(const n of this.momentsMenu.querySelectorAll("button")){const s=t!==void 0&&Number(n.dataset.t)===t.t;n.getAttribute("aria-current")==="true"!==s&&n.setAttribute("aria-current",String(s))}}toggleMomentsMenu(){this.momentsMenu.hidden?(this.momentsMenu.hidden=!1,this.momentsButton.setAttribute("aria-expanded","true")):this.closeMomentsMenu()}closeMomentsMenu(){this.momentsMenu.hidden=!0,this.momentsButton.setAttribute("aria-expanded","false")}handleMomentsDismiss=t=>{if(!this.momentsMenu.hidden){if(t instanceof KeyboardEvent){t.key==="Escape"&&this.closeMomentsMenu();return}t.composedPath().some(e=>e===this.momentsMenu||e===this.momentsButton)||this.closeMomentsMenu()}};seekSegmentList=[];refreshSeekSegments(t,e){const n=[0,...this.milestonesShown&&t>0?[...new Set(e.filter(r=>r>0&&r<t))].sort((r,o)=>r-o):[],Math.max(t,0)];this.seekSegmentList=[];const s=[];for(let r=0;r<n.length-1;r++){const o=document.createElement("div");o.className="seek-segment",o.style.flexGrow=String(Math.max(n[r+1]-n[r],1));const c=document.createElement("i");c.className="seek-hover";const l=document.createElement("i");l.className="seek-played",o.append(c,l),s.push(o),this.seekSegmentList.push({start:n[r],end:n[r+1],element:o,played:l,hover:c})}this.seekSegments.replaceChildren(...s),this.paintSeekProgress(this.player.time)}static fillOf(t,e){const i=t.end-t.start,n=i>0?(e-t.start)/i:e>=t.end?1:0;return`${Math.min(Math.max(n,0),1)*100}%`}paintSeekProgress(t){for(const i of this.seekSegmentList)i.played.style.width=pe.fillOf(i,t);const e=this.player.seekableDuration;this.seekDot.style.left=`${e>0?Math.min(Math.max(t/e,0),1)*100:0}%`}hoverSeek(t){const e=this.seekInput.getBoundingClientRect(),i=this.player.seekableDuration;if(e.width<=0||i<=0)return;const n=Math.min(Math.max((t.clientX-e.left)/e.width,0),1),s=n*i,r=this.seekSegmentList.length-1;this.seekSegmentList.forEach((f,p)=>{f.hover.style.width=pe.fillOf(f,s),f.element.classList.toggle("hovered",s>=f.start&&(s<f.end||p===r))});const o=this.milestonesShown?this.sighting.milestones:[],c=o.length>0?Md(o,s):void 0,l=c?this.said.read(c.label)??"":"",h=c?this.said.read(c.note):void 0,u=h?`${l} — ${h}`:l;this.seekPreviewTitle.textContent=u,this.seekPreviewTime.textContent=this.formatPosition(s),this.seekPreview.hidden=!1;const d=this.seekPreview.offsetWidth;this.seekPreview.style.left=`${Math.min(Math.max(n*e.width-d/2,0),Math.max(e.width-d,0))}px`,this.paintSeekPreview(s)}leaveSeek(){for(const t of this.seekSegmentList)t.hover.style.width="0",t.element.classList.remove("hovered");this.seekPreview.hidden=!0}seekPreviewPainter;paintSeekPreview(t){const e=this.seekPreviewPainter;this.seekPreviewCanvas.hidden=e===void 0,e?.(t,this.seekPreviewCanvas)}scrubbingPointer;beginTouchScrub(t){if(t.pointerType!=="mouse"){this.scrubbingPointer=t.pointerId;try{this.seekInput.setPointerCapture(t.pointerId)}catch{}this.seekToPointer(t)}}touchScrub(t){t.pointerId===this.scrubbingPointer&&this.seekToPointer(t)}endTouchScrub(t){t.pointerId===this.scrubbingPointer&&(this.scrubbingPointer=void 0,this.seekToPointer(t))}seekToPointer(t){const e=this.seekInput.getBoundingClientRect(),i=this.player.seekableDuration;if(e.width<=0||i<=0)return;const n=Math.min(Math.max((t.clientX-e.left)/e.width,0),1);this.player.seek(this.snapSeekToMark(n*i))}seekSnapArmed=!1;static MARK_SNAP_PX=6;markNear(t){const e=this.player.seekableDuration,i=this.seekInput.getBoundingClientRect().width;if(e<=0||i<=0)return;const n=pe.MARK_SNAP_PX/i*e;let s;for(const r of this.milestoneMarks.children){const o=Number(r.dataset.t);Math.abs(o-t)>n||(!s||Math.abs(o-t)<Math.abs(s.t-t))&&(s={t:o,name:r.title})}return s}snapSeekToMark(t){return this.seekSnapArmed?(this.seekSnapArmed=!1,this.markNear(t)?.t??t):t}nameMarkUnder(t){const e=this.seekInput.getBoundingClientRect(),i=this.player.seekableDuration;if(e.width<=0||i<=0)return;const n=(t.clientX-e.left)/e.width*i,s=this.markNear(n);s?this.seekInput.title=s.name:this.seekInput.removeAttribute("title")}showMilestoneAt(t){const e=this.milestonesShown&&this.sighting.milestones.length>0?Md(this.sighting.milestones,t):void 0;if(this.milestoneCaption.hidden=e===void 0,this.showCurrentMoment(e),!e)return;const i=document.createElement("b");i.textContent=this.said.read(e.label)??"";const n=this.said.read(e.note),s=n?` — ${n}`:"";this.milestoneCaption.replaceChildren(i,document.createTextNode(s))}exposureInstants(t){const e=this.exposureTimes(t),i=1/e.length;return e.map(n=>({shapes:this.shapesAt(n),share:i}))}exposureTimes(t=this.currentTime){const e=as.windowEndingAt(t,this.currentSighting.exposure??0);if(e.ms<pe.SHORTEST_VISIBLE_EXPOSURE_MS)return[t];const i=Math.min(pe.MAX_EXPOSURE_STEPS,Math.max(2,Math.round(e.ms/pe.SHORTEST_VISIBLE_EXPOSURE_MS))),n=Math.ceil(this.travelPxOver(e.fromMs,e.ms)/pe.EXPOSURE_STEP_PX),s=Math.min(pe.MAX_TRAVEL_STEPS,Math.max(i,n)),r=[];for(let o=0;o<s;o++)r.push(e.fromMs+e.ms*o/(s-1));return r}travelPxOver(t,e){const i=this.shapesAt(t),n=this.shapesAt(t+e);let s=0;for(const[r,o]of i){const c=n.get(r);if(!c)continue;const l=c.bounds.x+c.bounds.width/2-(o.bounds.x+o.bounds.width/2),h=c.bounds.y+c.bounds.height/2-(o.bounds.y+o.bounds.height/2);s=Math.max(s,Math.hypot(l,h))}return s}shapeAt(t,e,i){if(!this.accountHidden)for(const n of this.exposureTimes()){const s=this.currentSighting.timeline.hitTest(n,t,e,i);if(s)return s}}shapesAt(t){const e=new Map;for(const i of this.currentSighting.timeline.sourceIds){const n=this.currentSighting.timeline.getInterpolatedShapeAt(t,i);n&&e.set(i,n)}return e}static SHORTEST_VISIBLE_EXPOSURE_MS=20;static MAX_EXPOSURE_STEPS=48;static EXPOSURE_STEP_PX=2;static MAX_TRAVEL_STEPS=320;applyFrameFormat(){const t=bi.frameWidthPx(this.currentSighting.instrument,this.canvas.height);if(this.canvas.width===t)return;this.canvas.width=t,this.canvas.parentElement?.style.setProperty("--frame-aspect",`${t} / ${this.canvas.height}`)}canvasPointFromEvent(t){const e=this.canvas.getBoundingClientRect();if(!(e.width===0||e.height===0))return{x:(t.clientX-e.left)/e.width*this.canvas.width,y:(t.clientY-e.top)/e.height*this.canvas.height}}onFrame(t,e){this.canvasRenderer.clear(this.canvas.width,this.canvas.height);const i=this.playbackState!=="playing"?this.highlightedSourceIds:Ib;this.canvasRenderer.setStarPoints(bi.starPointsOf(this.sighting.instrument));const n=(Ze(this.sighting,t)?.rollDeg??0)+this.gaitAt(t).rollDeg;this.canvasRenderer.setRoll(n*Math.PI/180);const s=this.exposureInstants(t),r=this.frameShift;if(this.paintsShapes)for(const o of s)for(const[,c]of o.shapes){const l=o.share,h=l===1?c:{...c,transparency:1-(1-c.transparency)*l};this.canvasRenderer.paintShape(this.shifted(h,r))}for(const[o,c]of s[0].shapes)!this.selectionShown||!i.has(o)||(this.paintsShapes?i.size===1?this.canvasRenderer.paintShape({...c,selected:!0}):this.canvasRenderer.paintMemberOutline(c):this.canvasRenderer.paintSelectionOnly(this.shifted(c,r)));if(this.selectionShown&&i.size>1){const o=Dn.groupBoundsFor([...e].filter(([c])=>i.has(c)).map(([,c])=>c.bounds));this.canvasRenderer.paintGroupHandles(o)}this.overlayPainter?.(this.canvasRenderer),this.mapShapeBounds=s.flatMap(o=>[...o.shapes.values()].filter(c=>c.transparency<1).map(c=>this.shifted(c,r).bounds)),this.keepObserverMapClear(),this.seekInput.value=String(t),this.paintSeekProgress(t),this.timeStartLabel.textContent=this.formatPosition(t),this.showMilestoneAt(t),this.paintObserverMap(t),this.playbackState==="playing"?(this.soundPreview=void 0,this.sightingAudio.setSound(pM(this.currentSighting,t))):this.soundPreview?this.sightingAudio.setSound(this.soundPreview):this.sightingAudio.silence(),this.updatePlayPauseButton(),this.dispatchEvent(new CustomEvent("timeupdate",{detail:{time:t}}))}shifted(t,e){return e.x===0&&e.y===0?t:{...t,bounds:{...t.bounds,x:t.bounds.x+e.x,y:t.bounds.y+e.y}}}createPlayer(){const t=new Zx(this.currentSighting.timeline,(e,i)=>this.onFrame(e,i));return t.loop=this.loopEnabled,t.onEnded=()=>{this.updatePlayPauseButton(),this.dispatchEvent(new CustomEvent("ended",{bubbles:!0,composed:!0}))},t}static SEEK_KEY_STEP_MS=5e3;handleFullscreenKey=t=>{t.key.toLowerCase()!=="f"||t.altKey||t.ctrlKey||t.metaKey||!this.enableClickToPlay||t.composedPath().some(i=>i instanceof HTMLElement&&(i.isContentEditable||["INPUT","TEXTAREA","SELECT"].includes(i.tagName)&&i.type!=="range"))||(t.preventDefault(),this.toggleFullscreen())};handleSeekKey=t=>{if(t.altKey||t.ctrlKey||t.metaKey)return;const e=t.key==="ArrowLeft"?-1:t.key==="ArrowRight"?1:0;if(e){t.preventDefault();const i=this.player.seekableDuration;this.player.seek(Math.min(i,Math.max(0,this.player.time+e*pe.SEEK_KEY_STEP_MS)))}else t.key===" "&&(t.preventDefault(),this.togglePlayPause())};togglePlayPause(){if(!(this.player.seekableDuration<=0)){if(this.player.playbackState==="playing")this.player.pause(),this.soundPreview=void 0,this.sightingAudio.silence(),this.refresh();else if(this.clockHeld){this.playAfterHold=!this.playAfterHold;return}else this.sightingAudio.resume(),this.player.play();this.updatePlayPauseButton(),this.flashPlayback()}}flashPlayback(){const t=this.playbackFlash;t.innerHTML=this.player.playbackState==="playing"?Gt.PLAY:Gt.PAUSE,t.classList.remove("flashing"),t.offsetWidth,t.classList.add("flashing")}static icons=new WeakMap;static setIcon(t,e){pe.icons.get(t)!==e&&(pe.icons.set(t,e),t.innerHTML=e)}set captionHeld(t){this.stageElement.classList.toggle("caption-held",t)}static CONTROLS_IDLE_MS=3e3;controlsIdleTimer;wasPlaying=!1;quietControlsValue=!1;get quietControls(){return this.quietControlsValue}set quietControls(t){this.quietControlsValue=t,this.stageElement.classList.toggle("quiet",t)}tapRevealedOnly=!1;get hoverless(){return typeof matchMedia=="function"&&matchMedia("(hover: none)").matches}touchedStage(){if(!this.hoverless)return;this.player.playbackState==="playing"&&!this.stageElement.classList.contains("touched")&&(this.tapRevealedOnly=!0),this.revealControls()}pointerHeld=!1;handlePointerDown=()=>{this.pointerHeld=!0};resumeAfterScrub=!1;suspendForScrub(){this.player.playbackState==="playing"&&(this.resumeAfterScrub=!0,this.stopPlaying())}stopPlaying(){this.player.pause(),this.soundPreview=void 0,this.sightingAudio.silence(),this.refresh(),this.updatePlayPauseButton()}resumeFromScrub(){this.resumeAfterScrub&&(this.resumeAfterScrub=!1,this.sightingAudio.resume(),this.player.play(),this.updatePlayPauseButton())}handleHidden=()=>{this.player.playbackState==="playing"&&this.stopPlaying(),this.resumeAfterScrub=!1};handleVisibility=()=>{document.visibilityState==="hidden"&&this.handleHidden()};handlePointerRelease=()=>{this.resumeAfterScrub&&window.setTimeout(()=>this.resumeFromScrub(),0),this.pointerHeld&&(this.pointerHeld=!1,this.hoverless&&this.stageElement.classList.contains("touched")&&this.revealControls())};revealControls(){this.stageElement.classList.add("touched"),window.clearTimeout(this.controlsIdleTimer),this.player.playbackState==="playing"&&(this.pointerHeld||!this.momentsMenu.hidden||(this.controlsIdleTimer=window.setTimeout(()=>{this.stageElement.classList.remove("touched"),this.tapRevealedOnly=!1},pe.CONTROLS_IDLE_MS)))}updatePlayPauseButton(){const t=this.player.playbackState==="playing";this.stageElement.classList.toggle("paused",!t),t!==this.wasPlaying&&t&&this.hoverless&&(!this.quietControlsValue||this.stageElement.classList.contains("touched"))&&this.revealControls(),this.wasPlaying=t,pe.setIcon(this.playPauseButton,t?Gt.PAUSE:Gt.PLAY);const e=this.player.seekableDuration>0;this.playPauseButton.disabled=!e;const i=e?t?this.messages.pause:this.messages.play:this.messages.noDuration;this.playPauseButton.title=i,this.playPauseButton.setAttribute("aria-label",i)}toggleLoop(){this.loopEnabled=!this.loopEnabled,this.player.loop=this.loopEnabled}restorePlayback(){const t=this.playbackBeforeClick;t&&(this.currentTime=t.time,t.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(t=>{console.error("<rr0-ufo>: requestFullscreen() failed —",t)})}enterSimulatedFullscreen(){const t=this.fullscreenTarget;this.styleBeforeSimulatedFullscreen=t.getAttribute("style")??"",this.bodyOverflowBeforeSimulatedFullscreen=document.body.style.overflow;const e=t.style;e.setProperty("position","fixed"),e.setProperty("inset","0"),e.setProperty("margin","0"),e.setProperty("max-width","none"),e.setProperty("max-height","none"),e.setProperty("aspect-ratio","auto"),e.setProperty("z-index","2147483647"),e.setProperty("background","#000"),e.setProperty("width","100vw"),e.setProperty("width","100dvw"),e.setProperty("height","100vh"),e.setProperty("height","100dvh"),document.body.style.overflow="hidden",this.simulatedFullscreen=!0,document.addEventListener("keydown",this.handleSimulatedFullscreenKey),this.updateFullscreenButton(),this.updateMuteButton()}exitSimulatedFullscreen(){if(!this.simulatedFullscreen)return;const t=this.fullscreenTarget;this.styleBeforeSimulatedFullscreen?t.setAttribute("style",this.styleBeforeSimulatedFullscreen):t.removeAttribute("style"),document.body.style.overflow=this.bodyOverflowBeforeSimulatedFullscreen??"",this.simulatedFullscreen=!1,document.removeEventListener("keydown",this.handleSimulatedFullscreenKey),this.updateFullscreenButton(),this.updateMuteButton()}toggleObserverMap(){const t=this.observerMapPanel.hidden;this.observerMapAsked=t,this.setObserverMapOpen(t),this.keepObserverMapClear(),this.dispatchEvent(new CustomEvent("observermapchange",{bubbles:!0,composed:!0,detail:{open:t}}))}get observerMapOpen(){return!this.observerMapPanel.hidden}get milestonesVisible(){return this.milestonesShown}observerMapAsked=!1;applyObserverMapDefault(){const t=this.getAttribute(ks),e=t===null?this.sighting.observerMap??this.observerPath?.travels===!0:t!=="false";this.setObserverMapOpen(e&&this.observerPath!==void 0)}setObserverMapOpen(t){this.observerMapPanel.hidden=!t,this.observerMapPanel.removeAttribute("title"),this.observerMapButton.setAttribute("aria-pressed",String(t)),this.updateObserverMapButton(),t&&(this.sizeObserverMapCanvas(),this.loadObserverMapImagery(),this.paintObserverMap(this.currentTime))}updateObserverMapButton(){const t=!this.observerMapPanel.hidden;pe.setIcon(this.observerMapButton,t?Gt.MAP_ON:Gt.MAP_OFF);const e=t?this.messages.hideObserverMap:this.messages.showObserverMap;this.observerMapButton.title=e,this.observerMapButton.setAttribute("aria-label",e);const i=[[this.mapZoomInButton,this.messages.zoomMapIn],[this.mapZoomOutButton,this.messages.zoomMapOut],[this.mapFitButton,this.messages.fitMap]];for(const[n,s]of i)n.title=s,n.setAttribute("aria-label",s)}updateObserverMap(){const t=this.observerPath!==void 0;if(this.observerPath=Fo.of(this.currentSighting),this.observerMapButton.hidden=this.observerPath===void 0,!t&&this.observerPath&&this.applyObserverMapDefault(),!this.observerPath){this.setObserverMapOpen(!1),this.observerMapBounds=void 0;return}const e=this.tracesShownState?this.currentSighting.traces.flatMap(n=>n.points):[],i=ni.including(this.observerPath.boundsAround(pe.OBSERVER_MAP_MIN_SPAN_M,pe.OBSERVER_MAP_MARGIN),e);(!this.observerMapBounds||!this.sameGround(this.observerMapBounds,i))&&(this.observerMapBounds&&this.observerMapView.refit(this.observerMapBounds,i),this.observerMapBounds=i,this.observerMapImagery=void 0,this.observerMapImageryCredit=void 0,this.observerMapImageryFailed=!1,this.observerMapImageryBounds=void 0,this.observerMapImageryLoading=!1,this.observerMapPanel.hidden||this.loadObserverMapImagery())}sameGround(t,e){const i=Math.abs(t.east-t.west)/20;return Math.abs(t.north-e.north)<i&&Math.abs(t.south-e.south)<i&&Math.abs(t.west-e.west)<i&&Math.abs(t.east-e.east)<i}async loadObserverMapImagery(){const t=this.observerMapViewBounds;if(!t||this.observerMapPanel.hidden||this.observerMapImageryLoading||!this.observerMapImageryNeededFor(t))return;const e=this.observerMapView.changed,i=e?ni.expand(t,pe.OBSERVER_MAP_IMAGERY_AHEAD):t,n=pe.OBSERVER_MAP_IMAGERY_PX*(e?1+2*pe.OBSERVER_MAP_IMAGERY_AHEAD:1);this.observerMapImageryBounds=i,this.observerMapImageryViewWidth=t.east-t.west,this.observerMapImageryLoading=!0;const s=CM();try{const r=await s.getImageryTexture(i,{width:n,height:n});if(this.observerMapImageryBounds!==i)return;this.observerMapImagery=r,this.observerMapImageryCredit=s.attribution,this.observerMapImageryFailed=!1}catch{if(this.observerMapImageryBounds!==i)return;this.observerMapImageryFailed=this.observerMapImagery===void 0}finally{this.observerMapImageryBounds===i&&(this.observerMapImageryLoading=!1)}this.paintObserverMap(this.currentTime),this.scheduleObserverMapImagery()}static OBSERVER_MAP_IMAGERY_AHEAD=.5;static OBSERVER_MAP_IMAGERY_LOOKAHEAD=.25;observerMapImageryNeededFor(t){const e=this.observerMapImageryBounds;if(!e)return!0;const i=this.observerMapImagery?.bounds??e,n=this.observerMapView.changed?ni.expand(t,pe.OBSERVER_MAP_IMAGERY_LOOKAHEAD):t,s=n.west>=i.west&&n.east<=i.east&&n.south>=i.south&&n.north<=i.north,r=t.east-t.west>this.observerMapImageryViewWidth/2;return!s||!r}get observerMapCredit(){return this.observerMapImageryCredit}get observerMapFooterLine(){return this.observerMapImageryFailed?this.messages.mapImageryUnavailable:this.creditShownExternally?void 0:this.observerMapImageryCredit}mapShapeBounds=[];mapSceneBounds=[];setMapSubjectBounds(t){this.mapSceneBounds=t.map(e=>({x:e.x*this.canvas.width,y:e.y*this.canvas.height,width:e.width*this.canvas.width,height:e.height*this.canvas.height})),this.keepObserverMapClear()}keepObserverMapClear(){if(this.observerMapPanel.hidden)return;const t=this.observerMapBoxPx;if(!t)return;const e=[...this.mapShapeBounds,...this.mapSceneBounds],i=(l,h,u)=>{for(const d of e)if(!(d.x+d.width<l-u||d.x>h+u)&&!(d.y>t.bottom+u||d.y+d.height<t.top-u))return!0;return!1},n=[this.canvas.width-t.width,this.canvas.width],s=[0,t.width],r=pe.OBSERVER_MAP_CLEARANCE_PX,o=i(...n,0),c=i(...s,0);if(this.observerMapPanel.classList.toggle("subject-overlap",o&&c&&!this.observerMapAsked),this.observerMapPanel.classList.contains("on-the-left")){!o&&(c||!i(n[0],n[1],r))&&this.observerMapPanel.classList.remove("on-the-left");return}i(n[0],n[1],0)&&!i(s[0],s[1],0)&&this.observerMapPanel.classList.add("on-the-left")}observerMapBoxPx;static OBSERVER_MAP_CLEARANCE_PX=24;sizeObserverMapCanvas(){const t=this.observerMapPanel.clientWidth;if(t===0)return;const e=Math.round(t*(globalThis.devicePixelRatio??1));this.measureObserverMapBox(),this.observerMapCanvas.width!==e&&(this.observerMapCanvas.width=e,this.observerMapCanvas.height=e)}measureObserverMapBox(){const t=this.observerMapPanel.getBoundingClientRect(),e=this.canvas.getBoundingClientRect();if(e.width===0||e.height===0)return;const i=this.canvas.width/e.width,n=this.canvas.height/e.height;this.observerMapBoxPx={width:t.width*i,top:(t.top-e.top)*n,bottom:(t.bottom-e.top)*n}}paintObserverMap(t){if(this.observerMapPanel.hidden||!this.observerPath||!this.observerMapBounds)return;const e=Ze(this.currentSighting,t);e?.lat!==void 0&&e.lng!==void 0&&!this.observerMapDrag?.moved&&this.observerMapView.keepInView(this.observerMapBounds,{lat:e.lat,lng:e.lng},pe.OBSERVER_MAP_FOLLOW_MARGIN)&&this.scheduleObserverMapImagery();const i=this.currentSighting.instrument,n=[],s=this.currentSighting.milestones.length>0?Md(this.currentSighting.milestones,t):void 0;for(const r of this.milestonesShown?Wc(this.currentSighting.milestones):[]){const o=Ze(this.currentSighting,r.t);o?.lat===void 0||o.lng===void 0||n.push({label:this.said.read(r.label)??"",note:this.said.read(r.note),t:r.t,lat:o.lat,lng:o.lng,current:r===s})}this.observerMapRenderer.paint({bounds:this.observerMapViewBounds,imagery:this.observerMapImagery,path:this.observerPath,position:e?.lat!==void 0&&e.lng!==void 0?{lat:e.lat,lng:e.lng}:void 0,headingDeg:e?.headingDeg===void 0?void 0:e.headingDeg+this.lookYawDeg,coneHalfAngleDeg:e?rr.of(i,this.canvas.height,e.fovDeg).halfWidthAngleDeg(bi.aspectOf(i)):void 0,markers:n,traces:(this.tracesShownState?this.currentSighting.traces:[]).map(r=>({kind:r.kind,points:r.points,color:r.color,label:this.said.read(r.title)})),decor:this.observerMapDecorAt(t),observerLabel:this.said.read(this.currentSighting.observer?.title)??this.messages.observerHere,nightFraction:this.observerMapNightFraction,attribution:this.observerMapFooterLine})}toggleMilestones(){this.setMilestonesShown(!this.milestonesShown)}setMilestonesShown(t){this.milestonesShown=t,this.milestoneMarks.hidden=!t,this.momentsBox.hidden=!t||this.sighting.milestones.length===0,this.refreshSeekSegments(this.player.seekableDuration,Wc(this.sighting.milestones).map(e=>e.t)),this.milestonesButton.setAttribute("aria-pressed",String(t)),this.updateMilestonesButton(),this.showMilestoneAt(this.currentTime),this.paintObserverMap(this.currentTime)}updateMilestonesButton(){this.milestonesButton.hidden=this.currentSighting.milestones.length===0,this.momentsButton.title=this.messages.moments,pe.setIcon(this.milestonesButton,this.milestonesShown?Gt.MILESTONES_ON:Gt.MILESTONES_OFF);const t=this.milestonesShown?this.messages.hideMilestones:this.messages.showMilestones;this.milestonesButton.title=t,this.milestonesButton.setAttribute("aria-label",t)}observerMapDecorAt(t){const e=Ze(this.currentSighting,0);return e?.lat===void 0||e.lng===void 0?[]:this.currentSighting.decor.filter(i=>i.kind!=="crop").map(i=>{const n=Hr(i,t),{lat:s,lng:r}=Nn(n.eastM,-n.northM,e.lat,e.lng);return{lat:s,lng:r,headingDeg:n.headingDeg,label:this.said.read(i.title)??this.messages.decorHere}})}observerMapNightFraction;setSunAltitude(t){const e=t===void 0?void 0:Math.max(0,Math.min(1,-t/12));e!==this.observerMapNightFraction&&(this.observerMapNightFraction=e,this.paintObserverMap(this.currentTime))}setLookOffset(t,e){t===this.lookYawDeg&&e===this.lookPitchDeg||(this.lookYawDeg=t,this.lookPitchDeg=e,this.refresh())}get frameShiftPx(){return this.frameShift}get frameShift(){const t=this.gaitAt(this.currentTime),e=this.lookYawDeg+t.yawDeg,i=this.lookPitchDeg+t.pitchDeg;if(e===0&&i===0)return{x:0,y:0};const n=Ze(this.currentSighting,this.currentTime),s=rr.of(this.currentSighting.instrument,this.canvas.height,n?.fovDeg??60);return{x:-s.angleDegToRadiusPx(e),y:s.angleDegToRadiusPx(i)}}gaitAt(t){return Ce.bodyAt(this.currentSighting,t,this.steadyBody)}mutedState=!1;get muted(){return this.mutedState}set muted(t){t!==this.mutedState&&(this.mutedState=t,!t&&this.volumeState===0&&(this.volumeState=pe.RESTORED_VOLUME),this.applyLevel())}volumeState=1;static RESTORED_VOLUME=.5;get volume(){return this.volumeState}set volume(t){this.setVolume(t)}setVolume(t){this.volumeState=Math.min(Math.max(t,0),1),this.mutedState=this.volumeState===0,this.applyLevel()}get level(){return this.mutedState?0:this.volumeState}applyLevel(){this.sightingAudio.setLevel(this.level),this.updateMuteButton(),this.dispatchEvent(new CustomEvent("mutedchange",{bubbles:!0,composed:!0,detail:{muted:this.mutedState,volume:this.volumeState}}))}toggleMuted(){this.hasSound&&(this.muted=!this.mutedState)}ambientSound;get hasSound(){return this.currentSighting.soundTrack.allKeyframes.length>0||this.ambientSound?.(this.currentSighting)===!0}updateMuteButton(){const t=!this.hasSound;if(this.muteButton.disabled=t,this.volumeInput.hidden=t,t){pe.setIcon(this.muteButton,Gt.MUTED),this.muteButton.title=this.messages.noSound,this.muteButton.setAttribute("aria-label",this.messages.noSound),this.muteButton.setAttribute("aria-pressed","true");return}pe.setIcon(this.muteButton,this.mutedState?Gt.MUTED:Gt.VOLUME);const e=this.mutedState?this.messages.unmute:this.messages.mute;this.muteButton.title=e,this.muteButton.setAttribute("aria-label",e),this.muteButton.setAttribute("aria-pressed",String(this.mutedState)),this.volumeInput.value=String(this.level)}updateFullscreenButton(){const t=this.simulatedFullscreen||document.fullscreenElement===this.fullscreenTarget;pe.setIcon(this.fullscreenButton,t?Gt.EXIT_FULLSCREEN:Gt.ENTER_FULLSCREEN),this.fullscreenButton.title=t?this.messages.exitFullscreen:this.messages.fullscreen,this.fullscreenButton.setAttribute("aria-label",this.fullscreenButton.title)}get said(){return this.saidTexts??=new Yn(Gr.preferencesFor(this))}saidTexts;async loadLocaleMessages(){const t=Ep(Gr.preferencesFor(this),Ap);if(t===this.messagesLanguage||t==="en"&&this.messagesLanguage===void 0)return;this.messagesLanguage=t;const e=await lb(t);this.messagesLanguage===t&&this.applyMessages(e)}messagesLanguage;updateTimeLabelTitles(){const t=this.showClockTime?this.messages.switchToElapsed:this.messages.switchToClockTime,e=this.canSwitchTimeDisplay?` — ${t}`:"";this.timeStartLabel.title=this.messages.currentPosition+e,this.timeEndLabel.title=this.messages.duration+e,this.timePill.classList.toggle("switchable",this.canSwitchTimeDisplay),this.canSwitchTimeDisplay?(this.timePill.setAttribute("role","button"),this.timePill.setAttribute("tabindex","0")):(this.timePill.removeAttribute("role"),this.timePill.removeAttribute("tabindex"))}applyMessages(t){this.messages=t,this.updateTimeLabelTitles(),this.updatePlayPauseButton(),this.updateFullscreenButton(),this.updateMuteButton(),this.updateObserverMapButton(),this.updateReferencesButton(),this.updateTracesButton(),this.updateMilestonesButton(),this.renderIssues()}updateTimeLabels(){const t=this.currentSighting.event,e=fM(t);this.realDurationMs=e!==void 0&&e>0?e:void 0,this.realStartMs=t.time?Yf(t.time):void 0;const i=this.currentSighting.timeline.duration;this.player.playbackRate=this.realDurationMs!==void 0&&i>0?i/this.realDurationMs:1,this.player.durationOverrideMs=i>0?0:this.realDurationMs??0,this.timeEndLabel.textContent=this.formatEndOfTimeline(),this.timeStartLabel.textContent=this.formatPosition(this.player.time),this.updateTimeLabelTitles()}formatPosition(t){if(this.realDurationMs===void 0)return Nl(t);const e=this.currentSighting.timeline.duration,i=e>0&&t<=e?t/e*this.realDurationMs:t;return this.canShowClockTime?gg(mg(this.realStartMs+i)):Nl(i)}formatEndOfTimeline(){return this.realDurationMs===void 0?Nl(this.currentSighting.timeline.duration):this.canShowClockTime?gg(mg(this.realStartMs+this.realDurationMs)):Nl(this.realDurationMs)}}function mg(a){const t=new Date(a);return{hour:t.getUTCHours(),minute:t.getUTCMinutes(),second:t.getUTCSeconds()}}function gg(a){if(a.hour===void 0)return"0:00";const t=e=>String(e).padStart(2,"0");return a.second?`${t(a.hour)}:${t(a.minute??0)}:${t(a.second)}`:`${t(a.hour)}:${t(a.minute??0)}`}function Nl(a){const t=Math.round(a/1e3),e=Math.floor(t/60),i=t%60;return`${e}:${String(i).padStart(2,"0")}`}const Kf="rr0-ufo";function PM(){customElements.get(Kf)||customElements.define(Kf,pe)}const Cb="recordingissues";/**
2184
2184
  * @license
2185
2185
  * Copyright 2010-2026 Three.js Authors
2186
2186
  * SPDX-License-Identifier: MIT
@@ -8060,7 +8060,7 @@ ${Ct.OUTPUT_PROJECTION_GLSL}`)}}class nn{constructor(t,e){this.width=t,this.heig
8060
8060
  gl_FragColor = vec4(iceHaloLight(dir, ice), 1.0);
8061
8061
  }
8062
8062
  `,transparent:!0,blending:Pi,depthWrite:!1,side:Qe,fog:!1}),this.object=new At(new pi(Ui.RADIUS,64,32),this.material),this.object.renderOrder=-1,this.object.frustumCulled=!1,this.object.visible=!1;const i=this.material.uniforms;this.deckUniforms={uSource:i.uSource,uUp:i.uUp,uStrength:i.uStrength,uTint:i.uTint,uMap:i.uMap,uGain:i.uGain,uHaloShown:{value:0}}}deckUniforms;shown=!1;hostedByDeck=!1;set hosted(t){this.hostedByDeck=t,this.show(this.shown)}show(t){this.shown=t,this.object.visible=t&&!this.hostedByDeck,this.deckUniforms.uHaloShown.value=t?1:0}get awaitingFirstDisplay(){return this.tracing&&!this.everDisplayed}setUrgent(t){this.urgent=t}set onReady(t){this.onRepaint=t}update(t,e,i,n,s,r){const o=this.material.uniforms;if(i<=0){o.uStrength.value=0,this.show(!1),this.stopWork();return}o.uSource.value.set(t.x,t.y,t.z).normalize(),o.uStrength.value=i,o.uTint.value.set(n[0],n[1],n[2]),o.uIceCover.value=s.cover,o.uIceHeight.value=s.layerHeight,this.show(this.everDisplayed),this.requestMap(e,r)}requestMap(t,e){if(!(!(Math.abs(t-this.mappedAltitudeDeg)<Ui.ALTITUDE_STEP_DEG)||!(Math.abs(e-this.mappedAlignment)<Ui.ALIGNMENT_STEP))){this.next=void 0;return}if(this.tracing){if(this.tracingFor(t,e)){this.next=void 0;return}if(!(!(Math.abs(t-this.pendingAltitudeDeg)<Ui.LEAP_ALTITUDE_DEG)||!(Math.abs(e-this.pendingAlignment)<Ui.LEAP_ALIGNMENT))){this.next={sourceAltitudeDeg:t,alignment:e};return}}this.next=void 0,this.pendingAltitudeDeg=t,this.pendingAlignment=e,this.stopWork(),this.tracing=!0,this.startTracing(t,e)}startTracing(t,e){const i=++this.ticket,n=()=>{i!==this.ticket||!this.tracing||(this.sky.begin(t,e),this.scheduleWork())};kr.with(s=>{i!==this.ticket||!this.tracing||(this.job=s.trace(t,e,Ui.RAYS,r=>{this.job=void 0,this.texels.set(r),this.display(),this.finishTracing()},n))},n)}ticket=0;job;pendingAltitudeDeg=Number.NaN;pendingAlignment=Number.NaN;next;tracingFor(t,e){return this.tracing&&Math.abs(t-this.pendingAltitudeDeg)<Ui.ALTITUDE_STEP_DEG&&Math.abs(e-this.pendingAlignment)<Ui.ALIGNMENT_STEP}scheduleWork(){if(this.workHandle!==void 0)return;const t=()=>{if(this.workHandle=void 0,!this.tracing)return;const e=performance.now(),i=this.urgent?Ui.URGENT_BUDGET_MS:Ui.BUDGET_MS;do this.sky.trace(Ui.RAYS_PER_BATCH);while(this.sky.tracedRays<Ui.RAYS&&performance.now()-e<i);if(this.sky.tracedRays>=Ui.RAYS){this.publish(),this.finishTracing();return}this.workHandle=requestAnimationFrame(t)};this.workHandle=requestAnimationFrame(t)}finishTracing(){this.tracing=!1,this.mappedAltitudeDeg=this.pendingAltitudeDeg,this.mappedAlignment=this.pendingAlignment;const t=this.next;t&&this.requestMap(t.sourceAltitudeDeg,t.alignment)}stopWork(){this.ticket++,this.job?.cancel(),this.job=void 0,this.workHandle!==void 0&&cancelAnimationFrame(this.workHandle),this.workHandle=void 0,this.tracing=!1,this.next=void 0}publish(){eR.fromRadiance(this.sky.harvest().data,this.texels),this.display()}display(){this.texture.needsUpdate=!0,this.everDisplayed=!0,this.show(this.material.uniforms.uStrength.value>0),this.onRepaint?.()}dispose(){this.stopWork(),this.texture.dispose(),this.object.geometry.dispose(),this.material.dispose()}}class Fi{static MAX_CONCURRENT=24;static POINTS=8;static SEGMENTS=Fi.POINTS-1;static ACROSS=3;static VERTICES_PER_SEGMENT=(Fi.ACROSS-1)*6;static RADIUS=840;static MIN_HALF_WIDTH_DEG=.05;static BRIGHT_HALF_WIDTH_DEG=.22;object;positions;colors;meteors=[];radiantAltitudeDeg=0;radiantAzimuthDeg=0;constructor(){const t=Fi.MAX_CONCURRENT*Fi.SEGMENTS*Fi.VERTICES_PER_SEGMENT;this.positions=new Float32Array(t*3),this.colors=new Float32Array(t*3);const e=new ae;e.setAttribute("position",new te(this.positions,3)),e.setAttribute("color",new te(this.colors,3)),e.setDrawRange(0,0),this.object=new At(e,$n.material()),this.object.frustumCulled=!1,$n.track(this.object)}get schedule(){return this.meteors}setShower(t,e,i){this.meteors=t,this.radiantAltitudeDeg=e,this.radiantAzimuthDeg=i}update(t){const e=this.object.geometry;if(this.meteors.length===0){e.setDrawRange(0,0);return}const i=ka.aliveAt(this.meteors,t).slice(0,Fi.MAX_CONCURRENT);let n=0;for(const{meteor:s,progress:r}of i){const o=this.radiantOf(s);if(!o)continue;const c=Xe(o.altitudeDeg,o.azimuthDeg,1),[l,h]=this.basisAround(c),u=s.fromRadiantDeg+r*s.lengthDeg,d=Math.max(s.fromRadiantDeg,u-s.lengthDeg*.6),f=Math.min(1,(1-r)*2.5),p=this.turn(l,h,s.bearingDeg),v=(.15+.85*s.brightness)*f,m=S=>v*S**1.6,g=S=>this.onSphere(c,p,d+(u-d)*S),b=S=>Fi.RADIUS*((Fi.MIN_HALF_WIDTH_DEG+Fi.BRIGHT_HALF_WIDTH_DEG*s.brightness*S)*Math.PI/180);for(let S=1;S<Fi.POINTS;S++){const M=(S-1)/Fi.SEGMENTS,x=S/Fi.SEGMENTS;n=this.pushRibbon(n,g(M),g(x),b(M),b(x),m(M),m(x))}}e.setDrawRange(0,n),e.getAttribute("position").needsUpdate=!0,e.getAttribute("color").needsUpdate=!0}midpointOf(t){const e=this.radiantOf(t);if(!e)return;const i=Xe(e.altitudeDeg,e.azimuthDeg,1),[n,s]=this.basisAround(i),r=this.turn(n,s,t.bearingDeg),o=this.onSphere(i,r,t.fromRadiantDeg+t.lengthDeg/2),c=Math.hypot(o.x,o.y,o.z)||1;return{altitudeDeg:Math.asin(o.y/c)*180/Math.PI,azimuthDeg:(Math.atan2(o.x,-o.z)*180/Math.PI+360)%360}}radiantOf(t){return t.radiant?t.radiant:this.radiantAltitudeDeg>0?{altitudeDeg:this.radiantAltitudeDeg,azimuthDeg:this.radiantAzimuthDeg}:void 0}pushRibbon(t,e,i,n,s,r,o){const c=this.normalise(this.cross(this.normalise(e),this.normalise(this.subtract(i,e))));for(let l=0;l<Fi.ACROSS-1;l++){const h=l-1,u=l,d=this.across(e,c,n,h),f=this.across(i,c,s,h),p=this.across(e,c,n,u),v=this.across(i,c,s,u),m=(g,b)=>g===0?b:0;t=this.push(t,d,m(h,r)),t=this.push(t,f,m(h,o)),t=this.push(t,p,m(u,r)),t=this.push(t,f,m(h,o)),t=this.push(t,v,m(u,o)),t=this.push(t,p,m(u,r))}return t}across(t,e,i,n){return{x:t.x+e.x*i*n,y:t.y+e.y*i*n,z:t.z+e.z*i*n}}push(t,e,i){const n=t*3;this.positions[n]=e.x,this.positions[n+1]=e.y,this.positions[n+2]=e.z;const s=Rt.relativeOfResponse(Math.max(0,Math.min(1,i)));return this.colors[n]=s*.9,this.colors[n+1]=s*.95,this.colors[n+2]=s,t+1}turn(t,e,i){const n=i*Math.PI/180,s=Math.cos(n),r=Math.sin(n);return{x:t.x*s+e.x*r,y:t.y*s+e.y*r,z:t.z*s+e.z*r}}onSphere(t,e,i){const n=i*Math.PI/180,s=Math.cos(n),r=Math.sin(n);return{x:(t.x*s+e.x*r)*Fi.RADIUS,y:(t.y*s+e.y*r)*Fi.RADIUS,z:(t.z*s+e.z*r)*Fi.RADIUS}}basisAround(t){const e=Math.abs(t.y)<.9?{x:0,y:1,z:0}:{x:1,y:0,z:0},i=this.normalise(this.cross(t,e));return[i,this.normalise(this.cross(t,i))]}subtract(t,e){return{x:t.x-e.x,y:t.y-e.y,z:t.z-e.z}}cross(t,e){return{x:t.y*e.z-t.z*e.y,y:t.z*e.x-t.x*e.z,z:t.x*e.y-t.y*e.x}}normalise(t){const e=Math.hypot(t.x,t.y,t.z)||1;return{x:t.x/e,y:t.y/e,z:t.z/e}}dispose(){this.object.geometry.dispose(),this.object.material.dispose()}}class We{constructor(t,e={}){this.size=t,this.span=Math.min(t.lengthM,Math.max(0,e.spanM??t.lengthM)),this.bank=(t.lengthM-this.span)/2,this.deck=Math.min(t.heightM,e.deckThicknessM??We.DEFAULT_DECK_THICKNESS_M),this.railHeight=e.railing?.heightM??We.DEFAULT_RAILING_HEIGHT_M,this.postSpacing=Math.max(.3,e.railing?.postSpacingM??We.DEFAULT_POST_SPACING_M),this.rails=Math.max(0,Math.round(e.railing?.rails??We.DEFAULT_RAILS))}static DEFAULT_DECK_THICKNESS_M=1.2;static DEFAULT_RAILING_HEIGHT_M=1.05;static DEFAULT_POST_SPACING_M=1.5;static DEFAULT_RAILS=2;static BANK_SLOPE=1.5;static ABUTMENT_THICKNESS_M=1;static POST_SIDE_M=.08;static RAIL_HEIGHT_M=.08;static RAIL_DEPTH_M=.06;static BANK_STATIONS=12;static NATURAL_SIZE=Object.freeze({widthM:9,lengthM:40,heightM:6.5});span;bank;deck;railHeight;postSpacing;rails;roadAt(t){const e=Math.abs(t)-this.span/2;return e<=0?this.size.heightM:this.bank<=0?0:Math.max(0,this.size.heightM*(1-e/this.bank))}build(){const{widthM:t,heightM:e}=this.size,i=this.span/2,n=[];if(this.span>0){n.push(We.box(t,this.deck,this.span,0,e-this.deck/2,0));for(const c of[-1,1]){const l=e-this.deck;l>0&&this.bank>0&&n.push(We.box(t+1,l,We.ABUTMENT_THICKNESS_M,0,l/2,c*(i-We.ABUTMENT_THICKNESS_M/2)))}}const s=[];this.span>0&&s.push(We.box(t,.04,this.span,0,e+.02,0));const r=[];for(const c of[-1,1])this.bank<=0||(r.push(this.embankment(c)),s.push(this.bankRoad(c)));const o=[];for(const c of[-1,1])o.push(...this.railing(c*(t/2-We.POST_SIDE_M)));return{concrete:We.merge(n),road:We.merge(s),earth:We.merge(r),railing:We.merge(o)}}embankment(t){const e=this.size.widthM/2,i=this.stations(t),n=[],s=(l,h,u,d)=>{n.push(l.x,l.y,l.z,h.x,h.y,h.z,u.x,u.y,u.z,l.x,l.y,l.z,u.x,u.y,u.z,d.x,d.y,d.z)},r=l=>{const h=this.roadAt(l),u=e+We.BANK_SLOPE*h;return{leftFoot:new R(-u,0,l),leftTop:new R(-e,h,l),rightTop:new R(e,h,l),rightFoot:new R(u,0,l)}};for(let l=1;l<i.length;l++){const h=r(i[l-1]),u=r(i[l]),d=t>0,f=(p,v,m,g)=>d?s(p,v,m,g):s(g,m,v,p);f(h.leftFoot,h.leftTop,u.leftTop,u.leftFoot),f(h.leftTop,h.rightTop,u.rightTop,u.leftTop),f(h.rightTop,h.rightFoot,u.rightFoot,u.rightTop)}const o=r(i[0]);t>0?s(o.leftFoot,o.rightFoot,o.rightTop,o.leftTop):s(o.leftTop,o.rightTop,o.rightFoot,o.leftFoot);const c=new ae;return c.setAttribute("position",new ve(n,3)),c.computeVertexNormals(),c}bankRoad(t){const e=this.size.widthM/2,i=this.stations(t),n=[];for(let r=1;r<i.length;r++){const o=i[r-1],c=i[r],l=this.roadAt(o)+.02,h=this.roadAt(c)+.02,u=t>0?[[-e,l,o],[e,l,o],[e,h,c],[-e,h,c]]:[[-e,h,c],[e,h,c],[e,l,o],[-e,l,o]];for(const d of[0,2,1,0,3,2])n.push(...u[d])}const s=new ae;return s.setAttribute("position",new ve(n,3)),s.computeVertexNormals(),s}stations(t){const e=[];for(let i=0;i<=We.BANK_STATIONS;i++)e.push(t*(this.span/2+this.bank*i/We.BANK_STATIONS));return e}railing(t){const e=this.size.lengthM/2,i=Math.max(1,Math.round(this.size.lengthM/this.postSpacing)),n=[];for(let o=0;o<=i;o++)n.push(-e+this.size.lengthM*o/i);const s=[],r=We.POST_SIDE_M;for(const o of n)s.push(We.box(r,this.railHeight,r,t,this.roadAt(o)+this.railHeight/2,o));for(let o=1;o<=this.rails;o++){const c=this.railHeight*o/this.rails-We.RAIL_HEIGHT_M/2;for(let l=1;l<n.length;l++){const h=new R(t,this.roadAt(n[l-1])+c,n[l-1]),u=new R(t,this.roadAt(n[l])+c,n[l]);s.push(We.beam(h,u))}}return s}static box(t,e,i,n,s,r){return new Vi(t,e,i).translate(n,s,r)}static beam(t,e){const i=new R().subVectors(e,t),n=new Vi(We.RAIL_DEPTH_M,We.RAIL_HEIGHT_M,i.length()),s=new Sn().setFromUnitVectors(new R(0,0,1),i.clone().normalize()),r=new R().addVectors(t,e).multiplyScalar(.5);return n.applyMatrix4(new ne().compose(r,s,new R(1,1,1)))}static merge(t){const e=t.map(c=>c.getIndex()?c.toNonIndexed():c),i=e.reduce((c,l)=>c+l.getAttribute("position").count,0),n=new Float32Array(i*3),s=new Float32Array(i*3);let r=0;for(const c of e){const l=c.getAttribute("position"),h=c.getAttribute("normal");n.set(l.array,r*3),h&&s.set(h.array,r*3),r+=l.count}const o=new ae;o.setAttribute("position",new ve(n,3)),o.setAttribute("normal",new ve(s,3));for(const c of t)c.dispose();for(const c of e)c.dispose();return o}}class Ia{constructor(t,e={}){this.size=t,this.structure=e}static DEFAULT_DIAMETER_M=.008;static POLE_RADIUS_M=.13;static POLE_ABOVE_M=.5;static NATURAL_SIZE=Object.freeze({widthM:1,lengthM:30,heightM:5});get strands(){const t=this.structure.strands;return!t||t.length===0?[{heightM:this.size.heightM,acrossM:0}]:t.map(e=>({heightM:e.heightM,acrossM:e.acrossM??0}))}get poleStations(){const t=this.size.lengthM/2;switch(this.structure.poles??"both"){case"start":return[t];case"end":return[-t];case"none":return[];default:return[-t,t]}}get poleHeightM(){return this.structure.poleHeightM??Math.max(...this.strands.map(t=>t.heightM))+Ia.POLE_ABOVE_M}build(){const t=this.structure.diameterM??Ia.DEFAULT_DIAMETER_M,e=this.strands.map(n=>{const s=new Zn(t/2,t/2,this.size.lengthM,6);return s.rotateX(Math.PI/2),s.translate(n.acrossM,n.heightM,0),s}),i=this.poleStations.map(n=>{const s=new Zn(Ia.POLE_RADIUS_M*.8,Ia.POLE_RADIUS_M,this.poleHeightM,8);return s.translate(0,this.poleHeightM/2,n),s});return{strands:e,poles:i}}}const df=Math.PI/180;function Ae(a,t,e,i,n=!1){const s=n?new wn({color:new st(...e)}):new nc({color:new st(...e)}),r=new At(t,s);return r.position.y=i,r.userData={emissive:n},r.castShadow=!n,r.receiveShadow=!n,a.add(r),r}const ff=.25,iR=.002,nR=100,sR=1500,rR=.25,aR=1e3,oR=.15;function cR(a){const t=/^#([0-9a-f]{6})$/i.exec(a);if(!t)return[1,1,1];const e=parseInt(t[1],16);return[(e>>16&255)/255,(e>>8&255)/255,(e&255)/255]}const lR=[.32,.32,.3],Z2=[1,.85,.5],hR=[.25,.25,.25],J2=[1,.97,.85],uR=[.55,.68,.72],dR=.12,Ts=.03,Rs=.05,j2={front:0,behind:Math.PI,left:Math.PI/2,right:-Math.PI/2,"front-left":Math.PI/2,"behind-left":Math.PI/2,"front-right":-Math.PI/2,"behind-right":-Math.PI/2};function cn(a,t){return a?.[t]}function Ds(a,t,e,i,n,s,r,o){if(o===void 0)return;const c=new wn({color:new st(...uR).multiplyScalar(dR),transparent:!0,opacity:o/100,depthWrite:!1}),l=new At(new Vi(t,e,i),c);l.position.set(n,s,r),l.renderOrder=2,a.add(l)}const Gn=.05,pf=[.6,.58,.53],sv=[.5,.5,.48];function No(a,t,e,i,n,s,r,o){const c=new nc({color:new st(...o),side:Qe}),l=new At(new Vi(t,e,i),c);l.position.set(n,s,r),a.add(l)}function fR(a,t,e,i,n,s,r,o,c){const l=(i-s)/2,h=(p,v,m,g)=>{p<=0||(t?No(a,p,v,Gn,m,o+g,r,c):No(a,Gn,v,p,r,o+g,m,c))};h(e,l,0,i/2-l/2),h(e,l,0,-(i/2-l/2));const u=[...n].sort((p,v)=>p.center-v.center);let d=-e/2;for(const p of u){const m=p.center-p.main/2-d;h(m,s,d+m/2,0),d=p.center+p.main/2}const f=e/2-d;h(f,s,d+f/2,0)}function Q2(a,t,e,i,n,s,r,o,c,l){const h=(i+n)/2,u=n-i,d=(f,p,v,m)=>{f.length===0?p?No(a,v,u,Gn,0,h,m,pf):No(a,Gn,u,v,m,h,0,pf):fR(a,p,v,u,f,s,m,h,pf)};d(r,!0,t*2,-e+Gn),d(o,!0,t*2,e-Gn),d(c,!1,e*2,-t+Gn),d(l,!1,e*2,t-Gn),No(a,t*2,Gn,e*2,0,i+Gn,0,sv),No(a,t*2,Gn,e*2,0,n-Gn,0,sv)}function pp(a,t,e,i){switch(a){case"front":return{x:0,z:-(e-i)};case"behind":return{x:0,z:e-i};case"left":return{x:-(t-i),z:0};case"right":return{x:t-i,z:0};case"front-left":return{x:-(t-i),z:-Is};case"front-right":return{x:t-i,z:-Is};case"behind-left":return{x:-(t-i),z:Is};case"behind-right":return{x:t-i,z:Is}}}function ty(a,t,e,i,n,s,r,o){const c=vp();c.scale.setScalar(n),c.rotation.y=j2[e];const{x:l,z:h}=pp(t,s,r,o);c.position.set(l,i,h),a.add(c)}const mp=6,gp=6,Or=3,Tc=1.4,Rc=Or*.5,ey=1.2,iy=.35,pR=.75,mR=1.6;function rv(a,t,e,i,n){const s=new Ee,r=Math.max(1,a+1),o=r*Or;Ae(s,new Vi(mp,o,gp),[.55,.54,.5],o/2);const c=mp/2,l=gp/2;for(let h=0;h<r;h++){const u=h*Or+Or/2;Ds(s,Tc,Rc,Rs,0,u,-l-Ts,cn(t,"front")),Ds(s,Tc,Rc,Rs,0,u,l+Ts,cn(t,"behind")),Ds(s,Rs,Rc,Tc,-c-Ts,u,0,cn(t,"left")),Ds(s,Rs,Rc,Tc,c+Ts,u,0,cn(t,"right"))}if(e){const h=Math.min(Math.max(i??0,0),r-1);ty(s,e,n??e,h*Or,.72,c,l,ey);const u=d=>cn(t,d)!==void 0?[{main:Tc,center:0}]:[];Q2(s,c,l,h*Or,(h+1)*Or,Rc,u("front"),u("behind"),u("left"),u("right"))}return s}function av(){const a=new Ee,t=[[0,0,.55,.5],[.4,.1,.35,.4],[-.35,-.2,.4,.38],[.1,-.4,.35,.36],[-.15,.4,.3,.34]];for(const[e,i,n,s]of t){const r=new pi(n,10,7);r.scale(1,.85,1),r.translate(e,0,i),Ae(a,r,[.26,.28,.17],s)}return a}function gR(a){const t=new Ee,e=new We(Ye.sizeOf(a),a.bridge).build();Ae(t,e.concrete,[.6,.6,.58],0);const i=Ae(t,e.road,[.2,.2,.21],0),n=Ae(t,e.earth,[.3,.36,.22],0);for(const s of[i,n])s.material.side=bn;return Ae(t,e.railing,[.5,.52,.55],0),t}function vR(a){const t=new Ee,e=new Ia(Ye.sizeOf(a),a.wire).build();for(const i of e.strands)Ae(t,i,[.1,.1,.11],0);for(const i of e.poles)Ae(t,i,[.3,.24,.18],0);return t}function ov(){const a=new Ee;return Ae(a,new Zn(.15,.22,2,8),[.32,.22,.14],1),Ae(a,new rc(1.4,3,8),[.16,.32,.14],3.5),a}const cv=.275,MR=.35,yR=.9,xR=34,bR=8,SR=1.4;function lv(){const a=new Ee,t=new pi(cv,7,3,0,Math.PI*2,0,Math.PI/2);t.scale(1,MR/cv,1);const e=Ye.repeatOnGrid(t,xR,yR,bR,SR),i=Ae(a,e,[.26,.28,.22],0);return i.castShadow=!0,i.userData.cropBasePositions=e.getAttribute("position").array.slice(),i.userData.cropVerticesPerClump=t.getAttribute("position").count,t.dispose(),a}function hv(){const a=new Ee,t=new pi(1,7,3,0,Math.PI*2,0,Math.PI/2);return Ae(a,t,[.38,.36,.32],0),a}const wR=[.24,.22,.18],_R=[.14,.17,.08];function ER(){const a=new Ee,t=Ae(a,new Vi(1,1,1),wR,.5),e=Ae(a,new Vi(1,.03,1),_R,1.015);for(const i of[t,e])i.material.side=bn;return a}function uv(a){const t=new Ee;return Ae(t,new Zn(.05,.08,5,8),[.28,.28,.3],2.5),Ae(t,new pi(.25,12,8),a?Z2:lR,5.1,!0),t}const AR=[.08,.08,.08],Tr=.8,Ao=1,ws=1.7,mf=.6,ea=.46,wh=1.5,wo=.8,Is=.5,TR=ws;function dv(a,t,e,i){const n=new Ee;Ae(n,new Vi(1.8,1.4,4.2),[.45,.14,.14],.7),Ae(n,new Vi(Tr*2,mf,Ao*2),[.4,.12,.12],ws);for(const r of[-1.4,1.4])for(const o of[-.95,.95]){const c=Ae(n,new Zn(.4,.4,.3,12),AR,.4);c.rotation.z=Math.PI/2,c.position.x=o,c.position.z=r}const s=a?J2:hR;for(const r of[-.7,.7])Ae(n,new pi(.15,8,6),s,.7,!0).position.set(r,.7,-2.1);if(Ds(n,wh,ea,Rs,0,ws,-Ao-Ts,cn(t,"front")),Ds(n,wh,ea,Rs,0,ws,Ao+Ts,cn(t,"behind")),Ds(n,Rs,ea,wo,-Tr-Ts,ws,-Is,cn(t,"front-left")),Ds(n,Rs,ea,wo,-Tr-Ts,ws,Is,cn(t,"behind-left")),Ds(n,Rs,ea,wo,Tr+Ts,ws,-Is,cn(t,"front-right")),Ds(n,Rs,ea,wo,Tr+Ts,ws,Is,cn(t,"behind-right")),e){ty(n,e,i??e,pR,.5,Tr,Ao,iy);const r=(l,h)=>{const u=[];return cn(t,l)!==void 0&&u.push({main:wo,center:-Is}),cn(t,h)!==void 0&&u.push({main:wo,center:Is}),u},o=cn(t,"front")!==void 0?[{main:wh,center:0}]:[],c=cn(t,"behind")!==void 0?[{main:wh,center:0}]:[];Q2(n,Tr,Ao,ws-mf/2,ws+mf/2,ea,o,c,r("front-left","behind-left"),r("front-right","behind-right"))}return n}const fv=new Map;function pv(a,t){if(!a)return;const e=[[a.lengthM,t.lengthM],[a.heightM,t.heightM],[a.widthM,t.widthM]];for(const[i,n]of e)if(i!==void 0&&n>1e-6)return i/n}function gf(a,t){return t>1e-6?a/t:1}const ny=[.95,.9,.82],mv=[.72,.74,.78];function gv(){const a=new Ee;Ae(a,new Zn(.25,.3,1.5,10),mv,.75),Ae(a,new pi(.26,10,8),mv,1.74);const t=Ae(a,new rc(.07,.16,8),ny,1.74);return t.rotation.x=-Math.PI/2,t.position.z=-.22,a}function vp(){const a=new Ee;Ae(a,new Zn(.25,.3,1.5,10),[.3,.3,.35],.75),Ae(a,new pi(.22,10,8),[.62,.52,.46],1.72);const t=Ae(a,new rc(.07,.16,8),ny,1.72);return t.rotation.x=-Math.PI/2,t.position.z=-.2,a}const RR=17,vv=18.5,vf=[.16,.16,.18];function Mv(){const a=new Ee,t=Ae(a,new Zn(1.8,1.8,vv*2,10),vf,0);t.rotation.x=Math.PI/2,Ae(a,new Vi(RR*2,.5,4.5),vf,0);const e=Ae(a,new Vi(.4,5.5,4),vf,3);return e.position.z=-vv+2,a}class Ye{static GROWS_FROM_GROUND=new Set(["tree","shrub","crop","mound","terrace"]);static groundUnderFootprint(t,e,i,n,s,r=0){const o=Ye.sizeOf(t);if(r>o.heightM)return s(e,i);const c=(n??0)*Math.PI/180,l=Math.min(21,Math.max(2,Math.ceil(o.lengthM/.75)+1)),h=Math.min(21,Math.max(2,Math.ceil(o.widthM/.75)+1)),u=Ye.GROWS_FROM_GROUND.has(t.kind);let d=u?1/0:-1/0;for(let f=0;f<l;f++){const p=(f/(l-1)-.5)*o.lengthM;for(let v=0;v<h;v++){const m=(v/(h-1)-.5)*o.widthM,g=e+Math.sin(c)*p+Math.cos(c)*m,b=i-Math.cos(c)*p+Math.sin(c)*m;d=u?Math.min(d,s(g,b)):Math.max(d,s(g,b))}}return Number.isFinite(d)?d:s(e,i)}static occupantView(t,e=t.headingDeg){const i=t.observerSide;if(!i)throw new Error("occupantView requires object.observerSide to be set");const{x:n,z:s}=t.kind==="vehicle"?pp(i,Tr,Ao,iy):pp(i,mp/2,gp/2,ey),r=t.kind==="vehicle"?TR:(t.occupiedFloor??0)*Or+mR,o=(e??0)-j2[t.observerFacing??i]/df,c=this.scaleFor(t);return{x:n*c.x,z:s*c.z,eyeY:r*c.y,headingDeg:o}}static BODY_NAME="decor-body";static bodyOf(t){return t.getObjectByName(Ye.BODY_NAME)??t}static repeatOnGrid(t,e,i,n,s){const r=t.getAttribute("position"),o=t.getAttribute("normal"),c=t.getIndex();if(!c)throw new Error("repeatOnGrid needs an indexed geometry");const l=r.count,h=e*n,u=new Float32Array(l*h*3),d=new Float32Array(l*h*3),f=new Uint32Array(c.count*h),p=-((e-1)*i)/2,v=-((n-1)*s)/2;let m=0;for(let b=0;b<n;b++)for(let S=0;S<e;S++,m++){const M=v+b*s,x=p+S*i;for(let _=0;_<l;_++){const A=(m*l+_)*3;u[A]=r.getX(_)+M,u[A+1]=r.getY(_),u[A+2]=r.getZ(_)+x,d[A]=o.getX(_),d[A+1]=o.getY(_),d[A+2]=o.getZ(_)}for(let _=0;_<c.count;_++)f[m*c.count+_]=c.getX(_)+m*l}const g=new ae;return g.setAttribute("position",new ve(u,3)),g.setAttribute("normal",new ve(d,3)),g.setIndex(new Gp(f,1)),g}static fitTerrace(t,e,i){const n=Ye.sizeOf(e),s=n.widthM/2,r=n.lengthM/2,o=i(0,0)+n.heightM,c=Math.min(16,Math.max(1,Math.ceil(n.lengthM/3))),l=Ye.bodyOf(t).children.filter(M=>M.isMesh);if(l.length<2)return o;const h=Math.min(10,n.widthM/4),u=[-s];for(const M of[.25,.5,.75,1])u.push(-s+h*M);const d=Math.max(1,Math.ceil((n.widthM-2*h)/3));for(let M=1;M<d;M++)u.push(-s+h+(n.widthM-2*h)*M/d);for(const M of[1,.75,.5,.25,0])u.push(s-h*M);const f=M=>-r+n.lengthM*M/c,p=.8,v=(M,x)=>{const _=Math.min(1,Math.max(0,(s-Math.abs(M))/h)),A=_*_*(3-2*_);return A*o+(1-A)*Math.min(o,i(M,x))},m=[],g=(M,x)=>{const _=i(M[0],M[1])-p,A=i(x[0],x[1])-p,y=Math.max(v(M[0],M[1]),_),T=Math.max(v(x[0],x[1]),A);m.push(M[0],_,M[1],x[0],A,x[1],M[0],y,M[1]),m.push(x[0],A,x[1],x[0],T,x[1],M[0],y,M[1])};for(let M=0;M<u.length-1;M++)g([u[M],-r],[u[M+1],-r]),g([u[M],r],[u[M+1],r]);const b=[];for(let M=0;M<u.length-1;M++)for(let x=0;x<c;x++){const _=[u[M],f(x)],A=[u[M+1],f(x)],y=[u[M],f(x+1)],T=[u[M+1],f(x+1)];for(const[I,C,P]of[[_,y,A],[A,y,T]])for(const B of[I,C,P])b.push(B[0],v(B[0],B[1]),B[1])}const S=(M,x)=>{const _=new ae;_.setAttribute("position",new ve(x,3)),_.computeVertexNormals(),M.geometry.dispose(),M.geometry=_,M.position.y=0};return S(l[0],m),S(l[1],b),o}static fitCropToGround(t,e){t.updateMatrixWorld(!0);const i=new R;t.traverse(n=>{const s=n,r=s.userData.cropBasePositions,o=s.userData.cropVerticesPerClump;if(!s.isMesh||!r||!o)return;const c=s.geometry.getAttribute("position"),l=new ne().copy(s.matrixWorld).invert();for(let h=0;h<c.count;h+=o){i.set(r[h*3],0,r[h*3+2]).applyMatrix4(s.matrixWorld),i.y=e(i.x,i.z),i.applyMatrix4(l);for(let u=h;u<h+o;u++)c.setY(u,r[u*3+1]+i.y)}c.needsUpdate=!0,s.geometry.computeBoundingBox(),s.geometry.computeBoundingSphere()})}static paint(t,e){t.traverse(i=>{const n=i,s=n.userData;if(!n.isMesh||s?.emissive)return;const r=n.material;r?.color&&r.color.set(e)})}static build(t,e){const i=t.kind==="building"?rv(t.floors??Xm,t.windows,t.observerSide,t.occupiedFloor,t.observerFacing):t.kind==="tree"?ov():t.kind==="shrub"?av():t.kind==="bridge"?gR(t):t.kind==="wire"?vR(t):t.kind==="crop"?lv():t.kind==="terrace"?ER():t.kind==="mound"?hv():t.kind==="streetlight"?uv(e):t.kind==="vehicle"?dv(e,t.windows,t.observerSide,t.observerFacing):t.kind==="aircraft"?Mv():t.kind==="entity"?gv():vp();t.color&&this.paint(i,t.color);const n=this.scaleFor(t),s=new Ee;return i.name=Ye.BODY_NAME,i.scale.copy(n),s.add(i),t.headingDeg!==void 0&&(s.rotation.y=-t.headingDeg*df),this.addLights(s,t.lights),s}static scaleFor(t){const e=t.sizeM;if(!e||t.kind==="bridge"||t.kind==="wire"||t.kind==="terrace")return new R(1,1,1);const i=this.naturalSize(t.kind,t.floors);return new R(e.widthM===void 0?1:gf(e.widthM,i.widthM),e.heightM===void 0?1:gf(e.heightM,i.heightM),e.lengthM===void 0?1:gf(e.lengthM,i.lengthM))}static naturalSize(t,e){const i=t==="building"?Math.max(1,(e??Xm)+1):0;if(t==="bridge")return We.NATURAL_SIZE;if(t==="wire")return Ia.NATURAL_SIZE;if(t==="terrace")return{widthM:1,lengthM:1,heightM:1};const n=`${t}:${i}`,s=fv.get(n);if(s)return s;const r=t==="building"?rv(i-1,void 0,void 0,void 0):t==="tree"?ov():t==="shrub"?av():t==="crop"?lv():t==="mound"?hv():t==="streetlight"?uv(!1):t==="vehicle"?dv(!1,void 0,void 0):t==="aircraft"?Mv():t==="entity"?gv():vp(),o=new Qi().setFromObject(r),c={widthM:o.max.x-o.min.x,heightM:o.max.y-o.min.y,lengthM:o.max.z-o.min.z};return this.dispose(r),fv.set(n,c),c}static usesModel(t){return qf(t)!==void 0&&!(t.observerSide!==void 0&&mM(t.kind))}static applyModel(t,e,i,n={}){const s=this.bodyOf(t),r=new Ee;r.name=Ye.BODY_NAME,i.rotation.y=-(n.headingOffsetDeg??0)*df,i.updateMatrixWorld(!0);const o=new Qi().setFromObject(i),c={lengthM:o.max.z-o.min.z,heightM:o.max.y-o.min.y,widthM:o.max.x-o.min.x},l=pv(e.sizeM,c)??pv(n.depictedSizeM,c)??1;i.scale.multiplyScalar(l);const h=o.getCenter(new R).multiplyScalar(l);i.position.x-=h.x,i.position.z-=h.z,i.position.y-=e.kind==="aircraft"?h.y:o.min.y*l,i.traverse(u=>{u instanceof At&&(u.castShadow=!0,u.receiveShadow=!0)}),r.add(i),s.parent?(s.parent.add(r),s.removeFromParent()):t.add(r),this.dispose(s)}static sizeOf(t){const e=this.naturalSize(t.kind,t.floors);return{widthM:t.sizeM?.widthM??e.widthM,lengthM:t.sizeM?.lengthM??e.lengthM,heightM:t.sizeM?.heightM??e.heightM}}static addLights(t,e){for(const i of e??[]){const n=cR(i.color),s=Ae(t,new pi(ff,8,6),n,i.offsetM.y,!0);s.position.set(i.offsetM.x,i.offsetM.y,i.offsetM.z),s.userData={emissive:!0,lightId:i.id,lightColor:n},s.visible=!1;const r=s.material;r.blending=Pi,r.transparent=!0,r.depthWrite=!1,r.fog=!1}}static setLights(t,e,i,n,s=0,r=1,o=iR,c=[1,1,1]){if(!e||e.length===0)return;const l=new Map(e.map(f=>[f.id,f])),h=Math.max(1,n*o/ff),u=ff*h,d=r/(Math.PI*u*u);for(const f of t.children){if(!(f instanceof At))continue;const p=f.userData.lightId;if(!p)continue;const v=l.get(p);if(!v)continue;const m=s>0?MM(v,i,i+s):Px(v,i)?1:0;f.visible=m>0;const g=f.material,b=f.userData.lightColor;if(b){const S=m*nR*(v.intensity??1)*d;g.color.setRGB(b[0]*S*c[0],b[1]*S*c[1],b[2]*S*c[2])}f.scale.setScalar(h)}}static setLit(t,e,i,n=1){const[s,r,o]=e==="streetlight"?[sR,rR,Z2]:[aR,oR,J2],c=i?s*n/(Math.PI*r*r):0,l=[o[0]*c,o[1]*c,o[2]*c];t.traverse(h=>{const u=h.userData;!(h instanceof At)||!u.emissive||u.lightId||h.material.color.setRGB(...l)})}static dispose(t){t.traverse(e=>{if(!(e instanceof At)||e.userData.sharedModel)return;e.geometry.dispose();const i=e.material;for(const n of Array.isArray(i)?i:[i])n.dispose()})}}const Mf="https://ufoathome.org/models/index.json";class jc{attribution="3D models re-hosted by UFO@home, each under its own author's licence";fetchImpl;indexUrls;loading;static shared=new Map;sharing;constructor(t={}){this.sharing=!t.fetchImpl,this.fetchImpl=t.fetchImpl??fetch.bind(globalThis),this.indexUrls=t.indexUrls??DR()}async entries(t){const e=await this.load();return t?e.filter(i=>[i.kind].flat().includes(t)):e}async entry(t){return(await this.load()).find(e=>e.id===t)}load(){if(this.loading)return this.loading;if(!this.sharing)return this.loading=this.fetchFirstAvailable();const t=this.indexUrls.join(`
8063
- `);let e=jc.shared.get(t);return e||(e=this.fetchFirstAvailable(),jc.shared.set(t,e),e.then(i=>{i.length===0&&jc.shared.delete(t)})),this.loading=e}async fetchFirstAvailable(){for(const t of this.indexUrls){const e=await this.fetchIndex(t);if(e)return e}return[]}async fetchIndex(t){try{const e=await this.fetchImpl(t);if(!e.ok)return;const i=await e.json();return Array.isArray(i?.models)?i.models.map(({file:n,...s})=>({...s,url:new URL(n,t).href})):void 0}catch{return}}}function DR(){const a=`?v=${encodeURIComponent("0.104.1")}`,t=typeof location>"u"?void 0:new URL("/models/index.json",location.href).href;return(t&&t!==Mf?[t,Mf]:[Mf]).map(e=>e+a)}const IR=[{id:"ufoathome",name:"UFO@home",credit:"3D models re-hosted by UFO@home, each under its own author's licence",creditUrl:"https://ufoathome.org/models/",create:()=>new jc}];async function yf(a){const{GLTFLoader:t}=await je(async()=>{const{GLTFLoader:i}=await import("./GLTFLoader-C_t8vfKf.js");return{GLTFLoader:i}},[],import.meta.url),e=new t;return new Promise((i,n)=>{e.load(a,s=>i(Object.assign(s.scene,{animations:s.animations})),void 0,s=>n(new Error(`Could not load 3D model ${a}: ${s instanceof Error?s.message:String(s)}`)))})}const sy=["ellipsoid","sphere","disc","cylinder","cone","box","torus","figure"];class Cn{static MIN_ANGLE_RAD=.002;static FILL=(1-Math.exp(-4))/4;static MAX_SHARE=.3;mesh;constructor(t,e){this.mesh=new At(new dn(2,2),new Me({uniforms:{uColor:{value:new st(0,0,0)},uRadius:{value:1}},vertexShader:Cn.VERTEX,fragmentShader:Cn.FRAGMENT,transparent:!0,depthWrite:!1,blending:Pi,toneMapped:!1})),this.mesh.name=t,this.mesh.frustumCulled=!1,this.mesh.renderOrder=e,this.mesh.visible=!1}shine(t,e,i){this.mesh.visible=!0,this.mesh.position.set(t.x,t.y,t.z),this.mesh.material.uniforms.uRadius.value=e,this.mesh.material.uniforms.uColor.value.setRGB(i[0],i[1],i[2])}hide(){this.mesh.visible=!1}dispose(){this.mesh.geometry.dispose(),this.mesh.material.dispose()}static spread(t,e,i,n){const s=Math.max(t,n*Cn.MIN_ANGLE_RAD),r=Cn.FILL*Math.PI*s*s;return{radiusM:s,luminanceCdM2:i*Math.min(Cn.MAX_SHARE,e/r)}}static conserving(t){return Math.sqrt(t/(Cn.MAX_SHARE*Cn.FILL*Math.PI))}static VERTEX=`
8063
+ `);let e=jc.shared.get(t);return e||(e=this.fetchFirstAvailable(),jc.shared.set(t,e),e.then(i=>{i.length===0&&jc.shared.delete(t)})),this.loading=e}async fetchFirstAvailable(){for(const t of this.indexUrls){const e=await this.fetchIndex(t);if(e)return e}return[]}async fetchIndex(t){try{const e=await this.fetchImpl(t);if(!e.ok)return;const i=await e.json();return Array.isArray(i?.models)?i.models.map(({file:n,...s})=>({...s,url:new URL(n,t).href})):void 0}catch{return}}}function DR(){const a=`?v=${encodeURIComponent("0.105.1")}`,t=typeof location>"u"?void 0:new URL("/models/index.json",location.href).href;return(t&&t!==Mf?[t,Mf]:[Mf]).map(e=>e+a)}const IR=[{id:"ufoathome",name:"UFO@home",credit:"3D models re-hosted by UFO@home, each under its own author's licence",creditUrl:"https://ufoathome.org/models/",create:()=>new jc}];async function yf(a){const{GLTFLoader:t}=await je(async()=>{const{GLTFLoader:i}=await import("./GLTFLoader-C_t8vfKf.js");return{GLTFLoader:i}},[],import.meta.url),e=new t;return new Promise((i,n)=>{e.load(a,s=>i(Object.assign(s.scene,{animations:s.animations})),void 0,s=>n(new Error(`Could not load 3D model ${a}: ${s instanceof Error?s.message:String(s)}`)))})}const sy=["ellipsoid","sphere","disc","cylinder","cone","box","torus","figure"];class Cn{static MIN_ANGLE_RAD=.002;static FILL=(1-Math.exp(-4))/4;static MAX_SHARE=.3;mesh;constructor(t,e){this.mesh=new At(new dn(2,2),new Me({uniforms:{uColor:{value:new st(0,0,0)},uRadius:{value:1}},vertexShader:Cn.VERTEX,fragmentShader:Cn.FRAGMENT,transparent:!0,depthWrite:!1,blending:Pi,toneMapped:!1})),this.mesh.name=t,this.mesh.frustumCulled=!1,this.mesh.renderOrder=e,this.mesh.visible=!1}shine(t,e,i){this.mesh.visible=!0,this.mesh.position.set(t.x,t.y,t.z),this.mesh.material.uniforms.uRadius.value=e,this.mesh.material.uniforms.uColor.value.setRGB(i[0],i[1],i[2])}hide(){this.mesh.visible=!1}dispose(){this.mesh.geometry.dispose(),this.mesh.material.dispose()}static spread(t,e,i,n){const s=Math.max(t,n*Cn.MIN_ANGLE_RAD),r=Cn.FILL*Math.PI*s*s;return{radiusM:s,luminanceCdM2:i*Math.min(Cn.MAX_SHARE,e/r)}}static conserving(t){return Math.sqrt(t/(Cn.MAX_SHARE*Cn.FILL*Math.PI))}static VERTEX=`
8064
8064
  uniform float uRadius;
8065
8065
  varying vec2 vOffset;
8066
8066
  void main() {
@@ -8757,6 +8757,6 @@ void main() {
8757
8757
  gl_FragColor = vec4(color, tex.a * uOpacity * (1.0 - blur * 0.5));
8758
8758
  }
8759
8759
  `;function Yv(a){const e=document.createElement("canvas");e.width=128,e.height=128;const i=e.getContext("2d"),n=128/2-2,s=128/2,r=128/2,o="#010101",c="#f4f1e2";i.fillStyle=o,i.beginPath(),i.arc(s,r,n,0,Math.PI*2),i.fill();const l=ir(a.illuminatedFraction,0,1),h=a.phaseFraction<.5,u=n*Math.abs(1-2*l),d=l<.5;return i.save(),i.beginPath(),i.arc(s,r,n,0,Math.PI*2),i.clip(),i.fillStyle=c,i.beginPath(),h?(i.arc(s,r,n,-Math.PI/2,Math.PI/2,!1),i.ellipse(s,r,u,n,0,Math.PI/2,-Math.PI/2,d)):(i.arc(s,r,n,Math.PI/2,-Math.PI/2,!1),i.ellipse(s,r,u,n,0,-Math.PI/2,Math.PI/2,d)),i.fill(),i.restore(),new pr(e)}function TD(a){const t=document.createElement("canvas");t.width=128,t.height=128;const e=t.getContext("2d");return e.fillStyle="rgba(0, 0, 0, 0.55)",e.beginPath(),e.arc(64,64,60,0,Math.PI*2),e.fill(),e.fillStyle="#ffffff",e.font="bold 52px sans-serif",e.textAlign="center",e.textBaseline="middle",e.fillText(a,64,68),new pr(t)}function Nf(a){let t=a;return function(){t|=0,t=t+1831565813|0;let i=Math.imul(t^t>>>15,1|t);return i=i+Math.imul(i^i>>>7,61|i)^i,((i^i>>>14)>>>0)/4294967296}}class Wu{constructor(t,e){this.source=t,this.create=e}scene;wanted;pumping=!1;disposed=!1;static PATIENCE_FRAMES=600;static SCENE_WIDTH_PX=320;paint(t,e){this.disposed||(this.wanted={t,canvas:e},this.pumping||this.pump())}recordingChanged(t){this.scene&&(this.scene.sightingData=t)}dispose(){this.disposed=!0,this.scene?.remove(),this.scene=void 0}ensureScene(){if(this.scene)return this.scene;const t=this.create();return t.setAttribute("max-pixel-ratio","1"),Object.assign(t.style,{position:"fixed",left:"-10000px",top:"0",width:`${Wu.SCENE_WIDTH_PX}px`,visibility:"hidden",pointerEvents:"none"}),document.body.appendChild(t),t.documentUrl=this.source.documentUrl,t.accountInTheRound=this.source.accountInTheRound,t.sightingData=this.source.sightingData,this.scene=t,t}async pump(){this.pumping=!0;try{for(;this.wanted&&!this.disposed;){const{t,canvas:e}=this.wanted;this.wanted=void 0;const i=this.ensureScene();i.interpretation!==this.source.interpretation&&(i.interpretation=this.source.interpretation),i.compareAccount!==this.source.compareAccount&&(i.compareAccount=this.source.compareAccount),i.showAt(t);for(let n=0;n<Wu.PATIENCE_FRAMES&&!this.wanted&&!this.disposed&&(await new Promise(s=>requestAnimationFrame(()=>s())),!this.wanted);n++)if(i.snapshotTo(e)){e.dataset.ready="true";break}}}finally{this.pumping=!1}}}const kf=7.5,Ff=9;class _s{static cache=new Map;static load(t){let e=_s.cache.get(t);return e||(e=fetch(t).then(i=>i.arrayBuffer()).then(i=>_s.parse(i)),_s.cache.set(t,e)),e}static upTo(t,e){const i=t.filter((r,o)=>o===0||t[o-1].magnitudeLimit<e);if(i.length<=1)return _s.load(t[0].url);const n=i.map(r=>r.url).join(`
8760
- `);let s=_s.cache.get(n);return s||(s=Promise.all(i.map(r=>_s.load(r.url))).then(r=>r.reduce((o,c)=>_s.concat(o,c))),_s.cache.set(n,s)),s}static parse(t){const e=t.byteLength/(4*Float32Array.BYTES_PER_ELEMENT),i=e*Float32Array.BYTES_PER_ELEMENT;return{count:e,ra:new Float32Array(t,0*i,e),dec:new Float32Array(t,1*i,e),mag:new Float32Array(t,2*i,e),ci:new Float32Array(t,3*i,e)}}static concat(t,e){const i=(n,s)=>{const r=new Float32Array(n.length+s.length);return r.set(n,0),r.set(s,n.length),r};return{count:t.count+e.count,ra:i(t.ra,e.ra),dec:i(t.dec,e.dec),mag:i(t.mag,e.mag),ci:i(t.ci,e.ci)}}}class Ie{constructor(t){if(this.heights=t,t.length!==Ie.WIDTH*Ie.HEIGHT)throw new Error(`a lunar relief has ${Ie.WIDTH*Ie.HEIGHT} samples, not ${t.length}`)}static SAMPLES_PER_DEGREE=16;static WIDTH=360*Ie.SAMPLES_PER_DEGREE;static HEIGHT=180*Ie.SAMPLES_PER_DEGREE;static UNIT_KM=.1;static REFERENCE_RADIUS_KM=1737.4;static BAND_FROM_DEG=74;static BAND_TO_DEG=106;heightKm(t,e){const i=Ie.SAMPLES_PER_DEGREE,n=(e%360+360)%360*i-.5,s=(90-t)*i-.5,r=Math.floor(n),o=Math.floor(s),c=n-r,l=s-o,h=(f,p)=>{const v=(f%Ie.WIDTH+Ie.WIDTH)%Ie.WIDTH,m=Math.min(Ie.HEIGHT-1,Math.max(0,p));return this.heights[m*Ie.WIDTH+v]},u=h(r,o)*(1-c)+h(r+1,o)*c,d=h(r,o+1)*(1-c)+h(r+1,o+1)*c;return(u*(1-l)+d*l)*Ie.UNIT_KM}static inBand(t,e){const i=Math.PI/180,n=Math.acos(Math.cos(t*i)*Math.cos(e*i))*180/Math.PI;return n>=Ie.BAND_FROM_DEG&&n<=Ie.BAND_TO_DEG}static withBump(t,e,i,n=.4){const s=new Int8Array(Ie.WIDTH*Ie.HEIGHT),r=Ie.SAMPLES_PER_DEGREE,o=Math.ceil(n*r),c=Math.floor(e*r),l=Math.floor((90-t)*r);for(let h=-o;h<=o;h++)for(let u=-o;u<=o;u++)Math.hypot(u,h)<=o&&(s[(l+h)*Ie.WIDTH+(c+u+Ie.WIDTH)%Ie.WIDTH]=Math.round(i/Ie.UNIT_KM));return new Ie(s)}static smooth(){return new Ie(new Int8Array(Ie.WIDTH*Ie.HEIGHT))}}class Vn{static SAMPLES=5760;static SEARCH_FROM_DEG=87;static SEARCH_TO_DEG=90.2;static SEARCH_STEP_DEG=.0625;static profile(t,e,i,n=Vn.SAMPLES){const{s,u:r,w:o,distanceKm:c}=Vn.frame(t,e),l=Math.PI/180,h=new Float32Array(n),u=Ie.REFERENCE_RADIUS_KM;for(let d=0;d<n;d++){const f=d/n*2*Math.PI,p=Math.cos(f),v=Math.sin(f),m=p*r[0]+v*o[0],g=p*r[1]+v*o[1],b=p*r[2]+v*o[2];let S=0;for(let M=Vn.SEARCH_FROM_DEG;M<=Vn.SEARCH_TO_DEG;M+=Vn.SEARCH_STEP_DEG){const x=Math.cos(M*l),_=Math.sin(M*l),A=x*s[0]+_*m,y=x*s[1]+_*g,T=x*s[2]+_*b,I=Math.asin(Math.max(-1,Math.min(1,T)))/l,C=Math.atan2(y,A)/l,P=u+i.heightKm(I,C),B=Math.atan2(P*_,c-P*x);B>S&&(S=B)}h[d]=S/l}return{radiusDeg:h,meanRadiusDeg:Math.asin(u/c)/l}}static frame(t,e){const i=new qr(e.lat,e.lng,e.elevationM),n=ur(t),s=np(t,i,!1),r=new ge(s.x-n.x,s.y-n.y,s.z-n.z,n.t),o=Math.hypot(r.x,r.y,r.z)*Vn.AU_KM,c=Vn.bodyFixed(t),l=c(r),h=Math.hypot(l[0],l[1],l[2]),u=[l[0]/h,l[1]/h,l[2]/h],d=h4(t,i),f=cm(d),p=cr(d,new ge(-r.x,-r.y,-r.z,n.t)),v=Math.asin(p.z/Math.hypot(p.x,p.y,p.z)),m=Math.atan2(-p.y,p.x),g=new ge(-Math.sin(v)*Math.cos(m),Math.sin(v)*Math.sin(m),Math.cos(v),n.t),b=new ge(-Math.sin(m),-Math.cos(m),0,n.t);return{s:u,u:c(cr(f,g)),w:c(cr(f,b)),distanceKm:o}}static surfacePoint(t,e,i,n){const{s,u:r,w:o}=Vn.frame(t,e),c=Math.PI/180,l=[0,1,2].map(u=>Math.cos(i*c)*r[u]+Math.sin(i*c)*o[u]),h=[0,1,2].map(u=>Math.cos(n*c)*s[u]+Math.sin(n*c)*l[u]);return{latDeg:Math.asin(h[2])/c,lonDeg:Math.atan2(h[1],h[0])/c}}static radiusAt(t,e){const i=t.radiusDeg.length,n=(e/360*i%i+i)%i,s=Math.floor(n),r=n-s;return t.radiusDeg[s]*(1-r)+t.radiusDeg[(s+1)%i]*r}static uncoveredFraction(t,e,i){const n=t.radiusDeg.length,s=i.upDeg*i.upDeg+i.rightDeg*i.rightDeg;let r=0;for(let o=0;o<n;o++){const c=o/n*2*Math.PI,l=Math.cos(c),h=Math.sin(c),u=l*i.upDeg+h*i.rightDeg,d=u*u-s+e*e;if(d<=0)continue;const f=Math.sqrt(d),p=u+f;if(p<=0)continue;const v=Math.max(0,u-f),m=Math.max(v,t.radiusDeg[o]);p>m&&(r+=.5*(p*p-m*m))}return Math.min(1,Math.max(0,r*(2*Math.PI/n)/(Math.PI*e*e)))}static AU_KM=1495978707e-1;static bodyFixed(t){const e=A4(ut.Moon,t),i=Math.PI/180,n=e.ra*15*i,s=e.dec*i,r=e.spin*i,o=(l,[h,u,d])=>[Math.cos(l)*h+Math.sin(l)*u,-Math.sin(l)*h+Math.cos(l)*u,d],c=(l,[h,u,d])=>[h,Math.cos(l)*u+Math.sin(l)*d,-Math.sin(l)*u+Math.cos(l)*d];return l=>o(r,c(Math.PI/2-s,o(Math.PI/2+n,[l.x,l.y,l.z])))}static subObserverPoint(t,e){const i=new qr(e.lat,e.lng,e.elevationM),n=ur(t),s=np(t,i,!1),r=Vn.bodyFixed(t)(new ge(s.x-n.x,s.y-n.y,s.z-n.z,n.t)),o=Math.hypot(r[0],r[1],r[2]);return{latDeg:Math.asin(r[2]/o)*180/Math.PI,lonDeg:Math.atan2(r[1],r[0])*180/Math.PI}}}class Qc{static cache=new Map;static load(t){let e=Qc.cache.get(t);return e||(e=Qc.fetchRelief(t).catch(()=>{}),Qc.cache.set(t,e)),e}static async fetchRelief(t){const e=await fetch(t);if(!e.ok)return;let i=new Uint8Array(await e.arrayBuffer());if(i[0]===31&&i[1]===139){if(typeof DecompressionStream>"u")return;const n=new Blob([i]).stream().pipeThrough(new DecompressionStream("gzip"));i=new Uint8Array(await new Response(n).arrayBuffer())}return new Ie(new Int8Array(i.buffer,i.byteOffset,i.length))}}class Xu{constructor(t){this.names=t}body(t,e){return this.names?.bodies[t]??e}star(t){return this.names?.stars[t.name]??t.name}comet(t){return this.names?.comets[t.id]??t.name}nova(t){return this.names?.novae[t.id]??t.name}satelliteClass(t){return this.names?.satelliteClasses[t.id]??t.name}shower(t){return this.names?.showers[t.id]??t.name}lightRig(t){return this.names?.lightRigs[t.id]??t.name}instrument(t){return this.names?.instruments[t.id]??t.name}decorKind(t,e){return this.names?.decorKinds[t]??e}point(t){return Na.point(t,this.names?.compassPoints)}towards(t){return Na.towards(t,this.names)}}const RD=new URL(""+new URL("rain-BvWZrB9h.ogg",import.meta.url).href,import.meta.url).href,DD=new URL(""+new URL("wind-BjklexY7.ogg",import.meta.url).href,import.meta.url).href,ID=new URL(""+new URL("thunder-DA48qs_v.wav",import.meta.url).href,import.meta.url).href,CD=20,PD=1;class OD{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};level=1;master;output(t){return this.master||(this.master=t.createGain(),this.master.gain.value=this.level,this.master.connect(t.destination)),this.master}setLevel(t){this.level=t,this.master&&(this.master.gain.value=t)}resume(){if(!this.context){if(typeof AudioContext>"u")return;try{this.context=new AudioContext}catch(t){console.warn("WeatherAudio: Web Audio unavailable, weather sounds disabled:",t);return}}Oa.unlock(this.context)}setAmbient(t,e,i){if(this.requested={type:t,intensity:e,windSpeed:i},!this.context)return;this.paused&&(t="none",e=0,i=0);const n=t==="rain"||t==="hail"?t:"none";if(this.ambientVolume=n==="hail"?Math.min(1,e*1.3+.2):n==="rain"?e:0,n!==this.ambientKey){this.ambientKey=n;const r=++this.ambientToken;this.stopSource(this.ambientSource,this.ambientGain),this.ambientSource=void 0,this.ambientGain=void 0,n!=="none"&&this.startLoop(RD,this.ambientVolume).then(o=>this.applyIfCurrent(o,r,()=>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(i/CD,1);const s=i>PD;if(s!==this.windActive){this.windActive=s;const r=++this.windToken;this.stopSource(this.windSource,this.windGain),this.windSource=void 0,this.windGain=void 0,s&&this.startLoop(DD,this.windVolume).then(o=>this.applyIfCurrent(o,r,()=>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(t){if(t===this.paused)return;this.paused=t;const{type:e,intensity:i,windSpeed:n}=this.requested;this.setAmbient(e,i,n)}playThunder(){!this.context||this.paused||this.playOneShot(ID,.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.master=void 0,this.buffers.clear()}applyIfCurrent(t,e,i,n){if(e!==i()){t?.source.stop();return}n(t)}async startLoop(t,e){const i=this.context;if(i)try{const n=await this.getBuffer(t),s=i.createBufferSource();s.buffer=n,s.loop=!0;const r=i.createGain();return r.gain.value=e,s.connect(r).connect(this.output(i)),s.start(),{source:s,gain:r}}catch(n){console.warn("Weather ambient sound failed to load, staying silent:",n);return}}async playOneShot(t,e){const i=this.context;if(i)try{const n=await this.getBuffer(t),s=i.createBufferSource();s.buffer=n;const r=i.createGain();r.gain.value=e,s.connect(r).connect(this.output(i)),s.start()}catch(n){console.warn("Thunder sound failed to load:",n)}}async getBuffer(t){const e=this.context;if(!e)throw new Error("WeatherAudio: AudioContext not ready — resume() must be called first");let i=this.buffers.get(t);return i||(i=fetch(t).then(n=>{if(!n.ok)throw new Error(`Audio fetch failed (${n.status}): ${t}`);return n.arrayBuffer()}).then(n=>e.decodeAudioData(n)),this.buffers.set(t,i)),i}stopSource(t,e){try{t?.stop()}catch{}t?.disconnect(),e?.disconnect()}}class nr{constructor(t){this.elements=t;const{eccentricity:e,perihelionAu:i}=t,[n,s]=this.perifocalAxes(),r=Math.sqrt(nr.SUN_GM_AU3_PER_DAY2*(1+e)/i);this.perihelionPosition=this.scale(n,i),this.perihelionVelocity=this.scale(s,r),this.inverseSemiMajorAxis=(1-e)/i}static SUN_GM_AU3_PER_DAY2=.0002959122082855911;static MAX_ITERATIONS=200;perihelionPosition;perihelionVelocity;inverseSemiMajorAxis;positionAt(t){const e=t-this.elements.perihelionJd,i=this.universalAnomaly(e),n=this.inverseSemiMajorAxis*i*i,s=this.elements.perihelionAu,r=1-i*i/s*nr.stumpffC(n),o=e-i*i*i/Math.sqrt(nr.SUN_GM_AU3_PER_DAY2)*nr.stumpffS(n);return{x:r*this.perihelionPosition.x+o*this.perihelionVelocity.x,y:r*this.perihelionPosition.y+o*this.perihelionVelocity.y,z:r*this.perihelionPosition.z+o*this.perihelionVelocity.z}}heliocentricDistanceAt(t){const e=this.positionAt(t);return Math.hypot(e.x,e.y,e.z)}universalAnomaly(t){if(t===0)return 0;const e=Math.sign(t),i=Math.sqrt(nr.SUN_GM_AU3_PER_DAY2)*Math.abs(t),n=o=>{const c=this.inverseSemiMajorAxis*o*o,l=this.elements.perihelionAu;return(1-this.inverseSemiMajorAxis*l)*o*o*o*nr.stumpffS(c)+l*o};let s=Math.max(1,i/this.elements.perihelionAu);for(;n(s)<i;)s*=2;let r=0;for(let o=0;o<nr.MAX_ITERATIONS&&s-r>1e-13*Math.max(1,s);o++){const c=(r+s)/2;n(c)<i?r=c:s=c}return e*(r+s)/2}perifocalAxes(){const t=this.elements.ascendingNodeDeg*Math.PI/180,e=this.elements.argumentOfPerihelionDeg*Math.PI/180,i=this.elements.inclinationDeg*Math.PI/180,n=Math.cos(t),s=Math.sin(t),r=Math.cos(e),o=Math.sin(e),c=Math.cos(i),l=Math.sin(i);return[{x:n*r-s*o*c,y:s*r+n*o*c,z:o*l},{x:-n*o-s*r*c,y:-s*o+n*r*c,z:r*l}]}scale(t,e){return{x:t.x*e,y:t.y*e,z:t.z*e}}static stumpffC(t){if(Math.abs(t)<1e-6)return 1/2-t/24+t*t/720;if(t>0)return(1-Math.cos(Math.sqrt(t)))/t;const e=Math.sqrt(-t);return(Math.cosh(e)-1)/-t}static stumpffS(t){if(Math.abs(t)<1e-6)return 1/6-t/120+t*t/5040;if(t>0){const i=Math.sqrt(t);return(i-Math.sin(i))/(i*i*i)}const e=Math.sqrt(-t);return(Math.sinh(e)-e)/(e*e*e)}}const cy=[{id:"halley-1910",designation:"1P/Halley",name:"Halley's Comet",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:"Comet 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:"Comet 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:"Comet 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:"the Southern Comet",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:"the Eclipse Comet",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:"Comet 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:"Comet 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:"Comet 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:"Comet 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:"Comet 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:"Comet 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:"Comet 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:"Comet 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:"Comet 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:"Halley's Comet",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:"Comet 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:"Comet 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:"Comet 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:"Comet 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:"Comet 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:"Comet 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:"Comet 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 LD{static WINDOW_DAYS=200;static TWILIGHT_ELONGATION_DEG=15;static LIGHT_SPEED_AU_PER_DAY=173.144632674;static orbits=new Map;static aroundDate(t){const e=this.julianDayOf(t);return cy.filter(i=>Math.abs(e-i.orbit.perihelionJd)<=this.WINDOW_DAYS)}static brightestAt(t,e){return this.aroundDate(t).map(i=>this.appearanceOf(i,t,e)).sort((i,n)=>i.magnitude-n.magnitude)[0]}static appearanceOf(t,e,i){const n=Ne(e),s=this.earthPositionAt(n),r=this.apparentPositionOf(t,2451545+n.tt,s),o=this.subtract(r,s),c=this.length(r),l=this.length(o),h=this.tailEndAt(t,r,s,c,n,e,i),u=this.horizontalOf(o,n,e,i);return{apparition:t,position:u,...h,heliocentricDistanceAu:c,earthDistanceAu:l,elongationDeg:this.angleBetween(o,this.subtract({x:0,y:0,z:0},s)),magnitude:this.magnitudeAt(t,c,l)}}static magnitudeAt(t,e,i){const n=t.absoluteMagnitude+5*Math.log10(i)+2.5*t.activityExponent*Math.log10(e);return Math.max(n,t.peakMagnitude)}static tailEndAt(t,e,i,n,s,r,o){if(t.tailLengthAu===void 0)return{};const c=1+t.tailLengthAu/n,l=this.subtract({x:e.x*c,y:e.y*c,z:e.z*c},i),h=this.subtract(e,i);return{tailEnd:this.horizontalOf(l,s,r,o),tailLengthDeg:this.angleBetween(h,l)}}static apparentPositionOf(t,e,i){const n=this.orbitOf(t);let s=n.positionAt(e);for(let r=0;r<2;r++){const o=this.length(this.subtract(s,i))/this.LIGHT_SPEED_AU_PER_DAY;s=n.positionAt(e-o)}return s}static horizontalOf(t,e,i,n){const s=cr(a4(),new ge(t.x,t.y,t.z,e)),r=cr(W2(e),s),o=np(e,new qr(n.lat,n.lng,n.elevationM),!0),c=new ge(r.x-o.x,r.y-o.y,r.z-o.z,e),l=fd(c);return um(l.ra,l.dec,i,n)}static earthPositionAt(t){return cr(r4(),Wr(ut.Earth,t))}static julianDayOf(t){return 2451545+Ne(t).tt}static orbitOf(t){const e=this.orbits.get(t.id);if(e)return e;const i=new nr(t.orbit);return this.orbits.set(t.id,i),i}static subtract(t,e){return{x:t.x-e.x,y:t.y-e.y,z:t.z-e.z}}static length(t){return Math.hypot(t.x,t.y,t.z)}static angleBetween(t,e){const i=(t.x*e.x+t.y*e.y+t.z*e.z)/(this.length(t)*this.length(e)||1);return Math.acos(Math.min(1,Math.max(-1,i)))*180/Math.PI}}const Uf=[{id:"sn-1006",kind:"supernova",designation:"SN 1006",name:"Supernova of 1006",raHours:15.03947,decDeg:-42.09694,peakMagnitude:-7.5,peakJd:2088620,startJd:2088620,lightCurve:[[0,-7.5],[29,-5.9],[60,-4.9],[106,-3.2],[166,-1.9],[258,-1],[350,.5],[364,.7],[411,1.2],[456,1.8],[484,2.5],[785.5,7]],source:"Winkler, Gupta & Long 2003 (peak); decline borrowed from SN 1572",note:"The brightest stellar event in recorded history, seen in daylight, low in the southern sky from Europe and the Near East. The decline is modelled, not recorded, and falls below the naked eye after about two years where the chronicles speak of three."},{id:"sn-1054",kind:"supernova",designation:"SN 1054",name:"Supernova of 1054",raHours:5.5755,decDeg:22.0175,peakMagnitude:-6,peakJd:2106216,startJd:2106216,lightCurve:[[0,-6],[23,-4],[642,6]],source:"Chinese chronicles (Song huiyao), via Stephenson & Green 2002",note:"The explosion that left the Crab Nebula. Its magnitude is an estimate; the two durations are recorded."},{id:"sn-1181",kind:"supernova",designation:"SN 1181",name:"Supernova of 1181",raHours:.88645,decDeg:67.50067,peakMagnitude:0,peakJd:2152636,startJd:2152636,lightCurve:[[0,0],[185,6]],source:"Chinese and Japanese chronicles, via Stephenson & Green 2002",note:"Circumpolar from Europe and China, so never set. Its peak magnitude is uncertain by at least a magnitude."},{id:"sn-1572",kind:"supernova",designation:"SN 1572",name:"Tycho's Supernova",raHours:.42264,decDeg:64.14083,peakMagnitude:-4,peakJd:2295551,startJd:2295546,lightCurve:[[0,-3],[5,-4],[34,-2.4],[65,-1.4],[111,.3],[171,1.6],[263,2.5],[355,4],[369,4.2],[416,4.7],[461,5.3],[489,6]],source:"Tycho Brahe and contemporaries, reduced by Ruiz-Lapuente 2004",note:"Circumpolar from northern Europe. Tycho showed it had no parallax, so it was not in the air: a new star, beyond the Moon."},{id:"sn-1604",kind:"supernova",designation:"SN 1604",name:"Kepler's Supernova",raHours:17.51125,decDeg:-21.48733,peakMagnitude:-2.95,peakJd:2307210,startJd:2307191,lightCurve:[[0,.23],[3,-1.3],[6,-2.08],[9,-2.17],[19,-2.95],[27,-2.95],[32,-1.95],[36,-1.52],[86,.9],[96,.45],[103,1],[114,1.2],[118,1.55],[133,1.95],[137,2.3],[170,2.25],[185,2.25],[194,2.4],[197,2.9],[308,4.45],[324,4.45],[339,4.95],[364,4.7]],source:"Kepler, Fabricius, Maestlin and the Korean court astronomers, reduced by Ruiz-Lapuente 2017",note:"The last supernova in our Galaxy seen with the naked eye. It went behind the Sun from mid-November 1604 to January 1605, which is the gap in its record."},{id:"t-crb-1866",kind:"nova",designation:"T CrB",name:"Nova Coronae Borealis 1866",raHours:15.99171,decDeg:25.92017,peakMagnitude:2,peakJd:2402734,startJd:2402734,lightCurve:[[0,2],[1.5,3],[2.5,3.11],[6.5,5.18],[8.5,5.75],[10.5,6.85],[11.5,6.8],[12.5,7.5],[16,8.18],[32,9.27],[38,9.2],[40,8.95],[44,9.4],[48,9.07],[54,9.4],[58,9.21],[79,9.44],[107,9.26],[111,9.01],[115,8.21],[119,7.96],[159,7.51],[179,7.57],[183,7.97],[191,7.66],[199,8.2],[207,8.31],[211,8.83],[215,8.65],[223,8.97],[297,8.9],[345,9.25],[377,9.07],[425,9.3],[537,9.3]],source:"Recorded peak (Birmingham); curve borrowed from its 1946 eruption",note:"The first eruption of the recurrent nova T CrB to be seen. The decline is its 1946 one."},{id:"t-aur-1891",kind:"nova",designation:"T Aur",name:"Nova Aurigae 1891",raHours:5.53309,decDeg:30.44583,peakMagnitude:4.49,peakJd:2412083,startJd:2412079,lightCurve:[[0,5.28],[4,4.49],[24,4.58],[40,4.97],[52,4.95],[56,4.5],[60,4.9],[68,4.88],[72,5.25],[76,4.93],[84,5.44],[88,7.23],[96,8.85],[100,10.44]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"gk-per-1901",kind:"nova",designation:"GK Per",name:"Nova Persei 1901",raHours:3.52,decDeg:43.90431,peakMagnitude:.19,peakJd:24154395e-1,startJd:24154377e-1,lightCurve:[[0,2.7],[.8,.86],[1.8,.19],[2.3,.2],[5.8,1.78],[11.8,2.54],[12.8,2.98],[17.8,3.62],[18.8,3.35],[19.8,3.77],[20.8,3.59],[22.8,3.95],[24.8,3.82],[25.6,4.99],[25.9,4.89],[26.6,3.69],[27.6,3.94],[27.9,4.61],[28.6,5.28],[28.9,4.46],[29.9,3.8],[30.9,4.27],[31.6,5.21],[31.9,5.22],[32.9,3.88],[33.9,4.19],[34.6,4.85],[35.6,4.8],[36.6,4.23],[37.6,4.44],[38.9,4.15],[39.7,5.19],[40.6,5.39],[40.9,5.35],[41.9,4.01],[42.6,4.5],[42.9,4.49],[43.6,5.53],[44,5.23],[44.6,5.61],[44.9,5.5],[45.9,4.17],[46.9,4.69],[47.6,5.5],[48.6,5.59],[49.6,5.14],[49.9,4.48],[50.6,4.45],[50.9,4.55],[51.6,5.47],[52.6,5.74],[53.7,5.66],[55.7,4.41],[56.7,5.43],[58.7,5.81],[58.9,5.58],[59.7,5.64],[59.9,4.76],[60.9,4.26],[61.9,5.62],[62.7,5.85],[62.9,5.53],[63.7,5.8],[64.9,4.28],[65.6,5.33],[66.7,5.87],[66.9,5.56],[68.7,5.7],[68.9,5.3],[69.7,4.47],[70.7,5.65],[72.9,5.98],[73.9,5.71],[74.7,4.98],[74.9,4.46],[75.7,4.87],[76.9,6.05],[77.6,5.76],[78,6],[78.7,5.95],[80.7,4.98],[81.9,5.85],[82.7,6.02],[84.7,5.41],[84.9,5.08],[85.7,5.17],[85.9,5.6],[87,6.1],[88.8,6.2],[89.7,4.96],[89.9,4.93],[90.7,5.9],[91.9,6.32],[92.7,5.86],[93.1,6.24],[93.7,5.38],[93.9,6.2],[96.1,6.12],[97.1,6.37],[97.6,5.12],[98,5.85],[99.3,6.35],[101.3,6.12],[101.7,5.25],[102.3,4.95],[102.7,6.12],[103.2,5.83],[104.7,6.37],[105,6.13],[106,6.22],[106.7,4.88],[107.7,6.3],[108.1,6.4],[109,6],[109.7,5.16],[110,5.82],[112.1,5.89],[113.1,5.5],[115.7,5.8],[116,6.11],[118.7,5.68],[119,6.23],[119.7,5.85],[120,6.12],[121,4.62],[121.8,5.9],[123,5.48],[125,6.05],[126,5.89],[130.9,6.11],[146.1,6.02],[155.6,6.26],[180.4,6.09],[190.4,6.39],[245.5,6.87],[266.2,6.77],[301.1,7.16],[321.5,7.07],[346.5,7.87],[375.7,7.86],[385.8,8.09],[389.8,8.55],[406.1,8.33],[416.5,8.59],[445.9,8.62],[472.1,9.24],[565.9,9.74],[571,9.4],[589.8,9.76]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"Discovered on 21 February 1901 by Thomas Anderson in Edinburgh, and the brightest nova of the century until V603 Aql."},{id:"dn-gem-1912",kind:"nova",designation:"DN Gem",name:"Nova Geminorum 1912",raHours:6.9151,decDeg:32.14108,peakMagnitude:3.58,peakJd:241947675e-2,startJd:241947275e-2,lightCurve:[[0,11.7],[1,4.5],[4,3.58],[5,4.45],[5.5,5.32],[6,5.53],[6.5,5.11],[8,5.43],[8.5,5.16],[11,5.53],[11.5,5.13],[12,5.18],[13.75,4.5],[15.75,5.3],[18.75,6],[19.75,5.55],[26.75,6],[28.75,5.9],[31.75,6.6],[32.75,6.2],[33.75,6.5],[36.75,6.55],[39.75,6.2],[40.75,6.75],[41.75,7],[44.75,6.75],[52.75,6.75],[54.75,7.23],[58.25,7.5],[62.25,7.3],[64.25,7.47],[66.25,8.1],[70.25,7.5],[72.25,8.1],[78.25,7.55],[80.25,8.2],[86.25,7.2],[90.25,7.3],[92.25,7.8],[152.25,7.2],[160.25,7.4],[166.25,8.2],[168.25,8.2],[170.25,7.3],[180.25,7.4],[182.25,8],[186.25,7.5],[190.25,7.6],[192.25,8],[211.25,7.75],[227.25,8],[275.25,7.78],[315.25,8.6],[331.25,7.79],[339.25,8.27],[363.25,8.61],[443.25,8.93],[451.25,9.2],[535.25,10.3],[567.25,9.9],[615.25,10.8],[631.25,10.63],[647.25,10.88],[679.25,10.8],[695.25,11.07],[727.25,11]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"v603-aql-1918",kind:"nova",designation:"V603 Aql",name:"Nova Aquilae 1918",raHours:18.81518,decDeg:.58414,peakMagnitude:-.5,peakJd:242175475e-2,startJd:242174875e-2,lightCurve:[[0,11.3],[2,10.5],[4,6.6],[4.5,1.04],[6,-.5],[6.5,.18],[10,1.1],[10.5,.95],[12.75,1.89],[21.75,3.07],[23.75,3.76],[29.75,3.16],[34.75,3.5],[36.75,3.86],[44.75,3.79],[48.75,4.43],[52.75,3.84],[56.75,3.95],[57.75,4.04],[58.75,4.49],[59.75,4.42],[60.75,4.69],[62.75,4.6],[63.75,4.11],[64.75,3.97],[68.75,4.18],[70.75,4.65],[71.75,4.51],[73.75,4.73],[75.75,4.44],[79.75,4.85],[83.75,4.43],[89.75,4.88],[92.75,4.86],[94.75,4.58],[96.75,4.92],[99.75,5.05],[163.25,5.45],[167.25,5.7],[179.25,5.48],[191.25,5.8],[203.25,5.5],[247.25,5.9],[251.25,6.25],[257.25,5.5],[265.25,6.13],[281.25,6.33],[345.25,6.3],[385.25,6.73],[393.25,6.43],[425.25,6.71],[433.25,6.56],[461.25,7.27],[525.25,7.6],[541.25,7.47],[637.25,8.3],[669.25,8.17],[717.25,8.55],[749.25,8.4],[765.25,8.68],[885.25,8.75],[949.25,9.4],[1013.25,9.19],[1141.25,9.57],[1269.25,9.48],[1333.25,9.95],[1653.25,9.94],[1781.25,10.28],[1909.25,10.34],[2037.25,10.1],[2101.25,10.46],[2165.25,10.51],[2357.25,10.3],[2549.25,10.77],[2741.25,10.46],[2869.25,10.83],[3125.25,10.71],[3317.25,11.22],[3381.25,10.91],[3637.25,11.42],[3829.25,10.96],[3893.25,11.65],[3957.25,11.63],[4085.25,11.14],[4213.25,11.48],[4277.25,10.7],[4341.25,11.42],[4405.25,11.47],[4469.25,11.06],[4533.25,11.08],[4597.25,11.7],[4725.25,11.45],[4789.25,10.94]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"The brightest nova of the modern era, at magnitude -0.5 on 9-10 June 1918: as bright as Vega, in a summer evening sky, in wartime."},{id:"v476-cyg-1920",kind:"nova",designation:"V476 Cyg",name:"Nova Cygni 1920",raHours:19.97347,decDeg:53.61858,peakMagnitude:1.94,peakJd:242256025e-2,startJd:242255925e-2,lightCurve:[[0,2.7],[1,1.94],[3,2.07],[4.5,2.95],[8.25,4],[31.75,6.41],[35.75,7.23],[37.75,7.08],[41.75,7.33],[43.75,7.92],[45.75,8.2],[51.75,8.59],[63.75,8.82],[65.75,9.25],[71.75,8.93],[85.75,9.43],[87.75,9.05],[95.75,9.2],[97.75,8.67],[99.75,9.07],[112.75,8.78],[120.75,9.03],[128.75,8.67],[144.75,8.94],[152.75,8.73],[168.75,8.79],[176.75,9.28],[192.75,9],[216.75,9.6],[232.75,9.27],[240.75,9.5],[288.75,9.4],[296.75,9.6],[304.75,9.3],[320.75,9.73],[328.75,9.5],[336.75,9.8],[428.75,9.61],[476.75,10.01],[492.75,9.76],[508.75,9.87],[524.75,9.65],[556.75,9.87],[572.75,9.65],[620.75,10.22],[668.75,10.44],[684.75,10.23],[716.75,10.33],[756.75,10.66],[884.75,10.59],[948.75,10.96],[1108.75,10.96]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"rr-pic-1925",kind:"nova",designation:"RR Pic",name:"Nova Pictoris 1925",raHours:6.59335,decDeg:-62.64008,peakMagnitude:.95,peakJd:24243085e-1,startJd:24242995e-1,lightCurve:[[0,2.43],[5,2.35],[6,2.1],[7,2.4],[9,.95],[13,1.8],[14,1.7],[16,2.15],[18,2.2],[19,1.9],[23,3.1],[27,3.05],[31.5,3.58],[43.5,3.08],[47.5,3.15],[57.5,2.3],[59.5,1.65],[63.5,3.03],[65.5,2.84],[67.5,3.16],[69.5,2.4],[71.5,2.04],[73.5,2.05],[75.5,2.55],[79.5,3],[83.5,3.15],[116.5,3.54],[120.5,3.78],[124.5,3.67],[136.5,4.18],[148.5,4.34],[154.5,4.17],[194.5,4.43],[226.5,4.93],[234.5,4.8],[242.5,5.4],[250.5,5.5],[266.5,5.15],[298.5,5.6],[362.5,5.4],[414.5,5.7],[430.5,5.5],[494.5,6.2],[718.5,6.52],[830.5,6.3],[862.5,6.6],[878.5,6.4],[910.5,6.77],[958.5,6.67],[1062.5,7.07],[1318.5,7.35],[1590.5,8.12],[1718.5,8.25],[2486.5,8.59],[2614.5,8.47],[2742.5,8.7],[3382.5,8.6],[3766.5,8.97],[4022.5,8.79],[4150.5,9.22],[6710.5,10.29],[7414.5,11.03],[8438.5,10.96]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"A slow nova, and a southern one: more than two months within two magnitudes of its peak."},{id:"dq-her-1934",kind:"nova",designation:"DQ Her",name:"Nova Herculis 1934",raHours:18.12507,decDeg:45.85906,peakMagnitude:1.56,peakJd:24277935e-1,startJd:242778675e-2,lightCurve:[[0,3.4],[1.5,2.4],[3,2.67],[5.75,2.01],[6.75,1.56],[7.75,1.59],[11.75,2.97],[12.75,2.31],[14.75,3.07],[15.75,2.56],[16.75,2.51],[19.75,2.68],[23.75,2.53],[24.75,2.27],[26.75,2.58],[30.75,2.24],[31.75,2.63],[32.75,2.66],[34.75,2.11],[39.75,2.71],[41.75,2.31],[43.75,2.37],[46.75,3.64],[47.75,3.21],[50.75,3.23],[52.75,2.66],[55.75,2.56],[58.75,2.97],[60.75,2.77],[61.75,3.36],[63.75,3.43],[64.75,2.89],[65.75,3.22],[68.75,3.52],[69.75,2.95],[70.75,3.06],[71.75,2.7],[76.75,3.65],[79.75,3.74],[81.75,3.21],[83.75,3.75],[87.75,3.69],[92.75,4.04],[94.75,4.8],[97.75,4.24],[98.75,4.52],[100.75,4.08],[101.75,4.43],[105.75,4.58],[106.75,4.33],[107.75,4.73],[108.75,6.57],[109.75,8.08],[110.75,8.15],[111.75,8.56],[113.75,8.45],[114.75,9.15],[115.75,9.15],[116.75,9.59],[117.75,9.43],[118.75,9.8],[122.75,10.5],[123.75,10.28],[124.75,10.93],[127.75,10.83],[129.75,11.87],[131.75,12.42],[135.75,12.5],[137.75,12.9],[138.75,12.77],[139.75,13],[143.75,12],[144.75,12.33],[146.75,12.35],[147.75,11.64],[148.75,11.83],[150.75,10.9],[151.75,10.78],[152.75,11.17],[154.75,10.32],[155.75,10.4],[165.25,9.24],[185.25,7.74],[225.25,6.8],[273.25,6.72],[321.25,6.97],[333.25,6.79],[353.25,7],[357.25,6.82],[377.25,6.88],[401.25,7.29],[409.25,6.8],[413.25,6.8],[419.25,7.1],[435.25,7.09],[451.25,7.4],[475.25,7],[555.25,7.48],[823.25,7.83],[855.25,8.18],[1135.25,8.43],[1823.25,9.98],[1887.25,9.71],[2015.25,10.55],[2335.25,10.95]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"Lost about ten magnitudes in a few weeks from April 1935, when dust condensed around it, then came back to naked-eye brightness."},{id:"cp-lac-1936",kind:"nova",designation:"CP Lac",name:"Nova Lacertae 1936",raHours:22.26142,decDeg:55.61703,peakMagnitude:2.02,peakJd:242834025e-2,startJd:242833825e-2,lightCurve:[[0,4.03],[.5,2.9],[1,2.45],[2,2.02],[2.5,2.61],[4,3],[4.5,3.35],[5,3.3],[9.25,4.59],[14.25,5.45],[22.25,6.03],[23.25,6.3],[26.25,6.23],[38.25,6.74],[41.25,6.61],[50.25,7.35],[53.25,7.27],[57.25,7.7],[58.25,7.54],[60.25,7.55],[61.25,7.79],[71.25,7.6],[74.25,7.81],[76.25,8.3],[77.25,7.79],[86.25,8.21],[87.25,8],[88.25,8.25],[92.25,8.17],[94.25,8.47],[102.25,8.27],[103.25,8.7],[104.25,8.4],[110.25,8.66],[116.75,8.55],[122.75,8.83],[126.75,8.7],[140.75,9.06],[154.75,9.01],[164.75,9.36],[170.75,9.18],[174.75,9.48],[186.75,9.42],[188.75,9.73],[192.75,9.53],[200.75,9.74],[202.75,9.5],[204.75,9.77],[208.75,9.6],[214.75,9.75],[216.75,10.05],[222.75,9.7],[232.75,10.03],[236.75,9.82],[250.75,10.1],[254.75,9.9],[260.75,10.1],[264.75,9.8],[266.75,10.15],[268.75,10],[274.75,10.2],[276.75,9.9],[292.75,10.6],[294.75,10.6],[298.75,10.1],[318.75,10.35],[320.75,10.6],[322.75,10.3],[328.75,10.65],[332.75,10.3],[338.75,10.7],[348.75,10.53],[350.75,10.7],[354.75,10.37],[358.75,10.58],[365.75,10.43],[373.75,10.85],[421.75,10.94]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"cp-pup-1942",kind:"nova",designation:"CP Pup",name:"Nova Puppis 1942",raHours:8.19613,decDeg:-35.35139,peakMagnitude:.73,peakJd:243067675e-2,startJd:243067275e-2,lightCurve:[[0,.95],[4,.73],[4.5,1.3],[5.5,1.47],[6,2.01],[7.75,2.88],[8.75,2.97],[10.75,3.5],[11.75,4.02],[13.75,4.4],[14.75,3.8],[17.75,5],[18.75,4.93],[19.75,5.48],[23.75,5.5],[25.75,5.65],[26.75,5.99],[33.25,6.28],[45.25,6.6],[57.25,6.41],[81.25,6.85],[89.25,6.5],[97.25,6.67],[101.25,7],[113.25,6.66],[125.25,7.1],[135.25,6.96],[231.25,7.86],[279.25,7.8],[327.25,8.33],[407.25,8.18],[423.25,8.59],[471.25,8.53],[503.25,8.99],[551.25,8.97],[567.25,8.7],[583.25,9.47],[615.25,8.95],[655.25,9.5],[751.25,9.55],[815.25,10.09],[847.25,10.02],[879.25,10.48],[911.25,10.34],[1023.25,10.79],[1279.25,10.9]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"One of the fastest bright novae: two magnitudes gone in four days."},{id:"t-crb-1946",kind:"nova",designation:"T CrB",name:"Nova Coronae Borealis 1946",raHours:15.99171,decDeg:25.92017,peakMagnitude:2.5,peakJd:2431860,startJd:2431860,lightCurve:[[0,2.5],[1.5,3.5],[2.5,3.61],[6.5,5.68],[8.5,6.25],[10.5,7.35],[11.5,7.3],[12.5,8],[16,8.68],[32,9.77],[38,9.7],[40,9.45],[44,9.9],[48,9.57],[54,9.9],[58,9.71],[79,9.94],[107,9.76],[111,9.51],[115,8.71],[119,8.46],[159,8.01],[179,8.07],[183,8.47],[191,8.16],[199,8.7],[207,8.81],[211,9.33],[215,9.15],[223,9.47],[297,9.4],[345,9.75],[377,9.57],[425,9.8],[537,9.8]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"A recurrent nova. It erupted in 1866 and in 1946, and a third eruption was expected from 2024 on."},{id:"v446-her-1960",kind:"nova",designation:"V446 Her",name:"Nova Herculis 1960",raHours:18.956,decDeg:13.24147,peakMagnitude:4.83,peakJd:24370038e-1,startJd:24370033e-1,lightCurve:[[0,5.2],[.5,4.83],[2,4.9],[2.5,5.4],[3,5.05],[3.5,5.57],[4,5.25],[5,5.5],[6.5,5.4],[7.2,5.78],[8.2,5.6],[9.2,5.98],[10.2,5.92],[11.2,6.21],[16.2,6.1],[17.2,6.23],[18.2,7.2],[19.2,6.51],[20.2,6.78],[26.2,6.97],[27.2,7.24],[28.2,7.13],[29.2,7.45],[31.2,7.2],[40.7,7.57],[44.7,8.25],[46.7,7.84],[56.7,8.15],[60.7,8.9],[70.7,8.7],[72.7,8.14],[76.7,8.71],[80.7,8.47],[82.7,8.87],[86.7,8.57],[90.7,8.93],[107.7,9.11],[111.7,8.94],[115.7,9.27],[139.7,9.38],[151.7,9.91],[155.7,9.72],[173.7,10.51],[221.7,10.95]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"v533-her-1963",kind:"nova",designation:"V533 Her",name:"Nova Herculis 1963",raHours:18.23902,decDeg:41.85614,peakMagnitude:3,peakJd:24380605e-1,startJd:24380565e-1,lightCurve:[[0,8],[4,3],[4.5,3],[8,4],[13,3.95],[15,4.6],[21,4.53],[24,5.05],[27,5.15],[32,4.76],[34,4.98],[35,5.39],[37,5.43],[41,6.04],[49,6.02],[56.5,6.34],[60.5,6.11],[74.5,6.72],[102.5,6.99],[137.5,7.81],[197.5,8.31],[217.5,8.8],[225.5,8.57],[233.5,9.03],[237.5,8.78],[277.5,9.44],[301.5,9.46],[315.5,9.86],[323.5,9.73],[339.5,10.05],[355.5,10.74],[363.5,10.32],[371.5,10.6],[387.5,10.69],[427.5,10.38],[435.5,10.84],[443.5,10.74],[451.5,11.33],[459.5,10.98],[467.5,11.17],[507.5,11.16],[539.5,11.66],[603.5,11.7],[619.5,12.05],[651.5,12.03],[659.5,11.74],[667.5,10.9]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"hr-del-1967",kind:"nova",designation:"HR Del",name:"Nova Delphini 1967",raHours:20.70565,decDeg:19.16092,peakMagnitude:3.58,peakJd:2439838,startJd:2439646,lightCurve:[[0,11.9],[6,11.8],[12,8.8],[16,8.3],[20,6.7],[30,5.8],[36,5.51],[66,5.55],[78,5.35],[86,4.89],[96,5],[108,4.75],[136,5.13],[152,4.83],[182,4.93],[186,4.59],[192,3.58],[202,5],[220,5.46],[226,5.14],[230,5.45],[232,5.14],[236,5],[242,5.08],[244,4.59],[246,4.45],[254,5.3],[256,4.75],[260,5.69],[268,4.8],[274,4.94],[276,5.45],[280,5.2],[282,5.51],[286,5.58],[292,4.95],[294,5.16],[298,4.94],[311,5.09],[335,4.4],[367,5.76],[407,6.16],[423,6.55],[603,7.43],[907,8.32],[1451,9.41],[2347,10.75]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"An exceptionally slow nova: rose over months and stayed near magnitude 4 to 5 for most of 1967 and 1968."},{id:"lv-vul-1968",kind:"nova",designation:"LV Vul",name:"Nova Vulpeculae 1968",raHours:19.80012,decDeg:27.1715,peakMagnitude:4.5,peakJd:243996425e-2,startJd:243996325e-2,lightCurve:[[0,5],[1,4.5],[2,5],[2.5,4.86],[3,5.1],[3.5,4.88],[4,5.1],[5,4.9],[7,5.4],[8,5.23],[10.5,5.42],[12,5.82],[13,5.4],[13.5,5.74],[14,5.7],[14.5,6.08],[15,5.75],[15.5,5.86],[16,5.6],[17,5.8],[18,5.6],[20.5,6.34],[21,6.2],[22.5,6.84],[23,6.57],[24,6.98],[24.5,6.3],[25,7.1],[26,6.65],[34.25,7.48],[35.25,7.23],[39.25,7.32],[44.25,7.76],[45.25,7.49],[46.25,7.78],[50.25,7.84],[51.25,8.1],[53.25,7.9],[54.25,8.13],[56.25,8],[57.75,8.24],[67.75,8.52],[75.75,8.38],[83.75,8.69],[89.75,8.59],[125.75,9.32],[127.75,9.33],[129.75,8.98],[131.75,9.29],[135.75,9.43],[212.75,9.9],[220.75,10.16],[228.75,10.03],[236.75,10.3],[244.75,10.16],[264.75,10.54],[280.75,10.45],[296.75,10.79],[328.75,10.78]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"fh-ser-1970",kind:"nova",designation:"FH Ser",name:"Nova Serpentis 1970",raHours:18.51307,decDeg:2.61444,peakMagnitude:4.5,peakJd:244063425e-2,startJd:244063125e-2,lightCurve:[[0,7],[2,5],[3,4.5],[3.5,5],[4.5,4.6],[5.5,5],[6.5,4.68],[12.25,4.66],[16.25,5.3],[17.25,5.72],[18.25,5.3],[19.25,5.2],[23.25,5.84],[24.25,5.68],[27.25,5.9],[30.25,5.47],[32.25,5.9],[34.25,5.7],[43.25,6.28],[45.25,6.1],[50.25,6.62],[52.25,6.47],[57.25,6.63],[60.25,7.08],[61.25,6.87],[62.25,7.2],[63.25,6.85],[64.25,7.68],[65.25,7.3],[66.25,8.3],[67.25,7.93],[69.25,9.15],[71.25,9.2],[72.25,9.63],[74.25,9.9],[76.25,9.7],[77.25,10.25],[78.25,10.1],[79.25,10.4],[80.25,10.23],[81.25,10.57],[83.25,10.64],[85.25,10.35],[86.25,11.2],[87.25,10.1],[89.25,11.2],[96.25,11.35],[100.25,11.95],[102.25,11.1],[104.25,11.65],[106.25,11.5],[108.25,12.07],[114.75,11.32],[118.75,11.28],[122.75,10.93],[130.75,10.85],[134.75,10.52],[154.75,10.65],[162.75,10.12],[174.75,9.98],[178.75,10.34],[186.75,9.98],[214.75,10.25],[224.75,10.02],[240.75,10.2],[264.75,10],[272.75,10.2],[280.75,10.05],[288.75,10.4],[296.75,10],[348.75,10.7],[396.75,10.3],[444.75,10.73],[460.75,10.59],[540.75,10.94],[556.75,10.82]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"v1500-cyg-1975",kind:"nova",designation:"V1500 Cyg",name:"Nova Cygni 1975",raHours:21.19349,decDeg:48.15056,peakMagnitude:1.88,peakJd:244265525e-2,startJd:244265425e-2,lightCurve:[[0,2.44],[1,1.88],[1.5,1.88],[2.5,2.41],[3,3.38],[4,4.28],[8.25,5.81],[11.25,6.46],[22.25,7.35],[33.25,7.73],[34.25,7.97],[37.25,7.86],[40.25,8.3],[43.25,8.19],[48.25,8.6],[49.25,8.46],[66.25,9.04],[70.25,8.93],[75.25,9.23],[76.25,9.03],[80.25,9.39],[81.25,9.19],[83.25,9.35],[84.25,9.13],[86.25,9.39],[89.25,9.32],[90.25,9.54],[93.25,9.37],[105.75,9.86],[193.75,10.43],[201.75,10.7],[209.75,10.47],[257.75,10.94],[265.75,10.81]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"One of the fastest novae on record: discovered on 29 August 1975, at its peak of magnitude 1.9 within two days, and two magnitudes down again two days later."},{id:"v842-cen-1986",kind:"nova",designation:"V842 Cen",name:"Nova Centauri 1986",raHours:14.59794,decDeg:-57.6265,peakMagnitude:4.9,peakJd:244675975e-2,startJd:244675725e-2,lightCurve:[[0,5.6],[2.5,4.9],[3.5,5.1],[15.5,5.1],[17.5,5.75],[18.5,5.4],[20.5,5.5],[22.5,5.95],[30.5,6.15],[31.5,6.3],[32,7.5],[34.5,7.2],[38.5,7.5],[39,7],[41.5,7.15],[42.5,6.7],[44.5,7.23],[45.5,6.6],[53,9.3]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"sn-1987a",kind:"supernova",designation:"SN 1987A",name:"Supernova 1987A",raHours:5.59111,decDeg:-69.26975,peakMagnitude:2.98,peakJd:24469425e-1,startJd:24468495e-1,lightCurve:[[0,6.36],[1,6.11],[2,4.63],[4,4.45],[32,3.97],[56,3.15],[93,2.98],[105,3.35],[118,4.11],[134,4.43],[504,8.15],[617,10.27]],source:"V photometry compiled by the Open Supernova Catalog (Sternberg catalogue, IAU circulars, CTIO)",note:"In the Large Magellanic Cloud, 160 000 light years away: the nearest supernova since Kepler's, and invisible north of about 20° N."},{id:"v1974-cyg-1992",kind:"nova",designation:"V1974 Cyg",name:"Nova Cygni 1992",raHours:20.50879,decDeg:52.63078,peakMagnitude:4.27,peakJd:24486753e-1,startJd:24486718e-1,lightCurve:[[0,7.2],[1,5.23],[2,4.62],[3.5,4.27],[4.5,4.59],[6,4.5],[7,4.78],[7.5,4.52],[8,4.82],[10.7,5.25],[11.7,5.66],[16.7,5.85],[21.7,6.47],[22.7,6.3],[27.7,6.46],[29.7,6.83],[34.7,6.9],[35.7,7.25],[36.7,7],[37.7,7.16],[39.7,7.03],[43.7,7.41],[45.7,7.26],[50.7,7.45],[57.7,7.78],[58.7,8.13],[61.7,7.92],[64.7,8.19],[65.7,7.99],[71.7,8.22],[76.7,8.01],[128.2,8.72],[176.2,8.89],[192.2,9.15],[216.2,9.28],[232.2,9.07],[236.2,9.3],[390.2,10.99]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"v382-vel-1999",kind:"nova",designation:"V382 Vel",name:"Nova Velorum 1999",raHours:10.74678,decDeg:-52.42533,peakMagnitude:2.88,peakJd:245132225e-2,startJd:245132075e-2,lightCurve:[[0,2.99],[1.5,2.88],[2.5,3.46],[4.5,3.98],[5,4.32],[5.5,4.23],[7.5,4.85],[21.75,6.67],[30.25,7.2],[40.25,7.41],[93.25,7.95],[97.25,8.25],[101.25,8],[113.25,7.96],[129.25,8.5],[155.25,8.47],[163.25,9.1],[179.25,9],[187.25,8.7],[195.25,9.15],[211.25,9.23],[235.25,9.8],[243.25,9.71],[299.25,10.42],[383.25,10.52],[415.25,10.81]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"v1494-aql-1999",kind:"nova",designation:"V1494 Aql",name:"Nova Aquilae 1999",raHours:19.38482,decDeg:4.9555,peakMagnitude:4.11,peakJd:245151575e-2,startJd:245151425e-2,lightCurve:[[0,5.15],[.5,4.86],[1,4.27],[1.5,4.11],[2.5,4.35],[5,5.48],[10.5,6.26],[14.25,6.28],[20.25,7.43],[24.25,7.25],[25.25,7.63],[27.25,7.7],[29.25,7.42],[33.25,8.08],[35.25,8.03],[36.25,7.6],[37.25,7.6],[46.25,8.5],[54.25,8.28],[56.25,8.63],[58.25,8.4],[61.25,9.53],[62.25,9],[64.25,9.13],[69.25,8.58],[70.25,8.9],[72.25,8.88],[75.25,8.57],[77.25,9],[79.25,8.8],[81.25,9.7],[83.25,9.6],[85.25,9.8],[86.75,9.5],[88.75,9.54],[90.75,8.9],[92.75,8.85],[96.75,9.63],[102.75,9.7],[104.75,8.98],[106.75,8.73],[116.75,9.63],[118.75,9.6],[120.75,9.07],[122.75,9.26],[124.75,9.8],[128.75,9.36],[134.75,9.75],[147.75,9.92],[155.75,9.81],[259.75,10.96]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"v4743-sgr-2002",kind:"nova",designation:"V4743 Sgr",name:"Nova Sagittarii 2002",raHours:19.01926,decDeg:-22.00167,peakMagnitude:5,peakJd:245253775e-2,startJd:245253675e-2,lightCurve:[[0,5.2],[1,5],[2,5.89],[2.5,5.91],[3.5,6.43],[5,6.45],[5.5,6.86],[6,6.59],[7,6.77],[7.5,7.31],[8.5,6.99],[9,7.09],[10.5,7.86],[11,7.58],[11.5,7.89],[15.75,8.33],[17.75,8.18],[18.75,8.58],[19.75,8.44],[22.75,8.83],[23.75,8.6],[24.75,8.85],[27.75,8.83],[30.75,9.4],[31.75,9.09],[36.25,9.08],[38.25,9.34],[62.25,9.75],[66.25,10.1],[70.25,9.7],[74.25,10],[171.25,10.9]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"rs-oph-2006",kind:"nova",designation:"RS Oph",name:"Nova Ophiuchi 2006",raHours:17.83699,decDeg:-6.70792,peakMagnitude:4.8,peakJd:2453779,startJd:2453779,lightCurve:[[0,4.8],[1.25,4.97],[2.75,5.78],[3.25,5.7],[3.75,6.24],[4.25,6.05],[4.75,6.38],[5.25,6.3],[8.5,7.25],[14.5,7.95],[24.5,8.55],[29.5,9.08],[48,9.87],[80,10.28],[107,11.54],[119,11.54],[139,11.98],[147,11.83],[163,12.03],[171,11.97],[175,11.65],[183,11.84],[195,11.64],[203,11.8],[207,12.13],[219,11.45],[277,11.68],[325,11],[341,11.53],[357,11.62],[373,11.3],[405,11.5],[421,11.17],[469,10.96],[501,11.22],[549,10.75],[581,11.08],[597,10.98]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"A recurrent nova, erupting every twenty years or so (1898, 1907, 1933, 1945, 1958, 1967, 1985, 2006, 2021)."},{id:"v1280-sco-2007",kind:"nova",designation:"V1280 Sco",name:"Nova Scorpii 2007",raHours:16.96145,decDeg:-32.34325,peakMagnitude:3.8,peakJd:2454149,startJd:2454136,lightCurve:[[0,9.7],[13,3.8],[34,5.8],[103,15]],source:"AAVSO (discovery, peak, dust minimum); t2 from Das et al. 2008",note:"Faded from sight quickly when dust formed around it, three weeks after its peak."},{id:"v339-del-2013",kind:"nova",designation:"V339 Del",name:"Nova Delphini 2013",raHours:20.39186,decDeg:20.76772,peakMagnitude:4.4,peakJd:24565214e-1,startJd:24565214e-1,lightCurve:[[0,4.4],[11,6.4],[20,7.4]],source:"Gehrz et al. 2015 (peak, t2, t3)",note:"High in the summer evening sky of the northern hemisphere, and widely photographed."},{id:"v1369-cen-2013",kind:"nova",designation:"V1369 Cen",name:"Nova Centauri 2013",raHours:13.9126,decDeg:-59.15114,peakMagnitude:3.48,peakJd:245663965e-2,startJd:24566285e-1,lightCurve:[[0,5.33],[1.57,4.08],[2.75,3.73],[4.57,4.16],[5.96,4.15],[10.26,3.77],[11.15,3.48],[12.14,3.74],[14.17,4.78],[15.46,4.97],[23.16,4.22],[26.25,4.32],[27.31,4.82],[29.56,5.11],[32.66,4.71],[33.84,4.86],[36.05,4.46],[37.15,4.99],[41.42,4.59],[42.37,4.93],[43.37,4.82],[44.54,5.09],[49.95,5.38],[51.99,5.82],[54.21,5.77]],source:"AAVSO, binned by day, as plotted by Izzo 2017 (arXiv:1704.07214, figure 1)",note:"Discovered on 2 December 2013 by John Seach at magnitude 5.5, it flared several times, reaching about 3.3 around 14 December: the brightest nova of the century so far, and a southern one."},{id:"rs-oph-2021",kind:"nova",designation:"RS Oph",name:"Nova Ophiuchi 2021",raHours:17.83699,decDeg:-6.70792,peakMagnitude:4.6,peakJd:2459436,startJd:2459435,lightCurve:[[0,5],[1,4.6],[2.25,4.77],[3.75,5.58],[4.25,5.5],[4.75,6.04],[5.25,5.85],[5.75,6.18],[6.25,6.1],[9.5,7.05],[15.5,7.75],[25.5,8.35],[30.5,8.88],[49,9.67],[81,10.08],[108,11.34],[120,11.34],[140,11.78],[148,11.63],[164,11.83],[172,11.77],[176,11.45],[184,11.64],[196,11.44],[204,11.6],[208,11.93],[220,11.25],[278,11.48],[326,10.8],[342,11.33],[358,11.42],[374,11.1],[406,11.3],[422,10.97],[470,10.76],[502,11.02],[550,10.55],[582,10.88],[598,10.78]],source:"Recorded discovery and peak (8 and 9 August 2021); curve borrowed from its 2006 eruption",note:"RS Oph's latest eruption, discovered on 8 August 2021. The decline is its 2006 one."}];class qv{static UNIX_EPOCH_JD=24405875e-1;static aroundDate(t){const e=this.julianDayOf(t);return Uf.filter(i=>this.magnitudeAt(i,e)!==void 0)}static appearancesAt(t,e){const i=this.julianDayOf(t),n=[];for(const s of Uf){const r=this.magnitudeAt(s,i);r!==void 0&&n.push({outburst:s,position:os.ofJ2000(s.raHours,s.decDeg,t,e),magnitude:r})}return n.sort((s,r)=>s.magnitude-r.magnitude)}static brightestAt(t,e){return this.appearancesAt(t,e)[0]}static byId(t){return Uf.find(e=>e.id===t)}static magnitudeAt(t,e){const i=t.lightCurve,n=e-t.startJd;if(i.length===0||n<i[0][0]||n>i[i.length-1][0])return;let s=1;for(;s<i.length-1&&i[s][0]<n;)s++;const[r,o]=i[s-1]??i[0],[c,l]=i[s]??i[0];if(c===r)return o;const h=Math.min(1,Math.max(0,(n-r)/(c-r)));return o+h*(l-o)}static julianDayOf(t){return t.getTime()/864e5+this.UNIX_EPOCH_JD}}const ND=[{id:"quadrantids",code:"QUA",name:"Quadrantids",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:"April Lyrids",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:"eta Aquariids",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:"alpha Capricornids",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:"Southern delta Aquariids",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:"Perseids",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:"Southern Taurids",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:"October Draconids",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:"Orionids",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:"Northern Taurids",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:"Leonids",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:"Geminids",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:"Ursids",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}],Yu=6.5;class zf{static activeAt(t){return ND.flatMap(e=>{const i=this.nearness(e,t);return i<=0?[]:[{shower:e,zhr:e.peakZhr*i,nearness:i}]})}static nearness(t,e){const i=this.dayOfYear(e),n=this.dayOfYear(this.asDate(t.start)),s=this.dayOfYear(this.asDate(t.peak)),r=this.dayOfYear(this.asDate(t.end)),o=this.wrappedDelta(i,s),c=this.wrappedDelta(s,n),l=this.wrappedDelta(r,s);return o<0?o<-c?0:1+o/c:o>0?o>l?0:1-o/l:1}static observedRatePerHour(t,e,i,n=Yu){if(e<=0)return 0;const s=Yu-n;return t*Math.sin(e*Math.PI/180)/Math.pow(i,s)}static radiantPosition(t,e,i){return os.ofJ2000(t.radiantRaHours,t.radiantDecDeg,e,i)}static dayOfYear(t){const e=Date.UTC(t.getUTCFullYear(),0,1);return Math.floor((Date.UTC(t.getUTCFullYear(),t.getUTCMonth(),t.getUTCDate())-e)/864e5)+1}static asDate(t){return new Date(Date.UTC(2001,t.month-1,t.day))}static wrappedDelta(t,e){const i=t-e;return i>182?i-365:i<-182?i+365:i}}class fi{static QUIET_RATE_PER_HOUR=2;static APEX_RATE_PER_HOUR=8;static POPULATION_INDEX=3;static apexPosition(t,e){const i=Ne(t),n=new ld(0,FT(t).elon-90,1),s=cr(u4(i),hm(n,i)),r=fd(s);return um(r.ra,r.dec,t,e)}static observedRatePerHour(t,e=Yu){const i=fi.APEX_RATE_PER_HOUR*Math.max(0,Math.sin(t*Math.PI/180)),n=Yu-e;return(fi.QUIET_RATE_PER_HOUR+i)/Math.pow(fi.POPULATION_INDEX,n)}static schedule(t){const e=new pd(t.seed^1542469173);return ka.schedule(t).map(i=>{const n=fi.toCartesian({altitudeDeg:Math.asin(e.next())*180/Math.PI,azimuthDeg:e.between(0,360)}),s=i.fromRadiantDeg*Math.PI/180,r=fi.turnAround(n,e.between(0,360)),o={x:n.x*Math.cos(s)+r.x*Math.sin(s),y:n.y*Math.cos(s)+r.y*Math.sin(s),z:n.z*Math.cos(s)+r.z*Math.sin(s)};return{...i,radiant:fi.toHorizontal(o),bearingDeg:fi.bearingFrom(o,n)}})}static turnAround(t,e){const[i,n]=fi.basisAround(t),s=e*Math.PI/180;return{x:i.x*Math.cos(s)+n.x*Math.sin(s),y:i.y*Math.cos(s)+n.y*Math.sin(s),z:i.z*Math.cos(s)+n.z*Math.sin(s)}}static bearingFrom(t,e){const[i,n]=fi.basisAround(t),s=t.x*e.x+t.y*e.y+t.z*e.z,r=fi.normalise({x:e.x-t.x*s,y:e.y-t.y*s,z:e.z-t.z*s});return(Math.atan2(r.x*n.x+r.y*n.y+r.z*n.z,r.x*i.x+r.y*i.y+r.z*i.z)*180/Math.PI%360+360)%360}static basisAround(t){const e=Math.abs(t.y)<.9?{x:0,y:1,z:0}:{x:1,y:0,z:0},i=fi.normalise(fi.cross(t,e));return[i,fi.normalise(fi.cross(t,i))]}static toHorizontal(t){const e=Math.hypot(t.x,t.y,t.z)||1;return{altitudeDeg:Math.asin(Math.min(1,Math.max(-1,t.y/e)))*180/Math.PI,azimuthDeg:(Math.atan2(t.x,-t.z)*180/Math.PI%360+360)%360}}static appearanceOf(t){const e=fi.toCartesian(t.radiant??{altitudeDeg:90,azimuthDeg:0}),i=fi.turnAround(e,t.bearingDeg),n=t.fromRadiantDeg*Math.PI/180;return fi.toHorizontal({x:e.x*Math.cos(n)+i.x*Math.sin(n),y:e.y*Math.cos(n)+i.y*Math.sin(n),z:e.z*Math.cos(n)+i.z*Math.sin(n)})}static toCartesian(t){const e=t.altitudeDeg*Math.PI/180,i=t.azimuthDeg*Math.PI/180,n=Math.cos(e);return{x:n*Math.sin(i),y:Math.sin(e),z:-n*Math.cos(i)}}static cross(t,e){return{x:t.y*e.z-t.z*e.y,y:t.z*e.x-t.x*e.z,z:t.x*e.y-t.y*e.x}}static normalise(t){const e=Math.hypot(t.x,t.y,t.z)||1;return{x:t.x/e,y:t.y/e,z:t.z/e}}static TYPICAL_VELOCITY_KM_S=40}const $v="https://ufoathome.org/tle/index.json";class qi{static MAX_ELEMENT_AGE_DAYS=7;static DAY_MS=864e5;fetchImpl;indexUrls;index;files=new Map;constructor(t={}){this.fetchImpl=t.fetchImpl??fetch.bind(globalThis),this.indexUrls=t.indexUrls??qi.defaultIndexUrls()}static defaultIndexUrls(){const t=[];return typeof location<"u"&&/^https?:$/.test(location.protocol)&&t.push(new URL("/tle/index.json",location.href).href),t.includes($v)||t.push($v),t}static FIRST_SNAPSHOT="2021-02-22";async covers(t){const e=Date.parse(`${qi.FIRST_SNAPSHOT}T00:00:00Z`)-qi.MAX_ELEMENT_AGE_DAYS*qi.DAY_MS;if(t.getTime()<e)return!1;const i=await this.loadIndex();return i?Object.values(i.index.kinds).some(n=>t.getTime()>=Date.parse(n.from)-qi.MAX_ELEMENT_AGE_DAYS*qi.DAY_MS&&t.getTime()<=Date.parse(n.to)+qi.MAX_ELEMENT_AGE_DAYS*qi.DAY_MS):!1}async at(t){const e=await this.loadIndex();if(!e)return;const{index:i,base:n}=e,s=[],r=[];for(const o of Object.keys(i.kinds)){const c=await this.kindAt(o,t,i,n);s.push(...c),r.push(this.coverageOf(o,t,i,c.length>0))}return{objects:s,coverage:r,credit:i.credit,creditUrl:i.source}}async kindAt(t,e,i,n){const s=e.getTime(),r=i.binDays*qi.DAY_MS,o=Math.floor(s/r),c=s-o*r<r/2?o-1:o+1,l=new Set(i.kinds[t].bins),h=[o,c].map(v=>new Date(v*r).toISOString().slice(0,10)).filter(v=>l.has(v));if(h.length===0)return[];const[u,...d]=await Promise.all([this.json(new URL(`objects-${t}.json`,n).href),...h.map(v=>this.binary(new URL(`${t}/${v}.bin`,n).href))]),f=new Map;for(const v of d)for(const m of qi.decode(v,i.recordBytes)){const g=f.get(m.norad);(!g||Math.abs(m.epochMs-s)<Math.abs(g.epochMs-s))&&f.set(m.norad,m)}const p=[];for(const v of f.values()){const m=Math.abs(v.epochMs-s)/qi.DAY_MS;if(m>qi.MAX_ELEMENT_AGE_DAYS)continue;const g=u[v.norad]??{name:String(v.norad)};g.launch&&Date.parse(`${g.launch}T00:00:00Z`)>s||p.push({norad:v.norad,name:g.name,kind:t,launch:g.launch,stdMag:g.stdMag,elements:v,ageDays:m})}return p}coverageOf(t,e,i,n){const{from:s,to:r}=i.kinds[t],o=e.getTime(),c=qi.MAX_ELEMENT_AGE_DAYS*qi.DAY_MS,l=n?"covered":o<Date.parse(s)-c?"before":o>Date.parse(r)+c?"after":"gap";return{kind:t,status:l,from:s,to:r}}static decode(t,e){const i=new DataView(t),n=[];for(let s=0;s+e<=t.byteLength;s+=e)n.push({norad:i.getUint32(s,!0),epochMs:i.getFloat64(s+4,!0),bstar:i.getFloat32(s+12,!0),inclinationDeg:i.getFloat32(s+16,!0),raanDeg:i.getFloat32(s+20,!0),eccentricity:i.getFloat32(s+24,!0),argOfPerigeeDeg:i.getFloat32(s+28,!0),meanAnomalyDeg:i.getFloat32(s+32,!0),meanMotion:i.getFloat64(s+36,!0)});return n}loadIndex(){return this.index??=(async()=>{for(const t of this.indexUrls)try{const e=await this.fetchImpl(t);if(!e.ok)continue;return{index:await e.json(),base:t}}catch{}})(),this.index}json(t){return this.cached(t,async e=>e.json())}binary(t){return this.cached(t,async e=>e.arrayBuffer())}cached(t,e){let i=this.files.get(t);return i||(i=this.fetchImpl(t).then(n=>{if(!n.ok)throw new Error(`${t}: ${n.status}`);return e(n)}),i.catch(()=>this.files.delete(t)),this.files.set(t,i)),i}}class kD{lowerM;upperM;add(t,e){if(!(t<=0)){if(e.behindM!==void 0){const i=Fe.sizeMAt(e.behindM,t);this.lowerM=this.lowerM===void 0?i:Math.max(this.lowerM,i)}if(e.inFrontM!==void 0){const i=Fe.sizeMAt(e.inFrontM,t);this.upperM=this.upperM===void 0?i:Math.min(this.upperM,i)}}}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(t){return t<=0?{}:{minM:this.lowerM===void 0?void 0:Fe.distanceMAt(this.lowerM,t),maxM:this.upperM===void 0?void 0:Fe.distanceMAt(this.upperM,t)}}clear(){this.lowerM=void 0,this.upperM=void 0}}class Ua{static DEG_PER_SECOND=360/86164.0905;static degOver(t){return Math.max(0,t)*Ua.DEG_PER_SECOND}static instants(t,e){if(!(e>0))return 1;const i=Ua.degOver(t)/e;return i<1?1:Math.min(Ua.MAX_INSTANTS,Math.max(2,Math.ceil(i)))}static MAX_INSTANTS=64}class an{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 Ua.DEG_PER_SECOND*3600}static graspOf(t,e={}){const i=e.exposureSeconds??t.exposureSeconds,n=e.fNumber??t.fNumber;if(i===void 0||n===void 0||!(i>0)||!(n>0))return an.EYE;const s=e.focalLengthMm??t.frame?.focalLengthMm??an.UNKNOWN_CAMERA_FOCAL_MM,r=s/n,o=an.resolutionArcsec(t,s,r);return{apertureMm:r,exposureSeconds:Math.min(i,an.trailLimitedSeconds(o)),resolutionArcsec:o}}static resolutionArcsec(t,e,i){const s=(t.detailUm??an.UNKNOWN_CAMERA_DETAIL_UM)/1e3/e*an.ARCSEC_PER_RADIAN,r=1.22*an.WAVELENGTH_M/(i/1e3)*an.ARCSEC_PER_RADIAN;return Math.max(s,r)}static trailLimitedSeconds(t){return t/an.skyDriftArcsecPerSecond}static gainOverEye(t,e={}){const i=an.graspOf(t,e),n=an.EYE,s=(i.apertureMm/n.apertureMm)**2,r=i.exposureSeconds/n.exposureSeconds,o=(n.resolutionArcsec/i.resolutionArcsec)**2;return 1.25*Math.log10(s*r*o)}static gainFor(t,e){const i=e.fieldOfViewDeg===void 0?void 0:bi.focalLengthMmFor(t,e.fieldOfViewDeg);return an.gainOverEye(t,{fNumber:e.fNumber,focalLengthMm:i,exposureSeconds:e.exposureSeconds})}}const Kv=111320,Pc=Math.PI/180,FD=1.02,UD=1;class tl{static of(t,e){const i=tl.sightings(t,e);if(i.length<2)return;const n=tl.baseline(i);if(!n)return;const{near:s,far:r,closedM:o}=n,c=Math.tan(r.widthDeg/2*Pc)===0?0:Math.tan(s.widthDeg/2*Pc)/Math.tan(r.widthDeg/2*Pc);if(c<FD)return;const l=o/(c-1),h=Fe.sizeMAt(l,s.widthDeg),u=i.map(d=>({t:d.t,m:Fe.distanceMAt(h,d.widthDeg)}));return{widthM:h,distanceM:u,nearestM:Math.min(...u.map(d=>d.m)),fromT:r.t,toT:s.t,closedM:o}}static sightings(t,e){return t.timeline.allKeyframes.flatMap(i=>{const n=i.shapes.find(o=>o.sourceId===e)?.shape,s=n?.angular?.widthDeg,r=Ze(t,i.t);return s===void 0||s<=0||r?.lat===void 0||r.lng===void 0?[]:[{t:i.t,widthDeg:s,lat:r.lat,lng:r.lng,sightAzimuthDeg:n?.aim?.azimuthDeg??r.headingDeg}]}).sort((i,n)=>i.t-n.t)}static baseline(t){let e;for(const i of t)for(const n of t){if(i.t>=n.t)continue;const s=tl.closedAlongSight(i,n),[r,o,c]=s>=0?[n,i,s]:[i,n,-s];c<UD||r.widthDeg<=o.widthDeg||(!e||c>e.closedM)&&(e={near:r,far:o,closedM:c})}return e}static closedAlongSight(t,e){const i=(e.lat-t.lat)*Kv,n=(e.lng-t.lng)*Kv*Math.cos(t.lat*Pc),s=(t.sightAzimuthDeg??0)*Pc;return i*Math.cos(s)+n*Math.sin(s)}}class sn{static CONVENTIONAL_M=5;static NEAREST_M=.2;static MARGIN=1.1;static resolve(t){if(t.statedM!==void 0&&t.statedM>0)return{distanceM:sn.atLeastNearest(t.statedM),basis:"stated"};if(t.hypothesisM!==void 0&&t.hypothesisM>0)return{distanceM:sn.atLeastNearest(t.hypothesisM),basis:"hypothesis"};if(t.derivedM!==void 0&&t.derivedM>0)return{distanceM:sn.atLeastNearest(t.derivedM),basis:"derived"};const e=sn.largest(t.range?.minM,t.crossing?.behindM),i=sn.smallest(t.range?.maxM,t.crossing?.inFrontM),n=e===void 0?void 0:e*sn.MARGIN,s=i===void 0?void 0:i/sn.MARGIN;return n!==void 0&&s!==void 0?{distanceM:sn.atLeastNearest(n<=s?Math.sqrt(n*s):n),basis:"bounded"}:n!==void 0?{distanceM:sn.atLeastNearest(n),basis:"bounded"}:s!==void 0&&s<sn.CONVENTIONAL_M?{distanceM:sn.atLeastNearest(s),basis:"bounded"}:{distanceM:sn.CONVENTIONAL_M,basis:"conventional"}}static atLeastNearest(t){return Math.max(sn.NEAREST_M,t)}static largest(...t){const e=t.filter(i=>i!==void 0&&i>0);return e.length===0?void 0:Math.max(...e)}static smallest(...t){const e=t.filter(i=>i!==void 0&&i>0);return e.length===0?void 0:Math.min(...e)}}const Bf=Math.PI/180;class ce{constructor(t,e,i){this.body=t,this.ground=e;const n=[...t.track].sort((s,r)=>s.t-r.t);this.keys=this.place(n,i);for(const s of n)ce.collect(this.motionKeys,s.t,s.motions),ce.collect(this.lightKeys,s.t,s.lights)}static EYE_HEIGHT_M=1.6;static MAX_RANGE_M=3e4;static DEFAULT_SIZE={widthM:1,lengthM:1,heightM:1};static DEFAULT_APPEARANCE={color:"#c8c8c8",albedo:.5,luminanceCdM2:0};keys;motionKeys=new Map;lightKeys=new Map;static collect(t,e,i){for(const[n,s]of Object.entries(i??{})){const r=t.get(n)??[];r.push({t:e,value:s}),t.set(n,r)}}motionsAt(t){return ce.channelsAt(this.motionKeys,t,0)}lightsAt(t){return this.lightKeys.size>0?ce.channelsAt(this.lightKeys,t,void 0):void 0}static channelsAt(t,e,i){const n={};for(const[s,r]of t){let o=r.length-1;for(;o>=0&&r[o].t>e;)o--;if(o<0){i!==void 0&&(n[s]=i);continue}const c=r[o],l=r[Math.min(o+1,r.length-1)],h=l===c||l.t===c.t?0:Math.min(1,(e-c.t)/(l.t-c.t));n[s]=ce.lerp(c.value,l.value,h)}return n}static eyeOf(t,e,i){const n=Ze(t,0),s=Ze(t,e),o=n?.lat!==void 0&&n.lng!==void 0&&s?.lat!==void 0&&s.lng!==void 0?si(s.lat,s.lng,n.lat,n.lng):void 0,c=o?o.x:0,l=o?-o.z:0;return{eastM:c,northM:l,upM:i.heightAt(c,l)+ce.EYE_HEIGHT_M+(s?.elevationM??0),headingDeg:s?.headingDeg}}static lineOfSightMeetsGround(t,e,i,n){const s=ce.directionOf(e,i),r=l=>t.upM+s.upM*l-n.heightAt(t.eastM+s.eastM*l,t.northM+s.northM*l);let o=0,c=0;for(;c<ce.MAX_RANGE_M;){if(c=o+Math.max(.5,o*.01),r(c)<=0){for(let l=0;l<30;l++){const h=(o+c)/2;r(h)<=0?c=h:o=h}return c}o=c}}static directionOf(t,e){const i=t*Bf,n=e*Bf;return{eastM:Math.sin(i)*Math.cos(n),northM:Math.cos(i)*Math.cos(n),upM:Math.sin(n)}}at(t){const e=this.keys;if(e.length===0||t<e[0].t)return;let i=e.length-1;for(;i>0&&e[i].t>t;)i--;const n=e[i];if(!n.present)return;const s=e[Math.min(i+1,e.length-1)],r=s===n||s.t===n.t?0:Math.min(1,(t-n.t)/(s.t-n.t)),o=ce.lerp(n.eastM,s.eastM,r),c=ce.lerp(n.northM,s.northM,r),l={widthM:ce.lerp(n.sizeM.widthM,s.sizeM.widthM,r),lengthM:ce.lerp(n.sizeM.lengthM,s.sizeM.lengthM,r),heightM:ce.lerp(n.sizeM.heightM,s.sizeM.heightM,r)},h={headingDeg:ce.lerpAngle(n.attitude.headingDeg,s.attitude.headingDeg,r),pitchDeg:ce.lerp(n.attitude.pitchDeg,s.attitude.pitchDeg,r),rollDeg:ce.lerp(n.attitude.rollDeg,s.attitude.rollDeg,r)};let u;if("aboveGroundM"in n.vertical&&"aboveGroundM"in s.vertical){const d=ce.lerp(n.vertical.aboveGroundM,s.vertical.aboveGroundM,r);u=this.groundUnderFootprint(o,c,l,h.headingDeg)+d+l.heightM/2}else u=ce.lerp(this.centreUpOf(n),this.centreUpOf(s),r);return{id:this.body.id,model:this.body.model,explains:this.body.explains??[],outlineNode:this.body.outlineNode,eastM:o,northM:c,upM:u,sizeM:l,attitude:h,appearance:{color:(r<1?n:s).appearance.color,albedo:ce.lerp(n.appearance.albedo,s.appearance.albedo,r),luminanceCdM2:ce.lerp(n.appearance.luminanceCdM2,s.appearance.luminanceCdM2,r)},flame:ce.flameBetween(n.flame,s.flame,r),motions:this.motionsAt(t),lights:this.lightsAt(t),throwsFlame:this.body.track.some(d=>d.flame!==void 0&&d.flame.luminanceCdM2>0)}}static flameBetween(t,e,i){if(!t||t.luminanceCdM2<=0)return i>=1&&e&&e.luminanceCdM2>0?e:void 0;const n=t,s=e??t,r={...i<1?n:s,lengthM:ce.lerp(n.lengthM,s.lengthM,i),widthM:ce.lerp(n.widthM,s.widthM,i),luminanceCdM2:ce.lerp(n.luminanceCdM2,s.luminanceCdM2,i)};return r.luminanceCdM2>0?r:void 0}centreUpOf(t){return"upM"in t.vertical?t.vertical.upM:this.groundUnderFootprint(t.eastM,t.northM,t.sizeM,t.attitude.headingDeg)+t.vertical.aboveGroundM+t.sizeM.heightM/2}groundUnderFootprint(t,e,i,n){const s=n*Bf,r={eastM:Math.cos(s),northM:-Math.sin(s)},o={eastM:Math.sin(s),northM:Math.cos(s)};let c=this.ground.heightAt(t,e);for(const[l,h]of[[-1,-1],[1,-1],[-1,1],[1,1]]){const u=l*i.widthM/2,d=h*i.lengthM/2;c=Math.max(c,this.ground.heightAt(t+r.eastM*u+o.eastM*d,e+r.northM*u+o.northM*d))}return c}place(t,e){const i=[];let n;for(const s of t){const r=s.sizeM??n?.sizeM??ce.DEFAULT_SIZE,o={headingDeg:s.attitude?.headingDeg??n?.attitude.headingDeg??0,pitchDeg:s.attitude?.pitchDeg??n?.attitude.pitchDeg??0,rollDeg:s.attitude?.rollDeg??n?.attitude.rollDeg??0},c={color:s.appearance?.color??n?.appearance.color??ce.DEFAULT_APPEARANCE.color,albedo:s.appearance?.albedo??n?.appearance.albedo??ce.DEFAULT_APPEARANCE.albedo,luminanceCdM2:s.appearance?.luminanceCdM2??n?.appearance.luminanceCdM2??ce.DEFAULT_APPEARANCE.luminanceCdM2},l=this.positionOf(s,r,e)??(n&&{eastM:n.eastM,northM:n.northM,vertical:this.verticalOf(s,r)??n.vertical});if(!l)continue;const h=s.flame??n?.flame,u=s.present??n?.present??!0;n={t:s.t,...l,sizeM:r,attitude:o,appearance:c,flame:h,present:u},i.push(n)}return i}verticalOf(t,e){if(t.onGround)return{aboveGroundM:0};if(t.altitudeAboveGroundM!==void 0)return{aboveGroundM:t.altitudeAboveGroundM};if(t.altitudeM!==void 0)return{upM:t.altitudeM+e.heightM/2}}positionOf(t,e,i){if(t.eastM!==void 0&&t.northM!==void 0)return{eastM:t.eastM,northM:t.northM,vertical:this.verticalOf(t,e)??{aboveGroundM:0}};if(t.azimuthDeg===void 0||t.altitudeDeg===void 0)return;const n=i(t.t);if(!n)return;const s=t.distanceM??(t.onGround?ce.lineOfSightMeetsGround(n,t.azimuthDeg,t.altitudeDeg,this.ground):void 0);if(s===void 0)return;const r=ce.directionOf(t.azimuthDeg,t.altitudeDeg),o=n.eastM+r.eastM*s,c=n.northM+r.northM*s;return{eastM:o,northM:c,vertical:this.verticalOf(t,e)??{upM:n.upM+r.upM*s}}}static lerp(t,e,i){return t+(e-t)*i}static lerpAngle(t,e,i){const n=((e-t)%360+540)%360-180;return((t+n*i)%360+360)%360}}class be{static A=6378137;static E2=.00669437999014;static DEG=Math.PI/180;static STANDARD_DISTANCE_KM=100;static DEFAULT_COLOR="#ffb347";static DEFAULT_TRAIN_S=1.5;static FADE_MS=600;static TRAIN_POINTS=8;static leadAt(t,e){const i=t.track;if(i.length<2||e<i[0].t||e>i[i.length-1].t)return;let n=0;for(;n<i.length-2&&i[n+1].t<e;)n++;const s=i[n],r=i[n+1],o=r.t-s.t,c=o>0?(e-s.t)/o:0,[l,h]=be.alongGreatCircle(s,r,c);return{lat:l,lng:h,heightM:(s.altitudeKm+(r.altitudeKm-s.altitudeKm)*c)*1e3}}static viewsAt(t,e,i){const n=[];for(const s of t){const r=s.track[0]?.t??0,o=s.track[s.track.length-1]?.t??0;s.fragments.forEach((c,l)=>{const h=c.fromT??r,u=c.untilT??o;if(e<h||e>u)return;const d=(c.lagS??0)*1e3,f=be.leadAt(s,e-d);if(!f)return;const p=be.seenFrom(i,f);if(p.altitudeDeg<0)return;const v=Math.min(be.FADE_MS,(u-h)/4),m=v>0?Math.min(1,(e-h)/v,(u-e)/v):1,g=-2.5*Math.log10(Math.max(m,.001)),b=c.absoluteMagnitude+5*Math.log10(p.distanceKm/be.STANDARD_DISTANCE_KM)+g,S=[p],M=(c.trainS??be.DEFAULT_TRAIN_S)*1e3;for(let x=1;x<=be.TRAIN_POINTS;x++){const _=Math.min(M*x/be.TRAIN_POINTS,e-h),A=be.leadAt(s,e-d-_);if(!A||(S.push(be.seenFrom(i,A)),_>=e-h))break}n.push({reentryId:s.id,fragmentId:c.id??String(l),head:p,magnitude:b,color:c.color??be.DEFAULT_COLOR,train:S})})}return n}static seenFrom(t,e){const i=be.ecef(t),n=be.ecef(e),s=n[0]-i[0],r=n[1]-i[1],o=n[2]-i[2],c=t.lat*be.DEG,l=t.lng*be.DEG,h=-Math.sin(l)*s+Math.cos(l)*r,u=-Math.sin(c)*Math.cos(l)*s-Math.sin(c)*Math.sin(l)*r+Math.cos(c)*o,d=Math.cos(c)*Math.cos(l)*s+Math.cos(c)*Math.sin(l)*r+Math.sin(c)*o,f=Math.hypot(h,u,d);return{altitudeDeg:Math.asin(d/f)/be.DEG,azimuthDeg:(Math.atan2(h,u)/be.DEG+360)%360,distanceKm:f/1e3}}static ecef(t){const e=t.lat*be.DEG,i=t.lng*be.DEG,n=Math.sin(e),s=be.A/Math.sqrt(1-be.E2*n*n);return[(s+t.heightM)*Math.cos(e)*Math.cos(i),(s+t.heightM)*Math.cos(e)*Math.sin(i),(s*(1-be.E2)+t.heightM)*n]}static alongGreatCircle(t,e,i){const n=h=>{const u=h.lat*be.DEG,d=h.lng*be.DEG;return[Math.cos(u)*Math.cos(d),Math.cos(u)*Math.sin(d),Math.sin(u)]},s=n(t),r=n(e),o=Math.max(-1,Math.min(1,s[0]*r[0]+s[1]*r[1]+s[2]*r[2])),c=Math.acos(o);let l;if(c<1e-12)l=s;else{const h=Math.sin((1-i)*c)/Math.sin(c),u=Math.sin(i*c)/Math.sin(c);l=[s[0]*h+r[0]*u,s[1]*h+r[1]*u,s[2]*h+r[2]*u]}return[Math.atan2(l[2],Math.hypot(l[0],l[1]))/be.DEG,Math.atan2(l[1],l[0])/be.DEG]}}class pm{static FIRST_DAY="2022-01-01";static mayCover(t){return new Date(t).toISOString().slice(0,10)>=pm.FIRST_DAY}}class zD{constructor(t,e,i){this.citation=t,this.covers=e,this.load=i}loading;mayCover(t){return this.covers(t)}async between(t,e,i,n){try{return await(await this.provider()).between(t,e,i,n)}catch{return{status:"failed"}}}async describe(t,e){try{return await(await this.provider()).describe?.(t,e)}catch{return}}provider(){if(!this.loading){const t=this.load();this.loading=t,t.catch(()=>{this.loading===t&&(this.loading=void 0)})}return this.loading}}const BD="Aircraft positions: adsb.lol feeders and contributors, Open Database License 1.0 (https://www.adsb.lol/docs/open-data/historical/)",HD=[{id:"adsb-lol",name:"adsb.lol",credit:"adsb.lol feeders and contributors, ODbL 1.0",creditUrl:"https://www.adsb.lol/docs/open-data/historical/",create:()=>new zD(BD,a=>pm.mayCover(a),async()=>new(await je(async()=>{const{AdsbLolArchiveProvider:a}=await import("./AdsbLolArchiveProvider-BXH71WVn.js");return{AdsbLolArchiveProvider:a}},[],import.meta.url)).AdsbLolArchiveProvider)}];class on{static MAX_GAP_S=60;static FT_TO_M=.3048;static EARTH_RADIUS_KM=6371;static seenFrom(t,e,i){const n=on.positionAt(t,i);if(!n)return;const s=be.seenFrom(e,n.geo);if(!(s.altitudeDeg<0))return{track:t,sky:s,altitudeFt:n.altitudeFt,groundSpeedKt:n.groundSpeedKt,trackDeg:n.trackDeg,angularRateDegPerS:on.angularRate(t,e,i)}}static viewsAt(t,e,i){return t.flatMap(n=>on.seenFrom(n,e,i)??[])}static groundDistanceKm(t,e){const i=Math.PI/180,n=Math.sin((e.lat-t.lat)*i/2)**2+Math.cos(t.lat*i)*Math.cos(e.lat*i)*Math.sin((e.lng-t.lng)*i/2)**2;return 2*on.EARTH_RADIUS_KM*Math.asin(Math.min(1,Math.sqrt(n)))}static wrapLongitude(t){return((t+180)%360+360)%360-180}static positionAt(t,e){const i=t.points;if(i.length===0||e<i[0].t||e>i[i.length-1].t)return;let n=0;for(;n<i.length-1&&i[n+1].t<=e;)n++;const s=i[n],r=i[n+1]??s,o=r.t-s.t;if(o>on.MAX_GAP_S*1e3)return;const c=o>0?(e-s.t)/o:0,l=s.altitudeFt+(r.altitudeFt-s.altitudeFt)*c,h=(r.lng-s.lng+540)%360-180;return{geo:{lat:s.lat+(r.lat-s.lat)*c,lng:on.wrapLongitude(s.lng+h*c),heightM:l*on.FT_TO_M},altitudeFt:l,groundSpeedKt:s.groundSpeedKt,trackDeg:s.trackDeg}}static angularRate(t,e,i){const n=on.positionAt(t,i-500),s=on.positionAt(t,i+500);if(!n||!s)return;const r=on.unit(be.seenFrom(e,n.geo)),o=on.unit(be.seenFrom(e,s.geo)),c=Math.min(1,Math.max(-1,r[0]*o[0]+r[1]*o[1]+r[2]*o[2]));return Math.acos(c)*180/Math.PI}static unit(t){const e=t.altitudeDeg*Math.PI/180,i=t.azimuthDeg*Math.PI/180;return[Math.cos(e)*Math.sin(i),Math.cos(e)*Math.cos(i),Math.sin(e)]}}const Zv="https://ufoathome.org/fireballs/index.json";class Ps{static FIRST_MONTH="2018-12";static STRIKING_MAGNITUDE=-1;static COLOR="#eef2ff";static TRAIN_S=.3;fetchImpl;indexUrls;index;months=new Map;constructor(t={}){this.fetchImpl=t.fetchImpl??fetch.bind(globalThis),this.indexUrls=t.indexUrls??Ps.defaultIndexUrls()}static defaultIndexUrls(){const t=[];return typeof location<"u"&&/^https?:$/.test(location.protocol)&&t.push(new URL("/fireballs/index.json",location.href).href),t.includes(Zv)||t.push(Zv),t}static mayCover(t){return new Date(t).toISOString().slice(0,7)>=Ps.FIRST_MONTH}async credit(){return(await this.loadIndex())?.index.credit}async between(t,e){if(!Ps.mayCover(e))return;const i=await this.loadIndex();if(!i)return;const n=new Set([new Date(t).toISOString().slice(0,7),new Date(e).toISOString().slice(0,7)]);return[...n].some(r=>r>=i.index.from&&r<=i.index.to)?(await Promise.all([...n].filter(r=>i.index.months.includes(r)).map(r=>this.monthOf(r,i.base)))).flat().filter(r=>r.t>=t&&r.t<=e):void 0}static seenFrom(t,e){const i=Ps.peakFraction(t),n={lat:t.from[0]+(t.to[0]-t.from[0])*i,lng:t.from[1]+(t.to[1]-t.from[1])*i,heightM:t.peakHeightKm*1e3},s=be.seenFrom(e,n);if(!(s.altitudeDeg<0))return{record:t,peak:s,magnitude:t.peakMagnitude+5*Math.log10(s.distanceKm/be.STANDARD_DISTANCE_KM)}}static asReentry(t,e){const i=t.t-e,n=i+Math.max(t.durationS,.1)*1e3;return{id:`gmn-${t.id}`,track:[{t:i,lat:t.from[0],lng:t.from[1],altitudeKm:t.from[2]},{t:n,lat:t.to[0],lng:t.to[1],altitudeKm:t.to[2]}],fragments:[{absoluteMagnitude:t.peakMagnitude,color:Ps.COLOR,trainS:Ps.TRAIN_S}]}}static peakFraction(t){const e=t.from[2]-t.to[2];return Math.abs(e)<1e-6?.5:Math.min(1,Math.max(0,(t.from[2]-t.peakHeightKm)/e))}loadIndex(){return this.index??=(async()=>{for(const t of this.indexUrls)try{const e=await this.fetchImpl(t);if(e.ok)return{index:await e.json(),base:t}}catch{}})(),this.index}monthOf(t,e){let i=this.months.get(t);return i||(i=this.fetchImpl(new URL(`${t}.json`,e).href).then(n=>n.ok?n.json():[]).catch(()=>[]),this.months.set(t,i)),i}}const _o=Math.PI/180,Oc=180/Math.PI;class di{constructor(t){this.timeline=t}static DIRECTION_TOLERANCE_DEG=1;static SIZE_TOLERANCE=1.5;static RINGS=12;static SEGMENTS=24;at(t,e,i,n){const s=[];for(const r of e){const o=di.projectionOf(r,i,n?.(r));if(o)for(const c of r.explains){const l=this.timeline.getInterpolatedShapeAt(t,c);!l||l.transparency>=1||s.push({...di.compare(c,r.id,{aim:l.aim,angular:l.angular},o),title:l.title})}}return s}static compare(t,e,i,n){const s=[],r=i.aim?di.separationDeg(i.aim,n.aim):void 0;if(r!==void 0){const l=Math.max(i.angular?.widthDeg??0,n.angular.widthDeg)/2;r>Math.max(di.DIRECTION_TOLERANCE_DEG,l)&&s.push("direction")}const o=i.angular&&i.angular.widthDeg>0?n.angular.widthDeg/i.angular.widthDeg:void 0,c=i.angular&&i.angular.heightDeg>0?n.angular.heightDeg/i.angular.heightDeg:void 0;return o!==void 0&&!di.withinSize(o)&&s.push("width"),c!==void 0&&!di.withinSize(c)&&s.push("height"),{sourceId:t,bodyId:e,stated:i,predicted:n,separationDeg:r,widthRatio:o,heightRatio:c,disagreements:s}}static projectionOf(t,e,i){const n=i&&i.length>0?i:di.outlineOf(t),s=i&&i.length>0?di.centreOf(i):t,r=di.normalized({eastM:s.eastM-e.eastM,northM:s.northM-e.northM,upM:s.upM-e.upM});if(!r)return;const o=di.normalized({eastM:r.northM,northM:-r.eastM,upM:0})??{eastM:1,northM:0,upM:0},c=di.cross(o,r);let l=1/0,h=-1/0,u=1/0,d=-1/0;for(const f of n){const p={eastM:f.eastM-e.eastM,northM:f.northM-e.northM,upM:f.upM-e.upM},v=di.dot(p,r);if(v<=0)return;const m=Math.atan2(di.dot(p,o),v),g=Math.atan2(di.dot(p,c),v);l=Math.min(l,m),h=Math.max(h,m),u=Math.min(u,g),d=Math.max(d,g)}return{aim:{azimuthDeg:(Math.atan2(r.eastM,r.northM)*Oc+360)%360,altitudeDeg:Math.asin(Math.max(-1,Math.min(1,r.upM)))*Oc},angular:{widthDeg:(h-l)*Oc,heightDeg:(d-u)*Oc}}}static centreOf(t){const e=i=>(Math.min(...t.map(n=>n[i]))+Math.max(...t.map(n=>n[i])))/2;return{eastM:e("eastM"),northM:e("northM"),upM:e("upM")}}static separationDeg(t,e){const i=t.altitudeDeg*_o,n=e.altitudeDeg*_o,s=Math.sin(i)*Math.sin(n)+Math.cos(i)*Math.cos(n)*Math.cos((t.azimuthDeg-e.azimuthDeg)*_o);return Math.acos(Math.max(-1,Math.min(1,s)))*Oc}static withinSize(t){return t<=di.SIZE_TOLERANCE&&t>=1/di.SIZE_TOLERANCE}static outlineOf(t){const e=t.sizeM.widthM/2,i=t.sizeM.lengthM/2,n=t.sizeM.heightM/2,s=[],r=t.model.url===void 0?t.model.id:void 0;if(r!==void 0&&r!=="box"&&sy.includes(r))for(let u=0;u<=di.RINGS;u++){const d=u/di.RINGS*Math.PI;for(let f=0;f<di.SEGMENTS;f++){const p=f/di.SEGMENTS*2*Math.PI;s.push([e*Math.sin(d)*Math.cos(p),i*Math.sin(d)*Math.sin(p),n*Math.cos(d)])}}else for(const u of[-e,e])for(const d of[-i,i])for(const f of[-n,n])s.push([u,d,f]);const c=t.attitude.headingDeg*_o,l=t.attitude.pitchDeg*_o,h=t.attitude.rollDeg*_o;return s.map(([u,d,f])=>{const p=u*Math.cos(h)+f*Math.sin(h),v=-u*Math.sin(h)+f*Math.cos(h),m=d*Math.cos(l)-v*Math.sin(l),g=d*Math.sin(l)+v*Math.cos(l);return{eastM:t.eastM+p*Math.cos(c)+m*Math.sin(c),northM:t.northM-p*Math.sin(c)+m*Math.cos(c),upM:t.upM+g}})}static dot(t,e){return t.eastM*e.eastM+t.northM*e.northM+t.upM*e.upM}static cross(t,e){return{eastM:t.northM*e.upM-t.upM*e.northM,northM:t.upM*e.eastM-t.eastM*e.upM,upM:t.eastM*e.northM-t.northM*e.eastM}}static normalized(t){const e=Math.hypot(t.eastM,t.northM,t.upM);return e>1e-9?{eastM:t.eastM/e,northM:t.northM/e,upM:t.upM/e}:void 0}}PM();const GD={sun:"Sun",moon:"Moon",Venus:"Venus",Mars:"Mars",Jupiter:"Jupiter",Saturn:"Saturn"},VD="{name} — mag {mag}, {alt}° above the horizon",WD="{name} — satellite, mag {mag}, {height} km up",XD="satellites-change",YD="fireballs-change",qD="aircraft-change",ly="rr0-confrontation",$D="{name} — mag {mag}, {alt}° below the horizontal",Hf="Credits",Jv="comet:",jv="nova:",Qv={building:"Building",tree:"Tree",shrub:"Shrub",bridge:"Bridge",wire:"Overhead line",crop:"Crop row",terrace:"Terrace (restanque)",mound:"Stone heap",streetlight:"Streetlight",vehicle:"Vehicle",observer:"Observer",aircraft:"Aircraft",entity:"Being"},KD=new URL(""+new URL("lunar-relief.bin-ByThqxUn.gz",import.meta.url).href,import.meta.url).href,ZD=new URL(""+new URL("stars-mag7.5-B43R6Wvg.bin",import.meta.url).href,import.meta.url).href,JD=new URL(""+new URL("stars-mag7.5-9-BLV2tFmZ.bin",import.meta.url).href,import.meta.url).href,jD=-18,QD={sun:{altitudeDeg:-3,azimuthDeg:180,magnitude:-26.7},moon:{altitudeDeg:-90,azimuthDeg:0,phase:{phaseFraction:0,illuminatedFraction:0},magnitude:-12.7},planets:[]},Lh={lat:0,lng:0,elevationM:0,headingDeg:void 0,pitchDeg:0,fovDeg:60};class $e extends HTMLElement{creditsButton;set ownCredits(t){this.creditsButton.hidden=!t}static get observedAttributes(){return["src","star-catalog-src","deep-star-catalog-src","show-compass","max-pixel-ratio",ks,Fs]}shadow;stageElement;frameElement;sceneCanvas;loaderNote;loaderNotVideo;ufoElement;sceneRenderer;hoverTooltip;resizeObserver;sizeEstimates=new Map;sizeEstimatesFor;distanceHypotheses=new Map;depths=new Map;directionScratch=new R;meteorScheduleFor;lightningScheduleFor;lightningFlashes=[];lastLightningT;lastTimeMs=0;interpretationShown;confrontationReadings=[];confrontationSignature="";comparing=!1;inTheRound=!0;lastSkyKey;starCatalog;starCatalogRequest=0;static tleArchive=new qi;satellitesFor;satelliteRequest=0;satelliteStatus="none";satellites;satellitePassesMemo;static fireballArchive=new Ps;fireballs;static aircraftProviders=new Map;static SOUND_LOOKBACK_MS=3e5;static NO_CONTRAILS=[];static upperAirProviders=new Map;static NO_PRESENCE=new Map;aircraftSource=HD[0];static trafficRuntimeLoading;static trafficRuntime;static loadTrafficRuntime(){return $e.trafficRuntimeLoading??=je(()=>import("./trafficRuntime-BhspObgN.js"),__vite__mapDeps([2,1]),import.meta.url).then(t=>$e.trafficRuntime=t),$e.trafficRuntimeLoading.catch(()=>{$e.trafficRuntimeLoading=void 0}),$e.trafficRuntimeLoading}traffic;lastSun;decorMemo;seatedMemo;starCatalogDepth=0;weatherAudio=new OD;vehicleAudio=new Wx;aircraftAudio;vehicleHearing=new xu;thunderTimeoutId;handleFullscreenChange=()=>this.resizeToStage();handlePointerMove=t=>{this.sceneRenderer.setCompassHovered(!0);const e=this.ufoElement.canvasElement,i=e.getBoundingClientRect();if(i.width===0||i.height===0)return;const n=(t.clientX-i.left)/i.width*e.width,s=(t.clientY-i.top)/i.height*e.height;if(this.ufoElement.hasVisibleShapeAt(n,s)){this.hoverTooltip.hidden=!0;return}const r=(t.clientX-i.left)/i.width*2-1,o=-((t.clientY-i.top)/i.height*2-1),c=this.naming,l=c.names,h=this.sceneRenderer.pickBodyAt(r,o);if(h){this.showHoverTooltip(t,this.bodyName(h));return}const u=this.interpretationShown?this.sceneRenderer.pickInterpretationBodyAt(r,o):void 0,d=u?this.interpretationShown?.bodies.find(S=>S.id===u):void 0,f=d?this.said.read(d.title)||(d.model.id==="figure"?c.decorKind("entity",Qv.entity):void 0):void 0;if(f){this.showHoverTooltip(t,f);return}const p=this.sceneRenderer.pickDecorAt(r,o),v=p?this.ufoElement.sighting.decor.find(S=>S.id===p):void 0;if(v){this.showHoverTooltip(t,this.said.read(v.title)||c.decorKind(v.kind,Qv[v.kind]));return}const m=this.trafficTooltipAt(r,o);if(m){this.showHoverTooltip(t,m);return}const g=this.sceneRenderer.pickSatelliteAt(r,o);if(g){this.showHoverTooltip(t,(l?.satelliteTooltip??WD).replace("{name}",g.name).replace("{mag}",g.magnitude.toLocaleString(void 0,{maximumFractionDigits:1})).replace("{height}",Math.round(g.heightKm).toLocaleString()));return}const b=this.sceneRenderer.pickStarAt(r,o);if(b){const S=b.star.mag,M=b.altitudeDeg,x=M<0?l?.starTooltipBelow??$D:l?.starTooltip??VD;this.showHoverTooltip(t,x.replace("{name}",c.star(b.star)).replace("{mag}",S.toLocaleString(void 0,{maximumFractionDigits:Math.abs(S)<1?2:1})).replace("{alt}",String(Math.round(Math.abs(M)))));return}this.hoverTooltip.hidden=!0};bodyName(t){const e=t.startsWith(Jv)?t.slice(Jv.length):void 0,i=e?cy.find(r=>r.id===e):void 0;if(i)return this.naming.comet(i);const n=t.startsWith(jv)?qv.byId(t.slice(jv.length)):void 0;if(n)return this.naming.nova(n);const s=GD[t];return s===void 0?t:this.naming.body(t,s)}get naming(){return this.sceneNaming}sceneNaming=new Xu;namesLanguage="en";async loadSceneNames(){const t=Ep(Gr.preferencesFor(this),Ap);if(t===this.namesLanguage)return;this.namesLanguage=t;const e=await bM(t);t===this.namesLanguage&&this.applySceneNaming(new Xu(e))}renderLoaderText(t,e){let i=0;const n=(s,r)=>{s.setAttribute("aria-label",r),s.replaceChildren(),r.split(" ").forEach((o,c)=>{c>0&&s.append(" ");const l=document.createElement("span");l.className="scene-loader-word",l.setAttribute("aria-hidden","true");for(const h of o){const u=document.createElement("span");u.className="scene-loader-letter",u.style.setProperty("--i",String(i++)),u.textContent=h,l.append(u)}s.append(l),i++})};n(this.loaderNotVideo,t),i+=6,n(this.loaderNote,e)}applySceneNaming(t){this.sceneNaming=t;const e=t.names?.credits??Hf;this.creditsButton.title=e,this.creditsButton.setAttribute("aria-label",e),t.names&&this.renderLoaderText(t.names.notAVideo,t.names.isASimulation),this.sceneRenderer.setCompassPoints(t.names?.compassPoints)}showHoverTooltip(t,e){this.hoverTooltip.textContent=e,this.hoverTooltip.hidden=!1;const i=this.stageElement.getBoundingClientRect();this.hoverTooltip.style.left=`${t.clientX-i.left+12}px`,this.hoverTooltip.style.top=`${t.clientY-i.top+12}px`}handlePointerLeave=()=>{this.hoverTooltip.hidden=!0,this.sceneRenderer.setCompassHovered(!1)};handleLightningFlash(t){clearTimeout(this.thunderTimeoutId),this.thunderTimeoutId=window.setTimeout(()=>this.weatherAudio.playThunder(),Ii.thunderDelayMs(t))}handleFirstInteraction=()=>{this.weatherAudio.resume(),this.vehicleAudio.resume(),this.aircraftAudio?.resume(),!this.interacted&&(this.interacted=!0,this.setWeather(Dl(this.ufoElement.sighting,this.lastTimeMs)))};interacted=!1;applyLevel(){const t=this.ufoElement.level;this.weatherAudio.setLevel(t),this.vehicleAudio.setLevel(t),this.aircraftAudio?.setLevel(t)}handlePageGesture=()=>{this.ufoElement.playbackState==="playing"&&this.handleFirstInteraction()};unlockIfAlreadyActivated(){this.interacted||navigator.userActivation?.hasBeenActive&&this.handleFirstInteraction()}static GESTURES=["pointerdown","pointerup","touchend","click","keydown"];handleTimeUpdate=t=>{this.lastTimeMs=t.detail.time,this.syncAnimationsToPlayback(),this.updateAstronomy(this.lastTimeMs),this.ufoElement.playbackState==="playing"&&this.sceneRenderer.frame(performance.now())};syncAnimationsToPlayback(){const t=this.ufoElement.playbackState==="playing";this.sceneRenderer.setAnimationsRunning(t,t),this.weatherAudio.setPaused(!t),this.vehicleAudio.setPaused(!t),this.aircraftAudio?.setPaused(!t),t&&this.unlockIfAlreadyActivated(),t||clearTimeout(this.thunderTimeoutId)}constructor(){super(),this.shadow=this.attachShadow({mode:"open"});const t=document.createElement("template");t.innerHTML=`<style>${qx}</style>${Yx}`,this.shadow.appendChild(t.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 le(this.sceneCanvas);const e=this.shadow.getElementById("scene-loader");this.loaderNote=this.shadow.getElementById("scene-loader-note"),this.loaderNotVideo=this.shadow.getElementById("scene-loader-not-video"),this.renderLoaderText("This is not a video","It is a real-time simulation."),this.sceneRenderer.onFirstFrameHold=s=>{e.hidden=!s,this.ufoElement.captionHeld=s,this.ufoElement.holdClock(s)},this.hoverTooltip=this.shadow.getElementById("hover-tooltip"),this.ufoElement=document.createElement(Kf),this.ufoElement.classList.add("ufo-overlay"),this.ufoElement.paintsShapes=!1,this.forwardPlayerAttributes(),this.ufoElement.addEventListener("lookat",s=>this.lookToward(s.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.creditShownExternally=!0,this.creditsButton=this.shadow.getElementById("credits-button");const i=this.shadow.getElementById("credits-panel"),n=this.shadow.getElementById("credits-list");i.addEventListener("beforetoggle",s=>{s.newState==="open"&&rn.fill(n,this)}),this.creditsButton.title=Hf,this.creditsButton.setAttribute("aria-label",Hf),this.sceneRenderer.onMapSubjectBounds=s=>this.ufoElement.setMapSubjectBounds(s),this.ufoElement.addEventListener("timeupdate",this.handleTimeUpdate),this.ufoElement.seekPreviewPainter=(s,r)=>this.seekPreviewOf(r).paint(s,r),this.ufoElement.addEventListener("mutedchange",()=>this.applyLevel()),this.ufoElement.ambientSound=s=>s.vehicle!==void 0||s.decor.some(r=>r.engine!==void 0)||s.weatherTrack.allKeyframes.some(r=>r.weather.precipitationType!=="none"||r.weather.windSpeed>1),this.ufoElement.addEventListener("referenceview",s=>this.applyReferenceView(s.detail)),this.ufoElement.addEventListener("traceview",s=>this.sceneRenderer.setTracesShown(s.detail.shown)),this.ufoElement.canvasElement.addEventListener("pointermove",this.handlePointerMove),this.ufoElement.canvasElement.addEventListener("pointerleave",this.handlePointerLeave);for(const s of $e.GESTURES)this.addEventListener(s,this.handleFirstInteraction,!0)}get said(){return this.saidTexts??=new Yn(Gr.preferencesFor(this))}saidTexts;traceLabelsFor;traceLabels(t){const e=Gr.preferencesFor(this).join();if(this.traceLabelsFor?.traces!==t||this.traceLabelsFor.language!==e){const i=new Map;for(const n of t){const s=this.said.read(n.title);s&&i.set(n.id,s)}this.traceLabelsFor={traces:t,language:e,labels:i}}return this.traceLabelsFor.labels}connectedCallback(){this.saidTexts=void 0,this.loadSceneNames(),this.sceneRenderer.restoreContext(),this.resizeToStage(),this.updateAstronomy(this.lastTimeMs),this.loadStars(),this.resizeObserver=new ResizeObserver(()=>this.resizeToStage()),this.resizeObserver.observe(this.frameElement),this.watchVisibility(),document.addEventListener("fullscreenchange",this.handleFullscreenChange);for(const e of $e.GESTURES)document.addEventListener(e,this.handlePageGesture,!0);const t=this.getAttribute("src");t&&this.loadFromSrc(t)}watchVisibility(){this.visibilityObserver?.disconnect(),!(typeof IntersectionObserver>"u")&&(this.visibilityObserver=new IntersectionObserver(t=>{if(t[t.length-1].isIntersecting){this.sceneRenderer.resume();return}this.ufoElement.pause(),this.sceneRenderer.suspend()},{rootMargin:"100px"}),this.visibilityObserver.observe(this))}visibilityObserver;disconnectedCallback(){this.visibilityObserver?.disconnect(),this.resizeObserver?.disconnect(),document.removeEventListener("fullscreenchange",this.handleFullscreenChange);for(const t of $e.GESTURES)document.removeEventListener(t,this.handlePageGesture,!0);this.sceneRenderer.stopTwinkle(),clearTimeout(this.thunderTimeoutId),this.weatherAudio.dispose(),this.vehicleAudio.dispose(),this.aircraftAudio?.dispose(),this.seekPreview?.dispose(),this.seekPreview=void 0,queueMicrotask(()=>{this.isConnected||this.sceneRenderer.releaseContext()})}attributeChangedCallback(t,e,i){if(t==="src"&&i&&i!==e&&this.isConnected&&this.loadFromSrc(i),(t==="star-catalog-src"||t==="deep-star-catalog-src")&&i!==e&&this.isConnected&&this.loadStars(),t==="show-compass"&&i!==e&&this.sceneRenderer.setShowCompass(this.hasAttribute("show-compass")),t==="max-pixel-ratio"&&i!==e){const n=Number(i);this.sceneRenderer.setMaxPixelRatio(Number.isFinite(n)&&n>0?n:Math.min(window.devicePixelRatio||1,2))}(t===ks||t===Fs)&&i!==e&&this.forwardPlayerAttributes()}forwardPlayerAttributes(){for(const t of[ks,Fs]){const e=this.getAttribute(t);e===null?this.ufoElement.removeAttribute(t):this.ufoElement.setAttribute(t,e)}}setCompassForced(t){this.sceneRenderer.setCompassForced(t)}lookToward(t){const e=Ze(this.ufoElement.sighting,this.lastTimeMs);if(t.kind==="observer"||e?.lat===void 0||e.lng===void 0||e.headingDeg===void 0){this.setLookOffset(0,0);return}const{x:i,z:n}=si(t.lat,t.lng,e.lat,e.lng);if(Math.hypot(i,n)<1)return this.setLookOffset(0,0);const s=(Math.atan2(i,-n)*180/Math.PI+360)%360;this.setLookOffset(((s-e.headingDeg)%360+540)%360-180,-e.pitchDeg)}setLookOffset(t,e){this.sceneRenderer.setLookOffset(t,e),this.ufoElement.setLookOffset(t,e),this.updateAstronomy(this.lastTimeMs)}setIndoorLook(t,e){this.sceneRenderer.setIndoorLook(t,e)}setCloudRendering(t){this.sceneRenderer.setCloudRendering(t)}setWeather(t){this.sceneRenderer.setWeather(t),this.weatherAudio.setAmbient(t.precipitationType,t.precipitationIntensity*(t.precipitationAmount??1),t.windSpeed)}pickCloudAt(t,e){return this.sceneRenderer.pickCloudAt(t,e)}cloudDirectionAt(t,e){return this.sceneRenderer.cloudDirectionAt(t,e)}pickDecorAt(t,e){return this.sceneRenderer.pickDecorAt(t,e)}decorScreenBox(t){return this.sceneRenderer.decorScreenBox(t)}decorGroundPointAt(t,e,i){return this.sceneRenderer.decorGroundPointAt(t,e,i)}bodyScreenBox(t){return this.sceneRenderer.bodyScreenBox(t)}pickPlacedBodyAt(t,e){return this.sceneRenderer.pickPlacedBodyAt(t,e)}resumeWeatherAudio(){this.weatherAudio.resume(),this.vehicleAudio.resume(),this.aircraftAudio?.resume()}async loadFromSrc(t){const e=Gc.json(t);this.holdForNewScene(e);const i=await e;this.documentUrl=new URL(t,location.href).href,this.sightingData=i}holdForNewScene(t){this.sceneRenderer.holdForNewScene(t)}get documentUrl(){return this.sceneRenderer.documentUrl}set documentUrl(t){this.sceneRenderer.documentUrl=t}get sightingData(){return this.ufoElement.sightingData}set sightingData(t){this.ufoElement.sightingData=t,this.seekPreview?.recordingChanged(t),this.interpretationShown=this.inTheRound?this.ufoElement.sighting.interpretation:void 0,this.syncAccountHidden(),this.applyFrameFormat(),this.lastTimeMs=0,this.sceneRenderer.compileNextFrameOffThread(),this.updateAstronomy(0)}seekPreview;seekPreviewOf(t){const e=this.sceneCanvas.width>0&&this.sceneCanvas.height>0?this.sceneCanvas.width/this.sceneCanvas.height:1.7777777777777777,i=Math.round(t.width/e);return t.height!==i&&(t.height=i),this.seekPreview??=new Wu(this,()=>document.createElement(qu))}showAt(t){this.ufoElement.currentTime=t,this.framesAtAsk=this.sceneRenderer.framesDrawn}framesAtAsk=0;snapshotTo(t){if(this.sceneRenderer.frame(performance.now()),this.sceneRenderer.framesDrawn===this.framesAtAsk)return!1;const e=t.getContext("2d");return e?(e.drawImage(this.sceneCanvas,0,0,t.width,t.height),!0):!1}referenceAspect(t){return this.sceneRenderer.referenceAspect(t)}screenPointOf(t){return this.sceneRenderer.screenPointOf(t)}directionAt(t,e){return this.sceneRenderer.directionAt(t,e)}referenceFailedToLoad(t){return this.sceneRenderer.referenceFailedToLoad(t)}applyReferenceView(t){this.sceneRenderer.setReferencesShown(t.shown);for(const e of this.ufoElement.sighting.references){const i=t.views?.[e.id];this.sceneRenderer.setReferenceView(e.id,{opacity:i?i.shown?i.opacity:0:t.opacity})}}get currentTerrainAttribution(){return this.sceneRenderer.currentTerrainAttribution}get currentRoadAttribution(){return this.sceneRenderer.currentRoadAttribution}setTerrainProviders(t){this.sceneRenderer.setTerrainProviders(t)}setDecorModelProvider(t){this.sceneRenderer.setDecorModelProvider(t)}get decorModelCredits(){return[...new Map(this.sceneRenderer.currentDecorModelCredits.map(e=>[`${e.title}|${e.author??""}|${e.license}|${e.sourceUrl??""}`,e])).values()]}applyFrameFormat(){const t=this.ufoElement.sighting.instrument,e=Fe.CANVAS_HEIGHT_PX,i=bi.frameWidthPx(t,e);this.frameElement.style.setProperty("--frame-aspect",`${i} / ${e}`)}resizeToStage(){const t=this.frameElement.getBoundingClientRect(),e=Math.max(1,Math.round(t.width)),i=Math.max(1,Math.round(t.height));this.sceneCanvas.width=e,this.sceneCanvas.height=i,this.sceneRenderer.resize(e,i)}async loadStars(){const t=[{magnitudeLimit:kf,url:this.getAttribute("star-catalog-src")??ZD},{magnitudeLimit:Ff,url:this.getAttribute("deep-star-catalog-src")??JD}],e=this.instrumentReach(),i=++this.starCatalogRequest;this.starCatalogDepth=e>kf?Ff:kf;const n=await _s.upTo(t,e);i===this.starCatalogRequest&&(this.starCatalog=n,this.sceneRenderer.compileNextFrameOffThread(),this.updateAstronomy(this.lastTimeMs))}ensureStarsDeepEnough(){!this.starCatalog||this.starCatalogDepth>=Ff||this.instrumentReach()<=this.starCatalogDepth||this.loadStars()}instrumentReach(){const t=this.ufoElement.sighting,e=an.gainFor(t.instrument,{fNumber:Ze(t,0)?.fNumber,fieldOfViewDeg:xn.fovOf(t,0),exposureSeconds:t.exposure});return Kh(jD,e)}updateAstronomy(t){this.ensureStarsDeepEnough(),this.applySceneAt(t);const e=as.windowEndingAt(t,this.exposureSeconds()),i=e.seconds,n=this.degreesPerPixelAt(t),s=Ua.instants(i,n),r=Math.max(s,this.ufoElement.exposureTimes(t).length,as.instants(this.decorWithTraffic(this.ufoElement.sighting),Ze(this.ufoElement.sighting,t)?.elevationM??0,e.fromMs,i,n));if(r<=1){this.sceneRenderer.setExposure(1);return}this.sceneRenderer.setExposure(r,o=>this.applySceneAt(e.fromMs+e.ms*o/(r-1),{sky:Math.floor(o*s/r)!==Math.floor((o-1)*s/r),stepMs:e.ms/r}))}exposureSeconds(){return this.ufoElement.sighting.exposure??0}degreesPerPixelAt(t){const e=this.sceneCanvas.height;return e<=0?0:xn.fovOf(this.ufoElement.sighting,t)/e}roadGradeAt(t,e){return t.observerTrack.allKeyframes.length<2?0:Ro.at(t,e,this.sceneRenderer.bodyGround)}get roadGradeDeg(){return this.roadGradeAt(this.ufoElement.sighting,this.ufoElement.currentTime)}applySceneAt(t,e){const i=this.ufoElement.sighting;this.setWeather(Dl(i,t)),this.sceneRenderer.setInstrument(i.instrument),this.sceneRenderer.setLightPollution(i.lightPollution),e||this.vehicleAudio.setVoices(this.vehicleHearing.at(i,t)),e||this.pushAircraftSound(i,t),this.updateMeteorShower(i,t),this.updateLightning(i,t,e!==void 0),this.sceneRenderer.setDecor(this.seatedDecor(this.decorWithTraffic(i),t)),this.sceneRenderer.setDecorPresence(this.traffic?.set?.presence??$e.NO_PRESENCE),this.sceneRenderer.setDecorSunlight(this.trafficSunlight(t)),this.sceneRenderer.setContrails(this.traffic?.contrails??$e.NO_CONTRAILS),this.sceneRenderer.setContrailSunlight(this.contrailSunlight(t));const n=Ze(i,t);this.sceneRenderer.setReferences(i.references,n?.lat!==void 0&&n.lng!==void 0?{lat:n.lat,lng:n.lng}:void 0);const s=Ze(i,0),r=Eo(i,0),o=ra(i.event.time??{},n?.lng??Lh.lng,i.event.utcOffsetHours),c=i.weatherSource!==void 0&&o?Xx(o):void 0,l=Object.fromEntries(Qh(Eo(i,t)).map(T=>[T.id,eg(t,i.weatherTrack,r,s,n,T.id,T.instances?.length?void 0:c)]));this.sceneRenderer.setCloudOffset(eg(t,i.weatherTrack,r,s,n,void 0,c),l),this.sceneRenderer.setObserverPose(n?{...n,pitchDeg:n.pitchDeg+this.roadGradeAt(i,t)}:Lh),this.sceneRenderer.setLensOptics(this.lensOpticsAt(t)),this.sceneRenderer.setInstrumentGain(an.gainFor(i.instrument,{fNumber:n?.fNumber,fieldOfViewDeg:xn.fovOf(i,t),exposureSeconds:i.exposure}),i.instrument.detailUm!==void 0,ls.byId(n?.filter).opticalDensity),this.sceneRenderer.setMedium(i.instrument.medium,i.exposure,n?.fNumber??i.instrument.fNumber,i.iso),this.sceneRenderer.setGait(Ce.bodyAt(i,t,this.ufoElement.steadyBody)),this.sceneRenderer.updateDecorAnchoring(Ze(i,0),n,t),this.placeBodiesAt(t,e===void 0),this.sceneRenderer.updateDecorLitState(t,e?.stepMs??0),this.sceneRenderer.setTerrainOrigin(n?.lat,n?.lng,()=>{this.placeBodiesAt(this.lastTimeMs,!0),this.sceneRenderer.render()}),this.sceneRenderer.setStatedRoads(i.roads),this.sceneRenderer.setTraces(i.traces,this.traceLabels(i.traces)),this.pushPhenomenaAt(t);const h=n?.lat??Lh.lat,u=n?.lng??Lh.lng,d=ra(i.event.time??{},u,i.event.utcOffsetHours),f={lat:h,lng:u,elevationM:n?.elevationM??0};this.pushSatellitesAt(d,t,f),this.ensureFireballs(d);const p=[...this.interpretationShown?.reentries??[],...this.fireballs?.reentries??[]];if(this.sceneRenderer.setReentries(p.length===0?[]:be.viewsAt(p,t,{lat:h,lng:u,heightM:f.elevationM})),e&&!e.sky)return;if(!d){this.sceneRenderer.setAstronomy(QD);return}const v=new Date(d.getTime()+t),m=Math.max(1,Math.round(.25*this.degreesPerPixelAt(t)/Ua.DEG_PER_SECOND*1e3)),g=Math.max(1e-8,this.degreesPerPixelAt(t)*.1),b=`${Math.floor(v.getTime()/m)}|${Math.round(h/g)}|${Math.round(u/g)}|${Math.round(f.elevationM)}|${this.starCatalog?this.starCatalogDepth:0}`;if(b===this.lastSkyKey){this.sceneRenderer.render();return}this.lastSkyKey=b;const S=xh("Sun",v,f),M=xh("Moon",v,f);let x=Mi.separationOf(S,M)<1?Mi.viewAt(v,f):void 0;if(x){const T=Mi.offsetOf(S,M,x.separationDeg);if(x.obscuration>$e.LIMB_FROM_OBSCURATION){const I=this.limbFor(v,f);I&&(x={...x,obscuration:1-Vn.uncoveredFraction(I,x.sunRadiusDeg,T),limb:I})}x={...x,horizonShare:Mi.horizonShare(x,T,S.altitudeDeg,S.azimuthDeg,Cs.distanceKm(v,f))}}const _={...S,magnitude:uf("Sun",v)-2.5*Math.log10(Mi.beamFraction(x))};this.lastSun={altitudeDeg:_.altitudeDeg,azimuthDeg:_.azimuthDeg};const A={...M,phase:R4(v),magnitude:uf("Moon",v),radiusDeg:Cs.apparentRadiusDeg(v,f)},y=T4.map(T=>({body:T,position:xh(T,v,f),magnitude:uf(T,v)}));this.sceneRenderer.setAstronomy({sun:_,moon:A,planets:y,comet:this.cometAt(v,f),novae:qv.appearancesAt(v,f).map(({outburst:T,position:I,magnitude:C})=>({id:T.id,position:I,magnitude:C})),stars:this.starCatalog?{catalog:this.starCatalog,date:v,observer:f}:void 0,frame:{date:v,observer:f},eclipse:x}),this.ufoElement.setSunAltitude(_.altitudeDeg)}static LIMB_FROM_OBSCURATION=.98;limbRelief;limbRequested=!1;limbCache;limbFor(t,e){if(!this.limbRelief){this.limbRequested||(this.limbRequested=!0,Qc.load(KD).then(s=>{this.limbRelief=s,this.lastSkyKey="",s&&this.isConnected&&this.updateAstronomy(this.lastTimeMs)}));return}const i=this.limbCache;if(i&&Math.abs(t.getTime()-i.atMs)<5e3&&i.lat===e.lat&&i.lng===e.lng&&i.elevationM===e.elevationM)return i.profile;const n=Vn.profile(t,e,this.limbRelief);return this.limbCache={profile:n,atMs:t.getTime(),lat:e.lat,lng:e.lng,elevationM:e.elevationM},n}pushSatellitesAt(t,e,i){if(this.ensureSatellites(t),!t||!this.satellites){this.sceneRenderer.setSatellites([]);return}const n=new Date(t.getTime()+e),s=[];for(const r of this.satellites.passes.positionsAt(n,i,-1))r.magnitude!==void 0&&s.push({norad:r.object.norad,name:r.object.name,position:{altitudeDeg:r.altitudeDeg,azimuthDeg:r.azimuthDeg},magnitude:r.magnitude,heightKm:r.heightKm});this.sceneRenderer.setSatellites(s)}ensureFireballs(t){const e=this.ufoElement.sighting,i=Math.max((e.event.durationSeconds??0)*1e3,this.ufoElement.seekableDuration),n=t?.getTime(),s=n===void 0?"":`${n}+${i}`;if(this.fireballs?.key===s)return;if(n===void 0||!Ps.mayCover(n+i)){this.fireballs={key:s,status:"outside",reentries:[]};return}const r={key:s,status:"loading",reentries:[]};this.fireballs=r,$e.fireballArchive.between(n,n+i).then(o=>{r.status=o?"ready":"unavailable",r.records=o??[],r.reentries=r.records.map(c=>Ps.asReentry(c,n)),!(this.fireballs!==r||!this.isConnected)&&(this.dispatchEvent(new CustomEvent(YD)),r.reentries.length>0&&this.updateAstronomy(this.lastTimeMs))})}decorWithTraffic(t){const e=this.ensureTraffic(t);if(!e||e.objects.length===0)return t.decor;const i=this.decorMemo;if(i&&i.base===t.decor&&i.traffic===e.objects)return i.merged;const n=[...t.decor,...e.objects];return this.decorMemo={base:t.decor,traffic:e.objects,merged:n},n}seatedDecor(t,e){if(!t.some(r=>r.observerKeyframes?.length))return t;const i=t.map(r=>{if(!r.observerKeyframes?.length)return"";const o=Ym(r,e);return`${o.side??"-"}/${o.facing??"-"}`}).join("|"),n=this.seatedMemo;if(n&&n.base===t&&n.seats===i)return n.seated;const s=t.map(r=>{if(!r.observerKeyframes?.length)return r;const o=Ym(r,e);return{...r,observerSide:o.side,observerFacing:o.facing}});return this.seatedMemo={base:t,seats:i,seated:s},s}ensureTraffic(t){const e=Ze(t,0),i=e?.lng===void 0?void 0:ra(t.event.time??{},e.lng,t.event.utcOffsetHours),n=Math.max((t.event.durationSeconds??0)*1e3,this.ufoElement.seekableDuration),s=i?.getTime(),r=s===void 0||e?.lat===void 0||e.lng===void 0?"":`${this.aircraftSource.id}|${s}+${n}|${e.lat.toFixed(3)},${e.lng.toFixed(3)}|${Math.round(e.elevationM??0)}`;if(this.traffic?.key===r)return this.traffic.set;if(r===""||s===void 0||e?.lat===void 0||e.lng===void 0){this.traffic={key:r,status:"outside"};return}let o=$e.aircraftProviders.get(this.aircraftSource.id);if(o||$e.aircraftProviders.set(this.aircraftSource.id,o=this.aircraftSource.create()),o.mayCover&&!o.mayCover(s+n)){this.traffic={key:r,status:"outside"};return}const c={key:r,status:"loading",startMs:s,observer:{lat:e.lat,lng:e.lng}};this.traffic=c;const l={lat:e.lat,lng:e.lng,heightM:e.elevationM??0},h=on.MAX_GAP_S*1e3,u=$e.SOUND_LOOKBACK_MS,d={lat:e.lat,lng:e.lng,elevationM:e.elevationM??0},f=(p,v)=>p.TrafficDecor.from(c.tracks??[],l,s,p.TrafficDecor.MAX_OBJECTS,{models:v,sunElevationAt:m=>this.sunElevationAt(m,d)});o.between(l,s-u,s+n+h).then(async p=>{if(this.traffic!==c)return;if(p.status!=="found"){c.status=p.status==="outside"?"outside":"unavailable",this.announceTraffic();return}let v;try{v=await $e.loadTrafficRuntime()}catch{this.traffic===c&&(c.status="unavailable",this.announceTraffic());return}this.traffic===c&&(c.status="ready",c.tracks=p.tracks,c.set=f(v),this.startAircraftSound(c,v),this.announceTraffic(),this.describeTraffic(o,c,v,f),c.set.shown>0&&this.readUpperAir(c,v,s-u,s+n+h))})}trafficSunlight(t){const e=new Map,i=this.traffic,n=i?.set,s=this.lastSun;if(!n||!s||i.startMs===void 0||!i.observer)return e;for(const[r,o]of n.presence){if(t<o.fromMs||t>o.untilMs)continue;const c=n.flights.get(r),l=c?on.positionAt(c,i.startMs+t):void 0;l&&e.set(r,{heightM:l.geo.heightM,sunElevationDeg:Pn.sunElevationDeg(s,i.observer,l.geo)})}return e}trafficTooltipAt(t,e){const i=this.sceneRenderer.pickTrafficAt(t,e),n=i?this.trafficInfoAt(i):void 0;if(!n)return;const s=this.naming,r=$e.trafficRuntime;return r?.TrafficTooltip.text(n,s.names?.trafficTooltip??r.TrafficTooltip.ENGLISH,o=>s.towards(o))}trafficInfoAt(t){const e=this.traffic,i=e?.set?.flights.get(t);if(!e||!i||e.startMs===void 0||!e.observer)return;const n=$e.trafficRuntime;if(!n)return;const s=e.descriptions?.get(Xn.keyOf(i)),r=Ze(this.ufoElement.sighting,this.lastTimeMs),o={lat:e.observer.lat,lng:e.observer.lng,heightM:r?.elevationM??0},c=n.AmbientNoise.dbA(Dl(this.ufoElement.sighting,this.lastTimeMs)),l=n.TrafficInfos.at(i,s,o,e.startMs+this.lastTimeMs,{ambientDbA:c}),h=l&&this.contrailAt(t,this.lastTimeMs);return l&&h?{...l,contrail:h}:l}contrailAt(t,e){const i=this.traffic?.contrails?.find(s=>s.id===t);if(!i)return;let n;for(const s of i.points){if(s.tMs>e)break;n=s}return n?.forms?{persistent:n.persistent,iceRelativeHumidity:n.iceRelativeHumidity}:void 0}startAircraftSound(t,e){this.aircraftAudio||(this.aircraftAudio=new e.AircraftAudio,this.aircraftAudio.setLevel(this.ufoElement.level),this.interacted&&this.aircraftAudio.resume(),this.aircraftAudio.setPaused(this.ufoElement.playbackState!=="playing")),this.sortOutAudible(t,e)}sortOutAudible(t,e){!t.set||!t.observer||(t.audible=e.TrafficSound.candidates(t.set.flights,t.descriptions??new Map,Xn.keyOf,{...t.observer,heightM:0},{ambientDbA:e.AmbientNoise.BASE_DB_A}))}pushAircraftSound(t,e){const i=this.aircraftAudio;if(!i)return;const n=$e.trafficRuntime,s=this.traffic,r=s?.set;if(!n||!s||!r||!s.audible||s.startMs===void 0||!s.observer){i.setVoices([]);return}const o=Ze(t,e),c={lat:s.observer.lat,lng:s.observer.lng,heightM:o?.elevationM??0},l=Dl(t,e),h=n.TrafficSound.voices(s.audible,r.flights,s.descriptions??new Map,Xn.keyOf,c,s.startMs+e,{ambientDbA:n.AmbientNoise.dbA(l),referenceAmplitude:n.AmbientNoise.referenceAmplitude(l)});i.setVoices(h,o?.headingDeg??0)}announceTraffic(){this.isConnected&&(this.dispatchEvent(new CustomEvent(qD)),this.updateAstronomy(this.lastTimeMs))}async describeTraffic(t,e,i,n){if(!t.describe||!e.set||!e.tracks)return;const s=new Set([...e.set.flights.values()].map(l=>Xn.keyOf(l))),r=e.tracks.filter(l=>s.has(Xn.keyOf(l))&&l.points.length>0),o=new Map,c=new Map;await Promise.all(r.map(async l=>{const h=new Date(l.points[0].t).toISOString().slice(0,10),u=await t.describe(l,h).catch(()=>{});u&&(c.set(Xn.keyOf(l),u),o.set(Xn.keyOf(l),i.AircraftModels.of(u)))})),!(this.traffic!==e||o.size===0)&&(e.descriptions=c,e.models=o,e.set=n(i,o),this.planContrails(e,i),this.sortOutAudible(e,i),this.announceTraffic())}async readUpperAir(t,e,i,n){if(!t.observer)return;const s=this.upperAirSource??e.UPPER_AIR_SOURCES[0];let r=$e.upperAirProviders.get(s.id);r||$e.upperAirProviders.set(s.id,r=s.create());const o=await r.between(t.observer,i,n);this.traffic!==t||o.status!=="found"||(t.air=o.samples,t.airSource=o.source,this.planContrails(t,e),this.announceTraffic())}planContrails(t,e){!t.set||!t.air||t.startMs===void 0||(t.contrails=e.AircraftContrails.plan(t.set,t.models,t.air,t.startMs))}contrailSunlight(t){const e=new Map,i=this.traffic,n=i?.set,s=this.lastSun;if(!n||!s||!i.contrails?.length||i.startMs===void 0||!i.observer)return e;for(const r of i.contrails){const o=n.presence.get(r.id),c=n.flights.get(r.id);if(!o||!c)continue;const l=on.positionAt(c,i.startMs+Math.min(o.untilMs,Math.max(o.fromMs,t)));l&&e.set(r.id,{heightM:l.geo.heightM,sunElevationDeg:Pn.sunElevationDeg(s,i.observer,l.geo)})}return e}sunElevationAt(t,e){const i=xh("Sun",new Date(t.t),e);return Pn.sunElevationDeg(i,e,t)}upperAirSource;setUpperAirSource(t){t.id!==this.upperAirSource?.id&&(this.upperAirSource=t,this.traffic=void 0,this.decorMemo=void 0,this.updateAstronomy(this.lastTimeMs))}setAircraftSource(t){t.id!==this.aircraftSource.id&&(this.aircraftSource=t,this.traffic=void 0,this.decorMemo=void 0,this.updateAstronomy(this.lastTimeMs))}get aircraftState(){const t=this.traffic?.contrails?.length?this.upperAirSource??$e.trafficRuntime?.UPPER_AIR_SOURCES[0]:void 0;return{trailCredit:t&&{credit:t.credit,creditUrl:t.creditUrl},status:this.traffic?.status??"none",total:this.traffic?.set?.total??0,shown:this.traffic?.set?.shown??0,credit:this.aircraftSource.credit,creditUrl:this.aircraftSource.creditUrl}}get fireballState(){return{status:this.fireballs?.status??"none",records:this.fireballs?.records??[]}}ensureSatellites(t){const e=t?String(t.getTime()):"";if(e===this.satellitesFor)return;this.satellitesFor=e,this.satellites=void 0,this.satellitePassesMemo=void 0;const i=++this.satelliteRequest;if(!t){this.satelliteStatus="none";return}this.satelliteStatus="loading";const n=r=>{i===this.satelliteRequest&&(this.satelliteStatus=r,this.isConnected&&this.dispatchEvent(new CustomEvent(XD)))},s=$e.tleArchive;(async()=>{if(!await s.covers(t))return n("outside");const[r,o]=await Promise.all([s.at(t),je(()=>import("./SatellitePasses-Pfro2-0Z.js"),[],import.meta.url)]);if(i===this.satelliteRequest){if(!r)return n("unavailable");this.satellites={snapshot:r,passes:new o.SatellitePasses(r.objects)},n("ready"),this.isConnected&&this.updateAstronomy(this.lastTimeMs)}})().catch(()=>n("unavailable"))}get satelliteState(){const t=this.satellites?.snapshot;return{status:this.satelliteStatus,coverage:t?.coverage,credit:t?.credit,creditUrl:t?.creditUrl}}satellitePassesDuring(t){const e=this.satellites,i=this.ufoElement.sighting,n=Ze(i,0),s=i.event.place?.[0],r=n?.lat??s?.lat,o=n?.lng??s?.lng;if(!e||r===void 0||o===void 0)return[];const c=ra(i.event.time??{},o,i.event.utcOffsetHours);if(!c)return[];const l=Math.min(Math.max(t,0),4*36e5),h={lat:r,lng:o,elevationM:n?.elevationM??0},u=JSON.stringify([this.satellitesFor,c.getTime(),r,o,h.elevationM,l]);if(this.satellitePassesMemo?.key===u)return this.satellitePassesMemo.passes;const d=Math.max(10,Math.ceil(l/1e3/600)),f=e.passes.passesDuring(c,new Date(c.getTime()+l),h,d);return this.satellitePassesMemo={key:u,passes:f},f}cometAt(t,e){const i=LD.brightestAt(t,e);if(i)return{id:i.apparition.id,position:i.position,tailEnd:i.tailEnd,magnitude:i.magnitude}}pushPhenomenaAt(t){const e=this.ufoElement.sighting;e!==this.sizeEstimatesFor&&(this.sizeEstimates.clear(),this.distanceHypotheses.clear(),this.sizeEstimatesFor=e);const i=e.timeline,n=this.ufoElement.canvasElement,s=this.ufoElement.frameShiftPx,r=this.projectionAt(t),o=new Map,c=new Map,l=new Set;for(const p of i.sourceIds){const v=i.getInterpolatedShapeAt(t,p);if(!v)continue;const m={...v,bounds:{...v.bounds,x:v.bounds.x+s.x,y:v.bounds.y+s.y}};o.set(p,m);const g=v.aim?this.sceneRenderer.screenPointOf(ss.directionOf(v.aim,this.directionScratch)):{ndcX:(m.bounds.x+m.bounds.width/2)/n.width*2-1,ndcY:-((m.bounds.y+m.bounds.height/2)/n.height*2-1)},b=g!==void 0&&Math.abs(g.ndcX)<=1&&Math.abs(g.ndcY)<=1,S=b?this.sceneRenderer.decorDistancesAt(g.ndcX,g.ndcY,p):{};l.add(p),(b||v.aim)&&l.delete(p);const M=v.angular?.widthDeg??r.pxToDeg(v.bounds.width),x=this.sizeEstimateOf(p);x.add(M,S);const _=tl.of(e,p);c.set(p,sn.resolve({hypothesisM:this.distanceHypotheses.get(p),derivedM:_&&M>0?Fe.distanceMAt(_.widthM,M):void 0,range:x.distanceRangeAt(M),crossing:S}))}for(const[p,v]of o)for(const[m,g]of o){if(m===p||g.transparency>=1||g.bounds.width*g.bounds.height<=v.bounds.width*v.bounds.height||!(v.bounds.x>=g.bounds.x&&v.bounds.y>=g.bounds.y&&v.bounds.x+v.bounds.width<=g.bounds.x+g.bounds.width&&v.bounds.y+v.bounds.height<=g.bounds.y+g.bounds.height))continue;const S=c.get(m);S&&c.set(p,{distanceM:S.distanceM*.999,basis:S.basis});break}this.depths=c;const h=i.sourceIds,u=[];for(const[p,v]of o)u.push({sourceId:p,shape:v,distanceM:c.get(p).distanceM,renderOrder:h.indexOf(p),aim:v.aim,hidden:l.has(p)||this.interpretationShown!==void 0&&(!this.comparing||v.transparency>=1),ghost:this.interpretationShown!==void 0&&this.comparing});const f=(Ze(e,t)?.rollDeg??0)+Ce.bodyAt(e,t,this.ufoElement.steadyBody).rollDeg;this.sceneRenderer.setPhenomena(u,{projection:r,canvasWidthPx:n.width,canvasHeightPx:n.height,scale:Math.max(1,this.sceneCanvas.height/Math.max(1,n.height)),starPoints:bi.starPointsOf(e.instrument),rollRad:f*Math.PI/180})}get interpretation(){return this.interpretationShown}set interpretation(t){this.interpretationShown=t,this.syncAccountHidden(),this.updateAstronomy(this.lastTimeMs)}syncAccountHidden(){this.ufoElement.accountHidden=this.interpretationShown!==void 0&&!this.comparing}get accountInTheRound(){return this.inTheRound}set accountInTheRound(t){this.inTheRound=t}get compareAccount(){return this.comparing}set compareAccount(t){this.comparing=t,this.syncAccountHidden(),this.updateAstronomy(this.lastTimeMs)}get confrontation(){return this.confrontationReadings}groundAlong(t,e,i){const n=this.sceneRenderer.bodyGround,s=ce.eyeOf(this.ufoElement.sighting,i,n);return s?ce.lineOfSightMeetsGround(s,t,e,n):void 0}bodyReading(t,e){const i=this.sceneRenderer.bodyGround,n=this.ufoElement.sighting,s=d=>ce.eyeOf(n,d,i),r=new ce(t,i,s).at(e),o=s(e);if(!r||!o)return;const c=r.eastM-o.eastM,l=r.northM-o.northM,h=r.upM-o.upM,u=Math.hypot(c,l);return{azimuthDeg:(Math.atan2(c,l)*180/Math.PI+360)%360,altitudeDeg:Math.atan2(h,u)*180/Math.PI,distanceM:Math.hypot(u,h),eastM:r.eastM,northM:r.northM,aboveGroundM:r.upM-r.sizeM.heightM/2-i.heightAt(r.eastM,r.northM),sizeM:r.sizeM,attitude:r.attitude,appearance:r.appearance}}directionToBody(t,e){const i=this.sceneRenderer.bodyGround,n=this.ufoElement.sighting,s=p=>ce.eyeOf(n,p,i),r=new ce(t,i,s),o=r.at(e)?e:t.track[0]?.t,c=o===void 0?void 0:r.at(o),l=o===void 0?void 0:s(o);if(!c||!l)return;const h=c.eastM-l.eastM,u=c.northM-l.northM,d=c.upM-l.upM,f=Math.hypot(h,u);if(!(f===0&&d===0))return{azimuthDeg:(Math.atan2(h,u)*180/Math.PI+360)%360,altitudeDeg:Math.atan2(d,f)*180/Math.PI}}placeBodiesAt(t,e){const i=this.interpretationShown,n=this.ufoElement.sighting;let s=[],r=[];const o=this.sceneRenderer.bodyGround,c=p=>ce.eyeOf(n,p,o);i&&(s=i.bodies.map(p=>new ce(p,o,c).at(t)).filter(p=>p!==void 0));const l=Eo(n,t),h=l.windDirectionDeg*Math.PI/180,u={x:l.windSpeed*Math.sin(h),z:-l.windSpeed*Math.cos(h)};this.sceneRenderer.setBodies(s,t/1e3,i?.bodies.map(p=>p.id)??[],i?.smoke??[],u);const d=i&&this.comparing?c(t):void 0;if(d&&(r=new di(n.timeline).at(t,s,d,p=>p.outlineNode?this.sceneRenderer.bodyOutline?.(p.id,p.outlineNode):void 0)),this.confrontationReadings=r,!e)return;const f=JSON.stringify(r);f!==this.confrontationSignature&&(this.confrontationSignature=f,this.dispatchEvent(new CustomEvent(ly,{detail:r})))}setDistanceHypothesis(t,e){e===void 0||!(e>0)?this.distanceHypotheses.delete(t):this.distanceHypotheses.set(t,e),this.updateAstronomy(this.lastTimeMs)}depthOf(t){return this.depths.get(t)}sizeRangeOf(t){return this.sizeEstimateOf(t).sizeRange}distanceRangeAt(t,e){const i=this.ufoElement.sighting.timeline.getInterpolatedShapeAt(e,t);if(!i)return{};const n=i.angular?.widthDeg??this.projectionAt(e).pxToDeg(i.bounds.width);return this.sizeEstimateOf(t).distanceRangeAt(n)}sizeContradictory(t){return this.sizeEstimateOf(t).contradictory}updateMeteorShower(t,e){this.ensureMeteorSchedule(t),this.sceneRenderer.updateMeteors(e)}updateLightning(t,e,i){if(this.ensureLightningSchedule(t),this.sceneRenderer.updateLightning(e),i)return;const n=this.lastLightningT;if(this.lastLightningT=e,n===void 0||e<n||this.ufoElement.playbackState!=="playing")return;const s=this.lightningFlashes.filter(r=>r.t>n&&r.t<=e).pop();s&&Eo(t,s.t).storm&&this.handleLightningFlash(s)}ensureLightningSchedule(t){const e=Eo(t,0).precipitationIntensity,i=`${this.meteorInputsOf(t)}|${e}`;if(i===this.lightningScheduleFor)return;this.lightningScheduleFor=i;const n=t.event.time,s=t.event.place?.[0],r=n?.year!==void 0?ra(n,s?.lng??0,t.event.utcOffsetHours):void 0,o=(t.event.durationSeconds??0)*1e3||t.timeline.duration||2e4,c=Math.round((r?.getTime()??0)/1e3)+Math.round((s?.lat??0)*1e3)+7;this.lightningFlashes=Ii.schedule({durationMs:o,seed:c,intensity:e}),this.sceneRenderer.setLightning(this.lightningFlashes)}ensureMeteorSchedule(t){const e=this.meteorInputsOf(t);e!==this.meteorScheduleFor&&(this.meteorScheduleFor=e,this.scheduleMeteors(t))}meteorInputsOf(t){const e=t.event.place?.[0],i=t.event.time;return JSON.stringify([e?.lat,e?.lng,i?.year,i?.month,i?.day,i?.hour,i?.minute,i?.second,t.event.utcOffsetHours,t.event.durationSeconds,t.timeline.duration])}scheduleMeteors(t){const e=t.event.place?.[0],i=t.event.time,n=e?.lat!==void 0&&e.lng!==void 0&&i?.year!==void 0?ra(i,e.lng,t.event.utcOffsetHours):void 0;if(!n||e?.lat===void 0||e.lng===void 0){this.sceneRenderer.setMeteorShower([],0,0);return}const s={lat:e.lat,lng:e.lng,elevationM:0},r=(t.event.durationSeconds??0)*1e3||t.timeline.duration||2e4,o=Math.round(n.getTime()/1e3)+Math.round(e.lat*1e3),c=fi.schedule({ratePerHour:fi.observedRatePerHour(fi.apexPosition(n,s).altitudeDeg),durationMs:r,velocityKmS:fi.TYPICAL_VELOCITY_KM_S,seed:o}),l=zf.activeAt(n).map(u=>{const d=zf.radiantPosition(u.shower,n,s);return{entry:u,position:d,rate:zf.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=ka.schedule({ratePerHour:l.rate,durationMs:r,velocityKmS:l.entry.shower.velocityKmS,seed:o+1});this.sceneRenderer.setMeteorShower([...h,...c],l.position.altitudeDeg,l.position.azimuthDeg)}meteorByRank(t){this.ensureMeteorSchedule(this.ufoElement.sighting);const e=[...this.sceneRenderer.meteorSchedule].filter(s=>s.t+s.durationMs<=this.ufoElement.seekableDuration).sort((s,r)=>r.brightness-s.brightness);if(e.length===0)return;const i=e[t%e.length],n=this.sceneRenderer.meteorMidpoint(i);if(n)return{t:Math.round(i.t+i.durationMs*.45),...n}}lensOpticsAt(t){const e=this.ufoElement.sighting,i=e.instrument,n=i.frame,s=Ze(e,t),r=s?.fNumber??i.fNumber;if(!n||r===void 0)return;const o=bi.focalLengthMmFor(i,xn.fovOf(e,t));if(o!==void 0)return{focalLengthMm:o,fNumber:r,focusDistance:s?.focusDistanceM??0,frameHeightMm:n.heightMm}}projectionAt(t){const e=this.ufoElement.sighting;return rr.of(e.instrument,Fe.CANVAS_HEIGHT_PX,xn.fovOf(e,t))}sizeEstimateOf(t){let e=this.sizeEstimates.get(t);return e||(e=new kD,this.sizeEstimates.set(t,e)),e}}const qu="rr0-scene";function hy(){PM(),customElements.get(qu)||customElements.define(qu,$e)}const tI={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",sway:"Sway at rest",swayTitle:"How much the body holding the instrument moves the view when not walking: 1 for a person standing, 0 for a tripod. Blank: 1 (0 if the account says the observer was paralysed)",lightPollution:"Night sky",lightPollutionTitle:'The zenith of a moonless night at this place, in magnitudes per square arcsecond, as a Sky Quality Meter reads it or as the World Atlas of artificial sky brightness (Falchi et al. 2016, lightpollutionmap.info, "SQM") gives it. 22 is a natural sky; a suburb is about 19, a city centre 17. Blank: a natural sky',observationTime:"Observation start",observationEndTime:"Observation end",assessmentGroup:"Assessment",assessmentNames:{coverage:"Observer 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"},timeQualifierApproximate:"Approximate",timeQualifierUncertain:"Uncertain",timeQualifierBoth:"Uncertain and approximate",timeSeasonSpring:"Spring",timeSeasonSummer:"Summer",timeSeasonAutumn:"Autumn",timeSeasonWinter:"Winter",summaryGroups:{observation:"Observation",location:"Position",temporal:"Time",weather:"Weather",sound:"Sound"},summaryGroup:"Summary",summaryDescription:"Description",closeDescription:"Close the description",observerGroup:"Observer",observerId:"ID",observerTitle:"Title",observerLastName:"Last name",observerFirstNames:"First names",sightingId:"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",cloudsGroup:"Clouds",precipitationGroup:"Precipitation",windGroup:"Wind",soundKind:"Sound",soundNone:"None (silent)",soundHum:"Hum",soundWhistle:"Whistle",soundRumble:"Rumble",soundCrackle:"Crackle",soundVolume:"Loudness",soundPitch:"Pitch",soundSrc:"Recording",instrument:"Observed through",filter:"In front of it",filterNone:"nothing",filterSolarVisual:"a solar filter for the eye (eclipse glasses, density 5)",filterSolarPhoto:"a solar film for a camera (density 3.8)",decorAircraft:"Aircraft",decorEntity:"Being",decorAltitude:"Altitude",decorLights:"Lights",decorLightsNone:"none",decor:"Environment",decorBuilding:"Building",decorTree:"Tree",decorShrub:"Shrub",decorBridge:"Bridge",decorWire:"Overhead line",decorCrop:"Crop row",decorTerrace:"Terrace (restanque)",decorMound:"Stone heap",decorStreetlight:"Streetlight",decorVehicle:"Vehicle",decorObserver:"Other observer",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",goToMilestone:"Go to this moment",confirmAccept:"Delete",confirmDecline:"Cancel",decorWidth:"Width",decorLength:"Length",decorHeight:"Height",decorModel:"3D model",decorModelNone:"Built-in shape",decorModelDefault:"Default model",decorModelAdvanced:"Model from an address",decorModelFromCatalogue:"From the catalogue, which the recording names it by. Change a field and it becomes this recording's own address.",decorModelUrl:"glTF/GLB address",decorModelTitle:"Model name",decorModelAuthor:"Author",decorModelLicense:"Licence",decorModelSource:"Where it came from",decorFloors:"Floors",decorOccupiedFloor:"Occupied floor",decorObserverSide:"Observer location",decorObserverSideNone:"Not present",decorWindows:"Windows",decorSideFront:"Front",decorSideBehind:"Behind",decorSideLeft:"Left",decorSideRight:"Right",decorSideFrontLeft:"Front-left",decorSideFrontRight:"Front-right",decorSideBehindLeft:"Behind-left",decorSideBehindRight:"Behind-right"},Hc={...tI,accountBy:"Account by",unnamedObserver:"Observer {n}",about:"About",close:"Close",observation:"Observation",date:"Date",location:"Location",case:"Case",description:"Description",source:"Source",basis:{stated:"stated",derived:"derived",assumed:"assumed"},credits:"Credits",editThisObservation:"Edit this observation",embed:"Embed",embedReplay:"Player",embedEdit:"Editor",share:"Share",embedObservation:"Embed the observation",back:"Back",embedCopy:"Copy",shareLink:"Link",shareStartAt:"Start at",shareOptionLabels:"Show summary chips",shareOptionMap:"Open map",shareOptionMilestones:"Show moments",shareOptionCompare:"Compare account",embedCopied:"Copied",showLabels:"Show what it states",interpretation:"Interpretation",account:"Account",interpretationBy:"{title}, by {by}",confrontation:"Against the account",confrontationDirection:"{deg}° off",confrontationWidth:"width ×{ratio}",confrontationHeight:"height ×{ratio}",showComparison:"Compare with the account",hideComparison:"Stop comparing with the account",hideLabels:"Hide what it states"},eI=Object.freeze(Object.defineProperty({__proto__:null,sightingMessages_en:Hc},Symbol.toStringTag,{value:"Module"}));hy();class $u{static PRODUCTION="https://ufoathome.org";static home(){try{const t=new URL(import.meta.url),e=new URL(location.href);return(e.hostname==="localhost"||e.hostname==="127.0.0.1"||e.hostname==="[::1]"||e.hostname.endsWith(".localhost"))&&t.origin===e.origin?e.origin:$u.PRODUCTION}catch{return $u.PRODUCTION}}}const jh=$u.home(),Nh="compare-account",kh="start-time",Gf="account",Vf=`${jh}/edit/`;class qo extends HTMLElement{static get observedAttributes(){return["src","show-labels",kh,ks,Fs,Nh]}shadow;sceneElement;toolbarElement;accountElement;accountPrefix;observerText;observerSelect;infoButton;infoPanel;infoAppLink;editLink;infoObservationHeading;infoObservationList;infoCreditsToggle;infoCreditsList;infoCloseButton;shareButton;shareDialog;shareTitle;shareLinkOption;shareLinkLabel;shareLinkBox;shareEmbed;shareClose;shareEmbedOption;shareEmbedLabel;shareLink;shareReplayOptions;embedCode;shareCopy;shareStartOn;shareStart;shareStartLabel;shareOptions;embedReplayRadio;embedEditRadio;labelEmbedReplay;labelEmbedEdit;embedMarkup;embedCopyButton;labelsToggle;paramSummary;summaryBuilder=new sl(Hc,new Xu,new Yn(["en"]),new zh({}),{messages:Hc,locale:"en"});summarySignature="";assessmentEntries=[];assessmentToken=0;supportsPopover=typeof HTMLElement.prototype.showPopover=="function";entries=[];caseSource;interpretationChoice;interpretationLabel;interpretationSelect;confrontationElement;confrontationHeading;confrontationList;compareButton;interpretationLoaders=new Map;interpretationToken=0;offeredFor;currentSrc;infoOpen=!1;creditsOpen=!1;labelsShown=!1;language="en";messages=Hc;constructor(){super(),this.shadow=this.attachShadow({mode:"open"});const t=document.createElement("template");t.innerHTML=`<style>${by}</style>${xy}`,this.shadow.appendChild(t.content.cloneNode(!0)),this.sceneElement=document.createElement(qu),this.forwardPlayerAttributes(),this.sceneElement.ufoElement.creditShownExternally=!0,this.sceneElement.ownCredits=!1,this.shadow.getElementById("ufo-slot").replaceWith(this.sceneElement),this.toolbarElement=this.shadow.getElementById("toolbar"),this.accountElement=this.shadow.getElementById("account"),this.accountPrefix=this.shadow.getElementById("account-prefix"),this.observerText=this.shadow.getElementById("observer-text"),this.observerSelect=this.shadow.getElementById("observer"),this.infoButton=this.shadow.getElementById("info-button"),this.infoPanel=this.shadow.getElementById("info-panel"),this.infoAppLink=this.shadow.getElementById("info-app-link"),this.editLink=this.shadow.getElementById("edit-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.shareButton=document.createElement("button"),this.shareButton.type="button",this.shareButton.id="share-button",this.shareButton.setAttribute("aria-haspopup","dialog"),this.shareButton.innerHTML=Gt.SHARE,this.sceneElement.ufoElement.addControl(this.shareButton),this.shareDialog=this.shadow.getElementById("share-dialog"),this.shareTitle=this.shadow.getElementById("share-title"),this.shareLinkOption=this.shadow.getElementById("share-link-option"),this.shareLinkLabel=this.shadow.getElementById("share-link-label"),this.shareLinkBox=this.shadow.querySelector(".share-link"),this.shareEmbed=this.shadow.getElementById("share-embed"),this.shareClose=this.shadow.getElementById("share-close"),this.shareEmbedOption=this.shadow.getElementById("share-embed-option"),this.shareEmbedLabel=this.shadow.getElementById("share-embed-label"),this.shareLink=this.shadow.getElementById("share-link"),this.shareReplayOptions=this.shadow.getElementById("share-replay-options"),this.embedCode=this.shadow.getElementById("embed-code"),this.shareCopy=this.shadow.getElementById("share-copy"),this.shareStartOn=this.shadow.getElementById("share-start-on"),this.shareStart=this.shadow.getElementById("share-start"),this.shareStartLabel=this.shadow.getElementById("share-start-label");const e=i=>({input:this.shadow.getElementById(`share-opt-${i}`),label:this.shadow.getElementById(`share-opt-${i}-label`)});this.shareOptions={labels:e("labels"),map:e("map"),milestones:e("milestones"),compare:e("compare")},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.interpretationChoice=this.shadow.getElementById("interpretation-choice"),this.interpretationLabel=this.shadow.getElementById("interpretation-label"),this.interpretationSelect=this.shadow.getElementById("interpretation"),this.confrontationElement=this.shadow.getElementById("confrontation"),this.confrontationHeading=this.shadow.getElementById("confrontation-heading"),this.confrontationList=this.shadow.getElementById("confrontation-list"),this.compareButton=this.shadow.getElementById("compare-account"),this.compareButton.addEventListener("click",()=>this.setComparing(!this.sceneElement.compareAccount)),this.observerSelect.addEventListener("change",()=>this.selectObserver(this.observerSelect.value)),this.interpretationSelect.addEventListener("change",()=>void this.chooseInterpretation(this.interpretationSelect.value)),this.sceneElement.addEventListener(ly,i=>this.showConfrontation(i.detail)),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",i=>{i.newState==="open"&&(this.populateInfoPanel(),this.bringInfoButtonIntoView())}),this.infoPanel.addEventListener("toggle",i=>this.syncInfoOpen(i.newState==="open"))):this.infoButton.addEventListener("click",()=>this.toggleInfoPanel()),this.infoCloseButton.addEventListener("click",()=>this.toggleInfoPanel()),this.infoCreditsToggle.addEventListener("click",()=>this.toggleCredits()),this.shareButton.addEventListener("click",()=>this.openShare()),this.shareClose.addEventListener("click",()=>this.closeShare()),this.shareLinkOption.addEventListener("click",()=>this.showShareView("link")),this.shareEmbedOption.addEventListener("click",()=>this.showShareView("embed"));for(const i of[this.shareStartOn,this.shareStart,...Object.values(this.shareOptions).map(n=>n.input)])i.addEventListener("input",()=>this.refreshShareLinks());this.shareCopy.addEventListener("click",()=>void this.copyText(this.shareLink.value,this.shareLink,this.shareCopy)),this.shareDialog.addEventListener("click",i=>{i.target===this.shareDialog&&this.closeShare()});for(const i of[this.embedReplayRadio,this.embedEditRadio])i.addEventListener("change",()=>this.refreshShareLinks());this.embedCopyButton.addEventListener("click",()=>void this.copyEmbedMarkup()),this.isConnected&&this.loadLocaleMessages()}get scene(){return this.sceneElement}async loadLocaleMessages(){const t=++this.localeToken,e=Gr.preferencesFor(this);this.preferences=e;const i=Ep(e,Ap),[n,s,r]=i==="en"?[Hc,{},void 0]:await Promise.all([ub(i),db(i),bM(i)]);if(t!==this.localeToken)return;const o=i!==this.language;this.language=i,this.messages=n,this.tags=new zh(s),this.said=new Yn(e),this.summaryBuilder=new sl(this.messages,new Xu(r),this.said,this.tags,{messages:this.messages,locale:i}),this.accountPrefix.textContent=this.messages.accountBy,this.interpretationLabel.textContent=this.messages.interpretation,this.confrontationHeading.textContent=this.messages.confrontation;const c=this.entries.find(l=>l.src===this.currentSrc);c&&this.offerInterpretations(c),this.updateCompareButton(),this.infoButton.title=this.messages.about,this.infoButton.setAttribute("aria-label",this.messages.about),this.editLink.title=this.messages.editThisObservation,this.editLink.setAttribute("aria-label",this.messages.editThisObservation),this.infoCloseButton.setAttribute("aria-label",this.messages.close),this.infoObservationHeading.textContent=this.messages.observation,this.infoCreditsToggle.textContent=this.messages.credits,this.syncLabelsToggle(),this.refreshParamSummary(),o&&this.currentSrc&&this.runAssessments(),this.shareButton.title=this.messages.share,this.shareButton.setAttribute("aria-label",this.messages.share),this.shareClose.setAttribute("aria-label",this.messages.close),this.shareCopy.textContent=this.messages.embedCopy,this.shareStartLabel.textContent=this.messages.shareStartAt,this.shareOptions.labels.label.textContent=this.messages.shareOptionLabels,this.shareOptions.map.label.textContent=this.messages.shareOptionMap,this.shareOptions.milestones.label.textContent=this.messages.shareOptionMilestones,this.shareOptions.compare.label.textContent=this.messages.shareOptionCompare,this.shareStart.setAttribute("aria-label",this.messages.shareStartAt),this.shareEmbedLabel.textContent=this.messages.embed,this.shareLinkLabel.textContent=this.messages.shareLink,this.shareTitle.textContent=this.messages.share,this.labelEmbedReplay.textContent=this.messages.embedReplay,this.labelEmbedEdit.textContent=this.messages.embedEdit,this.embedCopyButton.textContent=this.messages.embedCopy,this.infoOpen&&this.populateInfoPanel(),this.updateAccountLine()}preferences=[];localeToken=0;said=new Yn(["en"]);tags=new zh({});connectedCallback(){Gr.preferencesFor(this).join()!==this.preferences.join()&&this.loadLocaleMessages();const t=this.getAttribute("src");t&&this.loadFromSrc(t)}disconnectedCallback(){document.removeEventListener("click",this.handleOutsideClick)}attributeChangedCallback(t,e,i){t==="src"&&i&&i!==e&&this.isConnected&&this.loadFromSrc(i),t==="show-labels"&&this.applyLabels(this.hasAttribute("show-labels")),(t===ks||t===Fs)&&this.forwardPlayerAttributes(),t===Nh&&this.setComparing(this.hasAttribute(Nh))}forwardPlayerAttributes(){for(const t of[ks,Fs]){const e=this.getAttribute(t);e===null?this.sceneElement.removeAttribute(t):this.sceneElement.setAttribute(t,e)}}async loadFromSrc(t){this.startPending=!0;const e=Gc.json(t);this.sceneElement.holdForNewScene(e);const i=await e;if(Array.isArray(i))throw new Error(`${t} is a bare list of recordings, which is no longer read: list them as the sighting events of a case.json`);if(cs.isCase(i)){const n=cs.sightingUrls(i,new URL(t,location.href).href);if(n.length===0)throw new Error(`${t} is a case with no sighting event: no recording to show`);await this.loadObserverUrls(n,{json:i,url:new URL(t,location.href).href})}else this.setEntries([{src:t,sighting:i}],void 0)}get sightingData(){return this.entries.find(t=>t.src===this.currentSrc)?.sighting}set sightingData(t){this.startPending=!0,this.currentSrc="",this.setEntries([{src:"",sighting:t}],void 0)}get observerUrls(){return this.entries.map(t=>t.src)}set observerUrls(t){this.loadObserverUrls(t)}async loadObserverUrls(t,e){const i=await Promise.all(t.map(async n=>({src:n,sighting:await Gc.json(n)})));this.setEntries(i,e)}setEntries(t,e){this.entries=t,this.caseSource=e,this.toolbarElement.hidden=t.length===0;const i=t.length>1;this.observerSelect.hidden=!i,this.observerText.hidden=i,this.observerSelect.innerHTML="";for(const s of t){const r=document.createElement("option");r.value=s.src,r.textContent=this.observerDisplayName(this.plain(s).observer)??this.messages.unnamedObserver.replace("{n}",String(t.indexOf(s)+1)),this.observerSelect.appendChild(r)}const n=t.find(s=>s.src===this.currentSrc)??t[0];n?this.selectObserver(n.src):this.updateAccountLine()}editorUrl(){if(!this.currentSrc)return Vf;const t=new URL(this.currentSrc,location.href),e=this.caseSource;return e?`${Vf}?file=${encodeURIComponent(e.url)}&track=${encodeURIComponent(this.shownTrackUrl()??t.href)}`:`${Vf}?file=${encodeURIComponent(t.href)}`}get editorHref(){return this.editorUrl()}shownTrackUrl(){const t=this.caseSource,e=this.entries.find(s=>s.src===this.currentSrc),i=/^case-(\d+)$/.exec(this.interpretationSelect.value);if(!t||!e||!i)return;const n=cs.interpretationEvents(t.json,this.plain(e).id)[Number(i[1])];return n?.url?new URL(n.url,t.url).href:void 0}embedMarkupFor(t){const e=t==="edit"?"rr0-sighting-editor":"rr0-sighting",i=new URL(`${e}.mjs`,import.meta.url).href,n=this.currentSrc?new URL(this.currentSrc,location.href).href:"",s=t==="replay"?this.replayAttributes().map(([r,o])=>o===""?` ${r}`:` ${r}="${o}"`).join(""):"";return`<script type="module" src="${i}"><\/script>
8761
- <${e} src="${n}"${s}></${e}>`}refreshEmbedMarkup(){const t=this.embedMarkupFor(this.embedEditRadio.checked?"edit":"replay");this.embedMarkup.value=t,this.shareCodeEditor&&(this.shareCodeEditor.text=t)}async copyText(t,e,i){try{await navigator.clipboard.writeText(t),i.textContent=this.messages.embedCopied,window.setTimeout(()=>i.textContent=this.messages.embedCopy,1500)}catch{e.select()}}async copyEmbedMarkup(){await this.copyText(this.shareCodeEditor?.text??this.embedMarkup.value,this.embedMarkup,this.embedCopyButton)}playUrl(){const t=this.replayQuery().join("&");return this.currentSrc?`${jh}/play/?file=${encodeURIComponent(new URL(this.currentSrc,location.href).href)}${t&&"&"+t}`:`${jh}/play/${t&&"?"+t}`}replayAttributes(){const t=this.shareOptions,e=[];return this.shareStartSeconds!==void 0&&e.push([kh,String(this.shareStartSeconds)]),t.labels.input.checked&&e.push(["show-labels",""]),t.map.input.checked&&e.push([ks,""]),t.milestones.input.checked||e.push([Fs,""]),t.compare.input.checked&&e.push([Nh,""]),e}replayQuery(){const t=this.shareOptions,e=[];return this.shareStartSeconds!==void 0&&e.push(`t=${this.shareStartSeconds}`),t.labels.input.checked||e.push("labels=0"),t.map.input.checked&&e.push("map=1"),t.milestones.input.checked||e.push("moments=0"),t.compare.input.checked&&e.push("compare=1"),e}get shareStartSeconds(){const t=Math.floor(Number(this.shareStart.value));return this.shareStartOn.checked&&Number.isFinite(t)&&t>=0?t:void 0}refreshShareLinks(){const t=this.embedEditRadio.checked;this.shareReplayOptions.disabled=t,this.shareLink.value=t?this.editorUrl():this.playUrl(),this.fitShareLink(),this.refreshEmbedMarkup()}fitShareLink(){this.shareLink.style.height="auto",this.shareLink.style.height=`${this.shareLink.scrollHeight}px`}shareCodeEditor;shareCodeLoading;loadShareCode(){this.shareCodeLoading??=je(async()=>{const{ShareCodeEditor:t}=await import("./ShareCodeEditor-C53SBK2N.js");return{ShareCodeEditor:t}},[],import.meta.url).then(({ShareCodeEditor:t})=>{this.shareCodeEditor=new t(this.embedCode,this.embedMarkup.value,e=>{this.embedMarkup.value=e},this.messages.embed),this.embedMarkup.hidden=!0}).catch(()=>{this.shareCodeLoading=void 0})}openShare(){const t=this.sceneElement.ufoElement;this.shareStart.max=String(Math.floor(t.seekableDuration/1e3)),this.shareStart.value=String(Math.floor(t.currentTime/1e3)),this.shareStartOn.checked=!1,this.shareOptions.labels.input.checked=this.labelsShown,this.shareOptions.map.input.checked=t.observerMapOpen,this.shareOptions.milestones.input.checked=t.milestonesVisible,this.shareOptions.compare.input.checked=this.sceneElement.compareAccount,this.refreshShareLinks(),this.showShareView("link"),typeof this.shareDialog.showModal=="function"?this.shareDialog.showModal():this.shareDialog.setAttribute("open",""),this.fitShareLink(),this.shareLink.select()}closeShare(){typeof this.shareDialog.close=="function"?this.shareDialog.close():this.shareDialog.removeAttribute("open")}showShareView(t){this.shareLinkBox.hidden=t!=="link",this.shareEmbed.hidden=t!=="embed",this.shareLinkOption.setAttribute("aria-pressed",String(t==="link")),this.shareEmbedOption.setAttribute("aria-pressed",String(t==="embed")),t==="embed"?this.loadShareCode():this.fitShareLink()}offerInterpretations(t){const e=this.offeredFor===t.sighting,i=this.interpretationSelect.value;this.offeredFor=t.sighting,this.interpretationToken++,this.interpretationLoaders=new Map,this.interpretationSelect.innerHTML="";const n=(l,h,u)=>{const d=document.createElement("option");d.value=l,d.textContent=h,this.interpretationSelect.appendChild(d),this.interpretationLoaders.set(l,u)},s=t===this.entries.find(l=>l.src===this.currentSrc)?this.sceneElement.ufoElement.sighting.interpretation:void 0;n(Gf,this.messages.account,()=>Promise.resolve(s));const r=this.caseSource;r&&cs.interpretationEvents(r.json,this.plain(t).id).forEach((l,h)=>{const u=this.said.read(l.title)??`#${h+1}`,d=(l.by??[]).map(f=>this.agentName(f)).filter(Boolean).join(", ");n(`case-${h}`,d?this.messages.interpretationBy.replace("{title}",u).replace("{by}",d):u,()=>cs.interpretationOf(l,r.url,f=>Gc.json(f)))});const c=e&&[...this.interpretationSelect.options].some(l=>l.value===i)?i:Gf;this.interpretationSelect.value=c,c===Gf?this.sceneElement.interpretation!==s&&(this.sceneElement.interpretation=s):this.sceneElement.interpretation||this.chooseInterpretation(c),this.interpretationChoice.hidden=this.interpretationSelect.options.length<2,this.showConfrontation(this.sceneElement.confrontation),this.updateCompareButton()}setComparing(t){this.sceneElement.compareAccount=t,this.updateCompareButton(),this.showConfrontation(this.sceneElement.confrontation)}updateCompareButton(){const t=this.sceneElement.compareAccount;this.compareButton.hidden=!this.sceneElement.interpretation,this.compareButton.setAttribute("aria-pressed",String(t));const e=t?this.messages.hideComparison:this.messages.showComparison;this.compareButton.title=e,this.compareButton.setAttribute("aria-label",e)}static DATE_LOCALES={en:"en-US",fr:"fr-FR",es:"es-ES",it:"it-IT"};get colon(){return this.language==="fr"?" : ":": "}async chooseInterpretation(t){const e=++this.interpretationToken,i=this.interpretationLoaders.get(t),n=i?await i().catch(s=>{console.warn(`<rr0-sighting>: could not read interpretation "${t}":`,s)}):void 0;e===this.interpretationToken&&(this.sceneElement.interpretation=n,this.editLink.href=this.editorUrl(),this.dispatchEvent(new CustomEvent("interpretationchange",{detail:{track:this.shownTrackUrl()}})),this.updateCompareButton(),this.showConfrontation(this.sceneElement.confrontation))}agentName(t){if("people"in t){const[e,...i]=t.people.replace(/([a-z])([A-Z])/g,"$1 $2").split(" ");return[...i,e].join(" ")}return"org"in t?t.org.replace(/([a-z])([A-Z])/g,"$1 $2"):this.observerDisplayName(t)??""}showConfrontation(t){this.confrontationList.innerHTML="",this.confrontationElement.hidden=!this.sceneElement.interpretation||!this.sceneElement.compareAccount;const e=new Intl.NumberFormat(this.language,{maximumFractionDigits:1,minimumFractionDigits:1}),i=new Intl.NumberFormat(this.language,{maximumFractionDigits:2,minimumFractionDigits:2});for(const n of t){const s=document.createElement("li");s.append(`${this.said.read(n.title)??n.sourceId}${this.colon}`);const r=[];n.separationDeg!==void 0&&r.push([this.messages.confrontationDirection.replace("{deg}",e.format(n.separationDeg)),n.disagreements.includes("direction")]),n.widthRatio!==void 0&&r.push([this.messages.confrontationWidth.replace("{ratio}",i.format(n.widthRatio)),n.disagreements.includes("width")]),n.heightRatio!==void 0&&r.push([this.messages.confrontationHeight.replace("{ratio}",i.format(n.heightRatio)),n.disagreements.includes("height")]),r.forEach(([o,c],l)=>{l>0&&s.append(" · ");const h=document.createElement("span");h.textContent=o,c&&(h.className="disagrees"),s.append(h)}),this.confrontationList.appendChild(s)}}startPending=!1;selectObserver(t){const e=this.entries.find(i=>i.src===t);if(e){if(this.currentSrc=t,this.observerSelect.value=t,this.sceneElement.documentUrl=e.src?new URL(e.src,location.href).href:void 0,this.sceneElement.holdForNewScene(),this.sceneElement.sightingData=e.sighting,this.startPending){this.startPending=!1;const i=Number(this.getAttribute(kh));this.hasAttribute(kh)&&Number.isFinite(i)&&(this.sceneElement.ufoElement.currentTime=Math.max(0,i)*1e3)}this.offerInterpretations(e),this.updateAccountLine(),this.refreshParamSummary(),this.runAssessments(),this.infoOpen&&this.populateInfoPanel(),this.dispatchEvent(new CustomEvent(iI,{detail:{src:t}}))}}async runAssessments(){const t=++this.assessmentToken,e=await new Hx(this.messages).read(this.sceneElement.ufoElement.sighting);t===this.assessmentToken&&(this.assessmentEntries=e.entries,this.refreshParamSummary())}updateAccountLine(){const t=this.entries.find(n=>n.src===this.currentSrc),e=t?this.observerDisplayName(this.plain(t).observer):void 0,i=e!==void 0||this.entries.length>1;this.accountElement.hidden=!i,this.observerText.textContent=e??"",this.editLink.hidden=!this.currentSrc,this.editLink.href=this.editorUrl(),this.editLink.title=this.messages.editThisObservation,this.editLink.setAttribute("aria-label",this.messages.editThisObservation)}observerDisplayName(t){if(!t)return;const e=[...t.firstNames??[],t.lastName].filter(Boolean).join(" ");return t.title||e||t.id}plainRecordings=new WeakMap;plain(t){return this.stripped(t).recording}stripped(t){let e=this.plainRecordings.get(t.sighting);return e||(e=hn.strip(t.sighting),this.plainRecordings.set(t.sighting,e)),e}basisOf(t,e){const i=this.stripped(t).provenance,n={stated:0,derived:1,assumed:2},s=i.paths().filter(c=>e.some(l=>c===l||c.startsWith(`${l}.`))).map(c=>i.at(c)),r=s.reduce((c,l)=>n[l.basis]>n[c]?l.basis:c,"stated"),o=s.filter(c=>c.basis===r&&c.rationale).map(c=>c.rationale);return{basis:r,rationales:o}}formatDate(t){const e=t.place?.[0],i=ra(t.time??{},e?.lng??0,t.utcOffsetHours);if(!i)return;const n=i.getTime()+this.utcOffsetHoursOf(t,e?.lng??0)*36e5;if(Number.isFinite(n))return new Intl.DateTimeFormat(qo.DATE_LOCALES[this.language],{dateStyle:"long",timeStyle:"short",timeZone:"UTC"}).format(new Date(n))}utcOffsetHoursOf(t,e){return t.utcOffsetHours??Math.round(e/15)}formatLocation(t){const e=t.place?.[0];if(e)return`${e.lat.toFixed(4)}, ${e.lng.toFixed(4)}`}toggleInfoPanel(){const t=!this.infoOpen;if(this.supportsPopover){const e=this.infoPanel.matches(":popover-open");t&&!e?this.infoPanel.showPopover():!t&&e&&this.infoPanel.hidePopover();return}t&&this.bringInfoButtonIntoView(),this.syncInfoOpen(t),this.infoPanel.hidden=!t,t?document.addEventListener("click",this.handleOutsideClick):document.removeEventListener("click",this.handleOutsideClick)}bringInfoButtonIntoView(){const t=this.infoButton.getBoundingClientRect(),e=window.innerHeight||document.documentElement.clientHeight;t.top>=0&&t.bottom<=e||this.infoButton.scrollIntoView({block:"center"})}syncInfoOpen(t){t!==this.infoOpen&&(this.infoOpen=t,this.infoButton.setAttribute("aria-expanded",String(t)),t?this.supportsPopover||this.populateInfoPanel():(this.creditsOpen=!1,this.infoCreditsList.hidden=!0,this.infoCreditsToggle.setAttribute("aria-expanded","false")))}handleOutsideClick=t=>{const e=t.composedPath();!e.includes(this.infoPanel)&&!e.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)}revealInPanel(t){t.scrollIntoView?.({block:"nearest"})}get showLabels(){return this.labelsShown}set showLabels(t){this.toggleAttribute("show-labels",t)}applyLabels(t){this.labelsShown=t,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 t=this.sceneElement.ufoElement.sighting,e=[...this.summaryBuilder.entriesFor(t,this.sceneElement.ufoElement.currentTime,{roadGradeDeg:this.sceneElement.roadGradeDeg}),...this.assessmentEntries],i=e.map(r=>`${r.field}=${r.label}=${r.value}${r.unit}${r.full??""}${r.fromSource?"*":""}`).join("|");if(i===this.summarySignature)return;this.summarySignature=i;const n=[];let s;for(const r of e){s&&s.group!==r.group&&(s=void 0);const o=r.group==="summary"?this.messages.summaryGroup:r.group==="observer"?this.messages.observerGroup:r.group in this.messages.summaryGroups?this.messages.summaryGroups[r.group]:r.group==="assessment"?this.messages.assessmentGroup:void 0;if(o!==void 0&&!s){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),s={group:r.group,element:l},n.push(l)}const c=this.paramItem(r);s?s.element.append(c):n.push(c)}this.paramSummary.replaceChildren(...n),this.syncDescription(e)}openDescription;syncDescription(t){this.openDescription!==void 0&&!t.some(e=>e.full===this.openDescription)&&(this.openDescription=void 0),iM.sync(this.paramSummary,this.openDescription,this.messages.summaryDescription,this.messages.closeDescription,()=>{this.openDescription=void 0,this.syncDescription(t)})}paramItem(t){const e=document.createElement("span");if(e.className=t.fromSource?"param-label from-source":"param-label",t.full!==void 0){e.classList.add("describable"),e.tabIndex=0,e.setAttribute("role","button");const s=()=>{this.openDescription=t.full,this.syncDescription([t])};e.addEventListener("click",s),e.addEventListener("keydown",r=>{(r.key==="Enter"||r.key===" ")&&(r.preventDefault(),s())})}const i=document.createElement("span");if(i.className="param-label-label",i.textContent=`${t.label} `,e.append(i),t.color!==void 0){const s=document.createElement("span");s.className="param-label-swatch",s.style.background=t.color,e.append(s)}const n=document.createElement("span");return n.className="param-label-value",n.textContent=t.unit===""?t.value:`${t.value} ${t.unit}`,e.append(n),e}populateInfoPanel(){const t=this.entries.find(e=>e.src===this.currentSrc);if(this.infoObservationList.innerHTML="",t){const e=this.caseSource&&(this.caseSource.json.title??this.caseSource.json.id);if(e&&this.appendInfoRow(this.infoObservationList,this.messages.case,e),!this.labelsShown){const s=this.formatDate(this.plain(t));s&&this.appendInfoRow(this.infoObservationList,this.messages.date,s,this.basisOf(t,qo.DATE_PATHS));const r=this.formatLocation(this.plain(t));r&&this.appendInfoRow(this.infoObservationList,this.messages.location,r,this.basisOf(t,qo.PLACE_PATHS))}const i=this.said.read(this.plain(t).description);i&&!this.labelsShown&&this.appendInfoRow(this.infoObservationList,this.messages.description,i);for(const s of this.plain(t).sources??[])this.appendInfoSource(this.infoObservationList,this.messages.source,s);const n=this.plain(t).tags;!this.labelsShown&&n&&n.length>0&&this.appendInfoRow(this.infoObservationList,this.messages.tags,n.map(s=>this.tags.name(s)).join(", "))}this.refreshEmbedMarkup(),this.infoAppLink.href=jh,this.infoAppLink.textContent="UFO@home v0.104.1",rn.fill(this.infoCreditsList,this.sceneElement)}appendInfoSource(t,e,i){const n=document.createElement("dt");n.textContent=e;const s=document.createElement("dd"),r=i.title??i.url??"";if(i.url&&/^https?:\/\//i.test(i.url)){const c=document.createElement("a");c.href=i.url,c.target="_blank",c.rel="noopener noreferrer",c.textContent=r,s.appendChild(c)}else s.append(r);const o=[i.authors?.join(", "),i.publication?.publisher,i.publication?.time,i.index].filter(Boolean);o.length>0&&s.append(`, ${o.join(", ")}`),t.append(n,s)}static DATE_PATHS=["time","utcOffsetHours","timeZone"];static PLACE_PATHS=["place.0"];appendInfoRow(t,e,i,n){const s=document.createElement("dt");s.textContent=e;const r=document.createElement("dd");if(r.textContent=i,n){const o=document.createElement("span");o.className=`basis basis-${n.basis}`,o.textContent=this.messages.basis[n.basis],n.rationales.length>0&&(o.title=n.rationales.join(`
8760
+ `);let s=_s.cache.get(n);return s||(s=Promise.all(i.map(r=>_s.load(r.url))).then(r=>r.reduce((o,c)=>_s.concat(o,c))),_s.cache.set(n,s)),s}static parse(t){const e=t.byteLength/(4*Float32Array.BYTES_PER_ELEMENT),i=e*Float32Array.BYTES_PER_ELEMENT;return{count:e,ra:new Float32Array(t,0*i,e),dec:new Float32Array(t,1*i,e),mag:new Float32Array(t,2*i,e),ci:new Float32Array(t,3*i,e)}}static concat(t,e){const i=(n,s)=>{const r=new Float32Array(n.length+s.length);return r.set(n,0),r.set(s,n.length),r};return{count:t.count+e.count,ra:i(t.ra,e.ra),dec:i(t.dec,e.dec),mag:i(t.mag,e.mag),ci:i(t.ci,e.ci)}}}class Ie{constructor(t){if(this.heights=t,t.length!==Ie.WIDTH*Ie.HEIGHT)throw new Error(`a lunar relief has ${Ie.WIDTH*Ie.HEIGHT} samples, not ${t.length}`)}static SAMPLES_PER_DEGREE=16;static WIDTH=360*Ie.SAMPLES_PER_DEGREE;static HEIGHT=180*Ie.SAMPLES_PER_DEGREE;static UNIT_KM=.1;static REFERENCE_RADIUS_KM=1737.4;static BAND_FROM_DEG=74;static BAND_TO_DEG=106;heightKm(t,e){const i=Ie.SAMPLES_PER_DEGREE,n=(e%360+360)%360*i-.5,s=(90-t)*i-.5,r=Math.floor(n),o=Math.floor(s),c=n-r,l=s-o,h=(f,p)=>{const v=(f%Ie.WIDTH+Ie.WIDTH)%Ie.WIDTH,m=Math.min(Ie.HEIGHT-1,Math.max(0,p));return this.heights[m*Ie.WIDTH+v]},u=h(r,o)*(1-c)+h(r+1,o)*c,d=h(r,o+1)*(1-c)+h(r+1,o+1)*c;return(u*(1-l)+d*l)*Ie.UNIT_KM}static inBand(t,e){const i=Math.PI/180,n=Math.acos(Math.cos(t*i)*Math.cos(e*i))*180/Math.PI;return n>=Ie.BAND_FROM_DEG&&n<=Ie.BAND_TO_DEG}static withBump(t,e,i,n=.4){const s=new Int8Array(Ie.WIDTH*Ie.HEIGHT),r=Ie.SAMPLES_PER_DEGREE,o=Math.ceil(n*r),c=Math.floor(e*r),l=Math.floor((90-t)*r);for(let h=-o;h<=o;h++)for(let u=-o;u<=o;u++)Math.hypot(u,h)<=o&&(s[(l+h)*Ie.WIDTH+(c+u+Ie.WIDTH)%Ie.WIDTH]=Math.round(i/Ie.UNIT_KM));return new Ie(s)}static smooth(){return new Ie(new Int8Array(Ie.WIDTH*Ie.HEIGHT))}}class Vn{static SAMPLES=5760;static SEARCH_FROM_DEG=87;static SEARCH_TO_DEG=90.2;static SEARCH_STEP_DEG=.0625;static profile(t,e,i,n=Vn.SAMPLES){const{s,u:r,w:o,distanceKm:c}=Vn.frame(t,e),l=Math.PI/180,h=new Float32Array(n),u=Ie.REFERENCE_RADIUS_KM;for(let d=0;d<n;d++){const f=d/n*2*Math.PI,p=Math.cos(f),v=Math.sin(f),m=p*r[0]+v*o[0],g=p*r[1]+v*o[1],b=p*r[2]+v*o[2];let S=0;for(let M=Vn.SEARCH_FROM_DEG;M<=Vn.SEARCH_TO_DEG;M+=Vn.SEARCH_STEP_DEG){const x=Math.cos(M*l),_=Math.sin(M*l),A=x*s[0]+_*m,y=x*s[1]+_*g,T=x*s[2]+_*b,I=Math.asin(Math.max(-1,Math.min(1,T)))/l,C=Math.atan2(y,A)/l,P=u+i.heightKm(I,C),B=Math.atan2(P*_,c-P*x);B>S&&(S=B)}h[d]=S/l}return{radiusDeg:h,meanRadiusDeg:Math.asin(u/c)/l}}static frame(t,e){const i=new qr(e.lat,e.lng,e.elevationM),n=ur(t),s=np(t,i,!1),r=new ge(s.x-n.x,s.y-n.y,s.z-n.z,n.t),o=Math.hypot(r.x,r.y,r.z)*Vn.AU_KM,c=Vn.bodyFixed(t),l=c(r),h=Math.hypot(l[0],l[1],l[2]),u=[l[0]/h,l[1]/h,l[2]/h],d=h4(t,i),f=cm(d),p=cr(d,new ge(-r.x,-r.y,-r.z,n.t)),v=Math.asin(p.z/Math.hypot(p.x,p.y,p.z)),m=Math.atan2(-p.y,p.x),g=new ge(-Math.sin(v)*Math.cos(m),Math.sin(v)*Math.sin(m),Math.cos(v),n.t),b=new ge(-Math.sin(m),-Math.cos(m),0,n.t);return{s:u,u:c(cr(f,g)),w:c(cr(f,b)),distanceKm:o}}static surfacePoint(t,e,i,n){const{s,u:r,w:o}=Vn.frame(t,e),c=Math.PI/180,l=[0,1,2].map(u=>Math.cos(i*c)*r[u]+Math.sin(i*c)*o[u]),h=[0,1,2].map(u=>Math.cos(n*c)*s[u]+Math.sin(n*c)*l[u]);return{latDeg:Math.asin(h[2])/c,lonDeg:Math.atan2(h[1],h[0])/c}}static radiusAt(t,e){const i=t.radiusDeg.length,n=(e/360*i%i+i)%i,s=Math.floor(n),r=n-s;return t.radiusDeg[s]*(1-r)+t.radiusDeg[(s+1)%i]*r}static uncoveredFraction(t,e,i){const n=t.radiusDeg.length,s=i.upDeg*i.upDeg+i.rightDeg*i.rightDeg;let r=0;for(let o=0;o<n;o++){const c=o/n*2*Math.PI,l=Math.cos(c),h=Math.sin(c),u=l*i.upDeg+h*i.rightDeg,d=u*u-s+e*e;if(d<=0)continue;const f=Math.sqrt(d),p=u+f;if(p<=0)continue;const v=Math.max(0,u-f),m=Math.max(v,t.radiusDeg[o]);p>m&&(r+=.5*(p*p-m*m))}return Math.min(1,Math.max(0,r*(2*Math.PI/n)/(Math.PI*e*e)))}static AU_KM=1495978707e-1;static bodyFixed(t){const e=A4(ut.Moon,t),i=Math.PI/180,n=e.ra*15*i,s=e.dec*i,r=e.spin*i,o=(l,[h,u,d])=>[Math.cos(l)*h+Math.sin(l)*u,-Math.sin(l)*h+Math.cos(l)*u,d],c=(l,[h,u,d])=>[h,Math.cos(l)*u+Math.sin(l)*d,-Math.sin(l)*u+Math.cos(l)*d];return l=>o(r,c(Math.PI/2-s,o(Math.PI/2+n,[l.x,l.y,l.z])))}static subObserverPoint(t,e){const i=new qr(e.lat,e.lng,e.elevationM),n=ur(t),s=np(t,i,!1),r=Vn.bodyFixed(t)(new ge(s.x-n.x,s.y-n.y,s.z-n.z,n.t)),o=Math.hypot(r[0],r[1],r[2]);return{latDeg:Math.asin(r[2]/o)*180/Math.PI,lonDeg:Math.atan2(r[1],r[0])*180/Math.PI}}}class Qc{static cache=new Map;static load(t){let e=Qc.cache.get(t);return e||(e=Qc.fetchRelief(t).catch(()=>{}),Qc.cache.set(t,e)),e}static async fetchRelief(t){const e=await fetch(t);if(!e.ok)return;let i=new Uint8Array(await e.arrayBuffer());if(i[0]===31&&i[1]===139){if(typeof DecompressionStream>"u")return;const n=new Blob([i]).stream().pipeThrough(new DecompressionStream("gzip"));i=new Uint8Array(await new Response(n).arrayBuffer())}return new Ie(new Int8Array(i.buffer,i.byteOffset,i.length))}}class Xu{constructor(t){this.names=t}body(t,e){return this.names?.bodies[t]??e}star(t){return this.names?.stars[t.name]??t.name}comet(t){return this.names?.comets[t.id]??t.name}nova(t){return this.names?.novae[t.id]??t.name}satelliteClass(t){return this.names?.satelliteClasses[t.id]??t.name}shower(t){return this.names?.showers[t.id]??t.name}lightRig(t){return this.names?.lightRigs[t.id]??t.name}instrument(t){return this.names?.instruments[t.id]??t.name}decorKind(t,e){return this.names?.decorKinds[t]??e}point(t){return Na.point(t,this.names?.compassPoints)}towards(t){return Na.towards(t,this.names)}}const RD=new URL(""+new URL("rain-BvWZrB9h.ogg",import.meta.url).href,import.meta.url).href,DD=new URL(""+new URL("wind-BjklexY7.ogg",import.meta.url).href,import.meta.url).href,ID=new URL(""+new URL("thunder-DA48qs_v.wav",import.meta.url).href,import.meta.url).href,CD=20,PD=1;class OD{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};level=1;master;output(t){return this.master||(this.master=t.createGain(),this.master.gain.value=this.level,this.master.connect(t.destination)),this.master}setLevel(t){this.level=t,this.master&&(this.master.gain.value=t)}resume(){if(!this.context){if(typeof AudioContext>"u")return;try{this.context=new AudioContext}catch(t){console.warn("WeatherAudio: Web Audio unavailable, weather sounds disabled:",t);return}}Oa.unlock(this.context)}setAmbient(t,e,i){if(this.requested={type:t,intensity:e,windSpeed:i},!this.context)return;this.paused&&(t="none",e=0,i=0);const n=t==="rain"||t==="hail"?t:"none";if(this.ambientVolume=n==="hail"?Math.min(1,e*1.3+.2):n==="rain"?e:0,n!==this.ambientKey){this.ambientKey=n;const r=++this.ambientToken;this.stopSource(this.ambientSource,this.ambientGain),this.ambientSource=void 0,this.ambientGain=void 0,n!=="none"&&this.startLoop(RD,this.ambientVolume).then(o=>this.applyIfCurrent(o,r,()=>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(i/CD,1);const s=i>PD;if(s!==this.windActive){this.windActive=s;const r=++this.windToken;this.stopSource(this.windSource,this.windGain),this.windSource=void 0,this.windGain=void 0,s&&this.startLoop(DD,this.windVolume).then(o=>this.applyIfCurrent(o,r,()=>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(t){if(t===this.paused)return;this.paused=t;const{type:e,intensity:i,windSpeed:n}=this.requested;this.setAmbient(e,i,n)}playThunder(){!this.context||this.paused||this.playOneShot(ID,.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.master=void 0,this.buffers.clear()}applyIfCurrent(t,e,i,n){if(e!==i()){t?.source.stop();return}n(t)}async startLoop(t,e){const i=this.context;if(i)try{const n=await this.getBuffer(t),s=i.createBufferSource();s.buffer=n,s.loop=!0;const r=i.createGain();return r.gain.value=e,s.connect(r).connect(this.output(i)),s.start(),{source:s,gain:r}}catch(n){console.warn("Weather ambient sound failed to load, staying silent:",n);return}}async playOneShot(t,e){const i=this.context;if(i)try{const n=await this.getBuffer(t),s=i.createBufferSource();s.buffer=n;const r=i.createGain();r.gain.value=e,s.connect(r).connect(this.output(i)),s.start()}catch(n){console.warn("Thunder sound failed to load:",n)}}async getBuffer(t){const e=this.context;if(!e)throw new Error("WeatherAudio: AudioContext not ready — resume() must be called first");let i=this.buffers.get(t);return i||(i=fetch(t).then(n=>{if(!n.ok)throw new Error(`Audio fetch failed (${n.status}): ${t}`);return n.arrayBuffer()}).then(n=>e.decodeAudioData(n)),this.buffers.set(t,i)),i}stopSource(t,e){try{t?.stop()}catch{}t?.disconnect(),e?.disconnect()}}class nr{constructor(t){this.elements=t;const{eccentricity:e,perihelionAu:i}=t,[n,s]=this.perifocalAxes(),r=Math.sqrt(nr.SUN_GM_AU3_PER_DAY2*(1+e)/i);this.perihelionPosition=this.scale(n,i),this.perihelionVelocity=this.scale(s,r),this.inverseSemiMajorAxis=(1-e)/i}static SUN_GM_AU3_PER_DAY2=.0002959122082855911;static MAX_ITERATIONS=200;perihelionPosition;perihelionVelocity;inverseSemiMajorAxis;positionAt(t){const e=t-this.elements.perihelionJd,i=this.universalAnomaly(e),n=this.inverseSemiMajorAxis*i*i,s=this.elements.perihelionAu,r=1-i*i/s*nr.stumpffC(n),o=e-i*i*i/Math.sqrt(nr.SUN_GM_AU3_PER_DAY2)*nr.stumpffS(n);return{x:r*this.perihelionPosition.x+o*this.perihelionVelocity.x,y:r*this.perihelionPosition.y+o*this.perihelionVelocity.y,z:r*this.perihelionPosition.z+o*this.perihelionVelocity.z}}heliocentricDistanceAt(t){const e=this.positionAt(t);return Math.hypot(e.x,e.y,e.z)}universalAnomaly(t){if(t===0)return 0;const e=Math.sign(t),i=Math.sqrt(nr.SUN_GM_AU3_PER_DAY2)*Math.abs(t),n=o=>{const c=this.inverseSemiMajorAxis*o*o,l=this.elements.perihelionAu;return(1-this.inverseSemiMajorAxis*l)*o*o*o*nr.stumpffS(c)+l*o};let s=Math.max(1,i/this.elements.perihelionAu);for(;n(s)<i;)s*=2;let r=0;for(let o=0;o<nr.MAX_ITERATIONS&&s-r>1e-13*Math.max(1,s);o++){const c=(r+s)/2;n(c)<i?r=c:s=c}return e*(r+s)/2}perifocalAxes(){const t=this.elements.ascendingNodeDeg*Math.PI/180,e=this.elements.argumentOfPerihelionDeg*Math.PI/180,i=this.elements.inclinationDeg*Math.PI/180,n=Math.cos(t),s=Math.sin(t),r=Math.cos(e),o=Math.sin(e),c=Math.cos(i),l=Math.sin(i);return[{x:n*r-s*o*c,y:s*r+n*o*c,z:o*l},{x:-n*o-s*r*c,y:-s*o+n*r*c,z:r*l}]}scale(t,e){return{x:t.x*e,y:t.y*e,z:t.z*e}}static stumpffC(t){if(Math.abs(t)<1e-6)return 1/2-t/24+t*t/720;if(t>0)return(1-Math.cos(Math.sqrt(t)))/t;const e=Math.sqrt(-t);return(Math.cosh(e)-1)/-t}static stumpffS(t){if(Math.abs(t)<1e-6)return 1/6-t/120+t*t/5040;if(t>0){const i=Math.sqrt(t);return(i-Math.sin(i))/(i*i*i)}const e=Math.sqrt(-t);return(Math.sinh(e)-e)/(e*e*e)}}const cy=[{id:"halley-1910",designation:"1P/Halley",name:"Halley's Comet",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:"Comet 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:"Comet 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:"Comet 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:"the Southern Comet",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:"the Eclipse Comet",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:"Comet 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:"Comet 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:"Comet 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:"Comet 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:"Comet 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:"Comet 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:"Comet 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:"Comet 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:"Comet 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:"Halley's Comet",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:"Comet 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:"Comet 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:"Comet 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:"Comet 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:"Comet 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:"Comet 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:"Comet 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 LD{static WINDOW_DAYS=200;static TWILIGHT_ELONGATION_DEG=15;static LIGHT_SPEED_AU_PER_DAY=173.144632674;static orbits=new Map;static aroundDate(t){const e=this.julianDayOf(t);return cy.filter(i=>Math.abs(e-i.orbit.perihelionJd)<=this.WINDOW_DAYS)}static brightestAt(t,e){return this.aroundDate(t).map(i=>this.appearanceOf(i,t,e)).sort((i,n)=>i.magnitude-n.magnitude)[0]}static appearanceOf(t,e,i){const n=Ne(e),s=this.earthPositionAt(n),r=this.apparentPositionOf(t,2451545+n.tt,s),o=this.subtract(r,s),c=this.length(r),l=this.length(o),h=this.tailEndAt(t,r,s,c,n,e,i),u=this.horizontalOf(o,n,e,i);return{apparition:t,position:u,...h,heliocentricDistanceAu:c,earthDistanceAu:l,elongationDeg:this.angleBetween(o,this.subtract({x:0,y:0,z:0},s)),magnitude:this.magnitudeAt(t,c,l)}}static magnitudeAt(t,e,i){const n=t.absoluteMagnitude+5*Math.log10(i)+2.5*t.activityExponent*Math.log10(e);return Math.max(n,t.peakMagnitude)}static tailEndAt(t,e,i,n,s,r,o){if(t.tailLengthAu===void 0)return{};const c=1+t.tailLengthAu/n,l=this.subtract({x:e.x*c,y:e.y*c,z:e.z*c},i),h=this.subtract(e,i);return{tailEnd:this.horizontalOf(l,s,r,o),tailLengthDeg:this.angleBetween(h,l)}}static apparentPositionOf(t,e,i){const n=this.orbitOf(t);let s=n.positionAt(e);for(let r=0;r<2;r++){const o=this.length(this.subtract(s,i))/this.LIGHT_SPEED_AU_PER_DAY;s=n.positionAt(e-o)}return s}static horizontalOf(t,e,i,n){const s=cr(a4(),new ge(t.x,t.y,t.z,e)),r=cr(W2(e),s),o=np(e,new qr(n.lat,n.lng,n.elevationM),!0),c=new ge(r.x-o.x,r.y-o.y,r.z-o.z,e),l=fd(c);return um(l.ra,l.dec,i,n)}static earthPositionAt(t){return cr(r4(),Wr(ut.Earth,t))}static julianDayOf(t){return 2451545+Ne(t).tt}static orbitOf(t){const e=this.orbits.get(t.id);if(e)return e;const i=new nr(t.orbit);return this.orbits.set(t.id,i),i}static subtract(t,e){return{x:t.x-e.x,y:t.y-e.y,z:t.z-e.z}}static length(t){return Math.hypot(t.x,t.y,t.z)}static angleBetween(t,e){const i=(t.x*e.x+t.y*e.y+t.z*e.z)/(this.length(t)*this.length(e)||1);return Math.acos(Math.min(1,Math.max(-1,i)))*180/Math.PI}}const Uf=[{id:"sn-1006",kind:"supernova",designation:"SN 1006",name:"Supernova of 1006",raHours:15.03947,decDeg:-42.09694,peakMagnitude:-7.5,peakJd:2088620,startJd:2088620,lightCurve:[[0,-7.5],[29,-5.9],[60,-4.9],[106,-3.2],[166,-1.9],[258,-1],[350,.5],[364,.7],[411,1.2],[456,1.8],[484,2.5],[785.5,7]],source:"Winkler, Gupta & Long 2003 (peak); decline borrowed from SN 1572",note:"The brightest stellar event in recorded history, seen in daylight, low in the southern sky from Europe and the Near East. The decline is modelled, not recorded, and falls below the naked eye after about two years where the chronicles speak of three."},{id:"sn-1054",kind:"supernova",designation:"SN 1054",name:"Supernova of 1054",raHours:5.5755,decDeg:22.0175,peakMagnitude:-6,peakJd:2106216,startJd:2106216,lightCurve:[[0,-6],[23,-4],[642,6]],source:"Chinese chronicles (Song huiyao), via Stephenson & Green 2002",note:"The explosion that left the Crab Nebula. Its magnitude is an estimate; the two durations are recorded."},{id:"sn-1181",kind:"supernova",designation:"SN 1181",name:"Supernova of 1181",raHours:.88645,decDeg:67.50067,peakMagnitude:0,peakJd:2152636,startJd:2152636,lightCurve:[[0,0],[185,6]],source:"Chinese and Japanese chronicles, via Stephenson & Green 2002",note:"Circumpolar from Europe and China, so never set. Its peak magnitude is uncertain by at least a magnitude."},{id:"sn-1572",kind:"supernova",designation:"SN 1572",name:"Tycho's Supernova",raHours:.42264,decDeg:64.14083,peakMagnitude:-4,peakJd:2295551,startJd:2295546,lightCurve:[[0,-3],[5,-4],[34,-2.4],[65,-1.4],[111,.3],[171,1.6],[263,2.5],[355,4],[369,4.2],[416,4.7],[461,5.3],[489,6]],source:"Tycho Brahe and contemporaries, reduced by Ruiz-Lapuente 2004",note:"Circumpolar from northern Europe. Tycho showed it had no parallax, so it was not in the air: a new star, beyond the Moon."},{id:"sn-1604",kind:"supernova",designation:"SN 1604",name:"Kepler's Supernova",raHours:17.51125,decDeg:-21.48733,peakMagnitude:-2.95,peakJd:2307210,startJd:2307191,lightCurve:[[0,.23],[3,-1.3],[6,-2.08],[9,-2.17],[19,-2.95],[27,-2.95],[32,-1.95],[36,-1.52],[86,.9],[96,.45],[103,1],[114,1.2],[118,1.55],[133,1.95],[137,2.3],[170,2.25],[185,2.25],[194,2.4],[197,2.9],[308,4.45],[324,4.45],[339,4.95],[364,4.7]],source:"Kepler, Fabricius, Maestlin and the Korean court astronomers, reduced by Ruiz-Lapuente 2017",note:"The last supernova in our Galaxy seen with the naked eye. It went behind the Sun from mid-November 1604 to January 1605, which is the gap in its record."},{id:"t-crb-1866",kind:"nova",designation:"T CrB",name:"Nova Coronae Borealis 1866",raHours:15.99171,decDeg:25.92017,peakMagnitude:2,peakJd:2402734,startJd:2402734,lightCurve:[[0,2],[1.5,3],[2.5,3.11],[6.5,5.18],[8.5,5.75],[10.5,6.85],[11.5,6.8],[12.5,7.5],[16,8.18],[32,9.27],[38,9.2],[40,8.95],[44,9.4],[48,9.07],[54,9.4],[58,9.21],[79,9.44],[107,9.26],[111,9.01],[115,8.21],[119,7.96],[159,7.51],[179,7.57],[183,7.97],[191,7.66],[199,8.2],[207,8.31],[211,8.83],[215,8.65],[223,8.97],[297,8.9],[345,9.25],[377,9.07],[425,9.3],[537,9.3]],source:"Recorded peak (Birmingham); curve borrowed from its 1946 eruption",note:"The first eruption of the recurrent nova T CrB to be seen. The decline is its 1946 one."},{id:"t-aur-1891",kind:"nova",designation:"T Aur",name:"Nova Aurigae 1891",raHours:5.53309,decDeg:30.44583,peakMagnitude:4.49,peakJd:2412083,startJd:2412079,lightCurve:[[0,5.28],[4,4.49],[24,4.58],[40,4.97],[52,4.95],[56,4.5],[60,4.9],[68,4.88],[72,5.25],[76,4.93],[84,5.44],[88,7.23],[96,8.85],[100,10.44]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"gk-per-1901",kind:"nova",designation:"GK Per",name:"Nova Persei 1901",raHours:3.52,decDeg:43.90431,peakMagnitude:.19,peakJd:24154395e-1,startJd:24154377e-1,lightCurve:[[0,2.7],[.8,.86],[1.8,.19],[2.3,.2],[5.8,1.78],[11.8,2.54],[12.8,2.98],[17.8,3.62],[18.8,3.35],[19.8,3.77],[20.8,3.59],[22.8,3.95],[24.8,3.82],[25.6,4.99],[25.9,4.89],[26.6,3.69],[27.6,3.94],[27.9,4.61],[28.6,5.28],[28.9,4.46],[29.9,3.8],[30.9,4.27],[31.6,5.21],[31.9,5.22],[32.9,3.88],[33.9,4.19],[34.6,4.85],[35.6,4.8],[36.6,4.23],[37.6,4.44],[38.9,4.15],[39.7,5.19],[40.6,5.39],[40.9,5.35],[41.9,4.01],[42.6,4.5],[42.9,4.49],[43.6,5.53],[44,5.23],[44.6,5.61],[44.9,5.5],[45.9,4.17],[46.9,4.69],[47.6,5.5],[48.6,5.59],[49.6,5.14],[49.9,4.48],[50.6,4.45],[50.9,4.55],[51.6,5.47],[52.6,5.74],[53.7,5.66],[55.7,4.41],[56.7,5.43],[58.7,5.81],[58.9,5.58],[59.7,5.64],[59.9,4.76],[60.9,4.26],[61.9,5.62],[62.7,5.85],[62.9,5.53],[63.7,5.8],[64.9,4.28],[65.6,5.33],[66.7,5.87],[66.9,5.56],[68.7,5.7],[68.9,5.3],[69.7,4.47],[70.7,5.65],[72.9,5.98],[73.9,5.71],[74.7,4.98],[74.9,4.46],[75.7,4.87],[76.9,6.05],[77.6,5.76],[78,6],[78.7,5.95],[80.7,4.98],[81.9,5.85],[82.7,6.02],[84.7,5.41],[84.9,5.08],[85.7,5.17],[85.9,5.6],[87,6.1],[88.8,6.2],[89.7,4.96],[89.9,4.93],[90.7,5.9],[91.9,6.32],[92.7,5.86],[93.1,6.24],[93.7,5.38],[93.9,6.2],[96.1,6.12],[97.1,6.37],[97.6,5.12],[98,5.85],[99.3,6.35],[101.3,6.12],[101.7,5.25],[102.3,4.95],[102.7,6.12],[103.2,5.83],[104.7,6.37],[105,6.13],[106,6.22],[106.7,4.88],[107.7,6.3],[108.1,6.4],[109,6],[109.7,5.16],[110,5.82],[112.1,5.89],[113.1,5.5],[115.7,5.8],[116,6.11],[118.7,5.68],[119,6.23],[119.7,5.85],[120,6.12],[121,4.62],[121.8,5.9],[123,5.48],[125,6.05],[126,5.89],[130.9,6.11],[146.1,6.02],[155.6,6.26],[180.4,6.09],[190.4,6.39],[245.5,6.87],[266.2,6.77],[301.1,7.16],[321.5,7.07],[346.5,7.87],[375.7,7.86],[385.8,8.09],[389.8,8.55],[406.1,8.33],[416.5,8.59],[445.9,8.62],[472.1,9.24],[565.9,9.74],[571,9.4],[589.8,9.76]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"Discovered on 21 February 1901 by Thomas Anderson in Edinburgh, and the brightest nova of the century until V603 Aql."},{id:"dn-gem-1912",kind:"nova",designation:"DN Gem",name:"Nova Geminorum 1912",raHours:6.9151,decDeg:32.14108,peakMagnitude:3.58,peakJd:241947675e-2,startJd:241947275e-2,lightCurve:[[0,11.7],[1,4.5],[4,3.58],[5,4.45],[5.5,5.32],[6,5.53],[6.5,5.11],[8,5.43],[8.5,5.16],[11,5.53],[11.5,5.13],[12,5.18],[13.75,4.5],[15.75,5.3],[18.75,6],[19.75,5.55],[26.75,6],[28.75,5.9],[31.75,6.6],[32.75,6.2],[33.75,6.5],[36.75,6.55],[39.75,6.2],[40.75,6.75],[41.75,7],[44.75,6.75],[52.75,6.75],[54.75,7.23],[58.25,7.5],[62.25,7.3],[64.25,7.47],[66.25,8.1],[70.25,7.5],[72.25,8.1],[78.25,7.55],[80.25,8.2],[86.25,7.2],[90.25,7.3],[92.25,7.8],[152.25,7.2],[160.25,7.4],[166.25,8.2],[168.25,8.2],[170.25,7.3],[180.25,7.4],[182.25,8],[186.25,7.5],[190.25,7.6],[192.25,8],[211.25,7.75],[227.25,8],[275.25,7.78],[315.25,8.6],[331.25,7.79],[339.25,8.27],[363.25,8.61],[443.25,8.93],[451.25,9.2],[535.25,10.3],[567.25,9.9],[615.25,10.8],[631.25,10.63],[647.25,10.88],[679.25,10.8],[695.25,11.07],[727.25,11]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"v603-aql-1918",kind:"nova",designation:"V603 Aql",name:"Nova Aquilae 1918",raHours:18.81518,decDeg:.58414,peakMagnitude:-.5,peakJd:242175475e-2,startJd:242174875e-2,lightCurve:[[0,11.3],[2,10.5],[4,6.6],[4.5,1.04],[6,-.5],[6.5,.18],[10,1.1],[10.5,.95],[12.75,1.89],[21.75,3.07],[23.75,3.76],[29.75,3.16],[34.75,3.5],[36.75,3.86],[44.75,3.79],[48.75,4.43],[52.75,3.84],[56.75,3.95],[57.75,4.04],[58.75,4.49],[59.75,4.42],[60.75,4.69],[62.75,4.6],[63.75,4.11],[64.75,3.97],[68.75,4.18],[70.75,4.65],[71.75,4.51],[73.75,4.73],[75.75,4.44],[79.75,4.85],[83.75,4.43],[89.75,4.88],[92.75,4.86],[94.75,4.58],[96.75,4.92],[99.75,5.05],[163.25,5.45],[167.25,5.7],[179.25,5.48],[191.25,5.8],[203.25,5.5],[247.25,5.9],[251.25,6.25],[257.25,5.5],[265.25,6.13],[281.25,6.33],[345.25,6.3],[385.25,6.73],[393.25,6.43],[425.25,6.71],[433.25,6.56],[461.25,7.27],[525.25,7.6],[541.25,7.47],[637.25,8.3],[669.25,8.17],[717.25,8.55],[749.25,8.4],[765.25,8.68],[885.25,8.75],[949.25,9.4],[1013.25,9.19],[1141.25,9.57],[1269.25,9.48],[1333.25,9.95],[1653.25,9.94],[1781.25,10.28],[1909.25,10.34],[2037.25,10.1],[2101.25,10.46],[2165.25,10.51],[2357.25,10.3],[2549.25,10.77],[2741.25,10.46],[2869.25,10.83],[3125.25,10.71],[3317.25,11.22],[3381.25,10.91],[3637.25,11.42],[3829.25,10.96],[3893.25,11.65],[3957.25,11.63],[4085.25,11.14],[4213.25,11.48],[4277.25,10.7],[4341.25,11.42],[4405.25,11.47],[4469.25,11.06],[4533.25,11.08],[4597.25,11.7],[4725.25,11.45],[4789.25,10.94]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"The brightest nova of the modern era, at magnitude -0.5 on 9-10 June 1918: as bright as Vega, in a summer evening sky, in wartime."},{id:"v476-cyg-1920",kind:"nova",designation:"V476 Cyg",name:"Nova Cygni 1920",raHours:19.97347,decDeg:53.61858,peakMagnitude:1.94,peakJd:242256025e-2,startJd:242255925e-2,lightCurve:[[0,2.7],[1,1.94],[3,2.07],[4.5,2.95],[8.25,4],[31.75,6.41],[35.75,7.23],[37.75,7.08],[41.75,7.33],[43.75,7.92],[45.75,8.2],[51.75,8.59],[63.75,8.82],[65.75,9.25],[71.75,8.93],[85.75,9.43],[87.75,9.05],[95.75,9.2],[97.75,8.67],[99.75,9.07],[112.75,8.78],[120.75,9.03],[128.75,8.67],[144.75,8.94],[152.75,8.73],[168.75,8.79],[176.75,9.28],[192.75,9],[216.75,9.6],[232.75,9.27],[240.75,9.5],[288.75,9.4],[296.75,9.6],[304.75,9.3],[320.75,9.73],[328.75,9.5],[336.75,9.8],[428.75,9.61],[476.75,10.01],[492.75,9.76],[508.75,9.87],[524.75,9.65],[556.75,9.87],[572.75,9.65],[620.75,10.22],[668.75,10.44],[684.75,10.23],[716.75,10.33],[756.75,10.66],[884.75,10.59],[948.75,10.96],[1108.75,10.96]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"rr-pic-1925",kind:"nova",designation:"RR Pic",name:"Nova Pictoris 1925",raHours:6.59335,decDeg:-62.64008,peakMagnitude:.95,peakJd:24243085e-1,startJd:24242995e-1,lightCurve:[[0,2.43],[5,2.35],[6,2.1],[7,2.4],[9,.95],[13,1.8],[14,1.7],[16,2.15],[18,2.2],[19,1.9],[23,3.1],[27,3.05],[31.5,3.58],[43.5,3.08],[47.5,3.15],[57.5,2.3],[59.5,1.65],[63.5,3.03],[65.5,2.84],[67.5,3.16],[69.5,2.4],[71.5,2.04],[73.5,2.05],[75.5,2.55],[79.5,3],[83.5,3.15],[116.5,3.54],[120.5,3.78],[124.5,3.67],[136.5,4.18],[148.5,4.34],[154.5,4.17],[194.5,4.43],[226.5,4.93],[234.5,4.8],[242.5,5.4],[250.5,5.5],[266.5,5.15],[298.5,5.6],[362.5,5.4],[414.5,5.7],[430.5,5.5],[494.5,6.2],[718.5,6.52],[830.5,6.3],[862.5,6.6],[878.5,6.4],[910.5,6.77],[958.5,6.67],[1062.5,7.07],[1318.5,7.35],[1590.5,8.12],[1718.5,8.25],[2486.5,8.59],[2614.5,8.47],[2742.5,8.7],[3382.5,8.6],[3766.5,8.97],[4022.5,8.79],[4150.5,9.22],[6710.5,10.29],[7414.5,11.03],[8438.5,10.96]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"A slow nova, and a southern one: more than two months within two magnitudes of its peak."},{id:"dq-her-1934",kind:"nova",designation:"DQ Her",name:"Nova Herculis 1934",raHours:18.12507,decDeg:45.85906,peakMagnitude:1.56,peakJd:24277935e-1,startJd:242778675e-2,lightCurve:[[0,3.4],[1.5,2.4],[3,2.67],[5.75,2.01],[6.75,1.56],[7.75,1.59],[11.75,2.97],[12.75,2.31],[14.75,3.07],[15.75,2.56],[16.75,2.51],[19.75,2.68],[23.75,2.53],[24.75,2.27],[26.75,2.58],[30.75,2.24],[31.75,2.63],[32.75,2.66],[34.75,2.11],[39.75,2.71],[41.75,2.31],[43.75,2.37],[46.75,3.64],[47.75,3.21],[50.75,3.23],[52.75,2.66],[55.75,2.56],[58.75,2.97],[60.75,2.77],[61.75,3.36],[63.75,3.43],[64.75,2.89],[65.75,3.22],[68.75,3.52],[69.75,2.95],[70.75,3.06],[71.75,2.7],[76.75,3.65],[79.75,3.74],[81.75,3.21],[83.75,3.75],[87.75,3.69],[92.75,4.04],[94.75,4.8],[97.75,4.24],[98.75,4.52],[100.75,4.08],[101.75,4.43],[105.75,4.58],[106.75,4.33],[107.75,4.73],[108.75,6.57],[109.75,8.08],[110.75,8.15],[111.75,8.56],[113.75,8.45],[114.75,9.15],[115.75,9.15],[116.75,9.59],[117.75,9.43],[118.75,9.8],[122.75,10.5],[123.75,10.28],[124.75,10.93],[127.75,10.83],[129.75,11.87],[131.75,12.42],[135.75,12.5],[137.75,12.9],[138.75,12.77],[139.75,13],[143.75,12],[144.75,12.33],[146.75,12.35],[147.75,11.64],[148.75,11.83],[150.75,10.9],[151.75,10.78],[152.75,11.17],[154.75,10.32],[155.75,10.4],[165.25,9.24],[185.25,7.74],[225.25,6.8],[273.25,6.72],[321.25,6.97],[333.25,6.79],[353.25,7],[357.25,6.82],[377.25,6.88],[401.25,7.29],[409.25,6.8],[413.25,6.8],[419.25,7.1],[435.25,7.09],[451.25,7.4],[475.25,7],[555.25,7.48],[823.25,7.83],[855.25,8.18],[1135.25,8.43],[1823.25,9.98],[1887.25,9.71],[2015.25,10.55],[2335.25,10.95]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"Lost about ten magnitudes in a few weeks from April 1935, when dust condensed around it, then came back to naked-eye brightness."},{id:"cp-lac-1936",kind:"nova",designation:"CP Lac",name:"Nova Lacertae 1936",raHours:22.26142,decDeg:55.61703,peakMagnitude:2.02,peakJd:242834025e-2,startJd:242833825e-2,lightCurve:[[0,4.03],[.5,2.9],[1,2.45],[2,2.02],[2.5,2.61],[4,3],[4.5,3.35],[5,3.3],[9.25,4.59],[14.25,5.45],[22.25,6.03],[23.25,6.3],[26.25,6.23],[38.25,6.74],[41.25,6.61],[50.25,7.35],[53.25,7.27],[57.25,7.7],[58.25,7.54],[60.25,7.55],[61.25,7.79],[71.25,7.6],[74.25,7.81],[76.25,8.3],[77.25,7.79],[86.25,8.21],[87.25,8],[88.25,8.25],[92.25,8.17],[94.25,8.47],[102.25,8.27],[103.25,8.7],[104.25,8.4],[110.25,8.66],[116.75,8.55],[122.75,8.83],[126.75,8.7],[140.75,9.06],[154.75,9.01],[164.75,9.36],[170.75,9.18],[174.75,9.48],[186.75,9.42],[188.75,9.73],[192.75,9.53],[200.75,9.74],[202.75,9.5],[204.75,9.77],[208.75,9.6],[214.75,9.75],[216.75,10.05],[222.75,9.7],[232.75,10.03],[236.75,9.82],[250.75,10.1],[254.75,9.9],[260.75,10.1],[264.75,9.8],[266.75,10.15],[268.75,10],[274.75,10.2],[276.75,9.9],[292.75,10.6],[294.75,10.6],[298.75,10.1],[318.75,10.35],[320.75,10.6],[322.75,10.3],[328.75,10.65],[332.75,10.3],[338.75,10.7],[348.75,10.53],[350.75,10.7],[354.75,10.37],[358.75,10.58],[365.75,10.43],[373.75,10.85],[421.75,10.94]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"cp-pup-1942",kind:"nova",designation:"CP Pup",name:"Nova Puppis 1942",raHours:8.19613,decDeg:-35.35139,peakMagnitude:.73,peakJd:243067675e-2,startJd:243067275e-2,lightCurve:[[0,.95],[4,.73],[4.5,1.3],[5.5,1.47],[6,2.01],[7.75,2.88],[8.75,2.97],[10.75,3.5],[11.75,4.02],[13.75,4.4],[14.75,3.8],[17.75,5],[18.75,4.93],[19.75,5.48],[23.75,5.5],[25.75,5.65],[26.75,5.99],[33.25,6.28],[45.25,6.6],[57.25,6.41],[81.25,6.85],[89.25,6.5],[97.25,6.67],[101.25,7],[113.25,6.66],[125.25,7.1],[135.25,6.96],[231.25,7.86],[279.25,7.8],[327.25,8.33],[407.25,8.18],[423.25,8.59],[471.25,8.53],[503.25,8.99],[551.25,8.97],[567.25,8.7],[583.25,9.47],[615.25,8.95],[655.25,9.5],[751.25,9.55],[815.25,10.09],[847.25,10.02],[879.25,10.48],[911.25,10.34],[1023.25,10.79],[1279.25,10.9]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"One of the fastest bright novae: two magnitudes gone in four days."},{id:"t-crb-1946",kind:"nova",designation:"T CrB",name:"Nova Coronae Borealis 1946",raHours:15.99171,decDeg:25.92017,peakMagnitude:2.5,peakJd:2431860,startJd:2431860,lightCurve:[[0,2.5],[1.5,3.5],[2.5,3.61],[6.5,5.68],[8.5,6.25],[10.5,7.35],[11.5,7.3],[12.5,8],[16,8.68],[32,9.77],[38,9.7],[40,9.45],[44,9.9],[48,9.57],[54,9.9],[58,9.71],[79,9.94],[107,9.76],[111,9.51],[115,8.71],[119,8.46],[159,8.01],[179,8.07],[183,8.47],[191,8.16],[199,8.7],[207,8.81],[211,9.33],[215,9.15],[223,9.47],[297,9.4],[345,9.75],[377,9.57],[425,9.8],[537,9.8]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"A recurrent nova. It erupted in 1866 and in 1946, and a third eruption was expected from 2024 on."},{id:"v446-her-1960",kind:"nova",designation:"V446 Her",name:"Nova Herculis 1960",raHours:18.956,decDeg:13.24147,peakMagnitude:4.83,peakJd:24370038e-1,startJd:24370033e-1,lightCurve:[[0,5.2],[.5,4.83],[2,4.9],[2.5,5.4],[3,5.05],[3.5,5.57],[4,5.25],[5,5.5],[6.5,5.4],[7.2,5.78],[8.2,5.6],[9.2,5.98],[10.2,5.92],[11.2,6.21],[16.2,6.1],[17.2,6.23],[18.2,7.2],[19.2,6.51],[20.2,6.78],[26.2,6.97],[27.2,7.24],[28.2,7.13],[29.2,7.45],[31.2,7.2],[40.7,7.57],[44.7,8.25],[46.7,7.84],[56.7,8.15],[60.7,8.9],[70.7,8.7],[72.7,8.14],[76.7,8.71],[80.7,8.47],[82.7,8.87],[86.7,8.57],[90.7,8.93],[107.7,9.11],[111.7,8.94],[115.7,9.27],[139.7,9.38],[151.7,9.91],[155.7,9.72],[173.7,10.51],[221.7,10.95]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"v533-her-1963",kind:"nova",designation:"V533 Her",name:"Nova Herculis 1963",raHours:18.23902,decDeg:41.85614,peakMagnitude:3,peakJd:24380605e-1,startJd:24380565e-1,lightCurve:[[0,8],[4,3],[4.5,3],[8,4],[13,3.95],[15,4.6],[21,4.53],[24,5.05],[27,5.15],[32,4.76],[34,4.98],[35,5.39],[37,5.43],[41,6.04],[49,6.02],[56.5,6.34],[60.5,6.11],[74.5,6.72],[102.5,6.99],[137.5,7.81],[197.5,8.31],[217.5,8.8],[225.5,8.57],[233.5,9.03],[237.5,8.78],[277.5,9.44],[301.5,9.46],[315.5,9.86],[323.5,9.73],[339.5,10.05],[355.5,10.74],[363.5,10.32],[371.5,10.6],[387.5,10.69],[427.5,10.38],[435.5,10.84],[443.5,10.74],[451.5,11.33],[459.5,10.98],[467.5,11.17],[507.5,11.16],[539.5,11.66],[603.5,11.7],[619.5,12.05],[651.5,12.03],[659.5,11.74],[667.5,10.9]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"hr-del-1967",kind:"nova",designation:"HR Del",name:"Nova Delphini 1967",raHours:20.70565,decDeg:19.16092,peakMagnitude:3.58,peakJd:2439838,startJd:2439646,lightCurve:[[0,11.9],[6,11.8],[12,8.8],[16,8.3],[20,6.7],[30,5.8],[36,5.51],[66,5.55],[78,5.35],[86,4.89],[96,5],[108,4.75],[136,5.13],[152,4.83],[182,4.93],[186,4.59],[192,3.58],[202,5],[220,5.46],[226,5.14],[230,5.45],[232,5.14],[236,5],[242,5.08],[244,4.59],[246,4.45],[254,5.3],[256,4.75],[260,5.69],[268,4.8],[274,4.94],[276,5.45],[280,5.2],[282,5.51],[286,5.58],[292,4.95],[294,5.16],[298,4.94],[311,5.09],[335,4.4],[367,5.76],[407,6.16],[423,6.55],[603,7.43],[907,8.32],[1451,9.41],[2347,10.75]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"An exceptionally slow nova: rose over months and stayed near magnitude 4 to 5 for most of 1967 and 1968."},{id:"lv-vul-1968",kind:"nova",designation:"LV Vul",name:"Nova Vulpeculae 1968",raHours:19.80012,decDeg:27.1715,peakMagnitude:4.5,peakJd:243996425e-2,startJd:243996325e-2,lightCurve:[[0,5],[1,4.5],[2,5],[2.5,4.86],[3,5.1],[3.5,4.88],[4,5.1],[5,4.9],[7,5.4],[8,5.23],[10.5,5.42],[12,5.82],[13,5.4],[13.5,5.74],[14,5.7],[14.5,6.08],[15,5.75],[15.5,5.86],[16,5.6],[17,5.8],[18,5.6],[20.5,6.34],[21,6.2],[22.5,6.84],[23,6.57],[24,6.98],[24.5,6.3],[25,7.1],[26,6.65],[34.25,7.48],[35.25,7.23],[39.25,7.32],[44.25,7.76],[45.25,7.49],[46.25,7.78],[50.25,7.84],[51.25,8.1],[53.25,7.9],[54.25,8.13],[56.25,8],[57.75,8.24],[67.75,8.52],[75.75,8.38],[83.75,8.69],[89.75,8.59],[125.75,9.32],[127.75,9.33],[129.75,8.98],[131.75,9.29],[135.75,9.43],[212.75,9.9],[220.75,10.16],[228.75,10.03],[236.75,10.3],[244.75,10.16],[264.75,10.54],[280.75,10.45],[296.75,10.79],[328.75,10.78]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"fh-ser-1970",kind:"nova",designation:"FH Ser",name:"Nova Serpentis 1970",raHours:18.51307,decDeg:2.61444,peakMagnitude:4.5,peakJd:244063425e-2,startJd:244063125e-2,lightCurve:[[0,7],[2,5],[3,4.5],[3.5,5],[4.5,4.6],[5.5,5],[6.5,4.68],[12.25,4.66],[16.25,5.3],[17.25,5.72],[18.25,5.3],[19.25,5.2],[23.25,5.84],[24.25,5.68],[27.25,5.9],[30.25,5.47],[32.25,5.9],[34.25,5.7],[43.25,6.28],[45.25,6.1],[50.25,6.62],[52.25,6.47],[57.25,6.63],[60.25,7.08],[61.25,6.87],[62.25,7.2],[63.25,6.85],[64.25,7.68],[65.25,7.3],[66.25,8.3],[67.25,7.93],[69.25,9.15],[71.25,9.2],[72.25,9.63],[74.25,9.9],[76.25,9.7],[77.25,10.25],[78.25,10.1],[79.25,10.4],[80.25,10.23],[81.25,10.57],[83.25,10.64],[85.25,10.35],[86.25,11.2],[87.25,10.1],[89.25,11.2],[96.25,11.35],[100.25,11.95],[102.25,11.1],[104.25,11.65],[106.25,11.5],[108.25,12.07],[114.75,11.32],[118.75,11.28],[122.75,10.93],[130.75,10.85],[134.75,10.52],[154.75,10.65],[162.75,10.12],[174.75,9.98],[178.75,10.34],[186.75,9.98],[214.75,10.25],[224.75,10.02],[240.75,10.2],[264.75,10],[272.75,10.2],[280.75,10.05],[288.75,10.4],[296.75,10],[348.75,10.7],[396.75,10.3],[444.75,10.73],[460.75,10.59],[540.75,10.94],[556.75,10.82]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"v1500-cyg-1975",kind:"nova",designation:"V1500 Cyg",name:"Nova Cygni 1975",raHours:21.19349,decDeg:48.15056,peakMagnitude:1.88,peakJd:244265525e-2,startJd:244265425e-2,lightCurve:[[0,2.44],[1,1.88],[1.5,1.88],[2.5,2.41],[3,3.38],[4,4.28],[8.25,5.81],[11.25,6.46],[22.25,7.35],[33.25,7.73],[34.25,7.97],[37.25,7.86],[40.25,8.3],[43.25,8.19],[48.25,8.6],[49.25,8.46],[66.25,9.04],[70.25,8.93],[75.25,9.23],[76.25,9.03],[80.25,9.39],[81.25,9.19],[83.25,9.35],[84.25,9.13],[86.25,9.39],[89.25,9.32],[90.25,9.54],[93.25,9.37],[105.75,9.86],[193.75,10.43],[201.75,10.7],[209.75,10.47],[257.75,10.94],[265.75,10.81]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"One of the fastest novae on record: discovered on 29 August 1975, at its peak of magnitude 1.9 within two days, and two magnitudes down again two days later."},{id:"v842-cen-1986",kind:"nova",designation:"V842 Cen",name:"Nova Centauri 1986",raHours:14.59794,decDeg:-57.6265,peakMagnitude:4.9,peakJd:244675975e-2,startJd:244675725e-2,lightCurve:[[0,5.6],[2.5,4.9],[3.5,5.1],[15.5,5.1],[17.5,5.75],[18.5,5.4],[20.5,5.5],[22.5,5.95],[30.5,6.15],[31.5,6.3],[32,7.5],[34.5,7.2],[38.5,7.5],[39,7],[41.5,7.15],[42.5,6.7],[44.5,7.23],[45.5,6.6],[53,9.3]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"sn-1987a",kind:"supernova",designation:"SN 1987A",name:"Supernova 1987A",raHours:5.59111,decDeg:-69.26975,peakMagnitude:2.98,peakJd:24469425e-1,startJd:24468495e-1,lightCurve:[[0,6.36],[1,6.11],[2,4.63],[4,4.45],[32,3.97],[56,3.15],[93,2.98],[105,3.35],[118,4.11],[134,4.43],[504,8.15],[617,10.27]],source:"V photometry compiled by the Open Supernova Catalog (Sternberg catalogue, IAU circulars, CTIO)",note:"In the Large Magellanic Cloud, 160 000 light years away: the nearest supernova since Kepler's, and invisible north of about 20° N."},{id:"v1974-cyg-1992",kind:"nova",designation:"V1974 Cyg",name:"Nova Cygni 1992",raHours:20.50879,decDeg:52.63078,peakMagnitude:4.27,peakJd:24486753e-1,startJd:24486718e-1,lightCurve:[[0,7.2],[1,5.23],[2,4.62],[3.5,4.27],[4.5,4.59],[6,4.5],[7,4.78],[7.5,4.52],[8,4.82],[10.7,5.25],[11.7,5.66],[16.7,5.85],[21.7,6.47],[22.7,6.3],[27.7,6.46],[29.7,6.83],[34.7,6.9],[35.7,7.25],[36.7,7],[37.7,7.16],[39.7,7.03],[43.7,7.41],[45.7,7.26],[50.7,7.45],[57.7,7.78],[58.7,8.13],[61.7,7.92],[64.7,8.19],[65.7,7.99],[71.7,8.22],[76.7,8.01],[128.2,8.72],[176.2,8.89],[192.2,9.15],[216.2,9.28],[232.2,9.07],[236.2,9.3],[390.2,10.99]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"v382-vel-1999",kind:"nova",designation:"V382 Vel",name:"Nova Velorum 1999",raHours:10.74678,decDeg:-52.42533,peakMagnitude:2.88,peakJd:245132225e-2,startJd:245132075e-2,lightCurve:[[0,2.99],[1.5,2.88],[2.5,3.46],[4.5,3.98],[5,4.32],[5.5,4.23],[7.5,4.85],[21.75,6.67],[30.25,7.2],[40.25,7.41],[93.25,7.95],[97.25,8.25],[101.25,8],[113.25,7.96],[129.25,8.5],[155.25,8.47],[163.25,9.1],[179.25,9],[187.25,8.7],[195.25,9.15],[211.25,9.23],[235.25,9.8],[243.25,9.71],[299.25,10.42],[383.25,10.52],[415.25,10.81]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"v1494-aql-1999",kind:"nova",designation:"V1494 Aql",name:"Nova Aquilae 1999",raHours:19.38482,decDeg:4.9555,peakMagnitude:4.11,peakJd:245151575e-2,startJd:245151425e-2,lightCurve:[[0,5.15],[.5,4.86],[1,4.27],[1.5,4.11],[2.5,4.35],[5,5.48],[10.5,6.26],[14.25,6.28],[20.25,7.43],[24.25,7.25],[25.25,7.63],[27.25,7.7],[29.25,7.42],[33.25,8.08],[35.25,8.03],[36.25,7.6],[37.25,7.6],[46.25,8.5],[54.25,8.28],[56.25,8.63],[58.25,8.4],[61.25,9.53],[62.25,9],[64.25,9.13],[69.25,8.58],[70.25,8.9],[72.25,8.88],[75.25,8.57],[77.25,9],[79.25,8.8],[81.25,9.7],[83.25,9.6],[85.25,9.8],[86.75,9.5],[88.75,9.54],[90.75,8.9],[92.75,8.85],[96.75,9.63],[102.75,9.7],[104.75,8.98],[106.75,8.73],[116.75,9.63],[118.75,9.6],[120.75,9.07],[122.75,9.26],[124.75,9.8],[128.75,9.36],[134.75,9.75],[147.75,9.92],[155.75,9.81],[259.75,10.96]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"v4743-sgr-2002",kind:"nova",designation:"V4743 Sgr",name:"Nova Sagittarii 2002",raHours:19.01926,decDeg:-22.00167,peakMagnitude:5,peakJd:245253775e-2,startJd:245253675e-2,lightCurve:[[0,5.2],[1,5],[2,5.89],[2.5,5.91],[3.5,6.43],[5,6.45],[5.5,6.86],[6,6.59],[7,6.77],[7.5,7.31],[8.5,6.99],[9,7.09],[10.5,7.86],[11,7.58],[11.5,7.89],[15.75,8.33],[17.75,8.18],[18.75,8.58],[19.75,8.44],[22.75,8.83],[23.75,8.6],[24.75,8.85],[27.75,8.83],[30.75,9.4],[31.75,9.09],[36.25,9.08],[38.25,9.34],[62.25,9.75],[66.25,10.1],[70.25,9.7],[74.25,10],[171.25,10.9]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010"},{id:"rs-oph-2006",kind:"nova",designation:"RS Oph",name:"Nova Ophiuchi 2006",raHours:17.83699,decDeg:-6.70792,peakMagnitude:4.8,peakJd:2453779,startJd:2453779,lightCurve:[[0,4.8],[1.25,4.97],[2.75,5.78],[3.25,5.7],[3.75,6.24],[4.25,6.05],[4.75,6.38],[5.25,6.3],[8.5,7.25],[14.5,7.95],[24.5,8.55],[29.5,9.08],[48,9.87],[80,10.28],[107,11.54],[119,11.54],[139,11.98],[147,11.83],[163,12.03],[171,11.97],[175,11.65],[183,11.84],[195,11.64],[203,11.8],[207,12.13],[219,11.45],[277,11.68],[325,11],[341,11.53],[357,11.62],[373,11.3],[405,11.5],[421,11.17],[469,10.96],[501,11.22],[549,10.75],[581,11.08],[597,10.98]],source:"AAVSO, binned by Strope, Schaefer & Henden 2010",note:"A recurrent nova, erupting every twenty years or so (1898, 1907, 1933, 1945, 1958, 1967, 1985, 2006, 2021)."},{id:"v1280-sco-2007",kind:"nova",designation:"V1280 Sco",name:"Nova Scorpii 2007",raHours:16.96145,decDeg:-32.34325,peakMagnitude:3.8,peakJd:2454149,startJd:2454136,lightCurve:[[0,9.7],[13,3.8],[34,5.8],[103,15]],source:"AAVSO (discovery, peak, dust minimum); t2 from Das et al. 2008",note:"Faded from sight quickly when dust formed around it, three weeks after its peak."},{id:"v339-del-2013",kind:"nova",designation:"V339 Del",name:"Nova Delphini 2013",raHours:20.39186,decDeg:20.76772,peakMagnitude:4.4,peakJd:24565214e-1,startJd:24565214e-1,lightCurve:[[0,4.4],[11,6.4],[20,7.4]],source:"Gehrz et al. 2015 (peak, t2, t3)",note:"High in the summer evening sky of the northern hemisphere, and widely photographed."},{id:"v1369-cen-2013",kind:"nova",designation:"V1369 Cen",name:"Nova Centauri 2013",raHours:13.9126,decDeg:-59.15114,peakMagnitude:3.48,peakJd:245663965e-2,startJd:24566285e-1,lightCurve:[[0,5.33],[1.57,4.08],[2.75,3.73],[4.57,4.16],[5.96,4.15],[10.26,3.77],[11.15,3.48],[12.14,3.74],[14.17,4.78],[15.46,4.97],[23.16,4.22],[26.25,4.32],[27.31,4.82],[29.56,5.11],[32.66,4.71],[33.84,4.86],[36.05,4.46],[37.15,4.99],[41.42,4.59],[42.37,4.93],[43.37,4.82],[44.54,5.09],[49.95,5.38],[51.99,5.82],[54.21,5.77]],source:"AAVSO, binned by day, as plotted by Izzo 2017 (arXiv:1704.07214, figure 1)",note:"Discovered on 2 December 2013 by John Seach at magnitude 5.5, it flared several times, reaching about 3.3 around 14 December: the brightest nova of the century so far, and a southern one."},{id:"rs-oph-2021",kind:"nova",designation:"RS Oph",name:"Nova Ophiuchi 2021",raHours:17.83699,decDeg:-6.70792,peakMagnitude:4.6,peakJd:2459436,startJd:2459435,lightCurve:[[0,5],[1,4.6],[2.25,4.77],[3.75,5.58],[4.25,5.5],[4.75,6.04],[5.25,5.85],[5.75,6.18],[6.25,6.1],[9.5,7.05],[15.5,7.75],[25.5,8.35],[30.5,8.88],[49,9.67],[81,10.08],[108,11.34],[120,11.34],[140,11.78],[148,11.63],[164,11.83],[172,11.77],[176,11.45],[184,11.64],[196,11.44],[204,11.6],[208,11.93],[220,11.25],[278,11.48],[326,10.8],[342,11.33],[358,11.42],[374,11.1],[406,11.3],[422,10.97],[470,10.76],[502,11.02],[550,10.55],[582,10.88],[598,10.78]],source:"Recorded discovery and peak (8 and 9 August 2021); curve borrowed from its 2006 eruption",note:"RS Oph's latest eruption, discovered on 8 August 2021. The decline is its 2006 one."}];class qv{static UNIX_EPOCH_JD=24405875e-1;static aroundDate(t){const e=this.julianDayOf(t);return Uf.filter(i=>this.magnitudeAt(i,e)!==void 0)}static appearancesAt(t,e){const i=this.julianDayOf(t),n=[];for(const s of Uf){const r=this.magnitudeAt(s,i);r!==void 0&&n.push({outburst:s,position:os.ofJ2000(s.raHours,s.decDeg,t,e),magnitude:r})}return n.sort((s,r)=>s.magnitude-r.magnitude)}static brightestAt(t,e){return this.appearancesAt(t,e)[0]}static byId(t){return Uf.find(e=>e.id===t)}static magnitudeAt(t,e){const i=t.lightCurve,n=e-t.startJd;if(i.length===0||n<i[0][0]||n>i[i.length-1][0])return;let s=1;for(;s<i.length-1&&i[s][0]<n;)s++;const[r,o]=i[s-1]??i[0],[c,l]=i[s]??i[0];if(c===r)return o;const h=Math.min(1,Math.max(0,(n-r)/(c-r)));return o+h*(l-o)}static julianDayOf(t){return t.getTime()/864e5+this.UNIX_EPOCH_JD}}const ND=[{id:"quadrantids",code:"QUA",name:"Quadrantids",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:"April Lyrids",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:"eta Aquariids",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:"alpha Capricornids",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:"Southern delta Aquariids",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:"Perseids",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:"Southern Taurids",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:"October Draconids",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:"Orionids",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:"Northern Taurids",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:"Leonids",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:"Geminids",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:"Ursids",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}],Yu=6.5;class zf{static activeAt(t){return ND.flatMap(e=>{const i=this.nearness(e,t);return i<=0?[]:[{shower:e,zhr:e.peakZhr*i,nearness:i}]})}static nearness(t,e){const i=this.dayOfYear(e),n=this.dayOfYear(this.asDate(t.start)),s=this.dayOfYear(this.asDate(t.peak)),r=this.dayOfYear(this.asDate(t.end)),o=this.wrappedDelta(i,s),c=this.wrappedDelta(s,n),l=this.wrappedDelta(r,s);return o<0?o<-c?0:1+o/c:o>0?o>l?0:1-o/l:1}static observedRatePerHour(t,e,i,n=Yu){if(e<=0)return 0;const s=Yu-n;return t*Math.sin(e*Math.PI/180)/Math.pow(i,s)}static radiantPosition(t,e,i){return os.ofJ2000(t.radiantRaHours,t.radiantDecDeg,e,i)}static dayOfYear(t){const e=Date.UTC(t.getUTCFullYear(),0,1);return Math.floor((Date.UTC(t.getUTCFullYear(),t.getUTCMonth(),t.getUTCDate())-e)/864e5)+1}static asDate(t){return new Date(Date.UTC(2001,t.month-1,t.day))}static wrappedDelta(t,e){const i=t-e;return i>182?i-365:i<-182?i+365:i}}class fi{static QUIET_RATE_PER_HOUR=2;static APEX_RATE_PER_HOUR=8;static POPULATION_INDEX=3;static apexPosition(t,e){const i=Ne(t),n=new ld(0,FT(t).elon-90,1),s=cr(u4(i),hm(n,i)),r=fd(s);return um(r.ra,r.dec,t,e)}static observedRatePerHour(t,e=Yu){const i=fi.APEX_RATE_PER_HOUR*Math.max(0,Math.sin(t*Math.PI/180)),n=Yu-e;return(fi.QUIET_RATE_PER_HOUR+i)/Math.pow(fi.POPULATION_INDEX,n)}static schedule(t){const e=new pd(t.seed^1542469173);return ka.schedule(t).map(i=>{const n=fi.toCartesian({altitudeDeg:Math.asin(e.next())*180/Math.PI,azimuthDeg:e.between(0,360)}),s=i.fromRadiantDeg*Math.PI/180,r=fi.turnAround(n,e.between(0,360)),o={x:n.x*Math.cos(s)+r.x*Math.sin(s),y:n.y*Math.cos(s)+r.y*Math.sin(s),z:n.z*Math.cos(s)+r.z*Math.sin(s)};return{...i,radiant:fi.toHorizontal(o),bearingDeg:fi.bearingFrom(o,n)}})}static turnAround(t,e){const[i,n]=fi.basisAround(t),s=e*Math.PI/180;return{x:i.x*Math.cos(s)+n.x*Math.sin(s),y:i.y*Math.cos(s)+n.y*Math.sin(s),z:i.z*Math.cos(s)+n.z*Math.sin(s)}}static bearingFrom(t,e){const[i,n]=fi.basisAround(t),s=t.x*e.x+t.y*e.y+t.z*e.z,r=fi.normalise({x:e.x-t.x*s,y:e.y-t.y*s,z:e.z-t.z*s});return(Math.atan2(r.x*n.x+r.y*n.y+r.z*n.z,r.x*i.x+r.y*i.y+r.z*i.z)*180/Math.PI%360+360)%360}static basisAround(t){const e=Math.abs(t.y)<.9?{x:0,y:1,z:0}:{x:1,y:0,z:0},i=fi.normalise(fi.cross(t,e));return[i,fi.normalise(fi.cross(t,i))]}static toHorizontal(t){const e=Math.hypot(t.x,t.y,t.z)||1;return{altitudeDeg:Math.asin(Math.min(1,Math.max(-1,t.y/e)))*180/Math.PI,azimuthDeg:(Math.atan2(t.x,-t.z)*180/Math.PI%360+360)%360}}static appearanceOf(t){const e=fi.toCartesian(t.radiant??{altitudeDeg:90,azimuthDeg:0}),i=fi.turnAround(e,t.bearingDeg),n=t.fromRadiantDeg*Math.PI/180;return fi.toHorizontal({x:e.x*Math.cos(n)+i.x*Math.sin(n),y:e.y*Math.cos(n)+i.y*Math.sin(n),z:e.z*Math.cos(n)+i.z*Math.sin(n)})}static toCartesian(t){const e=t.altitudeDeg*Math.PI/180,i=t.azimuthDeg*Math.PI/180,n=Math.cos(e);return{x:n*Math.sin(i),y:Math.sin(e),z:-n*Math.cos(i)}}static cross(t,e){return{x:t.y*e.z-t.z*e.y,y:t.z*e.x-t.x*e.z,z:t.x*e.y-t.y*e.x}}static normalise(t){const e=Math.hypot(t.x,t.y,t.z)||1;return{x:t.x/e,y:t.y/e,z:t.z/e}}static TYPICAL_VELOCITY_KM_S=40}const $v="https://ufoathome.org/tle/index.json";class qi{static MAX_ELEMENT_AGE_DAYS=7;static DAY_MS=864e5;fetchImpl;indexUrls;index;files=new Map;constructor(t={}){this.fetchImpl=t.fetchImpl??fetch.bind(globalThis),this.indexUrls=t.indexUrls??qi.defaultIndexUrls()}static defaultIndexUrls(){const t=[];return typeof location<"u"&&/^https?:$/.test(location.protocol)&&t.push(new URL("/tle/index.json",location.href).href),t.includes($v)||t.push($v),t}static FIRST_SNAPSHOT="2021-02-22";async covers(t){const e=Date.parse(`${qi.FIRST_SNAPSHOT}T00:00:00Z`)-qi.MAX_ELEMENT_AGE_DAYS*qi.DAY_MS;if(t.getTime()<e)return!1;const i=await this.loadIndex();return i?Object.values(i.index.kinds).some(n=>t.getTime()>=Date.parse(n.from)-qi.MAX_ELEMENT_AGE_DAYS*qi.DAY_MS&&t.getTime()<=Date.parse(n.to)+qi.MAX_ELEMENT_AGE_DAYS*qi.DAY_MS):!1}async at(t){const e=await this.loadIndex();if(!e)return;const{index:i,base:n}=e,s=[],r=[];for(const o of Object.keys(i.kinds)){const c=await this.kindAt(o,t,i,n);s.push(...c),r.push(this.coverageOf(o,t,i,c.length>0))}return{objects:s,coverage:r,credit:i.credit,creditUrl:i.source}}async kindAt(t,e,i,n){const s=e.getTime(),r=i.binDays*qi.DAY_MS,o=Math.floor(s/r),c=s-o*r<r/2?o-1:o+1,l=new Set(i.kinds[t].bins),h=[o,c].map(v=>new Date(v*r).toISOString().slice(0,10)).filter(v=>l.has(v));if(h.length===0)return[];const[u,...d]=await Promise.all([this.json(new URL(`objects-${t}.json`,n).href),...h.map(v=>this.binary(new URL(`${t}/${v}.bin`,n).href))]),f=new Map;for(const v of d)for(const m of qi.decode(v,i.recordBytes)){const g=f.get(m.norad);(!g||Math.abs(m.epochMs-s)<Math.abs(g.epochMs-s))&&f.set(m.norad,m)}const p=[];for(const v of f.values()){const m=Math.abs(v.epochMs-s)/qi.DAY_MS;if(m>qi.MAX_ELEMENT_AGE_DAYS)continue;const g=u[v.norad]??{name:String(v.norad)};g.launch&&Date.parse(`${g.launch}T00:00:00Z`)>s||p.push({norad:v.norad,name:g.name,kind:t,launch:g.launch,stdMag:g.stdMag,elements:v,ageDays:m})}return p}coverageOf(t,e,i,n){const{from:s,to:r}=i.kinds[t],o=e.getTime(),c=qi.MAX_ELEMENT_AGE_DAYS*qi.DAY_MS,l=n?"covered":o<Date.parse(s)-c?"before":o>Date.parse(r)+c?"after":"gap";return{kind:t,status:l,from:s,to:r}}static decode(t,e){const i=new DataView(t),n=[];for(let s=0;s+e<=t.byteLength;s+=e)n.push({norad:i.getUint32(s,!0),epochMs:i.getFloat64(s+4,!0),bstar:i.getFloat32(s+12,!0),inclinationDeg:i.getFloat32(s+16,!0),raanDeg:i.getFloat32(s+20,!0),eccentricity:i.getFloat32(s+24,!0),argOfPerigeeDeg:i.getFloat32(s+28,!0),meanAnomalyDeg:i.getFloat32(s+32,!0),meanMotion:i.getFloat64(s+36,!0)});return n}loadIndex(){return this.index??=(async()=>{for(const t of this.indexUrls)try{const e=await this.fetchImpl(t);if(!e.ok)continue;return{index:await e.json(),base:t}}catch{}})(),this.index}json(t){return this.cached(t,async e=>e.json())}binary(t){return this.cached(t,async e=>e.arrayBuffer())}cached(t,e){let i=this.files.get(t);return i||(i=this.fetchImpl(t).then(n=>{if(!n.ok)throw new Error(`${t}: ${n.status}`);return e(n)}),i.catch(()=>this.files.delete(t)),this.files.set(t,i)),i}}class kD{lowerM;upperM;add(t,e){if(!(t<=0)){if(e.behindM!==void 0){const i=Fe.sizeMAt(e.behindM,t);this.lowerM=this.lowerM===void 0?i:Math.max(this.lowerM,i)}if(e.inFrontM!==void 0){const i=Fe.sizeMAt(e.inFrontM,t);this.upperM=this.upperM===void 0?i:Math.min(this.upperM,i)}}}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(t){return t<=0?{}:{minM:this.lowerM===void 0?void 0:Fe.distanceMAt(this.lowerM,t),maxM:this.upperM===void 0?void 0:Fe.distanceMAt(this.upperM,t)}}clear(){this.lowerM=void 0,this.upperM=void 0}}class Ua{static DEG_PER_SECOND=360/86164.0905;static degOver(t){return Math.max(0,t)*Ua.DEG_PER_SECOND}static instants(t,e){if(!(e>0))return 1;const i=Ua.degOver(t)/e;return i<1?1:Math.min(Ua.MAX_INSTANTS,Math.max(2,Math.ceil(i)))}static MAX_INSTANTS=64}class an{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 Ua.DEG_PER_SECOND*3600}static graspOf(t,e={}){const i=e.exposureSeconds??t.exposureSeconds,n=e.fNumber??t.fNumber;if(i===void 0||n===void 0||!(i>0)||!(n>0))return an.EYE;const s=e.focalLengthMm??t.frame?.focalLengthMm??an.UNKNOWN_CAMERA_FOCAL_MM,r=s/n,o=an.resolutionArcsec(t,s,r);return{apertureMm:r,exposureSeconds:Math.min(i,an.trailLimitedSeconds(o)),resolutionArcsec:o}}static resolutionArcsec(t,e,i){const s=(t.detailUm??an.UNKNOWN_CAMERA_DETAIL_UM)/1e3/e*an.ARCSEC_PER_RADIAN,r=1.22*an.WAVELENGTH_M/(i/1e3)*an.ARCSEC_PER_RADIAN;return Math.max(s,r)}static trailLimitedSeconds(t){return t/an.skyDriftArcsecPerSecond}static gainOverEye(t,e={}){const i=an.graspOf(t,e),n=an.EYE,s=(i.apertureMm/n.apertureMm)**2,r=i.exposureSeconds/n.exposureSeconds,o=(n.resolutionArcsec/i.resolutionArcsec)**2;return 1.25*Math.log10(s*r*o)}static gainFor(t,e){const i=e.fieldOfViewDeg===void 0?void 0:bi.focalLengthMmFor(t,e.fieldOfViewDeg);return an.gainOverEye(t,{fNumber:e.fNumber,focalLengthMm:i,exposureSeconds:e.exposureSeconds})}}const Kv=111320,Pc=Math.PI/180,FD=1.02,UD=1;class tl{static of(t,e){const i=tl.sightings(t,e);if(i.length<2)return;const n=tl.baseline(i);if(!n)return;const{near:s,far:r,closedM:o}=n,c=Math.tan(r.widthDeg/2*Pc)===0?0:Math.tan(s.widthDeg/2*Pc)/Math.tan(r.widthDeg/2*Pc);if(c<FD)return;const l=o/(c-1),h=Fe.sizeMAt(l,s.widthDeg),u=i.map(d=>({t:d.t,m:Fe.distanceMAt(h,d.widthDeg)}));return{widthM:h,distanceM:u,nearestM:Math.min(...u.map(d=>d.m)),fromT:r.t,toT:s.t,closedM:o}}static sightings(t,e){return t.timeline.allKeyframes.flatMap(i=>{const n=i.shapes.find(o=>o.sourceId===e)?.shape,s=n?.angular?.widthDeg,r=Ze(t,i.t);return s===void 0||s<=0||r?.lat===void 0||r.lng===void 0?[]:[{t:i.t,widthDeg:s,lat:r.lat,lng:r.lng,sightAzimuthDeg:n?.aim?.azimuthDeg??r.headingDeg}]}).sort((i,n)=>i.t-n.t)}static baseline(t){let e;for(const i of t)for(const n of t){if(i.t>=n.t)continue;const s=tl.closedAlongSight(i,n),[r,o,c]=s>=0?[n,i,s]:[i,n,-s];c<UD||r.widthDeg<=o.widthDeg||(!e||c>e.closedM)&&(e={near:r,far:o,closedM:c})}return e}static closedAlongSight(t,e){const i=(e.lat-t.lat)*Kv,n=(e.lng-t.lng)*Kv*Math.cos(t.lat*Pc),s=(t.sightAzimuthDeg??0)*Pc;return i*Math.cos(s)+n*Math.sin(s)}}class sn{static CONVENTIONAL_M=5;static NEAREST_M=.2;static MARGIN=1.1;static resolve(t){if(t.statedM!==void 0&&t.statedM>0)return{distanceM:sn.atLeastNearest(t.statedM),basis:"stated"};if(t.hypothesisM!==void 0&&t.hypothesisM>0)return{distanceM:sn.atLeastNearest(t.hypothesisM),basis:"hypothesis"};if(t.derivedM!==void 0&&t.derivedM>0)return{distanceM:sn.atLeastNearest(t.derivedM),basis:"derived"};const e=sn.largest(t.range?.minM,t.crossing?.behindM),i=sn.smallest(t.range?.maxM,t.crossing?.inFrontM),n=e===void 0?void 0:e*sn.MARGIN,s=i===void 0?void 0:i/sn.MARGIN;return n!==void 0&&s!==void 0?{distanceM:sn.atLeastNearest(n<=s?Math.sqrt(n*s):n),basis:"bounded"}:n!==void 0?{distanceM:sn.atLeastNearest(n),basis:"bounded"}:s!==void 0&&s<sn.CONVENTIONAL_M?{distanceM:sn.atLeastNearest(s),basis:"bounded"}:{distanceM:sn.CONVENTIONAL_M,basis:"conventional"}}static atLeastNearest(t){return Math.max(sn.NEAREST_M,t)}static largest(...t){const e=t.filter(i=>i!==void 0&&i>0);return e.length===0?void 0:Math.max(...e)}static smallest(...t){const e=t.filter(i=>i!==void 0&&i>0);return e.length===0?void 0:Math.min(...e)}}const Bf=Math.PI/180;class ce{constructor(t,e,i){this.body=t,this.ground=e;const n=[...t.track].sort((s,r)=>s.t-r.t);this.keys=this.place(n,i);for(const s of n)ce.collect(this.motionKeys,s.t,s.motions),ce.collect(this.lightKeys,s.t,s.lights)}static EYE_HEIGHT_M=1.6;static MAX_RANGE_M=3e4;static DEFAULT_SIZE={widthM:1,lengthM:1,heightM:1};static DEFAULT_APPEARANCE={color:"#c8c8c8",albedo:.5,luminanceCdM2:0};keys;motionKeys=new Map;lightKeys=new Map;static collect(t,e,i){for(const[n,s]of Object.entries(i??{})){const r=t.get(n)??[];r.push({t:e,value:s}),t.set(n,r)}}motionsAt(t){return ce.channelsAt(this.motionKeys,t,0)}lightsAt(t){return this.lightKeys.size>0?ce.channelsAt(this.lightKeys,t,void 0):void 0}static channelsAt(t,e,i){const n={};for(const[s,r]of t){let o=r.length-1;for(;o>=0&&r[o].t>e;)o--;if(o<0){i!==void 0&&(n[s]=i);continue}const c=r[o],l=r[Math.min(o+1,r.length-1)],h=l===c||l.t===c.t?0:Math.min(1,(e-c.t)/(l.t-c.t));n[s]=ce.lerp(c.value,l.value,h)}return n}static eyeOf(t,e,i){const n=Ze(t,0),s=Ze(t,e),o=n?.lat!==void 0&&n.lng!==void 0&&s?.lat!==void 0&&s.lng!==void 0?si(s.lat,s.lng,n.lat,n.lng):void 0,c=o?o.x:0,l=o?-o.z:0;return{eastM:c,northM:l,upM:i.heightAt(c,l)+ce.EYE_HEIGHT_M+(s?.elevationM??0),headingDeg:s?.headingDeg}}static lineOfSightMeetsGround(t,e,i,n){const s=ce.directionOf(e,i),r=l=>t.upM+s.upM*l-n.heightAt(t.eastM+s.eastM*l,t.northM+s.northM*l);let o=0,c=0;for(;c<ce.MAX_RANGE_M;){if(c=o+Math.max(.5,o*.01),r(c)<=0){for(let l=0;l<30;l++){const h=(o+c)/2;r(h)<=0?c=h:o=h}return c}o=c}}static directionOf(t,e){const i=t*Bf,n=e*Bf;return{eastM:Math.sin(i)*Math.cos(n),northM:Math.cos(i)*Math.cos(n),upM:Math.sin(n)}}at(t){const e=this.keys;if(e.length===0||t<e[0].t)return;let i=e.length-1;for(;i>0&&e[i].t>t;)i--;const n=e[i];if(!n.present)return;const s=e[Math.min(i+1,e.length-1)],r=s===n||s.t===n.t?0:Math.min(1,(t-n.t)/(s.t-n.t)),o=ce.lerp(n.eastM,s.eastM,r),c=ce.lerp(n.northM,s.northM,r),l={widthM:ce.lerp(n.sizeM.widthM,s.sizeM.widthM,r),lengthM:ce.lerp(n.sizeM.lengthM,s.sizeM.lengthM,r),heightM:ce.lerp(n.sizeM.heightM,s.sizeM.heightM,r)},h={headingDeg:ce.lerpAngle(n.attitude.headingDeg,s.attitude.headingDeg,r),pitchDeg:ce.lerp(n.attitude.pitchDeg,s.attitude.pitchDeg,r),rollDeg:ce.lerp(n.attitude.rollDeg,s.attitude.rollDeg,r)};let u;if("aboveGroundM"in n.vertical&&"aboveGroundM"in s.vertical){const d=ce.lerp(n.vertical.aboveGroundM,s.vertical.aboveGroundM,r);u=this.groundUnderFootprint(o,c,l,h.headingDeg)+d+l.heightM/2}else u=ce.lerp(this.centreUpOf(n),this.centreUpOf(s),r);return{id:this.body.id,model:this.body.model,explains:this.body.explains??[],outlineNode:this.body.outlineNode,eastM:o,northM:c,upM:u,sizeM:l,attitude:h,appearance:{color:(r<1?n:s).appearance.color,albedo:ce.lerp(n.appearance.albedo,s.appearance.albedo,r),luminanceCdM2:ce.lerp(n.appearance.luminanceCdM2,s.appearance.luminanceCdM2,r)},flame:ce.flameBetween(n.flame,s.flame,r),motions:this.motionsAt(t),lights:this.lightsAt(t),throwsFlame:this.body.track.some(d=>d.flame!==void 0&&d.flame.luminanceCdM2>0)}}static flameBetween(t,e,i){if(!t||t.luminanceCdM2<=0)return i>=1&&e&&e.luminanceCdM2>0?e:void 0;const n=t,s=e??t,r={...i<1?n:s,lengthM:ce.lerp(n.lengthM,s.lengthM,i),widthM:ce.lerp(n.widthM,s.widthM,i),luminanceCdM2:ce.lerp(n.luminanceCdM2,s.luminanceCdM2,i)};return r.luminanceCdM2>0?r:void 0}centreUpOf(t){return"upM"in t.vertical?t.vertical.upM:this.groundUnderFootprint(t.eastM,t.northM,t.sizeM,t.attitude.headingDeg)+t.vertical.aboveGroundM+t.sizeM.heightM/2}groundUnderFootprint(t,e,i,n){const s=n*Bf,r={eastM:Math.cos(s),northM:-Math.sin(s)},o={eastM:Math.sin(s),northM:Math.cos(s)};let c=this.ground.heightAt(t,e);for(const[l,h]of[[-1,-1],[1,-1],[-1,1],[1,1]]){const u=l*i.widthM/2,d=h*i.lengthM/2;c=Math.max(c,this.ground.heightAt(t+r.eastM*u+o.eastM*d,e+r.northM*u+o.northM*d))}return c}place(t,e){const i=[];let n;for(const s of t){const r=s.sizeM??n?.sizeM??ce.DEFAULT_SIZE,o={headingDeg:s.attitude?.headingDeg??n?.attitude.headingDeg??0,pitchDeg:s.attitude?.pitchDeg??n?.attitude.pitchDeg??0,rollDeg:s.attitude?.rollDeg??n?.attitude.rollDeg??0},c={color:s.appearance?.color??n?.appearance.color??ce.DEFAULT_APPEARANCE.color,albedo:s.appearance?.albedo??n?.appearance.albedo??ce.DEFAULT_APPEARANCE.albedo,luminanceCdM2:s.appearance?.luminanceCdM2??n?.appearance.luminanceCdM2??ce.DEFAULT_APPEARANCE.luminanceCdM2},l=this.positionOf(s,r,e)??(n&&{eastM:n.eastM,northM:n.northM,vertical:this.verticalOf(s,r)??n.vertical});if(!l)continue;const h=s.flame??n?.flame,u=s.present??n?.present??!0;n={t:s.t,...l,sizeM:r,attitude:o,appearance:c,flame:h,present:u},i.push(n)}return i}verticalOf(t,e){if(t.onGround)return{aboveGroundM:0};if(t.altitudeAboveGroundM!==void 0)return{aboveGroundM:t.altitudeAboveGroundM};if(t.altitudeM!==void 0)return{upM:t.altitudeM+e.heightM/2}}positionOf(t,e,i){if(t.eastM!==void 0&&t.northM!==void 0)return{eastM:t.eastM,northM:t.northM,vertical:this.verticalOf(t,e)??{aboveGroundM:0}};if(t.azimuthDeg===void 0||t.altitudeDeg===void 0)return;const n=i(t.t);if(!n)return;const s=t.distanceM??(t.onGround?ce.lineOfSightMeetsGround(n,t.azimuthDeg,t.altitudeDeg,this.ground):void 0);if(s===void 0)return;const r=ce.directionOf(t.azimuthDeg,t.altitudeDeg),o=n.eastM+r.eastM*s,c=n.northM+r.northM*s;return{eastM:o,northM:c,vertical:this.verticalOf(t,e)??{upM:n.upM+r.upM*s}}}static lerp(t,e,i){return t+(e-t)*i}static lerpAngle(t,e,i){const n=((e-t)%360+540)%360-180;return((t+n*i)%360+360)%360}}class be{static A=6378137;static E2=.00669437999014;static DEG=Math.PI/180;static STANDARD_DISTANCE_KM=100;static DEFAULT_COLOR="#ffb347";static DEFAULT_TRAIN_S=1.5;static FADE_MS=600;static TRAIN_POINTS=8;static leadAt(t,e){const i=t.track;if(i.length<2||e<i[0].t||e>i[i.length-1].t)return;let n=0;for(;n<i.length-2&&i[n+1].t<e;)n++;const s=i[n],r=i[n+1],o=r.t-s.t,c=o>0?(e-s.t)/o:0,[l,h]=be.alongGreatCircle(s,r,c);return{lat:l,lng:h,heightM:(s.altitudeKm+(r.altitudeKm-s.altitudeKm)*c)*1e3}}static viewsAt(t,e,i){const n=[];for(const s of t){const r=s.track[0]?.t??0,o=s.track[s.track.length-1]?.t??0;s.fragments.forEach((c,l)=>{const h=c.fromT??r,u=c.untilT??o;if(e<h||e>u)return;const d=(c.lagS??0)*1e3,f=be.leadAt(s,e-d);if(!f)return;const p=be.seenFrom(i,f);if(p.altitudeDeg<0)return;const v=Math.min(be.FADE_MS,(u-h)/4),m=v>0?Math.min(1,(e-h)/v,(u-e)/v):1,g=-2.5*Math.log10(Math.max(m,.001)),b=c.absoluteMagnitude+5*Math.log10(p.distanceKm/be.STANDARD_DISTANCE_KM)+g,S=[p],M=(c.trainS??be.DEFAULT_TRAIN_S)*1e3;for(let x=1;x<=be.TRAIN_POINTS;x++){const _=Math.min(M*x/be.TRAIN_POINTS,e-h),A=be.leadAt(s,e-d-_);if(!A||(S.push(be.seenFrom(i,A)),_>=e-h))break}n.push({reentryId:s.id,fragmentId:c.id??String(l),head:p,magnitude:b,color:c.color??be.DEFAULT_COLOR,train:S})})}return n}static seenFrom(t,e){const i=be.ecef(t),n=be.ecef(e),s=n[0]-i[0],r=n[1]-i[1],o=n[2]-i[2],c=t.lat*be.DEG,l=t.lng*be.DEG,h=-Math.sin(l)*s+Math.cos(l)*r,u=-Math.sin(c)*Math.cos(l)*s-Math.sin(c)*Math.sin(l)*r+Math.cos(c)*o,d=Math.cos(c)*Math.cos(l)*s+Math.cos(c)*Math.sin(l)*r+Math.sin(c)*o,f=Math.hypot(h,u,d);return{altitudeDeg:Math.asin(d/f)/be.DEG,azimuthDeg:(Math.atan2(h,u)/be.DEG+360)%360,distanceKm:f/1e3}}static ecef(t){const e=t.lat*be.DEG,i=t.lng*be.DEG,n=Math.sin(e),s=be.A/Math.sqrt(1-be.E2*n*n);return[(s+t.heightM)*Math.cos(e)*Math.cos(i),(s+t.heightM)*Math.cos(e)*Math.sin(i),(s*(1-be.E2)+t.heightM)*n]}static alongGreatCircle(t,e,i){const n=h=>{const u=h.lat*be.DEG,d=h.lng*be.DEG;return[Math.cos(u)*Math.cos(d),Math.cos(u)*Math.sin(d),Math.sin(u)]},s=n(t),r=n(e),o=Math.max(-1,Math.min(1,s[0]*r[0]+s[1]*r[1]+s[2]*r[2])),c=Math.acos(o);let l;if(c<1e-12)l=s;else{const h=Math.sin((1-i)*c)/Math.sin(c),u=Math.sin(i*c)/Math.sin(c);l=[s[0]*h+r[0]*u,s[1]*h+r[1]*u,s[2]*h+r[2]*u]}return[Math.atan2(l[2],Math.hypot(l[0],l[1]))/be.DEG,Math.atan2(l[1],l[0])/be.DEG]}}class pm{static FIRST_DAY="2022-01-01";static mayCover(t){return new Date(t).toISOString().slice(0,10)>=pm.FIRST_DAY}}class zD{constructor(t,e,i){this.citation=t,this.covers=e,this.load=i}loading;mayCover(t){return this.covers(t)}async between(t,e,i,n){try{return await(await this.provider()).between(t,e,i,n)}catch{return{status:"failed"}}}async describe(t,e){try{return await(await this.provider()).describe?.(t,e)}catch{return}}provider(){if(!this.loading){const t=this.load();this.loading=t,t.catch(()=>{this.loading===t&&(this.loading=void 0)})}return this.loading}}const BD="Aircraft positions: adsb.lol feeders and contributors, Open Database License 1.0 (https://www.adsb.lol/docs/open-data/historical/)",HD=[{id:"adsb-lol",name:"adsb.lol",credit:"adsb.lol feeders and contributors, ODbL 1.0",creditUrl:"https://www.adsb.lol/docs/open-data/historical/",create:()=>new zD(BD,a=>pm.mayCover(a),async()=>new(await je(async()=>{const{AdsbLolArchiveProvider:a}=await import("./AdsbLolArchiveProvider-BXH71WVn.js");return{AdsbLolArchiveProvider:a}},[],import.meta.url)).AdsbLolArchiveProvider)}];class on{static MAX_GAP_S=60;static FT_TO_M=.3048;static EARTH_RADIUS_KM=6371;static seenFrom(t,e,i){const n=on.positionAt(t,i);if(!n)return;const s=be.seenFrom(e,n.geo);if(!(s.altitudeDeg<0))return{track:t,sky:s,altitudeFt:n.altitudeFt,groundSpeedKt:n.groundSpeedKt,trackDeg:n.trackDeg,angularRateDegPerS:on.angularRate(t,e,i)}}static viewsAt(t,e,i){return t.flatMap(n=>on.seenFrom(n,e,i)??[])}static groundDistanceKm(t,e){const i=Math.PI/180,n=Math.sin((e.lat-t.lat)*i/2)**2+Math.cos(t.lat*i)*Math.cos(e.lat*i)*Math.sin((e.lng-t.lng)*i/2)**2;return 2*on.EARTH_RADIUS_KM*Math.asin(Math.min(1,Math.sqrt(n)))}static wrapLongitude(t){return((t+180)%360+360)%360-180}static positionAt(t,e){const i=t.points;if(i.length===0||e<i[0].t||e>i[i.length-1].t)return;let n=0;for(;n<i.length-1&&i[n+1].t<=e;)n++;const s=i[n],r=i[n+1]??s,o=r.t-s.t;if(o>on.MAX_GAP_S*1e3)return;const c=o>0?(e-s.t)/o:0,l=s.altitudeFt+(r.altitudeFt-s.altitudeFt)*c,h=(r.lng-s.lng+540)%360-180;return{geo:{lat:s.lat+(r.lat-s.lat)*c,lng:on.wrapLongitude(s.lng+h*c),heightM:l*on.FT_TO_M},altitudeFt:l,groundSpeedKt:s.groundSpeedKt,trackDeg:s.trackDeg}}static angularRate(t,e,i){const n=on.positionAt(t,i-500),s=on.positionAt(t,i+500);if(!n||!s)return;const r=on.unit(be.seenFrom(e,n.geo)),o=on.unit(be.seenFrom(e,s.geo)),c=Math.min(1,Math.max(-1,r[0]*o[0]+r[1]*o[1]+r[2]*o[2]));return Math.acos(c)*180/Math.PI}static unit(t){const e=t.altitudeDeg*Math.PI/180,i=t.azimuthDeg*Math.PI/180;return[Math.cos(e)*Math.sin(i),Math.cos(e)*Math.cos(i),Math.sin(e)]}}const Zv="https://ufoathome.org/fireballs/index.json";class Ps{static FIRST_MONTH="2018-12";static STRIKING_MAGNITUDE=-1;static COLOR="#eef2ff";static TRAIN_S=.3;fetchImpl;indexUrls;index;months=new Map;constructor(t={}){this.fetchImpl=t.fetchImpl??fetch.bind(globalThis),this.indexUrls=t.indexUrls??Ps.defaultIndexUrls()}static defaultIndexUrls(){const t=[];return typeof location<"u"&&/^https?:$/.test(location.protocol)&&t.push(new URL("/fireballs/index.json",location.href).href),t.includes(Zv)||t.push(Zv),t}static mayCover(t){return new Date(t).toISOString().slice(0,7)>=Ps.FIRST_MONTH}async credit(){return(await this.loadIndex())?.index.credit}async between(t,e){if(!Ps.mayCover(e))return;const i=await this.loadIndex();if(!i)return;const n=new Set([new Date(t).toISOString().slice(0,7),new Date(e).toISOString().slice(0,7)]);return[...n].some(r=>r>=i.index.from&&r<=i.index.to)?(await Promise.all([...n].filter(r=>i.index.months.includes(r)).map(r=>this.monthOf(r,i.base)))).flat().filter(r=>r.t>=t&&r.t<=e):void 0}static seenFrom(t,e){const i=Ps.peakFraction(t),n={lat:t.from[0]+(t.to[0]-t.from[0])*i,lng:t.from[1]+(t.to[1]-t.from[1])*i,heightM:t.peakHeightKm*1e3},s=be.seenFrom(e,n);if(!(s.altitudeDeg<0))return{record:t,peak:s,magnitude:t.peakMagnitude+5*Math.log10(s.distanceKm/be.STANDARD_DISTANCE_KM)}}static asReentry(t,e){const i=t.t-e,n=i+Math.max(t.durationS,.1)*1e3;return{id:`gmn-${t.id}`,track:[{t:i,lat:t.from[0],lng:t.from[1],altitudeKm:t.from[2]},{t:n,lat:t.to[0],lng:t.to[1],altitudeKm:t.to[2]}],fragments:[{absoluteMagnitude:t.peakMagnitude,color:Ps.COLOR,trainS:Ps.TRAIN_S}]}}static peakFraction(t){const e=t.from[2]-t.to[2];return Math.abs(e)<1e-6?.5:Math.min(1,Math.max(0,(t.from[2]-t.peakHeightKm)/e))}loadIndex(){return this.index??=(async()=>{for(const t of this.indexUrls)try{const e=await this.fetchImpl(t);if(e.ok)return{index:await e.json(),base:t}}catch{}})(),this.index}monthOf(t,e){let i=this.months.get(t);return i||(i=this.fetchImpl(new URL(`${t}.json`,e).href).then(n=>n.ok?n.json():[]).catch(()=>[]),this.months.set(t,i)),i}}const _o=Math.PI/180,Oc=180/Math.PI;class di{constructor(t){this.timeline=t}static DIRECTION_TOLERANCE_DEG=1;static SIZE_TOLERANCE=1.5;static RINGS=12;static SEGMENTS=24;at(t,e,i,n){const s=[];for(const r of e){const o=di.projectionOf(r,i,n?.(r));if(o)for(const c of r.explains){const l=this.timeline.getInterpolatedShapeAt(t,c);!l||l.transparency>=1||s.push({...di.compare(c,r.id,{aim:l.aim,angular:l.angular},o),title:l.title})}}return s}static compare(t,e,i,n){const s=[],r=i.aim?di.separationDeg(i.aim,n.aim):void 0;if(r!==void 0){const l=Math.max(i.angular?.widthDeg??0,n.angular.widthDeg)/2;r>Math.max(di.DIRECTION_TOLERANCE_DEG,l)&&s.push("direction")}const o=i.angular&&i.angular.widthDeg>0?n.angular.widthDeg/i.angular.widthDeg:void 0,c=i.angular&&i.angular.heightDeg>0?n.angular.heightDeg/i.angular.heightDeg:void 0;return o!==void 0&&!di.withinSize(o)&&s.push("width"),c!==void 0&&!di.withinSize(c)&&s.push("height"),{sourceId:t,bodyId:e,stated:i,predicted:n,separationDeg:r,widthRatio:o,heightRatio:c,disagreements:s}}static projectionOf(t,e,i){const n=i&&i.length>0?i:di.outlineOf(t),s=i&&i.length>0?di.centreOf(i):t,r=di.normalized({eastM:s.eastM-e.eastM,northM:s.northM-e.northM,upM:s.upM-e.upM});if(!r)return;const o=di.normalized({eastM:r.northM,northM:-r.eastM,upM:0})??{eastM:1,northM:0,upM:0},c=di.cross(o,r);let l=1/0,h=-1/0,u=1/0,d=-1/0;for(const f of n){const p={eastM:f.eastM-e.eastM,northM:f.northM-e.northM,upM:f.upM-e.upM},v=di.dot(p,r);if(v<=0)return;const m=Math.atan2(di.dot(p,o),v),g=Math.atan2(di.dot(p,c),v);l=Math.min(l,m),h=Math.max(h,m),u=Math.min(u,g),d=Math.max(d,g)}return{aim:{azimuthDeg:(Math.atan2(r.eastM,r.northM)*Oc+360)%360,altitudeDeg:Math.asin(Math.max(-1,Math.min(1,r.upM)))*Oc},angular:{widthDeg:(h-l)*Oc,heightDeg:(d-u)*Oc}}}static centreOf(t){const e=i=>(Math.min(...t.map(n=>n[i]))+Math.max(...t.map(n=>n[i])))/2;return{eastM:e("eastM"),northM:e("northM"),upM:e("upM")}}static separationDeg(t,e){const i=t.altitudeDeg*_o,n=e.altitudeDeg*_o,s=Math.sin(i)*Math.sin(n)+Math.cos(i)*Math.cos(n)*Math.cos((t.azimuthDeg-e.azimuthDeg)*_o);return Math.acos(Math.max(-1,Math.min(1,s)))*Oc}static withinSize(t){return t<=di.SIZE_TOLERANCE&&t>=1/di.SIZE_TOLERANCE}static outlineOf(t){const e=t.sizeM.widthM/2,i=t.sizeM.lengthM/2,n=t.sizeM.heightM/2,s=[],r=t.model.url===void 0?t.model.id:void 0;if(r!==void 0&&r!=="box"&&sy.includes(r))for(let u=0;u<=di.RINGS;u++){const d=u/di.RINGS*Math.PI;for(let f=0;f<di.SEGMENTS;f++){const p=f/di.SEGMENTS*2*Math.PI;s.push([e*Math.sin(d)*Math.cos(p),i*Math.sin(d)*Math.sin(p),n*Math.cos(d)])}}else for(const u of[-e,e])for(const d of[-i,i])for(const f of[-n,n])s.push([u,d,f]);const c=t.attitude.headingDeg*_o,l=t.attitude.pitchDeg*_o,h=t.attitude.rollDeg*_o;return s.map(([u,d,f])=>{const p=u*Math.cos(h)+f*Math.sin(h),v=-u*Math.sin(h)+f*Math.cos(h),m=d*Math.cos(l)-v*Math.sin(l),g=d*Math.sin(l)+v*Math.cos(l);return{eastM:t.eastM+p*Math.cos(c)+m*Math.sin(c),northM:t.northM-p*Math.sin(c)+m*Math.cos(c),upM:t.upM+g}})}static dot(t,e){return t.eastM*e.eastM+t.northM*e.northM+t.upM*e.upM}static cross(t,e){return{eastM:t.northM*e.upM-t.upM*e.northM,northM:t.upM*e.eastM-t.eastM*e.upM,upM:t.eastM*e.northM-t.northM*e.eastM}}static normalized(t){const e=Math.hypot(t.eastM,t.northM,t.upM);return e>1e-9?{eastM:t.eastM/e,northM:t.northM/e,upM:t.upM/e}:void 0}}PM();const GD={sun:"Sun",moon:"Moon",Venus:"Venus",Mars:"Mars",Jupiter:"Jupiter",Saturn:"Saturn"},VD="{name} — mag {mag}, {alt}° above the horizon",WD="{name} — satellite, mag {mag}, {height} km up",XD="satellites-change",YD="fireballs-change",qD="aircraft-change",ly="rr0-confrontation",$D="{name} — mag {mag}, {alt}° below the horizontal",Hf="Credits",Jv="comet:",jv="nova:",Qv={building:"Building",tree:"Tree",shrub:"Shrub",bridge:"Bridge",wire:"Overhead line",crop:"Crop row",terrace:"Terrace (restanque)",mound:"Stone heap",streetlight:"Streetlight",vehicle:"Vehicle",observer:"Observer",aircraft:"Aircraft",entity:"Being"},KD=new URL(""+new URL("lunar-relief.bin-ByThqxUn.gz",import.meta.url).href,import.meta.url).href,ZD=new URL(""+new URL("stars-mag7.5-B43R6Wvg.bin",import.meta.url).href,import.meta.url).href,JD=new URL(""+new URL("stars-mag7.5-9-BLV2tFmZ.bin",import.meta.url).href,import.meta.url).href,jD=-18,QD={sun:{altitudeDeg:-3,azimuthDeg:180,magnitude:-26.7},moon:{altitudeDeg:-90,azimuthDeg:0,phase:{phaseFraction:0,illuminatedFraction:0},magnitude:-12.7},planets:[]},Lh={lat:0,lng:0,elevationM:0,headingDeg:void 0,pitchDeg:0,fovDeg:60};class $e extends HTMLElement{creditsButton;set ownCredits(t){this.creditsButton.hidden=!t}static get observedAttributes(){return["src","star-catalog-src","deep-star-catalog-src","show-compass","max-pixel-ratio",ks,Fs]}shadow;stageElement;frameElement;sceneCanvas;loaderNote;loaderNotVideo;ufoElement;sceneRenderer;hoverTooltip;resizeObserver;sizeEstimates=new Map;sizeEstimatesFor;distanceHypotheses=new Map;depths=new Map;directionScratch=new R;meteorScheduleFor;lightningScheduleFor;lightningFlashes=[];lastLightningT;lastTimeMs=0;interpretationShown;confrontationReadings=[];confrontationSignature="";comparing=!1;inTheRound=!0;lastSkyKey;starCatalog;starCatalogRequest=0;static tleArchive=new qi;satellitesFor;satelliteRequest=0;satelliteStatus="none";satellites;satellitePassesMemo;static fireballArchive=new Ps;fireballs;static aircraftProviders=new Map;static SOUND_LOOKBACK_MS=3e5;static NO_CONTRAILS=[];static upperAirProviders=new Map;static NO_PRESENCE=new Map;aircraftSource=HD[0];static trafficRuntimeLoading;static trafficRuntime;static loadTrafficRuntime(){return $e.trafficRuntimeLoading??=je(()=>import("./trafficRuntime-BhspObgN.js"),__vite__mapDeps([2,1]),import.meta.url).then(t=>$e.trafficRuntime=t),$e.trafficRuntimeLoading.catch(()=>{$e.trafficRuntimeLoading=void 0}),$e.trafficRuntimeLoading}traffic;lastSun;decorMemo;seatedMemo;starCatalogDepth=0;weatherAudio=new OD;vehicleAudio=new Wx;aircraftAudio;vehicleHearing=new xu;thunderTimeoutId;handleFullscreenChange=()=>this.resizeToStage();handlePointerMove=t=>{this.sceneRenderer.setCompassHovered(!0);const e=this.ufoElement.canvasElement,i=e.getBoundingClientRect();if(i.width===0||i.height===0)return;const n=(t.clientX-i.left)/i.width*e.width,s=(t.clientY-i.top)/i.height*e.height;if(this.ufoElement.hasVisibleShapeAt(n,s)){this.hoverTooltip.hidden=!0;return}const r=(t.clientX-i.left)/i.width*2-1,o=-((t.clientY-i.top)/i.height*2-1),c=this.naming,l=c.names,h=this.sceneRenderer.pickBodyAt(r,o);if(h){this.showHoverTooltip(t,this.bodyName(h));return}const u=this.interpretationShown?this.sceneRenderer.pickInterpretationBodyAt(r,o):void 0,d=u?this.interpretationShown?.bodies.find(S=>S.id===u):void 0,f=d?this.said.read(d.title)||(d.model.id==="figure"?c.decorKind("entity",Qv.entity):void 0):void 0;if(f){this.showHoverTooltip(t,f);return}const p=this.sceneRenderer.pickDecorAt(r,o),v=p?this.ufoElement.sighting.decor.find(S=>S.id===p):void 0;if(v){this.showHoverTooltip(t,this.said.read(v.title)||c.decorKind(v.kind,Qv[v.kind]));return}const m=this.trafficTooltipAt(r,o);if(m){this.showHoverTooltip(t,m);return}const g=this.sceneRenderer.pickSatelliteAt(r,o);if(g){this.showHoverTooltip(t,(l?.satelliteTooltip??WD).replace("{name}",g.name).replace("{mag}",g.magnitude.toLocaleString(void 0,{maximumFractionDigits:1})).replace("{height}",Math.round(g.heightKm).toLocaleString()));return}const b=this.sceneRenderer.pickStarAt(r,o);if(b){const S=b.star.mag,M=b.altitudeDeg,x=M<0?l?.starTooltipBelow??$D:l?.starTooltip??VD;this.showHoverTooltip(t,x.replace("{name}",c.star(b.star)).replace("{mag}",S.toLocaleString(void 0,{maximumFractionDigits:Math.abs(S)<1?2:1})).replace("{alt}",String(Math.round(Math.abs(M)))));return}this.hoverTooltip.hidden=!0};bodyName(t){const e=t.startsWith(Jv)?t.slice(Jv.length):void 0,i=e?cy.find(r=>r.id===e):void 0;if(i)return this.naming.comet(i);const n=t.startsWith(jv)?qv.byId(t.slice(jv.length)):void 0;if(n)return this.naming.nova(n);const s=GD[t];return s===void 0?t:this.naming.body(t,s)}get naming(){return this.sceneNaming}sceneNaming=new Xu;namesLanguage="en";async loadSceneNames(){const t=Ep(Gr.preferencesFor(this),Ap);if(t===this.namesLanguage)return;this.namesLanguage=t;const e=await bM(t);t===this.namesLanguage&&this.applySceneNaming(new Xu(e))}renderLoaderText(t,e){let i=0;const n=(s,r)=>{s.setAttribute("aria-label",r),s.replaceChildren(),r.split(" ").forEach((o,c)=>{c>0&&s.append(" ");const l=document.createElement("span");l.className="scene-loader-word",l.setAttribute("aria-hidden","true");for(const h of o){const u=document.createElement("span");u.className="scene-loader-letter",u.style.setProperty("--i",String(i++)),u.textContent=h,l.append(u)}s.append(l),i++})};n(this.loaderNotVideo,t),i+=6,n(this.loaderNote,e)}applySceneNaming(t){this.sceneNaming=t;const e=t.names?.credits??Hf;this.creditsButton.title=e,this.creditsButton.setAttribute("aria-label",e),t.names&&this.renderLoaderText(t.names.notAVideo,t.names.isASimulation),this.sceneRenderer.setCompassPoints(t.names?.compassPoints)}showHoverTooltip(t,e){this.hoverTooltip.textContent=e,this.hoverTooltip.hidden=!1;const i=this.stageElement.getBoundingClientRect();this.hoverTooltip.style.left=`${t.clientX-i.left+12}px`,this.hoverTooltip.style.top=`${t.clientY-i.top+12}px`}handlePointerLeave=()=>{this.hoverTooltip.hidden=!0,this.sceneRenderer.setCompassHovered(!1)};handleLightningFlash(t){clearTimeout(this.thunderTimeoutId),this.thunderTimeoutId=window.setTimeout(()=>this.weatherAudio.playThunder(),Ii.thunderDelayMs(t))}handleFirstInteraction=()=>{this.weatherAudio.resume(),this.vehicleAudio.resume(),this.aircraftAudio?.resume(),!this.interacted&&(this.interacted=!0,this.setWeather(Dl(this.ufoElement.sighting,this.lastTimeMs)))};interacted=!1;applyLevel(){const t=this.ufoElement.level;this.weatherAudio.setLevel(t),this.vehicleAudio.setLevel(t),this.aircraftAudio?.setLevel(t)}handlePageGesture=()=>{this.ufoElement.playbackState==="playing"&&this.handleFirstInteraction()};unlockIfAlreadyActivated(){this.interacted||navigator.userActivation?.hasBeenActive&&this.handleFirstInteraction()}static GESTURES=["pointerdown","pointerup","touchend","click","keydown"];handleTimeUpdate=t=>{this.lastTimeMs=t.detail.time,this.syncAnimationsToPlayback(),this.updateAstronomy(this.lastTimeMs),this.ufoElement.playbackState==="playing"&&this.sceneRenderer.frame(performance.now())};syncAnimationsToPlayback(){const t=this.ufoElement.playbackState==="playing";this.sceneRenderer.setAnimationsRunning(t,t),this.weatherAudio.setPaused(!t),this.vehicleAudio.setPaused(!t),this.aircraftAudio?.setPaused(!t),t&&this.unlockIfAlreadyActivated(),t||clearTimeout(this.thunderTimeoutId)}constructor(){super(),this.shadow=this.attachShadow({mode:"open"});const t=document.createElement("template");t.innerHTML=`<style>${qx}</style>${Yx}`,this.shadow.appendChild(t.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 le(this.sceneCanvas);const e=this.shadow.getElementById("scene-loader");this.loaderNote=this.shadow.getElementById("scene-loader-note"),this.loaderNotVideo=this.shadow.getElementById("scene-loader-not-video"),this.renderLoaderText("This is not a video","It is a real-time simulation."),this.sceneRenderer.onFirstFrameHold=s=>{e.hidden=!s,this.ufoElement.captionHeld=s,this.ufoElement.holdClock(s)},this.hoverTooltip=this.shadow.getElementById("hover-tooltip"),this.ufoElement=document.createElement(Kf),this.ufoElement.classList.add("ufo-overlay"),this.ufoElement.paintsShapes=!1,this.forwardPlayerAttributes(),this.ufoElement.addEventListener("lookat",s=>this.lookToward(s.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.creditShownExternally=!0,this.creditsButton=this.shadow.getElementById("credits-button");const i=this.shadow.getElementById("credits-panel"),n=this.shadow.getElementById("credits-list");i.addEventListener("beforetoggle",s=>{s.newState==="open"&&rn.fill(n,this)}),this.creditsButton.title=Hf,this.creditsButton.setAttribute("aria-label",Hf),this.sceneRenderer.onMapSubjectBounds=s=>this.ufoElement.setMapSubjectBounds(s),this.ufoElement.addEventListener("timeupdate",this.handleTimeUpdate),this.ufoElement.seekPreviewPainter=(s,r)=>this.seekPreviewOf(r).paint(s,r),this.ufoElement.addEventListener("mutedchange",()=>this.applyLevel()),this.ufoElement.ambientSound=s=>s.vehicle!==void 0||s.decor.some(r=>r.engine!==void 0)||s.weatherTrack.allKeyframes.some(r=>r.weather.precipitationType!=="none"||r.weather.windSpeed>1),this.ufoElement.addEventListener("referenceview",s=>this.applyReferenceView(s.detail)),this.ufoElement.addEventListener("traceview",s=>this.sceneRenderer.setTracesShown(s.detail.shown)),this.ufoElement.canvasElement.addEventListener("pointermove",this.handlePointerMove),this.ufoElement.canvasElement.addEventListener("pointerleave",this.handlePointerLeave);for(const s of $e.GESTURES)this.addEventListener(s,this.handleFirstInteraction,!0)}get said(){return this.saidTexts??=new Yn(Gr.preferencesFor(this))}saidTexts;traceLabelsFor;traceLabels(t){const e=Gr.preferencesFor(this).join();if(this.traceLabelsFor?.traces!==t||this.traceLabelsFor.language!==e){const i=new Map;for(const n of t){const s=this.said.read(n.title);s&&i.set(n.id,s)}this.traceLabelsFor={traces:t,language:e,labels:i}}return this.traceLabelsFor.labels}connectedCallback(){this.saidTexts=void 0,this.loadSceneNames(),this.sceneRenderer.restoreContext(),this.resizeToStage(),this.updateAstronomy(this.lastTimeMs),this.loadStars(),this.resizeObserver=new ResizeObserver(()=>this.resizeToStage()),this.resizeObserver.observe(this.frameElement),this.watchVisibility(),document.addEventListener("fullscreenchange",this.handleFullscreenChange);for(const e of $e.GESTURES)document.addEventListener(e,this.handlePageGesture,!0);const t=this.getAttribute("src");t&&this.loadFromSrc(t)}watchVisibility(){this.visibilityObserver?.disconnect(),!(typeof IntersectionObserver>"u")&&(this.visibilityObserver=new IntersectionObserver(t=>{if(t[t.length-1].isIntersecting){this.sceneRenderer.resume();return}this.ufoElement.pause(),this.sceneRenderer.suspend()},{rootMargin:"100px"}),this.visibilityObserver.observe(this))}visibilityObserver;disconnectedCallback(){this.visibilityObserver?.disconnect(),this.resizeObserver?.disconnect(),document.removeEventListener("fullscreenchange",this.handleFullscreenChange);for(const t of $e.GESTURES)document.removeEventListener(t,this.handlePageGesture,!0);this.sceneRenderer.stopTwinkle(),clearTimeout(this.thunderTimeoutId),this.weatherAudio.dispose(),this.vehicleAudio.dispose(),this.aircraftAudio?.dispose(),this.seekPreview?.dispose(),this.seekPreview=void 0,queueMicrotask(()=>{this.isConnected||this.sceneRenderer.releaseContext()})}attributeChangedCallback(t,e,i){if(t==="src"&&i&&i!==e&&this.isConnected&&this.loadFromSrc(i),(t==="star-catalog-src"||t==="deep-star-catalog-src")&&i!==e&&this.isConnected&&this.loadStars(),t==="show-compass"&&i!==e&&this.sceneRenderer.setShowCompass(this.hasAttribute("show-compass")),t==="max-pixel-ratio"&&i!==e){const n=Number(i);this.sceneRenderer.setMaxPixelRatio(Number.isFinite(n)&&n>0?n:Math.min(window.devicePixelRatio||1,2))}(t===ks||t===Fs)&&i!==e&&this.forwardPlayerAttributes()}forwardPlayerAttributes(){for(const t of[ks,Fs]){const e=this.getAttribute(t);e===null?this.ufoElement.removeAttribute(t):this.ufoElement.setAttribute(t,e)}}setCompassForced(t){this.sceneRenderer.setCompassForced(t)}lookToward(t){const e=Ze(this.ufoElement.sighting,this.lastTimeMs);if(t.kind==="observer"||e?.lat===void 0||e.lng===void 0||e.headingDeg===void 0){this.setLookOffset(0,0);return}const{x:i,z:n}=si(t.lat,t.lng,e.lat,e.lng);if(Math.hypot(i,n)<1)return this.setLookOffset(0,0);const s=(Math.atan2(i,-n)*180/Math.PI+360)%360;this.setLookOffset(((s-e.headingDeg)%360+540)%360-180,-e.pitchDeg)}setLookOffset(t,e){this.sceneRenderer.setLookOffset(t,e),this.ufoElement.setLookOffset(t,e),this.updateAstronomy(this.lastTimeMs)}setIndoorLook(t,e){this.sceneRenderer.setIndoorLook(t,e)}setCloudRendering(t){this.sceneRenderer.setCloudRendering(t)}setWeather(t){this.sceneRenderer.setWeather(t),this.weatherAudio.setAmbient(t.precipitationType,t.precipitationIntensity*(t.precipitationAmount??1),t.windSpeed)}pickCloudAt(t,e){return this.sceneRenderer.pickCloudAt(t,e)}cloudDirectionAt(t,e){return this.sceneRenderer.cloudDirectionAt(t,e)}pickDecorAt(t,e){return this.sceneRenderer.pickDecorAt(t,e)}decorScreenBox(t){return this.sceneRenderer.decorScreenBox(t)}decorGroundPointAt(t,e,i){return this.sceneRenderer.decorGroundPointAt(t,e,i)}bodyScreenBox(t){return this.sceneRenderer.bodyScreenBox(t)}pickPlacedBodyAt(t,e){return this.sceneRenderer.pickPlacedBodyAt(t,e)}resumeWeatherAudio(){this.weatherAudio.resume(),this.vehicleAudio.resume(),this.aircraftAudio?.resume()}async loadFromSrc(t){const e=Gc.json(t);this.holdForNewScene(e);const i=await e;this.documentUrl=new URL(t,location.href).href,this.sightingData=i}holdForNewScene(t){this.sceneRenderer.holdForNewScene(t)}get documentUrl(){return this.sceneRenderer.documentUrl}set documentUrl(t){this.sceneRenderer.documentUrl=t}get sightingData(){return this.ufoElement.sightingData}set sightingData(t){this.ufoElement.sightingData=t,this.seekPreview?.recordingChanged(t),this.interpretationShown=this.inTheRound?this.ufoElement.sighting.interpretation:void 0,this.syncAccountHidden(),this.applyFrameFormat(),this.lastTimeMs=0,this.sceneRenderer.compileNextFrameOffThread(),this.updateAstronomy(0)}seekPreview;seekPreviewOf(t){const e=this.sceneCanvas.width>0&&this.sceneCanvas.height>0?this.sceneCanvas.width/this.sceneCanvas.height:1.7777777777777777,i=Math.round(t.width/e);return t.height!==i&&(t.height=i),this.seekPreview??=new Wu(this,()=>document.createElement(qu))}showAt(t){this.ufoElement.currentTime=t,this.framesAtAsk=this.sceneRenderer.framesDrawn}framesAtAsk=0;snapshotTo(t){if(this.sceneRenderer.frame(performance.now()),this.sceneRenderer.framesDrawn===this.framesAtAsk)return!1;const e=t.getContext("2d");return e?(e.drawImage(this.sceneCanvas,0,0,t.width,t.height),!0):!1}referenceAspect(t){return this.sceneRenderer.referenceAspect(t)}screenPointOf(t){return this.sceneRenderer.screenPointOf(t)}directionAt(t,e){return this.sceneRenderer.directionAt(t,e)}referenceFailedToLoad(t){return this.sceneRenderer.referenceFailedToLoad(t)}applyReferenceView(t){this.sceneRenderer.setReferencesShown(t.shown);for(const e of this.ufoElement.sighting.references){const i=t.views?.[e.id];this.sceneRenderer.setReferenceView(e.id,{opacity:i?i.shown?i.opacity:0:t.opacity})}}get currentTerrainAttribution(){return this.sceneRenderer.currentTerrainAttribution}get currentRoadAttribution(){return this.sceneRenderer.currentRoadAttribution}setTerrainProviders(t){this.sceneRenderer.setTerrainProviders(t)}setDecorModelProvider(t){this.sceneRenderer.setDecorModelProvider(t)}get decorModelCredits(){return[...new Map(this.sceneRenderer.currentDecorModelCredits.map(e=>[`${e.title}|${e.author??""}|${e.license}|${e.sourceUrl??""}`,e])).values()]}applyFrameFormat(){const t=this.ufoElement.sighting.instrument,e=Fe.CANVAS_HEIGHT_PX,i=bi.frameWidthPx(t,e);this.frameElement.style.setProperty("--frame-aspect",`${i} / ${e}`)}resizeToStage(){const t=this.frameElement.getBoundingClientRect(),e=Math.max(1,Math.round(t.width)),i=Math.max(1,Math.round(t.height));this.sceneCanvas.width=e,this.sceneCanvas.height=i,this.sceneRenderer.resize(e,i)}async loadStars(){const t=[{magnitudeLimit:kf,url:this.getAttribute("star-catalog-src")??ZD},{magnitudeLimit:Ff,url:this.getAttribute("deep-star-catalog-src")??JD}],e=this.instrumentReach(),i=++this.starCatalogRequest;this.starCatalogDepth=e>kf?Ff:kf;const n=await _s.upTo(t,e);i===this.starCatalogRequest&&(this.starCatalog=n,this.sceneRenderer.compileNextFrameOffThread(),this.updateAstronomy(this.lastTimeMs))}ensureStarsDeepEnough(){!this.starCatalog||this.starCatalogDepth>=Ff||this.instrumentReach()<=this.starCatalogDepth||this.loadStars()}instrumentReach(){const t=this.ufoElement.sighting,e=an.gainFor(t.instrument,{fNumber:Ze(t,0)?.fNumber,fieldOfViewDeg:xn.fovOf(t,0),exposureSeconds:t.exposure});return Kh(jD,e)}updateAstronomy(t){this.ensureStarsDeepEnough(),this.applySceneAt(t);const e=as.windowEndingAt(t,this.exposureSeconds()),i=e.seconds,n=this.degreesPerPixelAt(t),s=Ua.instants(i,n),r=Math.max(s,this.ufoElement.exposureTimes(t).length,as.instants(this.decorWithTraffic(this.ufoElement.sighting),Ze(this.ufoElement.sighting,t)?.elevationM??0,e.fromMs,i,n));if(r<=1){this.sceneRenderer.setExposure(1);return}this.sceneRenderer.setExposure(r,o=>this.applySceneAt(e.fromMs+e.ms*o/(r-1),{sky:Math.floor(o*s/r)!==Math.floor((o-1)*s/r),stepMs:e.ms/r}))}exposureSeconds(){return this.ufoElement.sighting.exposure??0}degreesPerPixelAt(t){const e=this.sceneCanvas.height;return e<=0?0:xn.fovOf(this.ufoElement.sighting,t)/e}roadGradeAt(t,e){return t.observerTrack.allKeyframes.length<2?0:Ro.at(t,e,this.sceneRenderer.bodyGround)}get roadGradeDeg(){return this.roadGradeAt(this.ufoElement.sighting,this.ufoElement.currentTime)}applySceneAt(t,e){const i=this.ufoElement.sighting;this.setWeather(Dl(i,t)),this.sceneRenderer.setInstrument(i.instrument),this.sceneRenderer.setLightPollution(i.lightPollution),e||this.vehicleAudio.setVoices(this.vehicleHearing.at(i,t)),e||this.pushAircraftSound(i,t),this.updateMeteorShower(i,t),this.updateLightning(i,t,e!==void 0),this.sceneRenderer.setDecor(this.seatedDecor(this.decorWithTraffic(i),t)),this.sceneRenderer.setDecorPresence(this.traffic?.set?.presence??$e.NO_PRESENCE),this.sceneRenderer.setDecorSunlight(this.trafficSunlight(t)),this.sceneRenderer.setContrails(this.traffic?.contrails??$e.NO_CONTRAILS),this.sceneRenderer.setContrailSunlight(this.contrailSunlight(t));const n=Ze(i,t);this.sceneRenderer.setReferences(i.references,n?.lat!==void 0&&n.lng!==void 0?{lat:n.lat,lng:n.lng}:void 0);const s=Ze(i,0),r=Eo(i,0),o=ra(i.event.time??{},n?.lng??Lh.lng,i.event.utcOffsetHours),c=i.weatherSource!==void 0&&o?Xx(o):void 0,l=Object.fromEntries(Qh(Eo(i,t)).map(T=>[T.id,eg(t,i.weatherTrack,r,s,n,T.id,T.instances?.length?void 0:c)]));this.sceneRenderer.setCloudOffset(eg(t,i.weatherTrack,r,s,n,void 0,c),l),this.sceneRenderer.setObserverPose(n?{...n,pitchDeg:n.pitchDeg+this.roadGradeAt(i,t)}:Lh),this.sceneRenderer.setLensOptics(this.lensOpticsAt(t)),this.sceneRenderer.setInstrumentGain(an.gainFor(i.instrument,{fNumber:n?.fNumber,fieldOfViewDeg:xn.fovOf(i,t),exposureSeconds:i.exposure}),i.instrument.detailUm!==void 0,ls.byId(n?.filter).opticalDensity),this.sceneRenderer.setMedium(i.instrument.medium,i.exposure,n?.fNumber??i.instrument.fNumber,i.iso),this.sceneRenderer.setGait(Ce.bodyAt(i,t,this.ufoElement.steadyBody)),this.sceneRenderer.updateDecorAnchoring(Ze(i,0),n,t),this.placeBodiesAt(t,e===void 0),this.sceneRenderer.updateDecorLitState(t,e?.stepMs??0),this.sceneRenderer.setTerrainOrigin(n?.lat,n?.lng,()=>{this.placeBodiesAt(this.lastTimeMs,!0),this.sceneRenderer.render()}),this.sceneRenderer.setStatedRoads(i.roads),this.sceneRenderer.setTraces(i.traces,this.traceLabels(i.traces)),this.pushPhenomenaAt(t);const h=n?.lat??Lh.lat,u=n?.lng??Lh.lng,d=ra(i.event.time??{},u,i.event.utcOffsetHours),f={lat:h,lng:u,elevationM:n?.elevationM??0};this.pushSatellitesAt(d,t,f),this.ensureFireballs(d);const p=[...this.interpretationShown?.reentries??[],...this.fireballs?.reentries??[]];if(this.sceneRenderer.setReentries(p.length===0?[]:be.viewsAt(p,t,{lat:h,lng:u,heightM:f.elevationM})),e&&!e.sky)return;if(!d){this.sceneRenderer.setAstronomy(QD);return}const v=new Date(d.getTime()+t),m=Math.max(1,Math.round(.25*this.degreesPerPixelAt(t)/Ua.DEG_PER_SECOND*1e3)),g=Math.max(1e-8,this.degreesPerPixelAt(t)*.1),b=`${Math.floor(v.getTime()/m)}|${Math.round(h/g)}|${Math.round(u/g)}|${Math.round(f.elevationM)}|${this.starCatalog?this.starCatalogDepth:0}`;if(b===this.lastSkyKey){this.sceneRenderer.render();return}this.lastSkyKey=b;const S=xh("Sun",v,f),M=xh("Moon",v,f);let x=Mi.separationOf(S,M)<1?Mi.viewAt(v,f):void 0;if(x){const T=Mi.offsetOf(S,M,x.separationDeg);if(x.obscuration>$e.LIMB_FROM_OBSCURATION){const I=this.limbFor(v,f);I&&(x={...x,obscuration:1-Vn.uncoveredFraction(I,x.sunRadiusDeg,T),limb:I})}x={...x,horizonShare:Mi.horizonShare(x,T,S.altitudeDeg,S.azimuthDeg,Cs.distanceKm(v,f))}}const _={...S,magnitude:uf("Sun",v)-2.5*Math.log10(Mi.beamFraction(x))};this.lastSun={altitudeDeg:_.altitudeDeg,azimuthDeg:_.azimuthDeg};const A={...M,phase:R4(v),magnitude:uf("Moon",v),radiusDeg:Cs.apparentRadiusDeg(v,f)},y=T4.map(T=>({body:T,position:xh(T,v,f),magnitude:uf(T,v)}));this.sceneRenderer.setAstronomy({sun:_,moon:A,planets:y,comet:this.cometAt(v,f),novae:qv.appearancesAt(v,f).map(({outburst:T,position:I,magnitude:C})=>({id:T.id,position:I,magnitude:C})),stars:this.starCatalog?{catalog:this.starCatalog,date:v,observer:f}:void 0,frame:{date:v,observer:f},eclipse:x}),this.ufoElement.setSunAltitude(_.altitudeDeg)}static LIMB_FROM_OBSCURATION=.98;limbRelief;limbRequested=!1;limbCache;limbFor(t,e){if(!this.limbRelief){this.limbRequested||(this.limbRequested=!0,Qc.load(KD).then(s=>{this.limbRelief=s,this.lastSkyKey="",s&&this.isConnected&&this.updateAstronomy(this.lastTimeMs)}));return}const i=this.limbCache;if(i&&Math.abs(t.getTime()-i.atMs)<5e3&&i.lat===e.lat&&i.lng===e.lng&&i.elevationM===e.elevationM)return i.profile;const n=Vn.profile(t,e,this.limbRelief);return this.limbCache={profile:n,atMs:t.getTime(),lat:e.lat,lng:e.lng,elevationM:e.elevationM},n}pushSatellitesAt(t,e,i){if(this.ensureSatellites(t),!t||!this.satellites){this.sceneRenderer.setSatellites([]);return}const n=new Date(t.getTime()+e),s=[];for(const r of this.satellites.passes.positionsAt(n,i,-1))r.magnitude!==void 0&&s.push({norad:r.object.norad,name:r.object.name,position:{altitudeDeg:r.altitudeDeg,azimuthDeg:r.azimuthDeg},magnitude:r.magnitude,heightKm:r.heightKm});this.sceneRenderer.setSatellites(s)}ensureFireballs(t){const e=this.ufoElement.sighting,i=Math.max((e.event.durationSeconds??0)*1e3,this.ufoElement.seekableDuration),n=t?.getTime(),s=n===void 0?"":`${n}+${i}`;if(this.fireballs?.key===s)return;if(n===void 0||!Ps.mayCover(n+i)){this.fireballs={key:s,status:"outside",reentries:[]};return}const r={key:s,status:"loading",reentries:[]};this.fireballs=r,$e.fireballArchive.between(n,n+i).then(o=>{r.status=o?"ready":"unavailable",r.records=o??[],r.reentries=r.records.map(c=>Ps.asReentry(c,n)),!(this.fireballs!==r||!this.isConnected)&&(this.dispatchEvent(new CustomEvent(YD)),r.reentries.length>0&&this.updateAstronomy(this.lastTimeMs))})}decorWithTraffic(t){const e=this.ensureTraffic(t);if(!e||e.objects.length===0)return t.decor;const i=this.decorMemo;if(i&&i.base===t.decor&&i.traffic===e.objects)return i.merged;const n=[...t.decor,...e.objects];return this.decorMemo={base:t.decor,traffic:e.objects,merged:n},n}seatedDecor(t,e){if(!t.some(r=>r.observerKeyframes?.length))return t;const i=t.map(r=>{if(!r.observerKeyframes?.length)return"";const o=Ym(r,e);return`${o.side??"-"}/${o.facing??"-"}`}).join("|"),n=this.seatedMemo;if(n&&n.base===t&&n.seats===i)return n.seated;const s=t.map(r=>{if(!r.observerKeyframes?.length)return r;const o=Ym(r,e);return{...r,observerSide:o.side,observerFacing:o.facing}});return this.seatedMemo={base:t,seats:i,seated:s},s}ensureTraffic(t){const e=Ze(t,0),i=e?.lng===void 0?void 0:ra(t.event.time??{},e.lng,t.event.utcOffsetHours),n=Math.max((t.event.durationSeconds??0)*1e3,this.ufoElement.seekableDuration),s=i?.getTime(),r=s===void 0||e?.lat===void 0||e.lng===void 0?"":`${this.aircraftSource.id}|${s}+${n}|${e.lat.toFixed(3)},${e.lng.toFixed(3)}|${Math.round(e.elevationM??0)}`;if(this.traffic?.key===r)return this.traffic.set;if(r===""||s===void 0||e?.lat===void 0||e.lng===void 0){this.traffic={key:r,status:"outside"};return}let o=$e.aircraftProviders.get(this.aircraftSource.id);if(o||$e.aircraftProviders.set(this.aircraftSource.id,o=this.aircraftSource.create()),o.mayCover&&!o.mayCover(s+n)){this.traffic={key:r,status:"outside"};return}const c={key:r,status:"loading",startMs:s,observer:{lat:e.lat,lng:e.lng}};this.traffic=c;const l={lat:e.lat,lng:e.lng,heightM:e.elevationM??0},h=on.MAX_GAP_S*1e3,u=$e.SOUND_LOOKBACK_MS,d={lat:e.lat,lng:e.lng,elevationM:e.elevationM??0},f=(p,v)=>p.TrafficDecor.from(c.tracks??[],l,s,p.TrafficDecor.MAX_OBJECTS,{models:v,sunElevationAt:m=>this.sunElevationAt(m,d)});o.between(l,s-u,s+n+h).then(async p=>{if(this.traffic!==c)return;if(p.status!=="found"){c.status=p.status==="outside"?"outside":"unavailable",this.announceTraffic();return}let v;try{v=await $e.loadTrafficRuntime()}catch{this.traffic===c&&(c.status="unavailable",this.announceTraffic());return}this.traffic===c&&(c.status="ready",c.tracks=p.tracks,c.set=f(v),this.startAircraftSound(c,v),this.announceTraffic(),this.describeTraffic(o,c,v,f),c.set.shown>0&&this.readUpperAir(c,v,s-u,s+n+h))})}trafficSunlight(t){const e=new Map,i=this.traffic,n=i?.set,s=this.lastSun;if(!n||!s||i.startMs===void 0||!i.observer)return e;for(const[r,o]of n.presence){if(t<o.fromMs||t>o.untilMs)continue;const c=n.flights.get(r),l=c?on.positionAt(c,i.startMs+t):void 0;l&&e.set(r,{heightM:l.geo.heightM,sunElevationDeg:Pn.sunElevationDeg(s,i.observer,l.geo)})}return e}trafficTooltipAt(t,e){const i=this.sceneRenderer.pickTrafficAt(t,e),n=i?this.trafficInfoAt(i):void 0;if(!n)return;const s=this.naming,r=$e.trafficRuntime;return r?.TrafficTooltip.text(n,s.names?.trafficTooltip??r.TrafficTooltip.ENGLISH,o=>s.towards(o))}trafficInfoAt(t){const e=this.traffic,i=e?.set?.flights.get(t);if(!e||!i||e.startMs===void 0||!e.observer)return;const n=$e.trafficRuntime;if(!n)return;const s=e.descriptions?.get(Xn.keyOf(i)),r=Ze(this.ufoElement.sighting,this.lastTimeMs),o={lat:e.observer.lat,lng:e.observer.lng,heightM:r?.elevationM??0},c=n.AmbientNoise.dbA(Dl(this.ufoElement.sighting,this.lastTimeMs)),l=n.TrafficInfos.at(i,s,o,e.startMs+this.lastTimeMs,{ambientDbA:c}),h=l&&this.contrailAt(t,this.lastTimeMs);return l&&h?{...l,contrail:h}:l}contrailAt(t,e){const i=this.traffic?.contrails?.find(s=>s.id===t);if(!i)return;let n;for(const s of i.points){if(s.tMs>e)break;n=s}return n?.forms?{persistent:n.persistent,iceRelativeHumidity:n.iceRelativeHumidity}:void 0}startAircraftSound(t,e){this.aircraftAudio||(this.aircraftAudio=new e.AircraftAudio,this.aircraftAudio.setLevel(this.ufoElement.level),this.interacted&&this.aircraftAudio.resume(),this.aircraftAudio.setPaused(this.ufoElement.playbackState!=="playing")),this.sortOutAudible(t,e)}sortOutAudible(t,e){!t.set||!t.observer||(t.audible=e.TrafficSound.candidates(t.set.flights,t.descriptions??new Map,Xn.keyOf,{...t.observer,heightM:0},{ambientDbA:e.AmbientNoise.BASE_DB_A}))}pushAircraftSound(t,e){const i=this.aircraftAudio;if(!i)return;const n=$e.trafficRuntime,s=this.traffic,r=s?.set;if(!n||!s||!r||!s.audible||s.startMs===void 0||!s.observer){i.setVoices([]);return}const o=Ze(t,e),c={lat:s.observer.lat,lng:s.observer.lng,heightM:o?.elevationM??0},l=Dl(t,e),h=n.TrafficSound.voices(s.audible,r.flights,s.descriptions??new Map,Xn.keyOf,c,s.startMs+e,{ambientDbA:n.AmbientNoise.dbA(l),referenceAmplitude:n.AmbientNoise.referenceAmplitude(l)});i.setVoices(h,o?.headingDeg??0)}announceTraffic(){this.isConnected&&(this.dispatchEvent(new CustomEvent(qD)),this.updateAstronomy(this.lastTimeMs))}async describeTraffic(t,e,i,n){if(!t.describe||!e.set||!e.tracks)return;const s=new Set([...e.set.flights.values()].map(l=>Xn.keyOf(l))),r=e.tracks.filter(l=>s.has(Xn.keyOf(l))&&l.points.length>0),o=new Map,c=new Map;await Promise.all(r.map(async l=>{const h=new Date(l.points[0].t).toISOString().slice(0,10),u=await t.describe(l,h).catch(()=>{});u&&(c.set(Xn.keyOf(l),u),o.set(Xn.keyOf(l),i.AircraftModels.of(u)))})),!(this.traffic!==e||o.size===0)&&(e.descriptions=c,e.models=o,e.set=n(i,o),this.planContrails(e,i),this.sortOutAudible(e,i),this.announceTraffic())}async readUpperAir(t,e,i,n){if(!t.observer)return;const s=this.upperAirSource??e.UPPER_AIR_SOURCES[0];let r=$e.upperAirProviders.get(s.id);r||$e.upperAirProviders.set(s.id,r=s.create());const o=await r.between(t.observer,i,n);this.traffic!==t||o.status!=="found"||(t.air=o.samples,t.airSource=o.source,this.planContrails(t,e),this.announceTraffic())}planContrails(t,e){!t.set||!t.air||t.startMs===void 0||(t.contrails=e.AircraftContrails.plan(t.set,t.models,t.air,t.startMs))}contrailSunlight(t){const e=new Map,i=this.traffic,n=i?.set,s=this.lastSun;if(!n||!s||!i.contrails?.length||i.startMs===void 0||!i.observer)return e;for(const r of i.contrails){const o=n.presence.get(r.id),c=n.flights.get(r.id);if(!o||!c)continue;const l=on.positionAt(c,i.startMs+Math.min(o.untilMs,Math.max(o.fromMs,t)));l&&e.set(r.id,{heightM:l.geo.heightM,sunElevationDeg:Pn.sunElevationDeg(s,i.observer,l.geo)})}return e}sunElevationAt(t,e){const i=xh("Sun",new Date(t.t),e);return Pn.sunElevationDeg(i,e,t)}upperAirSource;setUpperAirSource(t){t.id!==this.upperAirSource?.id&&(this.upperAirSource=t,this.traffic=void 0,this.decorMemo=void 0,this.updateAstronomy(this.lastTimeMs))}setAircraftSource(t){t.id!==this.aircraftSource.id&&(this.aircraftSource=t,this.traffic=void 0,this.decorMemo=void 0,this.updateAstronomy(this.lastTimeMs))}get aircraftState(){const t=this.traffic?.contrails?.length?this.upperAirSource??$e.trafficRuntime?.UPPER_AIR_SOURCES[0]:void 0;return{trailCredit:t&&{credit:t.credit,creditUrl:t.creditUrl},status:this.traffic?.status??"none",total:this.traffic?.set?.total??0,shown:this.traffic?.set?.shown??0,credit:this.aircraftSource.credit,creditUrl:this.aircraftSource.creditUrl}}get fireballState(){return{status:this.fireballs?.status??"none",records:this.fireballs?.records??[]}}ensureSatellites(t){const e=t?String(t.getTime()):"";if(e===this.satellitesFor)return;this.satellitesFor=e,this.satellites=void 0,this.satellitePassesMemo=void 0;const i=++this.satelliteRequest;if(!t){this.satelliteStatus="none";return}this.satelliteStatus="loading";const n=r=>{i===this.satelliteRequest&&(this.satelliteStatus=r,this.isConnected&&this.dispatchEvent(new CustomEvent(XD)))},s=$e.tleArchive;(async()=>{if(!await s.covers(t))return n("outside");const[r,o]=await Promise.all([s.at(t),je(()=>import("./SatellitePasses-Pfro2-0Z.js"),[],import.meta.url)]);if(i===this.satelliteRequest){if(!r)return n("unavailable");this.satellites={snapshot:r,passes:new o.SatellitePasses(r.objects)},n("ready"),this.isConnected&&this.updateAstronomy(this.lastTimeMs)}})().catch(()=>n("unavailable"))}get satelliteState(){const t=this.satellites?.snapshot;return{status:this.satelliteStatus,coverage:t?.coverage,credit:t?.credit,creditUrl:t?.creditUrl}}satellitePassesDuring(t){const e=this.satellites,i=this.ufoElement.sighting,n=Ze(i,0),s=i.event.place?.[0],r=n?.lat??s?.lat,o=n?.lng??s?.lng;if(!e||r===void 0||o===void 0)return[];const c=ra(i.event.time??{},o,i.event.utcOffsetHours);if(!c)return[];const l=Math.min(Math.max(t,0),4*36e5),h={lat:r,lng:o,elevationM:n?.elevationM??0},u=JSON.stringify([this.satellitesFor,c.getTime(),r,o,h.elevationM,l]);if(this.satellitePassesMemo?.key===u)return this.satellitePassesMemo.passes;const d=Math.max(10,Math.ceil(l/1e3/600)),f=e.passes.passesDuring(c,new Date(c.getTime()+l),h,d);return this.satellitePassesMemo={key:u,passes:f},f}cometAt(t,e){const i=LD.brightestAt(t,e);if(i)return{id:i.apparition.id,position:i.position,tailEnd:i.tailEnd,magnitude:i.magnitude}}pushPhenomenaAt(t){const e=this.ufoElement.sighting;e!==this.sizeEstimatesFor&&(this.sizeEstimates.clear(),this.distanceHypotheses.clear(),this.sizeEstimatesFor=e);const i=e.timeline,n=this.ufoElement.canvasElement,s=this.ufoElement.frameShiftPx,r=this.projectionAt(t),o=new Map,c=new Map,l=new Set;for(const p of i.sourceIds){const v=i.getInterpolatedShapeAt(t,p);if(!v)continue;const m={...v,bounds:{...v.bounds,x:v.bounds.x+s.x,y:v.bounds.y+s.y}};o.set(p,m);const g=v.aim?this.sceneRenderer.screenPointOf(ss.directionOf(v.aim,this.directionScratch)):{ndcX:(m.bounds.x+m.bounds.width/2)/n.width*2-1,ndcY:-((m.bounds.y+m.bounds.height/2)/n.height*2-1)},b=g!==void 0&&Math.abs(g.ndcX)<=1&&Math.abs(g.ndcY)<=1,S=b?this.sceneRenderer.decorDistancesAt(g.ndcX,g.ndcY,p):{};l.add(p),(b||v.aim)&&l.delete(p);const M=v.angular?.widthDeg??r.pxToDeg(v.bounds.width),x=this.sizeEstimateOf(p);x.add(M,S);const _=tl.of(e,p);c.set(p,sn.resolve({hypothesisM:this.distanceHypotheses.get(p),derivedM:_&&M>0?Fe.distanceMAt(_.widthM,M):void 0,range:x.distanceRangeAt(M),crossing:S}))}for(const[p,v]of o)for(const[m,g]of o){if(m===p||g.transparency>=1||g.bounds.width*g.bounds.height<=v.bounds.width*v.bounds.height||!(v.bounds.x>=g.bounds.x&&v.bounds.y>=g.bounds.y&&v.bounds.x+v.bounds.width<=g.bounds.x+g.bounds.width&&v.bounds.y+v.bounds.height<=g.bounds.y+g.bounds.height))continue;const S=c.get(m);S&&c.set(p,{distanceM:S.distanceM*.999,basis:S.basis});break}this.depths=c;const h=i.sourceIds,u=[];for(const[p,v]of o)u.push({sourceId:p,shape:v,distanceM:c.get(p).distanceM,renderOrder:h.indexOf(p),aim:v.aim,hidden:l.has(p)||this.interpretationShown!==void 0&&(!this.comparing||v.transparency>=1),ghost:this.interpretationShown!==void 0&&this.comparing});const f=(Ze(e,t)?.rollDeg??0)+Ce.bodyAt(e,t,this.ufoElement.steadyBody).rollDeg;this.sceneRenderer.setPhenomena(u,{projection:r,canvasWidthPx:n.width,canvasHeightPx:n.height,scale:Math.max(1,this.sceneCanvas.height/Math.max(1,n.height)),starPoints:bi.starPointsOf(e.instrument),rollRad:f*Math.PI/180})}get interpretation(){return this.interpretationShown}set interpretation(t){this.interpretationShown=t,this.syncAccountHidden(),this.updateAstronomy(this.lastTimeMs)}syncAccountHidden(){this.ufoElement.accountHidden=this.interpretationShown!==void 0&&!this.comparing}get accountInTheRound(){return this.inTheRound}set accountInTheRound(t){this.inTheRound=t}get compareAccount(){return this.comparing}set compareAccount(t){this.comparing=t,this.syncAccountHidden(),this.updateAstronomy(this.lastTimeMs)}get confrontation(){return this.confrontationReadings}groundAlong(t,e,i){const n=this.sceneRenderer.bodyGround,s=ce.eyeOf(this.ufoElement.sighting,i,n);return s?ce.lineOfSightMeetsGround(s,t,e,n):void 0}bodyReading(t,e){const i=this.sceneRenderer.bodyGround,n=this.ufoElement.sighting,s=d=>ce.eyeOf(n,d,i),r=new ce(t,i,s).at(e),o=s(e);if(!r||!o)return;const c=r.eastM-o.eastM,l=r.northM-o.northM,h=r.upM-o.upM,u=Math.hypot(c,l);return{azimuthDeg:(Math.atan2(c,l)*180/Math.PI+360)%360,altitudeDeg:Math.atan2(h,u)*180/Math.PI,distanceM:Math.hypot(u,h),eastM:r.eastM,northM:r.northM,aboveGroundM:r.upM-r.sizeM.heightM/2-i.heightAt(r.eastM,r.northM),sizeM:r.sizeM,attitude:r.attitude,appearance:r.appearance}}directionToBody(t,e){const i=this.sceneRenderer.bodyGround,n=this.ufoElement.sighting,s=p=>ce.eyeOf(n,p,i),r=new ce(t,i,s),o=r.at(e)?e:t.track[0]?.t,c=o===void 0?void 0:r.at(o),l=o===void 0?void 0:s(o);if(!c||!l)return;const h=c.eastM-l.eastM,u=c.northM-l.northM,d=c.upM-l.upM,f=Math.hypot(h,u);if(!(f===0&&d===0))return{azimuthDeg:(Math.atan2(h,u)*180/Math.PI+360)%360,altitudeDeg:Math.atan2(d,f)*180/Math.PI}}placeBodiesAt(t,e){const i=this.interpretationShown,n=this.ufoElement.sighting;let s=[],r=[];const o=this.sceneRenderer.bodyGround,c=p=>ce.eyeOf(n,p,o);i&&(s=i.bodies.map(p=>new ce(p,o,c).at(t)).filter(p=>p!==void 0));const l=Eo(n,t),h=l.windDirectionDeg*Math.PI/180,u={x:l.windSpeed*Math.sin(h),z:-l.windSpeed*Math.cos(h)};this.sceneRenderer.setBodies(s,t/1e3,i?.bodies.map(p=>p.id)??[],i?.smoke??[],u);const d=i&&this.comparing?c(t):void 0;if(d&&(r=new di(n.timeline).at(t,s,d,p=>p.outlineNode?this.sceneRenderer.bodyOutline?.(p.id,p.outlineNode):void 0)),this.confrontationReadings=r,!e)return;const f=JSON.stringify(r);f!==this.confrontationSignature&&(this.confrontationSignature=f,this.dispatchEvent(new CustomEvent(ly,{detail:r})))}setDistanceHypothesis(t,e){e===void 0||!(e>0)?this.distanceHypotheses.delete(t):this.distanceHypotheses.set(t,e),this.updateAstronomy(this.lastTimeMs)}depthOf(t){return this.depths.get(t)}sizeRangeOf(t){return this.sizeEstimateOf(t).sizeRange}distanceRangeAt(t,e){const i=this.ufoElement.sighting.timeline.getInterpolatedShapeAt(e,t);if(!i)return{};const n=i.angular?.widthDeg??this.projectionAt(e).pxToDeg(i.bounds.width);return this.sizeEstimateOf(t).distanceRangeAt(n)}sizeContradictory(t){return this.sizeEstimateOf(t).contradictory}updateMeteorShower(t,e){this.ensureMeteorSchedule(t),this.sceneRenderer.updateMeteors(e)}updateLightning(t,e,i){if(this.ensureLightningSchedule(t),this.sceneRenderer.updateLightning(e),i)return;const n=this.lastLightningT;if(this.lastLightningT=e,n===void 0||e<n||this.ufoElement.playbackState!=="playing")return;const s=this.lightningFlashes.filter(r=>r.t>n&&r.t<=e).pop();s&&Eo(t,s.t).storm&&this.handleLightningFlash(s)}ensureLightningSchedule(t){const e=Eo(t,0).precipitationIntensity,i=`${this.meteorInputsOf(t)}|${e}`;if(i===this.lightningScheduleFor)return;this.lightningScheduleFor=i;const n=t.event.time,s=t.event.place?.[0],r=n?.year!==void 0?ra(n,s?.lng??0,t.event.utcOffsetHours):void 0,o=(t.event.durationSeconds??0)*1e3||t.timeline.duration||2e4,c=Math.round((r?.getTime()??0)/1e3)+Math.round((s?.lat??0)*1e3)+7;this.lightningFlashes=Ii.schedule({durationMs:o,seed:c,intensity:e}),this.sceneRenderer.setLightning(this.lightningFlashes)}ensureMeteorSchedule(t){const e=this.meteorInputsOf(t);e!==this.meteorScheduleFor&&(this.meteorScheduleFor=e,this.scheduleMeteors(t))}meteorInputsOf(t){const e=t.event.place?.[0],i=t.event.time;return JSON.stringify([e?.lat,e?.lng,i?.year,i?.month,i?.day,i?.hour,i?.minute,i?.second,t.event.utcOffsetHours,t.event.durationSeconds,t.timeline.duration])}scheduleMeteors(t){const e=t.event.place?.[0],i=t.event.time,n=e?.lat!==void 0&&e.lng!==void 0&&i?.year!==void 0?ra(i,e.lng,t.event.utcOffsetHours):void 0;if(!n||e?.lat===void 0||e.lng===void 0){this.sceneRenderer.setMeteorShower([],0,0);return}const s={lat:e.lat,lng:e.lng,elevationM:0},r=(t.event.durationSeconds??0)*1e3||t.timeline.duration||2e4,o=Math.round(n.getTime()/1e3)+Math.round(e.lat*1e3),c=fi.schedule({ratePerHour:fi.observedRatePerHour(fi.apexPosition(n,s).altitudeDeg),durationMs:r,velocityKmS:fi.TYPICAL_VELOCITY_KM_S,seed:o}),l=zf.activeAt(n).map(u=>{const d=zf.radiantPosition(u.shower,n,s);return{entry:u,position:d,rate:zf.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=ka.schedule({ratePerHour:l.rate,durationMs:r,velocityKmS:l.entry.shower.velocityKmS,seed:o+1});this.sceneRenderer.setMeteorShower([...h,...c],l.position.altitudeDeg,l.position.azimuthDeg)}meteorByRank(t){this.ensureMeteorSchedule(this.ufoElement.sighting);const e=[...this.sceneRenderer.meteorSchedule].filter(s=>s.t+s.durationMs<=this.ufoElement.seekableDuration).sort((s,r)=>r.brightness-s.brightness);if(e.length===0)return;const i=e[t%e.length],n=this.sceneRenderer.meteorMidpoint(i);if(n)return{t:Math.round(i.t+i.durationMs*.45),...n}}lensOpticsAt(t){const e=this.ufoElement.sighting,i=e.instrument,n=i.frame,s=Ze(e,t),r=s?.fNumber??i.fNumber;if(!n||r===void 0)return;const o=bi.focalLengthMmFor(i,xn.fovOf(e,t));if(o!==void 0)return{focalLengthMm:o,fNumber:r,focusDistance:s?.focusDistanceM??0,frameHeightMm:n.heightMm}}projectionAt(t){const e=this.ufoElement.sighting;return rr.of(e.instrument,Fe.CANVAS_HEIGHT_PX,xn.fovOf(e,t))}sizeEstimateOf(t){let e=this.sizeEstimates.get(t);return e||(e=new kD,this.sizeEstimates.set(t,e)),e}}const qu="rr0-scene";function hy(){PM(),customElements.get(qu)||customElements.define(qu,$e)}const tI={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",sway:"Sway at rest",swayTitle:"How much the body holding the instrument moves the view when not walking: 1 for a person standing, 0 for a tripod. Blank: 1 (0 if the account says the observer was paralysed)",lightPollution:"Night sky",lightPollutionTitle:'The zenith of a moonless night at this place, in magnitudes per square arcsecond, as a Sky Quality Meter reads it or as the World Atlas of artificial sky brightness (Falchi et al. 2016, lightpollutionmap.info, "SQM") gives it. 22 is a natural sky; a suburb is about 19, a city centre 17. Blank: a natural sky',observationTime:"Observation start",observationEndTime:"Observation end",assessmentGroup:"Assessment",assessmentNames:{coverage:"Observer 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"},timeQualifierApproximate:"Approximate",timeQualifierUncertain:"Uncertain",timeQualifierBoth:"Uncertain and approximate",timeSeasonSpring:"Spring",timeSeasonSummer:"Summer",timeSeasonAutumn:"Autumn",timeSeasonWinter:"Winter",summaryGroups:{observation:"Observation",location:"Position",temporal:"Time",weather:"Weather",sound:"Sound"},summaryGroup:"Summary",summaryDescription:"Description",closeDescription:"Close the description",observerGroup:"Observer",observerId:"ID",observerTitle:"Title",observerLastName:"Last name",observerFirstNames:"First names",sightingId:"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",cloudsGroup:"Clouds",precipitationGroup:"Precipitation",windGroup:"Wind",soundKind:"Sound",soundNone:"None (silent)",soundHum:"Hum",soundWhistle:"Whistle",soundRumble:"Rumble",soundCrackle:"Crackle",soundVolume:"Loudness",soundPitch:"Pitch",soundSrc:"Recording",instrument:"Observed through",filter:"In front of it",filterNone:"nothing",filterSolarVisual:"a solar filter for the eye (eclipse glasses, density 5)",filterSolarPhoto:"a solar film for a camera (density 3.8)",decorAircraft:"Aircraft",decorEntity:"Being",decorAltitude:"Altitude",decorLights:"Lights",decorLightsNone:"none",decor:"Environment",decorBuilding:"Building",decorTree:"Tree",decorShrub:"Shrub",decorBridge:"Bridge",decorWire:"Overhead line",decorCrop:"Crop row",decorTerrace:"Terrace (restanque)",decorMound:"Stone heap",decorStreetlight:"Streetlight",decorVehicle:"Vehicle",decorObserver:"Other observer",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",goToMilestone:"Go to this moment",decorWidth:"Width",decorLength:"Length",decorHeight:"Height",decorModel:"3D model",decorModelNone:"Built-in shape",decorModelDefault:"Default model",decorModelAdvanced:"Model from an address",decorModelFromCatalogue:"From the catalogue, which the recording names it by. Change a field and it becomes this recording's own address.",decorModelUrl:"glTF/GLB address",decorModelTitle:"Model name",decorModelAuthor:"Author",decorModelLicense:"Licence",decorModelSource:"Where it came from",decorFloors:"Floors",decorOccupiedFloor:"Occupied floor",decorObserverSide:"Observer location",decorObserverSideNone:"Not present",decorWindows:"Windows",decorSideFront:"Front",decorSideBehind:"Behind",decorSideLeft:"Left",decorSideRight:"Right",decorSideFrontLeft:"Front-left",decorSideFrontRight:"Front-right",decorSideBehindLeft:"Behind-left",decorSideBehindRight:"Behind-right"},Hc={...tI,accountBy:"Account by",unnamedObserver:"Observer {n}",about:"About",close:"Close",observation:"Observation",date:"Date",location:"Location",case:"Case",description:"Description",source:"Source",basis:{stated:"stated",derived:"derived",assumed:"assumed"},credits:"Credits",editThisObservation:"Edit this observation",embed:"Embed",embedReplay:"Player",embedEdit:"Editor",share:"Share",embedObservation:"Embed the observation",back:"Back",embedCopy:"Copy",shareLink:"Link",shareStartAt:"Start at",shareOptionLabels:"Show summary chips",shareOptionMap:"Open map",shareOptionMilestones:"Show moments",shareOptionCompare:"Compare account",embedCopied:"Copied",showLabels:"Show what it states",interpretation:"Interpretation",account:"Account",interpretationBy:"{title}, by {by}",confrontation:"Against the account",confrontationDirection:"{deg}° off",confrontationWidth:"width ×{ratio}",confrontationHeight:"height ×{ratio}",showComparison:"Compare with the account",hideComparison:"Stop comparing with the account",hideLabels:"Hide what it states"},eI=Object.freeze(Object.defineProperty({__proto__:null,sightingMessages_en:Hc},Symbol.toStringTag,{value:"Module"}));hy();class $u{static PRODUCTION="https://ufoathome.org";static home(){try{const t=new URL(import.meta.url),e=new URL(location.href);return(e.hostname==="localhost"||e.hostname==="127.0.0.1"||e.hostname==="[::1]"||e.hostname.endsWith(".localhost"))&&t.origin===e.origin?e.origin:$u.PRODUCTION}catch{return $u.PRODUCTION}}}const jh=$u.home(),Nh="compare-account",kh="start-time",Gf="account",Vf=`${jh}/edit/`;class qo extends HTMLElement{static get observedAttributes(){return["src","show-labels",kh,ks,Fs,Nh]}shadow;sceneElement;toolbarElement;accountElement;accountPrefix;observerText;observerSelect;infoButton;infoPanel;infoAppLink;editLink;infoObservationHeading;infoObservationList;infoCreditsToggle;infoCreditsList;infoCloseButton;shareButton;shareDialog;shareTitle;shareLinkOption;shareLinkLabel;shareLinkBox;shareEmbed;shareClose;shareEmbedOption;shareEmbedLabel;shareLink;shareReplayOptions;embedCode;shareCopy;shareStartOn;shareStart;shareStartLabel;shareOptions;embedReplayRadio;embedEditRadio;labelEmbedReplay;labelEmbedEdit;embedMarkup;embedCopyButton;labelsToggle;paramSummary;summaryBuilder=new sl(Hc,new Xu,new Yn(["en"]),new zh({}),{messages:Hc,locale:"en"});summarySignature="";assessmentEntries=[];assessmentToken=0;supportsPopover=typeof HTMLElement.prototype.showPopover=="function";entries=[];caseSource;interpretationChoice;interpretationLabel;interpretationSelect;confrontationElement;confrontationHeading;confrontationList;compareButton;interpretationLoaders=new Map;interpretationToken=0;offeredFor;currentSrc;infoOpen=!1;creditsOpen=!1;labelsShown=!1;language="en";messages=Hc;constructor(){super(),this.shadow=this.attachShadow({mode:"open"});const t=document.createElement("template");t.innerHTML=`<style>${by}</style>${xy}`,this.shadow.appendChild(t.content.cloneNode(!0)),this.sceneElement=document.createElement(qu),this.forwardPlayerAttributes(),this.sceneElement.ufoElement.creditShownExternally=!0,this.sceneElement.ownCredits=!1,this.shadow.getElementById("ufo-slot").replaceWith(this.sceneElement),this.toolbarElement=this.shadow.getElementById("toolbar"),this.accountElement=this.shadow.getElementById("account"),this.accountPrefix=this.shadow.getElementById("account-prefix"),this.observerText=this.shadow.getElementById("observer-text"),this.observerSelect=this.shadow.getElementById("observer"),this.infoButton=this.shadow.getElementById("info-button"),this.infoPanel=this.shadow.getElementById("info-panel"),this.infoAppLink=this.shadow.getElementById("info-app-link"),this.editLink=this.shadow.getElementById("edit-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.shareButton=document.createElement("button"),this.shareButton.type="button",this.shareButton.id="share-button",this.shareButton.setAttribute("aria-haspopup","dialog"),this.shareButton.innerHTML=Gt.SHARE,this.sceneElement.ufoElement.addControl(this.shareButton),this.shareDialog=this.shadow.getElementById("share-dialog"),this.shareTitle=this.shadow.getElementById("share-title"),this.shareLinkOption=this.shadow.getElementById("share-link-option"),this.shareLinkLabel=this.shadow.getElementById("share-link-label"),this.shareLinkBox=this.shadow.querySelector(".share-link"),this.shareEmbed=this.shadow.getElementById("share-embed"),this.shareClose=this.shadow.getElementById("share-close"),this.shareEmbedOption=this.shadow.getElementById("share-embed-option"),this.shareEmbedLabel=this.shadow.getElementById("share-embed-label"),this.shareLink=this.shadow.getElementById("share-link"),this.shareReplayOptions=this.shadow.getElementById("share-replay-options"),this.embedCode=this.shadow.getElementById("embed-code"),this.shareCopy=this.shadow.getElementById("share-copy"),this.shareStartOn=this.shadow.getElementById("share-start-on"),this.shareStart=this.shadow.getElementById("share-start"),this.shareStartLabel=this.shadow.getElementById("share-start-label");const e=i=>({input:this.shadow.getElementById(`share-opt-${i}`),label:this.shadow.getElementById(`share-opt-${i}-label`)});this.shareOptions={labels:e("labels"),map:e("map"),milestones:e("milestones"),compare:e("compare")},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.interpretationChoice=this.shadow.getElementById("interpretation-choice"),this.interpretationLabel=this.shadow.getElementById("interpretation-label"),this.interpretationSelect=this.shadow.getElementById("interpretation"),this.confrontationElement=this.shadow.getElementById("confrontation"),this.confrontationHeading=this.shadow.getElementById("confrontation-heading"),this.confrontationList=this.shadow.getElementById("confrontation-list"),this.compareButton=this.shadow.getElementById("compare-account"),this.compareButton.addEventListener("click",()=>this.setComparing(!this.sceneElement.compareAccount)),this.observerSelect.addEventListener("change",()=>this.selectObserver(this.observerSelect.value)),this.interpretationSelect.addEventListener("change",()=>void this.chooseInterpretation(this.interpretationSelect.value)),this.sceneElement.addEventListener(ly,i=>this.showConfrontation(i.detail)),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",i=>{i.newState==="open"&&(this.populateInfoPanel(),this.bringInfoButtonIntoView())}),this.infoPanel.addEventListener("toggle",i=>this.syncInfoOpen(i.newState==="open"))):this.infoButton.addEventListener("click",()=>this.toggleInfoPanel()),this.infoCloseButton.addEventListener("click",()=>this.toggleInfoPanel()),this.infoCreditsToggle.addEventListener("click",()=>this.toggleCredits()),this.shareButton.addEventListener("click",()=>this.openShare()),this.shareClose.addEventListener("click",()=>this.closeShare()),this.shareLinkOption.addEventListener("click",()=>this.showShareView("link")),this.shareEmbedOption.addEventListener("click",()=>this.showShareView("embed"));for(const i of[this.shareStartOn,this.shareStart,...Object.values(this.shareOptions).map(n=>n.input)])i.addEventListener("input",()=>this.refreshShareLinks());this.shareCopy.addEventListener("click",()=>void this.copyText(this.shareLink.value,this.shareLink,this.shareCopy)),this.shareDialog.addEventListener("click",i=>{i.target===this.shareDialog&&this.closeShare()});for(const i of[this.embedReplayRadio,this.embedEditRadio])i.addEventListener("change",()=>this.refreshShareLinks());this.embedCopyButton.addEventListener("click",()=>void this.copyEmbedMarkup()),this.isConnected&&this.loadLocaleMessages()}get scene(){return this.sceneElement}async loadLocaleMessages(){const t=++this.localeToken,e=Gr.preferencesFor(this);this.preferences=e;const i=Ep(e,Ap),[n,s,r]=i==="en"?[Hc,{},void 0]:await Promise.all([ub(i),db(i),bM(i)]);if(t!==this.localeToken)return;const o=i!==this.language;this.language=i,this.messages=n,this.tags=new zh(s),this.said=new Yn(e),this.summaryBuilder=new sl(this.messages,new Xu(r),this.said,this.tags,{messages:this.messages,locale:i}),this.accountPrefix.textContent=this.messages.accountBy,this.interpretationLabel.textContent=this.messages.interpretation,this.confrontationHeading.textContent=this.messages.confrontation;const c=this.entries.find(l=>l.src===this.currentSrc);c&&this.offerInterpretations(c),this.updateCompareButton(),this.infoButton.title=this.messages.about,this.infoButton.setAttribute("aria-label",this.messages.about),this.editLink.title=this.messages.editThisObservation,this.editLink.setAttribute("aria-label",this.messages.editThisObservation),this.infoCloseButton.setAttribute("aria-label",this.messages.close),this.infoObservationHeading.textContent=this.messages.observation,this.infoCreditsToggle.textContent=this.messages.credits,this.syncLabelsToggle(),this.refreshParamSummary(),o&&this.currentSrc&&this.runAssessments(),this.shareButton.title=this.messages.share,this.shareButton.setAttribute("aria-label",this.messages.share),this.shareClose.setAttribute("aria-label",this.messages.close),this.shareCopy.textContent=this.messages.embedCopy,this.shareStartLabel.textContent=this.messages.shareStartAt,this.shareOptions.labels.label.textContent=this.messages.shareOptionLabels,this.shareOptions.map.label.textContent=this.messages.shareOptionMap,this.shareOptions.milestones.label.textContent=this.messages.shareOptionMilestones,this.shareOptions.compare.label.textContent=this.messages.shareOptionCompare,this.shareStart.setAttribute("aria-label",this.messages.shareStartAt),this.shareEmbedLabel.textContent=this.messages.embed,this.shareLinkLabel.textContent=this.messages.shareLink,this.shareTitle.textContent=this.messages.share,this.labelEmbedReplay.textContent=this.messages.embedReplay,this.labelEmbedEdit.textContent=this.messages.embedEdit,this.embedCopyButton.textContent=this.messages.embedCopy,this.infoOpen&&this.populateInfoPanel(),this.updateAccountLine()}preferences=[];localeToken=0;said=new Yn(["en"]);tags=new zh({});connectedCallback(){Gr.preferencesFor(this).join()!==this.preferences.join()&&this.loadLocaleMessages();const t=this.getAttribute("src");t&&this.loadFromSrc(t)}disconnectedCallback(){document.removeEventListener("click",this.handleOutsideClick)}attributeChangedCallback(t,e,i){t==="src"&&i&&i!==e&&this.isConnected&&this.loadFromSrc(i),t==="show-labels"&&this.applyLabels(this.hasAttribute("show-labels")),(t===ks||t===Fs)&&this.forwardPlayerAttributes(),t===Nh&&this.setComparing(this.hasAttribute(Nh))}forwardPlayerAttributes(){for(const t of[ks,Fs]){const e=this.getAttribute(t);e===null?this.sceneElement.removeAttribute(t):this.sceneElement.setAttribute(t,e)}}async loadFromSrc(t){this.startPending=!0;const e=Gc.json(t);this.sceneElement.holdForNewScene(e);const i=await e;if(Array.isArray(i))throw new Error(`${t} is a bare list of recordings, which is no longer read: list them as the sighting events of a case.json`);if(cs.isCase(i)){const n=cs.sightingUrls(i,new URL(t,location.href).href);if(n.length===0)throw new Error(`${t} is a case with no sighting event: no recording to show`);await this.loadObserverUrls(n,{json:i,url:new URL(t,location.href).href})}else this.setEntries([{src:t,sighting:i}],void 0)}get sightingData(){return this.entries.find(t=>t.src===this.currentSrc)?.sighting}set sightingData(t){this.startPending=!0,this.currentSrc="",this.setEntries([{src:"",sighting:t}],void 0)}get observerUrls(){return this.entries.map(t=>t.src)}set observerUrls(t){this.loadObserverUrls(t)}async loadObserverUrls(t,e){const i=await Promise.all(t.map(async n=>({src:n,sighting:await Gc.json(n)})));this.setEntries(i,e)}setEntries(t,e){this.entries=t,this.caseSource=e,this.toolbarElement.hidden=t.length===0;const i=t.length>1;this.observerSelect.hidden=!i,this.observerText.hidden=i,this.observerSelect.innerHTML="";for(const s of t){const r=document.createElement("option");r.value=s.src,r.textContent=this.observerDisplayName(this.plain(s).observer)??this.messages.unnamedObserver.replace("{n}",String(t.indexOf(s)+1)),this.observerSelect.appendChild(r)}const n=t.find(s=>s.src===this.currentSrc)??t[0];n?this.selectObserver(n.src):this.updateAccountLine()}editorUrl(){if(!this.currentSrc)return Vf;const t=new URL(this.currentSrc,location.href),e=this.caseSource;return e?`${Vf}?file=${encodeURIComponent(e.url)}&track=${encodeURIComponent(this.shownTrackUrl()??t.href)}`:`${Vf}?file=${encodeURIComponent(t.href)}`}get editorHref(){return this.editorUrl()}shownTrackUrl(){const t=this.caseSource,e=this.entries.find(s=>s.src===this.currentSrc),i=/^case-(\d+)$/.exec(this.interpretationSelect.value);if(!t||!e||!i)return;const n=cs.interpretationEvents(t.json,this.plain(e).id)[Number(i[1])];return n?.url?new URL(n.url,t.url).href:void 0}embedMarkupFor(t){const e=t==="edit"?"rr0-sighting-editor":"rr0-sighting",i=new URL(`${e}.mjs`,import.meta.url).href,n=this.currentSrc?new URL(this.currentSrc,location.href).href:"",s=t==="replay"?this.replayAttributes().map(([r,o])=>o===""?` ${r}`:` ${r}="${o}"`).join(""):"";return`<script type="module" src="${i}"><\/script>
8761
+ <${e} src="${n}"${s}></${e}>`}refreshEmbedMarkup(){const t=this.embedMarkupFor(this.embedEditRadio.checked?"edit":"replay");this.embedMarkup.value=t,this.shareCodeEditor&&(this.shareCodeEditor.text=t)}async copyText(t,e,i){try{await navigator.clipboard.writeText(t),i.textContent=this.messages.embedCopied,window.setTimeout(()=>i.textContent=this.messages.embedCopy,1500)}catch{e.select()}}async copyEmbedMarkup(){await this.copyText(this.shareCodeEditor?.text??this.embedMarkup.value,this.embedMarkup,this.embedCopyButton)}playUrl(){const t=this.replayQuery().join("&");return this.currentSrc?`${jh}/play/?file=${encodeURIComponent(new URL(this.currentSrc,location.href).href)}${t&&"&"+t}`:`${jh}/play/${t&&"?"+t}`}replayAttributes(){const t=this.shareOptions,e=[];return this.shareStartSeconds!==void 0&&e.push([kh,String(this.shareStartSeconds)]),t.labels.input.checked&&e.push(["show-labels",""]),t.map.input.checked&&e.push([ks,""]),t.milestones.input.checked||e.push([Fs,""]),t.compare.input.checked&&e.push([Nh,""]),e}replayQuery(){const t=this.shareOptions,e=[];return this.shareStartSeconds!==void 0&&e.push(`t=${this.shareStartSeconds}`),t.labels.input.checked||e.push("labels=0"),t.map.input.checked&&e.push("map=1"),t.milestones.input.checked||e.push("moments=0"),t.compare.input.checked&&e.push("compare=1"),e}get shareStartSeconds(){const t=Math.floor(Number(this.shareStart.value));return this.shareStartOn.checked&&Number.isFinite(t)&&t>=0?t:void 0}refreshShareLinks(){const t=this.embedEditRadio.checked;this.shareReplayOptions.disabled=t,this.shareLink.value=t?this.editorUrl():this.playUrl(),this.fitShareLink(),this.refreshEmbedMarkup()}fitShareLink(){this.shareLink.style.height="auto",this.shareLink.style.height=`${this.shareLink.scrollHeight}px`}shareCodeEditor;shareCodeLoading;loadShareCode(){this.shareCodeLoading??=je(async()=>{const{ShareCodeEditor:t}=await import("./ShareCodeEditor-C53SBK2N.js");return{ShareCodeEditor:t}},[],import.meta.url).then(({ShareCodeEditor:t})=>{this.shareCodeEditor=new t(this.embedCode,this.embedMarkup.value,e=>{this.embedMarkup.value=e},this.messages.embed),this.embedMarkup.hidden=!0}).catch(()=>{this.shareCodeLoading=void 0})}openShare(){const t=this.sceneElement.ufoElement;this.shareStart.max=String(Math.floor(t.seekableDuration/1e3)),this.shareStart.value=String(Math.floor(t.currentTime/1e3)),this.shareStartOn.checked=!1,this.shareOptions.labels.input.checked=this.labelsShown,this.shareOptions.map.input.checked=t.observerMapOpen,this.shareOptions.milestones.input.checked=t.milestonesVisible,this.shareOptions.compare.input.checked=this.sceneElement.compareAccount,this.refreshShareLinks(),this.showShareView("link"),typeof this.shareDialog.showModal=="function"?this.shareDialog.showModal():this.shareDialog.setAttribute("open",""),this.fitShareLink(),this.shareLink.select()}closeShare(){typeof this.shareDialog.close=="function"?this.shareDialog.close():this.shareDialog.removeAttribute("open")}showShareView(t){this.shareLinkBox.hidden=t!=="link",this.shareEmbed.hidden=t!=="embed",this.shareLinkOption.setAttribute("aria-pressed",String(t==="link")),this.shareEmbedOption.setAttribute("aria-pressed",String(t==="embed")),t==="embed"?this.loadShareCode():this.fitShareLink()}offerInterpretations(t){const e=this.offeredFor===t.sighting,i=this.interpretationSelect.value;this.offeredFor=t.sighting,this.interpretationToken++,this.interpretationLoaders=new Map,this.interpretationSelect.innerHTML="";const n=(l,h,u)=>{const d=document.createElement("option");d.value=l,d.textContent=h,this.interpretationSelect.appendChild(d),this.interpretationLoaders.set(l,u)},s=t===this.entries.find(l=>l.src===this.currentSrc)?this.sceneElement.ufoElement.sighting.interpretation:void 0;n(Gf,this.messages.account,()=>Promise.resolve(s));const r=this.caseSource;r&&cs.interpretationEvents(r.json,this.plain(t).id).forEach((l,h)=>{const u=this.said.read(l.title)??`#${h+1}`,d=(l.by??[]).map(f=>this.agentName(f)).filter(Boolean).join(", ");n(`case-${h}`,d?this.messages.interpretationBy.replace("{title}",u).replace("{by}",d):u,()=>cs.interpretationOf(l,r.url,f=>Gc.json(f)))});const c=e&&[...this.interpretationSelect.options].some(l=>l.value===i)?i:Gf;this.interpretationSelect.value=c,c===Gf?this.sceneElement.interpretation!==s&&(this.sceneElement.interpretation=s):this.sceneElement.interpretation||this.chooseInterpretation(c),this.interpretationChoice.hidden=this.interpretationSelect.options.length<2,this.showConfrontation(this.sceneElement.confrontation),this.updateCompareButton()}setComparing(t){this.sceneElement.compareAccount=t,this.updateCompareButton(),this.showConfrontation(this.sceneElement.confrontation)}updateCompareButton(){const t=this.sceneElement.compareAccount;this.compareButton.hidden=!this.sceneElement.interpretation,this.compareButton.setAttribute("aria-pressed",String(t));const e=t?this.messages.hideComparison:this.messages.showComparison;this.compareButton.title=e,this.compareButton.setAttribute("aria-label",e)}static DATE_LOCALES={en:"en-US",fr:"fr-FR",es:"es-ES",it:"it-IT"};get colon(){return this.language==="fr"?" : ":": "}async chooseInterpretation(t){const e=++this.interpretationToken,i=this.interpretationLoaders.get(t),n=i?await i().catch(s=>{console.warn(`<rr0-sighting>: could not read interpretation "${t}":`,s)}):void 0;e===this.interpretationToken&&(this.sceneElement.interpretation=n,this.editLink.href=this.editorUrl(),this.dispatchEvent(new CustomEvent("interpretationchange",{detail:{track:this.shownTrackUrl()}})),this.updateCompareButton(),this.showConfrontation(this.sceneElement.confrontation))}agentName(t){if("people"in t){const[e,...i]=t.people.replace(/([a-z])([A-Z])/g,"$1 $2").split(" ");return[...i,e].join(" ")}return"org"in t?t.org.replace(/([a-z])([A-Z])/g,"$1 $2"):this.observerDisplayName(t)??""}showConfrontation(t){this.confrontationList.innerHTML="",this.confrontationElement.hidden=!this.sceneElement.interpretation||!this.sceneElement.compareAccount;const e=new Intl.NumberFormat(this.language,{maximumFractionDigits:1,minimumFractionDigits:1}),i=new Intl.NumberFormat(this.language,{maximumFractionDigits:2,minimumFractionDigits:2});for(const n of t){const s=document.createElement("li");s.append(`${this.said.read(n.title)??n.sourceId}${this.colon}`);const r=[];n.separationDeg!==void 0&&r.push([this.messages.confrontationDirection.replace("{deg}",e.format(n.separationDeg)),n.disagreements.includes("direction")]),n.widthRatio!==void 0&&r.push([this.messages.confrontationWidth.replace("{ratio}",i.format(n.widthRatio)),n.disagreements.includes("width")]),n.heightRatio!==void 0&&r.push([this.messages.confrontationHeight.replace("{ratio}",i.format(n.heightRatio)),n.disagreements.includes("height")]),r.forEach(([o,c],l)=>{l>0&&s.append(" · ");const h=document.createElement("span");h.textContent=o,c&&(h.className="disagrees"),s.append(h)}),this.confrontationList.appendChild(s)}}startPending=!1;selectObserver(t){const e=this.entries.find(i=>i.src===t);if(e){if(this.currentSrc=t,this.observerSelect.value=t,this.sceneElement.documentUrl=e.src?new URL(e.src,location.href).href:void 0,this.sceneElement.holdForNewScene(),this.sceneElement.sightingData=e.sighting,this.startPending){this.startPending=!1;const i=Number(this.getAttribute(kh));this.hasAttribute(kh)&&Number.isFinite(i)&&(this.sceneElement.ufoElement.currentTime=Math.max(0,i)*1e3)}this.offerInterpretations(e),this.updateAccountLine(),this.refreshParamSummary(),this.runAssessments(),this.infoOpen&&this.populateInfoPanel(),this.dispatchEvent(new CustomEvent(iI,{detail:{src:t}}))}}async runAssessments(){const t=++this.assessmentToken,e=await new Hx(this.messages).read(this.sceneElement.ufoElement.sighting);t===this.assessmentToken&&(this.assessmentEntries=e.entries,this.refreshParamSummary())}updateAccountLine(){const t=this.entries.find(n=>n.src===this.currentSrc),e=t?this.observerDisplayName(this.plain(t).observer):void 0,i=e!==void 0||this.entries.length>1;this.accountElement.hidden=!i,this.observerText.textContent=e??"",this.editLink.hidden=!this.currentSrc,this.editLink.href=this.editorUrl(),this.editLink.title=this.messages.editThisObservation,this.editLink.setAttribute("aria-label",this.messages.editThisObservation)}observerDisplayName(t){if(!t)return;const e=[...t.firstNames??[],t.lastName].filter(Boolean).join(" ");return t.title||e||t.id}plainRecordings=new WeakMap;plain(t){return this.stripped(t).recording}stripped(t){let e=this.plainRecordings.get(t.sighting);return e||(e=hn.strip(t.sighting),this.plainRecordings.set(t.sighting,e)),e}basisOf(t,e){const i=this.stripped(t).provenance,n={stated:0,derived:1,assumed:2},s=i.paths().filter(c=>e.some(l=>c===l||c.startsWith(`${l}.`))).map(c=>i.at(c)),r=s.reduce((c,l)=>n[l.basis]>n[c]?l.basis:c,"stated"),o=s.filter(c=>c.basis===r&&c.rationale).map(c=>c.rationale);return{basis:r,rationales:o}}formatDate(t){const e=t.place?.[0],i=ra(t.time??{},e?.lng??0,t.utcOffsetHours);if(!i)return;const n=i.getTime()+this.utcOffsetHoursOf(t,e?.lng??0)*36e5;if(Number.isFinite(n))return new Intl.DateTimeFormat(qo.DATE_LOCALES[this.language],{dateStyle:"long",timeStyle:"short",timeZone:"UTC"}).format(new Date(n))}utcOffsetHoursOf(t,e){return t.utcOffsetHours??Math.round(e/15)}formatLocation(t){const e=t.place?.[0];if(e)return`${e.lat.toFixed(4)}, ${e.lng.toFixed(4)}`}toggleInfoPanel(){const t=!this.infoOpen;if(this.supportsPopover){const e=this.infoPanel.matches(":popover-open");t&&!e?this.infoPanel.showPopover():!t&&e&&this.infoPanel.hidePopover();return}t&&this.bringInfoButtonIntoView(),this.syncInfoOpen(t),this.infoPanel.hidden=!t,t?document.addEventListener("click",this.handleOutsideClick):document.removeEventListener("click",this.handleOutsideClick)}bringInfoButtonIntoView(){const t=this.infoButton.getBoundingClientRect(),e=window.innerHeight||document.documentElement.clientHeight;t.top>=0&&t.bottom<=e||this.infoButton.scrollIntoView({block:"center"})}syncInfoOpen(t){t!==this.infoOpen&&(this.infoOpen=t,this.infoButton.setAttribute("aria-expanded",String(t)),t?this.supportsPopover||this.populateInfoPanel():(this.creditsOpen=!1,this.infoCreditsList.hidden=!0,this.infoCreditsToggle.setAttribute("aria-expanded","false")))}handleOutsideClick=t=>{const e=t.composedPath();!e.includes(this.infoPanel)&&!e.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)}revealInPanel(t){t.scrollIntoView?.({block:"nearest"})}get showLabels(){return this.labelsShown}set showLabels(t){this.toggleAttribute("show-labels",t)}applyLabels(t){this.labelsShown=t,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 t=this.sceneElement.ufoElement.sighting,e=[...this.summaryBuilder.entriesFor(t,this.sceneElement.ufoElement.currentTime,{roadGradeDeg:this.sceneElement.roadGradeDeg}),...this.assessmentEntries],i=e.map(r=>`${r.field}=${r.label}=${r.value}${r.unit}${r.full??""}${r.fromSource?"*":""}`).join("|");if(i===this.summarySignature)return;this.summarySignature=i;const n=[];let s;for(const r of e){s&&s.group!==r.group&&(s=void 0);const o=r.group==="summary"?this.messages.summaryGroup:r.group==="observer"?this.messages.observerGroup:r.group in this.messages.summaryGroups?this.messages.summaryGroups[r.group]:r.group==="assessment"?this.messages.assessmentGroup:void 0;if(o!==void 0&&!s){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),s={group:r.group,element:l},n.push(l)}const c=this.paramItem(r);s?s.element.append(c):n.push(c)}this.paramSummary.replaceChildren(...n),this.syncDescription(e)}openDescription;syncDescription(t){this.openDescription!==void 0&&!t.some(e=>e.full===this.openDescription)&&(this.openDescription=void 0),iM.sync(this.paramSummary,this.openDescription,this.messages.summaryDescription,this.messages.closeDescription,()=>{this.openDescription=void 0,this.syncDescription(t)})}paramItem(t){const e=document.createElement("span");if(e.className=t.fromSource?"param-label from-source":"param-label",t.full!==void 0){e.classList.add("describable"),e.tabIndex=0,e.setAttribute("role","button");const s=()=>{this.openDescription=t.full,this.syncDescription([t])};e.addEventListener("click",s),e.addEventListener("keydown",r=>{(r.key==="Enter"||r.key===" ")&&(r.preventDefault(),s())})}const i=document.createElement("span");if(i.className="param-label-label",i.textContent=`${t.label} `,e.append(i),t.color!==void 0){const s=document.createElement("span");s.className="param-label-swatch",s.style.background=t.color,e.append(s)}const n=document.createElement("span");return n.className="param-label-value",n.textContent=t.unit===""?t.value:`${t.value} ${t.unit}`,e.append(n),e}populateInfoPanel(){const t=this.entries.find(e=>e.src===this.currentSrc);if(this.infoObservationList.innerHTML="",t){const e=this.caseSource&&(this.caseSource.json.title??this.caseSource.json.id);if(e&&this.appendInfoRow(this.infoObservationList,this.messages.case,e),!this.labelsShown){const s=this.formatDate(this.plain(t));s&&this.appendInfoRow(this.infoObservationList,this.messages.date,s,this.basisOf(t,qo.DATE_PATHS));const r=this.formatLocation(this.plain(t));r&&this.appendInfoRow(this.infoObservationList,this.messages.location,r,this.basisOf(t,qo.PLACE_PATHS))}const i=this.said.read(this.plain(t).description);i&&!this.labelsShown&&this.appendInfoRow(this.infoObservationList,this.messages.description,i);for(const s of this.plain(t).sources??[])this.appendInfoSource(this.infoObservationList,this.messages.source,s);const n=this.plain(t).tags;!this.labelsShown&&n&&n.length>0&&this.appendInfoRow(this.infoObservationList,this.messages.tags,n.map(s=>this.tags.name(s)).join(", "))}this.refreshEmbedMarkup(),this.infoAppLink.href=jh,this.infoAppLink.textContent="UFO@home v0.105.1",rn.fill(this.infoCreditsList,this.sceneElement)}appendInfoSource(t,e,i){const n=document.createElement("dt");n.textContent=e;const s=document.createElement("dd"),r=i.title??i.url??"";if(i.url&&/^https?:\/\//i.test(i.url)){const c=document.createElement("a");c.href=i.url,c.target="_blank",c.rel="noopener noreferrer",c.textContent=r,s.appendChild(c)}else s.append(r);const o=[i.authors?.join(", "),i.publication?.publisher,i.publication?.time,i.index].filter(Boolean);o.length>0&&s.append(`, ${o.join(", ")}`),t.append(n,s)}static DATE_PATHS=["time","utcOffsetHours","timeZone"];static PLACE_PATHS=["place.0"];appendInfoRow(t,e,i,n){const s=document.createElement("dt");s.textContent=e;const r=document.createElement("dd");if(r.textContent=i,n){const o=document.createElement("span");o.className=`basis basis-${n.basis}`,o.textContent=this.messages.basis[n.basis],n.rationales.length>0&&(o.title=n.rationales.join(`
8762
8762
  `)),r.append(" ",o)}t.appendChild(s),t.appendChild(r)}}const tM="rr0-sighting",iI="observerchange",eM="rr0-eyeobserver";class nI extends qo{}function sI(){hy(),customElements.get(tM)||customElements.define(tM,qo),customElements.get(eM)||customElements.define(eM,nI)}sI();export{h1 as $,Oa as A,Qi as B,st as C,bb as D,rI as E,ve as F,Ee as G,oI as H,MI as I,aI as J,wl as K,Lx as L,At as M,vI as N,pI as O,F0 as P,uw as Q,be as R,tl as S,Xn as T,cw as U,R as V,fI as W,Au as X,un as Y,gI as Z,u2 as _,on as a,hI as a0,Sn as a1,Yg as a2,ti as a3,mI as a4,yI as a5,QM as a6,Aa as a7,kl as a8,wd as a9,Xr as aA,Sl as aB,Qb as aa,de as ab,Ue as ac,Qo as ad,s0 as ae,Bi as af,fr as ag,rw as ah,Nr as ai,Le as aj,lI as ak,uI as al,i2 as am,dI as an,yn as ao,ps as ap,e2 as aq,s1 as ar,QS as as,wu as at,N0 as au,Hi as av,l2 as aw,Yp as ax,qp as ay,me as az,xI as b,xh as c,Iu as d,dr as e,Me as f,As as g,bt as h,vt as i,ue as j,bI as k,ne as l,cI as m,ae as n,In as o,rb as p,Yh as q,pr as r,ra as s,Mc as t,si as u,te as v,wn as w,bn as x,BD as y,pm as z};