@rr0/ufoathome 0.105.9 → 0.107.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -4
- package/dist-embed-scene/{AdsbLolArchiveProvider-2vNkvjL5.js → AdsbLolArchiveProvider-BjLCSrqd.js} +1 -1
- package/dist-embed-scene/ContrailSystem-BlsY0hsn.js +1 -0
- package/dist-embed-scene/GLTFLoader-CS-YH8ii.js +1 -0
- package/{dist-embed-sighting/SceneNames_es-BuZsPlTw.js → dist-embed-scene/SceneNames_es-Ci7l0oHM.js} +1 -1
- package/dist-embed-scene/{SceneNames_fr-BFN6x9Z7.js → SceneNames_fr-DrE5E2My.js} +1 -1
- package/dist-embed-scene/{SceneNames_it-BOuH3VIw.js → SceneNames_it-B62A_y2n.js} +1 -1
- package/dist-embed-scene/{TraceSystem-DEXV4-2W.js → TraceSystem-D2DpL5Qj.js} +2 -2
- package/dist-embed-scene/rr0-scene.mjs +281 -281
- package/dist-embed-scene/sightingSchema-DvayIREy.js +1 -0
- package/dist-embed-scene/trafficRuntime-DXfGGvtU.js +2 -0
- package/dist-embed-sighting/AdsbLolArchiveProvider-4Pw0dn7p.js +1 -0
- package/dist-embed-sighting/{ContrailSystem-CkzapJ6C.js → ContrailSystem-BAjXhqPn.js} +1 -1
- package/dist-embed-sighting/GLTFLoader-CNvHx4ej.js +1 -0
- package/{dist-embed-scene/SceneNames_es-BuZsPlTw.js → dist-embed-sighting/SceneNames_es-Ci7l0oHM.js} +1 -1
- package/{dist-embed-sighting-editor/SceneNames_fr-BFN6x9Z7.js → dist-embed-sighting/SceneNames_fr-DrE5E2My.js} +1 -1
- package/dist-embed-sighting/{SceneNames_it-BOuH3VIw.js → SceneNames_it-B62A_y2n.js} +1 -1
- package/dist-embed-sighting/{SightingMessages_es-B5pZonER.js → SightingMessages_es-D0SmRmmj.js} +1 -1
- package/dist-embed-sighting/{SightingMessages_fr-BC_g9MLr.js → SightingMessages_fr-BfhL_1tZ.js} +1 -1
- package/dist-embed-sighting/{SightingMessages_it-CJRrig_B.js → SightingMessages_it-BEMTqX4e.js} +1 -1
- package/dist-embed-sighting/{TraceSystem-B-YEiVUL.js → TraceSystem-B0q64xUt.js} +1 -1
- package/dist-embed-sighting/rr0-sighting.mjs +290 -290
- package/dist-embed-sighting/sightingSchema-DvayIREy.js +1 -0
- package/dist-embed-sighting/trafficRuntime-B6wWQINc.js +2 -0
- package/dist-embed-sighting-editor/{AdsbLolArchiveProvider-Ir8tinqO.js → AdsbLolArchiveProvider-DQZ62TBH.js} +1 -1
- package/dist-embed-sighting-editor/BodyEditor-CMoVz1_C.js +28 -0
- package/dist-embed-sighting-editor/BodyEditorMessages_en-C3VGB1gD.js +1 -0
- package/dist-embed-sighting-editor/BodyEditorMessages_es-DN2YBKTK.js +1 -0
- package/dist-embed-sighting-editor/BodyEditorMessages_fr-BLypXEkB.js +1 -0
- package/dist-embed-sighting-editor/BodyEditorMessages_it-W1myJQbG.js +1 -0
- package/dist-embed-sighting-editor/CaseEditorMessages_es-CKvTynXZ.js +1 -0
- package/dist-embed-sighting-editor/CaseEditorMessages_fr-D0E0a1b7.js +1 -0
- package/dist-embed-sighting-editor/CaseEditorMessages_it-BqF60OPM.js +1 -0
- package/dist-embed-sighting-editor/CloudEditorMessages_es-RrGoxm6z.js +1 -0
- package/dist-embed-sighting-editor/CloudEditorMessages_fr-CAnkW7tI.js +1 -0
- package/dist-embed-sighting-editor/CloudEditorMessages_it-Batpxtii.js +1 -0
- package/dist-embed-sighting-editor/ContrailSystem-BVhZT9MA.js +1 -0
- package/dist-embed-sighting-editor/{CoverageAssessor-C_QKvYFk.js → CoverageAssessor-nSkY_QvH.js} +1 -1
- package/dist-embed-sighting-editor/GLTFLoader-DG1UHEzj.js +1 -0
- package/dist-embed-sighting-editor/{HynekAssessor-lMXrmVFe.js → HynekAssessor-Dz-MgFyV.js} +1 -1
- package/dist-embed-sighting-editor/LaunchEditor-JWBffL-Q.js +14 -0
- package/dist-embed-sighting-editor/LaunchEditorMessages_en-j4RgQPZu.js +1 -0
- package/dist-embed-sighting-editor/LaunchEditorMessages_es-9JZv0fqZ.js +1 -0
- package/dist-embed-sighting-editor/LaunchEditorMessages_fr-BUEdQmMO.js +1 -0
- package/dist-embed-sighting-editor/LaunchEditorMessages_it-CrRnOg0x.js +1 -0
- package/dist-embed-sighting-editor/{ModelSource-BJHgjQd9.js → ModelSource-Bjn_jG24.js} +1 -1
- package/dist-embed-sighting-editor/{ModelThumbnails-BMvmda-2.js → ModelThumbnails-1HcB-ZHo.js} +1 -1
- package/dist-embed-sighting-editor/{ModelViewer-O9_A3wzF.js → ModelViewer-_dx4AdKE.js} +1 -1
- package/dist-embed-sighting-editor/{SceneNames_es-BuZsPlTw.js → SceneNames_es-Ci7l0oHM.js} +1 -1
- package/{dist-embed-sighting/SceneNames_fr-BFN6x9Z7.js → dist-embed-sighting-editor/SceneNames_fr-DrE5E2My.js} +1 -1
- package/dist-embed-sighting-editor/{SceneNames_it-BOuH3VIw.js → SceneNames_it-B62A_y2n.js} +1 -1
- package/dist-embed-sighting-editor/SightingEditorMessages_es-D5j1X6Z2.js +12 -0
- package/dist-embed-sighting-editor/SightingEditorMessages_fr-CgUfJJ3U.js +12 -0
- package/dist-embed-sighting-editor/SightingEditorMessages_it-CaQOTbfC.js +12 -0
- package/dist-embed-sighting-editor/{SightingFileEditor-BnQi03df.js → SightingFileEditor-B4rU7k4Y.js} +1 -1
- package/dist-embed-sighting-editor/{TraceSystem-DCqCjgtt.js → TraceSystem-SX5TPgKr.js} +2 -2
- package/dist-embed-sighting-editor/rr0-sighting-editor.mjs +399 -477
- package/dist-embed-sighting-editor/sightingSchema-DvayIREy.js +1 -0
- package/dist-embed-sighting-editor/trafficRuntime--m7TgUuc.js +2 -0
- package/package.json +1 -1
- package/dist-embed-scene/ContrailSystem-CQsI1Z1v.js +0 -1
- package/dist-embed-scene/GLTFLoader-DYi1DaRQ.js +0 -1
- package/dist-embed-scene/sightingSchema-5AlscPkV.js +0 -1
- package/dist-embed-scene/trafficRuntime-VEoNI8g9.js +0 -2
- package/dist-embed-sighting/AdsbLolArchiveProvider-BXH71WVn.js +0 -1
- package/dist-embed-sighting/GLTFLoader-C_t8vfKf.js +0 -1
- package/dist-embed-sighting/sightingSchema-5AlscPkV.js +0 -1
- package/dist-embed-sighting/trafficRuntime-BhspObgN.js +0 -2
- package/dist-embed-sighting-editor/BodyEditor-CiPDf3PA.js +0 -51
- package/dist-embed-sighting-editor/BodyEditorMessages_en-D6h_2jc7.js +0 -1
- package/dist-embed-sighting-editor/BodyEditorMessages_es-DfSa9Yth.js +0 -1
- package/dist-embed-sighting-editor/BodyEditorMessages_fr-CG8xnMzM.js +0 -1
- package/dist-embed-sighting-editor/BodyEditorMessages_it-CIClW1lP.js +0 -1
- package/dist-embed-sighting-editor/CaseEditorMessages_es-D5DtN8Q1.js +0 -1
- package/dist-embed-sighting-editor/CaseEditorMessages_fr-WW3gM38H.js +0 -1
- package/dist-embed-sighting-editor/CaseEditorMessages_it-CN6g0t9U.js +0 -1
- package/dist-embed-sighting-editor/CloudEditorMessages_es-ozb6J7KN.js +0 -1
- package/dist-embed-sighting-editor/CloudEditorMessages_fr-CpKSij1v.js +0 -1
- package/dist-embed-sighting-editor/CloudEditorMessages_it-CPHBLAsn.js +0 -1
- package/dist-embed-sighting-editor/ContrailSystem-oqsCCklf.js +0 -1
- package/dist-embed-sighting-editor/GLTFLoader-BlqKtwJh.js +0 -1
- package/dist-embed-sighting-editor/SightingEditorMessages_es-BCCDtLQW.js +0 -12
- package/dist-embed-sighting-editor/SightingEditorMessages_fr-C0Y7LzSQ.js +0 -12
- package/dist-embed-sighting-editor/SightingEditorMessages_it-CYA5Ai17.js +0 -12
- package/dist-embed-sighting-editor/sightingSchema-5AlscPkV.js +0 -1
- package/dist-embed-sighting-editor/trafficRuntime-Ce_f9RDO.js +0 -2
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{E as Le,H as Q,J as he,K as Se,N as G,O as de,Q as w,h as pe,C as F,X as b,Y as U,Z as ye,_ as we,$ as be,l as B,a0 as Ne,V as C,a1 as me,a2 as Ie,a3 as ge,a4 as Oe,a5 as Ce,v as V,a6 as Fe,a7 as Te,a8 as Pe,a9 as ke,aa as He,ab as J,ac as Re,ad as Z,ae as De,af as ve,P as Ge,ag as X,ah as Ue,ai as Ee,x as Be,w as v,aj as Ke,n as je,ak as Ve,M as Xe,al as ze,am as qe,an as We,o as Ye,G as z,ao as Qe,m as Je,ap as Ze,aq as $e,ar as en,as as nn,at as tn,au as xe,d as sn,av as ne,aw as te,ax as se,ay as ie,az as re,aA as rn,aB as on,B as an,e as cn}from"./rr0-sighting.mjs";function oe(f,n){if(n===Le)return console.warn("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Geometry already defined as triangles."),f;if(n===Q||n===he){let e=f.getIndex();if(e===null){const r=[],a=f.getAttribute("position");if(a!==void 0){for(let o=0;o<a.count;o++)r.push(o);f.setIndex(r),e=f.getIndex()}else return console.error("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Undefined position attribute. Processing not possible."),f}const s=e.count-2,t=[];if(n===Q)for(let r=1;r<=s;r++)t.push(e.getX(0)),t.push(e.getX(r)),t.push(e.getX(r+1));else for(let r=0;r<s;r++)r%2===0?(t.push(e.getX(r)),t.push(e.getX(r+1)),t.push(e.getX(r+2))):(t.push(e.getX(r+2)),t.push(e.getX(r+1)),t.push(e.getX(r)));t.length/3!==s&&console.error("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Unable to generate correct amount of triangles.");const i=f.clone();return i.setIndex(t),i.clearGroups(),i}else return console.error("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Unknown draw mode:",n),f}function un(f){const n=new Map,e=new Map,s=f.clone();return Ae(f,s,function(t,i){n.set(i,t),e.set(t,i)}),s.traverse(function(t){if(!t.isSkinnedMesh)return;const i=t,r=n.get(t),a=r.skeleton.bones;i.skeleton=r.skeleton.clone(),i.bindMatrix.copy(r.bindMatrix),i.skeleton.bones=a.map(function(o){return e.get(o)}),i.bind(i.skeleton,i.bindMatrix)}),s}function Ae(f,n,e){e(f,n);for(let s=0;s<f.children.length;s++)Ae(f.children[s],n.children[s],e)}class Vn extends Se{constructor(n){super(n),this.dracoLoader=null,this.ktx2Loader=null,this.meshoptDecoder=null,this.pluginCallbacks=[],this.register(function(e){return new pn(e)}),this.register(function(e){return new mn(e)}),this.register(function(e){return new Ln(e)}),this.register(function(e){return new Sn(e)}),this.register(function(e){return new yn(e)}),this.register(function(e){return new Tn(e)}),this.register(function(e){return new Rn(e)}),this.register(function(e){return new En(e)}),this.register(function(e){return new xn(e)}),this.register(function(e){return new dn(e)}),this.register(function(e){return new An(e)}),this.register(function(e){return new gn(e)}),this.register(function(e){return new Mn(e)}),this.register(function(e){return new _n(e)}),this.register(function(e){return new fn(e)}),this.register(function(e){return new ae(e,g.EXT_MESHOPT_COMPRESSION)}),this.register(function(e){return new ae(e,g.KHR_MESHOPT_COMPRESSION)}),this.register(function(e){return new wn(e)})}load(n,e,s,t){const i=this;let r;if(this.resourcePath!=="")r=this.resourcePath;else if(this.path!==""){const c=G.extractUrlBase(n);r=G.resolveURL(c,this.path)}else r=G.extractUrlBase(n);this.manager.itemStart(n);const a=function(c){t?t(c):console.error(c),i.manager.itemError(n),i.manager.itemEnd(n)},o=new de(this.manager);o.setPath(this.path),o.setResponseType("arraybuffer"),o.setRequestHeader(this.requestHeader),o.setWithCredentials(this.withCredentials),o.load(n,function(c){try{i.parse(c,r,function(u){e(u),i.manager.itemEnd(n)},a)}catch(u){a(u)}},s,a)}setDRACOLoader(n){return this.dracoLoader=n,this}setKTX2Loader(n){return this.ktx2Loader=n,this}setMeshoptDecoder(n){return this.meshoptDecoder=n,this}register(n){return this.pluginCallbacks.indexOf(n)===-1&&this.pluginCallbacks.push(n),this}unregister(n){return this.pluginCallbacks.indexOf(n)!==-1&&this.pluginCallbacks.splice(this.pluginCallbacks.indexOf(n),1),this}parse(n,e,s,t){let i;const r={},a={},o=new TextDecoder;if(typeof n=="string")i=JSON.parse(n);else if(n instanceof ArrayBuffer)if(o.decode(new Uint8Array(n,0,4))===_e){try{r[g.KHR_BINARY_GLTF]=new bn(n)}catch(l){t&&t(l);return}i=JSON.parse(r[g.KHR_BINARY_GLTF].content)}else i=JSON.parse(o.decode(n));else i=n;if(i.asset===void 0||i.asset.version[0]<2){t&&t(new Error("THREE.GLTFLoader: Unsupported asset. glTF versions >=2.0 are supported."));return}const c=new Bn(i,{path:e||this.resourcePath||"",crossOrigin:this.crossOrigin,requestHeader:this.requestHeader,manager:this.manager,ktx2Loader:this.ktx2Loader,meshoptDecoder:this.meshoptDecoder});c.fileLoader.setRequestHeader(this.requestHeader);for(let u=0;u<this.pluginCallbacks.length;u++){const l=this.pluginCallbacks[u](c);l.name||console.error("THREE.GLTFLoader: Invalid plugin found: missing name"),a[l.name]=l,r[l.name]=!0}if(i.extensionsUsed)for(let u=0;u<i.extensionsUsed.length;++u){const l=i.extensionsUsed[u],h=i.extensionsRequired||[];switch(l){case g.KHR_MATERIALS_UNLIT:r[l]=new hn;break;case g.KHR_DRACO_MESH_COMPRESSION:r[l]=new Nn(i,this.dracoLoader);break;case g.KHR_TEXTURE_TRANSFORM:r[l]=new In;break;case g.KHR_MESH_QUANTIZATION:r[l]=new On;break;default:h.indexOf(l)>=0&&a[l]===void 0&&console.warn('THREE.GLTFLoader: Unknown extension "'+l+'".')}}c.setExtensions(r),c.setPlugins(a),c.parse(s,t)}parseAsync(n,e){const s=this;return new Promise(function(t,i){s.parse(n,e,t,i)})}}function ln(){let f={};return{get:function(n){return f[n]},add:function(n,e){f[n]=e},remove:function(n){delete f[n]},removeAll:function(){f={}}}}function _(f,n,e){const s=f.json.materials[n];return s.extensions&&s.extensions[e]?s.extensions[e]:null}const g={KHR_BINARY_GLTF:"KHR_binary_glTF",KHR_DRACO_MESH_COMPRESSION:"KHR_draco_mesh_compression",KHR_LIGHTS_PUNCTUAL:"KHR_lights_punctual",KHR_MATERIALS_CLEARCOAT:"KHR_materials_clearcoat",KHR_MATERIALS_DISPERSION:"KHR_materials_dispersion",KHR_MATERIALS_IOR:"KHR_materials_ior",KHR_MATERIALS_SHEEN:"KHR_materials_sheen",KHR_MATERIALS_SPECULAR:"KHR_materials_specular",KHR_MATERIALS_TRANSMISSION:"KHR_materials_transmission",KHR_MATERIALS_IRIDESCENCE:"KHR_materials_iridescence",KHR_MATERIALS_ANISOTROPY:"KHR_materials_anisotropy",KHR_MATERIALS_UNLIT:"KHR_materials_unlit",KHR_MATERIALS_VOLUME:"KHR_materials_volume",KHR_TEXTURE_BASISU:"KHR_texture_basisu",KHR_TEXTURE_TRANSFORM:"KHR_texture_transform",KHR_MESH_QUANTIZATION:"KHR_mesh_quantization",KHR_MATERIALS_EMISSIVE_STRENGTH:"KHR_materials_emissive_strength",EXT_MATERIALS_BUMP:"EXT_materials_bump",EXT_TEXTURE_WEBP:"EXT_texture_webp",EXT_TEXTURE_AVIF:"EXT_texture_avif",EXT_MESHOPT_COMPRESSION:"EXT_meshopt_compression",KHR_MESHOPT_COMPRESSION:"KHR_meshopt_compression",EXT_MESH_GPU_INSTANCING:"EXT_mesh_gpu_instancing"};class fn{constructor(n){this.parser=n,this.name=g.KHR_LIGHTS_PUNCTUAL,this.cache={refs:{},uses:{}}}_markDefs(){const n=this.parser,e=this.parser.json.nodes||[];for(let s=0,t=e.length;s<t;s++){const i=e[s];i.extensions&&i.extensions[this.name]&&i.extensions[this.name].light!==void 0&&n._addNodeRef(this.cache,i.extensions[this.name].light)}}_loadLight(n){const e=this.parser,s="light:"+n;let t=e.cache.get(s);if(t)return t;const i=e.json,o=((i.extensions&&i.extensions[this.name]||{}).lights||[])[n];let c;const u=new F(16777215);o.color!==void 0&&u.setRGB(o.color[0],o.color[1],o.color[2],b);const l=o.range!==void 0?o.range:0;switch(o.type){case"directional":c=new be(u),c.target.position.set(0,0,-1),c.add(c.target);break;case"point":c=new we(u),c.distance=l;break;case"spot":c=new ye(u),c.distance=l,o.spot=o.spot||{},o.spot.innerConeAngle=o.spot.innerConeAngle!==void 0?o.spot.innerConeAngle:0,o.spot.outerConeAngle=o.spot.outerConeAngle!==void 0?o.spot.outerConeAngle:Math.PI/4,c.angle=o.spot.outerConeAngle,c.penumbra=1-o.spot.innerConeAngle/o.spot.outerConeAngle,c.target.position.set(0,0,-1),c.add(c.target);break;default:throw new Error("THREE.GLTFLoader: Unexpected light type: "+o.type)}return c.position.set(0,0,0),y(c,o),o.intensity!==void 0&&(c.intensity=o.intensity),c.name=e.createUniqueName(o.name||"light_"+n),t=Promise.resolve(c),e.cache.add(s,t),t}getDependency(n,e){if(n==="light")return this._loadLight(e)}createNodeAttachment(n){const e=this,s=this.parser,i=s.json.nodes[n],a=(i.extensions&&i.extensions[this.name]||{}).light;return a===void 0?null:this._loadLight(a).then(function(o){return s._getNodeRef(e.cache,a,o)})}}class hn{constructor(){this.name=g.KHR_MATERIALS_UNLIT}getMaterialType(){return v}extendParams(n,e,s){const t=[];n.color=new F(1,1,1),n.opacity=1;const i=e.pbrMetallicRoughness;if(i){if(Array.isArray(i.baseColorFactor)){const r=i.baseColorFactor;n.color.setRGB(r[0],r[1],r[2],b),n.opacity=r[3]}i.baseColorTexture!==void 0&&t.push(s.assignTexture(n,"map",i.baseColorTexture,U))}return Promise.all(t)}}class dn{constructor(n){this.parser=n,this.name=g.KHR_MATERIALS_EMISSIVE_STRENGTH}extendMaterialParams(n,e){const s=_(this.parser,n,this.name);return s===null||s.emissiveStrength!==void 0&&(e.emissiveIntensity=s.emissiveStrength),Promise.resolve()}}class pn{constructor(n){this.parser=n,this.name=g.KHR_MATERIALS_CLEARCOAT}getMaterialType(n){return _(this.parser,n,this.name)!==null?w:null}extendMaterialParams(n,e){const s=_(this.parser,n,this.name);if(s===null)return Promise.resolve();const t=[];if(s.clearcoatFactor!==void 0&&(e.clearcoat=s.clearcoatFactor),s.clearcoatTexture!==void 0&&t.push(this.parser.assignTexture(e,"clearcoatMap",s.clearcoatTexture)),s.clearcoatRoughnessFactor!==void 0&&(e.clearcoatRoughness=s.clearcoatRoughnessFactor),s.clearcoatRoughnessTexture!==void 0&&t.push(this.parser.assignTexture(e,"clearcoatRoughnessMap",s.clearcoatRoughnessTexture)),s.clearcoatNormalTexture!==void 0&&(t.push(this.parser.assignTexture(e,"clearcoatNormalMap",s.clearcoatNormalTexture)),s.clearcoatNormalTexture.scale!==void 0)){const i=s.clearcoatNormalTexture.scale;e.clearcoatNormalScale=new pe(i,i)}return Promise.all(t)}}class mn{constructor(n){this.parser=n,this.name=g.KHR_MATERIALS_DISPERSION}getMaterialType(n){return _(this.parser,n,this.name)!==null?w:null}extendMaterialParams(n,e){const s=_(this.parser,n,this.name);return s===null||(e.dispersion=s.dispersion!==void 0?s.dispersion:0),Promise.resolve()}}class gn{constructor(n){this.parser=n,this.name=g.KHR_MATERIALS_IRIDESCENCE}getMaterialType(n){return _(this.parser,n,this.name)!==null?w:null}extendMaterialParams(n,e){const s=_(this.parser,n,this.name);if(s===null)return Promise.resolve();const t=[];return s.iridescenceFactor!==void 0&&(e.iridescence=s.iridescenceFactor),s.iridescenceTexture!==void 0&&t.push(this.parser.assignTexture(e,"iridescenceMap",s.iridescenceTexture)),s.iridescenceIor!==void 0&&(e.iridescenceIOR=s.iridescenceIor),e.iridescenceThicknessRange===void 0&&(e.iridescenceThicknessRange=[100,400]),s.iridescenceThicknessMinimum!==void 0&&(e.iridescenceThicknessRange[0]=s.iridescenceThicknessMinimum),s.iridescenceThicknessMaximum!==void 0&&(e.iridescenceThicknessRange[1]=s.iridescenceThicknessMaximum),s.iridescenceThicknessTexture!==void 0&&t.push(this.parser.assignTexture(e,"iridescenceThicknessMap",s.iridescenceThicknessTexture)),Promise.all(t)}}class Tn{constructor(n){this.parser=n,this.name=g.KHR_MATERIALS_SHEEN}getMaterialType(n){return _(this.parser,n,this.name)!==null?w:null}extendMaterialParams(n,e){const s=_(this.parser,n,this.name);if(s===null)return Promise.resolve();const t=[];if(e.sheenColor=new F(0,0,0),e.sheenRoughness=0,e.sheen=1,s.sheenColorFactor!==void 0){const i=s.sheenColorFactor;e.sheenColor.setRGB(i[0],i[1],i[2],b)}return s.sheenRoughnessFactor!==void 0&&(e.sheenRoughness=s.sheenRoughnessFactor),s.sheenColorTexture!==void 0&&t.push(this.parser.assignTexture(e,"sheenColorMap",s.sheenColorTexture,U)),s.sheenRoughnessTexture!==void 0&&t.push(this.parser.assignTexture(e,"sheenRoughnessMap",s.sheenRoughnessTexture)),Promise.all(t)}}class Rn{constructor(n){this.parser=n,this.name=g.KHR_MATERIALS_TRANSMISSION}getMaterialType(n){return _(this.parser,n,this.name)!==null?w:null}extendMaterialParams(n,e){const s=_(this.parser,n,this.name);if(s===null)return Promise.resolve();const t=[];return s.transmissionFactor!==void 0&&(e.transmission=s.transmissionFactor),s.transmissionTexture!==void 0&&t.push(this.parser.assignTexture(e,"transmissionMap",s.transmissionTexture)),Promise.all(t)}}class En{constructor(n){this.parser=n,this.name=g.KHR_MATERIALS_VOLUME}getMaterialType(n){return _(this.parser,n,this.name)!==null?w:null}extendMaterialParams(n,e){const s=_(this.parser,n,this.name);if(s===null)return Promise.resolve();const t=[];e.thickness=s.thicknessFactor!==void 0?s.thicknessFactor:0,s.thicknessTexture!==void 0&&t.push(this.parser.assignTexture(e,"thicknessMap",s.thicknessTexture)),e.attenuationDistance=s.attenuationDistance||1/0;const i=s.attenuationColor||[1,1,1];return e.attenuationColor=new F().setRGB(i[0],i[1],i[2],b),Promise.all(t)}}class xn{constructor(n){this.parser=n,this.name=g.KHR_MATERIALS_IOR}getMaterialType(n){return _(this.parser,n,this.name)!==null?w:null}extendMaterialParams(n,e){const s=_(this.parser,n,this.name);return s===null||(e.ior=s.ior!==void 0?s.ior:1.5,e.ior===0&&(e.ior=1e3)),Promise.resolve()}}class An{constructor(n){this.parser=n,this.name=g.KHR_MATERIALS_SPECULAR}getMaterialType(n){return _(this.parser,n,this.name)!==null?w:null}extendMaterialParams(n,e){const s=_(this.parser,n,this.name);if(s===null)return Promise.resolve();const t=[];e.specularIntensity=s.specularFactor!==void 0?s.specularFactor:1,s.specularTexture!==void 0&&t.push(this.parser.assignTexture(e,"specularIntensityMap",s.specularTexture));const i=s.specularColorFactor||[1,1,1];return e.specularColor=new F().setRGB(i[0],i[1],i[2],b),s.specularColorTexture!==void 0&&t.push(this.parser.assignTexture(e,"specularColorMap",s.specularColorTexture,U)),Promise.all(t)}}class _n{constructor(n){this.parser=n,this.name=g.EXT_MATERIALS_BUMP}getMaterialType(n){return _(this.parser,n,this.name)!==null?w:null}extendMaterialParams(n,e){const s=_(this.parser,n,this.name);if(s===null)return Promise.resolve();const t=[];return e.bumpScale=s.bumpFactor!==void 0?s.bumpFactor:1,s.bumpTexture!==void 0&&t.push(this.parser.assignTexture(e,"bumpMap",s.bumpTexture)),Promise.all(t)}}class Mn{constructor(n){this.parser=n,this.name=g.KHR_MATERIALS_ANISOTROPY}getMaterialType(n){return _(this.parser,n,this.name)!==null?w:null}extendMaterialParams(n,e){const s=_(this.parser,n,this.name);if(s===null)return Promise.resolve();const t=[];return s.anisotropyStrength!==void 0&&(e.anisotropy=s.anisotropyStrength),s.anisotropyRotation!==void 0&&(e.anisotropyRotation=s.anisotropyRotation),s.anisotropyTexture!==void 0&&t.push(this.parser.assignTexture(e,"anisotropyMap",s.anisotropyTexture)),Promise.all(t)}}class Ln{constructor(n){this.parser=n,this.name=g.KHR_TEXTURE_BASISU}loadTexture(n){const e=this.parser,s=e.json,t=s.textures[n];if(!t.extensions||!t.extensions[this.name])return null;const i=t.extensions[this.name],r=e.options.ktx2Loader;if(!r){if(s.extensionsRequired&&s.extensionsRequired.indexOf(this.name)>=0)throw new Error("THREE.GLTFLoader: setKTX2Loader must be called before loading KTX2 textures");return null}return e.loadTextureImage(n,i.source,r)}}class Sn{constructor(n){this.parser=n,this.name=g.EXT_TEXTURE_WEBP}loadTexture(n){const e=this.name,s=this.parser,t=s.json,i=t.textures[n];if(!i.extensions||!i.extensions[e])return null;const r=i.extensions[e],a=t.images[r.source];let o=s.textureLoader;if(a.uri){const c=s.options.manager.getHandler(a.uri);c!==null&&(o=c)}return s.loadTextureImage(n,r.source,o)}}class yn{constructor(n){this.parser=n,this.name=g.EXT_TEXTURE_AVIF}loadTexture(n){const e=this.name,s=this.parser,t=s.json,i=t.textures[n];if(!i.extensions||!i.extensions[e])return null;const r=i.extensions[e],a=t.images[r.source];let o=s.textureLoader;if(a.uri){const c=s.options.manager.getHandler(a.uri);c!==null&&(o=c)}return s.loadTextureImage(n,r.source,o)}}class ae{constructor(n,e){this.name=e,this.parser=n}loadBufferView(n){const e=this.parser.json,s=e.bufferViews[n];if(s.extensions&&s.extensions[this.name]){const t=s.extensions[this.name],i=this.parser.getDependency("buffer",t.buffer),r=this.parser.options.meshoptDecoder;if(!r||!r.supported){if(e.extensionsRequired&&e.extensionsRequired.indexOf(this.name)>=0)throw new Error("THREE.GLTFLoader: setMeshoptDecoder must be called before loading compressed files");return null}return i.then(function(a){const o=t.byteOffset||0,c=t.byteLength||0,u=t.count,l=t.byteStride,h=new Uint8Array(a,o,c);return r.decodeGltfBufferAsync?r.decodeGltfBufferAsync(u,l,h,t.mode,t.filter).then(function(d){return d.buffer}):r.ready.then(function(){const d=new ArrayBuffer(u*l);return r.decodeGltfBuffer(new Uint8Array(d),u,l,h,t.mode,t.filter),d})})}else return null}}class wn{constructor(n){this.name=g.EXT_MESH_GPU_INSTANCING,this.parser=n}createNodeMesh(n){const e=this.parser.json,s=e.nodes[n];if(!s.extensions||!s.extensions[this.name]||s.mesh===void 0)return null;const t=e.meshes[s.mesh];for(const c of t.primitives)if(c.mode!==L.TRIANGLES&&c.mode!==L.TRIANGLE_STRIP&&c.mode!==L.TRIANGLE_FAN&&c.mode!==void 0)return null;const r=s.extensions[this.name].attributes,a=[],o={};for(const c in r)a.push(this.parser.getDependency("accessor",r[c]).then(u=>(o[c]=u,o[c])));return a.length<1?null:(a.push(this.parser.createNodeMesh(n)),Promise.all(a).then(c=>{const u=c.pop(),l=u.isGroup?u.children:[u],h=c[0].count,d=[];for(const p of l){const R=new B,m=new C,T=new me,A=new C(1,1,1),x=new Ne(p.geometry,p.material,h);for(let E=0;E<h;E++)o.TRANSLATION&&m.fromBufferAttribute(o.TRANSLATION,E),o.ROTATION&&T.fromBufferAttribute(o.ROTATION,E),o.SCALE&&A.fromBufferAttribute(o.SCALE,E),x.setMatrixAt(E,R.compose(m,T,A));for(const E in o)if(E==="_COLOR_0"){const M=o[E];x.instanceColor=new Ie(M.array,M.itemSize,M.normalized)}else E!=="TRANSLATION"&&E!=="ROTATION"&&E!=="SCALE"&&p.geometry.setAttribute(E,o[E]);ge.prototype.copy.call(x,p),this.parser.assignFinalMaterial(x),d.push(x)}return u.isGroup?(u.clear(),u.add(...d),u):d[0]}))}}const _e="glTF",D=12,ce={JSON:1313821514,BIN:5130562};class bn{constructor(n){this.name=g.KHR_BINARY_GLTF,this.content=null,this.body=null;const e=new DataView(n,0,D),s=new TextDecoder;if(this.header={magic:s.decode(new Uint8Array(n.slice(0,4))),version:e.getUint32(4,!0),length:e.getUint32(8,!0)},this.header.magic!==_e)throw new Error("THREE.GLTFLoader: Unsupported glTF-Binary header.");if(this.header.version<2)throw new Error("THREE.GLTFLoader: Legacy binary file detected.");const t=this.header.length-D,i=new DataView(n,D);let r=0;for(;r<t;){const a=i.getUint32(r,!0);r+=4;const o=i.getUint32(r,!0);if(r+=4,o===ce.JSON){const c=new Uint8Array(n,D+r,a);this.content=s.decode(c)}else if(o===ce.BIN){const c=D+r;this.body=n.slice(c,c+a)}r+=a}if(this.content===null)throw new Error("THREE.GLTFLoader: JSON content not found.")}}class Nn{constructor(n,e){if(!e)throw new Error("THREE.GLTFLoader: No DRACOLoader instance provided.");this.name=g.KHR_DRACO_MESH_COMPRESSION,this.json=n,this.dracoLoader=e,this.dracoLoader.preload()}decodePrimitive(n,e){const s=this.json,t=this.dracoLoader,i=n.extensions[this.name].bufferView,r=n.extensions[this.name].attributes,a={},o={},c={};for(const u in r){const l=$[u]||u.toLowerCase();a[l]=r[u]}for(const u in n.attributes){const l=$[u]||u.toLowerCase();if(r[u]!==void 0){const h=s.accessors[n.attributes[u]],d=k[h.componentType];c[l]=d.name,o[l]=h.normalized===!0}}return e.getDependency("bufferView",i).then(function(u){return new Promise(function(l,h){t.decodeDracoFile(u,function(d){for(const p in d.attributes){const R=d.attributes[p],m=o[p];m!==void 0&&(R.normalized=m)}l(d)},a,c,b,h)})})}}class In{constructor(){this.name=g.KHR_TEXTURE_TRANSFORM}extendTexture(n,e){return(e.texCoord===void 0||e.texCoord===n.channel)&&e.offset===void 0&&e.rotation===void 0&&e.scale===void 0||(n=n.clone(),e.texCoord!==void 0&&(n.channel=e.texCoord),e.offset!==void 0&&n.offset.fromArray(e.offset),e.rotation!==void 0&&(n.rotation=e.rotation),e.scale!==void 0&&n.repeat.fromArray(e.scale),n.needsUpdate=!0),n}}class On{constructor(){this.name=g.KHR_MESH_QUANTIZATION}}class Me extends on{constructor(n,e,s,t){super(n,e,s,t)}copySampleValue_(n){const e=this.resultBuffer,s=this.sampleValues,t=this.valueSize,i=n*t*3+t;for(let r=0;r!==t;r++)e[r]=s[i+r];return e}interpolate_(n,e,s,t){const i=this.resultBuffer,r=this.sampleValues,a=this.valueSize,o=a*2,c=a*3,u=t-e,l=(s-e)/u,h=l*l,d=h*l,p=n*c,R=p-c,m=-2*d+3*h,T=d-h,A=1-m,x=T-h+l;for(let E=0;E!==a;E++){const M=r[R+E+a],N=r[R+E+o]*u,S=r[p+E+a],H=r[p+E]*u;i[E]=A*M+x*N+m*S+T*H}return i}}const Cn=new me;class Fn extends Me{interpolate_(n,e,s,t){const i=super.interpolate_(n,e,s,t);return Cn.fromArray(i).normalize().toArray(i),i}}const L={POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6},k={5120:Int8Array,5121:Uint8Array,5122:Int16Array,5123:Uint16Array,5125:Uint32Array,5126:Float32Array},ue={9728:Re,9729:J,9984:He,9985:ke,9986:Pe,9987:Te},le={33071:ve,33648:De,10497:Z},q={SCALAR:1,VEC2:2,VEC3:3,VEC4:4,MAT2:4,MAT3:9,MAT4:16},$={POSITION:"position",NORMAL:"normal",TANGENT:"tangent",TEXCOORD_0:"uv",TEXCOORD_1:"uv1",TEXCOORD_2:"uv2",TEXCOORD_3:"uv3",COLOR_0:"color",WEIGHTS_0:"skinWeight",JOINTS_0:"skinIndex"},I={scale:"scale",translation:"position",rotation:"quaternion",weights:"morphTargetInfluences"},Pn={CUBICSPLINE:void 0,LINEAR:xe,STEP:tn},W={OPAQUE:"OPAQUE",MASK:"MASK",BLEND:"BLEND"};function kn(f){return f.DefaultMaterial===void 0&&(f.DefaultMaterial=new Ee({color:16777215,emissive:0,metalness:1,roughness:1,transparent:!1,depthTest:!0,side:rn})),f.DefaultMaterial}function O(f,n,e){for(const s in e.extensions)f[s]===void 0&&(n.userData.gltfExtensions=n.userData.gltfExtensions||{},n.userData.gltfExtensions[s]=e.extensions[s])}function y(f,n){n.extras!==void 0&&(typeof n.extras=="object"?Object.assign(f.userData,n.extras):console.warn("THREE.GLTFLoader: Ignoring primitive type .extras, "+n.extras))}function Hn(f,n,e){let s=!1,t=!1,i=!1;for(let c=0,u=n.length;c<u;c++){const l=n[c];if(l.POSITION!==void 0&&(s=!0),l.NORMAL!==void 0&&(t=!0),l.COLOR_0!==void 0&&(i=!0),s&&t&&i)break}if(!s&&!t&&!i)return Promise.resolve(f);const r=[],a=[],o=[];for(let c=0,u=n.length;c<u;c++){const l=n[c];if(s){const h=l.POSITION!==void 0?e.getDependency("accessor",l.POSITION):f.attributes.position;r.push(h)}if(t){const h=l.NORMAL!==void 0?e.getDependency("accessor",l.NORMAL):f.attributes.normal;a.push(h)}if(i){const h=l.COLOR_0!==void 0?e.getDependency("accessor",l.COLOR_0):f.attributes.color;o.push(h)}}return Promise.all([Promise.all(r),Promise.all(a),Promise.all(o)]).then(function(c){const u=c[0],l=c[1],h=c[2];return s&&(f.morphAttributes.position=u),t&&(f.morphAttributes.normal=l),i&&(f.morphAttributes.color=h),f.morphTargetsRelative=!0,f})}function Dn(f,n){if(f.updateMorphTargets(),n.weights!==void 0)for(let e=0,s=n.weights.length;e<s;e++)f.morphTargetInfluences[e]=n.weights[e];if(n.extras&&Array.isArray(n.extras.targetNames)){const e=n.extras.targetNames;if(f.morphTargetInfluences.length===e.length){f.morphTargetDictionary={};for(let s=0,t=e.length;s<t;s++)f.morphTargetDictionary[e[s]]=s}else console.warn("THREE.GLTFLoader: Invalid extras.targetNames length. Ignoring names.")}}function vn(f){let n;const e=f.extensions&&f.extensions[g.KHR_DRACO_MESH_COMPRESSION];if(e?n="draco:"+e.bufferView+":"+e.indices+":"+Y(e.attributes):n=f.indices+":"+Y(f.attributes)+":"+f.mode,f.targets!==void 0)for(let s=0,t=f.targets.length;s<t;s++)n+=":"+Y(f.targets[s]);return n}function Y(f){let n="";const e=Object.keys(f).sort();for(let s=0,t=e.length;s<t;s++)n+=e[s]+":"+f[e[s]]+";";return n}function ee(f){switch(f){case Int8Array:return 1/127;case Uint8Array:return 1/255;case Int16Array:return 1/32767;case Uint16Array:return 1/65535;default:throw new Error("THREE.GLTFLoader: Unsupported normalized accessor component type.")}}function Gn(f){return f.search(/\.jpe?g($|\?)/i)>0||f.search(/^data\:image\/jpeg/)===0?"image/jpeg":f.search(/\.webp($|\?)/i)>0||f.search(/^data\:image\/webp/)===0?"image/webp":f.search(/\.ktx2($|\?)/i)>0||f.search(/^data\:image\/ktx2/)===0?"image/ktx2":"image/png"}const Un=new B;class Bn{constructor(n={},e={}){this.json=n,this.extensions={},this.plugins={},this.options=e,this.cache=new ln,this.associations=new Map,this.primitiveCache={},this.nodeCache={},this.meshCache={refs:{},uses:{}},this.cameraCache={refs:{},uses:{}},this.lightCache={refs:{},uses:{}},this.sourceCache={},this.textureCache={},this.nodeNamesUsed={};let s=!1,t=-1,i=!1,r=-1;if(typeof navigator<"u"&&typeof navigator.userAgent<"u"){const a=navigator.userAgent;s=/^((?!chrome|android).)*safari/i.test(a)===!0;const o=a.match(/Version\/(\d+)/);t=s&&o?parseInt(o[1],10):-1,i=a.indexOf("Firefox")>-1,r=i?a.match(/Firefox\/([0-9]+)\./)[1]:-1}typeof createImageBitmap>"u"||s&&t<17||i&&r<98?this.textureLoader=new Oe(this.options.manager):this.textureLoader=new Ce(this.options.manager),this.textureLoader.setCrossOrigin(this.options.crossOrigin),this.textureLoader.setRequestHeader(this.options.requestHeader),this.fileLoader=new de(this.options.manager),this.fileLoader.setResponseType("arraybuffer"),this.options.crossOrigin==="use-credentials"&&this.fileLoader.setWithCredentials(!0)}setExtensions(n){this.extensions=n}setPlugins(n){this.plugins=n}parse(n,e){const s=this,t=this.json,i=this.extensions;this.cache.removeAll(),this.nodeCache={},this._invokeAll(function(r){return r._markDefs&&r._markDefs()}),Promise.all(this._invokeAll(function(r){return r.beforeRoot&&r.beforeRoot()})).then(function(){return Promise.all([s.getDependencies("scene"),s.getDependencies("animation"),s.getDependencies("camera")])}).then(function(r){const a={scene:r[0][t.scene||0],scenes:r[0],animations:r[1],cameras:r[2],asset:t.asset,parser:s,userData:{}};return O(i,a,t),y(a,t),Promise.all(s._invokeAll(function(o){return o.afterRoot&&o.afterRoot(a)})).then(function(){for(const o of a.scenes)o.updateMatrixWorld();n(a)})}).catch(e)}_markDefs(){const n=this.json.nodes||[],e=this.json.skins||[],s=this.json.meshes||[];for(let t=0,i=e.length;t<i;t++){const r=e[t].joints;for(let a=0,o=r.length;a<o;a++)n[r[a]].isBone=!0}for(let t=0,i=n.length;t<i;t++){const r=n[t];r.mesh!==void 0&&(this._addNodeRef(this.meshCache,r.mesh),r.skin!==void 0&&(s[r.mesh].isSkinnedMesh=!0)),r.camera!==void 0&&this._addNodeRef(this.cameraCache,r.camera)}}_addNodeRef(n,e){e!==void 0&&(n.refs[e]===void 0&&(n.refs[e]=n.uses[e]=0),n.refs[e]++)}_getNodeRef(n,e,s){if(n.refs[e]<=1)return s;const t=s.clone(),i=(r,a)=>{const o=this.associations.get(r);o!=null&&this.associations.set(a,o);for(const[c,u]of r.children.entries())i(u,a.children[c])};return i(s,t),t.name+="_instance_"+n.uses[e]++,t}_invokeOne(n){const e=Object.values(this.plugins);e.push(this);for(let s=0;s<e.length;s++){const t=n(e[s]);if(t)return t}return null}_invokeAll(n){const e=Object.values(this.plugins);e.unshift(this);const s=[];for(let t=0;t<e.length;t++){const i=n(e[t]);i&&s.push(i)}return s}getDependency(n,e){const s=n+":"+e;let t=this.cache.get(s);if(!t){switch(n){case"scene":t=this.loadScene(e);break;case"node":t=this._invokeOne(function(i){return i.loadNode&&i.loadNode(e)});break;case"mesh":t=this._invokeOne(function(i){return i.loadMesh&&i.loadMesh(e)});break;case"accessor":t=this.loadAccessor(e);break;case"bufferView":t=this._invokeOne(function(i){return i.loadBufferView&&i.loadBufferView(e)});break;case"buffer":t=this.loadBuffer(e);break;case"material":t=this._invokeOne(function(i){return i.loadMaterial&&i.loadMaterial(e)});break;case"texture":t=this._invokeOne(function(i){return i.loadTexture&&i.loadTexture(e)});break;case"skin":t=this.loadSkin(e);break;case"animation":t=this._invokeOne(function(i){return i.loadAnimation&&i.loadAnimation(e)});break;case"camera":t=this.loadCamera(e);break;default:if(t=this._invokeOne(function(i){return i!=this&&i.getDependency&&i.getDependency(n,e)}),!t)throw new Error("Unknown type: "+n);break}this.cache.add(s,t)}return t}getDependencies(n){let e=this.cache.get(n);if(!e){const s=this,t=this.json[n+(n==="mesh"?"es":"s")]||[];e=Promise.all(t.map(function(i,r){return s.getDependency(n,r)})),this.cache.add(n,e)}return e}loadBuffer(n){const e=this.json.buffers[n],s=this.fileLoader;if(e.type&&e.type!=="arraybuffer")throw new Error("THREE.GLTFLoader: "+e.type+" buffer type is not supported.");if(e.uri===void 0&&n===0)return Promise.resolve(this.extensions[g.KHR_BINARY_GLTF].body);const t=this.options;return new Promise(function(i,r){s.load(G.resolveURL(e.uri,t.path),i,void 0,function(){r(new Error('THREE.GLTFLoader: Failed to load buffer "'+e.uri+'".'))})})}loadBufferView(n){const e=this.json.bufferViews[n];return this.getDependency("buffer",e.buffer).then(function(s){const t=e.byteLength||0,i=e.byteOffset||0;return s.slice(i,i+t)})}loadAccessor(n){const e=this,s=this.json,t=this.json.accessors[n];if(t.bufferView===void 0&&t.sparse===void 0){const r=q[t.type],a=k[t.componentType],o=t.normalized===!0,c=new a(t.count*r);return Promise.resolve(new V(c,r,o))}const i=[];return t.bufferView!==void 0?i.push(this.getDependency("bufferView",t.bufferView)):i.push(null),t.sparse!==void 0&&(i.push(this.getDependency("bufferView",t.sparse.indices.bufferView)),i.push(this.getDependency("bufferView",t.sparse.values.bufferView))),Promise.all(i).then(function(r){const a=r[0],o=q[t.type],c=k[t.componentType],u=c.BYTES_PER_ELEMENT,l=u*o,h=t.byteOffset||0,d=t.bufferView!==void 0?s.bufferViews[t.bufferView].byteStride:void 0,p=t.normalized===!0;let R,m;if(d&&d!==l){const T=Math.floor(h/d),A="InterleavedBuffer:"+t.bufferView+":"+t.componentType+":"+T+":"+t.count;let x=e.cache.get(A);x||(R=new c(a,T*d,t.count*d/u),x=new Fe(R,d/u),e.cache.add(A,x)),m=new sn(x,o,h%d/u,p)}else a===null?R=new c(t.count*o):R=new c(a,h,t.count*o),m=new V(R,o,p);if(t.sparse!==void 0){const T=q.SCALAR,A=k[t.sparse.indices.componentType],x=t.sparse.indices.byteOffset||0,E=t.sparse.values.byteOffset||0,M=new A(r[1],x,t.sparse.count*T),N=new c(r[2],E,t.sparse.count*o);a!==null&&(m=new V(m.array.slice(),m.itemSize,m.normalized)),m.normalized=!1;for(let S=0,H=M.length;S<H;S++){const P=M[S];if(m.setX(P,N[S*o]),o>=2&&m.setY(P,N[S*o+1]),o>=3&&m.setZ(P,N[S*o+2]),o>=4&&m.setW(P,N[S*o+3]),o>=5)throw new Error("THREE.GLTFLoader: Unsupported itemSize in sparse BufferAttribute.")}m.normalized=p}return m})}loadTexture(n){const e=this.json,s=this.options,i=e.textures[n].source,r=e.images[i];let a=this.textureLoader;if(r.uri){const o=s.manager.getHandler(r.uri);o!==null&&(a=o)}return this.loadTextureImage(n,i,a)}loadTextureImage(n,e,s){const t=this,i=this.json,r=i.textures[n],a=i.images[e],o=(a.uri||a.bufferView)+":"+r.sampler;if(this.textureCache[o])return this.textureCache[o];const c=this.loadImageSource(e,s).then(function(u){u.flipY=!1,u.name=r.name||a.name||"",u.name===""&&typeof a.uri=="string"&&a.uri.startsWith("data:image/")===!1&&(u.name=a.uri);const h=(i.samplers||{})[r.sampler]||{};return u.magFilter=ue[h.magFilter]||J,u.minFilter=ue[h.minFilter]||Te,u.wrapS=le[h.wrapS]||Z,u.wrapT=le[h.wrapT]||Z,u.generateMipmaps=!u.isCompressedTexture&&u.minFilter!==Re&&u.minFilter!==J,t.associations.set(u,{textures:n}),u}).catch(function(){return null});return this.textureCache[o]=c,c}loadImageSource(n,e){const s=this,t=this.json,i=this.options;if(this.sourceCache[n]!==void 0)return this.sourceCache[n].then(l=>l.clone());const r=t.images[n],a=self.URL||self.webkitURL;let o=r.uri||"",c=!1;if(r.bufferView!==void 0)o=s.getDependency("bufferView",r.bufferView).then(function(l){c=!0;const h=new Blob([l],{type:r.mimeType});return o=a.createObjectURL(h),o});else if(r.uri===void 0)throw new Error("THREE.GLTFLoader: Image "+n+" is missing URI and bufferView");const u=Promise.resolve(o).then(function(l){return new Promise(function(h,d){let p=h;e.isImageBitmapLoader===!0&&(p=function(R){const m=new ne(R);m.needsUpdate=!0,h(m)}),e.load(G.resolveURL(l,i.path),p,void 0,d)})}).then(function(l){return c===!0&&a.revokeObjectURL(o),y(l,r),l.userData.mimeType=r.mimeType||Gn(r.uri),l}).catch(function(l){throw console.error("THREE.GLTFLoader: Couldn't load texture",o),l});return this.sourceCache[n]=u,u}assignTexture(n,e,s,t){const i=this;return this.getDependency("texture",s.index).then(function(r){if(!r)return null;if(s.texCoord!==void 0&&s.texCoord>0&&(r=r.clone(),r.channel=s.texCoord),i.extensions[g.KHR_TEXTURE_TRANSFORM]){const a=s.extensions!==void 0?s.extensions[g.KHR_TEXTURE_TRANSFORM]:void 0;if(a){const o=i.associations.get(r);r=i.extensions[g.KHR_TEXTURE_TRANSFORM].extendTexture(r,a),i.associations.set(r,o)}}return t!==void 0&&(r.colorSpace=t),n[e]=r,r})}assignFinalMaterial(n){const e=n.geometry;let s=n.material;const t=e.attributes.tangent===void 0,i=e.attributes.color!==void 0,r=e.attributes.normal===void 0;if(n.isPoints){const a="PointsMaterial:"+s.uuid;let o=this.cache.get(a);o||(o=new Ge,X.prototype.copy.call(o,s),o.color.copy(s.color),o.map=s.map,o.sizeAttenuation=!1,this.cache.add(a,o)),s=o}else if(n.isLine){const a="LineBasicMaterial:"+s.uuid;let o=this.cache.get(a);o||(o=new Ue,X.prototype.copy.call(o,s),o.color.copy(s.color),o.map=s.map,this.cache.add(a,o)),s=o}if(t||i||r){let a="ClonedMaterial:"+s.uuid+":";t&&(a+="derivative-tangents:"),i&&(a+="vertex-colors:"),r&&(a+="flat-shading:");let o=this.cache.get(a);o||(o=s.clone(),i&&(o.vertexColors=!0),r&&(o.flatShading=!0),t&&(o.normalScale&&(o.normalScale.y*=-1),o.clearcoatNormalScale&&(o.clearcoatNormalScale.y*=-1)),this.cache.add(a,o),this.associations.set(o,this.associations.get(s))),s=o}n.material=s}getMaterialType(){return Ee}loadMaterial(n){const e=this,s=this.json,t=this.extensions,i=s.materials[n];let r;const a={},o=i.extensions||{},c=[];if(o[g.KHR_MATERIALS_UNLIT]){const l=t[g.KHR_MATERIALS_UNLIT];r=l.getMaterialType(),c.push(l.extendParams(a,i,e))}else{const l=i.pbrMetallicRoughness||{};if(a.color=new F(1,1,1),a.opacity=1,Array.isArray(l.baseColorFactor)){const h=l.baseColorFactor;a.color.setRGB(h[0],h[1],h[2],b),a.opacity=h[3]}l.baseColorTexture!==void 0&&c.push(e.assignTexture(a,"map",l.baseColorTexture,U)),a.metalness=l.metallicFactor!==void 0?l.metallicFactor:1,a.roughness=l.roughnessFactor!==void 0?l.roughnessFactor:1,l.metallicRoughnessTexture!==void 0&&(c.push(e.assignTexture(a,"metalnessMap",l.metallicRoughnessTexture)),c.push(e.assignTexture(a,"roughnessMap",l.metallicRoughnessTexture))),r=this._invokeOne(function(h){return h.getMaterialType&&h.getMaterialType(n)}),c.push(Promise.all(this._invokeAll(function(h){return h.extendMaterialParams&&h.extendMaterialParams(n,a)})))}i.doubleSided===!0&&(a.side=Be);const u=i.alphaMode||W.OPAQUE;if(u===W.BLEND?(a.transparent=!0,a.depthWrite=!1):(a.transparent=!1,u===W.MASK&&(a.alphaTest=i.alphaCutoff!==void 0?i.alphaCutoff:.5)),i.normalTexture!==void 0&&r!==v&&(c.push(e.assignTexture(a,"normalMap",i.normalTexture)),a.normalScale=new pe(1,1),i.normalTexture.scale!==void 0)){const l=i.normalTexture.scale;a.normalScale.set(l,l)}if(i.occlusionTexture!==void 0&&r!==v&&(c.push(e.assignTexture(a,"aoMap",i.occlusionTexture)),i.occlusionTexture.strength!==void 0&&(a.aoMapIntensity=i.occlusionTexture.strength)),i.emissiveFactor!==void 0&&r!==v){const l=i.emissiveFactor;a.emissive=new F().setRGB(l[0],l[1],l[2],b)}return i.emissiveTexture!==void 0&&r!==v&&c.push(e.assignTexture(a,"emissiveMap",i.emissiveTexture,U)),Promise.all(c).then(function(){const l=new r(a);return i.name&&(l.name=i.name),y(l,i),e.associations.set(l,{materials:n}),i.extensions&&O(t,l,i),l})}createUniqueName(n){const e=Ke.sanitizeNodeName(n||"");return e in this.nodeNamesUsed?e+"_"+ ++this.nodeNamesUsed[e]:(this.nodeNamesUsed[e]=0,e)}loadGeometries(n){const e=this,s=this.extensions,t=this.primitiveCache;function i(a){return s[g.KHR_DRACO_MESH_COMPRESSION].decodePrimitive(a,e).then(function(o){return fe(o,a,e)})}const r=[];for(let a=0,o=n.length;a<o;a++){const c=n[a],u=vn(c),l=t[u];if(l)r.push(l.promise);else{let h;c.extensions&&c.extensions[g.KHR_DRACO_MESH_COMPRESSION]?h=i(c):h=fe(new je,c,e),t[u]={primitive:c,promise:h},r.push(h)}}return Promise.all(r)}loadMesh(n){const e=this,s=this.json,t=this.extensions,i=s.meshes[n],r=i.primitives,a=[];for(let o=0,c=r.length;o<c;o++){const u=r[o].material===void 0?kn(this.cache):this.getDependency("material",r[o].material);a.push(u)}return a.push(e.loadGeometries(r)),Promise.all(a).then(function(o){const c=o.slice(0,o.length-1),u=o[o.length-1],l=[];for(let d=0,p=u.length;d<p;d++){const R=u[d],m=r[d];let T;const A=c[d];if(m.mode===L.TRIANGLES||m.mode===L.TRIANGLE_STRIP||m.mode===L.TRIANGLE_FAN||m.mode===void 0)T=i.isSkinnedMesh===!0?new Ve(R,A):new Xe(R,A),T.isSkinnedMesh===!0&&T.normalizeSkinWeights(),m.mode===L.TRIANGLE_STRIP?T.geometry=oe(T.geometry,he):m.mode===L.TRIANGLE_FAN&&(T.geometry=oe(T.geometry,Q));else if(m.mode===L.LINES)T=new ze(R,A);else if(m.mode===L.LINE_STRIP)T=new qe(R,A);else if(m.mode===L.LINE_LOOP)T=new We(R,A);else if(m.mode===L.POINTS)T=new Ye(R,A);else throw new Error("THREE.GLTFLoader: Primitive mode unsupported: "+m.mode);Object.keys(T.geometry.morphAttributes).length>0&&Dn(T,i),T.name=e.createUniqueName(i.name||"mesh_"+n),y(T,i),m.extensions&&O(t,T,m),e.assignFinalMaterial(T),l.push(T)}for(let d=0,p=l.length;d<p;d++)e.associations.set(l[d],{meshes:n,primitives:d});if(l.length===1)return i.extensions&&O(t,l[0],i),l[0];const h=new z;i.extensions&&O(t,h,i),e.associations.set(h,{meshes:n});for(let d=0,p=l.length;d<p;d++)h.add(l[d]);return h})}loadCamera(n){let e;const s=this.json.cameras[n],t=s[s.type];if(!t){console.warn("THREE.GLTFLoader: Missing camera parameters.");return}return s.type==="perspective"?e=new Qe(Je.radToDeg(t.yfov),t.aspectRatio||1,t.znear||1,t.zfar||2e6):s.type==="orthographic"&&(e=new Ze(-t.xmag,t.xmag,t.ymag,-t.ymag,t.znear,t.zfar)),s.name&&(e.name=this.createUniqueName(s.name)),y(e,s),Promise.resolve(e)}loadSkin(n){const e=this.json.skins[n],s=[];for(let t=0,i=e.joints.length;t<i;t++)s.push(this._loadNodeShallow(e.joints[t]));return e.inverseBindMatrices!==void 0?s.push(this.getDependency("accessor",e.inverseBindMatrices)):s.push(null),Promise.all(s).then(function(t){const i=t.pop(),r=t,a=[],o=[];for(let c=0,u=r.length;c<u;c++){const l=r[c];if(l){a.push(l);const h=new B;i!==null&&h.fromArray(i.array,c*16),o.push(h)}else console.warn('THREE.GLTFLoader: Joint "%s" could not be found.',e.joints[c])}return new $e(a,o)})}loadAnimation(n){const e=this.json,s=this,t=e.animations[n],i=t.name?t.name:"animation_"+n,r=[],a=[],o=[],c=[],u=[];for(let l=0,h=t.channels.length;l<h;l++){const d=t.channels[l],p=t.samplers[d.sampler],R=d.target,m=R.node,T=t.parameters!==void 0?t.parameters[p.input]:p.input,A=t.parameters!==void 0?t.parameters[p.output]:p.output;R.node!==void 0&&(r.push(this.getDependency("node",m)),a.push(this.getDependency("accessor",T)),o.push(this.getDependency("accessor",A)),c.push(p),u.push(R))}return Promise.all([Promise.all(r),Promise.all(a),Promise.all(o),Promise.all(c),Promise.all(u)]).then(function(l){const h=l[0],d=l[1],p=l[2],R=l[3],m=l[4],T=[];for(let x=0,E=h.length;x<E;x++){const M=h[x],N=d[x],S=p[x],H=R[x],P=m[x];if(M===void 0)continue;M.updateMatrix&&M.updateMatrix();const K=s._createAnimationTracks(M,N,S,H,P);if(K)for(let j=0;j<K.length;j++)T.push(K[j])}const A=new en(i,void 0,T);return y(A,t),A})}createNodeMesh(n){const e=this.json,s=this,t=e.nodes[n];return t.mesh===void 0?null:s.getDependency("mesh",t.mesh).then(function(i){const r=s._getNodeRef(s.meshCache,t.mesh,i);return t.weights!==void 0&&r.traverse(function(a){if(a.isMesh)for(let o=0,c=t.weights.length;o<c;o++)a.morphTargetInfluences[o]=t.weights[o]}),r})}loadNode(n){const e=this.json,s=this,t=e.nodes[n],i=s._loadNodeShallow(n),r=[],a=t.children||[];for(let c=0,u=a.length;c<u;c++)r.push(s.getDependency("node",a[c]));const o=t.skin===void 0?Promise.resolve(null):s.getDependency("skin",t.skin);return Promise.all([i,Promise.all(r),o]).then(function(c){const u=c[0],l=c[1],h=c[2];h!==null&&u.traverse(function(d){d.isSkinnedMesh&&d.bind(h,Un)});for(let d=0,p=l.length;d<p;d++)u.add(l[d]);if(u.userData.pivot!==void 0&&l.length>0){const d=u.userData.pivot,p=l[0];u.pivot=new C().fromArray(d),u.position.x-=d[0],u.position.y-=d[1],u.position.z-=d[2],p.position.set(0,0,0),delete u.userData.pivot}return u})}_loadNodeShallow(n){const e=this.json,s=this.extensions,t=this;if(this.nodeCache[n]!==void 0)return this.nodeCache[n];const i=e.nodes[n],r=i.name?t.createUniqueName(i.name):"",a=[],o=t._invokeOne(function(c){return c.createNodeMesh&&c.createNodeMesh(n)});return o&&a.push(o),i.camera!==void 0&&a.push(t.getDependency("camera",i.camera).then(function(c){return t._getNodeRef(t.cameraCache,i.camera,c)})),t._invokeAll(function(c){return c.createNodeAttachment&&c.createNodeAttachment(n)}).forEach(function(c){a.push(c)}),this.nodeCache[n]=Promise.all(a).then(function(c){let u;if(i.isBone===!0?u=new nn:c.length>1?u=new z:c.length===1?u=c[0]:u=new ge,u!==c[0])for(let l=0,h=c.length;l<h;l++)u.add(c[l]);if(i.name&&(u.userData.name=i.name,u.name=r),y(u,i),i.extensions&&O(s,u,i),i.matrix!==void 0){const l=new B;l.fromArray(i.matrix),u.applyMatrix4(l)}else i.translation!==void 0&&u.position.fromArray(i.translation),i.rotation!==void 0&&u.quaternion.fromArray(i.rotation),i.scale!==void 0&&u.scale.fromArray(i.scale);if(!t.associations.has(u))t.associations.set(u,{});else if(i.mesh!==void 0&&t.meshCache.refs[i.mesh]>1){const l=t.associations.get(u);t.associations.set(u,{...l})}return t.associations.get(u).nodes=n,u}),this.nodeCache[n]}loadScene(n){const e=this.extensions,s=this.json.scenes[n],t=this,i=new z;s.name&&(i.name=t.createUniqueName(s.name)),y(i,s),s.extensions&&O(e,i,s);const r=s.nodes||[],a=[];for(let o=0,c=r.length;o<c;o++)a.push(t.getDependency("node",r[o]));return Promise.all(a).then(function(o){for(let u=0,l=o.length;u<l;u++){const h=o[u];h.parent!==null?i.add(un(h)):i.add(h)}const c=u=>{const l=new Map;for(const[h,d]of t.associations)(h instanceof X||h instanceof ne)&&l.set(h,d);return u.traverse(h=>{const d=t.associations.get(h);d!=null&&l.set(h,d)}),l};return t.associations=c(i),i})}_createAnimationTracks(n,e,s,t,i){const r=[],a=n.name?n.name:n.uuid,o=[];function c(d){d.morphTargetInfluences&&o.push(d.name?d.name:d.uuid)}I[i.path]===I.weights?(c(n),n.isGroup&&n.children.forEach(c)):o.push(a);let u;switch(I[i.path]){case I.weights:u=se;break;case I.rotation:u=ie;break;case I.translation:case I.scale:u=te;break;default:switch(s.itemSize){case 1:u=se;break;case 2:case 3:default:u=te;break}break}const l=t.interpolation!==void 0?Pn[t.interpolation]:xe,h=this._getArrayFromAccessor(s);for(let d=0,p=o.length;d<p;d++){const R=new u(o[d]+"."+I[i.path],e.array,h,l);t.interpolation==="CUBICSPLINE"&&this._createCubicSplineTrackInterpolant(R),r.push(R)}return r}_getArrayFromAccessor(n){let e=n.array;if(n.normalized){const s=ee(e.constructor),t=new Float32Array(e.length);for(let i=0,r=e.length;i<r;i++)t[i]=e[i]*s;e=t}return e}_createCubicSplineTrackInterpolant(n){n.createInterpolant=function(s){const t=this instanceof ie?Fn:Me;return new t(this.times,this.values,this.getValueSize()/3,s)},n.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline=!0}}function Kn(f,n,e){const s=n.attributes,t=new an;if(s.POSITION!==void 0){const a=e.json.accessors[s.POSITION],o=a.min,c=a.max;if(o!==void 0&&c!==void 0){if(t.set(new C(o[0],o[1],o[2]),new C(c[0],c[1],c[2])),a.normalized){const u=ee(k[a.componentType]);t.min.multiplyScalar(u),t.max.multiplyScalar(u)}}else{console.warn("THREE.GLTFLoader: Missing min/max properties for accessor POSITION.");return}}else return;const i=n.targets;if(i!==void 0){const a=new C,o=new C;for(let c=0,u=i.length;c<u;c++){const l=i[c];if(l.POSITION!==void 0){const h=e.json.accessors[l.POSITION],d=h.min,p=h.max;if(d!==void 0&&p!==void 0){if(o.setX(Math.max(Math.abs(d[0]),Math.abs(p[0]))),o.setY(Math.max(Math.abs(d[1]),Math.abs(p[1]))),o.setZ(Math.max(Math.abs(d[2]),Math.abs(p[2]))),h.normalized){const R=ee(k[h.componentType]);o.multiplyScalar(R)}a.max(o)}else console.warn("THREE.GLTFLoader: Missing min/max properties for accessor POSITION.")}}t.expandByVector(a)}f.boundingBox=t;const r=new cn;t.getCenter(r.center),r.radius=t.min.distanceTo(t.max)/2,f.boundingSphere=r}function fe(f,n,e){const s=n.attributes,t=[];function i(r,a){return e.getDependency("accessor",r).then(function(o){f.setAttribute(a,o)})}for(const r in s){const a=$[r]||r.toLowerCase();a in f.attributes||t.push(i(s[r],a))}if(n.indices!==void 0&&!f.index){const r=e.getDependency("accessor",n.indices).then(function(a){f.setIndex(a)});t.push(r)}return re.workingColorSpace!==b&&"COLOR_0"in s&&console.warn(`THREE.GLTFLoader: Converting vertex colors from "srgb-linear" to "${re.workingColorSpace}" not supported.`),y(f,n),Kn(f,n,e),Promise.all(t).then(function(){return n.targets!==void 0?Hn(f,n.targets,e):f})}export{Vn as GLTFLoader};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const e={type:"number"},t={type:"string",doc:'Which account this is, unique across every recording anywhere: the day it happened, then who saw it ("1964-04-24-ZamoraLonnie"), or where for an anonymous observer.'},o={type:"object",fields:{year:{type:"number"},month:{type:"number"},day:{type:"number"},hour:{type:"number"},minute:{type:"number"},second:{type:"number"},season:{type:"enum",doc:'The season, when the date is only known to be "in the spring of 2022" (EDTF `2022-21`): then `month` and `day` are undefined.',values:["spring","summer","autumn","winter"]},raw:{type:"string",doc:"The exact EDTF-ish text as typed in the editor UI (e.g."}}},r={type:"object",doc:"See SightingEvent.endTime.",fields:{year:{type:"number"},month:{type:"number"},day:{type:"number"},hour:{type:"number"},minute:{type:"number"},second:{type:"number"},season:{type:"enum",doc:'The season, when the date is only known to be "in the spring of 2022" (EDTF `2022-21`): then `month` and `day` are undefined.',values:["spring","summer","autumn","winter"]},raw:{type:"string",doc:"The exact EDTF-ish text as typed in the editor UI (e.g."}}},n={type:"number",doc:"See SightingEvent.durationSeconds."},i={type:"string",doc:"See SightingEvent.durationText."},s={type:"number",doc:"See SightingEvent.utcOffsetHours — the legal time zone `time`/`endTime` are expressed in."},a={type:"string",doc:"See SightingEvent.timeZone — the IANA rule `utcOffsetHours` was derived from, when it was."},d={type:"array",fields:{lat:{type:"number"},lng:{type:"number"},name:{type:"string",doc:'The place as it is named, fully qualified — "Valensole, Alpes-de-Haute-Provence, …, France".'}}},c={type:"object",doc:"See Sighting.observer.",fields:{id:{type:"string",doc:'Who this is, as a reference: last name then first names, run together ("ZamoraLonnie"), whether or not a page exists for them yet.'},title:{type:"string"},lastName:{type:"string"},firstNames:{type:"array"}}},h={type:"object",doc:"Who saw it and how their account travelled — see Account, and Sighting.account.",fields:{observerAgeYears:{type:"number",doc:"The main observer's age in years AT THE TIME, not today — a 1974 account is read by whoever finds it decades later, and the number that means anything is the one from then."},observerOccupation:{type:"string",doc:'What the main observer did, as they are described: "boulanger", "pilote de ligne", "gendarme".',loose:!0},source:{type:"enum",doc:"How the account reached the person who wrote this recording.",values:["on-site","interview","telephone","questionnaire","letter","social-media","press"]},followedUp:{type:"boolean",doc:"Whether the observer was gone back to after the first account."}}},l={type:"number",doc:"How much the observer's body sways the view at rest: 1 a person, 0 a tripod — see Sighting.sway."},u={type:"object",doc:"The vehicle the observer was in, when the decor does not draw it — see Sighting.vehicle.",fields:{kind:{type:"enum",values:["car","van","truck","motorcycle","generic"]},windowsOpen:{type:"boolean",doc:"Whether the windows were open: the road and the wind come in, the cabin no longer muffles the engine."},noise:{type:"number",doc:'How loud it was, against an ordinary one of its kind: 1 by default, 1.5 for "very noisy".'}}},p={type:"string",doc:"See SightingEvent.description — a plain string, or one per language.",loose:!0},y={type:"array",doc:"See SightingEvent.tags."},m={type:"object",fields:{keyframes:{type:"array",fields:{t:{type:"number"},shapes:{type:"array",fields:{sourceId:{type:"string"},shape:{type:"object",fields:{kind:{type:"enum",values:["oval","polygon"]},bounds:{type:"object",fields:{x:{type:"number"},y:{type:"number"},width:{type:"number"},height:{type:"number"}}},color:{type:"string",doc:"CSS color"},angle:{type:"number",doc:"Rotation in radians about the shape's centre, positive = clockwise on screen; 0 = no rotation"},transparency:{type:"number",doc:"0 = opaque, 1 = fully transparent"},haloScale:{type:"number",doc:"0 = no halo/glow, >1 = larger glow radius"},blur:{type:"number",doc:"How indistinct the observer said its edges were — 0 for a hard outline, 1 for a shape with no edge at all."},brightness:{type:"number",doc:"How dazzling the observer said it was — 0 for a light you can look at, 1 for one you cannot."},selected:{type:"boolean"},title:{type:"string",doc:"What the observer calls it, if anything.",loose:!0},angular:{type:"object",doc:"How big this looked to the observer, in degrees of arc (see AngularExtent) — the recording's OWN statement of size, and the one it is allowed to make.",fields:{widthDeg:{type:"number",doc:"How wide it looked, in degrees of arc."},heightDeg:{type:"number",doc:"How tall it looked, in degrees of arc."}}},aim:{type:"object",doc:"Where the phenomenon itself was in the observer's sky (the direction of the shape's centre, not the way the observer was facing) — degrees of azimuth from true north and of altitude above the horizon, the same conventions as ObserverPose.",fields:{azimuthDeg:{type:"number",doc:"Degrees clockwise from true north, the same convention as ObserverPose.headingDeg."},altitudeDeg:{type:"number",doc:"Degrees above (positive) or below the horizon."}}},points:{type:"array",doc:"Points relative to bounds origin (0,0 = bounds.x, bounds.y)",fields:{x:{type:"number"},y:{type:"number"}}}}}}}}},order:{type:"array",doc:"Back-to-front paint/hit-test order — see Timeline's own `order` field."},groups:{type:"array",doc:"Each inner array is one group's member sourceIds (always >= 2 members) — see Timeline's own `groups` field."}}},g={type:"object",doc:"The observer's position/elevation/orientation over time — absent for older recordings, which fall back to the legacy static place[0] (see Sighting.ts's resolveObserverPoseAt).",fields:{keyframes:{type:"array",fields:{t:{type:"number"},pose:{type:"object",fields:{lat:{type:"number",doc:"Decimal degrees."},lng:{type:"number"},elevationM:{type:"number",doc:"Metres above the local ground under the observer, not above sea level: 0 for someone standing on it, the height of a window or a cliff top otherwise."},headingDeg:{type:"number",doc:"Degrees clockwise from true north."},pitchDeg:{type:"number",doc:"Degrees above (positive) or below (negative) the local horizontal — how far up/down the observer was looking, e.g."},rollDeg:{type:"number",doc:"How far the instrument itself was tilted about its own line of sight, degrees, positive clockwise as the observer saw it — a camera held askew, a head leaned over."},fovDeg:{type:"number",doc:"Vertical field of view in degrees, as a Three.js PerspectiveCamera would take it."},fNumber:{type:"number",doc:"How far the lens was stopped down — undefined for anything the recording did not state, which then falls back to the instrument's own setting (see Instrument.fNumber)."},focusDistanceM:{type:"number",doc:"How far away the lens was focused, metres — undefined meaning at infinity, which is where a camera pointed at the sky sits and the only setting under which everything celestial comes out sharp."},filter:{type:"string",doc:"What was held in front of the instrument — a FILTERS id, a solar filter for an eclipse."}}}}}}},b={type:"object",doc:"Weather over time — absent for older recordings, which fall back to the legacy static `weather` field below (see Sighting.ts's resolveWeatherAt).",fields:{keyframes:{type:"array",fields:{t:{type:"number"},weather:{type:"object",fields:{cloudLayers:{type:"array",doc:"Explicit layers override the historical cloud fields; [] means no clouds.",fields:{id:{type:"string",doc:"Stable across keyframes: reordering layers must not regenerate their cloud pattern."},instances:{type:"array",doc:"Optional explicit masses, independent of the generated coverage percentage.",fields:{id:{type:"string"},eastM:{type:"number",doc:"Position relative to the recording's initial observer, in metres east/north."},northM:{type:"number"},baseM:{type:"number"},thicknessM:{type:"number"},widthM:{type:"number"},depthM:{type:"number"},rotationDeg:{type:"number"},density:{type:"number"},darkness:{type:"number",doc:"Visual shading, 0 (white) to 1 (very dark); absent inherits the parent layer."},seed:{type:"number"}}},type:{type:"enum",values:["cumulus","stratus","stratocumulus","cirrus","unknown"]},baseM:{type:"number",doc:"Base in metres above the recording's reference ground, not above the moving observer."},thicknessM:{type:"number",doc:"Vertical extent in metres."},coverage:{type:"number",doc:"Horizontal coverage, 0–1."},sizeM:{type:"number",doc:"Characteristic horizontal cloud size in metres."},density:{type:"number",doc:"Relative optical density, 0–2; zero is transparent."},darkness:{type:"number",doc:"Visual shading, 0 (white) to 1 (very dark)."},iceCrystalAlignment:{type:"number",doc:"Degree of preferential crystal orientation, meaningful only for cirrus."},seed:{type:"number",doc:"Reproducible variation; defaults to a hash of the stable layer id."},windDirectionDeg:{type:"number",doc:"Optional wind overrides; bearing TOWARD which the cloud travels, clockwise from north."},windSpeed:{type:"number"}}},cloudCover:{type:"number",doc:"0 = clear sky, 1 = fully overcast."},cloudDarkness:{type:"number",doc:"0 = light/clear clouds, 1 = dark/stormy character."},cloudBaseM:{type:"number",doc:"Height of the cloud layer's BASE above the ground, in meters — 600 to 2000 m covers most real low cloud."},highCloudCover:{type:"number",doc:"How much of the sky the HIGH deck covered, 0 to 1 — cirrus and cirrostratus, above about six kilometres, where anything present is ice rather than water."},lowerCloudCover:{type:"number",doc:"How much of the sky the LOW and MIDDLE decks covered, 0 to 1 — the cloud that stands between a observer and anything higher up."},iceCrystalAlignment:{type:"number",doc:"How steadily the ice crystals were falling, 0 to 1 — the one thing about the sky that decides which halo forms stood, and the one thing no record of any sighting holds."},relativeHumidity:{type:"number",doc:"Relative humidity near the ground, 0 to 1."},precipitationType:{type:"enum",values:["none","rain","snow","hail"]},precipitationIntensity:{type:"number",doc:'0-1; meaningless while precipitationType is "none".'},precipitationAmount:{type:"number",doc:"How much of that precipitation is actually falling yet, 0 to 1 — absent meaning all of it."},windDirectionDeg:{type:"number",doc:"Degrees clockwise from true north — same convention as ObserverPose.headingDeg, and the direction the wind blows *toward*, not the one it comes from: SceneRenderer drifts every precipitation particle and cloud field along exactly this bearing (`sin/-cos`, north = -Z), so 0 means snow drifting northward."},windSpeed:{type:"number",doc:"Real-world wind speed in m/s (0 = calm, ~30 = violent storm/hurricane-force) — drives both cloud advection, visual precipitation drift and wind audio volume directly."},storm:{type:"boolean",doc:"Whether a thunderstorm was reported — drives both a scene-fog lightning flash and a delayed thunderclap (see SceneRenderer's lightning-flash scheduling, named for the visual mechanism it implements internally, not for this field)."}}}}}}},f={type:"object",doc:`Legacy static weather condition, kept only as weatherTrack's own fallback for recordings made before it existed — absent means "unknown/not recorded", not "clear skies" (renderers default to DEFAULT_WEATHER, see Weather.ts).`,fields:{cloudLayers:{type:"array",doc:"Explicit layers override the historical cloud fields; [] means no clouds.",fields:{id:{type:"string",doc:"Stable across keyframes: reordering layers must not regenerate their cloud pattern."},instances:{type:"array",doc:"Optional explicit masses, independent of the generated coverage percentage.",fields:{id:{type:"string"},eastM:{type:"number",doc:"Position relative to the recording's initial observer, in metres east/north."},northM:{type:"number"},baseM:{type:"number"},thicknessM:{type:"number"},widthM:{type:"number"},depthM:{type:"number"},rotationDeg:{type:"number"},density:{type:"number"},darkness:{type:"number",doc:"Visual shading, 0 (white) to 1 (very dark); absent inherits the parent layer."},seed:{type:"number"}}},type:{type:"enum",values:["cumulus","stratus","stratocumulus","cirrus","unknown"]},baseM:{type:"number",doc:"Base in metres above the recording's reference ground, not above the moving observer."},thicknessM:{type:"number",doc:"Vertical extent in metres."},coverage:{type:"number",doc:"Horizontal coverage, 0–1."},sizeM:{type:"number",doc:"Characteristic horizontal cloud size in metres."},density:{type:"number",doc:"Relative optical density, 0–2; zero is transparent."},darkness:{type:"number",doc:"Visual shading, 0 (white) to 1 (very dark)."},iceCrystalAlignment:{type:"number",doc:"Degree of preferential crystal orientation, meaningful only for cirrus."},seed:{type:"number",doc:"Reproducible variation; defaults to a hash of the stable layer id."},windDirectionDeg:{type:"number",doc:"Optional wind overrides; bearing TOWARD which the cloud travels, clockwise from north."},windSpeed:{type:"number"}}},cloudCover:{type:"number",doc:"0 = clear sky, 1 = fully overcast."},cloudDarkness:{type:"number",doc:"0 = light/clear clouds, 1 = dark/stormy character."},cloudBaseM:{type:"number",doc:"Height of the cloud layer's BASE above the ground, in meters — 600 to 2000 m covers most real low cloud."},highCloudCover:{type:"number",doc:"How much of the sky the HIGH deck covered, 0 to 1 — cirrus and cirrostratus, above about six kilometres, where anything present is ice rather than water."},lowerCloudCover:{type:"number",doc:"How much of the sky the LOW and MIDDLE decks covered, 0 to 1 — the cloud that stands between a observer and anything higher up."},iceCrystalAlignment:{type:"number",doc:"How steadily the ice crystals were falling, 0 to 1 — the one thing about the sky that decides which halo forms stood, and the one thing no record of any sighting holds."},relativeHumidity:{type:"number",doc:"Relative humidity near the ground, 0 to 1."},precipitationType:{type:"enum",values:["none","rain","snow","hail"]},precipitationIntensity:{type:"number",doc:'0-1; meaningless while precipitationType is "none".'},precipitationAmount:{type:"number",doc:"How much of that precipitation is actually falling yet, 0 to 1 — absent meaning all of it."},windDirectionDeg:{type:"number",doc:"Degrees clockwise from true north — same convention as ObserverPose.headingDeg, and the direction the wind blows *toward*, not the one it comes from: SceneRenderer drifts every precipitation particle and cloud field along exactly this bearing (`sin/-cos`, north = -Z), so 0 means snow drifting northward."},windSpeed:{type:"number",doc:"Real-world wind speed in m/s (0 = calm, ~30 = violent storm/hurricane-force) — drives both cloud advection, visual precipitation drift and wind audio volume directly."},storm:{type:"boolean",doc:"Whether a thunderstorm was reported — drives both a scene-fog lightning flash and a delayed thunderclap (see SceneRenderer's lightning-flash scheduling, named for the visual mechanism it implements internally, not for this field)."}}},w={type:"object",doc:"What the sighting sounded like over time — see SoundTrack.",fields:{keyframes:{type:"array",fields:{t:{type:"number"},sound:{type:"object",fields:{kind:{type:"enum",values:["none","hum","whistle","rumble","crackle"]},volume:{type:"number",doc:"How loud it was, 0 (inaudible) to 1 (as loud as the observer could describe) — deliberately relative rather than a dB SPL figure: nobody reports a sound level in decibels, and inventing one would claim a measurement where there is only an impression."},pitchHz:{type:"number",doc:`The sound's own frequency in Hz — the oscillator's pitch for the pitched kinds ("hum", "whistle"), and the noise filter's centre for the unpitched ones ("rumble", "crackle"), where it reads as how deep or how sharp the noise is.`},src:{type:"string",doc:"An actual audio recording of the sound, when one exists (a observer who filmed the event, a later recording of the same phenomenon) — replaces synthesis entirely while it is set, with `volume` still scaling it."}}}}}}},v={type:"array",doc:"See Sighting.decor.",fields:{id:{type:"string"},kind:{type:"enum",values:["terrace","building","tree","crop","mound","streetlight","vehicle","observer","aircraft","shrub","bridge","wire","entity"]},title:{type:"string",doc:'Optional display name, same role as Shape.title — falls back to a generic "{kind} {n}" label (see SightingEditorElement.decorLabel) when absent.',loose:!0},eastM:{type:"number",doc:"Meters from the observer's own position — eastM positive = east, northM positive = north."},northM:{type:"number"},headingDeg:{type:"number",doc:"Degrees clockwise from true north, same convention as ObserverPose.headingDeg — which way a vehicle is facing, or a observer looking."},lit:{type:"boolean",doc:"Streetlight lamp / vehicle headlights switched on."},litKeyframes:{type:"array",doc:"Sorted by t.",fields:{t:{type:"number"},lit:{type:"boolean"}}},lights:{type:"array",doc:"The object's individual lamps, each with its own place on the body and its own rhythm — see DecorLight, and LIGHT_RIGS for the ready-made sets.",fields:{id:{type:"string"},offsetM:{type:"object",doc:"Where it sits on the object, in meters relative to the object's own centre and heading: +x is its right, +y up, +z its front.",fields:{x:{type:"number"},y:{type:"number"},z:{type:"number"}}},color:{type:"string",doc:"CSS hex colour, as emitted — the regulated red/green/white of navigation lights, the amber of a hazard flasher."},intensity:{type:"number",doc:"Peak luminous intensity as a ratio to an ordinary navigation light's (1, about a hundred candela — see DecorSystem's LAMP_CANDELA); the airliner rig (LIGHT_RIGS) gives its beacon 1.5 and its wingtip strobes 20."},pattern:{type:"object",fields:{kind:{type:"enum",values:["steady","flash"]},perMinute:{type:"number"},dutyCycle:{type:"number"},phase:{type:"number"}}}}},track:{type:"array",doc:"Where the object is over time, when it moves — an aircraft crossing the sky, a car driving past.",fields:{t:{type:"number"},eastM:{type:"number"},northM:{type:"number"},altitudeM:{type:"number",doc:"Meters above the observer's own elevation."},headingDeg:{type:"number"}}},sightingUrl:{type:"string",doc:`For kind "observer" only: the URL of that observer's own sighting.json recording, if known — lets the 3D scene's own context menu offer "view this observer's account" (loading it the same way SightingEditorElement.importFromUrl already does).`},windows:{type:"object",doc:"Per-side window opacity, 0 (fully open — the pane is invisible, and DecorSystem.addRoom's own interior wall panel is skipped there too, same as no window at all) to 100 (fully closed — a solid-looking pane)."},color:{type:"string",doc:'What colour this object actually is, as a CSS colour — the same way a shape states its own (see Shape.color), because a recording is written and read by people and "#8f86a8" is a colour a person can type.'},observerSide:{type:"enum",values:["front","behind","left","right","front-left","front-right","behind-left","behind-right"]},observerFacing:{type:"enum",doc:'Which window the observer looks through, when it is not the one at their own seat: a driver sits at "front-left" and looks through the windshield ("front").',values:["front","behind","left","right","front-left","front-right","behind-left","behind-right"]},observerKeyframes:{type:"array",doc:"Where the observer sits over time, when they do not stay where they are: a driver is in the car until the moment they get out of it.",fields:{t:{type:"number"},side:{type:"enum",doc:"The seat they are in from this instant; absent means they are outside the object.",values:["front","behind","left","right","front-left","front-right","behind-left","behind-right"]},facing:{type:"enum",doc:"The window they look through from this instant, when it is not the one at their seat.",values:["front","behind","left","right","front-left","front-right","behind-left","behind-right"]}}},engine:{type:"object",doc:"A vehicle heard running — see DecorEngine: its engine turning with its own `track`, heard less the further it is from the observer.",fields:{kind:{type:"enum",doc:'Which sound: a decor object\'s own `kind` says only "vehicle".',values:["car","van","truck","motorcycle","generic"]},noise:{type:"number",doc:"As ObserverVehicle.noise."}}},bridge:{type:"object",doc:'Kind "bridge" only: how it is built, where that is known — see BridgeStructure.',fields:{spanM:{type:"number",doc:"Metres of open span under the deck, centred on the object."},deckThicknessM:{type:"number",doc:"Thickness of the deck slab, metres."},railing:{type:"object",doc:"The railing along both edges: its height above the road, the spacing of its posts, and how many horizontal rails it has — two rails make two rows of rectangular openings.",fields:{heightM:{type:"number"},postSpacingM:{type:"number"},rails:{type:"number"}}}}},wire:{type:"object",doc:'Kind "wire" only: how many strands, where they hang, and which ends stand on a pole — see WireStructure.',fields:{strands:{type:"array",doc:"The strands: each one's height above the ground and, for a crossarm, how far it hangs to one side of the line (positive to the right of its heading).",fields:{heightM:{type:"number"},acrossM:{type:"number"}}},poles:{type:"enum",doc:"Which ends stand on a pole: both (default), the one the object's heading points away from (`start`) or towards (`end`), or none, for a line anchored on buildings at both ends.",values:["none","both","start","end"]},diameterM:{type:"number",doc:"How thick a strand is, metres."},poleHeightM:{type:"number",doc:"How tall a pole is, metres."}}},floors:{type:"number",doc:'Kind "building" only: number of upper stories above the ground floor, set when the building is created (default 2, see SightingEditorElement.addDecor) and editable afterward.'},occupiedFloor:{type:"number",doc:'Kind "building" only, meaningful once observerSide is set: which floor the observer is on, 0 (ground floor) up to floors.'},occludesSourceIds:{type:"array",doc:"Shape sourceIds (see Timeline.sourceIds/Shape) this decor object sits in front of, from the observer's own reported viewpoint — occluding that shape wherever their screen positions line up (see SceneRenderer.isScreenPointOccluded)."},sizeM:{type:"object",doc:"How big it really is, in meters, along its own axes — see DecorSize.",fields:{widthM:{type:"number"},lengthM:{type:"number"},heightM:{type:"number"}}},model:{type:"object",doc:"The real 3D model that stands in for the primitive, if one does — see DecorModelRef.",fields:{id:{type:"string",doc:"Catalogue entry, resolved by the live DecorModelProvider."},url:{type:"string",doc:"Direct glTF/GLB address, taking precedence over `id`."},headingOffsetDeg:{type:"number",doc:"Degrees to turn the loaded model about its own vertical axis so its nose points the way this scene's heading convention expects (0 faces -Z — see DecorSystem's build)."},credit:{type:"object",doc:"Who made it and under what licence.",fields:{title:{type:"string"},author:{type:"string"},license:{type:"string",doc:"Licence name as its author states it, e.g."},sourceUrl:{type:"string",doc:"Where it came from, so the claim can be checked."}}}}}}},k={type:"array",doc:"The roads the account's own plan draws — see Sighting.roads and Road.ts.",fields:{id:{type:"string"},title:{type:"string",doc:"What the account calls it, where it calls it anything.",loose:!0},surface:{type:"enum",values:["paved","gravel","dirt"]},widthM:{type:"number",doc:"Carriageway width, metres."},path:{type:"array",doc:"The centre line, in metres east and north of the observer's place at t=0.",fields:{eastM:{type:"number"},northM:{type:"number"}}},source:{type:"string",doc:"Where this line comes from — the plan, the survey, the report it was read off.",loose:!0}}},S={type:"array",doc:"What an investigator drew over the place, imported from their file — see Sighting.traces and Trace.ts.",fields:{id:{type:"string"},title:{type:"string",doc:'What its author called it ("Ligne de visée depuis la ferme").',loose:!0},kind:{type:"enum",values:["polygon","point","line"]},points:{type:"array",doc:"One point for a marker, the vertices of a line, the vertices of an outline (not repeated at the end: it is closed by being a polygon).",fields:{lat:{type:"number"},lng:{type:"number"},altM:{type:"number",doc:"Metres, read as `InvestigatorTrace.altitude` says."}}},altitude:{type:"enum",doc:"How `altM` is read.",values:["ground","relative","absolute"]},color:{type:"string",doc:"CSS colour the author gave it, `#rrggbb`."},source:{type:"string",doc:"Whose it is and where it comes from — the person, the report, the file.",loose:!0}}},D={type:"object",doc:"Which meteorological record `weatherTrack` was looked up from, when it wasn't the observer who stated the conditions — see Sighting.weatherSource.",fields:{id:{type:"string",doc:"Stable dataset id, e.g."},name:{type:"string",doc:"Human-readable dataset name, e.g."},url:{type:"string",doc:"The exact request that produced these values, so the claim stays checkable years later."}}},M={type:"string",doc:"Which INSTRUMENTS entry this was observed through — see Sighting.instrumentId."},T={type:"number",doc:"How long the shutter stayed open, seconds — one value for the whole observation, see Sighting.exposureSeconds."},W={type:"number",doc:"The speed of the film or sensor this picture was taken on — see Sighting.iso."},j={type:"number",doc:`How bright the night sky is at the place, towns and all: the zenith of a moonless night in magnitudes per square arcsecond, a Sky Quality Meter's reading or the World Atlas's "SQM" figure (Falchi et al.`},H={type:"boolean",doc:"Whether the map of where the observer stood starts open — see Sighting.observerMap."},x={type:"array",doc:"The named moments of the account — see Milestone.",fields:{t:{type:"number",doc:"When, in milliseconds from the start of the recording — the same scale every track uses."},label:{type:"string",doc:'Short label, shown on the seek bar: the letter or number the account itself uses ("A", "B"), or a couple of words where it uses none.',loose:!0},note:{type:"string",doc:"What happened at that moment, in the account's own words where possible.",loose:!0}}},I={type:"array",doc:"Pictures of the place, laid over the reconstruction at the direction each was registered in — see SceneReference.",fields:{id:{type:"string",doc:"Stable id, what the editor's own list and a future trace on the picture name."},kind:{type:"enum",values:["photo","panorama"]},src:{type:"string",doc:"Where the picture is: an address, or the picture itself as a `data:` URL."},title:{type:"string",doc:'What to call it — "Vue depuis le muret, fin été 1968".',loose:!0},credit:{type:"string",doc:"Who made it and on what terms — shown wherever the picture is, because a credit that is not displayed is not a licence (see DataSource for the same rule on the data)."},creditUrl:{type:"string",doc:"Where that credit points: the source page, the licence."},t:{type:"number",doc:"The instant of the timeline it was taken at, milliseconds, for a picture made DURING the observation — by the observer, or by whoever was there."},from:{type:"object",doc:"Where it was taken from — the one point its registration holds for.",fields:{lat:{type:"number"},lng:{type:"number"}}},drawing:{type:"boolean",doc:"Whether somebody drew on it — a trajectory, an outline, an arrow — so that what the picture shows of the phenomenon is a statement made afterwards, not a thing the camera recorded."},opacity:{type:"number",doc:"How much of it shows, 0 to 1 — the starting point of the reader's own slider, since the comparison is made by sliding: all picture, all render, and the registration checked at every step between."},registration:{type:"object",fields:{headingDeg:{type:"number",doc:"Degrees clockwise from true north, the direction the picture's centre looks at."},pitchDeg:{type:"number",doc:"Degrees above the local horizontal, positive up."},rollDeg:{type:"number",doc:"Degrees the picture is tilted about its own axis, positive clockwise as it is looked at — see ObserverPose.rollDeg."},fovDeg:{type:"number",doc:"The picture's VERTICAL field, degrees — what the lens took in top to bottom, its horizontal field following from the image's own aspect ratio."}}},landmarks:{type:"array",doc:"The details it was lined up on — see PictureLandmark.",fields:{id:{type:"string"},label:{type:"string",doc:'What the detail is — "Arbre masquant", "barrière".',loose:!0},picture:{type:"object",doc:"Where it is on the picture, 0..1 from the top-left corner.",fields:{u:{type:"number"},v:{type:"number"}}},scene:{type:"object",doc:"Where it is from the observer, in the scene.",fields:{azimuthDeg:{type:"number"},altitudeDeg:{type:"number"}}}}}}},C={type:"array",doc:"Where the account can be read as it was given, each one a source — see RecordingSource.",fields:{type:{type:"enum",values:["book","article"]},title:{type:"string"},authors:{type:"array",doc:"The author(s) name(s): for a post, the account that posted it."},url:{type:"string",doc:"Where it can be read."},publication:{type:"object",doc:"Who published it and when (EDTF).",fields:{publisher:{type:"string"},time:{type:"string"}}},index:{type:"string",doc:"Chapter, page, etc."}}},E={type:"object",doc:"What the observer took it to be, in metres — see InterpretationJson.",fields:{title:{type:"string",doc:'What the claim is, in a few words — "Craft on its legs", "Weather balloon at 3 km".',loose:!0},bodies:{type:"array",fields:{id:{type:"string"},title:{type:"string",loose:!0},explains:{type:"array",doc:"The phenomena of the account (their `sourceId`s) this body claims to be — what its projected outline is measured against at each instant, and what is drawn as a ghost beside it."},model:{type:"object",doc:"What it is shaped like.",fields:{id:{type:"string",doc:"Catalogue entry, resolved by the live DecorModelProvider."},url:{type:"string",doc:"Direct glTF/GLB address, taking precedence over `id`."},headingOffsetDeg:{type:"number",doc:"Degrees to turn the loaded model about its own vertical axis so its nose points the way this scene's heading convention expects (0 faces -Z — see DecorSystem's build)."},credit:{type:"object",doc:"Who made it and under what licence.",fields:{title:{type:"string"},author:{type:"string"},license:{type:"string",doc:"Licence name as its author states it, e.g."},sourceUrl:{type:"string",doc:"Where it came from, so the claim can be checked."}}}}},outlineNode:{type:"string",doc:'The node of the model that IS what the observer drew — "hull" for a craft on legs the observer drew as an oval — and so what its outline is measured by (see BodyConfrontation).'},track:{type:"array",fields:{t:{type:"number"},eastM:{type:"number"},northM:{type:"number"},azimuthDeg:{type:"number"},altitudeDeg:{type:"number"},distanceM:{type:"number"},onGround:{type:"boolean",doc:"Standing on the ground."},present:{type:"boolean",doc:"Gone from here on — `false` — or back — `true`."},altitudeAboveGroundM:{type:"number",doc:"Metres between the ground under it and its lowest point."},altitudeM:{type:"number",doc:"Metres between its lowest point and the ground at the recording's own origin (where the observer stands at the start) — a height in the air that does NOT follow what is under the body."},sizeM:{type:"object",fields:{widthM:{type:"number"},lengthM:{type:"number"},heightM:{type:"number"}}},attitude:{type:"object",fields:{headingDeg:{type:"number"},pitchDeg:{type:"number"},rollDeg:{type:"number"}}},appearance:{type:"object",fields:{color:{type:"string",doc:"Its surface colour, CSS."},albedo:{type:"number",doc:"How much of the light falling on it it sends back, 0-1: aluminium ~0.7, a matt dark hull ~0.1."},luminanceCdM2:{type:"number",doc:"What it gives out of itself, candela per square metre — read through the scene's own photometry exactly as a flame's is (see BodyFlame), so that the same figure is a lamp at night and nothing at all against a noon sky."}}},flame:{type:"object",doc:"A flame coming out of it, from here on — see BodyFlame.",fields:{node:{type:"string"},lengthM:{type:"number",doc:"How far it reaches from the node, metres."},widthM:{type:"number",doc:"How wide it is at its widest, metres."},color:{type:"string",doc:"Its colour where it leaves the node, CSS."},tipColor:{type:"string",doc:"Its colour at its far end; the same as `color` when absent."},luminanceCdM2:{type:"number"},raisesDust:{type:"boolean",doc:"Whether it raises dust where it meets the ground — a flame reaching loose, dry soil does, the more the nearer it gets."}}},motions:{type:"object",doc:"How far along each of its model's own movements it is, by the movement's name in the model (a glTF animation): 0 at its start, 1 at its end, and on past 1 for one that repeats — a turn made three times is 3."},lights:{type:"object",doc:"The luminance of each of its model's own lights, cd/m², by the name of the light's material in the model: what lets one body carry lights that behave each their own way — a steady white at each end, a red one flashing between."}}}}},smoke:{type:"array",doc:"Fires the interpretation lights on the ground, as their smoke — see SmokeSource.",fields:{eastM:{type:"number"},northM:{type:"number"},fromT:{type:"number"},untilT:{type:"number"},halfLifeS:{type:"number",doc:"How fast it dies down, seconds to half its thickness — brush flares and smoulders."}}},reentries:{type:"array",doc:"Re-entries it claims were seen: placed on the Earth, not round the observer — see ReentryJson.",fields:{id:{type:"string"},title:{type:"string",loose:!0},explains:{type:"array",doc:"The phenomena of the account (their `sourceId`s) this re-entry claims to be — see BodyJson.explains."},object:{type:"object",doc:"The object that came down, when it is known — the catalogue says which piece it was.",fields:{name:{type:"string",doc:'Its catalogue name — "SL-12 R/B".'},cosparId:{type:"string",doc:'International designator — "1968-013C".'},norad:{type:"number",doc:"US Space Surveillance Network catalogue number — 3136."}}},track:{type:"array",doc:"Where the leading point of the break-up was, at instants of the recording.",fields:{t:{type:"number"},lat:{type:"number"},lng:{type:"number"},altitudeKm:{type:"number",doc:"Height above the ellipsoid, km."}}},fragments:{type:"array",doc:"The pieces seen, each following the same path some seconds behind the leading point.",fields:{id:{type:"string"},lagS:{type:"number",doc:"Seconds behind the leading point, along the same path."},fromT:{type:"number",doc:"When it is first seen, ms of the recording — when it broke off, or when it began to glow."},untilT:{type:"number",doc:"When it goes out, ms — burned up, or slowed below glowing."},absoluteMagnitude:{type:"number",doc:"Its brightness as a magnitude at 100 km — the meteor astronomers' absolute magnitude, which a fireball report gives — from which the brightness at the observer's actual distance follows."},color:{type:"string",doc:"Its colour, as a CSS hex colour."},trainS:{type:"number",doc:"How long a stretch of its own past path still glows behind it, seconds: the tail observers describe."}}}}}}},z={version:e,id:t,time:o,endTime:r,durationSeconds:n,durationText:i,utcOffsetHours:s,timeZone:a,place:d,observer:c,account:h,sway:l,vehicle:u,description:p,tags:y,timeline:m,observerTrack:g,weatherTrack:b,weather:f,soundTrack:w,decor:v,roads:k,traces:S,weatherSource:D,instrument:M,exposureSeconds:T,iso:W,lightPollution:j,observerMap:H,milestones:x,references:I,sources:C,interpretation:E};export{h as account,v as decor,z as default,p as description,n as durationSeconds,i as durationText,r as endTime,T as exposureSeconds,t as id,M as instrument,E as interpretation,W as iso,j as lightPollution,x as milestones,c as observer,H as observerMap,g as observerTrack,d as place,I as references,k as roads,w as soundTrack,C as sources,l as sway,y as tags,o as time,a as timeZone,m as timeline,S as traces,s as utcOffsetHours,u as vehicle,e as version,f as weather,D as weatherSource,b as weatherTrack};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{A as ot,L as ct,T as j,R as L,a as P}from"./rr0-sighting.mjs";import{C as q}from"./ContrailGrowth-CuAzwIoc.js";class A{static OCTAVES=[63,125,250,500,1e3,2e3,4e3,8e3];static STANDARD={temperatureC:15,relativeHumidity:.7,pressureKPa:101.325};static REFERENCE_PRESSURE_KPA=101.325;static REFERENCE_TEMPERATURE_K=293.15;static TRIPLE_POINT_K=273.16;static speedOfSound(t){return 20.0468*Math.sqrt(t+273.15)}static absorptionDbPerKm(t,e=A.STANDARD){const a=e.temperatureC+273.15,i=A.REFERENCE_TEMPERATURE_K,n=e.pressureKPa/A.REFERENCE_PRESSURE_KPA,r=10**(-6.8346*(A.TRIPLE_POINT_K/a)**1.261+4.6151),s=e.relativeHumidity*100*r/n,o=n*(24+40400*s*(.02+s)/(.391+s)),l=n*(a/i)**-.5*(9+280*s*Math.exp(-4.17*((a/i)**(-1/3)-1))),h=t*t;return 8.686*h*(184e-13*(1/n)*Math.sqrt(a/i)+(a/i)**-2.5*(.01275*Math.exp(-2239.1/a)/(o+h/o)+.1068*Math.exp(-3352/a)/(l+h/l)))*1e3}static aWeightingDb(t){const e=t*t,a=12194**2*e*e/((e+20.6**2)*Math.sqrt((e+107.7**2)*(e+737.9**2))*(e+12194**2));return 20*Math.log10(a)+2}static sumDb(t){return 10*Math.log10(t.reduce((e,a)=>e+10**(a/10),0))}}const lt=.25,Y=.4,$=6,F=12,ht=3,J=.2,ut=.2,dt=24,pt=3,mt=12,Z=1,gt=.7,At=1.5,Et=.8,bt=1.3,x=.9,Q=5,ft=25,Mt=.5,Dt=.12,tt=[.13,.31],St=.16,Rt=1.6,Bt=3.6,et=1.1,vt=.3,Ot=1e3,at=.7;class W{context;noiseBuffer;roughBuffers=new Map;voices=new Map;bus;reverb;reverbOut;level=1;master;paused=!0;requested=[];headingDeg=0;resume(){if(!this.context){if(typeof AudioContext>"u")return;try{this.context=new AudioContext}catch(t){console.warn("AircraftAudio: Web Audio unavailable, aircraft stay silent:",t);return}}ot.unlock(this.context),this.apply()}setLevel(t){this.level=t,this.master&&(this.master.gain.value=t)}setPaused(t){t!==this.paused&&(this.paused=t,this.apply())}setVoices(t,e=0){this.requested=t,this.headingDeg=e,this.apply()}dispose(){for(const t of[...this.voices.keys()])this.release(t);this.context?.close(),this.context=void 0,this.master=void 0,this.bus=void 0}apply(){const t=this.context;if(!t)return;const e=this.paused?[]:this.requested,a=new Set(e.map(i=>i.id));for(const i of[...this.voices.keys()])a.has(i)||this.release(i);for(const i of e){const n=this.voices.get(i.id)??this.build(t,i);this.retarget(t,n,i)}}build(t,e){const a=t.createGain();a.gain.value=0;let i;const n=this.busOf(t);typeof t.createStereoPanner=="function"?(i=t.createStereoPanner(),a.connect(i).connect(n)):a.connect(n);const r=t.createGain(),s=e.character?.modulationDepth??0;r.gain.value=1-s/2;const o=t.createOscillator();o.type="sine";const l=t.createGain();l.gain.value=s/2,o.connect(l).connect(r.gain),r.connect(a);const h=t.createBufferSource();h.buffer=this.noise(t),h.loop=!0,h.loopStart=Math.random()*$*.5;const u=[],d=[],c=[];for(const D of A.OCTAVES){const B=t.createBiquadFilter();B.type="bandpass",B.frequency.value=D,B.Q.value=Z;const C=t.createBiquadFilter();C.type="bandpass",C.frequency.value=D,C.Q.value=Z;const y=t.createGain();y.gain.value=0,h.connect(B).connect(C).connect(y).connect(r),u.push(B),d.push(C),c.push(y)}const p=[];for(const[D,B]of[[e.character?.toneHz,e.character?.toneShare],[e.character?.humHz,e.character?.humShare]])if(D!==void 0)for(let C=1;C<=pt;C++){const y=t.createOscillator();y.type="sine",y.frequency.value=D*C;const z=t.createGain();z.gain.value=0,y.connect(z).connect(a),p.push({oscillator:y,gain:z,harmonic:C,baseHz:D,share:B??0})}const m=t.createGain();m.gain.value=0,m.connect(a.gain);const b=tt.map(D=>{const B=t.createOscillator();return B.type="sine",B.frequency.value=D,B.connect(m),B}),M=t.createGain();M.gain.value=e.character?.roughness??J;const _=t.createBufferSource();_.buffer=this.roughTable(t,ht),_.loop=!0,_.loopStart=Math.random()*F*.5,_.connect(M).connect(r.gain);const T=t.createGain();T.gain.value=(e.character?.roughness??J)*ut;const S=t.createBufferSource();S.buffer=this.roughTable(t,dt),S.loop=!0,S.loopStart=Math.random()*F*.5,S.connect(T).connect(r.gain);let v;const G=this.busOf(t)&&this.reverb;G&&(v=t.createGain(),v.gain.value=0,a.connect(v).connect(G));const K=[h,_,S,o,...p.map(D=>D.oscillator),...b];for(const D of K)D.start();const X={nodes:[a,r,l,M,T,m,...p.map(D=>D.gain),...u,...d,...c,...v?[v]:[],...i?[i]:[],...K],sources:K,filters:u,seconds:d,gains:c,tones:p,lfo:o,lfoDepth:l,wander:b,wanderDepth:m,roughDepth:M,crackleDepth:T,beat:r,output:a,panner:i,send:v};return this.voices.set(e.id,X),X}retarget(t,e,a){const i=t.currentTime,n=(p,m)=>p.setTargetAtTime(m,i,lt),r=Math.min(At,Math.max(gt,a.dopplerRatio)),s=Math.min(bt,Math.max(Et,Math.sqrt(a.dopplerRatio))),o=t.sampleRate*.45,l=a.bandAmplitudes.map((p,m)=>p*W.unweighting(A.OCTAVES[m])),h=Math.sqrt(l.reduce((p,m)=>p+m*m,0)),u=Math.min(1,Math.max(0,(a.distanceKm-Q)/(ft-Q)));A.OCTAVES.forEach((p,m)=>{n(e.filters[m].frequency,Math.min(o,p*s)),n(e.seconds[m].frequency,Math.min(o,p*s)),n(e.gains[m].gain,l[m]*Math.sqrt(Ot/p))});const d=a.character;for(const{oscillator:p,gain:m,harmonic:b,baseHz:M,share:_}of e.tones){const T=M*b;n(p.frequency,T*r);const S=T*r;n(m.gain,S<o?_*St*l[W.bandOf(S)]/b:0)}d?.modulationHz!==void 0&&n(e.lfo.frequency,d.modulationHz*r);const c=h>0?at*(1-Math.exp(-h/at))/h:1;if(n(e.output.gain,c*(1-vt*u)),n(e.wanderDepth.gain,c*Dt*u/tt.length),e.send&&n(e.send.gain,Rt*u),e.panner){const p=(a.azimuthDeg-this.headingDeg)*Math.PI/180;n(e.panner.pan,Math.max(-x,Math.min(x,Math.sin(p)))*(1-Mt*u))}}static unweighting(t){return 10**(Math.min(mt,Math.max(0,-A.aWeightingDb(t)))/20)}static bandOf(t){let e=0;return A.OCTAVES.forEach((a,i)=>{Math.abs(Math.log(t/a))<Math.abs(Math.log(t/A.OCTAVES[e]))&&(e=i)}),e}roughTable(t,e){const a=this.roughBuffers.get(e);if(a)return a;const i=Math.floor(t.sampleRate*F),n=t.createBuffer(1,i,t.sampleRate),r=n.getChannelData(0),s=Array.from({length:F*e},()=>(Math.random()*2-1)**3),o=t.sampleRate/e;for(let l=0;l<r.length;l++){const h=l/o,u=Math.floor(h),d=h-u,c=d*d*(3-2*d);r[l]=s[u%s.length]*(1-c)+s[(u+1)%s.length]*c}return this.roughBuffers.set(e,n),n}roomImpulse(t){const e=Math.floor(t.sampleRate*Bt),a=t.createBuffer(2,e,t.sampleRate);for(let i=0;i<2;i++){const n=a.getChannelData(i);let r=0;for(let s=0;s<e;s++){const o=s/t.sampleRate,l=.6*Math.exp(-o/(et*2))+.04;r+=l*(Math.random()*2-1-r),n[s]=r*Math.exp(-o/et)}}return a}busOf(t){if(this.bus)return this.bus;const e=t.createGain();if(e.gain.value=this.level,e.connect(t.destination),this.master=e,typeof t.createConvolver=="function"){const a=t.createConvolver();a.buffer=this.roomImpulse(t);const i=t.createGain();i.gain.value=.9,a.connect(i),this.reverb=a,this.reverbOut=i}if(typeof t.createDynamicsCompressor=="function"){const a=t.createDynamicsCompressor();a.threshold.value=-6,a.knee.value=3,a.ratio.value=4,a.attack.value=.005,a.release.value=.25,a.connect(e),this.bus=a}else this.bus=e;return this.reverbOut?.connect(this.bus),this.bus}release(t){const e=this.voices.get(t);if(!e)return;this.voices.delete(t);const a=this.context;a&&(e.output.gain.setTargetAtTime(0,a.currentTime,Y/3),setTimeout(()=>{for(const i of e.sources)try{i.stop()}catch{}for(const i of e.nodes)i.disconnect()},Y*1e3*3))}noise(t){if(this.noiseBuffer)return this.noiseBuffer;const e=t.createBuffer(1,t.sampleRate*$,t.sampleRate),a=e.getChannelData(0);for(let i=0;i<a.length;i++)a[i]=Math.random()*2-1;return this.noiseBuffer=e,e}}class O{static BASE_DB_A=30;static WIND_DB_A=[[0,10],[1,28],[2,36],[3,40],[5,46],[8,52],[12,58],[20,66]];static RAIN_DB_A=[[0,0],[.1,42],[.3,50],[.6,58],[1,65]];static BED_RMS=.2;static MINIMUM_REFERENCE=.008;static WIND_BED_MIN_MS=1;static WIND_BED_FULL_MS=20;static dbA(t){const e=[O.BASE_DB_A,O.along(O.WIND_DB_A,t.windSpeed)];return(t.precipitationType==="rain"||t.precipitationType==="hail")&&e.push(O.along(O.RAIN_DB_A,t.precipitationIntensity)),10*Math.log10(e.filter(a=>a>0).reduce((a,i)=>a+10**(i/10),0))}static bedVolume(t){const e=t.windSpeed>O.WIND_BED_MIN_MS?Math.min(t.windSpeed/O.WIND_BED_FULL_MS,1):0,a=t.precipitationType==="hail"?Math.min(1,t.precipitationIntensity*1.3+.2):t.precipitationType==="rain"?t.precipitationIntensity:0;return Math.hypot(e,a)}static referenceAmplitude(t){return Math.max(O.BED_RMS*O.bedVolume(t),O.MINIMUM_REFERENCE)}static along(t,e){if(e<=t[0][0])return t[0][1];for(let a=1;a<t.length;a++)if(e<=t[a][0]){const[i,n]=t[a-1],[r,s]=t[a];return n+(s-n)*(e-i)/(r-i)}return t[t.length-1][1]}}class N{static TYPES={A318:["Airbus A318","airliner-narrow",34.1,31.4],A319:["Airbus A319","airliner-narrow",34.1,33.8],A320:["Airbus A320","airliner-narrow",34.1,37.6],A321:["Airbus A321","airliner-narrow",34.1,44.5],A19N:["Airbus A319neo","airliner-narrow",35.8,33.8],A20N:["Airbus A320neo","airliner-narrow",35.8,37.6],A21N:["Airbus A321neo","airliner-narrow",35.8,44.5],B737:["Boeing 737-700","airliner-narrow",34.3,33.6],B738:["Boeing 737-800","airliner-narrow",35.8,39.5],B739:["Boeing 737-900","airliner-narrow",35.8,42.1],B38M:["Boeing 737 MAX 8","airliner-narrow",35.9,39.5],B39M:["Boeing 737 MAX 9","airliner-narrow",35.9,42.2],B752:["Boeing 757-200","airliner-narrow",38,47.3],B753:["Boeing 757-300","airliner-narrow",38,54.4],B762:["Boeing 767-200","airliner-wide",47.6,48.5],B763:["Boeing 767-300","airliner-wide",47.6,54.9],B764:["Boeing 767-400","airliner-wide",51.9,61.4],B772:["Boeing 777-200","airliner-wide",60.9,63.7],B77L:["Boeing 777-200LR","airliner-wide",64.8,63.7],B77W:["Boeing 777-300ER","airliner-wide",64.8,73.9],B788:["Boeing 787-8","airliner-wide",60.1,56.7],B789:["Boeing 787-9","airliner-wide",60.1,62.8],B78X:["Boeing 787-10","airliner-wide",60.1,68.3],B744:["Boeing 747-400","airliner-wide",64.4,70.7],B748:["Boeing 747-8","airliner-wide",68.4,76.3],A306:["Airbus A300-600","airliner-wide",44.8,54.1],A310:["Airbus A310","airliner-wide",43.9,46.7],A332:["Airbus A330-200","airliner-wide",60.3,58.8],A333:["Airbus A330-300","airliner-wide",60.3,63.7],A338:["Airbus A330-800","airliner-wide",64,58.8],A339:["Airbus A330-900","airliner-wide",64,63.7],A343:["Airbus A340-300","airliner-wide",60.3,63.7],A346:["Airbus A340-600","airliner-wide",63.5,75.4],A359:["Airbus A350-900","airliner-wide",64.8,66.8],A35K:["Airbus A350-1000","airliner-wide",64.8,73.8],A388:["Airbus A380-800","airliner-wide",79.8,72.7],E170:["Embraer 170","regional-jet",26,29.9],E75L:["Embraer 175","regional-jet",26,31.7],E75S:["Embraer 175","regional-jet",26,31.7],E190:["Embraer 190","regional-jet",28.7,36.2],E195:["Embraer 195","regional-jet",28.7,38.7],E290:["Embraer 190-E2","regional-jet",33.7,36.2],E295:["Embraer 195-E2","regional-jet",33.7,41.5],CRJ2:["Bombardier CRJ200","regional-jet",21.2,26.8],CRJ7:["Bombardier CRJ700","regional-jet",23.2,32.3],CRJ9:["Bombardier CRJ900","regional-jet",24.9,36.2],CRJX:["Bombardier CRJ1000","regional-jet",26.2,39.1],AT72:["ATR 72","regional-turboprop",27.1,27.2],AT76:["ATR 72-600","regional-turboprop",27.1,27.2],AT45:["ATR 42","regional-turboprop",24.6,22.7],DH8D:["Dash 8 Q400","regional-turboprop",28.4,32.8],DH8C:["Dash 8-300","regional-turboprop",27.4,25.7],SF34:["Saab 340","regional-turboprop",21.4,19.7],B190:["Beechcraft 1900","regional-turboprop",17.7,17.6],C25A:["Cessna CitationJet CJ2","business-jet",14.3,14.4],C56X:["Cessna Citation Excel","business-jet",17.2,16],C68A:["Cessna Citation Latitude","business-jet",22,18.9],C550:["Cessna Citation II","business-jet",15.8,14.4],E55P:["Embraer Phenom 300","business-jet",15.9,15.6],E50P:["Embraer Phenom 100","business-jet",12.3,12.8],GLF5:["Gulfstream G550","business-jet",28.5,29.4],FA7X:["Dassault Falcon 7X","business-jet",26.2,23.4],CL60:["Bombardier Challenger 600","business-jet",19.6,20.9],LJ45:["Learjet 45","business-jet",14.6,17.7],H25B:["Hawker 800","business-jet",15.7,15.6],C172:["Cessna 172","light-piston",11,8.3],C152:["Cessna 152","light-piston",10.2,7.3],C182:["Cessna 182","light-piston",10.9,8.8],P28A:["Piper Cherokee","light-piston",10.7,7.2],PA34:["Piper Seneca","light-piston",11.8,8.7],SR20:["Cirrus SR20","light-piston",10.9,7.9],SR22:["Cirrus SR22","light-piston",11.7,7.9],S22T:["Cirrus SR22T","light-piston",11.7,7.9],DA40:["Diamond DA40","light-piston",11.6,8.1],DA42:["Diamond DA42","light-piston",13.4,8.6],BE20:["Beechcraft King Air 200","turboprop-light",16.6,13.3],BE58:["Beechcraft Baron","light-piston",11.5,9.1],C208:["Cessna Caravan","turboprop-light",15.9,11.5],PC12:["Pilatus PC-12","turboprop-light",16.3,14.4],TBM9:["Daher TBM 900","turboprop-light",12.8,10.7],EC35:["Airbus H135","helicopter-light",10.2,12.1],EC45:["Airbus H145","helicopter-medium",11,13.6],AS50:["Airbus H125","helicopter-light",10.7,12.9],EC30:["Airbus H130","helicopter-light",10.7,12.6],B407:["Bell 407","helicopter-light",10.7,12.7],B06:["Bell 206","helicopter-light",10.2,12],B429:["Bell 429","helicopter-medium",10.9,13],B505:["Bell 505","helicopter-light",10.4,11.9],R44:["Robinson R44","helicopter-light",10.1,11.7],R22:["Robinson R22","helicopter-light",7.7,8.8],A109:["Agusta A109","helicopter-medium",11,13],A139:["Leonardo AW139","helicopter-medium",13.8,16.7],S92:["Sikorsky S-92","helicopter-heavy",17.2,20.9],H60:["Sikorsky UH-60 Black Hawk","helicopter-heavy",16.4,19.8],T38:["Northrop T-38 Talon","military-jet",7.7,14.1],HAWK:["BAE Hawk","military-jet",9.4,11.9],GLID:["Glider","glider",17,7],BALL:["Balloon","balloon",15,20],ULAC:["Ultralight","ultralight",9.5,6],C42:["Ikarus C42","ultralight",9.4,6.3],DRON:["Drone","unmanned",1,.6]};static CATEGORIES={A1:["Light aircraft","light-piston",11,8.3],A2:["Small aircraft","business-jet",15,15],A3:["Large aircraft","airliner-narrow",34.1,37.6],A4:["High-vortex large aircraft","airliner-narrow",38,47.3],A5:["Heavy aircraft","airliner-wide",60.3,63.7],A6:["High-performance aircraft","military-jet",8,14],A7:["Rotorcraft","helicopter-medium",10.7,12.7],B1:["Glider","glider",17,7],B2:["Lighter-than-air","balloon",15,20],B4:["Ultralight","ultralight",9.5,6],B6:["Unmanned aircraft","unmanned",1.5,1]};static GENERIC={name:"Airliner",kind:"airliner-narrow",spanM:34.1,lengthM:37.6,basis:"nothing"};static of(t){const e=t?.type?.toUpperCase(),a=e?N.TYPES[e]:void 0;if(a)return{code:e,name:a[0],kind:a[1],spanM:a[2],lengthM:a[3],basis:"type"};const i=t?.category?N.CATEGORIES[t.category]:void 0;return i?{name:i[0],kind:i[1],spanM:i[2],lengthM:i[3],basis:"category"}:{...N.GENERIC}}static isHelicopter(t){return t.kind.startsWith("helicopter")}}class H{static DUSK_SUN_ELEVATION_DEG=-.83;static ALWAYS=new Set(["airliner-narrow","airliner-wide","regional-turboprop","regional-jet","business-jet"]);static NONE=new Set(["glider","balloon"]);static BRIGHTNESS={"light-piston":[.5,.2,.5],"turboprop-light":[.7,.4,.8],ultralight:[.4,.2,.4],unmanned:[0,.05,0],"helicopter-light":[1,1,1],"helicopter-medium":[1,1,1],"helicopter-heavy":[1,1,1],"military-jet":[1,1,1]};static lampsOn(t,e){if(H.NONE.has(t))return{navigation:!1,beacon:!1,strobes:!1};if(H.ALWAYS.has(t))return{navigation:!0,beacon:!0,strobes:!0};const a=e<H.DUSK_SUN_ELEVATION_DEG;return t==="unmanned"?{navigation:!1,beacon:!1,strobes:a}:{navigation:a,beacon:a,strobes:a}}static lights(t,e){const a=H.lampsOn(t.kind,e),i=t.kind.startsWith("helicopter"),n=ct.find(c=>c.id===(i?"helicopter":"airliner")).create(),[r,s]=i?[5,7]:[17,18],o=t.spanM/2/r,l=t.lengthM/2/s,[h,u,d]=H.BRIGHTNESS[t.kind]??[1,1,1];return n.filter(c=>c.id.startsWith("nav")?a.navigation:c.id.startsWith("strobe")?a.strobes:c.id.startsWith("beacon")?a.beacon:!0).filter(c=>!(c.id.startsWith("beacon")&&!a.beacon)).map(c=>{const p=c.id.startsWith("nav")?h:c.id.startsWith("strobe")?u:d;return{...c,offsetM:{x:c.offsetM.x*o,y:c.offsetM.y,z:c.offsetM.z*l},intensity:(c.intensity??1)*p}}).filter(c=>(c.intensity??1)>0)}static bodyColor(t){return t.kind==="military-jet"?"#8a8e94":t.kind.startsWith("helicopter")?"#c8ccd1":t.kind==="unmanned"?"#2c2e33":"#dde0e4"}}class k{static FAMILIES={"amvlab-a320":["A318","A319","A320","A321","A19N","A20N","A21N"],"amvlab-b737":["B732","B733","B734","B735","B736","B737","B738","B739","B37M","B38M","B39M","B3XM"],"amvlab-a350":["A359","A35K"],"amvlab-a380":["A388"],"amvlab-b787":["B788","B789","B78X"]};static BY_TYPE=new Map(Object.entries(k.FAMILIES).flatMap(([t,e])=>e.map(a=>[a,t])));static idOf(t){return t?k.BY_TYPE.get(t.toUpperCase()):void 0}}class f{static ID_PREFIX=j.ID_PREFIX;static MAX_OBJECTS=40;static FT_TO_M=.3048;static DEG=Math.PI/180;static from(t,e,a,i=f.MAX_OBJECTS,n={}){return new It(t,e,a,i,n).build()}static idOf(t,e){return j.idOf(t,e)}static keyOf(t){return j.keyOf(t)}static HEIGHT_OVER_LENGTH=.29;static sizeOf(t){return{widthM:t.spanM,lengthM:t.lengthM,heightM:t.lengthM*f.HEIGHT_OVER_LENGTH}}static offsetOf(t,e){const a=L.seenFrom(t,{lat:e.lat,lng:e.lng,heightM:e.altitudeFt*f.FT_TO_M}),i=a.distanceKm*1e3,n=i*Math.cos(a.altitudeDeg*f.DEG);return{eastM:n*Math.sin(a.azimuthDeg*f.DEG),northM:n*Math.cos(a.azimuthDeg*f.DEG),upM:i*Math.sin(a.altitudeDeg*f.DEG),altitudeDeg:a.altitudeDeg,distanceKm:a.distanceKm}}static segments(t){const e=[];let a=[];for(const i of t.points){const n=a[a.length-1];n&&i.t-n.t>P.MAX_GAP_S*1e3&&(e.push(a),a=[]),a.push(i)}return e.push(a),e.filter(i=>i.length>=2)}static bearingDeg(t,e){return(Math.atan2(e.eastM-t.eastM,e.northM-t.northM)/f.DEG+360)%360}}class It{constructor(t,e,a,i,n){this.tracks=t,this.observer=e,this.startMs=a,this.maxObjects=i,this.options=n}build(){const t=[];for(const a of this.tracks){const i=f.keyOf(a),n=this.options.models?.get(i)??N.of(void 0);f.segments(a).forEach((r,s)=>{const o=r.map(c=>({point:c,at:f.offsetOf(this.observer,c)}));if(!o.some(c=>c.at.altitudeDeg>=0))return;const l=o.map((c,p)=>({t:c.point.t-this.startMs,eastM:c.at.eastM,northM:c.at.northM,altitudeM:c.at.upM,headingDeg:c.point.trackDeg??(p+1<o.length?f.bearingDeg(c.at,o[p+1].at):f.bearingDeg(o[p-1].at,c.at))})),h=f.idOf(a,s),u=o[Math.floor(o.length/2)].point,d=this.options.sunElevationAt?.(u)??90;t.push({object:{id:h,kind:"aircraft",eastM:l[0].eastM,northM:l[0].northM,headingDeg:l[0].headingDeg,sizeM:f.sizeOf(n),model:k.idOf(n.code)?{id:k.idOf(n.code)}:void 0,color:H.bodyColor(n),lights:H.lights(n,d),track:l},presence:{fromMs:l[0].t,untilMs:l[l.length-1].t},flight:{icao:a.icao,nonIcao:a.nonIcao,points:r},closestKm:Math.min(...o.map(c=>c.at.distanceKm))})})}t.sort((a,i)=>a.closestKm-i.closestKm);const e=t.slice(0,this.maxObjects);return{objects:e.map(a=>a.object),presence:new Map(e.map(a=>[a.object.id,a.presence])),flights:new Map(e.map(a=>[a.object.id,a.flight])),total:t.length,shown:e.length}}}const st=[{id:"turbofan-narrow-body",name:"Turbofan airliner, narrow-body",kinds:["airliner-narrow"],totalDbA:148,shapeDb:[-32,-17,-9,-6,-5,-7,-12,-22],character:{toneHz:1800,toneShare:.3,humHz:90,humShare:.7}},{id:"turbofan-wide-body",name:"Turbofan airliner, wide-body",kinds:["airliner-wide"],totalDbA:151,shapeDb:[-28,-14,-7,-4,-3,-6,-12,-22],character:{toneHz:1200,toneShare:.3,humHz:70,humShare:.7}},{id:"regional-jet",name:"Regional jet",kinds:["regional-jet"],totalDbA:144,shapeDb:[-32,-17,-9,-5,-4,-6,-11,-21],character:{toneHz:1900,toneShare:.3,humHz:95,humShare:.7}},{id:"business-jet",name:"Business jet",kinds:["business-jet"],totalDbA:141,shapeDb:[-30,-15,-8,-4,-3,-4,-9,-19],character:{toneHz:2500,toneShare:.25,humHz:110,humShare:.7}},{id:"turboprop",name:"Turboprop",kinds:["regional-turboprop","turboprop-light"],totalDbA:138,shapeDb:[-14,-9,-8,-6,-8,-13,-20,-28],character:{toneHz:80,toneShare:.5}},{id:"light-piston",name:"Light piston aircraft",kinds:["light-piston"],totalDbA:130,shapeDb:[-18,-9,-5,-4,-8,-14,-22,-30],character:{toneHz:80,toneShare:.4}},{id:"ultralight",name:"Ultralight",kinds:["ultralight"],totalDbA:124,shapeDb:[-16,-8,-5,-4,-9,-15,-23,-31],character:{toneHz:140,toneShare:.4}},{id:"helicopter-light",name:"Light helicopter",kinds:["helicopter-light"],totalDbA:134,shapeDb:[-15,-8,-4,-3,-6,-10,-16,-24],character:{modulationHz:20,modulationDepth:.5}},{id:"helicopter-medium",name:"Medium helicopter",kinds:["helicopter-medium"],totalDbA:138,shapeDb:[-14,-7,-4,-3,-6,-10,-16,-24],character:{modulationHz:22,modulationDepth:.5}},{id:"helicopter-heavy",name:"Heavy helicopter",kinds:["helicopter-heavy"],totalDbA:144,shapeDb:[-12,-6,-4,-4,-7,-11,-17,-25],character:{modulationHz:17,modulationDepth:.5}},{id:"military-jet",name:"Military jet",kinds:["military-jet"],totalDbA:152,shapeDb:[-26,-12,-6,-3,-2,-3,-7,-15]},{id:"glider",name:"Glider",kinds:["glider"],totalDbA:85,shapeDb:[-30,-22,-15,-10,-8,-8,-14,-22]},{id:"balloon",name:"Hot-air balloon",kinds:["balloon"],totalDbA:100,shapeDb:[-25,-15,-9,-5,-3,-6,-12,-20]},{id:"unmanned",name:"Unmanned aircraft",kinds:["unmanned"],totalDbA:88,shapeDb:[-40,-30,-20,-12,-6,-3,-3,-8],character:{toneHz:450,toneShare:1}}],it=st.map(I=>({id:I.id,name:I.name,soundPowerA:I.shapeDb.map(t=>t+I.totalDbA-A.sumDb(I.shapeDb)),character:I.character}));class g{static DEFAULT_AMBIENT_DB_A=35;static DETECTION_MARGIN_DB=3;static AMBIENT_SHAPE_DB=[-12,-7,-5,-5,-7,-11,-17,-25];static HEARING_FLOOR_DB_A=0;static ITERATIONS=30;static CONVERGED_MS=.5;static VELOCITY_STEP_MS=500;static noiseOfKind(t){const e=st.find(a=>a.kinds.includes(t));return it.find(a=>a.id===(e?.id??"turbofan-narrow-body"))}static bandsAt(t,e,a=A.STANDARD){const i=20*Math.log10(Math.max(e*1e3,1))+11;return A.OCTAVES.map((n,r)=>t.soundPowerA[r]-i-A.absorptionDbPerKm(n,a)*e)}static couldBeHeard(t,e,a=g.DEFAULT_AMBIENT_DB_A,i=A.STANDARD){const n=g.ambientBands(a);return g.bandsAt(t,e,i).some((r,s)=>r>=Math.max(n[s]+g.DETECTION_MARGIN_DB,g.HEARING_FLOOR_DB_A))}static ambientBands(t){const e=g.AMBIENT_SHAPE_DB,a=A.sumDb(e);return e.map(i=>t+i-a)}static heardAt(t,e,a,i={}){const n=i.air??A.STANDARD,r=A.speedOfSound(n.temperatureC),s=t.points[t.points.length-1]?.t;if(s===void 0)return;let o=Math.min(a,s),l=P.positionAt(t,o);if(!l)return;let h=L.seenFrom(e,l.geo);for(let S=0;S<g.ITERATIONS;S++){const v=a-h.distanceKm*1e3*1e3/r,G=Math.abs(v-o);if(o=v,l=P.positionAt(t,o),!l)return;if(h=L.seenFrom(e,l.geo),G<g.CONVERGED_MS)break}const u=P.positionAt(t,a),d=u?L.seenFrom(e,u.geo):h,c=i.noise??it[0],p=i.ambientDbA??g.DEFAULT_AMBIENT_DB_A,m=g.ambientBands(p),b=g.bandsAt(c,h.distanceKm,n),M=b.map((S,v)=>S>=Math.max(m[v]+g.DETECTION_MARGIN_DB,g.HEARING_FLOOR_DB_A)),_=b.indexOf(Math.max(...b)),T=M.lastIndexOf(!0);return{track:t,audible:M.some(Boolean),levelDbA:A.sumDb(b),bandsDbA:b,ambientDbA:p,delayS:(a-o)/1e3,emittedAtMs:o,sound:h,seen:d,lagDeg:g.angleBetween(h,d),dopplerRatio:g.doppler(t,e,o,r),dominantHz:A.OCTAVES[_],cutoffHz:T<0?void 0:A.OCTAVES[T]}}static profile(t,e,a,i,n=2e3,r={}){const s=[];let o,l,h=a;for(let u=a;u<=i;u+=n){const d=g.heardAt(t,e,u,r);d&&(!l||d.levelDbA>l.levelDbA)&&(l=d,h=u),d?.audible?o?o.untilMs=u:s.push(o={fromMs:u,untilMs:u}):o=void 0}return{track:t,audible:s,peakDbA:l?.levelDbA??-1/0,peakAtMs:h,peakDelayS:l?.delayS??0}}static angleBetween(t,e){const a=h=>{const u=h.altitudeDeg*Math.PI/180,d=h.azimuthDeg*Math.PI/180;return[Math.cos(u)*Math.sin(d),Math.cos(u)*Math.cos(d),Math.sin(u)]},[i,n,r]=a(t),[s,o,l]=a(e);return Math.acos(Math.min(1,Math.max(-1,i*s+n*o+r*l)))*180/Math.PI}static doppler(t,e,a,i){const n=g.VELOCITY_STEP_MS,r=P.positionAt(t,a-n),s=P.positionAt(t,a+n);if(!r||!s)return 1;const o=L.seenFrom(e,r.geo).distanceKm*1e3,l=L.seenFrom(e,s.geo).distanceKm*1e3;return 1/(1-(o-l)/(2*n/1e3)/i)}}class wt{static at(t,e,a,i,n={}){const r=P.seenFrom(t,a,i);if(!r)return;const s=N.of(e),o=g.heardAt(t,a,i,{noise:g.noiseOfKind(s.kind),...n});return{hex:`${t.nonIcao?"~":""}${t.icao.toString(16).padStart(6,"0")}`,registration:e?.registration,typeCode:s.code??e?.type,name:s.basis==="nothing"?void 0:s.name,kind:s.kind,basis:s.basis,military:e?.military===!0,restricted:e?.restricted===!0,altitudeFt:r.altitudeFt,groundSpeedKt:r.groundSpeedKt,trackDeg:r.trackDeg,sky:r.sky,angularRateDegPerS:r.angularRateDegPerS,hearing:o&&{audible:o.audible,levelDbA:o.levelDbA,ambientDbA:o.ambientDbA,delayS:o.delayS,lagDeg:o.lagDeg,dopplerRatio:o.dopplerRatio,cutoffHz:o.cutoffHz,dominantHz:o.dominantHz}}}}class R{static REFERENCE_AMPLITUDE=.02;static MASKING_RANGE_DB=6;static KNEE_DB=20;static COMPRESSION_RATIO=1.5;static EXPANSION_RATIO=1.8;static DEFAULT_MAX_VOICES=4;static candidates(t,e,a,i,n={}){const r=new Set;for(const[s,o]of t){const l=g.noiseOfKind(N.of(e.get(a(o))).kind);let h=1/0;for(const u of o.points)h=Math.min(h,L.seenFrom(i,{lat:u.lat,lng:u.lng,heightM:u.altitudeFt*.3048}).distanceKm);g.couldBeHeard(l,h,n.ambientDbA,n.air)&&r.add(s)}return r}static voices(t,e,a,i,n,r,s={}){const o=[];for(const l of t){const h=e.get(l);if(!h||s.only?.(l)===!1)continue;const u=N.of(a.get(i(h))).kind,d=g.noiseOfKind(u),c=g.heardAt(h,n,r,{...s,noise:d});c?.audible&&o.push({id:l,kind:u,bandAmplitudes:R.bandAmplitudes(c.bandsDbA,c.ambientDbA,s.referenceAmplitude),levelDbA:c.levelDbA,distanceKm:c.sound.distanceKm,dopplerRatio:c.dopplerRatio,azimuthDeg:c.sound.azimuthDeg,elevationDeg:c.sound.altitudeDeg,character:d.character})}return o.sort((l,h)=>h.levelDbA-l.levelDbA).slice(0,s.maxVoices??R.DEFAULT_MAX_VOICES)}static bandAmplitudes(t,e,a=R.REFERENCE_AMPLITUDE){const i=g.ambientBands(e),n=g.DETECTION_MARGIN_DB,r=A.sumDb(t),s=r-e,o=s>=R.KNEE_DB?R.KNEE_DB+(s-R.KNEE_DB)/R.COMPRESSION_RATIO:R.KNEE_DB-(R.KNEE_DB-s)*R.EXPANSION_RATIO,l=a*10**(o/20);return t.map((h,u)=>{const d=Math.min(1,Math.max(0,(h-i[u]-n+R.MASKING_RANGE_DB)/(2*R.MASKING_RANGE_DB)));return d*d*(3-2*d)*l*10**((h-r)/20)})}static BANDS_HZ=A.OCTAVES}class U{static ENGLISH={unnamed:"Aircraft {hex}",altitude:"{value} ft",speed:"{value} kt",heading:"heading {value}°",position:"{distance} km away, {elevation}° above the horizon, {bearing}",heard:"Heard at {level} dB(A), left the aircraft {delay} s ago, {lag}° behind it: {character}{pitch}",rumble:"a low rumble, nothing above {cutoff} Hz",muffled:"a dull noise, nothing above {cutoff} Hz",broad:"a broad roar",pitchHigher:", pitch {percent} % higher",pitchLower:", pitch {percent} % lower",inaudible:"Not audible here: {level} dB(A) against {ambient} dB(A) of ambient noise",soundUnknown:"Its sound cannot be worked out: the aircraft was not recorded yet when it left",contrailPersistent:"Leaves a trail that lasts: the air is supersaturated over ice ({rhi} % over ice)",contrailShort:"Leaves a short-lived trail: the air is dry over ice ({rhi} % over ice)",military:"military",restricted:"identity withheld by its owner",candidate:"A compatible candidate, not an identification"};static RUMBLE_BELOW_HZ=500;static DULL_BELOW_HZ=2e3;static PITCH_NOTICED=.03;static text(t,e,a,i){const n=(d,c=0)=>d.toLocaleString(i,{maximumFractionDigits:c}),r=(d,c)=>d.replace(/\{(\w+)\}/g,(p,m)=>c[m]??`{${m}}`),s=[],o=[t.registration,t.name].filter(Boolean).join(" · ");s.push(o||r(e.unnamed,{hex:t.hex}));const l=[r(e.altitude,{value:n(Math.round(t.altitudeFt/100)*100)}),t.groundSpeedKt===void 0?void 0:r(e.speed,{value:n(Math.round(t.groundSpeedKt))}),t.trackDeg===void 0?void 0:r(e.heading,{value:n(Math.round(t.trackDeg))})].filter(Boolean);s.push(l.join(" · ")),s.push(r(e.position,{distance:n(t.sky.distanceKm,t.sky.distanceKm<10?1:0),elevation:n(Math.round(t.sky.altitudeDeg)),bearing:a(t.sky.azimuthDeg)}));const h=t.hearing;if(!h)s.push(e.soundUnknown);else if(!h.audible)s.push(r(e.inaudible,{level:n(Math.round(h.levelDbA)),ambient:n(Math.round(h.ambientDbA))}));else{const d=h.cutoffHz??0,c=d<=U.RUMBLE_BELOW_HZ?e.rumble:d<=U.DULL_BELOW_HZ?e.muffled:e.broad,p=h.dopplerRatio-1,m=Math.abs(p)<U.PITCH_NOTICED?"":r(p>0?e.pitchHigher:e.pitchLower,{percent:n(Math.round(Math.abs(p)*100))});s.push(r(e.heard,{level:n(Math.round(h.levelDbA)),delay:n(Math.round(h.delayS)),lag:n(Math.round(h.lagDeg)),character:r(c,{cutoff:n(d)}),pitch:m}))}t.contrail&&s.push(r(t.contrail.persistent?e.contrailPersistent:e.contrailShort,{rhi:n(Math.round(t.contrail.iceRelativeHumidity*100))}));const u=[t.military?e.military:void 0,t.restricted?e.restricted:void 0].filter(Boolean);return u.length>0&&s.push(u.join(" · ")),s.push(e.candidate),s.join(`
|
|
2
|
-
`)}}class V{static EFFICIENCY={"airliner-narrow":.34,"airliner-wide":.38,"regional-jet":.32,"business-jet":.3,"military-jet":.22,unknown:.34};static efficiencyOf(t){return V.EFFICIENCY[t]}}class E{static EMISSION_INDEX_WATER=1.25;static COMBUSTION_HEAT=432e5;static AIR_HEAT_CAPACITY=1004;static MOLAR_MASS_RATIO=.622;static FT_TO_M=.3048;static TROPOPAUSE_M=11e3;static TROPOPAUSE_HPA=226.32;static ISOTHERMAL_SCALE_HEIGHT_M=6341.62;static pressureAtAltitudeFt(t){const e=t*E.FT_TO_M;return e<=E.TROPOPAUSE_M?1013.25*(1-225577e-10*e)**5.25588:E.TROPOPAUSE_HPA*Math.exp(-(e-E.TROPOPAUSE_M)/E.ISOTHERMAL_SCALE_HEIGHT_M)}static saturationOverWaterPa(t){const e=t+273.15;return Math.exp(54.842763-6763.22/e-4.21*Math.log(e)+367e-6*e+Math.tanh(.0415*(e-218.8))*(53.878-1331.22/e-9.44523*Math.log(e)+.014025*e))}static saturationOverIcePa(t){const e=t+273.15;return Math.exp(9.550426-5723.265/e+3.53068*Math.log(e)-.00728332*e)}static iceRelativeHumidity(t,e){return e*E.saturationOverWaterPa(t)/E.saturationOverIcePa(t)}static mixingSlope(t,e){return E.EMISSION_INDEX_WATER*E.AIR_HEAT_CAPACITY*t*100/(E.MOLAR_MASS_RATIO*E.COMBUSTION_HEAT*(1-e))}static criticalTemperatureC(t,e){const a=Math.log(E.mixingSlope(t,e)-.053);return-46.46+9.43*a+.72*a*a}static requiredHumidity(t,e,a){const i=E.criticalTemperatureC(t,e);return(E.mixingSlope(t,e)*(a-i)+E.saturationOverWaterPa(i))/E.saturationOverWaterPa(a)}static evaluate(t,e){const a=E.criticalTemperatureC(t.pressureHpa,e),i=E.requiredHumidity(t.pressureHpa,e,t.temperatureC),n=E.iceRelativeHumidity(t.temperatureC,t.relativeHumidity),r=t.temperatureC<a&&t.relativeHumidity>=i;return{forms:r,persistent:r&&n>=1,criticalTemperatureC:a,requiredHumidity:i,iceRelativeHumidity:n}}}class w{static HOLD_MS=36e5;static DEG=Math.PI/180;static GAS_CONSTANT_OVER_GRAVITY=287.05/9.80665;static at(t,e,a){if(t.length===0)return;const i=t[0],n=t[t.length-1];if(e<i.t-w.HOLD_MS||e>n.t+w.HOLD_MS)return;const r=t.findIndex(c=>c.t>e),s=r===0?t[0]:t[(r===-1?t.length:r)-1],o=r===-1||r===0?s:t[r],l=w.atLevel(s,a),h=w.atLevel(o,a);if(!l||!h)return;const u=o.t>s.t?Math.min(1,Math.max(0,(e-s.t)/(o.t-s.t))):0,d=(c,p)=>c+(p-c)*u;return{pressureHpa:a,temperatureC:d(l.temperatureC,h.temperatureC),relativeHumidity:d(l.relativeHumidity,h.relativeHumidity),driftEastMs:d(l.driftEastMs,h.driftEastMs),driftNorthMs:d(l.driftNorthMs,h.driftNorthMs),shearPerS:d(l.shearPerS,h.shearPerS)}}static atLevel(t,e){const a=t.levels;for(let i=0;i+1<a.length;i++){const n=a[i],r=a[i+1];if(e>n.pressureHpa||e<r.pressureHpa)continue;const s=(Math.log(n.pressureHpa)-Math.log(e))/(Math.log(n.pressureHpa)-Math.log(r.pressureHpa)),o=(c,p)=>c+(p-c)*s,l=c=>{const p=c.windFromDeg*w.DEG;return{east:-c.windSpeedMs*Math.sin(p),north:-c.windSpeedMs*Math.cos(p)}},h=l(n),u=l(r),d=w.GAS_CONSTANT_OVER_GRAVITY*((n.temperatureC+r.temperatureC)/2+273.15)*Math.log(n.pressureHpa/r.pressureHpa);return{pressureHpa:e,temperatureC:o(n.temperatureC,r.temperatureC),relativeHumidity:o(n.relativeHumidity,r.relativeHumidity),driftEastMs:o(h.east,u.east),driftNorthMs:o(h.north,u.north),shearPerS:Math.hypot(u.east-h.east,u.north-h.north)/d}}}}class Ht{static plan(t,e,a,i){if(a.length===0)return[];const n=[];for(const r of t.objects){const s=t.flights.get(r.id),o=r.track;if(!s||!o||o.length!==s.points.length)continue;const l=e?.get(j.keyOf(s))??N.of(void 0),h=V.efficiencyOf(l.kind);if(h===void 0)continue;const u=[];o.forEach((d,c)=>{const p=s.points[c],m=E.pressureAtAltitudeFt(p.altitudeFt),b=w.at(a,i+d.t,m),M=b&&E.evaluate(b,h);u.push({tMs:d.t,eastM:d.eastM,northM:d.northM,upM:d.altitudeM??0,forms:M?.forms??!1,persistent:M?.persistent??!1,lifetimeS:M?q.lifetimeS(M.iceRelativeHumidity):0,driftEastMs:b?.driftEastMs??0,driftNorthMs:b?.driftNorthMs??0,shearPerS:b?.shearPerS??q.TYPICAL_SHEAR_PER_S,iceRelativeHumidity:M?.iceRelativeHumidity??0})}),u.some((d,c)=>d.forms&&u[c+1]?.forms)&&n.push({id:r.id,spanM:l.spanM,points:u})}return n}}const nt=[500,400,300,250,200,150],Tt=["temperature","relative_humidity","wind_speed","wind_direction"],Ct="2022-01-01",rt=.25;class _t{fetchImpl;baseUrl;cache=new Map;constructor(t={}){this.fetchImpl=t.fetchImpl??fetch.bind(globalThis),this.baseUrl=t.baseUrl??"https://historical-forecast-api.open-meteo.com/v1/forecast"}between(t,e,a){const i=new Date(e).toISOString().slice(0,10);if(i<Ct)return Promise.resolve({status:"outside"});const n=new Date(a).toISOString().slice(0,10),s=`${`${Math.round(t.lat/rt)},${Math.round(t.lng/rt)}`}|${i}|${n}`;let o=this.cache.get(s);return o||(o=this.read(t,i,n),this.cache.set(s,o),o.then(l=>{l.status==="failed"&&this.cache.delete(s)})),o}async read(t,e,a){const i=nt.flatMap(s=>Tt.map(o=>`${o}_${s}hPa`)),n=new URLSearchParams({latitude:String(t.lat),longitude:String(t.lng),start_date:e,end_date:a,hourly:i.join(","),wind_speed_unit:"ms",timezone:"UTC"}),r=`${this.baseUrl}?${n}`;try{const s=await this.fetchImpl(r);if(!s.ok)return{status:"failed"};const o=await s.json();return this.decode(o,{id:"open-meteo-forecast",name:"Open-Meteo (historical forecast)",url:r})}catch{return{status:"failed"}}}decode(t,e){const a=t.hourly;if(!a?.time)return{status:"outside"};const i=[];return a.time.forEach((n,r)=>{const s=[];for(const o of nt){const l=p=>a[`${p}_${o}hPa`]?.[r],h=l("temperature"),u=l("relative_humidity"),d=l("wind_speed"),c=l("wind_direction");if([h,u,d,c].some(p=>p==null))return;s.push({pressureHpa:o,temperatureC:h,relativeHumidity:u/100,windSpeedMs:d,windFromDeg:c})}i.push({t:Date.parse(`${n}Z`),levels:s})}),i.length>0?{status:"found",samples:i,source:e}:{status:"outside"}}}const Lt=[{id:"open-meteo-forecast",name:"Open-Meteo (historical forecast)",credit:"Weather data by Open-Meteo.com, CC BY 4.0",creditUrl:"https://open-meteo.com/en/docs/historical-forecast-api",create:()=>new _t}];export{W as AircraftAudio,Ht as AircraftContrails,N as AircraftModels,O as AmbientNoise,f as TrafficDecor,wt as TrafficInfos,R as TrafficSound,U as TrafficTooltip,Lt as UPPER_AIR_SOURCES};
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import{U as v,l as k,B as p,N as f}from"./rr0-sighting-editor.mjs";import{bodyEditorMessages_en as g}from"./BodyEditorMessages_en-D6h_2jc7.js";class b{constructor(e,i,t){this.container=e,this.host=i,this.render(),this.setLanguage(t)}messages=g;languageToken=0;currentId;catalogueToken=0;shownEntry;syncedId;shownAppearance;static swatchOf(e){const i=/^#([0-9a-f])([0-9a-f])([0-9a-f])$/i.exec(e);return i?`#${i[1]}${i[1]}${i[2]}${i[2]}${i[3]}${i[3]}`.toLowerCase():/^#[0-9a-f]{6}$/i.test(e)?e.toLowerCase():"#c8c8c8"}async setLanguage(e){const i=++this.languageToken,t=v.includes(e)?e:"en",o=t==="en"?g:await k(t);i===this.languageToken&&o!==this.messages&&(this.messages=o,this.render())}sync(){const e=this.bodies;e.some(a=>a.id===this.currentId)||(this.currentId=e[0]?.id),this.input("body-interpretation-title").value=this.host.said().read(this.interpretation?.title)??"";const i=this.select("body-select");i.replaceChildren(...e.map(a=>new Option(this.labelOf(a),a.id))),this.currentId!==void 0&&(i.value=this.currentId);const t=this.host.newBodyStart(),o=this.element("body-add");o.disabled=t===void 0,o.title=t?t.label!==void 0?this.messages.addBodyHint.replace("{shape}",t.label):this.messages.addBodyHintView:this.messages.addBody,this.input("body-interpretation-title").closest("label").hidden=!1,this.select("body-select").closest("label").hidden=e.length===0;const d=this.current;if(this.element("body-none").hidden=e.length>0,this.element("body-fields").hidden=d===void 0,!d)return;this.input("body-id").value=d.id,this.input("body-title").value=this.host.said().read(d.title)??"",this.syncExplains(d),this.syncModelOptions(d);const n=d.model;this.input("body-model-url").value=n.url??"",this.input("body-model-title").value=n.credit?.title??"",this.input("body-model-author").value=n.credit?.author??"",this.input("body-model-license").value=n.credit?.license??"",this.input("body-model-source").value=n.credit?.sourceUrl??"";const s=this.element("body-model-advanced");s.open=n.url!==void 0||s.open&&d.id===this.syncedId,this.syncedId=d.id,this.element("body-model-incomplete").hidden=n.url===void 0||n.credit?.title!==void 0&&n.credit.license!==void 0,this.input("body-outline-node").value=d.outlineNode??"",this.element("body-track").textContent=this.trackSummary(d),this.syncKeyframe()}syncKeyframe(){const e=this.current;if(!e)return;const i=this.host.currentTime(),t=this.messages;this.element("body-key-legend").textContent=t.atPlayhead.replace("{t}",b.seconds(i));const o=this.host.readingOf(e,i),d=e.track.find(c=>c.t===i),n=b.keyframeBefore(e,i);this.element("body-key-note").textContent=o?d?t.keyframeHere:t.keyframeAdded:t.notPlaced,this.element("body-key-delete").disabled=d===void 0;const s=this.container.getRootNode().activeElement,a=n?.eastM!==void 0&&n.northM!==void 0?"world":"observer";s!==this.select("body-key-mode")&&(this.select("body-key-mode").value=a);const r=this.select("body-key-mode").value,h=n?.onGround===!0;this.input("body-key-ground").checked=h;for(const c of["body-key-azimuth","body-key-elevation","body-key-distance"])this.input(c).closest("label").hidden=r!=="observer";for(const c of["body-key-east","body-key-north"])this.input(c).closest("label").hidden=r!=="world";this.input("body-key-above").closest("label").hidden=r!=="world"||h;const u=e.model.url!==void 0||!p.includes(e.model.id??"");if(this.input("body-key-colour").closest("label").hidden=u,!o)return;const y={"body-key-azimuth":o.azimuthDeg,"body-key-elevation":o.altitudeDeg,"body-key-distance":o.distanceM,"body-key-east":o.eastM,"body-key-north":o.northM,"body-key-above":o.aboveGroundM,"body-key-width":o.sizeM.widthM,"body-key-length":o.sizeM.lengthM,"body-key-height":o.sizeM.heightM,"body-key-heading":o.attitude.headingDeg,"body-key-pitch":o.attitude.pitchDeg,"body-key-roll":o.attitude.rollDeg,"body-key-albedo":o.appearance.albedo,"body-key-luminance":o.appearance.luminanceCdM2};this.shownAppearance=o.appearance,this.input("body-key-colour")!==s&&(this.input("body-key-colour").value=b.swatchOf(o.appearance.color));for(const[c,l]of Object.entries(y))this.input(c)!==s&&(this.input(c).value=String(Number(l.toFixed(2))))}render(){const e=this.messages,i=(t,o,d="text",n="",s="",a="")=>`<label><span>${o}</span> <input id="${t}" type="${d}" placeholder="${n}" ${a} autocomplete="off"/>${s?` ${s}`:""}</label>`;this.container.innerHTML=`<div class="body-editor">
|
|
2
|
-
<p class="body-intro">${e.intro}</p>
|
|
3
|
-
${i("body-interpretation-title",e.interpretationTitle)}
|
|
4
|
-
<p id="body-none" class="body-intro">${e.none}</p>
|
|
5
|
-
<label><span>${e.body}</span> <select id="body-select"></select></label>
|
|
6
|
-
<button id="body-add" type="button" class="icon-btn" title="${e.addBody}" aria-label="${e.addBody}">+</button>
|
|
7
|
-
<div id="body-fields" class="body-fields">
|
|
8
|
-
<button id="body-look" type="button" class="icon-btn" title="${e.lookAtBody}" aria-label="${e.lookAtBody}">🎯</button>
|
|
9
|
-
<button id="body-delete" type="button" class="icon-btn" title="${e.deleteBody}" aria-label="${e.deleteBody}">🗑</button>
|
|
10
|
-
${i("body-id",e.id)}
|
|
11
|
-
${i("body-title",e.title)}
|
|
12
|
-
<fieldset class="body-explains"><legend>${e.explains}</legend><div id="body-explains"></div></fieldset>
|
|
13
|
-
<label><span>${e.model}</span> <select id="body-model"></select></label>
|
|
14
|
-
<details id="body-model-advanced" class="decor-model-advanced" hidden>
|
|
15
|
-
<summary>${e.modelAdvanced}</summary>
|
|
16
|
-
${i("body-model-url",e.modelUrl,"text",e.modelUrlHint)}
|
|
17
|
-
${i("body-model-title",e.modelTitle)}
|
|
18
|
-
${i("body-model-author",e.modelAuthor)}
|
|
19
|
-
${i("body-model-license",e.modelLicense,"text","CC0 1.0")}
|
|
20
|
-
${i("body-model-source",e.modelSource,"url","https://…")}
|
|
21
|
-
<p id="body-model-incomplete" class="body-intro" hidden>${e.modelIncomplete}</p>
|
|
22
|
-
<p id="body-model-catalogue" class="body-intro" hidden>${e.modelFromCatalogue}</p>
|
|
23
|
-
</details>
|
|
24
|
-
${i("body-outline-node",e.outlineNode,"text",e.outlineNodeHint)}
|
|
25
|
-
<p class="body-track"><span>${e.track}</span> <output id="body-track"></output></p>
|
|
26
|
-
<fieldset class="body-key">
|
|
27
|
-
<legend id="body-key-legend"></legend>
|
|
28
|
-
<p id="body-key-note" class="body-intro"></p>
|
|
29
|
-
<label><span>${e.placement}</span> <select id="body-key-mode"><option value="observer">${e.fromObserver}</option><option value="world">${e.inWorld}</option></select></label>
|
|
30
|
-
${i("body-key-azimuth",e.azimuth,"number","","°",'min="0" max="360" step="0.01"')}
|
|
31
|
-
${i("body-key-elevation",e.elevation,"number","","°",'min="-90" max="90" step="0.01"')}
|
|
32
|
-
${i("body-key-distance",e.distance,"number","","m",'min="0.1" max="30000" step="0.1"')}
|
|
33
|
-
${i("body-key-east",e.east,"number","","m",'min="-30000" max="30000" step="0.1"')}
|
|
34
|
-
${i("body-key-north",e.north,"number","","m",'min="-30000" max="30000" step="0.1"')}
|
|
35
|
-
<label><input id="body-key-ground" type="checkbox"/> <span>${e.onGround}</span></label>
|
|
36
|
-
${i("body-key-above",e.aboveGround,"number","","m",'min="0" max="30000" step="0.1"')}
|
|
37
|
-
${i("body-key-width",e.width,"number","","m",'min="0.01" max="1000" step="0.01"')}
|
|
38
|
-
${i("body-key-length",e.length,"number","","m",'min="0.01" max="1000" step="0.01"')}
|
|
39
|
-
${i("body-key-height",e.height,"number","","m",'min="0.01" max="1000" step="0.01"')}
|
|
40
|
-
${i("body-key-heading",e.heading,"number","","°",'min="0" max="360" step="0.1"')}
|
|
41
|
-
${i("body-key-pitch",e.pitch,"number","","°",'min="-90" max="90" step="0.1"')}
|
|
42
|
-
${i("body-key-roll",e.roll,"number","","°",'min="-180" max="180" step="0.1"')}
|
|
43
|
-
<label><span>${e.colour}</span> <input id="body-key-colour" type="color"/></label>
|
|
44
|
-
${i("body-key-albedo",e.albedo,"number","0 – 1","",'min="0" max="1" step="0.01"')}
|
|
45
|
-
${i("body-key-luminance",e.luminance,"number","","cd/m²",'min="0" max="100000" step="0.1"')}
|
|
46
|
-
<p class="body-intro">${e.appearanceNote}</p>
|
|
47
|
-
<button id="body-key-delete" type="button">${e.deleteKeyframe}</button>
|
|
48
|
-
<p class="body-intro">${e.pictureHint}</p>
|
|
49
|
-
</fieldset>
|
|
50
|
-
</div>
|
|
51
|
-
</div>`,this.select("body-select").addEventListener("change",()=>{this.currentId=this.select("body-select").value,this.sync()}),this.input("body-interpretation-title").addEventListener("change",()=>this.updateInterpretationTitle()),this.element("body-delete").addEventListener("click",()=>this.deleteCurrent()),this.element("body-add").addEventListener("click",()=>this.addBody()),this.element("body-look").addEventListener("click",()=>{const t=this.current;t&&this.host.lookAt(t)});for(const t of["body-id","body-title","body-outline-node","body-model-url","body-model-title","body-model-author","body-model-license","body-model-source"])this.input(t).addEventListener("change",()=>this.updateCurrent());this.select("body-model").addEventListener("change",()=>{const t=this.select("body-model").value;t!==""&&(this.input("body-model-url").value=""),this.updateCurrent(),this.syncModelOptions(this.current),t!==""&&this.adoptCatalogueSize(t),this.element("body-model-advanced").open=t!==""&&!p.includes(t)}),this.element("body-explains").addEventListener("change",()=>this.updateCurrent());for(const t of b.KEY_FIELDS)this.input(t).addEventListener("input",()=>this.updateKeyframe()),this.input(t).addEventListener("change",()=>this.updateKeyframe());this.select("body-key-mode").addEventListener("change",()=>this.updateKeyframe()),this.element("body-key-delete").addEventListener("click",()=>this.deleteKeyframe()),this.host.modelPicker().enhance(this.select("body-model"),async t=>p.includes(t)?{shape:t}:this.host.modelProvider().entry(t).then(o=>o&&{url:o.url,headingOffsetDeg:o.headingOffsetDeg}),{current:()=>{const t=this.current?.model;return t?.url===void 0?void 0:{url:t.url,title:t.credit?.title??"",author:t.credit?.author??"",license:t.credit?.license??"",source:t.credit?.sourceUrl??""}},apply:t=>{this.input("body-model-url").value=t.url,this.input("body-model-title").value=t.title,this.input("body-model-author").value=t.author,this.input("body-model-license").value=t.license,this.input("body-model-source").value=t.source,this.shownEntry=void 0,this.select("body-model").value="",this.updateCurrent(),this.syncModelOptions(this.current)}}),f.fit(this.container),this.sync()}syncExplains(e){const i=this.host.shapes(),t=this.element("body-explains"),o=[...new Set([...i.map(d=>d.id),...e.explains??[]])];t.replaceChildren(...o.map(d=>{const n=document.createElement("label"),s=document.createElement("input");return s.type="checkbox",s.value=d,s.checked=e.explains?.includes(d)??!1,n.append(s," ",i.find(a=>a.id===d)?.label??d),n})),o.length===0&&(t.textContent=this.messages.explainsNothing)}async syncModelOptions(e){const i=++this.catalogueToken,t=await this.host.modelProvider().entries().catch(()=>[]);if(i!==this.catalogueToken)return;const o=this.messages,d=document.createElement("optgroup");d.label=o.primitives,d.append(...p.map(r=>new Option(o.primitive[r],r)));const n=document.createElement("optgroup");n.label=o.catalogue,n.append(...t.map(r=>new Option(r.name,r.id)));const s=this.select("body-model");s.replaceChildren(d,n),e.model.url!==void 0&&s.prepend(new Option(o.modelAdvanced,""));const a=e.model.url===void 0?e.model.id:void 0;a!==void 0&&![...s.options].some(r=>r.value===a)&&s.append(new Option(a,a)),s.value=a??"",this.showCatalogueModel(e.model.url===void 0?t.find(r=>r.id===e.model.id):void 0)}showCatalogueModel(e){const i=this.current;if(!i||i.model.url!==void 0){this.shownEntry=void 0,this.element("body-model-catalogue").hidden=!0;return}this.shownEntry=e;const t=this.container.getRootNode().activeElement,o=[["body-model-url",e?.url],["body-model-title",e?.credit.title],["body-model-author",e?.credit.author],["body-model-license",e?.credit.license],["body-model-source",e?.credit.sourceUrl]];for(const[d,n]of o)this.input(d)!==t&&(this.input(d).value=n??"");this.element("body-model-catalogue").hidden=e===void 0,this.element("body-model-incomplete").hidden=!0}updateInterpretationTitle(){const e=this.interpretation??{bodies:[]},i=this.host.said().write(e.title,this.input("body-interpretation-title").value,this.host.writingLanguage());this.write({...e,title:i})}updateCurrent(){const e=this.current;if(!e)return;const i=this.input("body-id").value.trim(),t=i!==""&&!this.bodies.some(n=>n!==e&&n.id===i)?i:e.id,o=[...this.element("body-explains").querySelectorAll("input:checked")].map(n=>n.value),d={...e,id:t,title:this.host.said().write(e.title,this.input("body-title").value,this.host.writingLanguage()),explains:o.length>0?o:void 0,model:this.statedModel(e.model),outlineNode:this.stringOrUndefined(this.input("body-outline-node").value)};this.currentId=t,this.write({...this.interpretation,bodies:this.bodies.map(n=>n===e?d:n)})}addBody(){const e=this.host.newBodyStart();if(!e)return;const i=new Set(this.bodies.map(n=>n.id));let t=i.size+1;for(;i.has(`body-${t}`);)t++;const o={id:`body-${t}`,explains:e.sourceId!==void 0?[e.sourceId]:void 0,model:{id:"ellipsoid"},track:[e.keyframe]};this.currentId=o.id;const d=this.interpretation??{bodies:[]};this.write({...d,bodies:[...this.bodies,o]},!0)}async adoptCatalogueSize(e){const t=(await this.host.modelProvider().entry(e).catch(()=>{}))?.sizeM,o=this.current;if(!t||!o||o.model.id!==e)return;if(!o.track.some(n=>n.sizeM)&&o.track.length>0){const[n,...s]=[...o.track].sort((h,u)=>h.t-u.t),a={widthM:t.widthM??1,lengthM:t.lengthM??t.widthM??1,heightM:t.heightM??1},r=[{...n,sizeM:a},...s];this.write({...this.interpretation,bodies:this.bodies.map(h=>h===o?{...o,track:r}:h)},!0);return}const d=o.track.map(n=>{const s=n.sizeM?.widthM,a=t.widthM??s;if(!n.sizeM||s===void 0||a===void 0||s<=0)return n;const r=a/s,h={widthM:t.widthM??n.sizeM.widthM*r,lengthM:t.lengthM??n.sizeM.lengthM*r,heightM:t.heightM??n.sizeM.heightM*r};return n.distanceM!==void 0&&n.azimuthDeg!==void 0?{...n,sizeM:h,distanceM:Number((n.distanceM*r).toFixed(1))}:{...n,sizeM:h}});this.write({...this.interpretation,bodies:this.bodies.map(n=>n===o?{...o,track:d}:n)},!0)}get currentBodyId(){return this.current?.id}resize(e){const i=(t,o)=>{this.input(t).value=String(Number(Math.max(.01,o).toFixed(2)))};i("body-key-width",e.widthM),i("body-key-length",e.lengthM),i("body-key-height",e.heightM),this.updateKeyframe()}turnTo(e){const i=t=>((t+180)%360+360)%360-180;this.input("body-key-heading").value=String(Number(((e.headingDeg%360+360)%360).toFixed(1))),this.input("body-key-pitch").value=String(Number(Math.max(-90,Math.min(90,e.pitchDeg)).toFixed(1))),this.input("body-key-roll").value=String(Number(i(e.rollDeg).toFixed(1))),this.updateKeyframe()}show(e){!this.bodies.some(i=>i.id===e)||e===this.currentId||(this.currentId=e,this.sync())}readingNow(){const e=this.current;return e&&this.host.readingOf(e,this.host.currentTime())}dragTo(e,i){const t=this.readingNow();if(!t)return;const o=this.host.currentTime(),d=this.input("body-key-ground").checked,n=d?this.host.groundAlong(e,i,o):void 0,s=Math.PI/180,a=(r,h)=>{this.input(r).value=String(Number(h.toFixed(2)))};if(this.select("body-key-mode").value==="world"){const r=Math.cos(t.altitudeDeg*s),h=t.eastM-Math.sin(t.azimuthDeg*s)*r*t.distanceM,u=t.northM-Math.cos(t.azimuthDeg*s)*r*t.distanceM,y=Math.hypot(t.eastM-h,t.northM-u),c=n!==void 0?n*Math.cos(i*s):y;if(a("body-key-east",h+Math.sin(e*s)*c),a("body-key-north",u+Math.cos(e*s)*c),!d){const l=m=>Math.max(-89,Math.min(89,m))*s;a("body-key-above",Math.max(0,t.aboveGroundM+c*(Math.tan(l(i))-Math.tan(l(t.altitudeDeg)))))}}else a("body-key-azimuth",(e%360+360)%360),a("body-key-elevation",Math.max(-90,Math.min(90,i))),n!==void 0&&a("body-key-distance",n);this.updateKeyframe()}scaleDistance(e){const i=this.readingNow();if(!i)return;const t=(o,d)=>{this.input(o).value=String(Number(d.toFixed(2)))};if(this.select("body-key-mode").value==="world"){const o=Math.PI/180,d=Math.cos(i.altitudeDeg*o),n=i.eastM-Math.sin(i.azimuthDeg*o)*d*i.distanceM,s=i.northM-Math.cos(i.azimuthDeg*o)*d*i.distanceM;t("body-key-east",n+(i.eastM-n)*e),t("body-key-north",s+(i.northM-s)*e)}else t("body-key-distance",Math.max(.1,i.distanceM*e));this.updateKeyframe()}updateKeyframe(){const e=this.current;if(!e)return;const i=this.host.currentTime(),t=l=>{const m=Number(this.input(l).value);return Number.isFinite(m)?m:0},o=this.input("body-key-ground").checked,d=this.select("body-key-mode").value==="world"?{t:i,eastM:t("body-key-east"),northM:t("body-key-north"),...o?{onGround:!0}:{altitudeAboveGroundM:t("body-key-above")}}:{t:i,azimuthDeg:t("body-key-azimuth"),altitudeDeg:t("body-key-elevation"),distanceM:Math.max(.1,t("body-key-distance")),...o?{onGround:!0}:{}},n=l=>Math.max(.01,t(l)),s={color:this.input("body-key-colour").value,albedo:Math.max(0,Math.min(1,t("body-key-albedo"))),luminanceCdM2:Math.max(0,t("body-key-luminance"))},a=this.shownAppearance,r=!a||b.swatchOf(a.color)!==s.color.toLowerCase()||Math.abs(a.albedo-s.albedo)>1e-6||Math.abs(a.luminanceCdM2-s.luminanceCdM2)>1e-6,h=e.track.find(l=>l.t===i)?.appearance,u=r?s:h??void 0,y={...b.withoutPlacement(e.track.find(l=>l.t===i)),...d,sizeM:{widthM:n("body-key-width"),lengthM:n("body-key-length"),heightM:n("body-key-height")},attitude:{headingDeg:t("body-key-heading"),pitchDeg:t("body-key-pitch"),rollDeg:t("body-key-roll")},...u?{appearance:u}:{}},c=[...e.track.filter(l=>l.t!==i),y].sort((l,m)=>l.t-m.t);this.write({...this.interpretation,bodies:this.bodies.map(l=>l===e?{...e,track:c}:l)}),this.element("body-track").textContent=this.trackSummary({...e,track:c}),this.syncKeyframe()}deleteKeyframe(){const e=this.current;if(!e)return;const i=this.host.currentTime(),t=e.track.filter(o=>o.t!==i);t.length!==e.track.length&&this.write({...this.interpretation,bodies:this.bodies.map(o=>o===e?{...e,track:t}:o)},!0)}static KEY_FIELDS=["body-key-azimuth","body-key-elevation","body-key-distance","body-key-east","body-key-north","body-key-ground","body-key-above","body-key-width","body-key-length","body-key-height","body-key-heading","body-key-pitch","body-key-roll","body-key-colour","body-key-albedo","body-key-luminance"];static withoutPlacement(e){if(!e)return{};const{eastM:i,northM:t,azimuthDeg:o,altitudeDeg:d,distanceM:n,onGround:s,altitudeAboveGroundM:a,sizeM:r,attitude:h,appearance:u,...y}=e;return y}static keyframeBefore(e,i){const t=[...e.track].sort((o,d)=>o.t-d.t);return[...t].reverse().find(o=>o.t<=i)??t[0]}static seconds(e){return`${Math.round(e/100)/10} s`}deleteCurrent(){const e=this.current;e&&(this.currentId=void 0,this.write({...this.interpretation,bodies:this.bodies.filter(i=>i!==e)},!0))}statedModel(e){const i=this.stringOrUndefined(this.input("body-model-url").value),t=this.shownEntry,o=n=>this.stringOrUndefined(this.input(n).value);if(t&&i===t.url&&o("body-model-title")===t.credit.title&&o("body-model-author")===t.credit.author&&o("body-model-license")===t.credit.license&&o("body-model-source")===t.credit.sourceUrl)return{id:t.id};if(i){const n=this.stringOrUndefined(this.input("body-model-title").value),s=this.stringOrUndefined(this.input("body-model-license").value);return{url:i,headingOffsetDeg:e.url!==void 0?e.headingOffsetDeg:void 0,credit:n!==void 0&&s!==void 0?{title:n,license:s,author:this.stringOrUndefined(this.input("body-model-author").value),sourceUrl:this.stringOrUndefined(this.input("body-model-source").value)}:void 0}}return{id:this.stringOrUndefined(this.select("body-model").value)??e.id??"ellipsoid"}}write(e,i=!1){const t=e.bodies.length===0&&e.title===void 0&&e.smoke===void 0&&e.reentries===void 0;if(this.host.sighting().interpretation=t?void 0:e,this.host.changed(),i){this.sync();return}const o=this.select("body-select");o.replaceChildren(...this.bodies.map(n=>new Option(this.labelOf(n),n.id))),this.currentId!==void 0&&(o.value=this.currentId);const d=this.current;d&&(this.input("body-id").value=d.id,this.element("body-model-incomplete").hidden=d.model.url===void 0||d.model.credit!==void 0,this.syncModelOptions(d))}trackSummary(e){const i=e.track.map(o=>o.t);if(i.length===0)return this.messages.trackEmpty;const t=o=>`${Math.round(o/100)/10} s`;return i.length===1?this.messages.trackSingle.replace("{at}",t(i[0])):this.messages.trackSpan.replace("{n}",String(i.length)).replace("{from}",t(Math.min(...i))).replace("{to}",t(Math.max(...i)))}labelOf(e){const i=this.host.said().read(e.title);return i?`${i} (${e.id})`:e.id}get interpretation(){return this.host.sighting().interpretation}get bodies(){return this.interpretation?.bodies??[]}get current(){return this.bodies.find(e=>e.id===this.currentId)}stringOrUndefined(e){const i=e.trim();return i===""?void 0:i}element(e){return this.container.querySelector("#"+e)}input(e){return this.element(e)}select(e){return this.element(e)}}export{b as BodyEditor};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const e={intro:"What the observer said the phenomenon was, in 3D: each body stands for one or more of the shapes drawn. Its movement comes from the file.",interpretationTitle:"Interpretation title",body:"Body",none:"No body yet: the observer said nothing of what it was, or it is still to be entered",deleteBody:"Delete body",addBody:"Add a body",addBodyHintView:"Where the observer is looking now",lookAtBody:"Look at it",addBodyHint:'Standing for the shape "{shape}", where the scene draws it now',id:"ID",title:"Name",explains:"Stands for the shapes",explainsNothing:"No shape",model:"3D model",primitives:"Built-in shapes",catalogue:"Catalogue",modelAdvanced:"Model from an address",modelUrl:"glTF/GLB address",modelUrlHint:"Absolute, or relative to this sighting.json",modelTitle:"Model name",modelAuthor:"Author",modelLicense:"Licence",modelSource:"Where it came from",modelIncomplete:"Not drawn until the model's name and licence are given",modelFromCatalogue:"From the catalogue, which the recording names it by. Change a field and it becomes this recording's own address.",outlineNode:"Part drawn by the observer",outlineNodeHint:"Node of the model, e.g. hull",track:"Movement",trackEmpty:"No keyframe",trackSpan:"{n} keyframes, from {from} to {to}",trackSingle:"1 keyframe, at {at}",atPlayhead:"At {t}",keyframeHere:"A keyframe stands here: editing changes it",keyframeAdded:"Editing adds a keyframe here",placement:"Position",fromObserver:"From the observer",inWorld:"In the world",azimuth:"Azimuth",elevation:"Elevation",distance:"Distance",east:"East",north:"North",onGround:"On the ground",aboveGround:"Above the ground",width:"Width",length:"Length",height:"Height",heading:"Heading",pitch:"Pitch",roll:"Roll",colour:"Colour",albedo:"Albedo",luminance:"Light of its own",appearanceNote:"The colour and the albedo paint the built-in shapes; a model of its own keeps its materials. Light of its own is what it gives out, lit or not.",deleteKeyframe:"Delete this keyframe",pictureHint:"On the picture: drag the body to move it, the wheel takes it nearer or further, the corners and sides size it, the stem turns it (with Shift: up and down pitches it, sideways rolls it).",notPlaced:"Not in the scene at this instant",primitive:{ellipsoid:"Ellipsoid",sphere:"Sphere",disc:"Disc",cylinder:"Cylinder",cone:"Cone",box:"Box",torus:"Torus",figure:"Human figure"}};export{e as bodyEditorMessages_en};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const e={intro:"Lo que el observador dijo que era el fenómeno, en 3D: cada cuerpo representa una o varias de las formas dibujadas. Su movimiento viene del archivo.",interpretationTitle:"Título de la interpretación",body:"Cuerpo",none:"Aún no hay ningún cuerpo: el observador no dijo nada de lo que era, o falta introducirlo",deleteBody:"Eliminar el cuerpo",addBody:"Añadir un cuerpo",addBodyHintView:"Donde mira el observador en este momento",lookAtBody:"Mirarlo",addBodyHint:"Representando la forma «{shape}», donde la escena la dibuja en este momento",id:"Identificador",title:"Nombre",explains:"Representa las formas",explainsNothing:"Ninguna forma",model:"Modelo 3D",primitives:"Formas básicas",catalogue:"Catálogo",modelAdvanced:"Modelo desde una dirección",modelUrl:"Dirección glTF/GLB",modelUrlHint:"Absoluta, o relativa a este sighting.json",modelTitle:"Nombre del modelo",modelAuthor:"Autor",modelLicense:"Licencia",modelSource:"Procedencia",modelIncomplete:"No se dibuja mientras falten el nombre y la licencia del modelo",modelFromCatalogue:"Del catálogo, por el que la grabación lo nombra. Cambia un campo y pasa a ser la dirección propia de esta grabación.",outlineNode:"Parte dibujada por el observador",outlineNodeHint:"Nodo del modelo, p. ej. hull",track:"Movimiento",trackEmpty:"Ningún fotograma clave",trackSpan:"{n} fotogramas clave, de {from} a {to}",trackSingle:"1 fotograma clave, en {at}",atPlayhead:"En {t}",keyframeHere:"Aquí hay un fotograma clave: editar lo modifica",keyframeAdded:"Editar añade aquí un fotograma clave",placement:"Posición",fromObserver:"Desde el observador",inWorld:"En el mundo",azimuth:"Acimut",elevation:"Elevación",distance:"Distancia",east:"Este",north:"Norte",onGround:"En el suelo",aboveGround:"Sobre el suelo",width:"Ancho",length:"Largo",height:"Alto",heading:"Rumbo",pitch:"Cabeceo",roll:"Alabeo",colour:"Color",albedo:"Albedo",luminance:"Luz propia",appearanceNote:"El color y el albedo pintan las formas básicas; un modelo propio conserva sus materiales. La luz propia es la que emite, esté iluminado o no.",deleteKeyframe:"Eliminar este fotograma clave",pictureHint:"En la imagen: arrastrar el cuerpo lo desplaza, la rueda lo acerca o lo aleja, las esquinas y los lados lo dimensionan, el vástago lo gira (con Mayús: arriba y abajo lo cabecean, los lados lo hacen alabear).",notPlaced:"No está en la escena en este instante",primitive:{ellipsoid:"Elipsoide",sphere:"Esfera",disc:"Disco",cylinder:"Cilindro",cone:"Cono",box:"Caja",torus:"Toro",figure:"Silueta humana"}};export{e as bodyEditorMessages_es};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const e={intro:"Ce que l'observateur a dit que le phénomène était, en 3D : chaque corps représente une ou plusieurs des formes dessinées. Son mouvement vient du fichier.",interpretationTitle:"Titre de l'interprétation",body:"Corps",none:"Aucun corps pour l'instant : l'observateur n'a rien dit de ce que c'était, ou c'est encore à saisir",deleteBody:"Supprimer le corps",addBody:"Ajouter un corps",addBodyHintView:"Là où l'observateur regarde à cet instant",lookAtBody:"Le regarder",addBodyHint:"Représentant la forme « {shape} », là où la scène la dessine à cet instant",id:"Identifiant",title:"Nom",explains:"Représente les formes",explainsNothing:"Aucune forme",model:"Modèle 3D",primitives:"Formes de base",catalogue:"Catalogue",modelAdvanced:"Modèle depuis une adresse",modelUrl:"Adresse glTF/GLB",modelUrlHint:"Absolue, ou relative à ce sighting.json",modelTitle:"Nom du modèle",modelAuthor:"Auteur",modelLicense:"Licence",modelSource:"Provenance",modelIncomplete:"Pas dessiné tant que le nom et la licence du modèle manquent",modelFromCatalogue:"Du catalogue, par lequel l'enregistrement le nomme. Modifiez un champ et il devient l'adresse propre à cet enregistrement.",outlineNode:"Partie dessinée par l'observateur",outlineNodeHint:"Nœud du modèle, par ex. hull",track:"Mouvement",trackEmpty:"Aucune image clé",trackSpan:"{n} images clés, de {from} à {to}",trackSingle:"1 image clé, à {at}",atPlayhead:"À {t}",keyframeHere:"Une image clé est ici : l'éditer la modifie",keyframeAdded:"Éditer ajoute une image clé ici",placement:"Position",fromObserver:"Depuis l'observateur",inWorld:"Dans le monde",azimuth:"Azimut",elevation:"Hauteur",distance:"Distance",east:"Est",north:"Nord",onGround:"Au sol",aboveGround:"Au-dessus du sol",width:"Largeur",length:"Longueur",height:"Hauteur",heading:"Cap",pitch:"Tangage",roll:"Roulis",colour:"Couleur",albedo:"Albédo",luminance:"Lumière propre",appearanceNote:"La couleur et l'albédo peignent les formes de base ; un modèle garde ses propres matériaux. La lumière propre est ce qu'il émet, éclairé ou non.",deleteKeyframe:"Supprimer cette image clé",pictureHint:"Sur l'image : glisser le corps le déplace, la molette le rapproche ou l'éloigne, les coins et les côtés le dimensionnent, la tige le tourne (avec Maj : haut et bas le cabrent, les côtés le font rouler).",notPlaced:"Pas dans la scène à cet instant",primitive:{ellipsoid:"Ellipsoïde",sphere:"Sphère",disc:"Disque",cylinder:"Cylindre",cone:"Cône",box:"Boîte",torus:"Tore",figure:"Silhouette humaine"}};export{e as bodyEditorMessages_fr};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const o={intro:"Ciò che l'osservatore ha detto che era il fenomeno, in 3D: ogni corpo rappresenta una o più delle forme disegnate. Il suo movimento viene dal file.",interpretationTitle:"Titolo dell'interpretazione",body:"Corpo",none:"Ancora nessun corpo: l'osservatore non ha detto nulla di ciò che era, o è ancora da inserire",deleteBody:"Elimina il corpo",addBody:"Aggiungi un corpo",addBodyHintView:"Dove guarda l'osservatore in questo momento",lookAtBody:"Guardalo",addBodyHint:"In rappresentanza della forma «{shape}», dove la scena la disegna in questo momento",id:"Identificativo",title:"Nome",explains:"Rappresenta le forme",explainsNothing:"Nessuna forma",model:"Modello 3D",primitives:"Forme di base",catalogue:"Catalogo",modelAdvanced:"Modello da un indirizzo",modelUrl:"Indirizzo glTF/GLB",modelUrlHint:"Assoluto, o relativo a questo sighting.json",modelTitle:"Nome del modello",modelAuthor:"Autore",modelLicense:"Licenza",modelSource:"Provenienza",modelIncomplete:"Non disegnato finché mancano il nome e la licenza del modello",modelFromCatalogue:"Dal catalogo, con cui la registrazione lo nomina. Modifica un campo e diventa l'indirizzo proprio di questa registrazione.",outlineNode:"Parte disegnata dall'osservatore",outlineNodeHint:"Nodo del modello, ad es. hull",track:"Movimento",trackEmpty:"Nessun fotogramma chiave",trackSpan:"{n} fotogrammi chiave, da {from} a {to}",trackSingle:"1 fotogramma chiave, a {at}",atPlayhead:"A {t}",keyframeHere:"Qui c'è un fotogramma chiave: modificarlo lo cambia",keyframeAdded:"Modificare aggiunge qui un fotogramma chiave",placement:"Posizione",fromObserver:"Dall'osservatore",inWorld:"Nel mondo",azimuth:"Azimut",elevation:"Elevazione",distance:"Distanza",east:"Est",north:"Nord",onGround:"A terra",aboveGround:"Sopra il suolo",width:"Larghezza",length:"Lunghezza",height:"Altezza",heading:"Rotta",pitch:"Beccheggio",roll:"Rollio",colour:"Colore",albedo:"Albedo",luminance:"Luce propria",appearanceNote:"Il colore e l'albedo dipingono le forme di base; un modello proprio conserva i suoi materiali. La luce propria è quella che emette, illuminato o no.",deleteKeyframe:"Elimina questo fotogramma chiave",pictureHint:"Sull'immagine: trascinare il corpo lo sposta, la rotellina lo avvicina o lo allontana, gli angoli e i lati lo dimensionano, lo stelo lo ruota (con Maiusc: su e giù lo fanno beccheggiare, i lati lo fanno rollare).",notPlaced:"Non è nella scena in questo istante",primitive:{ellipsoid:"Ellissoide",sphere:"Sfera",disc:"Disco",cylinder:"Cilindro",cone:"Cono",box:"Scatola",torus:"Toro",figure:"Sagoma umana"}};export{o as bodyEditorMessages_it};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const e={recording:"Grabación",untitledReading:"Lectura {n}",untitledObservation:"Observación {n}",deleteRecording:"Quitar esta grabación del caso",deleteReadingQuestion:"¿Eliminar esta lectura? Nada se escribe hasta guardar el caso.",deleteObservationQuestion:"¿Eliminar esta observación del caso? Nada se escribe hasta guardar el caso.",deleteRefused:"Esta observación es interpretada por {n} lectura(s): elimínelas primero.",titleField:"Título de la interpretación",authorField:"Autor",addTitle:"Añadir una observación",sourceField:"Origen",sourceBlank:"Una grabación en blanco",sourceFile:"Un archivo JSON",sourceUrl:"Una dirección",observerField:"Testigo",fileField:"Archivo",urlField:"Dirección",loadFailed:"No se pudo leer esa grabación.",isACase:"Eso es un caso, no una grabación.",ok:"Aceptar",cancel:"Cancelar",caseHeading:"Caso",caseId:"Identificador",caseTitle:"Título",caseTime:"Fecha",recordingsHeading:"Observaciones",add:"Añadir",addHint:"Añadir",interpretationOf:"Interpretación de",interpretationOfNone:"—",exportButton:"Guardar",exportTitle:"Guardar el caso",exportAlso:"Guardar también las observaciones",addToCase:"Añadir a un caso",unsavedChanges:"Cambios sin guardar",discardQuestion:"Hay cambios que aún no se han guardado. ¿Cargar de todos modos y perderlos?",discardTitle:"Cambios sin guardar",discardOk:"Cargar de todos modos",leaveQuestion:"Hay cambios que aún no se han guardado. ¿Salir de todos modos y perderlos?",leaveOk:"Salir de todos modos"};export{e as caseEditorMessages_es};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const e={recording:"Enregistrement",untitledReading:"Lecture {n}",untitledObservation:"Observation {n}",deleteRecording:"Retirer cet enregistrement du dossier",deleteReadingQuestion:"Supprimer cette lecture ? Rien n'est écrit avant la sauvegarde du dossier.",deleteObservationQuestion:"Supprimer cette observation du dossier ? Rien n'est écrit avant la sauvegarde du dossier.",deleteRefused:"Cette observation est interprétée par {n} lecture(s) : supprimez-les d'abord.",titleField:"Titre de l'interprétation",authorField:"Auteur",addTitle:"Ajouter une observation",sourceField:"Source",sourceBlank:"Un enregistrement vierge",sourceFile:"Un fichier JSON",sourceUrl:"Une adresse",observerField:"Témoin",fileField:"Fichier",urlField:"Adresse",loadFailed:"Cet enregistrement n'a pas pu être lu.",isACase:"C'est un dossier, pas un enregistrement.",ok:"OK",cancel:"Annuler",caseHeading:"Dossier",caseId:"Identifiant",caseTitle:"Titre",caseTime:"Date",recordingsHeading:"Observations",add:"Ajouter",addHint:"Ajouter",interpretationOf:"Interprétation de",interpretationOfNone:"—",exportButton:"Sauver",exportTitle:"Sauver le dossier",exportAlso:"Sauver aussi les observations",addToCase:"Ajouter à un dossier",unsavedChanges:"Modifications non sauvées",discardQuestion:"Des modifications ne sont pas encore sauvées. Charger quand même et les perdre ?",discardTitle:"Modifications non sauvées",discardOk:"Charger quand même",leaveQuestion:"Des modifications ne sont pas encore sauvées. Quitter quand même et les perdre ?",leaveOk:"Quitter quand même"};export{e as caseEditorMessages_fr};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const e={recording:"Registrazione",untitledReading:"Lettura {n}",untitledObservation:"Osservazione {n}",deleteRecording:"Togliere questa registrazione dal caso",deleteReadingQuestion:"Eliminare questa lettura? Nulla viene scritto prima del salvataggio del caso.",deleteObservationQuestion:"Eliminare questa osservazione dal caso? Nulla viene scritto prima del salvataggio del caso.",deleteRefused:"Questa osservazione è interpretata da {n} lettura/e: eliminale prima.",titleField:"Titolo dell'interpretazione",authorField:"Autore",addTitle:"Aggiungi un'osservazione",sourceField:"Origine",sourceBlank:"Una registrazione vuota",sourceFile:"Un file JSON",sourceUrl:"Un indirizzo",observerField:"Testimone",fileField:"File",urlField:"Indirizzo",loadFailed:"Impossibile leggere quella registrazione.",isACase:"Questo è un caso, non una registrazione.",ok:"OK",cancel:"Annulla",caseHeading:"Caso",caseId:"Identificativo",caseTitle:"Titolo",caseTime:"Data",recordingsHeading:"Osservazioni",add:"Aggiungi",addHint:"Aggiungi",interpretationOf:"Interpretazione di",interpretationOfNone:"—",exportButton:"Salva",exportTitle:"Salva il caso",exportAlso:"Salva anche le osservazioni",addToCase:"Aggiungi a un caso",unsavedChanges:"Modifiche non salvate",discardQuestion:"Alcune modifiche non sono ancora state salvate. Caricare comunque e perderle?",discardTitle:"Modifiche non salvate",discardOk:"Carica comunque",leaveQuestion:"Alcune modifiche non sono ancora state salvate. Uscire comunque e perderle?",leaveOk:"Esci comunque"};export{e as caseEditorMessages_it};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const e={intro:"Los registros meteorológicos aportan la cobertura y el viento cuando están disponibles. La forma, el espesor y el tamaño de las nubes son estimaciones visuales, no nubes individuales medidas.",editScope:"Alcance de los cambios",scopeInstant:"Instante actual",scopeObservation:"Toda la observación",layer:"Capa",addLayer:"Añadir capa",deleteLayer:"Eliminar capa",cloudType:"Tipo de nube",unknownType:"Desconocido",base:"Base (m)",thickness:"Espesor (m)",coverage:"Cobertura (%)",cloudSize:"Tamaño de las nubes (m)",density:"Densidad",darkness:"Oscuridad",crystalAlignment:"Alineación de los cristales",layerWindDirection:"Dirección del viento de la capa (°)",layerWindSpeed:"Velocidad del viento de la capa (m/s)",generalWind:"Viento general",patternSeed:"Semilla del patrón",editHelp:"Editar pausa la reproducción y guarda en el instante meteorológico actual. Un viento de capa vacío toma el viento general. Toda la observación aplica la propiedad editada a cada fotograma clave meteorológico.",individualClouds:"Nubes individuales",individualCloud:"Nube individual",addIndividualCloud:"Añadir nube individual",pointAtCloud:"Apuntar a la nube",deleteCloud:"Eliminar nube",manipulate:"Seleccionar y arrastrar nubes en el cielo",instanceEast:"Posición este (m)",instanceNorth:"Posición norte (m)",instanceBase:"Base de la nube (m)",instanceThickness:"Espesor de la nube (m)",instanceWidth:"Anchura de la nube (m)",instanceDepth:"Profundidad de la nube (m)",instanceRotation:"Rotación de la nube (°)",instanceDensity:"Densidad de la nube",layerDarkness:"Oscuridad de la capa",individualHelp:"Las nubes individuales siguen presentes con un 0 % de cobertura global. Arrastrar cambia la posición y la altitud; los campos numéricos fijan las dimensiones con precisión. Las nubes siguen el viento de su capa.",none:"Ninguna",cloud:"Nube",savedAcrossObservation:"Guardado en toda la observación; vientos conservados.",savedAtThisTime:"Meteorología guardada en este instante.",noCloudHere:"No hay ninguna nube individual aquí.",cloudSelected:"Nube seleccionada. Arrástrala para moverla.",cloudAdded:" Nube individual añadida, independiente de la cobertura global."};export{e as cloudEditorMessages_es};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const e={intro:"Les relevés fournissent la couverture et le vent lorsqu’ils sont disponibles. La forme, l’épaisseur et la taille des nuages sont des estimations visuelles, pas des nuages individuels mesurés.",editScope:"Portée des modifications",scopeInstant:"Instant courant",scopeObservation:"Toute l’observation",layer:"Couche",addLayer:"Ajouter une couche",deleteLayer:"Supprimer la couche",cloudType:"Type de nuage",unknownType:"Inconnu",base:"Base (m)",thickness:"Épaisseur (m)",coverage:"Couverture (%)",cloudSize:"Taille des nuages (m)",density:"Densité",darkness:"Obscurité",crystalAlignment:"Alignement des cristaux",layerWindDirection:"Direction du vent de la couche (°)",layerWindSpeed:"Vitesse du vent de la couche (m/s)",generalWind:"Vent général",patternSeed:"Graine du motif",editHelp:"L’édition met la lecture en pause et enregistre à l’instant météo courant. Un vent de couche vide reprend le vent général. Toute l’observation applique la propriété modifiée à chaque point de la timeline météo.",individualClouds:"Nuages individuels",individualCloud:"Nuage individuel",addIndividualCloud:"Ajouter un nuage individuel",pointAtCloud:"Pointer le nuage",deleteCloud:"Supprimer ce nuage",manipulate:"Sélectionner et déplacer les nuages dans le ciel",instanceEast:"Position est (m)",instanceNorth:"Position nord (m)",instanceBase:"Base du nuage (m)",instanceThickness:"Épaisseur du nuage (m)",instanceWidth:"Largeur du nuage (m)",instanceDepth:"Profondeur du nuage (m)",instanceRotation:"Rotation du nuage (°)",instanceDensity:"Densité du nuage",layerDarkness:"Obscurité de la couche",individualHelp:"Les nuages individuels restent présents à 0 % de couverture globale. Le glissement change la position et l’altitude ; les champs règlent précisément les dimensions. Les nuages suivent le vent de leur couche.",none:"Aucun",cloud:"Nuage",savedAcrossObservation:"Modifications enregistrées sur toute l’observation, vents conservés.",savedAtThisTime:"Météo enregistrée à cet instant.",noCloudHere:"Aucun nuage individuel à cet endroit.",cloudSelected:"Nuage sélectionné. Faire glisser pour le déplacer.",cloudAdded:" Nuage individuel ajouté : sa présence est indépendante de la couverture globale."};export{e as cloudEditorMessages_fr};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const e={intro:"I dati meteorologici forniscono la copertura e il vento quando sono disponibili. Forma, spessore e dimensione delle nuvole sono stime visive, non nuvole singole misurate.",editScope:"Ambito delle modifiche",scopeInstant:"Istante corrente",scopeObservation:"Tutta l’osservazione",layer:"Strato",addLayer:"Aggiungi strato",deleteLayer:"Elimina strato",cloudType:"Tipo di nuvola",unknownType:"Sconosciuto",base:"Base (m)",thickness:"Spessore (m)",coverage:"Copertura (%)",cloudSize:"Dimensione delle nuvole (m)",density:"Densità",darkness:"Oscurità",crystalAlignment:"Allineamento dei cristalli",layerWindDirection:"Direzione del vento dello strato (°)",layerWindSpeed:"Velocità del vento dello strato (m/s)",generalWind:"Vento generale",patternSeed:"Seme del motivo",editHelp:"La modifica mette in pausa la riproduzione e salva all’istante meteorologico corrente. Un vento di strato vuoto riprende il vento generale. Tutta l’osservazione applica la proprietà modificata a ogni fotogramma chiave meteorologico.",individualClouds:"Nuvole singole",individualCloud:"Nuvola singola",addIndividualCloud:"Aggiungi nuvola singola",pointAtCloud:"Punta la nuvola",deleteCloud:"Elimina nuvola",manipulate:"Seleziona e trascina le nuvole nel cielo",instanceEast:"Posizione est (m)",instanceNorth:"Posizione nord (m)",instanceBase:"Base della nuvola (m)",instanceThickness:"Spessore della nuvola (m)",instanceWidth:"Larghezza della nuvola (m)",instanceDepth:"Profondità della nuvola (m)",instanceRotation:"Rotazione della nuvola (°)",instanceDensity:"Densità della nuvola",layerDarkness:"Oscurità dello strato",individualHelp:"Le nuvole singole restano presenti allo 0 % di copertura globale. Il trascinamento cambia posizione e quota; i campi numerici fissano con precisione le dimensioni. Le nuvole seguono il vento del loro strato.",none:"Nessuna",cloud:"Nuvola",savedAcrossObservation:"Salvato su tutta l’osservazione; venti conservati.",savedAtThisTime:"Meteo salvato in questo istante.",noCloudHere:"Nessuna nuvola singola qui.",cloudSelected:"Nuvola selezionata. Trascinala per spostarla.",cloudAdded:" Nuvola singola aggiunta, indipendente dalla copertura globale."};export{e as cloudEditorMessages_it};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{G as T,J as A,$ as N,M as w,a0 as G,a1 as O}from"./rr0-sighting-editor.mjs";import{C as S}from"./ContrailGrowth-CuAzwIoc.js";class f{static MAX_SEGMENTS=4e3;static MIN_PIXELS=2;static UNRESOLVED_CONTRAST=.5;static VERTICES_PER_SEGMENT=12;object;group=new T;trails=[];positions=new Float32Array(f.MAX_SEGMENTS*f.VERTICES_PER_SEGMENT*3);colors=new Float32Array(f.MAX_SEGMENTS*f.VERTICES_PER_SEGMENT*4);segments=0;constructor(){const t=new A;t.setAttribute("position",new N(this.positions,3)),t.setAttribute("color",new N(this.colors,4)),t.setDrawRange(0,0),this.object=new w(t,new G({vertexColors:!0,transparent:!0,depthWrite:!1,side:O})),this.object.frustumCulled=!1,this.object.name="contrails",this.group.name="contrails",this.group.add(this.object)}get segmentCount(){return this.segments}set(t){this.trails=t}update(t,s,r){let h=0;this.segments=0;for(const n of this.trails){const a=this.samplesOf(n,t,s),e=r(n.id);for(let c=0;c+1<a.length;c++){const o=a[c],p=a[c+1];if(!o.forms||!p.forms)continue;if(this.segments>=f.MAX_SEGMENTS)break;const l=this.pushSegment(h,o,p,n.spanM,e,s);l>h&&this.segments++,h=l}}const M=this.object.geometry;M.setDrawRange(0,h);for(const[n,a]of[["position",3],["color",4]]){const e=M.getAttribute(n);e.clearUpdateRanges(),h>0&&e.addUpdateRange(0,h*a),e.needsUpdate=!0}}samplesOf(t,s,r){const h=s-S.FORMATION_S*1e3,M=[],n=(o,p,l,d,m,y)=>({x:p+o.driftEastMs*m+r.origin.x,y:d,z:-(l+o.driftNorthMs*m)+r.origin.z,age:m,forms:y,point:o});let a=-1;t.points.forEach((o,p)=>{o.tMs>h||(a=p,M.push(n(o,o.eastM,o.northM,o.upM,(s-o.tMs)/1e3,o.forms)))});const e=t.points[a],c=t.points[a+1];if(e&&c){const o=(h-e.tMs)/(c.tMs-e.tMs),p=(l,d)=>l+(d-l)*o;M.push(n(e,p(e.eastM,c.eastM),p(e.northM,c.northM),p(e.upM,c.upM),S.FORMATION_S,e.forms&&c.forms))}return M}pushSegment(t,s,r,h,M,n){const a={persistent:s.point.persistent,lifetimeS:s.point.lifetimeS,spanM:h,shearPerS:s.point.shearPerS},e=S.opacity(s.age,a),c=S.opacity(r.age,a);if(e<=0&&c<=0)return t;const o={x:r.x-s.x,y:r.y-s.y,z:r.z-s.z};if(Math.hypot(o.x,o.y,o.z)<1e-6)return t;const p={x:(s.x+r.x)/2-n.eye.x,y:(s.y+r.y)/2-n.eye.y,z:(s.z+r.z)/2-n.eye.z},l=this.normalise(this.cross(o,p)),d=(i,u)=>{const g=Math.hypot(i.x-n.eye.x,i.y-n.eye.y,i.z-n.eye.z),E=S.widthM(h,i.age,i.point.shearPerS),R=Math.max(E,f.MIN_PIXELS*n.pixelRad*g);return{half:R/2,alpha:u*(E/R)**f.UNRESOLVED_CONTRAST}},m=[{sample:s,...d(s,e)},{sample:r,...d(r,c)}],y=(i,u)=>{const g=t*3;this.positions[g]=i.sample.x+l.x*i.half*u,this.positions[g+1]=i.sample.y+l.y*i.half*u,this.positions[g+2]=i.sample.z+l.z*i.half*u;const E=t*4;this.colors[E]=M[0],this.colors[E+1]=M[1],this.colors[E+2]=M[2],this.colors[E+3]=u===0?i.alpha:0,t++},[x,z]=m;for(const[i,u]of[[-1,0],[1,0]])y(x,i),y(x,u),y(z,i),y(x,u),y(z,u),y(z,i);return t}cross(t,s){return{x:t.y*s.z-t.z*s.y,y:t.z*s.x-t.x*s.z,z:t.x*s.y-t.y*s.x}}normalise(t){const s=Math.hypot(t.x,t.y,t.z)||1;return{x:t.x/s,y:t.y/s,z:t.z/s}}dispose(){this.object.geometry.dispose(),this.object.material.dispose(),this.group.removeFromParent()}}export{f as ContrailSystem};
|