@xyo-network/react-map 2.64.0 → 2.64.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/dist/browser/AnimatedHeatMapSettings.js +56 -3
  2. package/dist/browser/AnimatedHeatMapSettings.js.map +1 -1
  3. package/dist/browser/Colors/index.js +0 -1
  4. package/dist/browser/Colors/index.js.map +1 -1
  5. package/dist/browser/Components/AnimatedHeatMap.js +623 -10
  6. package/dist/browser/Components/AnimatedHeatMap.js.map +1 -1
  7. package/dist/browser/Components/AnimatedHeatMapLoaded.js +864 -13
  8. package/dist/browser/Components/AnimatedHeatMapLoaded.js.map +1 -1
  9. package/dist/browser/Components/HeatMapSettings.js +56 -3
  10. package/dist/browser/Components/HeatMapSettings.js.map +1 -1
  11. package/dist/browser/Components/LayerAnimator.js +5 -4
  12. package/dist/browser/Components/LayerAnimator.js.map +1 -1
  13. package/dist/browser/Components/Legend.js +32 -7
  14. package/dist/browser/Components/Legend.js.map +1 -1
  15. package/dist/browser/Components/Legends/ColorGradient.js +3 -2
  16. package/dist/browser/Components/Legends/ColorGradient.js.map +1 -1
  17. package/dist/browser/Components/Legends/index.js +25 -1
  18. package/dist/browser/Components/Legends/index.js.map +1 -1
  19. package/dist/browser/Components/MapBox.js +66 -12
  20. package/dist/browser/Components/MapBox.js.map +1 -1
  21. package/dist/browser/Components/MapBoxHeat.js +151 -6
  22. package/dist/browser/Components/MapBoxHeat.js.map +1 -1
  23. package/dist/browser/Components/MapBoxPoints.js +207 -14
  24. package/dist/browser/Components/MapBoxPoints.js.map +1 -1
  25. package/dist/browser/Components/MapSettingsComponents/Setting.js +16 -3
  26. package/dist/browser/Components/MapSettingsComponents/Setting.js.map +1 -1
  27. package/dist/browser/Components/MapSettingsComponents/SettingsBox.js +38 -6
  28. package/dist/browser/Components/MapSettingsComponents/SettingsBox.js.map +1 -1
  29. package/dist/browser/Components/MapSettingsComponents/index.js +50 -2
  30. package/dist/browser/Components/MapSettingsComponents/index.js.map +1 -1
  31. package/dist/browser/Components/index.js +1084 -11
  32. package/dist/browser/Components/index.js.map +1 -1
  33. package/dist/browser/Contexts/HeatMapInitializer/Context.js +2 -1
  34. package/dist/browser/Contexts/HeatMapInitializer/Context.js.map +1 -1
  35. package/dist/browser/Contexts/HeatMapInitializer/Provider.js +235 -14
  36. package/dist/browser/Contexts/HeatMapInitializer/Provider.js.map +1 -1
  37. package/dist/browser/Contexts/HeatMapInitializer/index.js +294 -3
  38. package/dist/browser/Contexts/HeatMapInitializer/index.js.map +1 -1
  39. package/dist/browser/Contexts/HeatMapInitializer/useHeatMapInitializer.js +8 -2
  40. package/dist/browser/Contexts/HeatMapInitializer/useHeatMapInitializer.js.map +1 -1
  41. package/dist/browser/Contexts/MapBoxInstance/Context.js +2 -1
  42. package/dist/browser/Contexts/MapBoxInstance/Context.js.map +1 -1
  43. package/dist/browser/Contexts/MapBoxInstance/Provider.js +9 -3
  44. package/dist/browser/Contexts/MapBoxInstance/Provider.js.map +1 -1
  45. package/dist/browser/Contexts/MapBoxInstance/index.js +35 -3
  46. package/dist/browser/Contexts/MapBoxInstance/index.js.map +1 -1
  47. package/dist/browser/Contexts/MapBoxInstance/useMapBoxInstance.js +8 -2
  48. package/dist/browser/Contexts/MapBoxInstance/useMapBoxInstance.js.map +1 -1
  49. package/dist/browser/Contexts/MapSettings/Context.js +2 -1
  50. package/dist/browser/Contexts/MapSettings/Context.js.map +1 -1
  51. package/dist/browser/Contexts/MapSettings/Provider.js +117 -5
  52. package/dist/browser/Contexts/MapSettings/Provider.js.map +1 -1
  53. package/dist/browser/Contexts/MapSettings/index.js +148 -3
  54. package/dist/browser/Contexts/MapSettings/index.js.map +1 -1
  55. package/dist/browser/Contexts/MapSettings/useMapSettings.js +8 -2
  56. package/dist/browser/Contexts/MapSettings/useMapSettings.js.map +1 -1
  57. package/dist/browser/Contexts/MapboxAccessToken/Context.js +2 -1
  58. package/dist/browser/Contexts/MapboxAccessToken/Context.js.map +1 -1
  59. package/dist/browser/Contexts/MapboxAccessToken/Provider.js +9 -3
  60. package/dist/browser/Contexts/MapboxAccessToken/Provider.js.map +1 -1
  61. package/dist/browser/Contexts/MapboxAccessToken/index.js +22 -4
  62. package/dist/browser/Contexts/MapboxAccessToken/index.js.map +1 -1
  63. package/dist/browser/Contexts/MapboxAccessToken/use.js +8 -2
  64. package/dist/browser/Contexts/MapboxAccessToken/use.js.map +1 -1
  65. package/dist/browser/Contexts/index.js +459 -4
  66. package/dist/browser/Contexts/index.js.map +1 -1
  67. package/dist/browser/Layers/Builders/LocationHeatMapLayerBuilder.js +110 -6
  68. package/dist/browser/Layers/Builders/LocationHeatMapLayerBuilder.js.map +1 -1
  69. package/dist/browser/Layers/Builders/LocationHeatMapLayerBuilderAnimated.js +36 -4
  70. package/dist/browser/Layers/Builders/LocationHeatMapLayerBuilderAnimated.js.map +1 -1
  71. package/dist/browser/Layers/Builders/LocationPointsMapLayerBuilder.js +40 -4
  72. package/dist/browser/Layers/Builders/LocationPointsMapLayerBuilder.js.map +1 -1
  73. package/dist/browser/Layers/Builders/index.js +205 -3
  74. package/dist/browser/Layers/Builders/index.js.map +1 -1
  75. package/dist/browser/Layers/CircleLayer.js +3 -2
  76. package/dist/browser/Layers/CircleLayer.js.map +1 -1
  77. package/dist/browser/Layers/Configs/HeatMapFillLayerConfig.js +2 -1
  78. package/dist/browser/Layers/Configs/HeatMapFillLayerConfig.js.map +1 -1
  79. package/dist/browser/Layers/Configs/HeatMapLineLayerConfig.js +2 -1
  80. package/dist/browser/Layers/Configs/HeatMapLineLayerConfig.js.map +1 -1
  81. package/dist/browser/Layers/Configs/HeatMapSymbolLayerConfig.js +2 -1
  82. package/dist/browser/Layers/Configs/HeatMapSymbolLayerConfig.js.map +1 -1
  83. package/dist/browser/Layers/Configs/LocationPointLayerConfig.js +2 -1
  84. package/dist/browser/Layers/Configs/LocationPointLayerConfig.js.map +1 -1
  85. package/dist/browser/Layers/Configs/index.js +62 -4
  86. package/dist/browser/Layers/Configs/index.js.map +1 -1
  87. package/dist/browser/Layers/FillLayer.js +3 -2
  88. package/dist/browser/Layers/FillLayer.js.map +1 -1
  89. package/dist/browser/Layers/LineLayer.js +3 -2
  90. package/dist/browser/Layers/LineLayer.js.map +1 -1
  91. package/dist/browser/Layers/SymbolLayer.js +3 -2
  92. package/dist/browser/Layers/SymbolLayer.js.map +1 -1
  93. package/dist/browser/Layers/index.js +213 -7
  94. package/dist/browser/Layers/index.js.map +1 -1
  95. package/dist/browser/MapBoxClasses/MapBase.js +3 -2
  96. package/dist/browser/MapBoxClasses/MapBase.js.map +1 -1
  97. package/dist/browser/MapBoxClasses/MapHeat.js +41 -11
  98. package/dist/browser/MapBoxClasses/MapHeat.js.map +1 -1
  99. package/dist/browser/MapBoxClasses/MapPoints.js +33 -3
  100. package/dist/browser/MapBoxClasses/MapPoints.js.map +1 -1
  101. package/dist/browser/MapBoxClasses/MapSettings.js +6 -5
  102. package/dist/browser/MapBoxClasses/MapSettings.js.map +1 -1
  103. package/dist/browser/MapBoxClasses/index.js +288 -4
  104. package/dist/browser/MapBoxClasses/index.js.map +1 -1
  105. package/dist/browser/Settings/DefaultMapSettings.js +2 -1
  106. package/dist/browser/Settings/DefaultMapSettings.js.map +1 -1
  107. package/dist/browser/Settings/index.js +55 -2
  108. package/dist/browser/Settings/index.js.map +1 -1
  109. package/dist/browser/hooks/index.js +156 -5
  110. package/dist/browser/hooks/index.js.map +1 -1
  111. package/dist/browser/hooks/useDynamicMapResize.js +2 -1
  112. package/dist/browser/hooks/useDynamicMapResize.js.map +1 -1
  113. package/dist/browser/hooks/useDynamicPositioning.js +7 -6
  114. package/dist/browser/hooks/useDynamicPositioning.js.map +1 -1
  115. package/dist/browser/hooks/useFindHashes.js +4 -3
  116. package/dist/browser/hooks/useFindHashes.js.map +1 -1
  117. package/dist/browser/hooks/useHeatMapColors.js +2 -1
  118. package/dist/browser/hooks/useHeatMapColors.js.map +1 -1
  119. package/dist/browser/hooks/useQuadKeyPayloadsToFeatures.js +4 -3
  120. package/dist/browser/hooks/useQuadKeyPayloadsToFeatures.js.map +1 -1
  121. package/dist/browser/index.js +1298 -10
  122. package/dist/browser/index.js.map +1 -1
  123. package/dist/browser/lib/MapStyle.js +1 -0
  124. package/dist/browser/lib/MapStyle.js.map +1 -1
  125. package/dist/browser/lib/index.js +13 -2
  126. package/dist/browser/lib/index.js.map +1 -1
  127. package/dist/browser/types/index.js +0 -1
  128. package/dist/browser/types/index.js.map +1 -1
  129. package/dist/docs.json +296 -296
  130. package/package.json +14 -14
