@xyo-network/react-map 2.78.0 → 2.78.2

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.
@@ -1,3 +1,1308 @@
1
- var A=()=>({debugLayer:{devMode:!0,field:"debugLayer",hidden:!0,label:"Debug Layer",value:!1},debugLogging:{devMode:!0,field:"debugLogging",hidden:!0,label:"Debug Logging",value:!1},dynamicMapResize:{devMode:!0,field:"dynamicMapResize",hidden:!0,label:"Auto Map Resize",value:!0},enableControls:{devMode:!0,field:"enableControls",hidden:!0,label:"Map Controls",value:!1},fitToPoints:{devMode:!0,field:"fitToPoints",hidden:!0,label:"Fit To Points",value:!1},preferDark:{devMode:!1,field:"preferDark",hidden:!0,label:"Prefer dark",value:!1},scrollToZoom:{devMode:!0,field:"scrollToZoom",hidden:!0,label:"Scroll To Zoom",value:!1}});var K=A(),{debugLayer:We,scrollToZoom:qe,fitToPoints:Ze,preferDark:Ue}=K;We.hidden=!1;qe.value=!0;Ze.value=!1;Ue.value=!0;import{darken as oo,useTheme as ro}from"@mui/material";import{FlexCol as ao}from"@xylabs/react-flexbox";import{useState as no}from"react";import{forget as Ht}from"@xylabs/forget";import{useEffect as D,useState as kt}from"react";import{useEffect as ne,useMemo as Ke,useState as Xe}from"react";var ie=(r,e,o,t=!0)=>{let[a,n]=Xe(!1),i=Ke(()=>new ResizeObserver(()=>{let s=r.current?.getBoundingClientRect().width;s&&e.current&&(e.current.style.width=`${s}px`,setTimeout(()=>o?.resize()))}),[e,r,o]);ne(()=>{let s=!!(t&&o&&r?.current&&e.current);n(s)},[t,e,r,o]),ne(()=>{if(a)return r.current&&i.observe(r.current),()=>{i.disconnect()}},[t,a,e,r,o,i])};import{useWindowSize as Ye}from"@xylabs/react-shared";import{useEffect as Ve,useState as je}from"react";var et=1.6,tt=[.5,2],ot=[.9121644205263664,1.71785031559439],rt=[-81.4742014851959,12.788958675506933],se=(r,e,o)=>{let[t,a]=e,[n,i]=o||tt,s=i-n,c=a-t;return(r-n)/s*c+t},ce=()=>{let[r,e]=je({}),{width:o,height:t}=Ye();return Ve(()=>{if(o&&t){let a=o/t;e({center:[se(a,rt),se(a,ot)],zoom:et})}},[t,o]),{options:r}};import{useNetwork as at}from"@xyo-network/react-network";import{useMemo as nt}from"react";var it=["79af071f451fc7af10d009dc63236ef9a9b211732c1ee0c06f028fcecf2336c5","531bfba6d8dfefd3bcc888aca54cdbbd4574ed2b3ec551b230845a1f9a608898","c874412b4faa4947de81372fd1ba12fdd6f43f5e408622b7f357cb2bcb3f17cb","29d3f8b882c61a82a1a1675782a27e797ea7196f45a23b4409680ab8b8d5f14e","cfd20f80ac073fd9518f4ef3f43d2a1f5e4e56e40c2677f38d6f6fecd05df60c","1354fa73497519a39aed19fc99bdbae78a880a1eafb2f7898d607e07db36528d","1043b0d25eacfc5013ae9dba780305a6fbf01a43543bd871d7c00537fca142a9","973dfc5df142851ced258d52d0ac2784e814000ac22e35776f772256b0d4dde9","463808eb74d3d87e6563970e0301a493577f8cd1b501e6e0ffa5e027ad2cea95","15b21acea2e3fd9d1ace3768a72636ee7bdf67a6f8e0807bfa2273dea2207555","32d377bfe7ebe382598c54dd13f8af7510e0a1e2fd2e913311fdd58e517e5e2e,"],st="c7bbf61f61cfd4a1b2def160c28136fc1d100d39fbdb67b227a2c6e558d9d3a5",le=()=>{let{network:r}=at(),e=r?.nodes?.find(n=>n.type==="archivist")?.explorerMapHashes,o=e?.animatedAnswerHashes||it,t=e?.staticAnswerHash||st;return nt(()=>[t,...o],[o,t])};import{useTheme as ct}from"@mui/material";var pe=()=>{let r=ct(),e="#FFFF75",o="#FF0000",t={highUsageColor:o,lowUsageColor:"#FFB3B3",staticMapColor:e},a={endColor:o,endLabel:"High",heading:"Network Usage",startColor:e,startLabel:"Low",textColor:r.palette.common.white};return{heatMapColorProps:t,legendProps:a}};import{compact as lt}from"@xylabs/lodash";import{GeoJson as pt}from"@xyo-network/sdk-geo";import{useEffect as mt,useState as X}from"react";var me=({density:r,quadkey:e})=>{let o=new pt(e).polygonFeature();return o.properties={count:r,density:r},o},ue=r=>(r.properties&&(r.properties.value=r.properties.density/5),r),de=r=>{let[e,o]=X([[]]),[t,a]=X([]),[n,i]=X();return mt(()=>{if(Array.isArray(r))if(lt(r).length>0){let s=r?.map(c=>c?.result.map(me));o(s.map(c=>c?.map(ue)??[]))}else i(new Error("Cannot find payloads for provided hashes"));if(r&&r.result){let c=r.result.map(me);a(c.map(ue))}},[r]),{error:n,features:t,multipleFeatureSets:e}};import{assertEx as ut}from"@xylabs/assert";import{GeoJson as fe}from"@xyo-network/sdk-geo";var P=class{_config;constructor(e){this._config={requestLocation:!0,zoom:2,...e}}get isMapReady(){return!!this._config.map}initializeMapSource(e){let o=()=>{let n=fe.featureCollection(this._config.features);return fe.featuresSource(n)},t=this._config.map.getSource(e.source),a=o();return t?t.setData(ut(a.data)):this._config.map.addSource(e.source,a),e.update(this._config.map,!0),this}};import{assertEx as ge}from"@xylabs/assert";import{delay as Y}from"@xylabs/delay";import{forget as ye}from"@xylabs/forget";import{GeoJson as B}from"@xyo-network/sdk-geo";import{LngLatBounds as dt}from"mapbox-gl";var C=class extends P{static animationStarted=!1;config;constructor(e){super(e),this.config=e}static initialMapPositioning(e,o,t,a){if(!t)return;let n;return a?n=a:(n=new dt,t.forEach(i=>{for(let s of i.geometry.coordinates)for(let c of s)n.extend(c)})),o.setCenter(n.getCenter()),o.fitBounds(n,e),this}static async initializeAnimatedHeatMapSource(e,o,t,a,n){this.animationStarted=!0;let i=0,s=0,c=o.map(y=>{let L=B.featureCollection(y);return B.featuresSource(L)});this.updateLayer(t,e[0],c[0]),this.updateLayer(t,e[1],c[1]);for(let y of e)t.setPaintProperty(y.id,"fill-opacity",0);let l=3e3,m=.5,g=10,p=30,u=l/p,d=a??"#FFB3B3",f=n??"#FF0000",b=(y,L,M)=>{let U=Math.sin(M/p*Math.PI/2),Je=Math.cos(M/p*Math.PI/2),$e=y+y*U,Qe=L*Je;return["let","density",["+",["/",["number",["get","value"]],$e],Qe],["interpolate",["linear"],["var","density"],0,d,.5,f]]},S=e.map(y=>!1),Ee=async(y,L)=>{for(let M=p;M>=1;M--)t.setPaintProperty(y,"fill-color",b(g,m,M*(180/u))),await Y(u);S[L]=!0},_e=async(y,L)=>{for(let M=1;M<=p;M++)t.setPaintProperty(y,"fill-color",b(g,m,M*(180/u))),await Y(u);S[L]=!1},ae=!1;await(async()=>{for(ge(!ae,()=>"Animation Already Started"),ae=!0;this.animationStarted;){let y=i%e.length,L=(i+1)%e.length,M=s%o.length,U=(s+1)%o.length;for(S[y]&&(this.updateLayer(t,e[y],c[M]),ye(_e(e[y].id,y))),S[L]||(this.updateLayer(t,e[L],c[U]),ye(Ee(e[L].id,L)));(S[y]||!S[L])&&this.animationStarted;)await Y(1e3);i++,s++}})()}static updateLayer(e,o,t){let a=e.getSource(o.source);a&&t.data?a.setData(t.data):t&&e.addSource(o.source,t),o.update(e,!0)}initializeHeatMapSource(e){let o=t=>{let a=B.featureCollection(this.config.features);return B.featuresSource(a)};for(let[t,a]of e.entries()){let n=this.config.map.getSource(a.source),i=o(t);n?n.setData(ge(i.data)):this.config.map.addSource(a.source,i),a.update(this.config.map,!0)}return this}};import{LngLatBounds as ft}from"mapbox-gl";var T=class extends P{config;constructor(e){super(e),this.config=e}initialMapPositioning(e,o){let t;return o?t=o:(t=new ft,this.config.features.forEach(a=>{t.extend(a.geometry.coordinates)})),this.config.map.setCenter(t.getCenter()),this.config.map.fitBounds(t,e),this.config.map}};import{GeolocateControl as gt,NavigationControl as yt}from"mapbox-gl";var I=class r{static geoLocateControl;static mapListeners={logData:(e,o)=>{let t=o||e?.target;t&&(console.log("zoom",t.getZoom()),console.log("center",t.getCenter()))}};static navControl;static requestLocation;static toggleControls(e,o,t,a){return e?r.addControls(o,t,a):r.removeControls(o),this}static toggleDebugLayer(e,o,t){return o.getLayer(t)&&(e?o.setLayoutProperty(t,"visibility","visible"):o.setLayoutProperty(t,"visibility","none")),this}static toggleDebugLogging(e,o){let t=["resize","zoomend","dragend"];if(e){this.mapListeners.logData(void 0,o);for(let a of t)o.on(a,this.mapListeners.logData)}else for(let a of t)o.off(a,this.mapListeners.logData)}static toggleScrollToZoom(e,o){return e?o.scrollZoom.enable():o.scrollZoom.disable(),this}static updateSettings(e){let{settings:o,map:t,zoom:a,requestLocation:n,debugLayerName:i=""}=e,{scrollToZoom:s,enableControls:c,debugLayer:l,debugLogging:m}=o;r.toggleControls(c?.value,t,a,n).toggleScrollToZoom(s?.value,t).toggleDebugLayer(l?.value,t,i).toggleDebugLogging(m.value,t)}static addControls(e,o,t){let a=new gt({fitBoundsOptions:{zoom:o||2},positionOptions:{enableHighAccuracy:!0},trackUserLocation:!0}),n=new yt({showCompass:!1});return this.geoLocateControl=this.geoLocateControl||a,this.navControl=this.navControl||n,!e.hasControl(this.geoLocateControl)&&t&&e.addControl(this.geoLocateControl),e.hasControl(this.navControl)||e.addControl(this.navControl,"top-left"),this}static removeControls(e){return this.geoLocateControl&&e.hasControl(this.geoLocateControl)&&this.requestLocation&&e.removeControl(this.geoLocateControl),this.navControl&&e.hasControl(this.navControl)&&e.removeControl(this.navControl),this}};import{useEffect as Mt,useState as Le}from"react";import{createContext as Lt}from"react";var N=Lt({});import{jsx as ht}from"react/jsx-runtime";var Me=({children:r})=>{let[e,o]=Le(),[t,a]=Le(!1),n={map:e,mapInitialized:t,setMapBoxInstance:o};return Mt(()=>{!t&&e&&e?.on("load",()=>{a(!0)})},[e,t,a]),ht(N.Provider,{value:n,children:r})};import{assertEx as xt}from"@xylabs/assert";import{useContext as bt}from"react";var x=()=>{let r=bt(N);return xt("map"in r,()=>"useMapBoxInstance must be used within a MapBoxInstanceContext"),r};import{useEffect as St,useState as Pt}from"react";import{createContext as Ct}from"react";var O=Ct({});import{jsx as Ft}from"react/jsx-runtime";var he=({children:r,debugLayerName:e,defaultMapSettings:o,requestLocation:t,zoom:a=1})=>{let[n,i]=Pt(o||{}),{map:s,mapInitialized:c}=x(),l={mapSettings:n,setMapSettings:i};return St(()=>{n&&s&&c&&I.updateSettings({debugLayerName:e,map:s,requestLocation:t,settings:n,zoom:a})},[e,s,c,n,t,a]),Ft(O.Provider,{value:l,children:r})};import{useContext as wt}from"react";var h=()=>wt(O);import{createContext as vt}from"react";var G=vt({});import{jsx as At}from"react/jsx-runtime";var xe=({children:r,featureSets:e,featureSetsLayers:o,features:t,fitToPadding:a,heatMapColorProps:n,layers:i,zoom:s})=>{let[c,l]=kt(),{options:m}=ce(),{mapSettings:g}=h(),{map:p,mapInitialized:u}=x(),d={MapHeat:c,heatMapColorProps:n};return D(()=>{if(u&&e?.length&&e[0].length>0&&p&&o?.length){let{lowUsageColor:f,highUsageColor:b}=n;Ht(C.initializeAnimatedHeatMapSource(o,e,p,f,b))}return()=>{C.animationStarted=!1}},[e,o,u,p,n]),D(()=>{c&&u&&t?.length&&i?.length&&c.initializeHeatMapSource(i)},[c,t?.length,i,u]),D(()=>{if(u){let{fitToPoints:f}=g||{};p&&(f?.value===!0?C.initialMapPositioning({padding:a},p,t):m.zoom&&m.center&&(p.setZoom(m.zoom),p.setCenter(m.center)))}},[c,p,g,a,m,u,t]),D(()=>{p&&t?.length&&l(new C({features:t,map:p,zoom:s}))},[p,t,s]),At(G.Provider,{value:d,children:r})};import{assertEx as Bt}from"@xylabs/assert";import{useContext as Tt}from"react";var ia=()=>{let r=Tt(G);return Bt("heatMapInitialized"in r,()=>"useHeatMapInitializer must be used within a HeatMapInitializerContext"),r};import{createContextEx as It}from"@xyo-network/react-shared";var R=It();import{useState as Nt}from"react";import{jsx as Ot}from"react/jsx-runtime";var ua=({defaultAccessToken:r,...e})=>{let[o,t]=Nt();return Ot(R.Provider,{value:{accessToken:o??r,provided:!0,setAccessToken:t},...e})};import{useContextEx as Gt}from"@xyo-network/react-shared";var La=(r=!1)=>Gt(R,"MapboxAccessToken",r);var z=r=>({paint:{"fill-color":r,"fill-opacity":["let","density",["+",["/",["number",["get","value"]],4],.125],["interpolate",["linear"],["var","density"],.8,["var","density"],1,.85]]}});var be=r=>({layout:{visibility:"none"},paint:{"line-color":r,"line-opacity":["let","density",0,["interpolate",["linear"],["var","density"],.8,["var","density"],1,.85]],"line-width":.5}});var Ce=r=>({layout:{"text-anchor":"center","text-field":["concat","value: ",["to-string",["+",["/",["number",["get","value"]],2],.25]],`
2
- `,"count: ",["to-string",["get","count"]]],"text-size":10,visibility:"none"},paint:{"text-color":r}});var Se=(r,e,o)=>({paint:{"circle-color":r,"circle-opacity":o,"circle-radius":e}});import{LayerBase as Dt}from"@xyo-network/sdk-geo";var F=class extends Dt{FillLayerOptions;type="fill";constructor(e,o,t){super(e,o),this.FillLayerOptions=t||{id:this.id,source:this.source}}buildLayer(){return{...this.FillLayerOptions,id:this.id,source:this.source,type:this.type}}};import{LayerBase as Rt}from"@xyo-network/sdk-geo";var E=class extends Rt{LineLayerOptions;type="line";constructor(e,o,t){super(e,o),this.LineLayerOptions=t||{id:this.id,source:this.source}}buildLayer(){return{...this.LineLayerOptions,id:this.id,layout:{},source:this.source,type:this.type}}};import{LayerBase as zt}from"@xyo-network/sdk-geo";var _=class extends zt{SymbolLayerOptions;type="symbol";constructor(e,o,t){super(e,o),this.SymbolLayerOptions=t||{id:this.id,source:this.source}}buildLayer(){return{...this.SymbolLayerOptions,id:this.id,source:this.source,type:this.type}}};var V={LocationDebugLayerId:"location-debug-id",LocationDebugLayerSource:"location-debug-source",LocationFillLayerId:"location-fill-id",LocationFillLayerSource:"location-fill-source",LocationLineLayerId:"location-line-id",LocationLineLayerSource:"location-line-source"},Ia=(r,e="#000")=>{let{LocationFillLayerId:o,LocationFillLayerSource:t,LocationLineLayerId:a,LocationLineLayerSource:n,LocationDebugLayerId:i,LocationDebugLayerSource:s}=V,c=z(r),l=be(r),m=Ce(e),g=new F(o,t,c),p=new E(a,n,l),u=new _(i,s,m);return[g,p,u]};var Et=(r,e)=>({LocationDebugLayerId:`location-${e}-debug-id-${r}`,LocationDebugLayerSource:`location-${e}-debug-source-${r}`,LocationFillLayerId:`location-${e}-fill-id-${r}`,LocationFillLayerSource:`location-${e}-fill-source-${r}`,LocationLineLayerId:`location-${e}-line-id-${r}`,LocationLineLayerSource:`location-${e}-line-source-${r}`}),J=(r,e,o="")=>{let{LocationFillLayerId:t,LocationFillLayerSource:a}=Et(e,o),n=z(r);return new F(t,a,n)};import{LayerBase as _t}from"@xyo-network/sdk-geo";var $=class extends _t{CircleLayerOptions;type="circle";constructor(e,o,t){super(e,o),this.CircleLayerOptions=t||{id:this.id,source:this.source,type:"circle"}}buildLayer(){return{filter:["==","$type","Point"],layout:{},paint:{"circle-color":"#ff0000","circle-radius":6},type:this.type,...this.CircleLayerOptions,id:this.id,source:this.source}}};var Jt={LocationDotsLayerId:"location-dots",LocationDotsLayerSource:"location-dots-source"},Ja=(r,e=6,o=.8)=>{let{LocationDotsLayerId:t,LocationDotsLayerSource:a}=Jt,n=Se(r,e,o);return[new $(t,a,n)]};import{FlexCol as eo}from"@xylabs/react-flexbox";import"mapbox-gl/dist/mapbox-gl.css";import{Map as Qt}from"mapbox-gl";import{useEffect as Pe,useRef as Fe,useState as Wt}from"react";var $t=(i=>(i.Dark="mapbox/dark-v10",i.Light="mapbox/light-v10",i.Outdoors="mapbox/outdoors-v11",i.Satellite="mapbox/satellite-v9",i.SatelliteStreets="mapbox/satellite-streets-v11",i.Streets="mapbox/streets-v11",i))($t||{});import{jsx as qt}from"react/jsx-runtime";var Q=({accessToken:r,darkMode:e=!1,options:o,zoom:t=2,...a})=>{let[n,i]=Wt(),s=Fe(null),c=Fe(null),{setMapBoxInstance:l,map:m}=x(),{mapSettings:g}=h(),p=g?.dynamicMapResize.value;return ie(s,c,m,p),Pe(()=>{g?.preferDark?.value===!0?n?.setStyle("mapbox://styles/mapbox/dark-v10"):n?.setStyle(`mapbox://styles/${e?"mapbox/dark-v10":"mapbox/light-v10"}`)},[n,e,g]),Pe(()=>{let u=new Qt({accessToken:r,center:[0,0],container:s.current??"",style:"mapbox://styles/mapbox/light-v10",zoom:t,...o});return l?.(u),i(u),c.current=document.querySelector(".mapboxgl-canvas"),console.log("Created Map"),()=>{console.log("Removing Map"),u.remove()}},[s,i,o,t,l,r]),qt("div",{ref:u=>s.current=u,style:{bottom:0,left:0,position:"absolute",right:0,top:0,...a}})};import{FormControlLabel as Zt,Switch as Ut}from"@mui/material";import{jsx as we}from"react/jsx-runtime";var ve=({developerMode:r,field:e,...o})=>{let{mapSettings:t,setMapSettings:a}=h(),n=t?.[e],i=s=>{n&&a?.(c=>(c[n.field].value=s.target.checked,{...c}))};return n?.devMode&&r===!1||n?.hidden?null:we(Zt,{label:n?.label,control:we(Ut,{checked:n?.value,onChange:i,...o})})};import{Paper as Kt,Stack as Xt}from"@mui/material";import{FlexGrowRow as Yt,FlexRow as Vt}from"@xylabs/react-flexbox";import{useAppSettings as jt}from"@xyo-network/react-app-settings";import{jsx as v}from"react/jsx-runtime";var W=({developerMode:r,...e})=>{let{mapSettings:o}=h(),{developerMode:t}=jt();return o&&(r??t)?v(Yt,{bottom:36,left:10,position:"absolute",...e,children:v(Vt,{paddingX:2,children:v(Kt,{children:v(Xt,{direction:"row",spacing:1,marginX:1,children:Object.keys(o).map((n,i)=>v(ve,{field:o[n].field,developerMode:r},i))})})})}):null};import{jsx as He,jsxs as to}from"react/jsx-runtime";var ke=({accessToken:r,children:e,mapBoxOptions:o,zoom:t,legend:a,developerMode:n,...i})=>to(eo,{...i,children:[He(Q,{accessToken:r,options:o,zoom:t}),He(W,{developerMode:n}),a,e]});import{jsx as H}from"react/jsx-runtime";var Ae=({accessToken:r,animatedFeatureSets:e,defaultMapSettings:o,heatMapColorProps:t,staticFeatureSet:a,...n})=>{let i=ro(),{staticMapColor:s,lowUsageColor:c,highUsageColor:l}=t||{},m=s??i.palette.primary.light,[g]=no([J(m,0,"static"),J(c||m,0,"animated"),J(l||oo(m,.9),1,"animated")]);return e?.length?H(Me,{children:H(he,{defaultMapSettings:o,debugLayerName:V.LocationDebugLayerId,children:H(xe,{features:a,layers:[g[0]],featureSets:e,featureSetsLayers:g.slice(1,3),heatMapColorProps:t,children:H(ke,{accessToken:r,...n})})})}):H(ao,{minHeight:160,minWidth:160,busy:!0})};import{Alert as Oe,AlertTitle as mo}from"@mui/material";import{FlexCol as uo}from"@xylabs/react-flexbox";import{useWeakArchivistFromNode as fo,useWeakArchivistGet as go}from"@xyo-network/react-archivist";import{useMediaQuery as co,useTheme as lo}from"@mui/material";import{FlexCol as po}from"@xylabs/react-flexbox";import{Typography as j,useTheme as io}from"@mui/material";import{FlexCol as ee,FlexRow as so}from"@xylabs/react-flexbox";import{jsx as k,jsxs as Be}from"react/jsx-runtime";var Te=({startColor:r,endColor:e,startLabel:o,endLabel:t,heading:a,textColor:n,...i})=>{let s=io();return Be(ee,{...i,children:[k(j,{mb:s.spacing(.25),color:n,variant:"caption",textAlign:"center",children:a}),k(ee,{flexGrow:1,alignItems:"stretch",paddingX:s.spacing(1),mb:s.spacing(.25),children:k(ee,{height:s.spacing(.75),border:`1px solid ${n}`,sx:{backgroundImage:`linear-gradient(to right, ${r},${e})`}})}),Be(so,{flexGrow:1,justifyContent:"space-between",children:[k(j,{color:n,variant:"caption",children:o}),k(j,{color:n,variant:"caption",children:t})]})]})};import{jsx as Ie}from"react/jsx-runtime";var Ne=({...r})=>{let{startColor:e,endColor:o,startLabel:t,endLabel:a,heading:n,textColor:i}=r,s=lo(),c=co(s.breakpoints.down("sm"));return Ie(po,{position:"absolute",bottom:0,right:0,children:Ie(Te,{startColor:e,endColor:o,startLabel:t,endLabel:a,heading:n,textColor:i,alignItems:"stretch",marginBottom:s.spacing(4),marginLeft:c?s.spacing(3):0,marginRight:c?s.spacing(2):s.spacing(3),width:c?"40vw":s.spacing(18)})})};import{jsx as q,jsxs as Ge}from"react/jsx-runtime";var Qn=({accessToken:r,archivistNameOrAddress:e,...o})=>{let t=le(),[a]=fo(e),[n,i]=go(a,t),{multipleFeatureSets:s}=de(n),{heatMapColorProps:c,legendProps:l}=pe(),m={flexGrow:1,legend:l?q(Ne,{...l}):null};return Ge(uo,{alignItems:"stretch",...o,children:[i?Ge(Oe,{sx:{mt:2},children:[q(mo,{children:"Error Loading Map"}),i.message?`Error: ${i.message}`:null,"You might try authenticating again."]}):null,t===void 0?q(Oe,{children:"Missing answer hash for heat map query"}):q(Ae,{accessToken:r,defaultMapSettings:K,animatedFeatureSets:s.slice(1,s.length),staticFeatureSet:s[0],heatMapColorProps:c,...m})]})};var yo=A(),{debugLayer:Lo,scrollToZoom:Mo,fitToPoints:ho}=yo;Lo.hidden=!1;Mo.value=!0;ho.value=!0;import{useInterval as xo}from"@xylabs/react-shared";import{useCallback as w,useEffect as De,useRef as bo,useState as Co}from"react";import{Fragment as So,jsx as Po}from"react/jsx-runtime";var te=2e3,Re=3,Vn=({animateLayers:r,children:e,layers:o,layersInitialized:t,map:a})=>{let[n,i]=Co([]),s=bo([]),c=w(d=>(n[d]?s.current.push(d):s.current.push(0),s.current.at(-1)),[n]),l=w(()=>{let d=s.current.at(-1);return d===void 0?(c(0),0):d},[c]),m=w(()=>{s.current.shift()},[]),g=w(()=>{let d=n[l()];return c(l()+1),d},[n,c,l]),p=w(d=>{d?(a?.setPaintProperty(d.id,"fill-opacity",.85),setTimeout(()=>{a?.setPaintProperty(d.id,"fill-opacity",0),m()},te*2)):console.warn("tried to queue an empty layer")},[a,m]);De(()=>{o?.length&&a&&t&&i(o.filter(d=>{let f=d.id.startsWith("location-fill");return f&&a.setPaintProperty(d.id,"fill-opacity-transition",{delay:0,duration:4e3}),f}))},[o,t,a]);let u=w(()=>{let d=[];for(let f=0;f<Re;f++)d.push(g());for(let[f,b]of d.entries())f===0?p(b):setTimeout(()=>{p(b)},te*f)},[g,p]);return De(()=>{r&&t&&a&&n.length>0&&u()},[r,n.length,t,a,u]),xo(()=>{r&&t&&a&&n.length>0&&u()},te*Re),Po(So,{children:e})};import{Alert as Fo}from"@mui/material";import{FlexCol as wo}from"@xylabs/react-flexbox";import{useCallback as oe,useEffect as ze,useState as vo}from"react";import{Fragment as Ho,jsx as Z,jsxs as ko}from"react/jsx-runtime";var ci=({accessToken:r,features:e,fitToPointsPadding:o=20,layers:t,zoom:a,...n})=>{let[i,s]=vo(),{mapSettings:c}=h(),{map:l,mapInitialized:m}=x(),g=f=>f!==void 0?{maxZoom:f}:{},p=oe(()=>{if(i?.isMapReady&&e?.length&&t)for(let f of t)i.initializeMapSource(f)},[i,e,t]),u=oe(()=>{let{fitToPoints:f}=c||{};i&&l&&f?.value===!0&&i.initialMapPositioning({padding:o,...g(a)})},[c,i,l,o,a]),d=oe(()=>{i?.initialMapPositioning({padding:o,...g(a)}),p()},[i,o,p,a]);return ze(()=>{l&&e?.length&&s(new T({features:e,map:l,zoom:a}))},[l,e,a]),ze(()=>{m&&(u(),d())},[m,d,u]),Z(wo,{alignItems:"stretch",id:"xyo-mapbox-wrap",...n,children:e?ko(Ho,{children:[Z(Q,{accessToken:r,zoom:a}),Z(W,{})]}):Z(Fo,{severity:"error",children:"No data to show"})})};import{isPayloadOfSchemaType as re}from"@xyo-network/payload-model";var Ao="network.xyo.location.range.answer",di=re(Ao),Bo="network.xyo.location.heatmap.answer",fi=re(Bo),To="network.xyo.location.heatmap.quadkey.answer",gi=re(To);export{Ae as AnimatedHeatMap,Ne as AnimatedHeatMapLegend,Qn as AnimatedHeatMapLoaded,K as AnimatedHeatMapSettings,$ as CircleLayerBuilder,Te as ColorGradientLegend,A as DefaultMapSettings,F as FillLayerBuilder,z as HeatMapFillLayerConfig,xe as HeatMapInitializerProvider,be as HeatMapLineLayerConfig,yo as HeatMapSettings,Ce as HeatMapSymbolLayerConfig,Vn as LayerAnimator,E as LineLayerBuilder,Ia as LocationHeatMapLayerBuilder,J as LocationHeatMapLayerBuilderAnimated,Se as LocationPointLayerConfig,Ja as LocationPointsMapLayerBuilder,P as MapBase,Q as MapBox,Me as MapBoxInstanceProvider,C as MapHeat,V as MapHeatConstants,T as MapPoints,Jt as MapPointsConstants,ve as MapSettingSwitch,I as MapSettings,W as MapSettingsBox,he as MapSettingsProvider,$t as MapStyle,R as MapboxAccessTokenContext,ua as MapboxAccessTokenProvider,ke as MapboxHeatFlexBox,ci as MapboxPointsFlexBox,Ao as NetworkLocationAnswerSchema,Bo as NetworkLocationHeatmapAnswerSchema,To as NetworkLocationHeatmapQuadkeyAnswerSchema,_ as SymbolLayerBuilder,di as isNetworkLocationAnswer,fi as isNetworkLocationHeatmapAnswer,gi as isNetworkLocationHeatmapQuadkeyAnswer,ie as useDynamicMapResize,ce as useDynamicPositioning,le as useFindHashes,pe as useHeatMapColors,ia as useHeatMapInitializer,x as useMapBoxInstance,h as useMapSettings,La as useMapboxAccessToken,de as useQuadKeyPayloadsToFeatures};
1
+ // src/Settings/DefaultMapSettings.ts
2
+ var DefaultMapSettings = () => ({
3
+ debugLayer: {
4
+ devMode: true,
5
+ field: "debugLayer",
6
+ hidden: true,
7
+ label: "Debug Layer",
8
+ value: false
9
+ },
10
+ debugLogging: {
11
+ devMode: true,
12
+ field: "debugLogging",
13
+ hidden: true,
14
+ label: "Debug Logging",
15
+ value: false
16
+ },
17
+ dynamicMapResize: {
18
+ devMode: true,
19
+ field: "dynamicMapResize",
20
+ hidden: true,
21
+ label: "Auto Map Resize",
22
+ value: true
23
+ },
24
+ enableControls: {
25
+ devMode: true,
26
+ field: "enableControls",
27
+ hidden: true,
28
+ label: "Map Controls",
29
+ value: false
30
+ },
31
+ fitToPoints: {
32
+ devMode: true,
33
+ field: "fitToPoints",
34
+ hidden: true,
35
+ label: "Fit To Points",
36
+ value: false
37
+ },
38
+ preferDark: {
39
+ devMode: false,
40
+ field: "preferDark",
41
+ hidden: true,
42
+ label: "Prefer dark",
43
+ value: false
44
+ },
45
+ scrollToZoom: {
46
+ devMode: true,
47
+ field: "scrollToZoom",
48
+ hidden: true,
49
+ label: "Scroll To Zoom",
50
+ value: false
51
+ }
52
+ });
53
+
54
+ // src/AnimatedHeatMapSettings.ts
55
+ var AnimatedHeatMapSettings = DefaultMapSettings();
56
+ var { debugLayer, scrollToZoom, fitToPoints, preferDark } = AnimatedHeatMapSettings;
57
+ debugLayer.hidden = false;
58
+ scrollToZoom.value = true;
59
+ fitToPoints.value = false;
60
+ preferDark.value = true;
61
+
62
+ // src/Components/AnimatedHeatMap.tsx
63
+ import { darken, useTheme as useTheme2 } from "@mui/material";
64
+ import { FlexCol as FlexCol2 } from "@xylabs/react-flexbox";
65
+ import { useState as useState9 } from "react";
66
+
67
+ // src/Contexts/HeatMapInitializer/Provider.tsx
68
+ import { forget as forget2 } from "@xylabs/forget";
69
+ import { useEffect as useEffect6, useState as useState6 } from "react";
70
+
71
+ // src/hooks/useDynamicMapResize.tsx
72
+ import { useEffect, useMemo, useState } from "react";
73
+ var useDynamicMapResize = (mapContainerRef, mapCanvasRef, mapInstance, active = true) => {
74
+ const [dependenciesReady, setDependenciesReady] = useState(false);
75
+ const resizer = useMemo(
76
+ () => new ResizeObserver(() => {
77
+ const width = mapContainerRef.current?.getBoundingClientRect().width;
78
+ if (width && mapCanvasRef.current) {
79
+ mapCanvasRef.current.style.width = `${width}px`;
80
+ setTimeout(() => mapInstance?.resize());
81
+ }
82
+ }),
83
+ [mapCanvasRef, mapContainerRef, mapInstance]
84
+ );
85
+ useEffect(() => {
86
+ const dependenciesReady2 = !!(active && mapInstance && mapContainerRef?.current && mapCanvasRef.current);
87
+ setDependenciesReady(dependenciesReady2);
88
+ }, [active, mapCanvasRef, mapContainerRef, mapInstance]);
89
+ useEffect(() => {
90
+ if (dependenciesReady) {
91
+ if (mapContainerRef.current) {
92
+ resizer.observe(mapContainerRef.current);
93
+ }
94
+ return () => {
95
+ resizer.disconnect();
96
+ };
97
+ }
98
+ }, [active, dependenciesReady, mapCanvasRef, mapContainerRef, mapInstance, resizer]);
99
+ };
100
+
101
+ // src/hooks/useDynamicPositioning.tsx
102
+ import { useWindowSize } from "@xylabs/react-shared";
103
+ import { useEffect as useEffect2, useState as useState2 } from "react";
104
+ var defaultZoom = 1.6;
105
+ var defaultAspectRatioRange = [0.5, 2];
106
+ var latRange = [0.9121644205263664, 1.71785031559439];
107
+ var lngRange = [-81.4742014851959, 12.788958675506933];
108
+ var linearInterpolate = (aspectRatio, degreeRange, aspectRatioRange) => {
109
+ const [degreeMin, degreeMax] = degreeRange;
110
+ const [aspectRatioMin, aspectRatioMax] = aspectRatioRange || defaultAspectRatioRange;
111
+ const aspectRatioRangeSpan = aspectRatioMax - aspectRatioMin;
112
+ const degreeRangeSpan = degreeMax - degreeMin;
113
+ const percent = (aspectRatio - aspectRatioMin) / aspectRatioRangeSpan;
114
+ const scaledDegree = percent * degreeRangeSpan + degreeMin;
115
+ return scaledDegree;
116
+ };
117
+ var useDynamicPositioning = () => {
118
+ const [options, setOptions] = useState2({});
119
+ const { width, height } = useWindowSize();
120
+ useEffect2(() => {
121
+ if (width && height) {
122
+ const aspectRatio = width / height;
123
+ setOptions({
124
+ center: [linearInterpolate(aspectRatio, lngRange), linearInterpolate(aspectRatio, latRange)],
125
+ zoom: defaultZoom
126
+ });
127
+ }
128
+ }, [height, width]);
129
+ return { options };
130
+ };
131
+
132
+ // src/hooks/useFindHashes.tsx
133
+ import { useNetwork } from "@xyo-network/react-network";
134
+ import { useMemo as useMemo2 } from "react";
135
+ var animatedAnswerHashesConst = [
136
+ "79af071f451fc7af10d009dc63236ef9a9b211732c1ee0c06f028fcecf2336c5",
137
+ "531bfba6d8dfefd3bcc888aca54cdbbd4574ed2b3ec551b230845a1f9a608898",
138
+ "c874412b4faa4947de81372fd1ba12fdd6f43f5e408622b7f357cb2bcb3f17cb",
139
+ "29d3f8b882c61a82a1a1675782a27e797ea7196f45a23b4409680ab8b8d5f14e",
140
+ "cfd20f80ac073fd9518f4ef3f43d2a1f5e4e56e40c2677f38d6f6fecd05df60c",
141
+ "1354fa73497519a39aed19fc99bdbae78a880a1eafb2f7898d607e07db36528d",
142
+ "1043b0d25eacfc5013ae9dba780305a6fbf01a43543bd871d7c00537fca142a9",
143
+ "973dfc5df142851ced258d52d0ac2784e814000ac22e35776f772256b0d4dde9",
144
+ "463808eb74d3d87e6563970e0301a493577f8cd1b501e6e0ffa5e027ad2cea95",
145
+ "15b21acea2e3fd9d1ace3768a72636ee7bdf67a6f8e0807bfa2273dea2207555",
146
+ "32d377bfe7ebe382598c54dd13f8af7510e0a1e2fd2e913311fdd58e517e5e2e,"
147
+ ];
148
+ var staticAnswerHashConst = "c7bbf61f61cfd4a1b2def160c28136fc1d100d39fbdb67b227a2c6e558d9d3a5";
149
+ var useFindHashes = () => {
150
+ const { network } = useNetwork();
151
+ const exploreMapHashes = network?.nodes?.find((node) => node.type === "archivist")?.explorerMapHashes;
152
+ const animatedAnswerHashes = exploreMapHashes?.animatedAnswerHashes || animatedAnswerHashesConst;
153
+ const staticAnswerHash = exploreMapHashes?.staticAnswerHash || staticAnswerHashConst;
154
+ const foundHashes = useMemo2(() => [staticAnswerHash, ...animatedAnswerHashes], [animatedAnswerHashes, staticAnswerHash]);
155
+ return foundHashes;
156
+ };
157
+
158
+ // src/hooks/useHeatMapColors.tsx
159
+ import { useTheme } from "@mui/material";
160
+ var useHeatMapColors = () => {
161
+ const theme = useTheme();
162
+ const staticMapColor = "#FFFF75";
163
+ const highUsageColor = "#FF0000";
164
+ const heatMapColorProps = {
165
+ highUsageColor,
166
+ lowUsageColor: "#FFB3B3",
167
+ staticMapColor
168
+ };
169
+ const legendProps = {
170
+ endColor: highUsageColor,
171
+ endLabel: "High",
172
+ heading: "Network Usage",
173
+ startColor: staticMapColor,
174
+ startLabel: "Low",
175
+ textColor: theme.palette.common.white
176
+ };
177
+ return { heatMapColorProps, legendProps };
178
+ };
179
+
180
+ // src/hooks/useQuadKeyPayloadsToFeatures.tsx
181
+ import { compact } from "@xylabs/lodash";
182
+ import { GeoJson } from "@xyo-network/sdk-geo";
183
+ import { useEffect as useEffect3, useState as useState3 } from "react";
184
+ var quadKeyToFeature = ({ density, quadkey }) => {
185
+ const polygonFeature = new GeoJson(quadkey).polygonFeature();
186
+ polygonFeature.properties = {
187
+ count: density,
188
+ density
189
+ };
190
+ return polygonFeature;
191
+ };
192
+ var setDensity = (feature) => {
193
+ if (feature.properties) {
194
+ feature.properties.value = feature.properties.density / 5;
195
+ }
196
+ return feature;
197
+ };
198
+ var useQuadKeyPayloadsToFeatures = (payloads) => {
199
+ const [multipleFeatureSets, setMultipleFeatureSets] = useState3([[]]);
200
+ const [features, setFeatures] = useState3([]);
201
+ const [error, setError] = useState3();
202
+ useEffect3(() => {
203
+ if (Array.isArray(payloads)) {
204
+ if (compact(payloads).length > 0) {
205
+ const mappedFeatures = payloads?.map((payload) => payload?.result.map(quadKeyToFeature));
206
+ setMultipleFeatureSets(mappedFeatures.map((features2) => features2?.map(setDensity) ?? []));
207
+ } else {
208
+ setError(new Error("Cannot find payloads for provided hashes"));
209
+ }
210
+ }
211
+ if (payloads && payloads.result) {
212
+ const singlePayload = payloads;
213
+ const mappedFeatures = singlePayload.result.map(quadKeyToFeature);
214
+ setFeatures(mappedFeatures.map(setDensity));
215
+ }
216
+ }, [payloads]);
217
+ return { error, features, multipleFeatureSets };
218
+ };
219
+
220
+ // src/MapBoxClasses/MapBase.ts
221
+ import { assertEx } from "@xylabs/assert";
222
+ import { GeoJson as GeoJson2 } from "@xyo-network/sdk-geo";
223
+ var MapBase = class {
224
+ _config;
225
+ constructor(config) {
226
+ this._config = { requestLocation: true, zoom: 2, ...config };
227
+ }
228
+ get isMapReady() {
229
+ return !!this._config.map;
230
+ }
231
+ initializeMapSource(layer) {
232
+ const getSource = () => {
233
+ const featuresCollection = GeoJson2.featureCollection(this._config.features);
234
+ return GeoJson2.featuresSource(featuresCollection);
235
+ };
236
+ const existingSource = this._config.map.getSource(layer.source);
237
+ const source = getSource();
238
+ if (existingSource) {
239
+ existingSource.setData(assertEx(source.data));
240
+ } else {
241
+ this._config.map.addSource(layer.source, source);
242
+ }
243
+ layer.update(this._config.map, true);
244
+ return this;
245
+ }
246
+ };
247
+
248
+ // src/MapBoxClasses/MapHeat.ts
249
+ import { assertEx as assertEx2 } from "@xylabs/assert";
250
+ import { delay } from "@xylabs/delay";
251
+ import { forget } from "@xylabs/forget";
252
+ import { GeoJson as GeoJson3 } from "@xyo-network/sdk-geo";
253
+ import { LngLatBounds } from "mapbox-gl";
254
+ var MapHeat = class extends MapBase {
255
+ static animationStarted = false;
256
+ config;
257
+ constructor(config) {
258
+ super(config);
259
+ this.config = config;
260
+ }
261
+ static initialMapPositioning(options, map, features, initialBounds) {
262
+ if (!features) {
263
+ return;
264
+ }
265
+ let bounds;
266
+ if (initialBounds) {
267
+ bounds = initialBounds;
268
+ } else {
269
+ bounds = new LngLatBounds();
270
+ features.forEach((feature) => {
271
+ for (const coordinates of feature.geometry.coordinates) {
272
+ for (const position of coordinates) {
273
+ bounds.extend(position);
274
+ }
275
+ }
276
+ });
277
+ }
278
+ map.setCenter(bounds.getCenter());
279
+ map.fitBounds(bounds, options);
280
+ return this;
281
+ }
282
+ static async initializeAnimatedHeatMapSource(layers, featureSet, map, startColor, endColor) {
283
+ this.animationStarted = true;
284
+ let layerTick = 0;
285
+ let sourceTick = 0;
286
+ const sources = featureSet.map((feature) => {
287
+ const featuresCollection = GeoJson3.featureCollection(feature);
288
+ return GeoJson3.featuresSource(featuresCollection);
289
+ });
290
+ this.updateLayer(map, layers[0], sources[0]);
291
+ this.updateLayer(map, layers[1], sources[1]);
292
+ for (const layer of layers) {
293
+ map.setPaintProperty(layer.id, "fill-opacity", 0);
294
+ }
295
+ const frameLength = 3e3;
296
+ const initialPad = 0.5;
297
+ const factor = 10;
298
+ const steps = 30;
299
+ const stepLength = frameLength / steps;
300
+ const lowUsageColor = startColor ?? "#FFB3B3";
301
+ const highUsageColor = endColor ?? "#FF0000";
302
+ const dynamicFillColor = (factor2, initialPad2, i) => {
303
+ const sinFade = Math.sin(i / steps * Math.PI / 2);
304
+ const cosFade = Math.cos(i / steps * Math.PI / 2);
305
+ const divisor = factor2 + factor2 * sinFade;
306
+ const offset = initialPad2 * cosFade;
307
+ return [
308
+ "let",
309
+ "density",
310
+ ["+", ["/", ["number", ["get", "value"]], divisor], offset],
311
+ ["interpolate", ["linear"], ["var", "density"], 0, lowUsageColor, 0.5, highUsageColor]
312
+ ];
313
+ };
314
+ const fadedIn = layers.map((_) => false);
315
+ const fadeIn = async (id, index) => {
316
+ for (let i = steps; i >= 1; i--) {
317
+ map.setPaintProperty(id, "fill-color", dynamicFillColor(factor, initialPad, i * (180 / stepLength)));
318
+ await delay(stepLength);
319
+ }
320
+ fadedIn[index] = true;
321
+ };
322
+ const fadeOut = async (id, index) => {
323
+ for (let i = 1; i <= steps; i++) {
324
+ map.setPaintProperty(id, "fill-color", dynamicFillColor(factor, initialPad, i * (180 / stepLength)));
325
+ await delay(stepLength);
326
+ }
327
+ fadedIn[index] = false;
328
+ };
329
+ let started = false;
330
+ const startAnimation = async () => {
331
+ assertEx2(!started, () => "Animation Already Started");
332
+ started = true;
333
+ while (this.animationStarted) {
334
+ const upLayer = layerTick % layers.length;
335
+ const downLayer = (layerTick + 1) % layers.length;
336
+ const incomingSource = sourceTick % featureSet.length;
337
+ const outgoingSource = (sourceTick + 1) % featureSet.length;
338
+ if (fadedIn[upLayer]) {
339
+ this.updateLayer(map, layers[upLayer], sources[incomingSource]);
340
+ forget(fadeOut(layers[upLayer].id, upLayer));
341
+ }
342
+ if (!fadedIn[downLayer]) {
343
+ this.updateLayer(map, layers[downLayer], sources[outgoingSource]);
344
+ forget(fadeIn(layers[downLayer].id, downLayer));
345
+ }
346
+ while ((fadedIn[upLayer] || !fadedIn[downLayer]) && this.animationStarted) {
347
+ await delay(1e3);
348
+ }
349
+ layerTick++;
350
+ sourceTick++;
351
+ }
352
+ };
353
+ await startAnimation();
354
+ }
355
+ static updateLayer(map, layer, source) {
356
+ const existingSource = map.getSource(layer.source);
357
+ if (existingSource && source.data) {
358
+ existingSource.setData(source.data);
359
+ } else if (source) {
360
+ map.addSource(layer.source, source);
361
+ }
362
+ layer.update(map, true);
363
+ }
364
+ // Build layers each with the same features
365
+ initializeHeatMapSource(layers) {
366
+ const getSource = (_) => {
367
+ const featuresCollection = GeoJson3.featureCollection(this.config.features);
368
+ return GeoJson3.featuresSource(featuresCollection);
369
+ };
370
+ for (const [index, layer] of layers.entries()) {
371
+ const existingSource = this.config.map.getSource(layer.source);
372
+ const source = getSource(index);
373
+ if (existingSource) {
374
+ existingSource.setData(assertEx2(source.data));
375
+ } else {
376
+ this.config.map.addSource(layer.source, source);
377
+ }
378
+ layer.update(this.config.map, true);
379
+ }
380
+ return this;
381
+ }
382
+ };
383
+
384
+ // src/MapBoxClasses/MapPoints.ts
385
+ import { LngLatBounds as LngLatBounds2 } from "mapbox-gl";
386
+ var MapPoints = class extends MapBase {
387
+ config;
388
+ constructor(config) {
389
+ super(config);
390
+ this.config = config;
391
+ }
392
+ initialMapPositioning(options, initialBounds) {
393
+ let bounds;
394
+ if (initialBounds) {
395
+ bounds = initialBounds;
396
+ } else {
397
+ bounds = new LngLatBounds2();
398
+ this.config.features.forEach((feature) => {
399
+ bounds.extend(feature.geometry.coordinates);
400
+ });
401
+ }
402
+ this.config.map.setCenter(bounds.getCenter());
403
+ this.config.map.fitBounds(bounds, options);
404
+ return this.config.map;
405
+ }
406
+ };
407
+
408
+ // src/MapBoxClasses/MapSettings.ts
409
+ import { GeolocateControl, NavigationControl } from "mapbox-gl";
410
+ var MapSettings = class _MapSettings {
411
+ static geoLocateControl;
412
+ static mapListeners = {
413
+ logData: (ev, map) => {
414
+ const target = map || ev?.target;
415
+ if (target) {
416
+ console.log("zoom", target.getZoom());
417
+ console.log("center", target.getCenter());
418
+ }
419
+ }
420
+ };
421
+ static navControl;
422
+ static requestLocation;
423
+ static toggleControls(value, map, zoom, requestLocation) {
424
+ if (value) {
425
+ _MapSettings.addControls(map, zoom, requestLocation);
426
+ } else {
427
+ _MapSettings.removeControls(map);
428
+ }
429
+ return this;
430
+ }
431
+ static toggleDebugLayer(value, map, layerName) {
432
+ const debugLayer3 = map.getLayer(layerName);
433
+ if (debugLayer3) {
434
+ if (value) {
435
+ map.setLayoutProperty(layerName, "visibility", "visible");
436
+ } else {
437
+ map.setLayoutProperty(layerName, "visibility", "none");
438
+ }
439
+ }
440
+ return this;
441
+ }
442
+ static toggleDebugLogging(value, map) {
443
+ const debugEvents = ["resize", "zoomend", "dragend"];
444
+ if (value) {
445
+ this.mapListeners.logData(void 0, map);
446
+ for (const event of debugEvents) map.on(event, this.mapListeners.logData);
447
+ } else {
448
+ for (const event of debugEvents) map.off(event, this.mapListeners.logData);
449
+ }
450
+ }
451
+ static toggleScrollToZoom(value, map) {
452
+ if (value) {
453
+ map.scrollZoom.enable();
454
+ } else {
455
+ map.scrollZoom.disable();
456
+ }
457
+ return this;
458
+ }
459
+ static updateSettings(config) {
460
+ const { settings, map, zoom, requestLocation, debugLayerName = "" } = config;
461
+ const { scrollToZoom: scrollToZoom3, enableControls, debugLayer: debugLayer3, debugLogging } = settings;
462
+ _MapSettings.toggleControls(enableControls?.value, map, zoom, requestLocation).toggleScrollToZoom(scrollToZoom3?.value, map).toggleDebugLayer(debugLayer3?.value, map, debugLayerName).toggleDebugLogging(debugLogging.value, map);
463
+ }
464
+ // Needs to be static so we ensure controls are only instantiated once
465
+ static addControls(map, zoom, requestLocation) {
466
+ const geolocateControl = new GeolocateControl({
467
+ fitBoundsOptions: {
468
+ zoom: zoom || 2
469
+ },
470
+ positionOptions: {
471
+ enableHighAccuracy: true
472
+ },
473
+ trackUserLocation: true
474
+ });
475
+ const navControl = new NavigationControl({
476
+ showCompass: false
477
+ });
478
+ this.geoLocateControl = this.geoLocateControl || geolocateControl;
479
+ this.navControl = this.navControl || navControl;
480
+ if (!map.hasControl(this.geoLocateControl) && requestLocation) {
481
+ map.addControl(this.geoLocateControl);
482
+ }
483
+ if (!map.hasControl(this.navControl)) {
484
+ map.addControl(this.navControl, "top-left");
485
+ }
486
+ return this;
487
+ }
488
+ static removeControls(map) {
489
+ if (this.geoLocateControl && map.hasControl(this.geoLocateControl) && this.requestLocation) {
490
+ map.removeControl(this.geoLocateControl);
491
+ }
492
+ if (this.navControl && map.hasControl(this.navControl)) {
493
+ map.removeControl(this.navControl);
494
+ }
495
+ return this;
496
+ }
497
+ };
498
+
499
+ // src/Contexts/MapBoxInstance/Provider.tsx
500
+ import { useEffect as useEffect4, useState as useState4 } from "react";
501
+
502
+ // src/Contexts/MapBoxInstance/Context.ts
503
+ import { createContext } from "react";
504
+ var MapBoxInstanceContext = createContext({});
505
+
506
+ // src/Contexts/MapBoxInstance/Provider.tsx
507
+ import { jsx } from "react/jsx-runtime";
508
+ var MapBoxInstanceProvider = ({ children }) => {
509
+ const [map, setMapBoxInstance] = useState4();
510
+ const [mapInitialized, setMapInitialized] = useState4(false);
511
+ const value = { map, mapInitialized, setMapBoxInstance };
512
+ useEffect4(() => {
513
+ if (!mapInitialized && map) {
514
+ map?.on("load", () => {
515
+ setMapInitialized(true);
516
+ });
517
+ }
518
+ }, [map, mapInitialized, setMapInitialized]);
519
+ return /* @__PURE__ */ jsx(MapBoxInstanceContext.Provider, { value, children });
520
+ };
521
+
522
+ // src/Contexts/MapBoxInstance/useMapBoxInstance.tsx
523
+ import { assertEx as assertEx3 } from "@xylabs/assert";
524
+ import { useContext } from "react";
525
+ var useMapBoxInstance = () => {
526
+ const context = useContext(MapBoxInstanceContext);
527
+ assertEx3("map" in context, () => "useMapBoxInstance must be used within a MapBoxInstanceContext");
528
+ return context;
529
+ };
530
+
531
+ // src/Contexts/MapSettings/Provider.tsx
532
+ import { useEffect as useEffect5, useState as useState5 } from "react";
533
+
534
+ // src/Contexts/MapSettings/Context.ts
535
+ import { createContext as createContext2 } from "react";
536
+ var MapSettingsContext = createContext2({});
537
+
538
+ // src/Contexts/MapSettings/Provider.tsx
539
+ import { jsx as jsx2 } from "react/jsx-runtime";
540
+ var MapSettingsProvider = ({
541
+ children,
542
+ debugLayerName,
543
+ defaultMapSettings,
544
+ requestLocation,
545
+ zoom = 1
546
+ }) => {
547
+ const [mapSettings, setMapSettings] = useState5(defaultMapSettings || {});
548
+ const { map, mapInitialized } = useMapBoxInstance();
549
+ const value = {
550
+ mapSettings,
551
+ setMapSettings
552
+ };
553
+ useEffect5(() => {
554
+ if (mapSettings && map && mapInitialized) {
555
+ MapSettings.updateSettings({ debugLayerName, map, requestLocation, settings: mapSettings, zoom });
556
+ }
557
+ }, [debugLayerName, map, mapInitialized, mapSettings, requestLocation, zoom]);
558
+ return /* @__PURE__ */ jsx2(MapSettingsContext.Provider, { value, children });
559
+ };
560
+
561
+ // src/Contexts/MapSettings/useMapSettings.tsx
562
+ import { useContext as useContext2 } from "react";
563
+ var useMapSettings = () => {
564
+ const context = useContext2(MapSettingsContext);
565
+ return context;
566
+ };
567
+
568
+ // src/Contexts/HeatMapInitializer/Context.ts
569
+ import { createContext as createContext3 } from "react";
570
+ var HeatMapInitializerContext = createContext3({});
571
+
572
+ // src/Contexts/HeatMapInitializer/Provider.tsx
573
+ import { jsx as jsx3 } from "react/jsx-runtime";
574
+ var HeatMapInitializerProvider = ({
575
+ children,
576
+ featureSets,
577
+ featureSetsLayers,
578
+ features,
579
+ fitToPadding,
580
+ heatMapColorProps,
581
+ layers,
582
+ zoom
583
+ }) => {
584
+ const [mapHeat, setMapHeat] = useState6();
585
+ const { options } = useDynamicPositioning();
586
+ const { mapSettings } = useMapSettings();
587
+ const { map, mapInitialized } = useMapBoxInstance();
588
+ const value = {
589
+ MapHeat: mapHeat,
590
+ heatMapColorProps
591
+ };
592
+ useEffect6(() => {
593
+ if (mapInitialized && featureSets?.length && featureSets[0].length > 0 && map && featureSetsLayers?.length) {
594
+ const { lowUsageColor, highUsageColor } = heatMapColorProps;
595
+ forget2(MapHeat.initializeAnimatedHeatMapSource(featureSetsLayers, featureSets, map, lowUsageColor, highUsageColor));
596
+ }
597
+ return () => {
598
+ MapHeat.animationStarted = false;
599
+ };
600
+ }, [featureSets, featureSetsLayers, mapInitialized, map, heatMapColorProps]);
601
+ useEffect6(() => {
602
+ if (mapHeat && mapInitialized && features?.length && layers?.length) {
603
+ mapHeat.initializeHeatMapSource(layers);
604
+ }
605
+ }, [mapHeat, features?.length, layers, mapInitialized]);
606
+ useEffect6(() => {
607
+ if (mapInitialized) {
608
+ const { fitToPoints: fitToPoints3 } = mapSettings || {};
609
+ if (map) {
610
+ if (fitToPoints3?.value === true) {
611
+ MapHeat.initialMapPositioning({ padding: fitToPadding }, map, features);
612
+ } else if (options.zoom && options.center) {
613
+ map.setZoom(options.zoom);
614
+ map.setCenter(options.center);
615
+ }
616
+ }
617
+ }
618
+ }, [mapHeat, map, mapSettings, fitToPadding, options, mapInitialized, features]);
619
+ useEffect6(() => {
620
+ if (map && features?.length) {
621
+ setMapHeat(new MapHeat({ features, map, zoom }));
622
+ }
623
+ }, [map, features, zoom]);
624
+ return /* @__PURE__ */ jsx3(HeatMapInitializerContext.Provider, { value, children });
625
+ };
626
+
627
+ // src/Contexts/HeatMapInitializer/useHeatMapInitializer.tsx
628
+ import { assertEx as assertEx4 } from "@xylabs/assert";
629
+ import { useContext as useContext3 } from "react";
630
+ var useHeatMapInitializer = () => {
631
+ const context = useContext3(HeatMapInitializerContext);
632
+ assertEx4("heatMapInitialized" in context, () => "useHeatMapInitializer must be used within a HeatMapInitializerContext");
633
+ return context;
634
+ };
635
+
636
+ // src/Contexts/MapboxAccessToken/Context.ts
637
+ import { createContextEx } from "@xyo-network/react-shared";
638
+ var MapboxAccessTokenContext = createContextEx();
639
+
640
+ // src/Contexts/MapboxAccessToken/Provider.tsx
641
+ import { useState as useState7 } from "react";
642
+ import { jsx as jsx4 } from "react/jsx-runtime";
643
+ var MapboxAccessTokenProvider = ({ defaultAccessToken, ...props }) => {
644
+ const [accessToken, setAccessToken] = useState7();
645
+ return /* @__PURE__ */ jsx4(MapboxAccessTokenContext.Provider, { value: { accessToken: accessToken ?? defaultAccessToken, provided: true, setAccessToken }, ...props });
646
+ };
647
+
648
+ // src/Contexts/MapboxAccessToken/use.ts
649
+ import { useContextEx } from "@xyo-network/react-shared";
650
+ var useMapboxAccessToken = (required = false) => {
651
+ return useContextEx(MapboxAccessTokenContext, "MapboxAccessToken", required);
652
+ };
653
+
654
+ // src/Layers/Configs/HeatMapFillLayerConfig.ts
655
+ var HeatMapFillLayerConfig = (color) => ({
656
+ paint: {
657
+ "fill-color": color,
658
+ "fill-opacity": [
659
+ "let",
660
+ "density",
661
+ ["+", ["/", ["number", ["get", "value"]], 4], 0.125],
662
+ ["interpolate", ["linear"], ["var", "density"], 0.8, ["var", "density"], 1, 0.85]
663
+ ]
664
+ }
665
+ });
666
+
667
+ // src/Layers/Configs/HeatMapLineLayerConfig.ts
668
+ var HeatMapLineLayerConfig = (color) => ({
669
+ layout: {
670
+ // Enable for debugging
671
+ visibility: "none"
672
+ },
673
+ paint: {
674
+ "line-color": color,
675
+ "line-opacity": ["let", "density", 0, ["interpolate", ["linear"], ["var", "density"], 0.8, ["var", "density"], 1, 0.85]],
676
+ "line-width": 0.5
677
+ }
678
+ });
679
+
680
+ // src/Layers/Configs/HeatMapSymbolLayerConfig.ts
681
+ var HeatMapSymbolLayerConfig = (color) => ({
682
+ layout: {
683
+ "text-anchor": "center",
684
+ "text-field": [
685
+ "concat",
686
+ "value: ",
687
+ ["to-string", ["+", ["/", ["number", ["get", "value"]], 2], 0.25]],
688
+ "\n",
689
+ "count: ",
690
+ ["to-string", ["get", "count"]]
691
+ ],
692
+ "text-size": 10,
693
+ visibility: "none"
694
+ },
695
+ paint: {
696
+ "text-color": color
697
+ }
698
+ });
699
+
700
+ // src/Layers/Configs/LocationPointLayerConfig.ts
701
+ var LocationPointLayerConfig = (color, circleRadius, circleOpacity) => {
702
+ return {
703
+ paint: {
704
+ "circle-color": color,
705
+ "circle-opacity": circleOpacity,
706
+ "circle-radius": circleRadius
707
+ }
708
+ };
709
+ };
710
+
711
+ // src/Layers/FillLayer.ts
712
+ import { LayerBase } from "@xyo-network/sdk-geo";
713
+ var FillLayerBuilder = class extends LayerBase {
714
+ FillLayerOptions;
715
+ // ensures this class passes for `AnyLayer` type in MapBox
716
+ type = "fill";
717
+ constructor(id, source, FillLayerOptions) {
718
+ super(id, source);
719
+ this.FillLayerOptions = FillLayerOptions || { id: this.id, source: this.source };
720
+ }
721
+ buildLayer() {
722
+ return {
723
+ ...this.FillLayerOptions,
724
+ id: this.id,
725
+ source: this.source,
726
+ type: this.type
727
+ };
728
+ }
729
+ };
730
+
731
+ // src/Layers/LineLayer.ts
732
+ import { LayerBase as LayerBase2 } from "@xyo-network/sdk-geo";
733
+ var LineLayerBuilder = class extends LayerBase2 {
734
+ LineLayerOptions;
735
+ // ensures this class passes for `AnyLayer` type in MapBox
736
+ type = "line";
737
+ constructor(id, source, LineLayerOptions) {
738
+ super(id, source);
739
+ this.LineLayerOptions = LineLayerOptions || { id: this.id, source: this.source };
740
+ }
741
+ buildLayer() {
742
+ return {
743
+ ...this.LineLayerOptions,
744
+ id: this.id,
745
+ layout: {},
746
+ source: this.source,
747
+ type: this.type
748
+ };
749
+ }
750
+ };
751
+
752
+ // src/Layers/SymbolLayer.ts
753
+ import { LayerBase as LayerBase3 } from "@xyo-network/sdk-geo";
754
+ var SymbolLayerBuilder = class extends LayerBase3 {
755
+ SymbolLayerOptions;
756
+ // ensures this class passes for `AnyLayer` type in MapBox
757
+ type = "symbol";
758
+ constructor(id, source, SymbolLayerOptions) {
759
+ super(id, source);
760
+ this.SymbolLayerOptions = SymbolLayerOptions || { id: this.id, source: this.source };
761
+ }
762
+ buildLayer() {
763
+ return {
764
+ ...this.SymbolLayerOptions,
765
+ id: this.id,
766
+ source: this.source,
767
+ type: this.type
768
+ };
769
+ }
770
+ };
771
+
772
+ // src/Layers/Builders/LocationHeatMapLayerBuilder.ts
773
+ var MapHeatConstants = {
774
+ LocationDebugLayerId: "location-debug-id",
775
+ LocationDebugLayerSource: "location-debug-source",
776
+ LocationFillLayerId: "location-fill-id",
777
+ LocationFillLayerSource: "location-fill-source",
778
+ LocationLineLayerId: "location-line-id",
779
+ LocationLineLayerSource: "location-line-source"
780
+ };
781
+ var LocationHeatMapLayerBuilder = (color, alternateColor = "#000") => {
782
+ const {
783
+ LocationFillLayerId,
784
+ LocationFillLayerSource,
785
+ LocationLineLayerId,
786
+ LocationLineLayerSource,
787
+ LocationDebugLayerId,
788
+ LocationDebugLayerSource
789
+ } = MapHeatConstants;
790
+ const fillLayerConfig = HeatMapFillLayerConfig(color);
791
+ const lineLayerConfig = HeatMapLineLayerConfig(color);
792
+ const debugLayerConfig = HeatMapSymbolLayerConfig(alternateColor);
793
+ const fillLayer = new FillLayerBuilder(LocationFillLayerId, LocationFillLayerSource, fillLayerConfig);
794
+ const lineLayer = new LineLayerBuilder(LocationLineLayerId, LocationLineLayerSource, lineLayerConfig);
795
+ const debugLayer3 = new SymbolLayerBuilder(LocationDebugLayerId, LocationDebugLayerSource, debugLayerConfig);
796
+ return [fillLayer, lineLayer, debugLayer3];
797
+ };
798
+
799
+ // src/Layers/Builders/LocationHeatMapLayerBuilderAnimated.ts
800
+ var MapHeatConstants2 = (index, type) => ({
801
+ LocationDebugLayerId: `location-${type}-debug-id-${index}`,
802
+ LocationDebugLayerSource: `location-${type}-debug-source-${index}`,
803
+ LocationFillLayerId: `location-${type}-fill-id-${index}`,
804
+ LocationFillLayerSource: `location-${type}-fill-source-${index}`,
805
+ LocationLineLayerId: `location-${type}-line-id-${index}`,
806
+ LocationLineLayerSource: `location-${type}-line-source-${index}`
807
+ });
808
+ var LocationHeatMapLayerBuilderAnimated = (color, index, type = "") => {
809
+ const { LocationFillLayerId, LocationFillLayerSource } = MapHeatConstants2(index, type);
810
+ const fillLayerConfig = HeatMapFillLayerConfig(color);
811
+ const fillLayer = new FillLayerBuilder(LocationFillLayerId, LocationFillLayerSource, fillLayerConfig);
812
+ return fillLayer;
813
+ };
814
+
815
+ // src/Layers/CircleLayer.ts
816
+ import { LayerBase as LayerBase4 } from "@xyo-network/sdk-geo";
817
+ var CircleLayerBuilder = class extends LayerBase4 {
818
+ CircleLayerOptions;
819
+ // ensures this class passes for `AnyLayer` type in MapBox
820
+ type = "circle";
821
+ constructor(id, source, CircleLayerOptions) {
822
+ super(id, source);
823
+ this.CircleLayerOptions = CircleLayerOptions || { id: this.id, source: this.source, type: "circle" };
824
+ }
825
+ buildLayer() {
826
+ return {
827
+ filter: ["==", "$type", "Point"],
828
+ layout: {},
829
+ paint: {
830
+ "circle-color": "#ff0000",
831
+ "circle-radius": 6
832
+ },
833
+ type: this.type,
834
+ ...this.CircleLayerOptions,
835
+ id: this.id,
836
+ source: this.source
837
+ };
838
+ }
839
+ };
840
+
841
+ // src/Layers/Builders/LocationPointsMapLayerBuilder.ts
842
+ var MapPointsConstants = {
843
+ LocationDotsLayerId: "location-dots",
844
+ LocationDotsLayerSource: "location-dots-source"
845
+ };
846
+ var LocationPointsMapLayerBuilder = (color, circleRadius = 6, circleOpacity = 0.8) => {
847
+ const { LocationDotsLayerId, LocationDotsLayerSource } = MapPointsConstants;
848
+ const dotLayerConfig = LocationPointLayerConfig(color, circleRadius, circleOpacity);
849
+ const dotLayer = new CircleLayerBuilder(LocationDotsLayerId, LocationDotsLayerSource, dotLayerConfig);
850
+ return [dotLayer];
851
+ };
852
+
853
+ // src/Components/MapBoxHeat.tsx
854
+ import { FlexCol } from "@xylabs/react-flexbox";
855
+
856
+ // src/Components/MapBox.tsx
857
+ import "mapbox-gl/dist/mapbox-gl.css";
858
+ import { Map as Map3 } from "mapbox-gl";
859
+ import { useEffect as useEffect7, useRef, useState as useState8 } from "react";
860
+
861
+ // src/lib/MapStyle.ts
862
+ var MapStyle = /* @__PURE__ */ ((MapStyle2) => {
863
+ MapStyle2["Dark"] = "mapbox/dark-v10";
864
+ MapStyle2["Light"] = "mapbox/light-v10";
865
+ MapStyle2["Outdoors"] = "mapbox/outdoors-v11";
866
+ MapStyle2["Satellite"] = "mapbox/satellite-v9";
867
+ MapStyle2["SatelliteStreets"] = "mapbox/satellite-streets-v11";
868
+ MapStyle2["Streets"] = "mapbox/streets-v11";
869
+ return MapStyle2;
870
+ })(MapStyle || {});
871
+
872
+ // src/Components/MapBox.tsx
873
+ import { jsx as jsx5 } from "react/jsx-runtime";
874
+ var MapBox = ({ accessToken, darkMode = false, options, zoom = 2, ...props }) => {
875
+ const [map, setMap] = useState8();
876
+ const mapContainerRef = useRef(null);
877
+ const mapCanvasRef = useRef(null);
878
+ const { setMapBoxInstance, map: mapInstance } = useMapBoxInstance();
879
+ const { mapSettings } = useMapSettings();
880
+ const activeResize = mapSettings?.dynamicMapResize.value;
881
+ useDynamicMapResize(mapContainerRef, mapCanvasRef, mapInstance, activeResize);
882
+ useEffect7(() => {
883
+ if (mapSettings?.preferDark?.value === true) {
884
+ map?.setStyle(`mapbox://styles/${"mapbox/dark-v10" /* Dark */}`);
885
+ } else {
886
+ map?.setStyle(`mapbox://styles/${darkMode ? "mapbox/dark-v10" /* Dark */ : "mapbox/light-v10" /* Light */}`);
887
+ }
888
+ }, [map, darkMode, mapSettings]);
889
+ useEffect7(() => {
890
+ const map2 = new Map3({
891
+ accessToken,
892
+ center: [0, 0],
893
+ container: mapContainerRef.current ?? "",
894
+ style: `mapbox://styles/${"mapbox/light-v10" /* Light */}`,
895
+ zoom,
896
+ ...options
897
+ });
898
+ setMapBoxInstance?.(map2);
899
+ setMap(map2);
900
+ mapCanvasRef.current = document.querySelector(".mapboxgl-canvas");
901
+ console.log("Created Map");
902
+ return () => {
903
+ console.log("Removing Map");
904
+ map2.remove();
905
+ };
906
+ }, [mapContainerRef, setMap, options, zoom, setMapBoxInstance, accessToken]);
907
+ return /* @__PURE__ */ jsx5(
908
+ "div",
909
+ {
910
+ ref: (el) => mapContainerRef.current = el,
911
+ style: {
912
+ bottom: 0,
913
+ left: 0,
914
+ position: "absolute",
915
+ right: 0,
916
+ top: 0,
917
+ ...props
918
+ }
919
+ }
920
+ );
921
+ };
922
+
923
+ // src/Components/MapSettingsComponents/Setting.tsx
924
+ import { FormControlLabel, Switch } from "@mui/material";
925
+ import { jsx as jsx6 } from "react/jsx-runtime";
926
+ var MapSettingSwitch = ({ developerMode, field, ...props }) => {
927
+ const { mapSettings, setMapSettings } = useMapSettings();
928
+ const setting = mapSettings?.[field];
929
+ const onLocalChange = (event) => {
930
+ if (setting) {
931
+ setMapSettings?.((previous) => {
932
+ previous[setting.field].value = event.target.checked;
933
+ return { ...previous };
934
+ });
935
+ }
936
+ };
937
+ if (setting?.devMode && developerMode === false) {
938
+ return null;
939
+ }
940
+ return setting?.hidden ? null : /* @__PURE__ */ jsx6(FormControlLabel, { label: setting?.label, control: /* @__PURE__ */ jsx6(Switch, { checked: setting?.value, onChange: onLocalChange, ...props }) });
941
+ };
942
+
943
+ // src/Components/MapSettingsComponents/SettingsBox.tsx
944
+ import { Paper, Stack } from "@mui/material";
945
+ import { FlexGrowRow, FlexRow } from "@xylabs/react-flexbox";
946
+ import { useAppSettings } from "@xyo-network/react-app-settings";
947
+ import { jsx as jsx7 } from "react/jsx-runtime";
948
+ var MapSettingsBox = ({ developerMode, ...props }) => {
949
+ const { mapSettings } = useMapSettings();
950
+ const { developerMode: devModeFromContext } = useAppSettings();
951
+ const resolveDeveloperMode = developerMode ?? devModeFromContext;
952
+ return mapSettings && resolveDeveloperMode ? /* @__PURE__ */ jsx7(FlexGrowRow, { bottom: 36, left: 10, position: "absolute", ...props, children: /* @__PURE__ */ jsx7(FlexRow, { paddingX: 2, children: /* @__PURE__ */ jsx7(Paper, { children: /* @__PURE__ */ jsx7(Stack, { direction: "row", spacing: 1, marginX: 1, children: Object.keys(mapSettings).map((key, index) => {
953
+ return /* @__PURE__ */ jsx7(MapSettingSwitch, { field: mapSettings[key].field, developerMode }, index);
954
+ }) }) }) }) }) : null;
955
+ };
956
+
957
+ // src/Components/MapBoxHeat.tsx
958
+ import { jsx as jsx8, jsxs } from "react/jsx-runtime";
959
+ var MapboxHeatFlexBox = ({ accessToken, children, mapBoxOptions, zoom, legend, developerMode, ...props }) => {
960
+ return /* @__PURE__ */ jsxs(FlexCol, { ...props, children: [
961
+ /* @__PURE__ */ jsx8(MapBox, { accessToken, options: mapBoxOptions, zoom }),
962
+ /* @__PURE__ */ jsx8(MapSettingsBox, { developerMode }),
963
+ legend,
964
+ children
965
+ ] });
966
+ };
967
+
968
+ // src/Components/AnimatedHeatMap.tsx
969
+ import { jsx as jsx9 } from "react/jsx-runtime";
970
+ var AnimatedHeatMap = ({
971
+ accessToken,
972
+ animatedFeatureSets,
973
+ defaultMapSettings,
974
+ heatMapColorProps,
975
+ staticFeatureSet,
976
+ ...props
977
+ }) => {
978
+ const theme = useTheme2();
979
+ const { staticMapColor, lowUsageColor, highUsageColor } = heatMapColorProps || {};
980
+ const localStaticMapColor = staticMapColor ?? theme.palette.primary.light;
981
+ const [layers] = useState9([
982
+ LocationHeatMapLayerBuilderAnimated(localStaticMapColor, 0, "static"),
983
+ LocationHeatMapLayerBuilderAnimated(lowUsageColor || localStaticMapColor, 0, "animated"),
984
+ LocationHeatMapLayerBuilderAnimated(highUsageColor || darken(localStaticMapColor, 0.9), 1, "animated")
985
+ ]);
986
+ return animatedFeatureSets?.length ? /* @__PURE__ */ jsx9(MapBoxInstanceProvider, { children: /* @__PURE__ */ jsx9(MapSettingsProvider, { defaultMapSettings, debugLayerName: MapHeatConstants.LocationDebugLayerId, children: /* @__PURE__ */ jsx9(
987
+ HeatMapInitializerProvider,
988
+ {
989
+ features: staticFeatureSet,
990
+ layers: [layers[0]],
991
+ featureSets: animatedFeatureSets,
992
+ featureSetsLayers: layers.slice(1, 3),
993
+ heatMapColorProps,
994
+ children: /* @__PURE__ */ jsx9(MapboxHeatFlexBox, { accessToken, ...props })
995
+ }
996
+ ) }) }) : /* @__PURE__ */ jsx9(FlexCol2, { minHeight: 160, minWidth: 160, busy: true });
997
+ };
998
+
999
+ // src/Components/AnimatedHeatMapLoaded.tsx
1000
+ import { Alert, AlertTitle } from "@mui/material";
1001
+ import { FlexCol as FlexCol5 } from "@xylabs/react-flexbox";
1002
+ import { useWeakArchivistFromNode, useWeakArchivistGet } from "@xyo-network/react-archivist";
1003
+
1004
+ // src/Components/Legend.tsx
1005
+ import { useMediaQuery, useTheme as useTheme4 } from "@mui/material";
1006
+ import { FlexCol as FlexCol4 } from "@xylabs/react-flexbox";
1007
+
1008
+ // src/Components/Legends/ColorGradient.tsx
1009
+ import { Typography, useTheme as useTheme3 } from "@mui/material";
1010
+ import { FlexCol as FlexCol3, FlexRow as FlexRow2 } from "@xylabs/react-flexbox";
1011
+ import { jsx as jsx10, jsxs as jsxs2 } from "react/jsx-runtime";
1012
+ var ColorGradientLegend = ({ startColor, endColor, startLabel, endLabel, heading, textColor, ...props }) => {
1013
+ const theme = useTheme3();
1014
+ return /* @__PURE__ */ jsxs2(FlexCol3, { ...props, children: [
1015
+ /* @__PURE__ */ jsx10(Typography, { mb: theme.spacing(0.25), color: textColor, variant: "caption", textAlign: "center", children: heading }),
1016
+ /* @__PURE__ */ jsx10(FlexCol3, { flexGrow: 1, alignItems: "stretch", paddingX: theme.spacing(1), mb: theme.spacing(0.25), children: /* @__PURE__ */ jsx10(
1017
+ FlexCol3,
1018
+ {
1019
+ height: theme.spacing(0.75),
1020
+ border: `1px solid ${textColor}`,
1021
+ sx: { backgroundImage: `linear-gradient(to right, ${startColor},${endColor})` }
1022
+ }
1023
+ ) }),
1024
+ /* @__PURE__ */ jsxs2(FlexRow2, { flexGrow: 1, justifyContent: "space-between", children: [
1025
+ /* @__PURE__ */ jsx10(Typography, { color: textColor, variant: "caption", children: startLabel }),
1026
+ /* @__PURE__ */ jsx10(Typography, { color: textColor, variant: "caption", children: endLabel })
1027
+ ] })
1028
+ ] });
1029
+ };
1030
+
1031
+ // src/Components/Legend.tsx
1032
+ import { jsx as jsx11 } from "react/jsx-runtime";
1033
+ var AnimatedHeatMapLegend = ({ ...legendProps }) => {
1034
+ const { startColor, endColor, startLabel, endLabel, heading, textColor } = legendProps;
1035
+ const theme = useTheme4();
1036
+ const isSmall = useMediaQuery(theme.breakpoints.down("sm"));
1037
+ return /* @__PURE__ */ jsx11(FlexCol4, { position: "absolute", bottom: 0, right: 0, children: /* @__PURE__ */ jsx11(
1038
+ ColorGradientLegend,
1039
+ {
1040
+ startColor,
1041
+ endColor,
1042
+ startLabel,
1043
+ endLabel,
1044
+ heading,
1045
+ textColor,
1046
+ ...{
1047
+ alignItems: "stretch",
1048
+ marginBottom: theme.spacing(4),
1049
+ marginLeft: isSmall ? theme.spacing(3) : 0,
1050
+ marginRight: isSmall ? theme.spacing(2) : theme.spacing(3),
1051
+ width: isSmall ? "40vw" : theme.spacing(18)
1052
+ }
1053
+ }
1054
+ ) });
1055
+ };
1056
+
1057
+ // src/Components/AnimatedHeatMapLoaded.tsx
1058
+ import { jsx as jsx12, jsxs as jsxs3 } from "react/jsx-runtime";
1059
+ var AnimatedHeatMapLoaded = ({ accessToken, archivistNameOrAddress, ...props }) => {
1060
+ const hashes = useFindHashes();
1061
+ const [archivist] = useWeakArchivistFromNode(archivistNameOrAddress);
1062
+ const [payloads, xyoError] = useWeakArchivistGet(archivist, hashes);
1063
+ const { multipleFeatureSets } = useQuadKeyPayloadsToFeatures(payloads);
1064
+ const { heatMapColorProps, legendProps } = useHeatMapColors();
1065
+ const MapBoxHeatProps = {
1066
+ flexGrow: 1,
1067
+ legend: legendProps ? /* @__PURE__ */ jsx12(AnimatedHeatMapLegend, { ...legendProps }) : null
1068
+ };
1069
+ return /* @__PURE__ */ jsxs3(FlexCol5, { alignItems: "stretch", ...props, children: [
1070
+ xyoError ? /* @__PURE__ */ jsxs3(Alert, { sx: { mt: 2 }, children: [
1071
+ /* @__PURE__ */ jsx12(AlertTitle, { children: "Error Loading Map" }),
1072
+ xyoError.message ? `Error: ${xyoError.message}` : null,
1073
+ "You might try authenticating again."
1074
+ ] }) : null,
1075
+ hashes === void 0 ? /* @__PURE__ */ jsx12(Alert, { children: "Missing answer hash for heat map query" }) : /* @__PURE__ */ jsx12(
1076
+ AnimatedHeatMap,
1077
+ {
1078
+ accessToken,
1079
+ defaultMapSettings: AnimatedHeatMapSettings,
1080
+ animatedFeatureSets: multipleFeatureSets.slice(1, multipleFeatureSets.length),
1081
+ staticFeatureSet: multipleFeatureSets[0],
1082
+ heatMapColorProps,
1083
+ ...MapBoxHeatProps
1084
+ }
1085
+ )
1086
+ ] });
1087
+ };
1088
+
1089
+ // src/Components/HeatMapSettings.ts
1090
+ var HeatMapSettings = DefaultMapSettings();
1091
+ var { debugLayer: debugLayer2, scrollToZoom: scrollToZoom2, fitToPoints: fitToPoints2 } = HeatMapSettings;
1092
+ debugLayer2.hidden = false;
1093
+ scrollToZoom2.value = true;
1094
+ fitToPoints2.value = true;
1095
+
1096
+ // src/Components/LayerAnimator.tsx
1097
+ import { useInterval } from "@xylabs/react-shared";
1098
+ import { useCallback, useEffect as useEffect8, useRef as useRef2, useState as useState10 } from "react";
1099
+ import { Fragment, jsx as jsx13 } from "react/jsx-runtime";
1100
+ var timeIncrement = 2e3;
1101
+ var animatedLayerCount = 3;
1102
+ var LayerAnimator = ({ animateLayers, children, layers, layersInitialized, map }) => {
1103
+ const [fillLayers, setFillLayers] = useState10([]);
1104
+ const layerIndexQueue = useRef2([]);
1105
+ const incrementQueue = useCallback(
1106
+ (index) => {
1107
+ if (fillLayers[index]) {
1108
+ layerIndexQueue.current.push(index);
1109
+ } else {
1110
+ layerIndexQueue.current.push(0);
1111
+ }
1112
+ return layerIndexQueue.current.at(-1);
1113
+ },
1114
+ [fillLayers]
1115
+ );
1116
+ const lastQueuedIndex = useCallback(() => {
1117
+ const last = layerIndexQueue.current.at(-1);
1118
+ if (last === void 0) {
1119
+ incrementQueue(0);
1120
+ return 0;
1121
+ } else {
1122
+ return last;
1123
+ }
1124
+ }, [incrementQueue]);
1125
+ const unshiftQueue = useCallback(() => {
1126
+ layerIndexQueue.current.shift();
1127
+ }, []);
1128
+ const getNextLayer = useCallback(() => {
1129
+ const nextLayer = fillLayers[lastQueuedIndex()];
1130
+ incrementQueue(lastQueuedIndex() + 1);
1131
+ return nextLayer;
1132
+ }, [fillLayers, incrementQueue, lastQueuedIndex]);
1133
+ const layerAnimateWorker = useCallback(
1134
+ (layer) => {
1135
+ if (layer) {
1136
+ map?.setPaintProperty(layer.id, "fill-opacity", 0.85);
1137
+ setTimeout(() => {
1138
+ map?.setPaintProperty(layer.id, "fill-opacity", 0);
1139
+ unshiftQueue();
1140
+ }, timeIncrement * 2);
1141
+ } else {
1142
+ console.warn("tried to queue an empty layer");
1143
+ }
1144
+ },
1145
+ [map, unshiftQueue]
1146
+ );
1147
+ useEffect8(() => {
1148
+ if (layers?.length && map && layersInitialized) {
1149
+ setFillLayers(
1150
+ layers.filter((layer) => {
1151
+ const fillLayer = layer.id.startsWith("location-fill");
1152
+ if (fillLayer) {
1153
+ map.setPaintProperty(layer.id, "fill-opacity-transition", { delay: 0, duration: 4e3 });
1154
+ }
1155
+ return fillLayer;
1156
+ })
1157
+ );
1158
+ }
1159
+ }, [layers, layersInitialized, map]);
1160
+ const queueLayerAnimation = useCallback(() => {
1161
+ const animatedLayers = [];
1162
+ for (let i = 0; i < animatedLayerCount; i++) {
1163
+ animatedLayers.push(getNextLayer());
1164
+ }
1165
+ for (const [index, layer] of animatedLayers.entries()) {
1166
+ if (index === 0) {
1167
+ layerAnimateWorker(layer);
1168
+ } else {
1169
+ setTimeout(() => {
1170
+ layerAnimateWorker(layer);
1171
+ }, timeIncrement * index);
1172
+ }
1173
+ }
1174
+ }, [getNextLayer, layerAnimateWorker]);
1175
+ useEffect8(() => {
1176
+ if (animateLayers && layersInitialized && map && fillLayers.length > 0) {
1177
+ queueLayerAnimation();
1178
+ }
1179
+ }, [animateLayers, fillLayers.length, layersInitialized, map, queueLayerAnimation]);
1180
+ useInterval(() => {
1181
+ if (animateLayers && layersInitialized && map && fillLayers.length > 0) {
1182
+ queueLayerAnimation();
1183
+ }
1184
+ }, timeIncrement * animatedLayerCount);
1185
+ return /* @__PURE__ */ jsx13(Fragment, { children });
1186
+ };
1187
+
1188
+ // src/Components/MapBoxPoints.tsx
1189
+ import { Alert as Alert2 } from "@mui/material";
1190
+ import { FlexCol as FlexCol6 } from "@xylabs/react-flexbox";
1191
+ import { useCallback as useCallback2, useEffect as useEffect9, useState as useState11 } from "react";
1192
+ import { Fragment as Fragment2, jsx as jsx14, jsxs as jsxs4 } from "react/jsx-runtime";
1193
+ var MapboxPointsFlexBox = ({
1194
+ accessToken,
1195
+ features,
1196
+ fitToPointsPadding = 20,
1197
+ layers,
1198
+ zoom,
1199
+ ...props
1200
+ }) => {
1201
+ const [mapPoints, setMapPoints] = useState11();
1202
+ const { mapSettings } = useMapSettings();
1203
+ const { map, mapInitialized } = useMapBoxInstance();
1204
+ const customFitToBoundsOptions = (zoom2) => {
1205
+ if (zoom2 !== void 0) {
1206
+ return {
1207
+ maxZoom: zoom2
1208
+ };
1209
+ }
1210
+ return {};
1211
+ };
1212
+ const updateFeatures = useCallback2(() => {
1213
+ if (mapPoints?.isMapReady && features?.length && layers)
1214
+ for (const layer of layers) {
1215
+ mapPoints.initializeMapSource(layer);
1216
+ }
1217
+ }, [mapPoints, features, layers]);
1218
+ const updateMapSetup = useCallback2(() => {
1219
+ const { fitToPoints: fitToPoints3 } = mapSettings || {};
1220
+ if (mapPoints && map && fitToPoints3?.value === true) {
1221
+ mapPoints.initialMapPositioning({ padding: fitToPointsPadding, ...customFitToBoundsOptions(zoom) });
1222
+ }
1223
+ }, [mapSettings, mapPoints, map, fitToPointsPadding, zoom]);
1224
+ const reInitializeMap = useCallback2(() => {
1225
+ mapPoints?.initialMapPositioning({ padding: fitToPointsPadding, ...customFitToBoundsOptions(zoom) });
1226
+ updateFeatures();
1227
+ }, [mapPoints, fitToPointsPadding, updateFeatures, zoom]);
1228
+ useEffect9(() => {
1229
+ if (map && features?.length) {
1230
+ setMapPoints(new MapPoints({ features, map, zoom }));
1231
+ }
1232
+ }, [map, features, zoom]);
1233
+ useEffect9(() => {
1234
+ if (mapInitialized) {
1235
+ updateMapSetup();
1236
+ reInitializeMap();
1237
+ }
1238
+ }, [mapInitialized, reInitializeMap, updateMapSetup]);
1239
+ return /* @__PURE__ */ jsx14(FlexCol6, { alignItems: "stretch", id: "xyo-mapbox-wrap", ...props, children: features ? /* @__PURE__ */ jsxs4(Fragment2, { children: [
1240
+ /* @__PURE__ */ jsx14(MapBox, { accessToken, zoom }),
1241
+ /* @__PURE__ */ jsx14(MapSettingsBox, {})
1242
+ ] }) : /* @__PURE__ */ jsx14(Alert2, { severity: "error", children: "No data to show" }) });
1243
+ };
1244
+
1245
+ // src/types/NetworkLocationAnswerBase.ts
1246
+ import { isPayloadOfSchemaType } from "@xyo-network/payload-model";
1247
+ var NetworkLocationAnswerSchema = "network.xyo.location.range.answer";
1248
+ var isNetworkLocationAnswer = isPayloadOfSchemaType(NetworkLocationAnswerSchema);
1249
+ var NetworkLocationHeatmapAnswerSchema = "network.xyo.location.heatmap.answer";
1250
+ var isNetworkLocationHeatmapAnswer = isPayloadOfSchemaType(NetworkLocationHeatmapAnswerSchema);
1251
+ var NetworkLocationHeatmapQuadkeyAnswerSchema = "network.xyo.location.heatmap.quadkey.answer";
1252
+ var isNetworkLocationHeatmapQuadkeyAnswer = isPayloadOfSchemaType(
1253
+ NetworkLocationHeatmapQuadkeyAnswerSchema
1254
+ );
1255
+ export {
1256
+ AnimatedHeatMap,
1257
+ AnimatedHeatMapLegend,
1258
+ AnimatedHeatMapLoaded,
1259
+ AnimatedHeatMapSettings,
1260
+ CircleLayerBuilder,
1261
+ ColorGradientLegend,
1262
+ DefaultMapSettings,
1263
+ FillLayerBuilder,
1264
+ HeatMapFillLayerConfig,
1265
+ HeatMapInitializerProvider,
1266
+ HeatMapLineLayerConfig,
1267
+ HeatMapSettings,
1268
+ HeatMapSymbolLayerConfig,
1269
+ LayerAnimator,
1270
+ LineLayerBuilder,
1271
+ LocationHeatMapLayerBuilder,
1272
+ LocationHeatMapLayerBuilderAnimated,
1273
+ LocationPointLayerConfig,
1274
+ LocationPointsMapLayerBuilder,
1275
+ MapBase,
1276
+ MapBox,
1277
+ MapBoxInstanceProvider,
1278
+ MapHeat,
1279
+ MapHeatConstants,
1280
+ MapPoints,
1281
+ MapPointsConstants,
1282
+ MapSettingSwitch,
1283
+ MapSettings,
1284
+ MapSettingsBox,
1285
+ MapSettingsProvider,
1286
+ MapStyle,
1287
+ MapboxAccessTokenContext,
1288
+ MapboxAccessTokenProvider,
1289
+ MapboxHeatFlexBox,
1290
+ MapboxPointsFlexBox,
1291
+ NetworkLocationAnswerSchema,
1292
+ NetworkLocationHeatmapAnswerSchema,
1293
+ NetworkLocationHeatmapQuadkeyAnswerSchema,
1294
+ SymbolLayerBuilder,
1295
+ isNetworkLocationAnswer,
1296
+ isNetworkLocationHeatmapAnswer,
1297
+ isNetworkLocationHeatmapQuadkeyAnswer,
1298
+ useDynamicMapResize,
1299
+ useDynamicPositioning,
1300
+ useFindHashes,
1301
+ useHeatMapColors,
1302
+ useHeatMapInitializer,
1303
+ useMapBoxInstance,
1304
+ useMapSettings,
1305
+ useMapboxAccessToken,
1306
+ useQuadKeyPayloadsToFeatures
1307
+ };
3
1308
  //# sourceMappingURL=index.js.map