gralobe 1.0.14 → 1.0.15

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.
@@ -541,44 +541,48 @@
541
541
  `,e.appendChild(this.element),this.updateSize(),this.resizeObserver=new ResizeObserver(()=>this.updateSize()),this.resizeObserver.observe(e)}getSizeClass(e,t){const i=Math.min(e,t);return i<200?"xs":i<300?"sm":i<450?"md":"lg"}updateSize(){const e=this.parentContainer.clientWidth,t=this.parentContainer.clientHeight,i=this.getSizeClass(e,t);this.element.classList.remove("size-xs","size-sm","size-md","size-lg"),this.element.classList.add(`size-${i}`)}show(e){const t=this.element.querySelector(".gralobe-legend-title"),i=this.element.querySelector(".gralobe-legend-gradient"),n=this.element.querySelector(".gralobe-legend-min"),r=this.element.querySelector(".gralobe-legend-max"),s=this.element.querySelector(".gralobe-legend-description");t.textContent=e.name,s.textContent=e.description;const[o,l,c]=e.colorScale;i.style.background=`linear-gradient(to right, ${o}, ${l}, ${c})`;const h=e.format??Vi(e.unit);n.textContent=h(e.domain[0]),r.textContent=h(e.domain[1]),this.element.classList.add("visible"),this.visible=!0}hide(){this.element.classList.remove("visible"),this.visible=!1}isVisible(){return this.visible}getElement(){return this.element}dispose(){this.resizeObserver?.disconnect(),this.element.remove()}}var Ta={trailer:59};function gr(a=256){let e=0,t=new Uint8Array(a);return{get buffer(){return t.buffer},reset(){e=0},bytesView(){return t.subarray(0,e)},bytes(){return t.slice(0,e)},writeByte(n){i(e+1),t[e]=n,e++},writeBytes(n,r=0,s=n.length){i(e+s);for(let o=0;o<s;o++)t[e++]=n[o+r]},writeBytesView(n,r=0,s=n.byteLength){i(e+s),t.set(n.subarray(r,r+s),e),e+=s}};function i(n){var r=t.length;if(r>=n)return;var s=1024*1024;n=Math.max(n,r*(r<s?2:1.125)>>>0),r!=0&&(n=Math.max(n,256));let o=t;t=new Uint8Array(n),e>0&&t.set(o.subarray(0,e),0)}}var Gi=12,_r=5003,Da=[0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535];function Ma(a,e,t,i,n=gr(512),r=new Uint8Array(256),s=new Int32Array(_r),o=new Int32Array(_r)){let l=s.length,c=Math.max(2,i);r.fill(0),o.fill(0),s.fill(-1);let h=0,u=0,p=c+1,m=p,f=!1,d=m,g=(1<<d)-1,_=1<<p-1,y=_+1,x=_+2,v=0,b=t[0],C=0;for(let w=l;w<65536;w*=2)++C;C=8-C,n.writeByte(c),P(_);let E=t.length;for(let w=1;w<E;w++)e:{let T=t[w],O=(T<<Gi)+b,S=T<<C^b;if(s[S]===O){b=o[S];break e}let R=S===0?1:l-S;for(;s[S]>=0;)if(S-=R,S<0&&(S+=l),s[S]===O){b=o[S];break e}P(b),b=T,x<1<<Gi?(o[S]=x++,s[S]=O):(s.fill(-1),x=_+2,f=!0,P(_))}return P(b),P(y),n.writeByte(0),n.bytesView();function P(w){for(h&=Da[u],u>0?h|=w<<u:h=w,u+=d;u>=8;)r[v++]=h&255,v>=254&&(n.writeByte(v),n.writeBytesView(r,0,v),v=0),h>>=8,u-=8;if((x>g||f)&&(f?(d=m,g=(1<<d)-1,f=!1):(++d,g=d===Gi?1<<d:(1<<d)-1)),w==y){for(;u>0;)r[v++]=h&255,v>=254&&(n.writeByte(v),n.writeBytesView(r,0,v),v=0),h>>=8,u-=8;v>0&&(n.writeByte(v),n.writeBytesView(r,0,v),v=0)}}}var Oa=Ma;function yr(a,e,t){return a<<8&63488|e<<2&992|t>>3}function xr(a,e,t,i){return a>>4|e&240|(t&240)<<4|(i&240)<<8}function br(a,e,t){return a>>4<<8|e&240|t>>4}function Yt(a,e,t){return a<e?e:a>t?t:a}function Ht(a){return a*a}function vr(a,e,t){var i=0,n=1e100;let r=a[e],s=r.cnt;r.ac;let o=r.rc,l=r.gc,c=r.bc;for(var h=r.fw;h!=0;h=a[h].fw){let p=a[h],m=p.cnt,f=s*m/(s+m);if(!(f>=n)){var u=0;u+=f*Ht(p.rc-o),!(u>=n)&&(u+=f*Ht(p.gc-l),!(u>=n)&&(u+=f*Ht(p.bc-c),!(u>=n)&&(n=u,i=h)))}}r.err=n,r.nn=i}function ji(){return{ac:0,rc:0,gc:0,bc:0,cnt:0,nn:0,fw:0,bk:0,tm:0,mtm:0,err:0}}function Ra(a,e){let t=e==="rgb444"?4096:65536,i=new Array(t),n=a.length;if(e==="rgba4444")for(let r=0;r<n;++r){let s=a[r],o=s>>24&255,l=s>>16&255,c=s>>8&255,h=s&255,u=xr(h,c,l,o),p=u in i?i[u]:i[u]=ji();p.rc+=h,p.gc+=c,p.bc+=l,p.ac+=o,p.cnt++}else if(e==="rgb444")for(let r=0;r<n;++r){let s=a[r],o=s>>16&255,l=s>>8&255,c=s&255,h=br(c,l,o),u=h in i?i[h]:i[h]=ji();u.rc+=c,u.gc+=l,u.bc+=o,u.cnt++}else for(let r=0;r<n;++r){let s=a[r],o=s>>16&255,l=s>>8&255,c=s&255,h=yr(c,l,o),u=h in i?i[h]:i[h]=ji();u.rc+=c,u.gc+=l,u.bc+=o,u.cnt++}return i}function Ia(a,e,t={}){let{format:i="rgb565",clearAlpha:n=!0,clearAlphaColor:r=0,clearAlphaThreshold:s=0,oneBitAlpha:o=!1}=t;if(!a||!a.buffer)throw new Error("quantize() expected RGBA Uint8Array data");if(!(a instanceof Uint8Array)&&!(a instanceof Uint8ClampedArray))throw new Error("quantize() expected RGBA Uint8Array data");let l=new Uint32Array(a.buffer),c=t.useSqrt!==!1,h=i==="rgba4444",u=Ra(l,i),p=u.length,m=p-1,f=new Uint32Array(p+1);for(var d=0,g=0;g<p;++g){let I=u[g];if(I!=null){var _=1/I.cnt;h&&(I.ac*=_),I.rc*=_,I.gc*=_,I.bc*=_,u[d++]=I}}Ht(e)/d<.022&&(c=!1);for(var g=0;g<d-1;++g)u[g].fw=g+1,u[g+1].bk=g,c&&(u[g].cnt=Math.sqrt(u[g].cnt));c&&(u[g].cnt=Math.sqrt(u[g].cnt));var y,x,v;for(g=0;g<d;++g){vr(u,g);var b=u[g].err;for(x=++f[0];x>1&&(v=x>>1,!(u[y=f[v]].err<=b));x=v)f[x]=y;f[x]=g}var C=d-e;for(g=0;g<C;){for(var E;;){var P=f[1];if(E=u[P],E.tm>=E.mtm&&u[E.nn].mtm<=E.tm)break;E.mtm==m?P=f[1]=f[f[0]--]:(vr(u,P),E.tm=g);var b=u[P].err;for(x=1;(v=x+x)<=f[0]&&(v<f[0]&&u[f[v]].err>u[f[v+1]].err&&v++,!(b<=u[y=f[v]].err));x=v)f[x]=y;f[x]=P}var w=u[E.nn],T=E.cnt,O=w.cnt,_=1/(T+O);h&&(E.ac=_*(T*E.ac+O*w.ac)),E.rc=_*(T*E.rc+O*w.rc),E.gc=_*(T*E.gc+O*w.gc),E.bc=_*(T*E.bc+O*w.bc),E.cnt+=w.cnt,E.mtm=++g,u[w.bk].fw=w.fw,u[w.fw].bk=w.bk,w.mtm=m}let S=[];var R=0;for(g=0;;++R){let I=Yt(Math.round(u[g].rc),0,255),G=Yt(Math.round(u[g].gc),0,255),N=Yt(Math.round(u[g].bc),0,255),F=255;h&&(F=Yt(Math.round(u[g].ac),0,255),o&&(F=F<=(typeof o=="number"?o:127)?0:255),n&&F<=s&&(I=G=N=r,F=0));let se=h?[I,G,N,F]:[I,G,N];if(La(S,se)||S.push(se),(g=u[g].fw)==0)break}return S}function La(a,e){for(let t=0;t<a.length;t++){let i=a[t],n=i[0]===e[0]&&i[1]===e[1]&&i[2]===e[2],r=i.length>=4&&e.length>=4?i[3]===e[3]:!0;if(n&&r)return!0}return!1}function ka(a,e,t="rgb565"){if(!a||!a.buffer)throw new Error("quantize() expected RGBA Uint8Array data");if(!(a instanceof Uint8Array)&&!(a instanceof Uint8ClampedArray))throw new Error("quantize() expected RGBA Uint8Array data");if(e.length>256)throw new Error("applyPalette() only works with 256 colors or less");let i=new Uint32Array(a.buffer),n=i.length,r=t==="rgb444"?4096:65536,s=new Uint8Array(n),o=new Array(r);if(t==="rgba4444")for(let l=0;l<n;l++){let c=i[l],h=c>>24&255,u=c>>16&255,p=c>>8&255,m=c&255,f=xr(m,p,u,h),d=f in o?o[f]:o[f]=Ua(m,p,u,h,e);s[l]=d}else{let l=t==="rgb444"?br:yr;for(let c=0;c<n;c++){let h=i[c],u=h>>16&255,p=h>>8&255,m=h&255,f=l(m,p,u),d=f in o?o[f]:o[f]=Fa(m,p,u,e);s[c]=d}}return s}function Ua(a,e,t,i,n){let r=0,s=1e100;for(let o=0;o<n.length;o++){let l=n[o],c=l[3],h=He(c-i);if(h>s)continue;let u=l[0];if(h+=He(u-a),h>s)continue;let p=l[1];if(h+=He(p-e),h>s)continue;let m=l[2];h+=He(m-t),!(h>s)&&(s=h,r=o)}return r}function Fa(a,e,t,i){let n=0,r=1e100;for(let s=0;s<i.length;s++){let o=i[s],l=o[0],c=He(l-a);if(c>r)continue;let h=o[1];if(c+=He(h-e),c>r)continue;let u=o[2];c+=He(u-t),!(c>r)&&(r=c,n=s)}return n}function He(a){return a*a}function za(a={}){let{initialCapacity:e=4096,auto:t=!0}=a,i=gr(e),n=5003,r=new Uint8Array(256),s=new Int32Array(n),o=new Int32Array(n),l=!1;return{reset(){i.reset(),l=!1},finish(){i.writeByte(Ta.trailer)},bytes(){return i.bytes()},bytesView(){return i.bytesView()},get buffer(){return i.buffer},get stream(){return i},writeHeader:c,writeFrame(h,u,p,m={}){let{transparent:f=!1,transparentIndex:d=0,delay:g=0,palette:_=null,repeat:y=0,colorDepth:x=8,dispose:v=-1}=m,b=!1;if(t?l||(b=!0,c(),l=!0):b=!!m.first,u=Math.max(0,Math.floor(u)),p=Math.max(0,Math.floor(p)),b){if(!_)throw new Error("First frame must include a { palette } option");$a(i,u,p,_,x),Er(i,_),y>=0&&Ba(i,y)}let C=Math.round(g/10);Na(i,v,C,f,d);let E=!!_&&!b;Va(i,u,p,E?_:null),E&&Er(i,_),Ga(i,h,u,p,x,r,s,o)}};function c(){wr(i,"GIF89a")}}function Na(a,e,t,i,n){a.writeByte(33),a.writeByte(249),a.writeByte(4),n<0&&(n=0,i=!1);var r,s;i?(r=1,s=2):(r=0,s=0),e>=0&&(s=e&7),s<<=2,a.writeByte(0|s|0|r),ke(a,t),a.writeByte(n||0),a.writeByte(0)}function $a(a,e,t,i,n=8){let r=1,s=0,o=Yi(i.length)-1,l=r<<7|n-1<<4|s<<3|o;ke(a,e),ke(a,t),a.writeBytes([l,0,0])}function Ba(a,e){a.writeByte(33),a.writeByte(255),a.writeByte(11),wr(a,"NETSCAPE2.0"),a.writeByte(3),a.writeByte(1),ke(a,e),a.writeByte(0)}function Er(a,e){let t=1<<Yi(e.length);for(let i=0;i<t;i++){let n=[0,0,0];i<e.length&&(n=e[i]),a.writeByte(n[0]),a.writeByte(n[1]),a.writeByte(n[2])}}function Va(a,e,t,i){if(a.writeByte(44),ke(a,0),ke(a,0),ke(a,e),ke(a,t),i){let n=0,r=0,s=Yi(i.length)-1;a.writeByte(128|n|r|0|s)}else a.writeByte(0)}function Ga(a,e,t,i,n=8,r,s,o){Oa(t,i,e,n,a,r,s,o)}function ke(a,e){a.writeByte(e&255),a.writeByte(e>>8&255)}function wr(a,e){for(var t=0;t<e.length;t++)a.writeByte(e.charCodeAt(t))}function Yi(a){return Math.max(Math.ceil(Math.log2(a)),1)}class ja{renderer;scene;camera;isRecording=!1;frames=[];mediaRecorder=null;recordedChunks=[];captureCanvas;captureCtx;compositeCanvas;compositeCtx;gifWidth=480;gifHeight=270;legendElement=null;countryLabels=null;constructor(e,t,i){this.renderer=e,this.scene=t,this.camera=i,this.captureCanvas=document.createElement("canvas"),this.captureCtx=this.captureCanvas.getContext("2d",{willReadFrequently:!0}),this.compositeCanvas=document.createElement("canvas"),this.compositeCtx=this.compositeCanvas.getContext("2d")}setLegendElement(e){this.legendElement=e}setCountryLabels(e){this.countryLabels=e}drawCountryLabelsOnCanvas(e,t,i){if(this.countryLabels)try{this.countryLabels.getVisibleLabelsForCanvas(this.camera,t,i).forEach(r=>{e.save(),e.globalAlpha=r.opacity,e.font="bold 12px Arial, sans-serif",e.textAlign="center",e.textBaseline="middle",e.strokeStyle="rgba(0, 0, 0, 0.8)",e.lineWidth=3,e.strokeText(r.text,r.x,r.y),e.fillStyle="#ffffff",e.fillText(r.text,r.x,r.y),e.restore()})}catch(n){console.warn("Failed to draw country labels:",n)}}drawOverlaysOnCanvas(e,t,i){this.drawCountryLabelsOnCanvas(e,t,i),this.drawLegendOnCanvas(e,t,i)}drawLegendOnCanvas(e,t,i){try{if(!this.legendElement||!this.legendElement.classList.contains("visible"))return;const n=this.legendElement,r=n.querySelector(".legend-title"),s=n.querySelector(".legend-gradient"),o=n.querySelector(".legend-min"),l=n.querySelector(".legend-max"),c=n.querySelector(".legend-description");if(!r||!s)return;const h=280,u=100,p=20,m=t-h-p,f=i-u-p,d=12;e.fillStyle="rgba(0, 10, 20, 0.9)",e.strokeStyle="rgba(100, 170, 255, 0.5)",e.lineWidth=2,e.beginPath(),e.roundRect?e.roundRect(m,f,h,u,d):e.rect(m,f,h,u),e.fill(),e.stroke(),e.fillStyle="#44aaff",e.font="bold 18px Arial, sans-serif",e.fillText(r.textContent||"",m+16,f+28);const g=m+16,_=f+40,y=h-32,x=20,v=s.style.background||"";let b=[];const C=v.match(/rgba?\([^)]+\)/g);if(C&&C.length>=2)b=C;else{const E=v.match(/#[0-9a-fA-F]{3,8}/g);E&&E.length>=2&&(b=E)}if(b.length>=2){const E=e.createLinearGradient(g,0,g+y,0);E.addColorStop(0,b[0]),b.length>=3?(E.addColorStop(.5,b[1]),E.addColorStop(1,b[2])):E.addColorStop(1,b[1]),e.fillStyle=E,e.beginPath(),e.roundRect?e.roundRect(g,_,y,x,4):e.rect(g,_,y,x),e.fill()}else{const E=e.createLinearGradient(g,0,g+y,0);E.addColorStop(0,"#cc6600"),E.addColorStop(.5,"#ffaa44"),E.addColorStop(1,"#ffeecc"),e.fillStyle=E,e.beginPath(),e.roundRect?e.roundRect(g,_,y,x,4):e.rect(g,_,y,x),e.fill(),console.log("Legend gradient style:",v)}if(e.fillStyle="#cccccc",e.font="14px Arial, sans-serif",o&&e.fillText(o.textContent||"",g,f+78),l){const E=l.textContent||"",P=e.measureText(E).width;e.fillText(E,g+y-P,f+78)}c&&c.textContent&&(e.fillStyle="#888888",e.font="italic 12px Arial, sans-serif",e.fillText(c.textContent,g,f+95))}catch(n){console.warn("Failed to draw legend on canvas:",n)}}screenshot(e={}){const{width:t=1920,height:i=1080}=e,n=this.renderer.domElement.width,r=this.renderer.domElement.height;this.renderer.setSize(t,i),this.camera.aspect=t/i,this.camera.updateProjectionMatrix(),this.renderer.render(this.scene,this.camera),this.compositeCanvas.width=t,this.compositeCanvas.height=i,this.compositeCtx.drawImage(this.renderer.domElement,0,0),this.drawOverlaysOnCanvas(this.compositeCtx,t,i);const s=this.compositeCanvas.toDataURL("image/png");this.renderer.setSize(n,r),this.camera.aspect=n/r,this.camera.updateProjectionMatrix(),this.downloadFile(s,`globe-${Date.now()}.png`)}startVideoRecording(e={}){return new Promise(t=>{if(this.isRecording){t();return}const i=this.renderer.domElement;this.compositeCanvas.width=i.width,this.compositeCanvas.height=i.height,this.compositeCtx.drawImage(i,0,0),this.drawOverlaysOnCanvas(this.compositeCtx,this.compositeCanvas.width,this.compositeCanvas.height);const n=this.compositeCanvas.captureStream(60),r=[{mime:"video/mp4;codecs=avc1",ext:"mp4"},{mime:"video/mp4",ext:"mp4"},{mime:"video/webm;codecs=h264",ext:"webm"},{mime:"video/webm;codecs=vp9",ext:"webm"},{mime:"video/webm;codecs=vp8",ext:"webm"},{mime:"video/webm",ext:"webm"}];let s="video/webm",o="webm";for(const{mime:c,ext:h}of r)if(MediaRecorder.isTypeSupported(c)){s=c,o=h,console.log(`Video recording using: ${c}`);break}this.mediaRecorder=new MediaRecorder(n,{mimeType:s,videoBitsPerSecond:8e6}),this.recordedChunks=[];const l=o;this.mediaRecorder.ondataavailable=c=>{c.data.size>0&&this.recordedChunks.push(c.data)},this.mediaRecorder.onstop=()=>{const c=s.split(";")[0],h=new Blob(this.recordedChunks,{type:c}),u=URL.createObjectURL(h);this.downloadFile(u,`globe-${Date.now()}.${l}`),URL.revokeObjectURL(u)},this.mediaRecorder.onstart=()=>{this.isRecording=!0,setTimeout(()=>t(),50)},this.mediaRecorder.start(100)})}updateVideoFrame(){if(!this.isRecording||!this.mediaRecorder)return;const e=this.compositeCanvas.width,t=this.compositeCanvas.height;this.compositeCtx.drawImage(this.renderer.domElement,0,0,e,t),this.drawOverlaysOnCanvas(this.compositeCtx,e,t)}stopVideoRecording(){!this.isRecording||!this.mediaRecorder||(this.mediaRecorder.stop(),this.isRecording=!1)}startGifCapture(e={}){if(this.isRecording)return;this.frames=[],this.isRecording=!0;const{width:t=480,height:i=270}=e;this.gifWidth=t,this.gifHeight=i,this.captureCanvas.width=t,this.captureCanvas.height=i}captureGifFrame(){if(!this.isRecording)return;const e=this.renderer.domElement,t=this.gifWidth,i=this.gifHeight;this.captureCtx.drawImage(e,0,0,t,i),this.drawOverlaysOnCanvas(this.captureCtx,t,i);const n=this.captureCtx.getImageData(0,0,t,i);this.frames.push({data:new Uint8ClampedArray(n.data),width:t,height:i})}async stopGifCapture(e={}){if(!this.isRecording)return;if(this.isRecording=!1,this.frames.length===0){console.warn("No frames captured for GIF");return}const{fps:t=20,filename:i}=e,n=Math.round(1e3/t);console.log(`Generating GIF with ${this.frames.length} frames at ${t} fps...`);try{const r=this.frames[0],s=r.width,o=r.height,l=Ia(r.data,256),c=za();for(let f=0;f<this.frames.length;f++){const d=this.frames[f],g=ka(d.data,l);c.writeFrame(g,s,o,{palette:f===0?l:void 0,delay:n,repeat:f===0?0:void 0}),f%10===0&&await new Promise(_=>setTimeout(_,0))}c.finish();const h=c.bytes(),u=new Blob([h],{type:"image/gif"}),p=URL.createObjectURL(u),m=i||`globe-${Date.now()}.gif`;this.downloadFile(p,m),setTimeout(()=>URL.revokeObjectURL(p),1e3),console.log(`GIF saved: ${m} (${this.frames.length} frames, ${(u.size/1024).toFixed(1)}KB)`)}catch(r){console.error("Failed to generate GIF:",r)}this.frames=[]}getIsRecording(){return this.isRecording}getFrameCount(){return this.frames.length}downloadFile(e,t){const i=document.createElement("a");i.href=e,i.download=t,i.style.display="none",document.body.appendChild(i),i.click(),document.body.removeChild(i)}}class Ya extends A.Object3D{constructor(e=document.createElement("div")){super(),this.isCSS2DObject=!0,this.element=e,this.element.style.position="absolute",this.element.style.userSelect="none",this.element.setAttribute("draggable",!1),this.center=new A.Vector2(.5,.5),this.addEventListener("removed",function(){this.traverse(function(t){t.element&&t.element instanceof t.element.ownerDocument.defaultView.Element&&t.element.parentNode!==null&&t.element.remove()})})}copy(e,t){return super.copy(e,t),this.element=e.element.cloneNode(!0),this.center=e.center,this}}const lt=new A.Vector3,Cr=new A.Matrix4,Pr=new A.Matrix4,Ar=new A.Vector3,Sr=new A.Vector3;class Ha{constructor(e={}){const t=this;let i,n,r,s;const o={objects:new WeakMap},l=e.element!==void 0?e.element:document.createElement("div");l.style.overflow="hidden",this.domElement=l,this.sortObjects=!0,this.getSize=function(){return{width:i,height:n}},this.render=function(f,d){f.matrixWorldAutoUpdate===!0&&f.updateMatrixWorld(),d.parent===null&&d.matrixWorldAutoUpdate===!0&&d.updateMatrixWorld(),Cr.copy(d.matrixWorldInverse),Pr.multiplyMatrices(d.projectionMatrix,Cr),h(f,f,d),this.sortObjects&&m(f)},this.setSize=function(f,d){i=f,n=d,r=i/2,s=n/2,l.style.width=f+"px",l.style.height=d+"px"};function c(f){f.isCSS2DObject&&(f.element.style.display="none");for(let d=0,g=f.children.length;d<g;d++)c(f.children[d])}function h(f,d,g){if(f.visible===!1){c(f);return}if(f.isCSS2DObject){lt.setFromMatrixPosition(f.matrixWorld),lt.applyMatrix4(Pr);const _=lt.z>=-1&&lt.z<=1&&f.layers.test(g.layers)===!0,y=f.element;y.style.display=_===!0?"":"none",_===!0&&(f.onBeforeRender(t,d,g),y.style.transform="translate("+-100*f.center.x+"%,"+-100*f.center.y+"%)translate("+(lt.x*r+r)+"px,"+(-lt.y*s+s)+"px)",y.parentNode!==l&&l.appendChild(y),f.onAfterRender(t,d,g));const x={distanceToCameraSquared:u(g,f)};o.objects.set(f,x)}for(let _=0,y=f.children.length;_<y;_++)h(f.children[_],d,g)}function u(f,d){return Ar.setFromMatrixPosition(f.matrixWorld),Sr.setFromMatrixPosition(d.matrixWorld),Ar.distanceToSquared(Sr)}function p(f){const d=[];return f.traverseVisible(function(g){g.isCSS2DObject&&d.push(g)}),d}function m(f){const d=p(f).sort(function(_,y){if(_.renderOrder!==y.renderOrder)return y.renderOrder-_.renderOrder;const x=o.objects.get(_).distanceToCameraSquared,v=o.objects.get(y).distanceToCameraSquared;return x-v}),g=d.length;for(let _=0,y=d.length;_<y;_++)d[_].element.style.zIndex=g-_}}}const Za={CN:[35,105],IN:[22,78],US:[39,-98],ID:[-2,118],PK:[30,70],BR:[-10,-55],NG:[9,8],BD:[24,90],RU:[60,100],MX:[23,-102],JP:[36,138],ET:[9,38.5],PH:[12,122],EG:[27,30],VN:[16,108],DE:[51,10],TR:[39,35],IR:[32,53],TH:[15,101],GB:[54,-2],FR:[46,2],IT:[42.5,12.5],ZA:[-29,24],TZ:[-6,35],KE:[0,38],KR:[36,128],CO:[4,-72],ES:[40,-4],AR:[-34,-64],UG:[1,32],DZ:[28,3],UA:[49,32],IQ:[33,44],PL:[52,20],CA:[56,-106],MA:[32,-5],SA:[24,45],PE:[-10,-76],AU:[-25,134],MY:[4,109.5],GH:[8,-1],NP:[28,84],VE:[7,-66],MG:[-19,47],CM:[6,12],NL:[52.5,5.5],CL:[-34,-71],SE:[62,15],NO:[64,10],SG:[1.3,103.8],NZ:[-42,174],IE:[53,-8],IL:[31,35],AE:[24,54],CH:[47,8],AT:[47.5,14.5],PT:[39.5,-8],GR:[39,22],CZ:[49.8,15.5],BE:[50.8,4],HU:[47,20],FI:[64,26],DK:[56,10],IS:[65,-18],CD:[-3,22],SD:[16,30],AO:[-12.5,18.5],MZ:[-18,35],CI:[7.5,-5.5],NE:[17,10],BF:[12,-1.5],ML:[17,-4],SN:[14.5,-14.5],ZM:[-15,28],ZW:[-19,29.5],RW:[-2,30],AF:[33,65],MM:[21,96],KP:[40,127],MN:[46,105],LK:[7.8,80.8],KZ:[48,67],UZ:[41,64],CU:[22,-79.5],EC:[-1.5,-78.5],GT:[15.5,-90.3],BO:[-17,-65],HN:[15,-86.5],PY:[-23,-58],UY:[-33,-56],CR:[10,-84],PA:[9,-80]},Ka=new Set(["CN","IN","US","BR","RU","JP","DE","GB","FR","AU","CA","MX","ID","SA","ZA","EG","NG","AR","IT","ES","KR","TR","PL","NL","CH","SE","NO","PK","BD","VN"]),Xa=new Set(["CN","IN","US","BR","RU","AU","CA"]),Wa=new Set(["RU","CA","US","CN","BR","AU"]),qa=new Set(["IN","AR","KZ","DZ","CD","SA","MX","ID","SD","LY","IR","MN","PE","TD","NE","AO","ML","ZA","CO","ET","BO","MR","EG","TZ","NG","VE","PK","TR","CL","MM"]),Qa=new Set(["AF","UA","MG","MZ","FR","ES","TH","CM","PG","JP","DE","VN","MY","CI","PL","IT","PH","EC","BF","NZ","GB","GH","RO","LA","GY","OM","BY","KH","SN","UG","NO","SE","FI","MR","ZM","ZW","NP","MA","IQ","BD"]);class Ja{labelRenderer;labels=[];labelGroup;currentStyle="none";sphereRadius;currentMorph=0;globe=null;camera=null;constructor(e,t){this.sphereRadius=t,this.labelRenderer=new Ha;const i=e.clientWidth||800,n=e.clientHeight||600;this.labelRenderer.setSize(i,n),this.labelRenderer.domElement.style.position="absolute",this.labelRenderer.domElement.style.top="0",this.labelRenderer.domElement.style.left="0",this.labelRenderer.domElement.style.pointerEvents="none",e.appendChild(this.labelRenderer.domElement),this.labelGroup=new D.Group,this.injectStyles(),this.createLabels()}injectStyles(){const e=document.createElement("style");e.textContent=`
