gralobe 1.0.13 → 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;
@@ -1155,5 +1160,5 @@ void main() {
1155
1160
 
1156
1161
  gl_FragColor = vec4(1.0, 1.0, 1.0, alpha * vOpacity * 0.9);
1157
1162
  }
1158
- `,Tr={satellite:"https://raw.githubusercontent.com/mrdoob/three.js/dev/examples/textures/planets/earth_atmos_2048.jpg",natural:"https://raw.githubusercontent.com/mrdoob/three.js/dev/examples/textures/planets/earth_day_4096.jpg",dark:"https://raw.githubusercontent.com/mrdoob/three.js/dev/examples/textures/planets/earth_lights_2048.png",light:"https://raw.githubusercontent.com/turban/webgl-earth/master/images/2_no_clouds_4k.jpg",night:"https://raw.githubusercontent.com/mrdoob/three.js/dev/examples/textures/planets/earth_lights_2048.png",topographic:"https://eoimages.gsfc.nasa.gov/images/imagerecords/74000/74117/world.topo.200407.3x5400x2700.jpg"},Dr={texture:"satellite",labels:"all",statistic:"lifeExpectancy",autoRotate:!1,initialView:"globe",showControls:!1,showLegend:!0,effects:{atmosphereIntensity:0,atmosphere:!1,clouds:!1,starTwinkle:!0},extrudeHeight:!1};class ao{container;config;scene;camera;renderer;controls;globe=null;material=null;atmosphere=null;stars=null;gui=null;choropleth=null;legend=null;exporter=null;countryLabels=null;textureLoader=new D.TextureLoader;dataTexture=null;morph=0;currentStatistic=null;animationId=null;isDestroyed=!1;ready;resolveReady;constructor(e,t={}){if(typeof e=="string"){const i=document.querySelector(e);if(!i)throw new Error(`Container not found: ${e}`);this.container=i}else this.container=e;this.config={...Dr,...t,effects:{...Dr.effects,...t.effects}},this.ready=new Promise(i=>{this.resolveReady=i}),this.init()}async init(){const e=this.config.width||this.container.clientWidth||800,t=this.config.height||this.container.clientHeight||600;this.scene=new D.Scene,this.scene.background=new D.Color(2066),this.camera=new D.PerspectiveCamera(50,e/t,1,1e3),this.camera.position.set(0,0,this.config.initialView==="flat"?350:150),this.renderer=new D.WebGLRenderer({antialias:!0}),this.renderer.setSize(e,t),this.renderer.setPixelRatio(Math.min(window.devicePixelRatio,2)),this.container.appendChild(this.renderer.domElement),this.controls=new Ir(this.camera,this.renderer.domElement),this.controls.enableDamping=!0,this.controls.minDistance=80,this.controls.maxDistance=400,this.choropleth=new Ca,this.config.showLegend&&(this.legend=new Sa(this.container)),await this.createGlobe(),this.createStars(),this.config.effects.atmosphere&&this.createAtmosphere(),this.countryLabels=new Ja(this.container,Ze),this.scene.add(this.countryLabels.getGroup()),this.globe&&this.countryLabels.setGlobe(this.globe),this.countryLabels.setCamera(this.camera),this.countryLabels.setStyle(this.config.labels),this.exporter=new ja(this.renderer,this.scene,this.camera),this.config.showControls&&this.createGUI(),await this.choropleth.waitForLoad(),this.setStatistic(this.config.statistic),this.morph=this.config.initialView==="globe"?1:0,this.material&&(this.material.uniforms.uMorph.value=this.morph),this.countryLabels?.setMorph(this.morph),window.addEventListener("resize",this.handleResize),document.addEventListener("fullscreenchange",this.handleFullscreenChange),window.addEventListener("keydown",this.handleKeydown),this.animate(),this.resolveReady()}async createGlobe(){const e=await this.textureLoader.loadAsync(Tr[this.config.texture]);e.anisotropy=this.renderer.capabilities.getMaxAnisotropy(),e.minFilter=D.LinearMipmapLinearFilter,e.magFilter=D.LinearFilter;const t=document.createElement("canvas");t.width=2048,t.height=1024,this.dataTexture=new D.CanvasTexture(t);const i=new D.PlaneGeometry(Math.PI*2*Ze,Math.PI*Ze,256,128);this.material=new D.ShaderMaterial({vertexShader:eo,fragmentShader:to,uniforms:{uMorph:{value:0},uTime:{value:0},uParchment:{value:0},uExtremeParchment:{value:0},uTransitionEffect:{value:0},uTexture:{value:e},uDataTexture:{value:this.dataTexture},uCloudTexture:{value:null},uNightTexture:{value:null},uDataOpacity:{value:0},uDataOverlay:{value:0},uExtrudeHeight:{value:this.config.extrudeHeight?1:0},uSunDir:{value:new D.Vector3(1,.5,1).normalize()},uClouds:{value:this.config.effects.clouds?1:0},uCloudSpeed:{value:this.config.effects.cloudSpeed||1},uCloudOpacity:{value:this.config.effects.cloudOpacity||.6},uAtmosphereIntensity:{value:this.config.effects.atmosphereIntensity||0},uAurora:{value:this.config.effects.aurora?1:0},uAuroraIntensity:{value:1},uCityLights:{value:this.config.effects.cityLights?1:0},uCityLightsIntensity:{value:1},uOceanSpecular:{value:this.config.effects.oceanSpecular?1:0},uSpecularIntensity:{value:1},uSunGlow:{value:0},uGridLines:{value:this.config.effects.gridLines?1:0},uGridOpacity:{value:this.config.effects.gridOpacity||.5},uScanEffect:{value:0},uScanSpeed:{value:1},uHologram:{value:this.config.effects.hologramMode?1:0},uHologramColor:{value:new D.Color(65535)},uVintage:{value:this.config.effects.vintageMode?1:0},uThermal:{value:this.config.effects.thermalMode?1:0},uBlueprint:{value:this.config.effects.blueprintMode?1:0},uGlowPulse:{value:this.config.effects.glowPulse?1:0},uGlowColor:{value:new D.Color(4491519)}},side:D.DoubleSide}),this.globe=new D.Mesh(i,this.material),this.scene.add(this.globe)}createAtmosphere(){const e=new D.PlaneGeometry(Math.PI*2*Ze*1.15,Math.PI*Ze*1.15,128,64),t=new D.ShaderMaterial({vertexShader:io,fragmentShader:no,uniforms:{uMorph:{value:0}},side:D.BackSide,transparent:!0,blending:D.AdditiveBlending,depthWrite:!1});this.atmosphere=new D.Mesh(e,t),this.scene.add(this.atmosphere)}createStars(){const t=new D.BufferGeometry,i=new Float32Array(3e3*3),n=new Float32Array(3e3),r=new Float32Array(3e3);for(let o=0;o<3e3;o++){const l=300+Math.random()*300,c=Math.random()*Math.PI*2,h=Math.acos(2*Math.random()-1);i[o*3]=l*Math.sin(h)*Math.cos(c),i[o*3+1]=l*Math.sin(h)*Math.sin(c),i[o*3+2]=l*Math.cos(h),n[o]=.5+Math.random()*1.5,r[o]=Math.random()*Math.PI*2}t.setAttribute("position",new D.BufferAttribute(i,3)),t.setAttribute("aSize",new D.BufferAttribute(n,1)),t.setAttribute("aPhase",new D.BufferAttribute(r,1));const s=new D.ShaderMaterial({vertexShader:ro,fragmentShader:so,uniforms:{uTime:{value:0},uTwinkle:{value:this.config.effects.starTwinkle?1:0}},transparent:!0,blending:D.AdditiveBlending,depthWrite:!1});this.stars=new D.Points(t,s),this.scene.add(this.stars)}createGUI(){this.gui=new Ni({title:"Globe Controls",width:300});const e=this.gui.addFolder("View");e.add({toGlobe:()=>this.toGlobe()},"toGlobe").name("→ Globe"),e.add({toFlat:()=>this.toFlat()},"toFlat").name("→ Flat Map"),e.add({morph:this.morph},"morph",0,1).name("Morph").onChange(r=>this.setMorph(r)),e.open();const t=this.gui.addFolder("Statistics"),i=Object.keys(Zt);t.add({stat:this.config.statistic},"stat",i).name("Statistic").onChange(r=>this.setStatistic(r)),t.open();const n=["none","minimal","major","all"];this.gui.add({labels:this.config.labels},"labels",n).name("Labels").onChange(r=>this.setLabels(r)),this.gui.add(this.config,"autoRotate").name("Auto Rotate")}handleResize=()=>{if(this.isDestroyed)return;const e=this.config.width||this.container.clientWidth,t=this.config.height||this.container.clientHeight;this.camera.aspect=e/t,this.camera.updateProjectionMatrix(),this.renderer.setSize(e,t),this.countryLabels?.resize(e,t)};handleFullscreenChange=()=>{this.isDestroyed||setTimeout(()=>this.handleResize(),50)};handleKeydown=e=>{this.isDestroyed||((e.key==="g"||e.key==="G")&&(this.morph>.5?this.toFlat():this.toGlobe()),(e.key==="f"||e.key==="F")&&this.toggleFullscreen())};animate=()=>{if(this.isDestroyed)return;this.animationId=requestAnimationFrame(this.animate);const e=performance.now()*.001;this.material&&(this.material.uniforms.uTime.value=e),this.stars&&(this.stars.material.uniforms.uTime.value=e),this.controls.update(),this.config.autoRotate&&this.globe&&(this.globe.rotation.y+=.002*this.morph),this.countryLabels?.update(),this.renderer.render(this.scene,this.camera),this.countryLabels?.render(this.scene,this.camera)};toGlobe(){wt.to(this,{morph:1,duration:2.5,ease:"power2.inOut",onUpdate:()=>{this.material&&(this.material.uniforms.uMorph.value=this.morph),this.atmosphere&&(this.atmosphere.material.uniforms.uMorph.value=this.morph),this.countryLabels?.setMorph(this.morph),this.config.onViewChange?.("globe",this.morph)}}),wt.to(this.camera.position,{z:150,duration:2.5,ease:"power2.inOut"})}toFlat(){wt.to(this,{morph:0,duration:2.5,ease:"power2.inOut",onUpdate:()=>{this.material&&(this.material.uniforms.uMorph.value=this.morph),this.atmosphere&&(this.atmosphere.material.uniforms.uMorph.value=this.morph),this.countryLabels?.setMorph(this.morph),this.config.onViewChange?.("flat",this.morph)}}),wt.to(this.camera.position,{z:350,duration:2.5,ease:"power2.inOut"})}setMorph(e){this.morph=Math.max(0,Math.min(1,e)),this.material&&(this.material.uniforms.uMorph.value=this.morph),this.atmosphere&&(this.atmosphere.material.uniforms.uMorph.value=this.morph),this.countryLabels?.setMorph(this.morph)}getMorph(){return this.morph}setStatistic(e){if(typeof e=="string"){if(!Zt[e]){console.warn(`Unknown statistic: ${e}`);return}this.currentStatistic=e;const i=va.find(n=>n.id===e);if(i&&this.choropleth){const n=this.choropleth.renderTexture(i);if(this.material&&n){const r=new D.CanvasTexture(n);r.needsUpdate=!0,this.material.uniforms.uDataTexture.value=r,this.material.uniforms.uDataOverlay.value=1,this.material.uniforms.uDataOpacity.value=.7}}this.legend&&i&&this.legend.show(i)}else{const t=e;if(this.currentStatistic=t.definition.id,this.choropleth){const i=this.choropleth.renderCustomTexture(t.values,t.definition.colorScale,t.definition.domain);if(this.material&&i){const n=new D.CanvasTexture(i);n.needsUpdate=!0,this.material.uniforms.uDataTexture.value=n,this.material.uniforms.uDataOverlay.value=1,this.material.uniforms.uDataOpacity.value=.7}}this.legend&&this.legend.show(t.definition)}}setLabels(e){this.countryLabels?.setStyle(e)}async setTexture(e){const t=Tr[e];if(!(!t||!this.material))try{const i=await this.textureLoader.loadAsync(t);i.anisotropy=this.renderer.capabilities.getMaxAnisotropy(),i.minFilter=D.LinearMipmapLinearFilter,i.magFilter=D.LinearFilter,this.material.uniforms.uTexture.value=i}catch(i){console.error("Failed to load texture:",e,i)}}setAutoRotate(e){this.config.autoRotate=e}screenshot(e){this.exporter?.screenshot(e)}async recordGif(e){if(!this.exporter)return;const t=e?.duration||5,i=e?.fps||20,n=t*i;this.exporter.startGifCapture(e);for(let r=0;r<n;r++)this.exporter.captureGifFrame(),await new Promise(s=>setTimeout(s,1e3/i));await this.exporter.stopGifCapture(e)}async recordVideo(e){if(!this.exporter)return;const t=e?.duration||5;await this.exporter.startVideoRecording(e),await new Promise(i=>setTimeout(i,t*1e3)),this.exporter.stopVideoRecording()}setEffects(e){Object.assign(this.config.effects,e),this.material&&(e.atmosphere!==void 0&&(e.atmosphere&&!this.atmosphere?this.createAtmosphere():!e.atmosphere&&this.atmosphere&&(this.scene.remove(this.atmosphere),this.atmosphere.geometry.dispose(),this.atmosphere.material.dispose(),this.atmosphere=null)),e.clouds!==void 0&&(this.material.uniforms.uClouds.value=e.clouds?1:0),e.cloudSpeed!==void 0&&(this.material.uniforms.uCloudSpeed.value=e.cloudSpeed),e.cloudOpacity!==void 0&&(this.material.uniforms.uCloudOpacity.value=e.cloudOpacity),e.atmosphereIntensity!==void 0&&(this.material.uniforms.uAtmosphereIntensity.value=e.atmosphereIntensity),e.gridLines!==void 0&&(this.material.uniforms.uGridLines.value=e.gridLines?1:0),e.gridOpacity!==void 0&&(this.material.uniforms.uGridOpacity.value=e.gridOpacity),e.glowPulse!==void 0&&(this.material.uniforms.uGlowPulse.value=e.glowPulse?1:0),e.starTwinkle!==void 0&&this.stars&&(this.stars.material.uniforms.uTwinkle.value=e.starTwinkle?1:0))}resize(e,t){this.config.width=e,this.config.height=t,this.handleResize()}async toggleFullscreen(){document.fullscreenElement?(await document.exitFullscreen(),setTimeout(()=>this.handleResize(),100)):(await this.container.requestFullscreen(),setTimeout(()=>this.handleResize(),100))}isFullscreen(){return document.fullscreenElement===this.container}destroy(){this.isDestroyed=!0,this.animationId&&cancelAnimationFrame(this.animationId),window.removeEventListener("resize",this.handleResize),window.removeEventListener("keydown",this.handleKeydown),document.removeEventListener("fullscreenchange",this.handleFullscreenChange),this.gui?.destroy(),this.legend?.dispose(),this.countryLabels?.dispose(),this.globe?.geometry.dispose(),this.globe?.material?.dispose(),this.atmosphere?.geometry.dispose(),this.atmosphere?.material?.dispose(),this.stars?.geometry.dispose(),this.stars?.material?.dispose(),this.renderer.dispose(),this.container.removeChild(this.renderer.domElement)}}ae.BUILT_IN_STATISTICS=Zt,ae.GlobeViz=ao,ae.WORLD_STATISTICS=$i,ae.createFormatter=Vi,ae.formatValue=Pa,ae.normalizeCountryValues=fr,ae.toNumericCode=Bi,Object.defineProperty(ae,Symbol.toStringTag,{value:"Module"})}));
1163
+ `,Tr={satellite:"https://raw.githubusercontent.com/mrdoob/three.js/dev/examples/textures/planets/earth_atmos_2048.jpg",natural:"https://raw.githubusercontent.com/mrdoob/three.js/dev/examples/textures/planets/earth_day_4096.jpg",dark:"https://raw.githubusercontent.com/mrdoob/three.js/dev/examples/textures/planets/earth_lights_2048.png",light:"https://raw.githubusercontent.com/turban/webgl-earth/master/images/2_no_clouds_4k.jpg",night:"https://raw.githubusercontent.com/mrdoob/three.js/dev/examples/textures/planets/earth_lights_2048.png",topographic:"https://eoimages.gsfc.nasa.gov/images/imagerecords/74000/74117/world.topo.200407.3x5400x2700.jpg"},Dr={texture:"satellite",labels:"all",statistic:"lifeExpectancy",autoRotate:!1,initialView:"globe",showControls:!1,showLegend:!0,effects:{atmosphereIntensity:0,atmosphere:!1,clouds:!1,starTwinkle:!0},extrudeHeight:!1};class ao{container;config;scene;camera;renderer;controls;globe=null;material=null;atmosphere=null;stars=null;gui=null;choropleth=null;legend=null;exporter=null;countryLabels=null;textureLoader=new D.TextureLoader;dataTexture=null;morph=0;currentStatistic=null;animationId=null;isDestroyed=!1;ready;resolveReady;constructor(e,t={}){if(typeof e=="string"){const i=document.querySelector(e);if(!i)throw new Error(`Container not found: ${e}`);this.container=i}else this.container=e;this.config={...Dr,...t,effects:{...Dr.effects,...t.effects}},this.ready=new Promise(i=>{this.resolveReady=i}),this.init()}async init(){const e=this.config.width||this.container.clientWidth||800,t=this.config.height||this.container.clientHeight||600;this.scene=new D.Scene,this.scene.background=new D.Color(2066),this.camera=new D.PerspectiveCamera(50,e/t,1,1e3),this.camera.position.set(0,0,this.config.initialView==="flat"?350:150),this.renderer=new D.WebGLRenderer({antialias:!0}),this.renderer.setSize(e,t),this.renderer.setPixelRatio(Math.min(window.devicePixelRatio,2)),this.container.appendChild(this.renderer.domElement),this.controls=new Ir(this.camera,this.renderer.domElement),this.controls.enableDamping=!0,this.controls.minDistance=80,this.controls.maxDistance=400,this.choropleth=new Ca,this.config.showLegend&&(this.legend=new Sa(this.container)),await this.createGlobe(),this.createStars(),this.config.effects.atmosphere&&this.createAtmosphere(),this.countryLabels=new Ja(this.container,Ze),this.scene.add(this.countryLabels.getGroup()),this.globe&&this.countryLabels.setGlobe(this.globe),this.countryLabels.setCamera(this.camera),this.countryLabels.setStyle(this.config.labels),this.exporter=new ja(this.renderer,this.scene,this.camera),this.config.showControls&&this.createGUI(),await this.choropleth.waitForLoad(),this.setStatistic(this.config.statistic),this.morph=this.config.initialView==="globe"?1:0,this.material&&(this.material.uniforms.uMorph.value=this.morph),this.countryLabels?.setMorph(this.morph),window.addEventListener("resize",this.handleResize),document.addEventListener("fullscreenchange",this.handleFullscreenChange),window.addEventListener("keydown",this.handleKeydown),this.animate(),this.resolveReady()}async createGlobe(){const e=await this.textureLoader.loadAsync(Tr[this.config.texture]);e.anisotropy=this.renderer.capabilities.getMaxAnisotropy(),e.minFilter=D.LinearMipmapLinearFilter,e.magFilter=D.LinearFilter;const t=document.createElement("canvas");t.width=2048,t.height=1024,this.dataTexture=new D.CanvasTexture(t);const i=new D.PlaneGeometry(Math.PI*2*Ze,Math.PI*Ze,256,128);this.material=new D.ShaderMaterial({vertexShader:eo,fragmentShader:to,uniforms:{uMorph:{value:0},uTime:{value:0},uParchment:{value:0},uExtremeParchment:{value:0},uTransitionEffect:{value:0},uTexture:{value:e},uDataTexture:{value:this.dataTexture},uCloudTexture:{value:null},uNightTexture:{value:null},uDataOpacity:{value:0},uDataOverlay:{value:0},uExtrudeHeight:{value:this.config.extrudeHeight?1:0},uSunDir:{value:new D.Vector3(1,.5,1).normalize()},uClouds:{value:this.config.effects.clouds?1:0},uCloudSpeed:{value:this.config.effects.cloudSpeed||1},uCloudOpacity:{value:this.config.effects.cloudOpacity||.6},uAtmosphereIntensity:{value:this.config.effects.atmosphereIntensity||0},uAurora:{value:this.config.effects.aurora?1:0},uAuroraIntensity:{value:1},uCityLights:{value:this.config.effects.cityLights?1:0},uCityLightsIntensity:{value:1},uOceanSpecular:{value:this.config.effects.oceanSpecular?1:0},uSpecularIntensity:{value:1},uSunGlow:{value:0},uGridLines:{value:this.config.effects.gridLines?1:0},uGridOpacity:{value:this.config.effects.gridOpacity||.5},uScanEffect:{value:0},uScanSpeed:{value:1},uHologram:{value:this.config.effects.hologramMode?1:0},uHologramColor:{value:new D.Color(65535)},uVintage:{value:this.config.effects.vintageMode?1:0},uThermal:{value:this.config.effects.thermalMode?1:0},uBlueprint:{value:this.config.effects.blueprintMode?1:0},uGlowPulse:{value:this.config.effects.glowPulse?1:0},uGlowColor:{value:new D.Color(4491519)}},side:D.DoubleSide}),this.globe=new D.Mesh(i,this.material),this.scene.add(this.globe)}createAtmosphere(){const e=new D.PlaneGeometry(Math.PI*2*Ze*1.15,Math.PI*Ze*1.15,128,64),t=new D.ShaderMaterial({vertexShader:io,fragmentShader:no,uniforms:{uMorph:{value:0}},side:D.BackSide,transparent:!0,blending:D.AdditiveBlending,depthWrite:!1});this.atmosphere=new D.Mesh(e,t),this.scene.add(this.atmosphere)}createStars(){const t=new D.BufferGeometry,i=new Float32Array(3e3*3),n=new Float32Array(3e3),r=new Float32Array(3e3);for(let o=0;o<3e3;o++){const l=300+Math.random()*300,c=Math.random()*Math.PI*2,h=Math.acos(2*Math.random()-1);i[o*3]=l*Math.sin(h)*Math.cos(c),i[o*3+1]=l*Math.sin(h)*Math.sin(c),i[o*3+2]=l*Math.cos(h),n[o]=.5+Math.random()*1.5,r[o]=Math.random()*Math.PI*2}t.setAttribute("position",new D.BufferAttribute(i,3)),t.setAttribute("aSize",new D.BufferAttribute(n,1)),t.setAttribute("aPhase",new D.BufferAttribute(r,1));const s=new D.ShaderMaterial({vertexShader:ro,fragmentShader:so,uniforms:{uTime:{value:0},uTwinkle:{value:this.config.effects.starTwinkle?1:0}},transparent:!0,blending:D.AdditiveBlending,depthWrite:!1});this.stars=new D.Points(t,s),this.scene.add(this.stars)}createGUI(){getComputedStyle(this.container).position==="static"&&(this.container.style.position="relative"),this.gui=new Ni({container:this.container,title:"⚙ Controls",width:220,closeFolders:!0});const t=this.gui.domElement;t.style.position="absolute",t.style.top="8px",t.style.right="8px",t.style.zIndex="100",this.gui.close();const i=this.gui.addFolder("View");i.add({toGlobe:()=>this.toGlobe()},"toGlobe").name("→ Globe"),i.add({toFlat:()=>this.toFlat()},"toFlat").name("→ Flat"),i.add({morph:this.morph},"morph",0,1).name("Morph").onChange(o=>this.setMorph(o));const n=this.gui.addFolder("Statistics"),r=Object.keys(Zt);n.add({stat:this.config.statistic},"stat",r).name("Statistic").onChange(o=>this.setStatistic(o));const s=["none","minimal","major","all"];this.gui.addFolder("Display").add({labels:this.config.labels},"labels",s).name("Labels").onChange(o=>this.setLabels(o)),this.gui.add(this.config,"autoRotate").name("Auto Rotate")}handleResize=()=>{if(this.isDestroyed)return;const e=this.config.width||this.container.clientWidth,t=this.config.height||this.container.clientHeight;this.camera.aspect=e/t,this.camera.updateProjectionMatrix(),this.renderer.setSize(e,t),this.countryLabels?.resize(e,t)};handleFullscreenChange=()=>{this.isDestroyed||setTimeout(()=>this.handleResize(),50)};handleKeydown=e=>{this.isDestroyed||((e.key==="g"||e.key==="G")&&(this.morph>.5?this.toFlat():this.toGlobe()),(e.key==="f"||e.key==="F")&&this.toggleFullscreen())};animate=()=>{if(this.isDestroyed)return;this.animationId=requestAnimationFrame(this.animate);const e=performance.now()*.001;this.material&&(this.material.uniforms.uTime.value=e),this.stars&&(this.stars.material.uniforms.uTime.value=e),this.controls.update(),this.config.autoRotate&&this.globe&&(this.globe.rotation.y+=.002*this.morph),this.countryLabels?.update(),this.renderer.render(this.scene,this.camera),this.countryLabels?.render(this.scene,this.camera)};toGlobe(){wt.to(this,{morph:1,duration:2.5,ease:"power2.inOut",onUpdate:()=>{this.material&&(this.material.uniforms.uMorph.value=this.morph),this.atmosphere&&(this.atmosphere.material.uniforms.uMorph.value=this.morph),this.countryLabels?.setMorph(this.morph),this.config.onViewChange?.("globe",this.morph)}}),wt.to(this.camera.position,{z:150,duration:2.5,ease:"power2.inOut"})}toFlat(){wt.to(this,{morph:0,duration:2.5,ease:"power2.inOut",onUpdate:()=>{this.material&&(this.material.uniforms.uMorph.value=this.morph),this.atmosphere&&(this.atmosphere.material.uniforms.uMorph.value=this.morph),this.countryLabels?.setMorph(this.morph),this.config.onViewChange?.("flat",this.morph)}}),wt.to(this.camera.position,{z:350,duration:2.5,ease:"power2.inOut"})}setMorph(e){this.morph=Math.max(0,Math.min(1,e)),this.material&&(this.material.uniforms.uMorph.value=this.morph),this.atmosphere&&(this.atmosphere.material.uniforms.uMorph.value=this.morph),this.countryLabels?.setMorph(this.morph)}getMorph(){return this.morph}setStatistic(e){if(typeof e=="string"){if(!Zt[e]){console.warn(`Unknown statistic: ${e}`);return}this.currentStatistic=e;const i=va.find(n=>n.id===e);if(i&&this.choropleth){const n=this.choropleth.renderTexture(i);if(this.material&&n){const r=new D.CanvasTexture(n);r.needsUpdate=!0,this.material.uniforms.uDataTexture.value=r,this.material.uniforms.uDataOverlay.value=1,this.material.uniforms.uDataOpacity.value=.7}}this.legend&&i&&this.legend.show(i)}else{const t=e;if(this.currentStatistic=t.definition.id,this.choropleth){const i=this.choropleth.renderCustomTexture(t.values,t.definition.colorScale,t.definition.domain);if(this.material&&i){const n=new D.CanvasTexture(i);n.needsUpdate=!0,this.material.uniforms.uDataTexture.value=n,this.material.uniforms.uDataOverlay.value=1,this.material.uniforms.uDataOpacity.value=.7}}this.legend&&this.legend.show(t.definition)}}setLabels(e){this.countryLabels?.setStyle(e)}async setTexture(e){const t=Tr[e];if(!(!t||!this.material))try{const i=await this.textureLoader.loadAsync(t);i.anisotropy=this.renderer.capabilities.getMaxAnisotropy(),i.minFilter=D.LinearMipmapLinearFilter,i.magFilter=D.LinearFilter,this.material.uniforms.uTexture.value=i}catch(i){console.error("Failed to load texture:",e,i)}}setAutoRotate(e){this.config.autoRotate=e}screenshot(e){this.exporter?.screenshot(e)}async recordGif(e){if(!this.exporter)return;const t=e?.duration||5,i=e?.fps||20,n=t*i;this.exporter.startGifCapture(e);for(let r=0;r<n;r++)this.exporter.captureGifFrame(),await new Promise(s=>setTimeout(s,1e3/i));await this.exporter.stopGifCapture(e)}async recordVideo(e){if(!this.exporter)return;const t=e?.duration||5;await this.exporter.startVideoRecording(e),await new Promise(i=>setTimeout(i,t*1e3)),this.exporter.stopVideoRecording()}setEffects(e){Object.assign(this.config.effects,e),this.material&&(e.atmosphere!==void 0&&(e.atmosphere&&!this.atmosphere?this.createAtmosphere():!e.atmosphere&&this.atmosphere&&(this.scene.remove(this.atmosphere),this.atmosphere.geometry.dispose(),this.atmosphere.material.dispose(),this.atmosphere=null)),e.clouds!==void 0&&(this.material.uniforms.uClouds.value=e.clouds?1:0),e.cloudSpeed!==void 0&&(this.material.uniforms.uCloudSpeed.value=e.cloudSpeed),e.cloudOpacity!==void 0&&(this.material.uniforms.uCloudOpacity.value=e.cloudOpacity),e.atmosphereIntensity!==void 0&&(this.material.uniforms.uAtmosphereIntensity.value=e.atmosphereIntensity),e.gridLines!==void 0&&(this.material.uniforms.uGridLines.value=e.gridLines?1:0),e.gridOpacity!==void 0&&(this.material.uniforms.uGridOpacity.value=e.gridOpacity),e.glowPulse!==void 0&&(this.material.uniforms.uGlowPulse.value=e.glowPulse?1:0),e.starTwinkle!==void 0&&this.stars&&(this.stars.material.uniforms.uTwinkle.value=e.starTwinkle?1:0))}resize(e,t){this.config.width=e,this.config.height=t,this.handleResize()}async toggleFullscreen(){document.fullscreenElement?(await document.exitFullscreen(),setTimeout(()=>this.handleResize(),100)):(await this.container.requestFullscreen(),setTimeout(()=>this.handleResize(),100))}isFullscreen(){return document.fullscreenElement===this.container}destroy(){this.isDestroyed=!0,this.animationId&&cancelAnimationFrame(this.animationId),window.removeEventListener("resize",this.handleResize),window.removeEventListener("keydown",this.handleKeydown),document.removeEventListener("fullscreenchange",this.handleFullscreenChange),this.gui?.destroy(),this.legend?.dispose(),this.countryLabels?.dispose(),this.globe?.geometry.dispose(),this.globe?.material?.dispose(),this.atmosphere?.geometry.dispose(),this.atmosphere?.material?.dispose(),this.stars?.geometry.dispose(),this.stars?.material?.dispose(),this.renderer.dispose(),this.container.removeChild(this.renderer.domElement)}}ae.BUILT_IN_STATISTICS=Zt,ae.GlobeViz=ao,ae.WORLD_STATISTICS=$i,ae.createFormatter=Vi,ae.formatValue=Pa,ae.normalizeCountryValues=fr,ae.toNumericCode=Bi,Object.defineProperty(ae,Symbol.toStringTag,{value:"Module"})}));
1159
1164
  //# sourceMappingURL=gralobe.umd.cjs.map