@@ -1,12 +1,1085 @@
1
- export * from "./AnimatedHeatMap";
2
- export * from "./AnimatedHeatMapLoaded";
3
- export * from "./FeaturesToLayersMap";
4
- export * from "./HeatMapSettings";
5
- export * from "./LayerAnimator";
6
- export * from "./Legend";
7
- export * from "./Legends";
8
- export * from "./MapBox";
9
- export * from "./MapBoxHeat";
10
- export * from "./MapBoxPoints";
11
- export * from "./MapSettingsComponents";
1
+ // src/Components/AnimatedHeatMap.tsx
2
+ import { darken, useTheme as useTheme2 } from "@mui/material";
3
+ import { FlexCol as FlexCol2 } from "@xylabs/react-flexbox";
4
+ import { useState as useState8 } from "react";
5
+
6
+ // src/Contexts/HeatMapInitializer/Provider.tsx
7
+ import { forget as forget2 } from "@xylabs/forget";
8
+ import { useEffect as useEffect6, useState as useState6 } from "react";
9
+
10
+ // src/hooks/useDynamicMapResize.tsx
11
+ import { useEffect, useMemo, useState } from "react";
12
+ var useDynamicMapResize = (mapContainerRef, mapCanvasRef, mapInstance, active = true) => {
13
+ const [dependenciesReady, setDependenciesReady] = useState(false);
14
+ const resizer = useMemo(
15
+ () => new ResizeObserver(() => {
16
+ const width = mapContainerRef.current?.getBoundingClientRect().width;
17
+ if (width && mapCanvasRef.current) {
18
+ mapCanvasRef.current.style.width = `${width}px`;
19
+ setTimeout(() => mapInstance?.resize());
20
+ }
21
+ }),
22
+ [mapCanvasRef, mapContainerRef, mapInstance]
23
+ );
24
+ useEffect(() => {
25
+ const dependenciesReady2 = !!(active && mapInstance && mapContainerRef?.current && mapCanvasRef.current);
26
+ setDependenciesReady(dependenciesReady2);
27
+ }, [active, mapCanvasRef, mapContainerRef, mapInstance]);
28
+ useEffect(() => {
29
+ if (dependenciesReady) {
30
+ if (mapContainerRef.current) {
31
+ resizer.observe(mapContainerRef.current);
32
+ }
33
+ return () => {
34
+ resizer.disconnect();
35
+ };
36
+ }
37
+ }, [active, dependenciesReady, mapCanvasRef, mapContainerRef, mapInstance, resizer]);
38
+ };
39
+
40
+ // src/hooks/useDynamicPositioning.tsx
41
+ import { useWindowSize } from "@xylabs/react-shared";
42
+ import { useEffect as useEffect2, useState as useState2 } from "react";
43
+ var defaultZoom = 1.6;
44
+ var defaultAspectRatioRange = [0.5, 2];
45
+ var latRange = [0.9121644205263664, 1.71785031559439];
46
+ var lngRange = [-81.4742014851959, 12.788958675506933];
47
+ var linearInterpolate = (aspectRatio, degreeRange, aspectRatioRange) => {
48
+ const [degreeMin, degreeMax] = degreeRange;
49
+ const [aspectRatioMin, aspectRatioMax] = aspectRatioRange || defaultAspectRatioRange;
50
+ const aspectRatioRangeSpan = aspectRatioMax - aspectRatioMin;
51
+ const degreeRangeSpan = degreeMax - degreeMin;
52
+ const percent = (aspectRatio - aspectRatioMin) / aspectRatioRangeSpan;
53
+ const scaledDegree = percent * degreeRangeSpan + degreeMin;
54
+ return scaledDegree;
55
+ };
56
+ var useDynamicPositioning = () => {
57
+ const [options, setOptions] = useState2({});
58
+ const { width, height } = useWindowSize();
59
+ useEffect2(() => {
60
+ if (width && height) {
61
+ const aspectRatio = width / height;
62
+ setOptions({
63
+ center: [linearInterpolate(aspectRatio, lngRange), linearInterpolate(aspectRatio, latRange)],
64
+ zoom: defaultZoom
65
+ });
66
+ }
67
+ }, [height, width]);
68
+ return { options };
69
+ };
70
+
71
+ // src/hooks/useFindHashes.tsx
72
+ import { useNetwork } from "@xyo-network/react-network";
73
+ import { useMemo as useMemo2 } from "react";
74
+ var animatedAnswerHashesConst = [
75
+ "79af071f451fc7af10d009dc63236ef9a9b211732c1ee0c06f028fcecf2336c5",
76
+ "531bfba6d8dfefd3bcc888aca54cdbbd4574ed2b3ec551b230845a1f9a608898",
77
+ "c874412b4faa4947de81372fd1ba12fdd6f43f5e408622b7f357cb2bcb3f17cb",
78
+ "29d3f8b882c61a82a1a1675782a27e797ea7196f45a23b4409680ab8b8d5f14e",
79
+ "cfd20f80ac073fd9518f4ef3f43d2a1f5e4e56e40c2677f38d6f6fecd05df60c",
80
+ "1354fa73497519a39aed19fc99bdbae78a880a1eafb2f7898d607e07db36528d",
81
+ "1043b0d25eacfc5013ae9dba780305a6fbf01a43543bd871d7c00537fca142a9",
82
+ "973dfc5df142851ced258d52d0ac2784e814000ac22e35776f772256b0d4dde9",
83
+ "463808eb74d3d87e6563970e0301a493577f8cd1b501e6e0ffa5e027ad2cea95",
84
+ "15b21acea2e3fd9d1ace3768a72636ee7bdf67a6f8e0807bfa2273dea2207555",
85
+ "32d377bfe7ebe382598c54dd13f8af7510e0a1e2fd2e913311fdd58e517e5e2e,"
86
+ ];
87
+ var staticAnswerHashConst = "c7bbf61f61cfd4a1b2def160c28136fc1d100d39fbdb67b227a2c6e558d9d3a5";
88
+ var useFindHashes = () => {
89
+ const { network } = useNetwork();
90
+ const exploreMapHashes = network?.nodes?.find((node) => node.type === "archivist")?.explorerMapHashes;
91
+ const animatedAnswerHashes = exploreMapHashes?.animatedAnswerHashes || animatedAnswerHashesConst;
92
+ const staticAnswerHash = exploreMapHashes?.staticAnswerHash || staticAnswerHashConst;
93
+ const foundHashes = useMemo2(() => [staticAnswerHash, ...animatedAnswerHashes], [animatedAnswerHashes, staticAnswerHash]);
94
+ return foundHashes;
95
+ };
96
+
97
+ // src/hooks/useHeatMapColors.tsx
98
+ import { useTheme } from "@mui/material";
99
+ var useHeatMapColors = () => {
100
+ const theme = useTheme();
101
+ const staticMapColor = "#FFFF75";
102
+ const highUsageColor = "#FF0000";
103
+ const heatMapColorProps = {
104
+ highUsageColor,
105
+ lowUsageColor: "#FFB3B3",
106
+ staticMapColor
107
+ };
108
+ const legendProps = {
109
+ endColor: highUsageColor,
110
+ endLabel: "High",
111
+ heading: "Network Usage",
112
+ startColor: staticMapColor,
113
+ startLabel: "Low",
114
+ textColor: theme.palette.common.white
115
+ };
116
+ return { heatMapColorProps, legendProps };
117
+ };
118
+
119
+ // src/hooks/useQuadKeyPayloadsToFeatures.tsx
120
+ import { compact } from "@xylabs/lodash";
121
+ import { GeoJson } from "@xyo-network/sdk-geo";
122
+ import { useEffect as useEffect3, useState as useState3 } from "react";
123
+ var quadKeyToFeature = ({ density, quadkey }) => {
124
+ const polygonFeature = new GeoJson(quadkey).polygonFeature();
125
+ polygonFeature.properties = {
126
+ count: density,
127
+ density
128
+ };
129
+ return polygonFeature;
130
+ };
131
+ var setDensity = (feature) => {
132
+ if (feature.properties) {
133
+ feature.properties.value = feature.properties.density / 5;
134
+ }
135
+ return feature;
136
+ };
137
+ var useQuadKeyPayloadsToFeatures = (payloads) => {
138
+ const [multipleFeatureSets, setMultipleFeatureSets] = useState3([[]]);
139
+ const [features, setFeatures] = useState3([]);
140
+ const [error, setError] = useState3();
141
+ useEffect3(() => {
142
+ if (Array.isArray(payloads)) {
143
+ if (compact(payloads).length !== 0) {
144
+ const payloadsArray = payloads;
145
+ const mappedFeatures = payloadsArray?.map((payload) => payload?.result.map(quadKeyToFeature));
146
+ setMultipleFeatureSets(mappedFeatures.map((features2) => features2?.map(setDensity) ?? []));
147
+ } else {
148
+ setError(new Error("Cannot find payloads for provided hashes"));
149
+ }
150
+ }
151
+ if (payloads && payloads.result) {
152
+ const singlePayload = payloads;
153
+ const mappedFeatures = singlePayload.result.map(quadKeyToFeature);
154
+ setFeatures(mappedFeatures.map(setDensity));
155
+ }
156
+ }, [payloads]);
157
+ return { error, features, multipleFeatureSets };
158
+ };
159
+
160
+ // src/MapBoxClasses/MapBase.ts
161
+ import { assertEx } from "@xylabs/assert";
162
+ import { GeoJson as GeoJson2 } from "@xyo-network/sdk-geo";
163
+ var MapBase = class {
164
+ _config;
165
+ constructor(config) {
166
+ this._config = { requestLocation: true, zoom: 2, ...config };
167
+ }
168
+ get isMapReady() {
169
+ return !!this._config.map;
170
+ }
171
+ initializeMapSource(layer) {
172
+ const getSource = () => {
173
+ const featuresCollection = GeoJson2.featureCollection(this._config.features);
174
+ return GeoJson2.featuresSource(featuresCollection);
175
+ };
176
+ const existingSource = this._config.map.getSource(layer.source);
177
+ const source = getSource();
178
+ if (existingSource) {
179
+ existingSource.setData(assertEx(source.data));
180
+ } else {
181
+ this._config.map.addSource(layer.source, source);
182
+ }
183
+ layer.update(this._config.map, true);
184
+ return this;
185
+ }
186
+ };
187
+
188
+ // src/MapBoxClasses/MapHeat.ts
189
+ import { assertEx as assertEx2 } from "@xylabs/assert";
190
+ import { delay } from "@xylabs/delay";
191
+ import { forget } from "@xylabs/forget";
192
+ import { GeoJson as GeoJson3 } from "@xyo-network/sdk-geo";
193
+ import { LngLatBounds } from "mapbox-gl";
194
+ var MapHeat = class extends MapBase {
195
+ static animationStarted = false;
196
+ config;
197
+ constructor(config) {
198
+ super(config);
199
+ this.config = config;
200
+ }
201
+ static initialMapPositioning(options, map, features, initialBounds) {
202
+ if (!features) {
203
+ return;
204
+ }
205
+ let bounds;
206
+ if (initialBounds) {
207
+ bounds = initialBounds;
208
+ } else {
209
+ bounds = new LngLatBounds();
210
+ features.forEach((feature) => {
211
+ feature.geometry.coordinates.forEach((coordinates) => {
212
+ coordinates.forEach((position) => {
213
+ bounds.extend(position);
214
+ });
215
+ });
216
+ });
217
+ }
218
+ map.setCenter(bounds.getCenter());
219
+ map.fitBounds(bounds, options);
220
+ return this;
221
+ }
222
+ static async initializeAnimatedHeatMapSource(layers, featureSet, map, startColor, endColor) {
223
+ this.animationStarted = true;
224
+ let layerTick = 0;
225
+ let sourceTick = 0;
226
+ const sources = featureSet.map((feature) => {
227
+ const featuresCollection = GeoJson3.featureCollection(feature);
228
+ return GeoJson3.featuresSource(featuresCollection);
229
+ });
230
+ this.updateLayer(map, layers[0], sources[0]);
231
+ this.updateLayer(map, layers[1], sources[1]);
232
+ layers.forEach((layer) => {
233
+ map.setPaintProperty(layer.id, "fill-opacity", 0);
234
+ });
235
+ const frameLength = 3e3;
236
+ const initialPad = 0.5;
237
+ const factor = 10;
238
+ const steps = 30;
239
+ const stepLength = frameLength / steps;
240
+ const lowUsageColor = startColor ?? "#FFB3B3";
241
+ const highUsageColor = endColor ?? "#FF0000";
242
+ const dynamicFillColor = (factor2, initialPad2, i) => {
243
+ const sinFade = Math.sin(i / steps * Math.PI / 2);
244
+ const cosFade = Math.cos(i / steps * Math.PI / 2);
245
+ const divisor = factor2 + factor2 * sinFade;
246
+ const offset = initialPad2 * cosFade;
247
+ return [
248
+ "let",
249
+ "density",
250
+ ["+", ["/", ["number", ["get", "value"]], divisor], offset],
251
+ ["interpolate", ["linear"], ["var", "density"], 0, lowUsageColor, 0.5, highUsageColor]
252
+ ];
253
+ };
254
+ const fadedIn = layers.map((_) => false);
255
+ const fadeIn = async (id, index) => {
256
+ for (let i = steps; i >= 1; i--) {
257
+ map.setPaintProperty(id, "fill-color", dynamicFillColor(factor, initialPad, i * (180 / stepLength)));
258
+ await delay(stepLength);
259
+ }
260
+ fadedIn[index] = true;
261
+ };
262
+ const fadeOut = async (id, index) => {
263
+ for (let i = 1; i <= steps; i++) {
264
+ map.setPaintProperty(id, "fill-color", dynamicFillColor(factor, initialPad, i * (180 / stepLength)));
265
+ await delay(stepLength);
266
+ }
267
+ fadedIn[index] = false;
268
+ };
269
+ let started = false;
270
+ const startAnimation = async () => {
271
+ assertEx2(!started, "Animation Already Started");
272
+ started = true;
273
+ while (this.animationStarted) {
274
+ const upLayer = layerTick % layers.length;
275
+ const downLayer = (layerTick + 1) % layers.length;
276
+ const incomingSource = sourceTick % featureSet.length;
277
+ const outgoingSource = (sourceTick + 1) % featureSet.length;
278
+ if (fadedIn[upLayer]) {
279
+ this.updateLayer(map, layers[upLayer], sources[incomingSource]);
280
+ forget(fadeOut(layers[upLayer].id, upLayer));
281
+ }
282
+ if (!fadedIn[downLayer]) {
283
+ this.updateLayer(map, layers[downLayer], sources[outgoingSource]);
284
+ forget(fadeIn(layers[downLayer].id, downLayer));
285
+ }
286
+ while ((fadedIn[upLayer] || !fadedIn[downLayer]) && this.animationStarted) {
287
+ await delay(1e3);
288
+ }
289
+ layerTick++;
290
+ sourceTick++;
291
+ }
292
+ };
293
+ await startAnimation();
294
+ }
295
+ static updateLayer(map, layer, source) {
296
+ const existingSource = map.getSource(layer.source);
297
+ if (existingSource && source.data) {
298
+ existingSource.setData(source.data);
299
+ } else if (source) {
300
+ map.addSource(layer.source, source);
301
+ }
302
+ layer.update(map, true);
303
+ }
304
+ // Build layers each with the same features
305
+ initializeHeatMapSource(layers) {
306
+ const getSource = (_) => {
307
+ const featuresCollection = GeoJson3.featureCollection(this.config.features);
308
+ return GeoJson3.featuresSource(featuresCollection);
309
+ };
310
+ layers.forEach((layer, index) => {
311
+ const existingSource = this.config.map.getSource(layer.source);
312
+ const source = getSource(index);
313
+ if (existingSource) {
314
+ existingSource.setData(assertEx2(source.data));
315
+ } else {
316
+ this.config.map.addSource(layer.source, source);
317
+ }
318
+ layer.update(this.config.map, true);
319
+ });
320
+ return this;
321
+ }
322
+ };
323
+
324
+ // src/MapBoxClasses/MapPoints.ts
325
+ import { LngLatBounds as LngLatBounds2 } from "mapbox-gl";
326
+ var MapPoints = class extends MapBase {
327
+ config;
328
+ constructor(config) {
329
+ super(config);
330
+ this.config = config;
331
+ }
332
+ initialMapPositioning(options, initialBounds) {
333
+ let bounds;
334
+ if (initialBounds) {
335
+ bounds = initialBounds;
336
+ } else {
337
+ bounds = new LngLatBounds2();
338
+ this.config.features.forEach((feature) => {
339
+ bounds.extend(feature.geometry.coordinates);
340
+ });
341
+ }
342
+ this.config.map.setCenter(bounds.getCenter());
343
+ this.config.map.fitBounds(bounds, options);
344
+ return this.config.map;
345
+ }
346
+ };
347
+
348
+ // src/MapBoxClasses/MapSettings.ts
349
+ import { GeolocateControl, NavigationControl } from "mapbox-gl";
350
+ var MapSettings = class _MapSettings {
351
+ static geoLocateControl;
352
+ static mapListeners = {
353
+ logData: (ev, map) => {
354
+ const target = map || ev?.target;
355
+ if (target) {
356
+ console.log("zoom", target.getZoom());
357
+ console.log("center", target.getCenter());
358
+ }
359
+ }
360
+ };
361
+ static navControl;
362
+ static requestLocation;
363
+ static toggleControls(value, map, zoom, requestLocation) {
364
+ if (value) {
365
+ _MapSettings.addControls(map, zoom, requestLocation);
366
+ } else {
367
+ _MapSettings.removeControls(map);
368
+ }
369
+ return this;
370
+ }
371
+ static toggleDebugLayer(value, map, layerName) {
372
+ const debugLayer3 = map.getLayer(layerName);
373
+ if (debugLayer3) {
374
+ if (value) {
375
+ map.setLayoutProperty(layerName, "visibility", "visible");
376
+ } else {
377
+ map.setLayoutProperty(layerName, "visibility", "none");
378
+ }
379
+ }
380
+ return this;
381
+ }
382
+ static toggleDebugLogging(value, map) {
383
+ const debugEvents = ["resize", "zoomend", "dragend"];
384
+ if (value) {
385
+ this.mapListeners.logData(void 0, map);
386
+ debugEvents.forEach((event) => map.on(event, this.mapListeners.logData));
387
+ } else {
388
+ debugEvents.forEach((event) => map.off(event, this.mapListeners.logData));
389
+ }
390
+ }
391
+ static toggleScrollToZoom(value, map) {
392
+ if (value) {
393
+ map.scrollZoom.enable();
394
+ } else {
395
+ map.scrollZoom.disable();
396
+ }
397
+ return this;
398
+ }
399
+ static updateSettings(config) {
400
+ const { settings, map, zoom, requestLocation, debugLayerName = "" } = config;
401
+ const { scrollToZoom: scrollToZoom3, enableControls, debugLayer: debugLayer3, debugLogging } = settings;
402
+ _MapSettings.toggleControls(enableControls?.value, map, zoom, requestLocation).toggleScrollToZoom(scrollToZoom3?.value, map).toggleDebugLayer(debugLayer3?.value, map, debugLayerName).toggleDebugLogging(debugLogging.value, map);
403
+ }
404
+ // Needs to be static so we ensure controls are only instantiated once
405
+ static addControls(map, zoom, requestLocation) {
406
+ const geolocateControl = new GeolocateControl({
407
+ fitBoundsOptions: {
408
+ zoom: zoom || 2
409
+ },
410
+ positionOptions: {
411
+ enableHighAccuracy: true
412
+ },
413
+ trackUserLocation: true
414
+ });
415
+ const navControl = new NavigationControl({
416
+ showCompass: false
417
+ });
418
+ this.geoLocateControl = this.geoLocateControl || geolocateControl;
419
+ this.navControl = this.navControl || navControl;
420
+ if (!map.hasControl(this.geoLocateControl)) {
421
+ if (requestLocation) {
422
+ map.addControl(this.geoLocateControl);
423
+ }
424
+ }
425
+ if (!map.hasControl(this.navControl)) {
426
+ map.addControl(this.navControl, "top-left");
427
+ }
428
+ return this;
429
+ }
430
+ static removeControls(map) {
431
+ if (this.geoLocateControl && map.hasControl(this.geoLocateControl)) {
432
+ if (this.requestLocation) {
433
+ map.removeControl(this.geoLocateControl);
434
+ }
435
+ }
436
+ if (this.navControl && map.hasControl(this.navControl)) {
437
+ map.removeControl(this.navControl);
438
+ }
439
+ return this;
440
+ }
441
+ };
442
+
443
+ // src/Contexts/MapBoxInstance/Provider.tsx
444
+ import { useEffect as useEffect4, useState as useState4 } from "react";
445
+
446
+ // src/Contexts/MapBoxInstance/Context.ts
447
+ import { createContext } from "react";
448
+ var MapBoxInstanceContext = createContext({});
449
+
450
+ // src/Contexts/MapBoxInstance/Provider.tsx
451
+ import { jsx } from "react/jsx-runtime";
452
+ var MapBoxInstanceProvider = ({ children }) => {
453
+ const [map, setMapBoxInstance] = useState4();
454
+ const [mapInitialized, setMapInitialized] = useState4(false);
455
+ const value = { map, mapInitialized, setMapBoxInstance };
456
+ useEffect4(() => {
457
+ if (!mapInitialized && map) {
458
+ map?.on("load", () => {
459
+ setMapInitialized(true);
460
+ });
461
+ }
462
+ }, [map, mapInitialized, setMapInitialized]);
463
+ return /* @__PURE__ */ jsx(MapBoxInstanceContext.Provider, { value, children });
464
+ };
465
+
466
+ // src/Contexts/MapBoxInstance/useMapBoxInstance.tsx
467
+ import { assertEx as assertEx3 } from "@xylabs/assert";
468
+ import { useContext } from "react";
469
+ var useMapBoxInstance = () => {
470
+ const context = useContext(MapBoxInstanceContext);
471
+ assertEx3("map" in context, "useMapBoxInstance must be used within a MapBoxInstanceContext");
472
+ return context;
473
+ };
474
+
475
+ // src/Contexts/MapSettings/Provider.tsx
476
+ import { useEffect as useEffect5, useState as useState5 } from "react";
477
+
478
+ // src/Contexts/MapSettings/Context.ts
479
+ import { createContext as createContext2 } from "react";
480
+ var MapSettingsContext = createContext2({});
481
+
482
+ // src/Contexts/MapSettings/Provider.tsx
483
+ import { jsx as jsx2 } from "react/jsx-runtime";
484
+ var MapSettingsProvider = ({
485
+ children,
486
+ debugLayerName,
487
+ defaultMapSettings,
488
+ requestLocation,
489
+ zoom = 1
490
+ }) => {
491
+ const [mapSettings, setMapSettings] = useState5(defaultMapSettings || {});
492
+ const { map, mapInitialized } = useMapBoxInstance();
493
+ const value = {
494
+ mapSettings,
495
+ setMapSettings
496
+ };
497
+ useEffect5(() => {
498
+ if (mapSettings && map && mapInitialized) {
499
+ MapSettings.updateSettings({ debugLayerName, map, requestLocation, settings: mapSettings, zoom });
500
+ }
501
+ }, [debugLayerName, map, mapInitialized, mapSettings, requestLocation, zoom]);
502
+ return /* @__PURE__ */ jsx2(MapSettingsContext.Provider, { value, children });
503
+ };
504
+
505
+ // src/Contexts/MapSettings/useMapSettings.tsx
506
+ import { useContext as useContext2 } from "react";
507
+ var useMapSettings = () => {
508
+ const context = useContext2(MapSettingsContext);
509
+ return context;
510
+ };
511
+
512
+ // src/Contexts/HeatMapInitializer/Context.ts
513
+ import { createContext as createContext3 } from "react";
514
+ var HeatMapInitializerContext = createContext3({});
515
+
516
+ // src/Contexts/HeatMapInitializer/Provider.tsx
517
+ import { jsx as jsx3 } from "react/jsx-runtime";
518
+ var HeatMapInitializerProvider = ({
519
+ children,
520
+ featureSets,
521
+ featureSetsLayers,
522
+ features,
523
+ fitToPadding,
524
+ heatMapColorProps,
525
+ layers,
526
+ zoom
527
+ }) => {
528
+ const [mapHeat, setMapHeat] = useState6();
529
+ const { options } = useDynamicPositioning();
530
+ const { mapSettings } = useMapSettings();
531
+ const { map, mapInitialized } = useMapBoxInstance();
532
+ const value = {
533
+ MapHeat: mapHeat,
534
+ heatMapColorProps
535
+ };
536
+ useEffect6(() => {
537
+ if (mapInitialized && featureSets?.length && featureSets[0].length && map && featureSetsLayers?.length) {
538
+ const { lowUsageColor, highUsageColor } = heatMapColorProps;
539
+ forget2(MapHeat.initializeAnimatedHeatMapSource(featureSetsLayers, featureSets, map, lowUsageColor, highUsageColor));
540
+ }
541
+ return () => {
542
+ MapHeat.animationStarted = false;
543
+ };
544
+ }, [featureSets, featureSetsLayers, mapInitialized, map, heatMapColorProps]);
545
+ useEffect6(() => {
546
+ if (mapHeat && mapInitialized && features?.length && layers?.length) {
547
+ mapHeat.initializeHeatMapSource(layers);
548
+ }
549
+ }, [mapHeat, features?.length, layers, mapInitialized]);
550
+ useEffect6(() => {
551
+ if (mapInitialized) {
552
+ const { fitToPoints: fitToPoints3 } = mapSettings || {};
553
+ if (map) {
554
+ if (fitToPoints3?.value === true) {
555
+ MapHeat.initialMapPositioning({ padding: fitToPadding }, map, features);
556
+ } else if (options.zoom && options.center) {
557
+ map.setZoom(options.zoom);
558
+ map.setCenter(options.center);
559
+ }
560
+ }
561
+ }
562
+ }, [mapHeat, map, mapSettings, fitToPadding, options, mapInitialized, features]);
563
+ useEffect6(() => {
564
+ if (map && features?.length) {
565
+ setMapHeat(new MapHeat({ features, map, zoom }));
566
+ }
567
+ }, [map, features, zoom]);
568
+ return /* @__PURE__ */ jsx3(HeatMapInitializerContext.Provider, { value, children });
569
+ };
570
+
571
+ // src/Layers/Configs/HeatMapFillLayerConfig.ts
572
+ var HeatMapFillLayerConfig = (color) => ({
573
+ paint: {
574
+ "fill-color": color,
575
+ "fill-opacity": [
576
+ "let",
577
+ "density",
578
+ ["+", ["/", ["number", ["get", "value"]], 4], 0.125],
579
+ ["interpolate", ["linear"], ["var", "density"], 0.8, ["var", "density"], 1, 0.85]
580
+ ]
581
+ }
582
+ });
583
+
584
+ // src/Layers/FillLayer.ts
585
+ import { LayerBase } from "@xyo-network/sdk-geo";
586
+ var FillLayerBuilder = class extends LayerBase {
587
+ FillLayerOptions;
588
+ // ensures this class passes for `AnyLayer` type in MapBox
589
+ type = "fill";
590
+ constructor(id, source, FillLayerOptions) {
591
+ super(id, source);
592
+ this.FillLayerOptions = FillLayerOptions || { id: this.id, source: this.source };
593
+ }
594
+ buildLayer() {
595
+ return {
596
+ ...this.FillLayerOptions,
597
+ id: this.id,
598
+ source: this.source,
599
+ type: this.type
600
+ };
601
+ }
602
+ };
603
+
604
+ // src/Layers/Builders/LocationHeatMapLayerBuilder.ts
605
+ var MapHeatConstants = {
606
+ LocationDebugLayerId: "location-debug-id",
607
+ LocationDebugLayerSource: "location-debug-source",
608
+ LocationFillLayerId: "location-fill-id",
609
+ LocationFillLayerSource: "location-fill-source",
610
+ LocationLineLayerId: "location-line-id",
611
+ LocationLineLayerSource: "location-line-source"
612
+ };
613
+
614
+ // src/Layers/Builders/LocationHeatMapLayerBuilderAnimated.ts
615
+ var MapHeatConstants2 = (index, type) => ({
616
+ LocationDebugLayerId: `location-${type}-debug-id-${index}`,
617
+ LocationDebugLayerSource: `location-${type}-debug-source-${index}`,
618
+ LocationFillLayerId: `location-${type}-fill-id-${index}`,
619
+ LocationFillLayerSource: `location-${type}-fill-source-${index}`,
620
+ LocationLineLayerId: `location-${type}-line-id-${index}`,
621
+ LocationLineLayerSource: `location-${type}-line-source-${index}`
622
+ });
623
+ var LocationHeatMapLayerBuilderAnimated = (color, index, type = "") => {
624
+ const { LocationFillLayerId, LocationFillLayerSource } = MapHeatConstants2(index, type);
625
+ const fillLayerConfig = HeatMapFillLayerConfig(color);
626
+ const fillLayer = new FillLayerBuilder(LocationFillLayerId, LocationFillLayerSource, fillLayerConfig);
627
+ return fillLayer;
628
+ };
629
+
630
+ // src/Components/MapBoxHeat.tsx
631
+ import { FlexCol } from "@xylabs/react-flexbox";
632
+
633
+ // src/Components/MapBox.tsx
634
+ import "mapbox-gl/dist/mapbox-gl.css";
635
+ import { Map as Map3 } from "mapbox-gl";
636
+ import { useEffect as useEffect7, useRef, useState as useState7 } from "react";
637
+ import { jsx as jsx4 } from "react/jsx-runtime";
638
+ var MapBox = ({ accessToken, darkMode = false, options, zoom = 2, ...props }) => {
639
+ const [map, setMap] = useState7();
640
+ const mapContainerRef = useRef(null);
641
+ const mapCanvasRef = useRef(null);
642
+ const { setMapBoxInstance, map: mapInstance } = useMapBoxInstance();
643
+ const { mapSettings } = useMapSettings();
644
+ const activeResize = mapSettings?.dynamicMapResize.value;
645
+ useDynamicMapResize(mapContainerRef, mapCanvasRef, mapInstance, activeResize);
646
+ useEffect7(() => {
647
+ if (mapSettings?.preferDark?.value === true) {
648
+ map?.setStyle(`mapbox://styles/${"mapbox/dark-v10" /* Dark */}`);
649
+ } else {
650
+ map?.setStyle(`mapbox://styles/${darkMode ? "mapbox/dark-v10" /* Dark */ : "mapbox/light-v10" /* Light */}`);
651
+ }
652
+ }, [map, darkMode, mapSettings]);
653
+ useEffect7(() => {
654
+ const map2 = new Map3({
655
+ accessToken,
656
+ center: [0, 0],
657
+ container: mapContainerRef.current ?? "",
658
+ style: `mapbox://styles/${"mapbox/light-v10" /* Light */}`,
659
+ zoom,
660
+ ...options
661
+ });
662
+ setMapBoxInstance?.(map2);
663
+ setMap(map2);
664
+ mapCanvasRef.current = document.querySelector(".mapboxgl-canvas");
665
+ console.log("Created Map");
666
+ return () => {
667
+ console.log("Removing Map");
668
+ map2.remove();
669
+ };
670
+ }, [mapContainerRef, setMap, options, zoom, setMapBoxInstance, accessToken]);
671
+ return /* @__PURE__ */ jsx4(
672
+ "div",
673
+ {
674
+ ref: (el) => mapContainerRef.current = el,
675
+ style: {
676
+ bottom: 0,
677
+ left: 0,
678
+ position: "absolute",
679
+ right: 0,
680
+ top: 0,
681
+ ...props
682
+ }
683
+ }
684
+ );
685
+ };
686
+
687
+ // src/Components/MapSettingsComponents/Setting.tsx
688
+ import { FormControlLabel, Switch } from "@mui/material";
689
+ import { jsx as jsx5 } from "react/jsx-runtime";
690
+ var MapSettingSwitch = ({ developerMode, field, ...props }) => {
691
+ const { mapSettings, setMapSettings } = useMapSettings();
692
+ const setting = mapSettings?.[field];
693
+ const onLocalChange = (event) => {
694
+ if (setting) {
695
+ setMapSettings?.((previous) => {
696
+ previous[setting.field].value = event.target.checked;
697
+ return { ...previous };
698
+ });
699
+ }
700
+ };
701
+ if (setting?.devMode && developerMode === false) {
702
+ return null;
703
+ }
704
+ return setting?.hidden ? null : /* @__PURE__ */ jsx5(FormControlLabel, { label: setting?.label, control: /* @__PURE__ */ jsx5(Switch, { checked: setting?.value, onChange: onLocalChange, ...props }) });
705
+ };
706
+
707
+ // src/Components/MapSettingsComponents/SettingsBox.tsx
708
+ import { Paper, Stack } from "@mui/material";
709
+ import { FlexGrowRow, FlexRow } from "@xylabs/react-flexbox";
710
+ import { useAppSettings } from "@xyo-network/react-app-settings";
711
+ import { jsx as jsx6 } from "react/jsx-runtime";
712
+ var MapSettingsBox = ({ developerMode, ...props }) => {
713
+ const { mapSettings } = useMapSettings();
714
+ const { developerMode: devModeFromContext } = useAppSettings();
715
+ const resolveDeveloperMode = developerMode ?? devModeFromContext;
716
+ return mapSettings && resolveDeveloperMode ? /* @__PURE__ */ jsx6(FlexGrowRow, { bottom: 36, left: 10, position: "absolute", ...props, children: /* @__PURE__ */ jsx6(FlexRow, { paddingX: 2, children: /* @__PURE__ */ jsx6(Paper, { children: /* @__PURE__ */ jsx6(Stack, { direction: "row", spacing: 1, marginX: 1, children: Object.keys(mapSettings).map((key, index) => {
717
+ return /* @__PURE__ */ jsx6(MapSettingSwitch, { field: mapSettings[key].field, developerMode }, index);
718
+ }) }) }) }) }) : null;
719
+ };
720
+
721
+ // src/Components/MapBoxHeat.tsx
722
+ import { jsx as jsx7, jsxs } from "react/jsx-runtime";
723
+ var MapboxHeatFlexBox = ({ accessToken, children, mapBoxOptions, zoom, legend, developerMode, ...props }) => {
724
+ return /* @__PURE__ */ jsxs(FlexCol, { ...props, children: [
725
+ /* @__PURE__ */ jsx7(MapBox, { accessToken, options: mapBoxOptions, zoom }),
726
+ /* @__PURE__ */ jsx7(MapSettingsBox, { developerMode }),
727
+ legend,
728
+ children
729
+ ] });
730
+ };
731
+
732
+ // src/Components/AnimatedHeatMap.tsx
733
+ import { jsx as jsx8 } from "react/jsx-runtime";
734
+ var AnimatedHeatMap = ({
735
+ accessToken,
736
+ animatedFeatureSets,
737
+ defaultMapSettings,
738
+ heatMapColorProps,
739
+ staticFeatureSet,
740
+ ...props
741
+ }) => {
742
+ const theme = useTheme2();
743
+ const { staticMapColor, lowUsageColor, highUsageColor } = heatMapColorProps || {};
744
+ const localStaticMapColor = staticMapColor ?? theme.palette.primary.light;
745
+ const [layers] = useState8([
746
+ LocationHeatMapLayerBuilderAnimated(localStaticMapColor, 0, "static"),
747
+ LocationHeatMapLayerBuilderAnimated(lowUsageColor || localStaticMapColor, 0, "animated"),
748
+ LocationHeatMapLayerBuilderAnimated(highUsageColor || darken(localStaticMapColor, 0.9), 1, "animated")
749
+ ]);
750
+ return animatedFeatureSets?.length ? /* @__PURE__ */ jsx8(MapBoxInstanceProvider, { children: /* @__PURE__ */ jsx8(MapSettingsProvider, { defaultMapSettings, debugLayerName: MapHeatConstants.LocationDebugLayerId, children: /* @__PURE__ */ jsx8(
751
+ HeatMapInitializerProvider,
752
+ {
753
+ features: staticFeatureSet,
754
+ layers: [layers[0]],
755
+ featureSets: animatedFeatureSets,
756
+ featureSetsLayers: layers.slice(1, 3),
757
+ heatMapColorProps,
758
+ children: /* @__PURE__ */ jsx8(MapboxHeatFlexBox, { accessToken, ...props })
759
+ }
760
+ ) }) }) : /* @__PURE__ */ jsx8(FlexCol2, { minHeight: 160, minWidth: 160, busy: true });
761
+ };
762
+
763
+ // src/Components/AnimatedHeatMapLoaded.tsx
764
+ import { Alert, AlertTitle } from "@mui/material";
765
+ import { FlexCol as FlexCol5 } from "@xylabs/react-flexbox";
766
+ import { useArchivistFromNode, useArchivistGet } from "@xyo-network/react-archivist";
767
+
768
+ // src/Settings/DefaultMapSettings.ts
769
+ var DefaultMapSettings = () => ({
770
+ debugLayer: {
771
+ devMode: true,
772
+ field: "debugLayer",
773
+ hidden: true,
774
+ label: "Debug Layer",
775
+ value: false
776
+ },
777
+ debugLogging: {
778
+ devMode: true,
779
+ field: "debugLogging",
780
+ hidden: true,
781
+ label: "Debug Logging",
782
+ value: false
783
+ },
784
+ dynamicMapResize: {
785
+ devMode: true,
786
+ field: "dynamicMapResize",
787
+ hidden: true,
788
+ label: "Auto Map Resize",
789
+ value: true
790
+ },
791
+ enableControls: {
792
+ devMode: true,
793
+ field: "enableControls",
794
+ hidden: true,
795
+ label: "Map Controls",
796
+ value: false
797
+ },
798
+ fitToPoints: {
799
+ devMode: true,
800
+ field: "fitToPoints",
801
+ hidden: true,
802
+ label: "Fit To Points",
803
+ value: false
804
+ },
805
+ preferDark: {
806
+ devMode: false,
807
+ field: "preferDark",
808
+ hidden: true,
809
+ label: "Prefer dark",
810
+ value: false
811
+ },
812
+ scrollToZoom: {
813
+ devMode: true,
814
+ field: "scrollToZoom",
815
+ hidden: true,
816
+ label: "Scroll To Zoom",
817
+ value: false
818
+ }
819
+ });
820
+
821
+ // src/AnimatedHeatMapSettings.ts
822
+ var AnimatedHeatMapSettings = DefaultMapSettings();
823
+ var { debugLayer, scrollToZoom, fitToPoints, preferDark } = AnimatedHeatMapSettings;
824
+ debugLayer.hidden = false;
825
+ scrollToZoom.value = true;
826
+ fitToPoints.value = false;
827
+ preferDark.value = true;
828
+
829
+ // src/Components/Legend.tsx
830
+ import { useMediaQuery, useTheme as useTheme4 } from "@mui/material";
831
+ import { FlexCol as FlexCol4 } from "@xylabs/react-flexbox";
832
+
833
+ // src/Components/Legends/ColorGradient.tsx
834
+ import { Typography, useTheme as useTheme3 } from "@mui/material";
835
+ import { FlexCol as FlexCol3, FlexRow as FlexRow2 } from "@xylabs/react-flexbox";
836
+ import { jsx as jsx9, jsxs as jsxs2 } from "react/jsx-runtime";
837
+ var ColorGradientLegend = ({ startColor, endColor, startLabel, endLabel, heading, textColor, ...props }) => {
838
+ const theme = useTheme3();
839
+ return /* @__PURE__ */ jsxs2(FlexCol3, { ...props, children: [
840
+ /* @__PURE__ */ jsx9(Typography, { mb: theme.spacing(0.25), color: textColor, variant: "caption", textAlign: "center", children: heading }),
841
+ /* @__PURE__ */ jsx9(FlexCol3, { flexGrow: 1, alignItems: "stretch", paddingX: theme.spacing(1), mb: theme.spacing(0.25), children: /* @__PURE__ */ jsx9(
842
+ FlexCol3,
843
+ {
844
+ height: theme.spacing(0.75),
845
+ border: `1px solid ${textColor}`,
846
+ sx: { backgroundImage: `linear-gradient(to right, ${startColor},${endColor})` }
847
+ }
848
+ ) }),
849
+ /* @__PURE__ */ jsxs2(FlexRow2, { flexGrow: 1, justifyContent: "space-between", children: [
850
+ /* @__PURE__ */ jsx9(Typography, { color: textColor, variant: "caption", children: startLabel }),
851
+ /* @__PURE__ */ jsx9(Typography, { color: textColor, variant: "caption", children: endLabel })
852
+ ] })
853
+ ] });
854
+ };
855
+
856
+ // src/Components/Legend.tsx
857
+ import { jsx as jsx10 } from "react/jsx-runtime";
858
+ var AnimatedHeatMapLegend = ({ ...legendProps }) => {
859
+ const { startColor, endColor, startLabel, endLabel, heading, textColor } = legendProps;
860
+ const theme = useTheme4();
861
+ const isSmall = useMediaQuery(theme.breakpoints.down("sm"));
862
+ return /* @__PURE__ */ jsx10(FlexCol4, { position: "absolute", bottom: 0, right: 0, children: /* @__PURE__ */ jsx10(
863
+ ColorGradientLegend,
864
+ {
865
+ startColor,
866
+ endColor,
867
+ startLabel,
868
+ endLabel,
869
+ heading,
870
+ textColor,
871
+ ...{
872
+ alignItems: "stretch",
873
+ marginBottom: theme.spacing(4),
874
+ marginLeft: isSmall ? theme.spacing(3) : 0,
875
+ marginRight: isSmall ? theme.spacing(2) : theme.spacing(3),
876
+ width: isSmall ? "40vw" : theme.spacing(18)
877
+ }
878
+ }
879
+ ) });
880
+ };
881
+
882
+ // src/Components/AnimatedHeatMapLoaded.tsx
883
+ import { jsx as jsx11, jsxs as jsxs3 } from "react/jsx-runtime";
884
+ var AnimatedHeatMapLoaded = ({ accessToken, archivistNameOrAddress, ...props }) => {
885
+ const hashes = useFindHashes();
886
+ const [archivist] = useArchivistFromNode(archivistNameOrAddress);
887
+ const [payloads, xyoError] = useArchivistGet(archivist, hashes);
888
+ const { multipleFeatureSets } = useQuadKeyPayloadsToFeatures(payloads);
889
+ const { heatMapColorProps, legendProps } = useHeatMapColors();
890
+ const MapBoxHeatProps = {
891
+ flexGrow: 1,
892
+ legend: legendProps ? /* @__PURE__ */ jsx11(AnimatedHeatMapLegend, { ...legendProps }) : null
893
+ };
894
+ return /* @__PURE__ */ jsxs3(FlexCol5, { alignItems: "stretch", ...props, children: [
895
+ xyoError ? /* @__PURE__ */ jsxs3(Alert, { sx: { mt: 2 }, children: [
896
+ /* @__PURE__ */ jsx11(AlertTitle, { children: "Error Loading Map" }),
897
+ xyoError.message ? `Error: ${xyoError.message}` : null,
898
+ "You might try authenticating again."
899
+ ] }) : null,
900
+ hashes !== void 0 ? /* @__PURE__ */ jsx11(
901
+ AnimatedHeatMap,
902
+ {
903
+ accessToken,
904
+ defaultMapSettings: AnimatedHeatMapSettings,
905
+ animatedFeatureSets: multipleFeatureSets.slice(1, multipleFeatureSets.length),
906
+ staticFeatureSet: multipleFeatureSets[0],
907
+ heatMapColorProps,
908
+ ...MapBoxHeatProps
909
+ }
910
+ ) : /* @__PURE__ */ jsx11(Alert, { children: "Missing answer hash for heat map query" })
911
+ ] });
912
+ };
913
+
914
+ // src/Components/HeatMapSettings.ts
915
+ var HeatMapSettings = DefaultMapSettings();
916
+ var { debugLayer: debugLayer2, scrollToZoom: scrollToZoom2, fitToPoints: fitToPoints2 } = HeatMapSettings;
917
+ debugLayer2.hidden = false;
918
+ scrollToZoom2.value = true;
919
+ fitToPoints2.value = true;
920
+
921
+ // src/Components/LayerAnimator.tsx
922
+ import { useInterval } from "@xylabs/react-shared";
923
+ import { useCallback, useEffect as useEffect8, useRef as useRef2, useState as useState9 } from "react";
924
+ import { Fragment, jsx as jsx12 } from "react/jsx-runtime";
925
+ var timeIncrement = 2e3;
926
+ var animatedLayerCount = 3;
927
+ var LayerAnimator = ({ animateLayers, children, layers, layersInitialized, map }) => {
928
+ const [fillLayers, setFillLayers] = useState9([]);
929
+ const layerIndexQueue = useRef2([]);
930
+ const incrementQueue = useCallback(
931
+ (index) => {
932
+ if (fillLayers[index]) {
933
+ layerIndexQueue.current.push(index);
934
+ } else {
935
+ layerIndexQueue.current.push(0);
936
+ }
937
+ return layerIndexQueue.current.at(-1);
938
+ },
939
+ [fillLayers]
940
+ );
941
+ const lastQueuedIndex = useCallback(() => {
942
+ const last = layerIndexQueue.current.at(-1);
943
+ if (last === void 0) {
944
+ incrementQueue(0);
945
+ return 0;
946
+ } else {
947
+ return last;
948
+ }
949
+ }, [incrementQueue]);
950
+ const unshiftQueue = useCallback(() => {
951
+ layerIndexQueue.current.shift();
952
+ }, []);
953
+ const getNextLayer = useCallback(() => {
954
+ const nextLayer = fillLayers[lastQueuedIndex()];
955
+ incrementQueue(lastQueuedIndex() + 1);
956
+ return nextLayer;
957
+ }, [fillLayers, incrementQueue, lastQueuedIndex]);
958
+ const layerAnimateWorker = useCallback(
959
+ (layer) => {
960
+ if (layer) {
961
+ map?.setPaintProperty(layer.id, "fill-opacity", 0.85);
962
+ setTimeout(() => {
963
+ map?.setPaintProperty(layer.id, "fill-opacity", 0);
964
+ unshiftQueue();
965
+ }, timeIncrement * 2);
966
+ } else {
967
+ console.warn("tried to queue an empty layer");
968
+ }
969
+ },
970
+ [map, unshiftQueue]
971
+ );
972
+ useEffect8(() => {
973
+ if (layers?.length && map && layersInitialized) {
974
+ setFillLayers(
975
+ layers.filter((layer) => {
976
+ const fillLayer = layer.id.startsWith("location-fill");
977
+ if (fillLayer) {
978
+ map.setPaintProperty(layer.id, "fill-opacity-transition", { delay: 0, duration: 4e3 });
979
+ }
980
+ return fillLayer;
981
+ })
982
+ );
983
+ }
984
+ }, [layers, layersInitialized, map]);
985
+ const queueLayerAnimation = useCallback(() => {
986
+ const animatedLayers = [];
987
+ for (let i = 0; i < animatedLayerCount; i++) {
988
+ animatedLayers.push(getNextLayer());
989
+ }
990
+ animatedLayers.forEach((layer, index) => {
991
+ if (index === 0) {
992
+ layerAnimateWorker(layer);
993
+ } else {
994
+ setTimeout(() => {
995
+ layerAnimateWorker(layer);
996
+ }, timeIncrement * index);
997
+ }
998
+ });
999
+ }, [getNextLayer, layerAnimateWorker]);
1000
+ useEffect8(() => {
1001
+ if (animateLayers && layersInitialized && map && fillLayers.length) {
1002
+ queueLayerAnimation();
1003
+ }
1004
+ }, [animateLayers, fillLayers.length, layersInitialized, map, queueLayerAnimation]);
1005
+ useInterval(() => {
1006
+ if (animateLayers && layersInitialized && map && fillLayers.length) {
1007
+ queueLayerAnimation();
1008
+ }
1009
+ }, timeIncrement * animatedLayerCount);
1010
+ return /* @__PURE__ */ jsx12(Fragment, { children });
1011
+ };
1012
+
1013
+ // src/Components/MapBoxPoints.tsx
1014
+ import { Alert as Alert2 } from "@mui/material";
1015
+ import { FlexCol as FlexCol6 } from "@xylabs/react-flexbox";
1016
+ import { useCallback as useCallback2, useEffect as useEffect9, useState as useState10 } from "react";
1017
+ import { Fragment as Fragment2, jsx as jsx13, jsxs as jsxs4 } from "react/jsx-runtime";
1018
+ var MapboxPointsFlexBox = ({
1019
+ accessToken,
1020
+ features,
1021
+ fitToPointsPadding = 20,
1022
+ layers,
1023
+ zoom,
1024
+ ...props
1025
+ }) => {
1026
+ const [mapPoints, setMapPoints] = useState10();
1027
+ const { mapSettings } = useMapSettings();
1028
+ const { map, mapInitialized } = useMapBoxInstance();
1029
+ const customFitToBoundsOptions = (zoom2) => {
1030
+ if (zoom2 !== void 0) {
1031
+ return {
1032
+ maxZoom: zoom2
1033
+ };
1034
+ }
1035
+ return {};
1036
+ };
1037
+ const updateFeatures = useCallback2(() => {
1038
+ if (mapPoints?.isMapReady && features?.length) {
1039
+ layers?.forEach((layer) => {
1040
+ mapPoints.initializeMapSource(layer);
1041
+ });
1042
+ }
1043
+ }, [mapPoints, features, layers]);
1044
+ const updateMapSetup = useCallback2(() => {
1045
+ const { fitToPoints: fitToPoints3 } = mapSettings || {};
1046
+ if (mapPoints && map) {
1047
+ if (fitToPoints3?.value === true) {
1048
+ mapPoints.initialMapPositioning({ padding: fitToPointsPadding, ...customFitToBoundsOptions(zoom) });
1049
+ }
1050
+ }
1051
+ }, [mapSettings, mapPoints, map, fitToPointsPadding, zoom]);
1052
+ const reInitializeMap = useCallback2(() => {
1053
+ mapPoints?.initialMapPositioning({ padding: fitToPointsPadding, ...customFitToBoundsOptions(zoom) });
1054
+ updateFeatures();
1055
+ }, [mapPoints, fitToPointsPadding, updateFeatures, zoom]);
1056
+ useEffect9(() => {
1057
+ if (map && features?.length) {
1058
+ setMapPoints(new MapPoints({ features, map, zoom }));
1059
+ }
1060
+ }, [map, features, zoom]);
1061
+ useEffect9(() => {
1062
+ if (mapInitialized) {
1063
+ updateMapSetup();
1064
+ reInitializeMap();
1065
+ }
1066
+ }, [mapInitialized, reInitializeMap, updateMapSetup]);
1067
+ return /* @__PURE__ */ jsx13(FlexCol6, { alignItems: "stretch", id: "xyo-mapbox-wrap", ...props, children: features ? /* @__PURE__ */ jsxs4(Fragment2, { children: [
1068
+ /* @__PURE__ */ jsx13(MapBox, { accessToken, zoom }),
1069
+ /* @__PURE__ */ jsx13(MapSettingsBox, {})
1070
+ ] }) : /* @__PURE__ */ jsx13(Alert2, { severity: "error", children: "No data to show" }) });
1071
+ };
1072
+ export {
1073
+ AnimatedHeatMap,
1074
+ AnimatedHeatMapLegend,
1075
+ AnimatedHeatMapLoaded,
1076
+ ColorGradientLegend,
1077
+ HeatMapSettings,
1078
+ LayerAnimator,
1079
+ MapBox,
1080
+ MapSettingSwitch,
1081
+ MapSettingsBox,
1082
+ MapboxHeatFlexBox,
1083
+ MapboxPointsFlexBox
1084
+ };
12
1085
  //# sourceMappingURL=index.js.map