542
542
  .country-label {
543
543
  font-family: system-ui, -apple-system, sans-serif;
544
- font-weight: 400;
545
- color: rgba(255, 255, 255, 0.65);
544
+ font-weight: 500;
545
+ color: rgba(255, 255, 255, 0.9);
546
546
  text-shadow:
547
- 0 0 2px rgba(0, 0, 0, 0.9),
548
- 0 0 4px rgba(0, 0, 0, 0.5);
547
+ 0 1px 2px rgba(0, 0, 0, 1),
548
+ 0 0 4px rgba(0, 0, 0, 0.9),
549
+ 0 0 8px rgba(0, 0, 0, 0.7),
550
+ 0 0 12px rgba(0, 0, 0, 0.5);
549
551
  white-space: nowrap;
550
552
  pointer-events: none;
551
553
  user-select: none;
552
554
  transform: translateX(-50%);
553
555
  transition: opacity 0.3s ease;
554
- letter-spacing: 0.5px;
556
+ letter-spacing: 1px;
555
557
  text-transform: uppercase;
556
558
  }
557
559
 
558
560
  /* Size categories - proportional to country size */
559
561
  .country-label.size-large {
562
+ font-size: 11px;
563
+ font-weight: 600;
564
+ letter-spacing: 2.5px;
565
+ color: rgba(255, 255, 255, 0.95);
566
+ }
567
+
568
+ .country-label.size-medium {
560
569
  font-size: 9px;
561
570
  font-weight: 500;
562
- letter-spacing: 2px;
563
- color: rgba(255, 255, 255, 0.7);
571
+ letter-spacing: 1.5px;
572
+ color: rgba(255, 255, 255, 0.9);
564
573
  }
565
574
 
566
- .country-label.size-medium {
575
+ .country-label.size-small {
567
576
  font-size: 7px;
577
+ font-weight: 500;
568
578
  letter-spacing: 1px;
569
- color: rgba(255, 255, 255, 0.6);
579
+ color: rgba(255, 255, 255, 0.8);
570
580
  }
571
581
 
572
- .country-label.size-small {
582
+ .country-label.size-tiny {
573
583
  font-size: 6px;
574
584
  letter-spacing: 0.5px;
575
- color: rgba(255, 255, 255, 0.5);
576
- }
577
-
578
- .country-label.size-tiny {
579
- font-size: 5px;
580
- letter-spacing: 0.3px;
581
- color: rgba(255, 255, 255, 0.4);
585
+ color: rgba(255, 255, 255, 0.7);
582
586
  }
583
587
 
584
588
  .country-label.hidden {
@@ -586,37 +590,38 @@
586
590
  visibility: hidden;
587
591
  }
588
592
 
589
- /* Minimal style - slightly bolder for the 7 largest */
593
+ /* Minimal style - bold for the 7 largest */
590
594
  .label-style-minimal .country-label.size-large {
591
- font-size: 10px;
592
- font-weight: 600;
595
+ font-size: 12px;
596
+ font-weight: 700;
593
597
  letter-spacing: 3px;
594
- color: rgba(255, 255, 255, 0.75);
598
+ color: #fff;
595
599
  }
596
600
 
597
601
  /* Major style - balanced visibility */
598
602
  .label-style-major .country-label.size-large {
599
- font-size: 8px;
603
+ font-size: 10px;
604
+ font-weight: 600;
600
605
  letter-spacing: 2px;
601
606
  }
602
607
 
603
608
  .label-style-major .country-label.size-medium {
604
- font-size: 6px;
609
+ font-size: 8px;
605
610
  }
606
611
 
607
- /* All style - keep everything subtle */
612
+ /* All style - slightly more subtle but still readable */
608
613
  .label-style-all .country-label {
609
- color: rgba(255, 255, 255, 0.5);
614
+ color: rgba(255, 255, 255, 0.85);
610
615
  }
611
616
 
612
617
  .label-style-all .country-label.size-large {
613
- font-size: 8px;
614
- color: rgba(255, 255, 255, 0.6);
618
+ font-size: 9px;
619
+ color: rgba(255, 255, 255, 0.9);
615
620
  }
616
621
 
617
622
  .label-style-all .country-label.size-tiny {
618
- font-size: 4px;
619
- color: rgba(255, 255, 255, 0.35);
623
+ font-size: 5px;
624
+ color: rgba(255, 255, 255, 0.6);
620
625
  }
621
626
  `,document.head.appendChild(e)}getSizeCategory(e){return Wa.has(e)?"large":qa.has(e)?"medium":Qa.has(e)?"small":"tiny"}createLabels(){$i.forEach(e=>{const t=Za[e.code];if(!t)return;const[i,n]=t,r=this.getSizeCategory(e.code),s=document.createElement("div");s.className=`country-label hidden size-${r}`,s.textContent=e.name;const o=new Ya(s),l={element:s,object:o,country:e,lat:i,lon:n,sizeCategory:r};this.labelGroup.add(o),this.labels.push(l),this.updateLabelPosition(o,l,this.currentMorph)})}tempVector=new D.Vector3;cameraDirection=new D.Vector3;updateLabelPosition(e,t,i){const{lat:n,lon:r,element:s}=t,o=n*Math.PI/180,l=r*Math.PI/180,c=this.sphereRadius+.5,h=c*Math.cos(o)*Math.sin(l),u=c*Math.sin(o),p=c*Math.cos(o)*Math.cos(l),m=2*Math.PI*this.sphereRadius,f=Math.PI*this.sphereRadius,d=(r+180)/360,g=(n+90)/180,_=(d-.5)*m,y=(g-.5)*f,x=.5;if(this.globe&&i>.01)if(this.tempVector.set(h,u,p),this.tempVector.applyEuler(this.globe.rotation),e.position.set(this.tempVector.x*i+_*(1-i),this.tempVector.y*i+y*(1-i),this.tempVector.z*i+x*(1-i)),this.camera&&i>.5){this.cameraDirection.copy(this.camera.position).normalize();const C=this.tempVector.clone().normalize().dot(this.cameraDirection)>.15;s.style.opacity=C?"":"0"}else s.style.opacity="";else e.position.set(h*i+_*(1-i),u*i+y*(1-i),p*i+x*(1-i)),s.style.opacity=""}getGroup(){return this.labelGroup}setStyle(e){this.currentStyle=e,this.labels.forEach(t=>{const i=t.country.code;let n=!1;switch(e){case"none":n=!1;break;case"minimal":n=Xa.has(i);break;case"major":n=Ka.has(i);break;case"all":case"capitals":n=!0;break}t.element.classList.toggle("hidden",!n)}),this.labelRenderer.domElement.className=`label-style-${e}`}setMorph(e){this.currentMorph=e}setGlobe(e){this.globe=e}setCamera(e){this.camera=e}update(){this.currentStyle!=="none"&&this.labels.forEach(e=>{this.updateLabelPosition(e.object,e,this.currentMorph)})}render(e,t){this.currentStyle!=="none"&&this.labelRenderer.render(e,t)}resize(e,t){this.labelRenderer.setSize(e,t)}getStyle(){return this.currentStyle}getVisibleLabelsForCanvas(e,t,i){if(this.currentStyle==="none")return[];const n=[],r=new D.Vector3;return this.labels.forEach(s=>{const o=s.element.style.opacity,l=o===""?1:parseFloat(o)||0;if(l<.1||s.element.classList.contains("hidden"))return;s.object.getWorldPosition(r),r.project(e);const c=(r.x*.5+.5)*t,h=(-r.y*.5+.5)*i;c>=0&&c<=t&&h>=0&&h<=i&&r.z<1&&n.push({text:s.country.name,x:c,y:h,opacity:l})}),n}dispose(){this.labels.forEach(e=>{this.labelGroup.remove(e.object),e.element.remove()}),this.labels=[],this.labelRenderer.domElement.remove()}}const Zt={lifeExpectancy:{id:"lifeExpectancy",name:"Life Expectancy",unit:"years",description:"Average life expectancy at birth",colorScale:["#feedde","#fdbe85","#d94701"],domain:[55,85],format:a=>`${a.toFixed(1)} years`},humanDevIndex:{id:"humanDevIndex",name:"Human Development Index",unit:"",description:"UN composite index of life expectancy, education, and income",colorScale:["#fee5d9","#fcae91","#cb181d"],domain:[.4,1],format:a=>a.toFixed(3)},gdpPerCapita:{id:"gdpPerCapita",name:"GDP per Capita (PPP)",unit:"$",description:"Purchasing power parity adjusted GDP per person",colorScale:["#edf8e9","#74c476","#006d2c"],domain:[1e3,8e4],format:a=>`$${(a/1e3).toFixed(1)}k`},co2Emissions:{id:"co2Emissions",name:"CO₂ Emissions",unit:"t/capita",description:"Carbon dioxide emissions per capita",colorScale:["#f7fbff","#6baed6","#08306b"],domain:[0,20],format:a=>`${a.toFixed(1)}t`},renewableEnergy:{id:"renewableEnergy",name:"Renewable Energy",unit:"%",description:"Share of renewable energy in total energy consumption",colorScale:["#f7fcf5","#74c476","#00441b"],domain:[0,100],format:a=>`${a.toFixed(0)}%`},internetUsers:{id:"internetUsers",name:"Internet Penetration",unit:"%",description:"Percentage of population using the internet",colorScale:["#f2f0f7","#9e9ac8","#54278f"],domain:[0,100],format:a=>`${a.toFixed(0)}%`},urbanPopulation:{id:"urbanPopulation",name:"Urbanization",unit:"%",description:"Percentage of population living in urban areas",colorScale:["#fff5eb","#fd8d3c","#7f2704"],domain:[15,100],format:a=>`${a.toFixed(0)}%`},healthExpenditure:{id:"healthExpenditure",name:"Health Spending",unit:"% GDP",description:"Total health expenditure as percentage of GDP",colorScale:["#fff5f0","#fb6a4a","#99000d"],domain:[2,18],format:a=>`${a.toFixed(1)}%`},forestArea:{id:"forestArea",name:"Forest Coverage",unit:"%",description:"Forest area as percentage of total land area",colorScale:["#f7fcf5","#41ab5d","#00441b"],domain:[0,75],format:a=>`${a.toFixed(0)}%`},population:{id:"population",name:"Population",unit:"millions",description:"Total population",colorScale:["#fff7bc","#fec44f","#d95f0e"],domain:[1,1500],format:a=>`${a.toFixed(0)}M`},accessElectricity:{id:"accessElectricity",name:"Electricity Access",unit:"%",description:"Percentage of population with access to electricity",colorScale:["#ffeda0","#feb24c","#f03b20"],domain:[20,100],format:a=>`${a.toFixed(0)}%`},educationExpenditure:{id:"educationExpenditure",name:"Education Spending",unit:"% GDP",description:"Government expenditure on education as percentage of GDP",colorScale:["#edf8fb","#7bccc4","#0868ac"],domain:[1,10],format:a=>`${a.toFixed(1)}%`}};Zt.lifeExpectancy;const Ze=50,eo=`
622
627
  uniform float uMorph;