@aguacerowx/react-native 0.0.53 → 0.0.54

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 (261) hide show
  1. package/LICENSE +21 -0
  2. package/android/src/main/java/com/aguacerowx/reactnative/NexradRadarLayerView.java +14 -2
  3. package/android/src/main/java/com/aguacerowx/reactnative/WeatherFrameProcessorModule.java +77 -0
  4. package/index.js +1 -1
  5. package/ios/WeatherFrameProcessorModule.m +19 -15
  6. package/ios/WeatherFrameProcessorModule.swift +65 -0
  7. package/lib/commonjs/AguaceroContext.js +0 -4
  8. package/lib/commonjs/AguaceroContext.js.map +1 -1
  9. package/lib/commonjs/GridRenderLayer.js +62 -76
  10. package/lib/commonjs/GridRenderLayer.js.map +1 -1
  11. package/lib/commonjs/MapManager.js +110 -224
  12. package/lib/commonjs/MapManager.js.map +1 -1
  13. package/lib/commonjs/MapRegistry.js +21 -33
  14. package/lib/commonjs/MapRegistry.js.map +1 -1
  15. package/lib/commonjs/NexradRadarLayer.android.js +28 -100
  16. package/lib/commonjs/NexradRadarLayer.android.js.map +1 -1
  17. package/lib/commonjs/NexradRadarLayer.ios.js +26 -97
  18. package/lib/commonjs/NexradRadarLayer.ios.js.map +1 -1
  19. package/lib/commonjs/NexradSitesMapLayer.js +41 -61
  20. package/lib/commonjs/NexradSitesMapLayer.js.map +1 -1
  21. package/lib/commonjs/SatelliteLayer.android.js +26 -38
  22. package/lib/commonjs/SatelliteLayer.android.js.map +1 -1
  23. package/lib/commonjs/SatelliteLayer.ios.js +30 -42
  24. package/lib/commonjs/SatelliteLayer.ios.js.map +1 -1
  25. package/lib/commonjs/StyleApplicator.js +129 -175
  26. package/lib/commonjs/StyleApplicator.js.map +1 -1
  27. package/lib/commonjs/WeatherLayerManager.js +995 -1646
  28. package/lib/commonjs/WeatherLayerManager.js.map +1 -1
  29. package/lib/commonjs/aguaceroCoreDebugHooks.js +58 -130
  30. package/lib/commonjs/aguaceroCoreDebugHooks.js.map +1 -1
  31. package/lib/commonjs/aguaceroRnDebug.js +147 -288
  32. package/lib/commonjs/aguaceroRnDebug.js.map +1 -1
  33. package/lib/commonjs/cdnAuthenticatedFetch.js +104 -0
  34. package/lib/commonjs/cdnAuthenticatedFetch.js.map +1 -0
  35. package/lib/commonjs/dispatchViewManagerCommandCompat.js +51 -88
  36. package/lib/commonjs/dispatchViewManagerCommandCompat.js.map +1 -1
  37. package/lib/commonjs/gridCdnAuth.js +41 -50
  38. package/lib/commonjs/gridCdnAuth.js.map +1 -1
  39. package/lib/commonjs/index.js +14 -0
  40. package/lib/commonjs/index.js.map +1 -1
  41. package/lib/commonjs/nexrad/nexradAndroidController.js +851 -863
  42. package/lib/commonjs/nexrad/nexradAndroidController.js.map +1 -1
  43. package/lib/commonjs/nexrad/nexradCrossSectionSampleAtLatLon.bundled.js +62 -85
  44. package/lib/commonjs/nexrad/nexradCrossSectionSampleAtLatLon.bundled.js.map +1 -1
  45. package/lib/commonjs/nexrad/nexradDiag.js +32 -148
  46. package/lib/commonjs/nexrad/nexradDiag.js.map +1 -1
  47. package/lib/commonjs/nexrad/nexradLevel2Keys.js +261 -0
  48. package/lib/commonjs/nexrad/nexradLevel2Keys.js.map +1 -0
  49. package/lib/commonjs/nexrad/nexradLutBuild.js +64 -111
  50. package/lib/commonjs/nexrad/nexradLutBuild.js.map +1 -1
  51. package/lib/commonjs/nexrad/nexradMapboxFrameOpts.bundled.js +136 -164
  52. package/lib/commonjs/nexrad/nexradMapboxFrameOpts.bundled.js.map +1 -1
  53. package/lib/commonjs/nexrad/nexradSdkImports.js +51 -0
  54. package/lib/commonjs/nexrad/nexradSdkImports.js.map +1 -0
  55. package/lib/commonjs/nexrad/radarArchiveCore.bundled.js +2848 -4455
  56. package/lib/commonjs/nexrad/radarArchiveCore.bundled.js.map +1 -1
  57. package/lib/commonjs/nexrad/radarDecode.worker.bundled.js +445 -648
  58. package/lib/commonjs/nexrad/radarDecode.worker.bundled.js.map +1 -1
  59. package/lib/commonjs/nexrad/radarFrameGpuMatch.bundled.js +52 -68
  60. package/lib/commonjs/nexrad/radarFrameGpuMatch.bundled.js.map +1 -1
  61. package/lib/commonjs/nexradNativeCommandIds.js +24 -0
  62. package/lib/commonjs/nexradNativeCommandIds.js.map +1 -0
  63. package/lib/commonjs/nws/NwsAlertsOverlay.android.js.map +1 -1
  64. package/lib/commonjs/nws/NwsAlertsOverlay.ios.js.map +1 -1
  65. package/lib/commonjs/nws/NwsAlertsOverlay.js +3 -3
  66. package/lib/commonjs/nws/NwsAlertsOverlay.js.map +1 -1
  67. package/lib/commonjs/nws/NwsAlertsOverlay.native.js +235 -361
  68. package/lib/commonjs/nws/NwsAlertsOverlay.native.js.map +1 -1
  69. package/lib/commonjs/nws/eventSourceRnPolyfill.js +92 -146
  70. package/lib/commonjs/nws/eventSourceRnPolyfill.js.map +1 -1
  71. package/lib/commonjs/nws/nwsAndroidConstants.js +2 -8
  72. package/lib/commonjs/nws/nwsAndroidConstants.js.map +1 -1
  73. package/lib/commonjs/satellite/satelliteAndroidController.js +117 -202
  74. package/lib/commonjs/satellite/satelliteAndroidController.js.map +1 -1
  75. package/lib/commonjs/satelliteBridgeDiag.js +3 -13
  76. package/lib/commonjs/satelliteBridgeDiag.js.map +1 -1
  77. package/lib/commonjs/satelliteRnDebug.js +117 -218
  78. package/lib/commonjs/satelliteRnDebug.js.map +1 -1
  79. package/lib/module/AguaceroContext.js +2 -7
  80. package/lib/module/AguaceroContext.js.map +1 -1
  81. package/lib/module/GridRenderLayer.js +66 -80
  82. package/lib/module/GridRenderLayer.js.map +1 -1
  83. package/lib/module/MapManager.js +125 -239
  84. package/lib/module/MapManager.js.map +1 -1
  85. package/lib/module/MapRegistry.js +21 -33
  86. package/lib/module/MapRegistry.js.map +1 -1
  87. package/lib/module/NexradRadarLayer.android.js +32 -104
  88. package/lib/module/NexradRadarLayer.android.js.map +1 -1
  89. package/lib/module/NexradRadarLayer.ios.js +30 -101
  90. package/lib/module/NexradRadarLayer.ios.js.map +1 -1
  91. package/lib/module/NexradSitesMapLayer.js +44 -63
  92. package/lib/module/NexradSitesMapLayer.js.map +1 -1
  93. package/lib/module/SatelliteLayer.android.js +32 -44
  94. package/lib/module/SatelliteLayer.android.js.map +1 -1
  95. package/lib/module/SatelliteLayer.ios.js +36 -48
  96. package/lib/module/SatelliteLayer.ios.js.map +1 -1
  97. package/lib/module/StyleApplicator.js +144 -191
  98. package/lib/module/StyleApplicator.js.map +1 -1
  99. package/lib/module/WeatherLayerManager.js +1024 -1675
  100. package/lib/module/WeatherLayerManager.js.map +1 -1
  101. package/lib/module/aguaceroCoreDebugHooks.js +59 -130
  102. package/lib/module/aguaceroCoreDebugHooks.js.map +1 -1
  103. package/lib/module/aguaceroRnDebug.js +151 -292
  104. package/lib/module/aguaceroRnDebug.js.map +1 -1
  105. package/lib/module/cdnAuthenticatedFetch.js +97 -0
  106. package/lib/module/cdnAuthenticatedFetch.js.map +1 -0
  107. package/lib/module/dispatchViewManagerCommandCompat.js +52 -90
  108. package/lib/module/dispatchViewManagerCommandCompat.js.map +1 -1
  109. package/lib/module/gridCdnAuth.js +38 -50
  110. package/lib/module/gridCdnAuth.js.map +1 -1
  111. package/lib/module/index.js +9 -7
  112. package/lib/module/index.js.map +1 -1
  113. package/lib/module/nexrad/nexradAndroidController.js +865 -876
  114. package/lib/module/nexrad/nexradAndroidController.js.map +1 -1
  115. package/lib/module/nexrad/nexradCrossSectionSampleAtLatLon.bundled.js +62 -85
  116. package/lib/module/nexrad/nexradCrossSectionSampleAtLatLon.bundled.js.map +1 -1
  117. package/lib/module/nexrad/nexradDiag.js +31 -145
  118. package/lib/module/nexrad/nexradDiag.js.map +1 -1
  119. package/lib/module/nexrad/nexradLevel2Keys.js +245 -0
  120. package/lib/module/nexrad/nexradLevel2Keys.js.map +1 -0
  121. package/lib/module/nexrad/nexradLutBuild.js +64 -110
  122. package/lib/module/nexrad/nexradLutBuild.js.map +1 -1
  123. package/lib/module/nexrad/nexradMapboxFrameOpts.bundled.js +136 -163
  124. package/lib/module/nexrad/nexradMapboxFrameOpts.bundled.js.map +1 -1
  125. package/lib/module/nexrad/nexradSdkImports.js +4 -0
  126. package/lib/module/nexrad/nexradSdkImports.js.map +1 -0
  127. package/lib/module/nexrad/radarArchiveCore.bundled.js +2839 -4448
  128. package/lib/module/nexrad/radarArchiveCore.bundled.js.map +1 -1
  129. package/lib/module/nexrad/radarDecode.worker.bundled.js +445 -648
  130. package/lib/module/nexrad/radarDecode.worker.bundled.js.map +1 -1
  131. package/lib/module/nexrad/radarFrameGpuMatch.bundled.js +50 -66
  132. package/lib/module/nexrad/radarFrameGpuMatch.bundled.js.map +1 -1
  133. package/lib/module/nexradNativeCommandIds.js +18 -0
  134. package/lib/module/nexradNativeCommandIds.js.map +1 -0
  135. package/lib/module/nws/NwsAlertsOverlay.android.js +1 -1
  136. package/lib/module/nws/NwsAlertsOverlay.android.js.map +1 -1
  137. package/lib/module/nws/NwsAlertsOverlay.ios.js +1 -1
  138. package/lib/module/nws/NwsAlertsOverlay.ios.js.map +1 -1
  139. package/lib/module/nws/NwsAlertsOverlay.js +5 -5
  140. package/lib/module/nws/NwsAlertsOverlay.js.map +1 -1
  141. package/lib/module/nws/NwsAlertsOverlay.native.js +248 -373
  142. package/lib/module/nws/NwsAlertsOverlay.native.js.map +1 -1
  143. package/lib/module/nws/eventSourceRnPolyfill.js +92 -146
  144. package/lib/module/nws/eventSourceRnPolyfill.js.map +1 -1
  145. package/lib/module/nws/nwsAndroidConstants.js +2 -8
  146. package/lib/module/nws/nwsAndroidConstants.js.map +1 -1
  147. package/lib/module/satellite/satelliteAndroidController.js +123 -208
  148. package/lib/module/satellite/satelliteAndroidController.js.map +1 -1
  149. package/lib/module/satelliteBridgeDiag.js +3 -13
  150. package/lib/module/satelliteBridgeDiag.js.map +1 -1
  151. package/lib/module/satelliteRnDebug.js +123 -223
  152. package/lib/module/satelliteRnDebug.js.map +1 -1
  153. package/lib/typescript/AguaceroContext.d.ts +0 -4
  154. package/lib/typescript/AguaceroContext.d.ts.map +1 -1
  155. package/lib/typescript/GridRenderLayer.d.ts.map +1 -1
  156. package/lib/typescript/MapManager.d.ts +0 -12
  157. package/lib/typescript/MapManager.d.ts.map +1 -1
  158. package/lib/typescript/MapRegistry.d.ts +10 -12
  159. package/lib/typescript/MapRegistry.d.ts.map +1 -1
  160. package/lib/typescript/NexradRadarLayer.android.d.ts.map +1 -1
  161. package/lib/typescript/NexradRadarLayer.ios.d.ts.map +1 -1
  162. package/lib/typescript/NexradSitesMapLayer.d.ts +4 -10
  163. package/lib/typescript/NexradSitesMapLayer.d.ts.map +1 -1
  164. package/lib/typescript/SatelliteLayer.android.d.ts.map +1 -1
  165. package/lib/typescript/SatelliteLayer.ios.d.ts.map +1 -1
  166. package/lib/typescript/StyleApplicator.d.ts +1 -1
  167. package/lib/typescript/StyleApplicator.d.ts.map +1 -1
  168. package/lib/typescript/WeatherLayerManager.d.ts.map +1 -1
  169. package/lib/typescript/aguaceroCoreDebugHooks.d.ts +2 -9
  170. package/lib/typescript/aguaceroCoreDebugHooks.d.ts.map +1 -1
  171. package/lib/typescript/aguaceroRnDebug.d.ts +47 -66
  172. package/lib/typescript/aguaceroRnDebug.d.ts.map +1 -1
  173. package/lib/typescript/cdnAuthenticatedFetch.d.ts +10 -0
  174. package/lib/typescript/cdnAuthenticatedFetch.d.ts.map +1 -0
  175. package/lib/typescript/dispatchViewManagerCommandCompat.d.ts +1 -17
  176. package/lib/typescript/dispatchViewManagerCommandCompat.d.ts.map +1 -1
  177. package/lib/typescript/gridCdnAuth.d.ts +16 -21
  178. package/lib/typescript/gridCdnAuth.d.ts.map +1 -1
  179. package/lib/typescript/index.d.ts +1 -0
  180. package/lib/typescript/nexrad/nexradAndroidController.d.ts +39 -89
  181. package/lib/typescript/nexrad/nexradAndroidController.d.ts.map +1 -1
  182. package/lib/typescript/nexrad/nexradCrossSectionSampleAtLatLon.bundled.d.ts +2 -1
  183. package/lib/typescript/nexrad/nexradCrossSectionSampleAtLatLon.bundled.d.ts.map +1 -1
  184. package/lib/typescript/nexrad/nexradDiag.d.ts +13 -101
  185. package/lib/typescript/nexrad/nexradDiag.d.ts.map +1 -1
  186. package/lib/typescript/nexrad/nexradLevel2Keys.d.ts +36 -0
  187. package/lib/typescript/nexrad/nexradLevel2Keys.d.ts.map +1 -0
  188. package/lib/typescript/nexrad/nexradLutBuild.d.ts +3 -10
  189. package/lib/typescript/nexrad/nexradLutBuild.d.ts.map +1 -1
  190. package/lib/typescript/nexrad/nexradMapboxFrameOpts.bundled.d.ts +4 -3
  191. package/lib/typescript/nexrad/nexradMapboxFrameOpts.bundled.d.ts.map +1 -1
  192. package/lib/typescript/nexrad/nexradSdkImports.d.ts +2 -0
  193. package/lib/typescript/nexrad/nexradSdkImports.d.ts.map +1 -0
  194. package/lib/typescript/nexrad/radarArchiveCore.bundled.d.ts +12 -7
  195. package/lib/typescript/nexrad/radarArchiveCore.bundled.d.ts.map +1 -1
  196. package/lib/typescript/nexrad/radarDecode.worker.bundled.d.ts +20 -20
  197. package/lib/typescript/nexrad/radarDecode.worker.bundled.d.ts.map +1 -1
  198. package/lib/typescript/nexrad/radarFrameGpuMatch.bundled.d.ts +4 -3
  199. package/lib/typescript/nexrad/radarFrameGpuMatch.bundled.d.ts.map +1 -1
  200. package/lib/typescript/nexradNativeCommandIds.d.ts +2 -0
  201. package/lib/typescript/nexradNativeCommandIds.d.ts.map +1 -0
  202. package/lib/typescript/nws/NwsAlertsOverlay.native.d.ts +6 -17
  203. package/lib/typescript/nws/NwsAlertsOverlay.native.d.ts.map +1 -1
  204. package/lib/typescript/nws/eventSourceRnPolyfill.d.ts +0 -3
  205. package/lib/typescript/nws/eventSourceRnPolyfill.d.ts.map +1 -1
  206. package/lib/typescript/nws/nwsAndroidConstants.d.ts +0 -5
  207. package/lib/typescript/nws/nwsAndroidConstants.d.ts.map +1 -1
  208. package/lib/typescript/satellite/satelliteAndroidController.d.ts +9 -47
  209. package/lib/typescript/satellite/satelliteAndroidController.d.ts.map +1 -1
  210. package/lib/typescript/satelliteBridgeDiag.d.ts +1 -5
  211. package/lib/typescript/satelliteBridgeDiag.d.ts.map +1 -1
  212. package/lib/typescript/satelliteRnDebug.d.ts +24 -30
  213. package/lib/typescript/satelliteRnDebug.d.ts.map +1 -1
  214. package/package.json +75 -74
  215. package/src/AguaceroContext.js +1 -7
  216. package/src/GridRenderLayer.js +1 -128
  217. package/src/MapManager.js +1 -277
  218. package/src/MapRegistry.js +1 -56
  219. package/src/NexradRadarLayer.android.js +1 -121
  220. package/src/NexradRadarLayer.ios.js +1 -115
  221. package/src/NexradSitesMapLayer.js +1 -75
  222. package/src/SatelliteLayer.android.js +1 -63
  223. package/src/SatelliteLayer.ios.js +1 -70
  224. package/src/StyleApplicator.js +1 -241
  225. package/src/WeatherLayerManager.js +1 -2045
  226. package/src/aguaceroCoreDebugHooks.js +1 -142
  227. package/src/aguaceroRnDebug.js +1 -336
  228. package/src/cdnAuthenticatedFetch.js +1 -0
  229. package/src/dispatchViewManagerCommandCompat.js +1 -100
  230. package/src/gridCdnAuth.js +1 -56
  231. package/src/index.js +1 -27
  232. package/src/nexrad/nexradAndroidController.js +1 -1078
  233. package/src/nexrad/nexradCrossSectionSampleAtLatLon.bundled.js +1 -91
  234. package/src/nexrad/nexradDiag.js +1 -150
  235. package/src/nexrad/nexradLevel2Keys.js +1 -0
  236. package/src/nexrad/nexradLutBuild.js +1 -126
  237. package/src/nexrad/nexradMapboxFrameOpts.bundled.js +1 -245
  238. package/src/nexrad/nexradSdkImports.js +1 -0
  239. package/src/nexrad/radarArchiveCore.bundled.js +1 -7085
  240. package/src/nexrad/radarDecode.worker.bundled.js +1 -813
  241. package/src/nexrad/radarFrameGpuMatch.bundled.js +1 -79
  242. package/src/nexradNativeCommandIds.js +1 -0
  243. package/src/nws/NwsAlertsOverlay.android.js +1 -1
  244. package/src/nws/NwsAlertsOverlay.ios.js +1 -1
  245. package/src/nws/NwsAlertsOverlay.js +1 -7
  246. package/src/nws/NwsAlertsOverlay.native.js +1 -463
  247. package/src/nws/eventSourceRnPolyfill.js +7 -193
  248. package/src/nws/nwsAndroidConstants.js +1 -8
  249. package/src/satellite/satelliteAndroidController.js +1 -257
  250. package/src/satelliteBridgeDiag.js +1 -15
  251. package/src/satelliteRnDebug.js +1 -269
  252. package/lib/commonjs/nexrad/nexradNativeCommandIds.js +0 -51
  253. package/lib/commonjs/nexrad/nexradNativeCommandIds.js.map +0 -1
  254. package/lib/module/nexrad/nexradNativeCommandIds.js +0 -44
  255. package/lib/module/nexrad/nexradNativeCommandIds.js.map +0 -1
  256. package/lib/typescript/nexrad/nexradNativeCommandIds.d.ts +0 -9
  257. package/lib/typescript/nexrad/nexradNativeCommandIds.d.ts.map +0 -1
  258. package/src/nexrad/nexradNativeCommandIds.js +0 -44
  259. /package/lib/commonjs/{nexrad/nexradSitesUs.json → nexradSitesUs.json} +0 -0
  260. /package/lib/module/{nexrad/nexradSitesUs.json → nexradSitesUs.json} +0 -0
  261. /package/src/{nexrad/nexradSitesUs.json → nexradSitesUs.json} +0 -0
@@ -1,1024 +1,1013 @@
1
- /**
2
- * AguaceroCore NEXRAD Android native custom layer (parity with mapsgl {@link NexradWeatherController}).
3
- */
4
- import { getUnitConversionFunction, getDefaultRadarTilt, nexradBinGroupIdForKey, variableToNexradGroup } from '@aguacerowx/javascript-sdk';
5
- import { fromByteArray } from 'base64-js';
6
- import { fetchAndParseArchive, objectKeyToUrl, setNexradArchiveApiKey, setNexradArchiveBundleId, setNexradArchiveSiteOrigin, setNexradSitesJsonUrl, setNexradSitesFetchAuth } from './radarArchiveCore.bundled.js';
7
- import { prepareRadarFrameForGpuReadout } from './radarFrameGpuMatch.bundled.js';
8
- import { mapboxFrameUploadOptionsForNexradState } from './nexradMapboxFrameOpts.bundled.js';
9
- import { sampleNexradFrameAtLatLon } from './nexradCrossSectionSampleAtLatLon.bundled.js';
10
- import { buildNexradLutRgba } from './nexradLutBuild.js';
11
- import { Platform } from 'react-native';
12
- import { nexradDiagBootSnapshot, nexradDiagGateTextureSummary, nexradPerfSpan } from './nexradDiag.js';
13
- import { aguaceroDebug, getAguaceroAuthDiagnosticSnapshot, isAguaceroRnDebugEnabled } from '../aguaceroRnDebug';
14
- nexradDiagBootSnapshot({
1
+ import { getUnitConversionFunction as O, getDefaultRadarTilt as Q, nexradBinGroupIdForKey as X, variableToNexradGroup as ee } from "./nexradSdkImports.js";
2
+ import { fetchAndApplyLevel2ListingToCore as te, isValidLevel2SweepObjectKey as j, level2ListingCacheNeedsRefresh as D, level2ListingEmptyHint as ae, listingContextParams as E, rebuildLevel2TimeToKeyMap as re, resolveLevel2ObjectKeyForFetch as ie } from "./nexradLevel2Keys.js";
3
+ import { fromByteArray as J } from "base64-js";
4
+ import { fetchAndParseArchive as k, getNexradArchiveAuthSnapshot as ne, objectKeyToUrl as G, setNexradArchiveApiKey as L, setNexradArchiveBundleId as R, setNexradArchiveSiteOrigin as w, setNexradArchiveUserId as $, setNexradSitesJsonUrl as se, setNexradSitesFetchAuth as B } from "./radarArchiveCore.bundled.js";
5
+ import { RN_DEFAULT_GRID_REQUEST_SITE_ORIGIN as I } from "../gridCdnAuth";
6
+ import { prepareRadarFrameForGpuReadout as oe } from "./radarFrameGpuMatch.bundled.js";
7
+ import { mapboxFrameUploadOptionsForNexradState as V } from "./nexradMapboxFrameOpts.bundled.js";
8
+ import { sampleNexradFrameAtLatLon as le } from "./nexradCrossSectionSampleAtLatLon.bundled.js";
9
+ import { buildNexradLutRgba as de } from "./nexradLutBuild.js";
10
+ import { Platform as ce } from "react-native";
11
+ import { nexradDiagBootSnapshot as ue, nexradDiagGateTextureSummary as he, nexradPerfSpan as h, nexradPipelineLog as y } from "./nexradDiag.js";
12
+ import { aguaceroDebug as z, getAguaceroAuthDiagnosticSnapshot as H, isAguaceroRnDebugEnabled as W } from "../aguaceroRnDebug";
13
+ ue({
15
14
  archiveExports: {
16
- setNexradArchiveApiKey: typeof setNexradArchiveApiKey,
17
- setNexradArchiveBundleId: typeof setNexradArchiveBundleId,
18
- objectKeyToUrl: typeof objectKeyToUrl,
19
- fetchAndParseArchive: typeof fetchAndParseArchive
15
+ setNexradArchiveApiKey: typeof L,
16
+ setNexradArchiveBundleId: typeof R,
17
+ objectKeyToUrl: typeof G,
18
+ fetchAndParseArchive: typeof k
20
19
  }
21
20
  });
22
-
23
- /** @returns {boolean} */
24
- function ensureRadarArchiveBindings(label) {
25
- const ok = typeof setNexradArchiveApiKey === 'function' && typeof setNexradArchiveBundleId === 'function' && typeof objectKeyToUrl === 'function' && typeof fetchAndParseArchive === 'function';
26
- return ok;
21
+ function q(c) {
22
+ return typeof L == "function" && typeof R == "function" && typeof G == "function" && typeof k == "function";
27
23
  }
28
- function pickNearestLevel3ObjectKey(unixTime, timeToKeyMap, maxDeltaSec = 600) {
29
- const direct = timeToKeyMap[String(unixTime)];
30
- if (direct) return direct;
31
- const entries = Object.entries(timeToKeyMap || {});
32
- if (entries.length === 0) return null;
33
- let bestKey = null;
34
- let bestDelta = Infinity;
35
- for (const [tStr, key] of entries) {
36
- const t = Number(tStr);
37
- if (!Number.isFinite(t)) continue;
38
- const d = Math.abs(t - unixTime);
39
- if (d < bestDelta) {
40
- bestDelta = d;
41
- bestKey = key;
42
- }
43
- }
44
- if (bestKey == null) return null;
45
- if (bestDelta > maxDeltaSec && Number.isFinite(maxDeltaSec)) return null;
46
- return bestKey;
24
+ function me(c, e, t = 600) {
25
+ const a = e[String(c)];
26
+ if (a) return a;
27
+ const n = Object.entries(e || {});
28
+ if (n.length === 0) return null;
29
+ let i = null,
30
+ r = 1 / 0;
31
+ for (const [s, l] of n) {
32
+ const o = Number(s);
33
+ if (!Number.isFinite(o)) continue;
34
+ const m = Math.abs(o - c);
35
+ m < r && (r = m, i = l);
36
+ }
37
+ return i == null || r > t && Number.isFinite(t) ? null : i;
47
38
  }
48
- function isVelocityStyleRadarVar(radarVariable) {
49
- return radarVariable === 'VEL' || radarVariable === 'SW' || radarVariable === 'N0G' || radarVariable === 'N0W';
39
+ function U(c) {
40
+ return c === "VEL" || c === "SW" || c === "N0G" || c === "N0W";
50
41
  }
51
- function velocityRangeToMs(rangeMin, rangeMax, displayUnit) {
52
- if (rangeMin == null || rangeMax == null || !displayUnit || displayUnit.toLowerCase() === 'm/s' || displayUnit.toLowerCase() === 'ms') {
53
- return [rangeMin, rangeMax];
54
- }
55
- const toMs = getUnitConversionFunction(displayUnit, 'm/s', 'nexrad_vel');
56
- if (!toMs) return [rangeMin, rangeMax];
57
- return [toMs(rangeMin), toMs(rangeMax)];
42
+ function pe(c, e, t) {
43
+ if (c == null || e == null || !t || t.toLowerCase() === "m/s" || t.toLowerCase() === "ms") return [c, e];
44
+ const a = O(t, "m/s", "nexrad_vel");
45
+ return a ? [a(c), a(e)] : [c, e];
58
46
  }
59
- function colormapToMs(colormap, radarVariable, displayUnit) {
60
- if (!colormap || !Array.isArray(colormap) || colormap.length < 2) return colormap;
61
- if (!isVelocityStyleRadarVar(radarVariable)) return colormap;
62
- if (!displayUnit || displayUnit.toLowerCase() === 'm/s' || displayUnit.toLowerCase() === 'ms') return colormap;
63
- const toMs = getUnitConversionFunction(displayUnit, 'm/s', radarVariable === 'SW' || radarVariable === 'N0W' ? 'nexrad_sw' : 'nexrad_vel');
64
- if (!toMs) return colormap;
65
- const out = [...colormap];
66
- for (let i = 0; i < out.length; i += 2) {
67
- const v = out[i];
68
- if (typeof v === 'number' && Number.isFinite(v)) out[i] = toMs(v);
69
- }
70
- return out;
47
+ function ye(c, e, t) {
48
+ if (!c || !Array.isArray(c) || c.length < 2 || !U(e) || !t || t.toLowerCase() === "m/s" || t.toLowerCase() === "ms") return c;
49
+ const a = O(t, "m/s", e === "SW" || e === "N0W" ? "nexrad_sw" : "nexrad_vel");
50
+ if (!a) return c;
51
+ const n = [...c];
52
+ for (let i = 0; i < n.length; i += 2) {
53
+ const r = n[i];
54
+ typeof r == "number" && Number.isFinite(r) && (n[i] = a(r));
55
+ }
56
+ return n;
71
57
  }
72
- function radarShaderValueRange(rangeMin, rangeMax, radarVariable, units, nexradDataSource) {
73
- const v = (radarVariable || '').toUpperCase();
74
- if (isVelocityStyleRadarVar(v)) {
75
- const [vmin, vmax] = velocityRangeToMs(rangeMin, rangeMax, units);
76
- return [vmin ?? 0, vmax ?? 80];
77
- }
78
- if (nexradDataSource === 'level3' && (v === 'N0H' || v === 'HHC')) {
79
- const lo = rangeMin ?? 0;
80
- let hi = rangeMax ?? 11;
81
- if (hi > 11) hi = 11;
82
- if (hi < lo) hi = lo;
83
- return [lo, hi];
84
- }
85
- if (v === 'KDP') {
86
- const lo = rangeMin ?? -2;
87
- let hi = rangeMax ?? 8;
88
- if (hi < lo) hi = lo;
89
- return [lo, hi];
90
- }
91
- return [rangeMin ?? 0, rangeMax ?? 80];
58
+ function ge(c, e, t, a, n) {
59
+ const i = (t || "").toUpperCase();
60
+ if (U(i)) {
61
+ const [r, s] = pe(c, e, a);
62
+ return [r ?? 0, s ?? 80];
63
+ }
64
+ if (n === "level3" && (i === "N0H" || i === "HHC")) {
65
+ const r = c ?? 0;
66
+ let s = e ?? 11;
67
+ return s > 11 && (s = 11), s < r && (s = r), [r, s];
68
+ }
69
+ if (i === "KDP") {
70
+ const r = c ?? -2;
71
+ let s = e ?? 8;
72
+ return s < r && (s = r), [r, s];
73
+ }
74
+ return [c ?? 0, e ?? 80];
92
75
  }
93
- function nexradLevel3IsHydrometeorClassification(radarVariable) {
94
- const v = (radarVariable || '').toUpperCase();
95
- return v === 'N0H' || v === 'HHC';
76
+ function fe(c) {
77
+ const e = (c || "").toUpperCase();
78
+ return e === "N0H" || e === "HHC";
96
79
  }
97
- const NEXRAD_HYDROMETEOR_CLASS_LABELS = ['Biological', 'Ground clutter', 'Ice crystals', 'Dry snow', 'Wet snow', 'Light rain', 'Heavy rain', 'Big drops', 'Graupel', 'Hail/rain', 'Large hail', 'Giant hail'];
98
- function nexradHydrometeorLabelForClassIndex(value) {
99
- const idx = Math.round(Number(value));
100
- if (idx >= 12) return null;
101
- if (idx >= 0 && idx < NEXRAD_HYDROMETEOR_CLASS_LABELS.length) {
102
- return NEXRAD_HYDROMETEOR_CLASS_LABELS[idx];
103
- }
104
- return `Class ${idx}`;
80
+ const Y = ["Biological", "Ground clutter", "Ice crystals", "Dry snow", "Wet snow", "Light rain", "Heavy rain", "Big drops", "Graupel", "Hail/rain", "Large hail", "Giant hail"];
81
+ function xe(c) {
82
+ const e = Math.round(Number(c));
83
+ return e >= 12 ? null : e >= 0 && e < Y.length ? Y[e] : `Class ${e}`;
105
84
  }
106
- function velocityMsToDisplay(valueMs, displayUnit) {
107
- if (!displayUnit || displayUnit.toLowerCase() === 'm/s' || displayUnit.toLowerCase() === 'ms') {
108
- return valueMs;
109
- }
110
- const fromMs = getUnitConversionFunction('m/s', displayUnit, 'nexrad_vel');
111
- return fromMs ? fromMs(valueMs) : valueMs;
85
+ function ve(c, e) {
86
+ if (!e || e.toLowerCase() === "m/s" || e.toLowerCase() === "ms") return c;
87
+ const t = O("m/s", e, "nexrad_vel");
88
+ return t ? t(c) : c;
112
89
  }
113
- function beamHeightKm(slantRangeKm, elevDeg) {
114
- const el = elevDeg * Math.PI / 180;
115
- const ReKm = 6371000 * 4 / (3 * 1000);
116
- const cosEl = Math.max(Math.cos(el), 0.05);
117
- const s = slantRangeKm / cosEl;
118
- return Math.sqrt(s * s + ReKm * ReKm + 2 * s * ReKm * Math.sin(el)) - ReKm;
90
+ function _e(c, e) {
91
+ const t = e * Math.PI / 180,
92
+ a = 6371e3 * 4 / (3 * 1e3),
93
+ n = Math.max(Math.cos(t), .05),
94
+ i = c / n;
95
+ return Math.sqrt(i * i + a * a + 2 * i * a * Math.sin(t)) - a;
119
96
  }
120
- function formatNexradInspectNumeric(raw, radarVariable) {
121
- const vu = (radarVariable || '').toUpperCase();
122
- const vl = radarVariable || '';
123
- if (vu.includes('RATE') || vl.toLowerCase().includes('rate')) {
124
- return Number(raw.toFixed(3).replace(/\.?0+$/, ''));
125
- }
126
- if (vu === 'RHO' || vu === 'ZDR' || vl.includes('RhoHV') || vl.includes('Zdr')) {
127
- return Number(raw.toFixed(2));
128
- }
129
- if (Math.abs(raw) < 10) return Number(raw.toFixed(1));
130
- return Math.round(raw);
97
+ function Se(c, e) {
98
+ const t = (e || "").toUpperCase(),
99
+ a = e || "";
100
+ return t.includes("RATE") || a.toLowerCase().includes("rate") ? Number(c.toFixed(3).replace(/\.?0+$/, "")) : t === "RHO" || t === "ZDR" || a.includes("RhoHV") || a.includes("Zdr") ? Number(c.toFixed(2)) : Math.abs(c) < 10 ? Number(c.toFixed(1)) : Math.round(c);
131
101
  }
132
-
133
- /** Keep low so Level-2 decode stays off the critical path for touches/animations (was 4). */
134
- /** iOS Metal uploads benefit from overlapping fetches; keep Android at 1 for steadier radio/CPU. */
135
- const PRELOAD_CONCURRENCY = Platform.OS === 'ios' ? 2 : 1;
136
- function yieldToJsEventLoop() {
137
- return new Promise(resolve => setTimeout(resolve, 0));
102
+ const be = ce.OS === "ios" ? 2 : 1;
103
+ function M() {
104
+ return new Promise(c => setTimeout(c, 0));
138
105
  }
139
-
140
- /** Match mapsgl {@link MapboxRadarLayer} geometry LRU — reuse serialized native payloads when scrubbing. */
141
- const NATIVE_UPLOAD_JSON_LRU_MAX = 12;
142
- function rleCompressGateData(gateData) {
143
- const len = gateData.length;
144
- const out = new Uint8Array(len * 2);
145
- let outIdx = 0;
146
- let i = 0;
147
- while (i < len) {
148
- let val0 = gateData[i];
149
- let val1 = gateData[i + 1];
150
- let count = 1;
151
- let maxCount = len - i >> 1;
152
- if (maxCount > 65535) maxCount = 65535;
153
- let j = i + 2;
154
- while (count < maxCount && gateData[j] === val0 && gateData[j + 1] === val1) {
155
- count++;
156
- j += 2;
157
- }
158
- out[outIdx++] = count & 0xFF;
159
- out[outIdx++] = count >> 8 & 0xFF;
160
- out[outIdx++] = val0;
161
- out[outIdx++] = val1;
162
- i = j;
163
- }
164
- return out.subarray(0, outIdx);
106
+ const Ne = 12;
107
+ function Te(c) {
108
+ const e = c.length,
109
+ t = new Uint8Array(e * 2);
110
+ let a = 0,
111
+ n = 0;
112
+ for (; n < e;) {
113
+ let i = c[n],
114
+ r = c[n + 1],
115
+ s = 1,
116
+ l = e - n >> 1;
117
+ l > 65535 && (l = 65535);
118
+ let o = n + 2;
119
+ for (; s < l && c[o] === i && c[o + 1] === r;) s++, o += 2;
120
+ t[a++] = s & 255, t[a++] = s >> 8 & 255, t[a++] = i, t[a++] = r, n = o;
121
+ }
122
+ return t.subarray(0, a);
165
123
  }
166
124
  export class NexradAndroidController {
167
- /**
168
- * @param {*} core - AguaceroCore instance
169
- * @param {React.MutableRefObject<{ uploadNexradFrame?: (s: string) => void; uploadNexradStyleOnly?: (s: string) => void; clearNexrad?: () => void; activateNexradCachedFrame?: (k: string) => void } | null>} layerRef
170
- * @param {object} [options]
171
- */
172
- constructor(core, layerRef, options = {}) {
173
- this.core = core;
174
- this._layerRef = layerRef;
175
- this._lastSyncKey = null;
176
- this._abort = null;
177
- this._interpolateColormap = options.interpolateNexradColormap !== false;
178
- this._gateSmoothing = options.nexradGateSmoothing === true;
179
- this._frameCache = new Map();
180
- /** WeakMap: decoded frame → Map(uploadOptsKey → prepared frame). Avoids O(n²) canonical re-bin every map move. */
181
- this._gpuReadoutPrep = new WeakMap();
182
- this._preloadAbort = null;
183
- this._preloadTimelineSig = null;
184
- this._nativeFrameUploaded = false;
185
- /** @type {{ valueScale: number; valueOffset: number } | null} */
186
- this._lastUploadMeta = null;
187
- /** @type {Map<string, { json: string; valueScale: number; valueOffset: number }>} */
188
- this._nativeUploadJsonLru = new Map();
189
- /** @type {Set<string>} Sync keys with gate texture registered in Android GL cache (AguaceroNexradGpuFrameReady). */
190
- this._nativeGpuReadyKeys = new Set();
191
- /** @type {Map<string, { valueScale: number; valueOffset: number }>} */
192
- this._uploadMetaBySyncKey = new Map();
193
- /** @type {{ remove: () => void } | null} */
194
- this._gpuReadyEventSub = null;
125
+ constructor(e, t, a = {}) {
126
+ this.core = e, this._layerRef = t, this._lastSyncKey = null, this._abort = null, this._interpolateColormap = a.interpolateNexradColormap !== !1, this._gateSmoothing = a.nexradGateSmoothing === !0, this._frameCache = new Map(), this._gpuReadoutPrep = new WeakMap(), this._preloadAbort = null, this._preloadTimelineSig = null, this._listingRefreshPromise = null, this._nativeFrameUploaded = !1, this._lastUploadMeta = null, this._nativeUploadJsonLru = new Map(), this._nativeGpuReadyKeys = new Set(), this._uploadMetaBySyncKey = new Map(), this._gpuReadyEventSub = null;
195
127
  try {
196
128
  const {
197
- DeviceEventEmitter
198
- } = require('react-native');
199
- if (DeviceEventEmitter && typeof DeviceEventEmitter.addListener === 'function') {
200
- this._gpuReadyEventSub = DeviceEventEmitter.addListener('AguaceroNexradGpuFrameReady', e => {
201
- const k = e && e.nativeGpuCacheKey;
202
- if (typeof k === 'string' && k.length > 0) {
203
- this._nativeGpuReadyKeys.add(k);
204
- this._trimNativeGpuReadyKeys(96);
205
- }
206
- });
207
- }
208
- } catch (err) {
209
- /* ignore */
210
- }
211
- const base = typeof core?.baseGridUrl === 'string' ? core.baseGridUrl.replace(/\/$/, '') : '';
212
- if (base && typeof navigator !== 'undefined' && navigator.product === 'ReactNative') {
213
- setNexradSitesJsonUrl(`${base}/data/nexrad.json`);
214
- setNexradSitesFetchAuth(core.apiKey || '', core.bundleId || '');
215
- }
216
- setNexradArchiveSiteOrigin(core.gridRequestSiteOrigin || 'https://localhost');
217
- if (isAguaceroRnDebugEnabled()) {
218
- aguaceroDebug('nexrad.authConfigured', getAguaceroAuthDiagnosticSnapshot(core, {
219
- phase: 'NexradAndroidController.constructor'
129
+ DeviceEventEmitter: i
130
+ } = require("react-native");
131
+ i && typeof i.addListener == "function" && (this._gpuReadyEventSub = i.addListener("AguaceroNexradGpuFrameReady", r => {
132
+ const s = r && r.nativeGpuCacheKey;
133
+ typeof s == "string" && s.length > 0 && (this._nativeGpuReadyKeys.add(s), this._trimNativeGpuReadyKeys(96));
220
134
  }));
221
- }
135
+ } catch {}
136
+ const n = typeof e?.baseGridUrl == "string" ? e.baseGridUrl.replace(/\/$/, "") : "";
137
+ n && typeof navigator < "u" && navigator.product === "ReactNative" && (se(`${n}/data/nexrad.json`), B(e.apiKey || "", e.bundleId || "")), L(e.apiKey || ""), R(e.bundleId || ""), w(e.gridRequestSiteOrigin || I), $(e.nexradUserId || "sdk-user"), W() && z("nexrad.authConfigured", {
138
+ ...ne({
139
+ phase: "NexradAndroidController.constructor"
140
+ }),
141
+ ...H(e, {
142
+ phase: "NexradAndroidController.constructor"
143
+ })
144
+ });
222
145
  }
223
- _trimNativeGpuReadyKeys(max) {
224
- while (this._nativeGpuReadyKeys.size > max) {
225
- const first = this._nativeGpuReadyKeys.values().next().value;
226
- if (first === undefined) break;
227
- this._nativeGpuReadyKeys.delete(first);
146
+ _trimNativeGpuReadyKeys(e) {
147
+ for (; this._nativeGpuReadyKeys.size > e;) {
148
+ const t = this._nativeGpuReadyKeys.values().next().value;
149
+ if (t === void 0) break;
150
+ this._nativeGpuReadyKeys.delete(t);
228
151
  }
229
152
  }
230
- _rememberUploadMetaForSyncKey(syncKey, valueScale, valueOffset) {
231
- this._uploadMetaBySyncKey.set(syncKey, {
232
- valueScale,
233
- valueOffset
234
- });
235
- while (this._uploadMetaBySyncKey.size > 40) {
236
- const k = this._uploadMetaBySyncKey.keys().next().value;
237
- if (k === undefined) break;
238
- this._uploadMetaBySyncKey.delete(k);
153
+ _rememberUploadMetaForSyncKey(e, t, a) {
154
+ for (this._uploadMetaBySyncKey.set(e, {
155
+ valueScale: t,
156
+ valueOffset: a
157
+ }); this._uploadMetaBySyncKey.size > 40;) {
158
+ const n = this._uploadMetaBySyncKey.keys().next().value;
159
+ if (n === void 0) break;
160
+ this._uploadMetaBySyncKey.delete(n);
239
161
  }
240
162
  }
241
- updateStyleOptions(options) {
242
- if (options.interpolateNexradColormap != null) {
243
- this._interpolateColormap = options.interpolateNexradColormap !== false;
244
- }
245
- if (options.nexradGateSmoothing != null) {
246
- this._gateSmoothing = options.nexradGateSmoothing === true;
247
- }
163
+ updateStyleOptions(e) {
164
+ e.interpolateNexradColormap != null && (this._interpolateColormap = e.interpolateNexradColormap !== !1), e.nexradGateSmoothing != null && (this._gateSmoothing = e.nexradGateSmoothing === !0);
248
165
  }
249
166
  destroy() {
250
167
  try {
251
168
  this._gpuReadyEventSub?.remove();
252
- } catch (_) {
253
- /* ignore */
254
- }
255
- this._gpuReadyEventSub = null;
256
- this._nativeGpuReadyKeys.clear();
257
- this._uploadMetaBySyncKey.clear();
258
- this._abort?.abort();
259
- this._abort = null;
260
- this._preloadAbort?.abort();
261
- this._preloadAbort = null;
262
- this._frameCache.clear();
263
- this._gpuReadoutPrep = new WeakMap();
264
- this._preloadTimelineSig = null;
265
- this._lastSyncKey = null;
266
- this._nativeFrameUploaded = false;
267
- this._lastUploadMeta = null;
268
- this._nativeUploadJsonLru.clear();
269
- this._layerRef?.current?.clearNexrad?.();
169
+ } catch {}
170
+ this._gpuReadyEventSub = null, this._nativeGpuReadyKeys.clear(), this._uploadMetaBySyncKey.clear(), this._abort?.abort(), this._abort = null, this._preloadAbort?.abort(), this._preloadAbort = null, this._frameCache.clear(), this._gpuReadoutPrep = new WeakMap(), this._preloadTimelineSig = null, this._lastSyncKey = null, this._nativeFrameUploaded = !1, this._lastUploadMeta = null, this._nativeUploadJsonLru.clear(), this._layerRef?.current?.clearNexrad?.();
270
171
  }
271
- _getPreparedReadoutFrame(frame, uploadOpts) {
272
- let byOpts = this._gpuReadoutPrep.get(frame);
273
- if (!byOpts) {
274
- byOpts = new Map();
275
- this._gpuReadoutPrep.set(frame, byOpts);
276
- }
277
- const optKey = uploadOpts && typeof uploadOpts === 'object' ? JSON.stringify(uploadOpts) : String(uploadOpts);
278
- let prepared = byOpts.get(optKey);
279
- if (!prepared) {
280
- prepared = prepareRadarFrameForGpuReadout(frame, uploadOpts);
281
- byOpts.set(optKey, prepared);
282
- }
283
- return prepared;
172
+ _getPreparedReadoutFrame(e, t) {
173
+ let a = this._gpuReadoutPrep.get(e);
174
+ a || (a = new Map(), this._gpuReadoutPrep.set(e, a));
175
+ const n = t && typeof t == "object" ? JSON.stringify(t) : String(t);
176
+ let i = a.get(n);
177
+ return i || (i = oe(e, t), a.set(n, i)), i;
284
178
  }
285
179
  _native() {
286
180
  return this._layerRef?.current;
287
181
  }
288
- _lutPack(state) {
289
- const radarVar = (state.nexradProduct || 'REF').toUpperCase();
290
- const colormapFlat = state.colormap;
291
- const colormapForShader = colormapToMs(colormapFlat, radarVar, state.units);
292
- const [shaderMin, shaderMax] = radarShaderValueRange(colormapFlat?.[0], colormapFlat?.[colormapFlat.length - 2], radarVar, state.units, state.nexradDataSource);
293
- const {
294
- bytes,
295
- discreteIntegerLut
296
- } = buildNexradLutRgba(colormapForShader, shaderMin, shaderMax, this._interpolateColormap);
182
+ _lutPack(e) {
183
+ const t = (e.nexradProduct || "REF").toUpperCase(),
184
+ a = e.colormap,
185
+ n = ye(a, t, e.units),
186
+ [i, r] = ge(a?.[0], a?.[a.length - 2], t, e.units, e.nexradDataSource),
187
+ {
188
+ bytes: s,
189
+ discreteIntegerLut: l
190
+ } = de(n, i, r, this._interpolateColormap);
297
191
  return {
298
- lutB64: fromByteArray(bytes),
299
- lutMin: shaderMin,
300
- lutMax: shaderMax,
301
- discreteIntegerLut
192
+ lutB64: J(s),
193
+ lutMin: i,
194
+ lutMax: r,
195
+ discreteIntegerLut: l
302
196
  };
303
197
  }
304
-
305
- /**
306
- * LRU for full native JSON payloads (parity with mapsgl gate-texture reuse — avoids base64 + stringify on repeat scrubs).
307
- * @param {string} syncKey
308
- * @returns {{ json: string; valueScale: number; valueOffset: number } | null}
309
- */
310
- _nativeUploadJsonLruTouch(syncKey) {
311
- const ent = this._nativeUploadJsonLru.get(syncKey);
312
- if (!ent) return null;
313
- this._nativeUploadJsonLru.delete(syncKey);
314
- this._nativeUploadJsonLru.set(syncKey, ent);
315
- return ent;
316
- }
317
-
318
- /** @param {string} syncKey @param {{ json: string; valueScale: number; valueOffset: number }} entry */
319
- _nativeUploadJsonLruPut(syncKey, entry) {
320
- if (this._nativeUploadJsonLru.has(syncKey)) this._nativeUploadJsonLru.delete(syncKey);
321
- this._nativeUploadJsonLru.set(syncKey, entry);
322
- while (this._nativeUploadJsonLru.size > NATIVE_UPLOAD_JSON_LRU_MAX) {
323
- const oldest = this._nativeUploadJsonLru.keys().next().value;
324
- if (oldest === undefined) break;
325
- this._nativeUploadJsonLru.delete(oldest);
326
- }
327
- }
328
-
329
- /**
330
- * Full-frame JSON includes LUT + opacity + shader toggles; keep LRU key aligned so scrubbing
331
- * cannot resurrect an outdated style after the user changes only presentation options.
332
- */
333
- _nativeUploadLruKey(state, syncKey) {
334
- return `${syncKey}|o:${state.opacity ?? 1}|g:${this._gateSmoothing ? 1 : 0}|i:${this._interpolateColormap ? 1 : 0}`;
335
- }
336
-
337
- /**
338
- * After JS decoded a frame into `_frameCache`, optionally push it through the native bridge.
339
- * During timeline preload we **only** upload the **currently displayed** unix to Metal; other
340
- * volumes stay in the JS cache until {@link sync} needs them (avoids 40+ full decodes on load).
341
- */
342
- _primeNativeGpuUploadIfNeeded(snapshot, unix, p, frame, abortSignal) {
343
- if (!frame || !p || abortSignal && abortSignal.aborted) return;
344
- try {
345
- const displayUx = snapshot.nexradTimestamp != null && Number.isFinite(Number(snapshot.nexradTimestamp)) ? Number(snapshot.nexradTimestamp) : NaN;
346
- if (Number.isFinite(displayUx) && Number(unix) !== displayUx) {
347
- return;
348
- }
349
- const syncKey = this._syncIdentity(snapshot, p, unix);
350
- if (this._nativeGpuReadyKeys.has(syncKey)) {
351
- return;
352
- }
353
- if (!this._native()?.uploadNexradFrame) {
354
- return;
355
- }
356
- this._uploadFrameToNative(snapshot, frame, p, unix);
357
- } catch (err) {
358
- /* ignore */
359
- }
360
- }
361
-
362
- /**
363
- * @param {*} state
364
- * @param {*} frame - decoded archive frame
365
- * @param {{ fetchKey: string }} p - from {@link _buildFetchParamsForUnix}
366
- * @param {number} unix
367
- */
368
- _uploadFrameToNative(state, frame, p, unix) {
369
- const uploadTotal = nexradPerfSpan(`uploadFrame.total site=${state.nexradSite} unix=${unix} var=${p?.radarVar ?? state.nexradProduct}`);
370
- const n = this._native();
371
- if (!n?.uploadNexradFrame) {
372
- uploadTotal.end({
373
- outcome: 'skippedNoNative'
198
+ _nativeUploadJsonLruTouch(e) {
199
+ const t = this._nativeUploadJsonLru.get(e);
200
+ return t ? (this._nativeUploadJsonLru.delete(e), this._nativeUploadJsonLru.set(e, t), t) : null;
201
+ }
202
+ _nativeUploadJsonLruPut(e, t) {
203
+ for (this._nativeUploadJsonLru.has(e) && this._nativeUploadJsonLru.delete(e), this._nativeUploadJsonLru.set(e, t); this._nativeUploadJsonLru.size > Ne;) {
204
+ const a = this._nativeUploadJsonLru.keys().next().value;
205
+ if (a === void 0) break;
206
+ this._nativeUploadJsonLru.delete(a);
207
+ }
208
+ }
209
+ _nativeUploadLruKey(e, t) {
210
+ return `${t}|o:${e.opacity ?? 1}|g:${this._gateSmoothing ? 1 : 0}|i:${this._interpolateColormap ? 1 : 0}`;
211
+ }
212
+ _primeNativeGpuUploadIfNeeded(e, t, a, n, i) {
213
+ if (!(!n || !a || i && i.aborted)) try {
214
+ const r = e.nexradTimestamp != null && Number.isFinite(Number(e.nexradTimestamp)) ? Number(e.nexradTimestamp) : NaN;
215
+ if (Number.isFinite(r) && Number(t) !== r) return;
216
+ const s = this._syncIdentity(e, a, t);
217
+ if (this._nativeGpuReadyKeys.has(s) || !this._native()?.uploadNexradFrame) return;
218
+ this._uploadFrameToNative(e, n, a, t);
219
+ } catch {}
220
+ }
221
+ _uploadFrameToNative(e, t, a, n) {
222
+ const i = h(`uploadFrame.total site=${e.nexradSite} unix=${n} var=${a?.radarVar ?? e.nexradProduct}`),
223
+ r = this._native();
224
+ if (!r?.uploadNexradFrame) {
225
+ y("upload.skip", {
226
+ reason: "noNativeUploadMethod",
227
+ site: e.nexradSite,
228
+ unix: n,
229
+ layerRefSet: !!this._layerRef?.current
230
+ }), i.end({
231
+ outcome: "skippedNoNative"
374
232
  });
375
233
  return;
376
234
  }
377
- const syncKey = this._syncIdentity(state, p, unix);
378
- const lruKey = this._nativeUploadLruKey(state, syncKey);
379
- const lruHit = this._nativeUploadJsonLruTouch(lruKey);
380
- if (lruHit) {
381
- this._lastUploadMeta = {
382
- valueScale: lruHit.valueScale,
383
- valueOffset: lruHit.valueOffset
384
- };
385
- this._rememberUploadMetaForSyncKey(syncKey, lruHit.valueScale, lruHit.valueOffset);
386
- if (n.activateNexradCachedFrame && this._nativeGpuReadyKeys.has(syncKey)) {
387
- const tAct = nexradPerfSpan('uploadFrame.nativeGpuActivateOnly');
388
- n.activateNexradCachedFrame(syncKey);
389
- tAct.end({
390
- keyLen: syncKey.length
235
+ const s = this._syncIdentity(e, a, n),
236
+ l = this._nativeUploadLruKey(e, s),
237
+ o = this._nativeUploadJsonLruTouch(l);
238
+ if (o) {
239
+ if (this._lastUploadMeta = {
240
+ valueScale: o.valueScale,
241
+ valueOffset: o.valueOffset
242
+ }, this._rememberUploadMetaForSyncKey(s, o.valueScale, o.valueOffset), r.activateNexradCachedFrame && this._nativeGpuReadyKeys.has(s)) {
243
+ const K = h("uploadFrame.nativeGpuActivateOnly");
244
+ r.activateNexradCachedFrame(s), K.end({
245
+ keyLen: s.length
391
246
  });
392
- const tStyle = nexradPerfSpan('uploadFrame.styleAfterGpuActivate');
393
- this.applyStyleFromState(state);
394
- tStyle.end({});
395
- this._nativeFrameUploaded = true;
396
- uploadTotal.end({
397
- outcome: 'gpuActivateOnly',
398
- jsonCharsSkipped: lruHit.json.length
247
+ const Z = h("uploadFrame.styleAfterGpuActivate");
248
+ this.applyStyleFromState(e), Z.end({}), this._nativeFrameUploaded = !0, i.end({
249
+ outcome: "gpuActivateOnly",
250
+ jsonCharsSkipped: o.json.length
399
251
  });
400
252
  return;
401
253
  }
402
- const bridge = nexradPerfSpan('uploadFrame.nativeJsonLru.bridgeDispatch');
403
- n.uploadNexradFrame(lruHit.json);
404
- bridge.end({
405
- jsonChars: lruHit.json.length,
406
- path: 'jsonLruHit'
407
- });
408
- this._nativeFrameUploaded = true;
409
- uploadTotal.end({
410
- outcome: 'jsonLruHit',
411
- jsonChars: lruHit.json.length
254
+ const A = h("uploadFrame.nativeJsonLru.bridgeDispatch");
255
+ r.uploadNexradFrame(o.json), A.end({
256
+ jsonChars: o.json.length,
257
+ path: "jsonLruHit"
258
+ }), this._nativeFrameUploaded = !0, i.end({
259
+ outcome: "jsonLruHit",
260
+ jsonChars: o.json.length
412
261
  });
413
262
  return;
414
263
  }
415
- const tOpts = nexradPerfSpan('uploadFrame.mapboxFrameUploadOptions');
416
- const uploadOpts = mapboxFrameUploadOptionsForNexradState(state);
417
- tOpts.end({});
418
-
419
- // Skip JS sorting for Android native upload
420
- // We pass the raw frame and let Android do the sorting/canonicalization
421
- const rawFrame = frame;
264
+ const m = h("uploadFrame.mapboxFrameUploadOptions"),
265
+ u = V(e);
266
+ m.end({});
267
+ const d = t;
422
268
  this._lastUploadMeta = {
423
- valueScale: rawFrame.valueScale,
424
- valueOffset: rawFrame.valueOffset
269
+ valueScale: d.valueScale,
270
+ valueOffset: d.valueOffset
425
271
  };
426
- const tLut = nexradPerfSpan('uploadFrame.lutPack_buildNexradLutRgba');
427
- const style = this._lutPack(state);
428
- tLut.end({
429
- lutB64Chars: style.lutB64?.length ?? 0,
430
- discreteIntegerLut: style.discreteIntegerLut,
431
- lutMin: style.lutMin,
432
- lutMax: style.lutMax
272
+ const N = h("uploadFrame.lutPack_buildNexradLutRgba"),
273
+ p = this._lutPack(e);
274
+ N.end({
275
+ lutB64Chars: p.lutB64?.length ?? 0,
276
+ discreteIntegerLut: p.discreteIntegerLut,
277
+ lutMin: p.lutMin,
278
+ lutMax: p.lutMax
433
279
  });
434
- const tRay = nexradPerfSpan('uploadFrame.rayBoundariesToJsArray');
435
- const rayBoundaries = rawFrame.rayBoundariesDeg?.slice ? Array.from(rawFrame.rayBoundariesDeg) : [...(rawFrame.rayBoundariesDeg || [])];
436
- tRay.end({
437
- len: rayBoundaries.length
280
+ const F = h("uploadFrame.rayBoundariesToJsArray"),
281
+ g = d.rayBoundariesDeg?.slice ? Array.from(d.rayBoundariesDeg) : [...(d.rayBoundariesDeg || [])];
282
+ F.end({
283
+ len: g.length
438
284
  });
439
- const tB64 = nexradPerfSpan('uploadFrame.gateData_toBase64');
440
- const rleGateData = rleCompressGateData(rawFrame.gateData);
441
- const gateB64 = fromByteArray(rleGateData);
442
- tB64.end({
443
- gateB64Chars: gateB64.length,
444
- rleBytes: rleGateData.length,
445
- rawBytes: rawFrame.gateData.length
285
+ const f = h("uploadFrame.gateData_toBase64"),
286
+ _ = Te(d.gateData),
287
+ C = J(_);
288
+ f.end({
289
+ gateB64Chars: C.length,
290
+ rleBytes: _.length,
291
+ rawBytes: d.gateData.length
446
292
  });
447
- const payload = {
448
- gateB64,
449
- gateIsRle: true,
450
- nGates: rawFrame.nGates,
451
- nRays: rawFrame.nRays,
452
- stationLat: rawFrame.stationLat,
453
- stationLon: rawFrame.stationLon,
454
- firstGateKm: rawFrame.firstGateKm,
455
- gateWidthKm: rawFrame.gateWidthKm,
456
- rayBoundaries,
457
- lutB64: style.lutB64,
458
- valueScale: rawFrame.valueScale,
459
- valueOffset: rawFrame.valueOffset,
460
- lutMin: style.lutMin,
461
- lutMax: style.lutMax,
462
- discreteIntegerLut: style.discreteIntegerLut,
463
- opacity: state.opacity ?? 1,
464
- gateSmoothPolar: this._gateSmoothing ? 1 : 0,
465
- interpolateLut: this._interpolateColormap ? 1 : 0,
466
- nativeGpuCacheKey: syncKey,
467
- uploadOpts: uploadOpts
468
- };
469
- const tJson = nexradPerfSpan('uploadFrame.JSON_stringify_payload');
470
- const json = JSON.stringify(payload);
471
- tJson.end({
472
- jsonChars: json.length,
473
- rayBoundaryLen: rayBoundaries.length
474
- });
475
- const tLruPut = nexradPerfSpan('uploadFrame.nativeUploadJsonLruPut');
476
- this._nativeUploadJsonLruPut(lruKey, {
477
- json,
478
- valueScale: rawFrame.valueScale,
479
- valueOffset: rawFrame.valueOffset
293
+ const x = {
294
+ gateB64: C,
295
+ gateIsRle: !0,
296
+ nGates: d.nGates,
297
+ nRays: d.nRays,
298
+ stationLat: d.stationLat,
299
+ stationLon: d.stationLon,
300
+ firstGateKm: d.firstGateKm,
301
+ gateWidthKm: d.gateWidthKm,
302
+ rayBoundaries: g,
303
+ lutB64: p.lutB64,
304
+ valueScale: d.valueScale,
305
+ valueOffset: d.valueOffset,
306
+ lutMin: p.lutMin,
307
+ lutMax: p.lutMax,
308
+ discreteIntegerLut: p.discreteIntegerLut ? 1 : 0,
309
+ opacity: e.opacity ?? 1,
310
+ gateSmoothPolar: this._gateSmoothing ? 1 : 0,
311
+ interpolateLut: this._interpolateColormap ? 1 : 0,
312
+ nativeGpuCacheKey: s,
313
+ uploadOpts: u
314
+ },
315
+ S = h("uploadFrame.JSON_stringify_payload"),
316
+ v = JSON.stringify(x);
317
+ S.end({
318
+ jsonChars: v.length,
319
+ rayBoundaryLen: g.length
480
320
  });
481
- tLruPut.end({
482
- lruKeyTail: lruKey.slice(-96),
321
+ const b = h("uploadFrame.nativeUploadJsonLruPut");
322
+ this._nativeUploadJsonLruPut(l, {
323
+ json: v,
324
+ valueScale: d.valueScale,
325
+ valueOffset: d.valueOffset
326
+ }), b.end({
327
+ lruKeyTail: l.slice(-96),
483
328
  lruSize: this._nativeUploadJsonLru.size
484
329
  });
485
- const gateSummary = nexradDiagGateTextureSummary(rawFrame.gateData, rawFrame.nGates, rawFrame.nRays, rawFrame.valueScale, rawFrame.valueOffset, style.lutMin, style.lutMax);
486
- const tBridge = nexradPerfSpan('uploadFrame.nativeBridge_uploadNexradFrame');
487
- n.uploadNexradFrame(json);
488
- tBridge.end({
489
- jsonChars: json.length,
490
- path: 'fullRebuild'
491
- });
492
- this._rememberUploadMetaForSyncKey(syncKey, rawFrame.valueScale, rawFrame.valueOffset);
493
- this._nativeFrameUploaded = true;
494
- uploadTotal.end({
495
- outcome: 'fullPipeline',
496
- jsonChars: json.length,
497
- nGates: rawFrame.nGates,
498
- nRays: rawFrame.nRays
330
+ const T = he(d.gateData, d.nGates, d.nRays, d.valueScale, d.valueOffset, p.lutMin, p.lutMax),
331
+ P = h("uploadFrame.nativeBridge_uploadNexradFrame");
332
+ r.uploadNexradFrame(v), P.end({
333
+ jsonChars: v.length,
334
+ path: "fullRebuild"
335
+ }), this._rememberUploadMetaForSyncKey(s, d.valueScale, d.valueOffset), this._nativeFrameUploaded = !0, i.end({
336
+ outcome: "fullPipeline",
337
+ jsonChars: v.length,
338
+ nGates: d.nGates,
339
+ nRays: d.nRays
499
340
  });
500
341
  }
501
- applyStyleFromState(state) {
502
- const perf = nexradPerfSpan(`applyStyleFromState site=${state.nexradSite} product=${state.nexradProduct} tilt=${state.nexradTilt}`);
503
- const n = this._native();
504
- if (!this._nativeFrameUploaded || !this._lastUploadMeta || !n?.uploadNexradStyleOnly) {
505
- perf.end({
506
- outcome: 'skipped',
342
+ applyStyleFromState(e) {
343
+ const t = h(`applyStyleFromState site=${e.nexradSite} product=${e.nexradProduct} tilt=${e.nexradTilt}`),
344
+ a = this._native();
345
+ if (!this._nativeFrameUploaded || !this._lastUploadMeta || !a?.uploadNexradStyleOnly) {
346
+ t.end({
347
+ outcome: "skipped",
507
348
  nativeFrameUploaded: this._nativeFrameUploaded,
508
349
  hasUploadMeta: !!this._lastUploadMeta,
509
- hasStyleMethod: !!n?.uploadNexradStyleOnly
350
+ hasStyleMethod: !!a?.uploadNexradStyleOnly
510
351
  });
511
352
  return;
512
353
  }
513
- const tLut = nexradPerfSpan('applyStyleFromState.lutPack');
514
- const style = this._lutPack(state);
515
- tLut.end({
516
- lutB64Chars: style.lutB64?.length ?? 0
517
- });
518
- const payload = {
519
- lutB64: style.lutB64,
520
- valueScale: this._lastUploadMeta.valueScale,
521
- valueOffset: this._lastUploadMeta.valueOffset,
522
- lutMin: style.lutMin,
523
- lutMax: style.lutMax,
524
- discreteIntegerLut: style.discreteIntegerLut,
525
- opacity: state.opacity ?? 1,
526
- gateSmoothPolar: this._gateSmoothing ? 1 : 0,
527
- interpolateLut: this._interpolateColormap ? 1 : 0
528
- };
529
- const tJson = nexradPerfSpan('applyStyleFromState.JSON_stringify');
530
- const json = JSON.stringify(payload);
531
- tJson.end({
532
- jsonChars: json.length
354
+ const n = h("applyStyleFromState.lutPack"),
355
+ i = this._lutPack(e);
356
+ n.end({
357
+ lutB64Chars: i.lutB64?.length ?? 0
533
358
  });
534
- const tBridge = nexradPerfSpan('applyStyleFromState.nativeBridge');
535
- n.uploadNexradStyleOnly(json);
536
- tBridge.end({
537
- jsonChars: json.length
359
+ const r = {
360
+ lutB64: i.lutB64,
361
+ valueScale: this._lastUploadMeta.valueScale,
362
+ valueOffset: this._lastUploadMeta.valueOffset,
363
+ lutMin: i.lutMin,
364
+ lutMax: i.lutMax,
365
+ discreteIntegerLut: i.discreteIntegerLut ? 1 : 0,
366
+ opacity: e.opacity ?? 1,
367
+ gateSmoothPolar: this._gateSmoothing ? 1 : 0,
368
+ interpolateLut: this._interpolateColormap ? 1 : 0
369
+ },
370
+ s = h("applyStyleFromState.JSON_stringify"),
371
+ l = JSON.stringify(r);
372
+ s.end({
373
+ jsonChars: l.length
538
374
  });
539
- perf.end({
540
- outcome: 'dispatched'
375
+ const o = h("applyStyleFromState.nativeBridge");
376
+ a.uploadNexradStyleOnly(l), o.end({
377
+ jsonChars: l.length
378
+ }), t.end({
379
+ outcome: "dispatched"
541
380
  });
542
381
  }
543
- _resolveListingContext(state) {
544
- const nk = this.core._nexradTimesCacheKey?.();
545
- const ent = nk ? this.core.nexradTimesByStation?.[nk] : null;
546
- // Merge so we still resolve object keys if the last state event omitted maps but the core cache is populated.
547
- const timeToKeyMap = {
548
- ...(ent?.timeToKeyMap || {}),
549
- ...(state.nexradTimeToKeyMap || {})
550
- };
551
- const motionMap = {
552
- ...(ent?.level3MotionTimeToKeyMap || {}),
553
- ...(state.nexradLevel3MotionTimeToKeyMap || {})
382
+ _resolveListingContext(e) {
383
+ const {
384
+ site: t,
385
+ elevNorm: a,
386
+ group: n
387
+ } = E(e),
388
+ i = (e?.nexradDataSource || "level2") !== "level3" && t ? `${t}_${n}_${a}` : this.core._nexradTimesCacheKey?.(),
389
+ r = i ? this.core.nexradTimesByStation?.[i] : null,
390
+ s = e?.nexradTimeToKeyMap && typeof e.nexradTimeToKeyMap == "object" ? e.nexradTimeToKeyMap : {};
391
+ let l = r?.timeToKeyMap && typeof r.timeToKeyMap == "object" ? {
392
+ ...s,
393
+ ...r.timeToKeyMap
394
+ } : {
395
+ ...s
554
396
  };
397
+ const o = r?.level2Clens,
398
+ m = Array.isArray(r?.unixTimes) && r.unixTimes.length > 0 ? r.unixTimes : Array.isArray(e?.availableNexradTimestamps) && e.availableNexradTimestamps.length > 0 ? e.availableNexradTimestamps : void 0;
399
+ if (this._nexradRadarSource(e) === "level2" && o && typeof o == "object" && Object.keys(o).length > 0) {
400
+ const d = re({
401
+ stationId: t,
402
+ elevNorm: a,
403
+ group: n,
404
+ timeToKeyMap: l,
405
+ level2Clens: o,
406
+ unixTimes: m
407
+ });
408
+ Object.keys(d).length > 0 ? l = d : Object.keys(l).length > 0 && (l = Object.fromEntries(Object.entries(l).filter(([, N]) => j(N))));
409
+ } else this._nexradRadarSource(e) === "level2" && (l = Object.fromEntries(Object.entries(l).filter(([, d]) => j(d))));
410
+ const u = r?.level3MotionTimeToKeyMap || {};
555
411
  return {
556
- nk,
557
- ent,
558
- timeToKeyMap,
559
- motionMap
412
+ nk: i,
413
+ ent: r,
414
+ timeToKeyMap: l,
415
+ motionMap: u
560
416
  };
561
417
  }
562
- _buildFetchParamsForUnix(state, unix) {
563
- const radarVar = (state.nexradProduct || 'REF').toUpperCase();
564
- const radarSource = state.nexradDataSource === 'level3' ? 'level3' : 'level2';
565
- const groupId = nexradBinGroupIdForKey(variableToNexradGroup(radarVar));
418
+ _nexradStateWithCoreListing(e) {
566
419
  const {
567
- timeToKeyMap,
568
- motionMap
569
- } = this._resolveListingContext(state);
570
- const objectKey = timeToKeyMap[String(unix)];
571
- if (!objectKey) {
572
- return null;
573
- }
574
- let motionObjectKey = null;
575
- if (radarVar === 'VEL' && state.nexradStormRelative) {
576
- motionObjectKey = pickNearestLevel3ObjectKey(unix, motionMap);
420
+ site: t,
421
+ elevNorm: a,
422
+ group: n
423
+ } = E(e),
424
+ i = (e?.nexradDataSource || "level2") !== "level3" && t ? `${t}_${n}_${a}` : this.core._nexradTimesCacheKey?.(),
425
+ r = i ? this.core.nexradTimesByStation?.[i] : null;
426
+ if (!r) return e;
427
+ const s = Array.isArray(r.unixTimes) ? r.unixTimes : [],
428
+ {
429
+ timeToKeyMap: l
430
+ } = this._resolveListingContext(e),
431
+ o = this.core._getFilteredNexradTimestampsForVariable(s),
432
+ m = this._nexradRadarSource(e) === "level2" ? o.filter(d => j(l[String(d)])) : o.filter(d => typeof l[String(d)] == "string" && l[String(d)].length > 0);
433
+ let u = e.nexradTimestamp != null ? e.nexradTimestamp : this.core.state.nexradTimestamp != null ? this.core.state.nexradTimestamp : null;
434
+ return u == null && m.length > 0 && (u = m[m.length - 1]), {
435
+ ...e,
436
+ availableNexradTimestamps: m,
437
+ nexradTimeToKeyMap: l,
438
+ nexradLevel3MotionTimeToKeyMap: r.level3MotionTimeToKeyMap || {},
439
+ nexradTimestamp: u
440
+ };
441
+ }
442
+ async _ensureLevel2ListingReady(e) {
443
+ if (this._nexradRadarSource(e) !== "level2") return;
444
+ if (this._listingRefreshPromise) {
445
+ await this._listingRefreshPromise;
446
+ return;
577
447
  }
578
- const url = objectKeyToUrl(objectKey, radarSource);
579
- const fetchKey = `${url}|${radarVar}|${radarSource}|${motionObjectKey || ''}`;
448
+ const t = () => this.core._nexradTimesCacheKey?.(),
449
+ a = () => t() ? this.core.nexradTimesByStation?.[t()] : null;
450
+ D(a()) && (this._listingRefreshPromise = (async () => {
451
+ try {
452
+ await this.core.refreshNexradTimes();
453
+ let n = a();
454
+ if (D(n)) {
455
+ const s = await te(this.core, this.core.state, {
456
+ siteOrigin: this.core.gridRequestSiteOrigin || ""
457
+ });
458
+ if (n = a(), !s) {
459
+ y("listing.patchFailed", {
460
+ site: e.nexradSite,
461
+ cacheKey: t()
462
+ });
463
+ return;
464
+ }
465
+ if (n?.level2ListingEmpty) {
466
+ y("listing.empty", {
467
+ site: e.nexradSite,
468
+ cacheKey: t(),
469
+ hint: ae(e.nexradSite)
470
+ });
471
+ return;
472
+ }
473
+ }
474
+ const i = n?.timeToKeyMap || {},
475
+ r = Object.values(i).find(s => typeof s == "string" && s.length > 0);
476
+ y("listing.refreshed", {
477
+ site: e.nexradSite,
478
+ product: e.nexradProduct,
479
+ tilt: e.nexradTilt,
480
+ cacheKey: t(),
481
+ clensEntries: Object.keys(n?.level2Clens || {}).length,
482
+ mappedTimes: Object.keys(i).length,
483
+ sampleKeyTail: typeof r == "string" ? r.slice(-72) : r
484
+ });
485
+ } catch (n) {
486
+ y("listing.refreshFailed", {
487
+ site: e.nexradSite,
488
+ message: n?.message || String(n)
489
+ });
490
+ } finally {
491
+ this._listingRefreshPromise = null;
492
+ }
493
+ })(), await this._listingRefreshPromise);
494
+ }
495
+ _logListingDiag(e, t, a, n = {}) {
496
+ const {
497
+ nk: i,
498
+ ent: r,
499
+ timeToKeyMap: s,
500
+ motionMap: l
501
+ } = this._resolveListingContext(t),
502
+ o = Object.keys(s || {}),
503
+ m = a != null ? s[String(a)] : void 0;
504
+ y(e, {
505
+ site: t.nexradSite,
506
+ product: t.nexradProduct,
507
+ tilt: t.nexradTilt,
508
+ radarSource: this._nexradRadarSource(t),
509
+ unix: a,
510
+ listingCacheKey: i,
511
+ coreListingPresent: !!r,
512
+ stateMapEntries: Object.keys(t.nexradTimeToKeyMap || {}).length,
513
+ mergedMapEntries: o.length,
514
+ motionMapEntries: Object.keys(l || {}).length,
515
+ availableUnixCount: Array.isArray(t.availableNexradTimestamps) ? t.availableNexradTimestamps.length : 0,
516
+ hasObjectKeyForUnix: a != null && Object.prototype.hasOwnProperty.call(s, String(a)),
517
+ objectKeyTail: typeof m == "string" ? m.slice(-72) : m,
518
+ sampleMapEntries: o.slice(0, 4).map(u => ({
519
+ unix: u,
520
+ keyTail: String(s[u] || "").slice(-56)
521
+ })),
522
+ nativeLayerReady: !!this._native()?.uploadNexradFrame,
523
+ ...n
524
+ });
525
+ }
526
+ _nexradRadarSource(e) {
527
+ return e.nexradDataSource === "level3" ? "level3" : "level2";
528
+ }
529
+ _buildFetchParamsForUnix(e, t, a = {}) {
530
+ const n = a.logDiag !== !1,
531
+ i = (e.nexradProduct || "REF").toUpperCase(),
532
+ r = this._nexradRadarSource(e),
533
+ s = X(ee(i)),
534
+ {
535
+ ent: l,
536
+ timeToKeyMap: o,
537
+ motionMap: m
538
+ } = this._resolveListingContext(e),
539
+ u = o[String(t)];
540
+ if (!u) return n && this._logListingDiag("fetchParams.missingObjectKey", e, t, {
541
+ radarVar: i
542
+ }), null;
543
+ const d = r === "level2" ? ie({
544
+ state: e,
545
+ listingEntry: l,
546
+ unix: t,
547
+ radarVar: i,
548
+ rawKey: u
549
+ }) : u;
550
+ if (!d) return n && y("fetchParams.invalidLevel2ObjectKey", {
551
+ site: e.nexradSite,
552
+ unix: t,
553
+ rawKeyTail: String(u).slice(-72),
554
+ hasLevel2Clens: !!(l?.level2Clens && Object.keys(l.level2Clens).length)
555
+ }), null;
556
+ let N = null;
557
+ i === "VEL" && e.nexradStormRelative && (N = me(t, m));
558
+ const p = G(d, r),
559
+ F = `${p}|${i}|${r}|${N || ""}`;
580
560
  return {
581
- objectKey,
582
- url,
583
- fetchKey,
584
- motionObjectKey,
585
- radarVar,
586
- radarSource,
587
- groupId
561
+ objectKey: d,
562
+ url: p,
563
+ fetchKey: F,
564
+ motionObjectKey: N,
565
+ radarVar: i,
566
+ radarSource: r,
567
+ groupId: s
588
568
  };
589
569
  }
590
- async _fetchFrame(state, unix, {
591
- signal,
592
- priority
570
+ async _fetchFrame(e, t, {
571
+ signal: a,
572
+ priority: n
593
573
  }) {
594
- const fetchPerf = nexradPerfSpan(`fetchAndParseArchive priority=${priority} site=${state.nexradSite} unix=${unix} product=${state.nexradProduct}`);
595
- const p = this._buildFetchParamsForUnix(state, unix);
596
- if (!p) {
597
- fetchPerf.end({
598
- ok: false,
599
- reason: 'noFetchParams'
600
- });
601
- return null;
602
- }
574
+ const i = h(`fetchAndParseArchive priority=${n} site=${e.nexradSite} unix=${t} product=${e.nexradProduct}`),
575
+ r = this._buildFetchParamsForUnix(e, t);
576
+ if (!r) return i.end({
577
+ ok: !1,
578
+ reason: "noFetchParams"
579
+ }), null;
580
+ y("fetch.start", {
581
+ priority: n,
582
+ site: e.nexradSite,
583
+ unix: t,
584
+ radarVar: r.radarVar,
585
+ radarSource: r.radarSource,
586
+ url: r.url?.replace(/([?&])apiKey=[^&]*/gi, "$1apiKey=(redacted)"),
587
+ objectKeyTail: (r.objectKey || "").slice(-72),
588
+ motionKeyTail: (r.motionObjectKey || "").slice(-48)
589
+ });
603
590
  try {
604
- const frame = await fetchAndParseArchive(p.url, p.objectKey, p.radarVar, p.groupId, p.radarSource, {
605
- signal,
606
- priority,
607
- level3MotionObjectKey: p.motionObjectKey
608
- });
609
- fetchPerf.end({
610
- ok: !!frame,
611
- radarVar: p.radarVar,
612
- radarSource: p.radarSource,
613
- objectKeyTail: (p.objectKey || '').slice(-48),
614
- motionKeyTail: (p.motionObjectKey || '').slice(-48)
615
- });
616
- return frame;
617
- } catch (err) {
618
- fetchPerf.end({
619
- ok: false,
620
- error: err?.message || String(err),
621
- radarVar: p.radarVar,
622
- radarSource: p.radarSource
623
- });
624
- throw err;
591
+ const s = await k(r.url, r.objectKey, r.radarVar, r.groupId, r.radarSource, {
592
+ signal: a,
593
+ priority: n,
594
+ level3MotionObjectKey: r.motionObjectKey
595
+ }),
596
+ l = {
597
+ ok: !!s,
598
+ radarVar: r.radarVar,
599
+ radarSource: r.radarSource,
600
+ objectKeyTail: (r.objectKey || "").slice(-48),
601
+ motionKeyTail: (r.motionObjectKey || "").slice(-48)
602
+ };
603
+ return s && (l.nGates = s.nGates, l.nRays = s.nRays, l.gateBytes = s.gateData?.length ?? 0), i.end(l), y(s ? "fetch.ok" : "fetch.emptyFrame", l), s;
604
+ } catch (s) {
605
+ const l = {
606
+ ok: !1,
607
+ error: s?.message || String(s),
608
+ radarVar: r.radarVar,
609
+ radarSource: r.radarSource,
610
+ objectKeyTail: (r.objectKey || "").slice(-48)
611
+ };
612
+ throw i.end(l), y("fetch.error", l), s;
625
613
  }
626
614
  }
627
- _preloadTimelineSignature(state) {
628
- const nk = this.core._nexradTimesCacheKey?.() || '';
629
- const ts = [...(state.availableNexradTimestamps || [])].map(Number).filter(t => Number.isFinite(t)).sort((a, b) => a - b).join(',');
630
- const tilt = state.nexradTilt != null && Number.isFinite(Number(state.nexradTilt)) ? Number(state.nexradTilt).toFixed(3) : '';
631
- return `${nk}|${ts}|sr:${state.nexradStormRelative ? 1 : 0}|tilt:${tilt}`;
615
+ _preloadTimelineSignature(e) {
616
+ const t = this.core._nexradTimesCacheKey?.() || "",
617
+ a = [...(e.availableNexradTimestamps || [])].map(Number).filter(i => Number.isFinite(i)).sort((i, r) => i - r).join(","),
618
+ n = e.nexradTilt != null && Number.isFinite(Number(e.nexradTilt)) ? Number(e.nexradTilt).toFixed(3) : "";
619
+ return `${t}|${a}|sr:${e.nexradStormRelative ? 1 : 0}|tilt:${n}`;
632
620
  }
633
- _syncIdentity(state, p, unix) {
634
- const tilt = state.nexradTilt != null && Number.isFinite(Number(state.nexradTilt)) ? Number(state.nexradTilt).toFixed(3) : '';
635
- return `${p.fetchKey}|tilt:${tilt}|u:${unix}`;
621
+ _syncIdentity(e, t, a) {
622
+ const n = e.nexradTilt != null && Number.isFinite(Number(e.nexradTilt)) ? Number(e.nexradTilt).toFixed(3) : "";
623
+ return `${t.fetchKey}|tilt:${n}|u:${a}`;
636
624
  }
637
- preloadAllAvailable(state) {
638
- if (!state.isNexrad || !state.nexradSite) return;
639
- if (!ensureRadarArchiveBindings('preloadAllAvailable')) return;
640
- const times = [...(state.availableNexradTimestamps || [])].map(Number).filter(t => Number.isFinite(t));
641
- if (!times.length) {
642
- // Important: do not touch `_preloadTimelineSig` or the frame cache here — callers
643
- // sometimes pass `core.state` before `availableNexradTimestamps` is committed; an
644
- // empty list must not poison the signature or wipe the LRU (see WeatherLayerManager
645
- // preload kick merging subscription snapshot).
625
+ async preloadAllAvailable(e) {
626
+ if (!e.isNexrad || !e.nexradSite) {
627
+ y("preload.skip", {
628
+ reason: "notNexradOrNoSite",
629
+ isNexrad: e.isNexrad,
630
+ site: e.nexradSite
631
+ });
646
632
  return;
647
633
  }
648
- const sig = this._preloadTimelineSignature(state);
649
- if (sig === this._preloadTimelineSig) {
634
+ if (!q("preloadAllAvailable")) {
635
+ y("preload.skip", {
636
+ reason: "missingArchiveBindings",
637
+ site: e.nexradSite
638
+ });
650
639
  return;
651
640
  }
652
- this._preloadTimelineSig = sig;
653
- this._preloadAbort?.abort();
654
- this._preloadAbort = new AbortController();
655
- const signal = this._preloadAbort.signal;
656
-
657
- // Keep the volume currently on screen in the JS cache so getInspectPayload (mapsgl parity readouts)
658
- // still works while we clear and rebuild the prefetch LRU — otherwise readouts stay null until
659
- // this unix is fetched again (often last in the timeline).
660
- const curUnix = state.nexradTimestamp != null && Number.isFinite(Number(state.nexradTimestamp)) ? Number(state.nexradTimestamp) : NaN;
661
-
662
- // Keep frames that are still in the new timeline (or the currently displayed one)
663
- // to avoid re-fetching them when expanding the duration window.
664
- const validFetchKeys = new Set();
665
- for (const unix of times) {
666
- const p = this._buildFetchParamsForUnix(state, unix);
667
- if (p) validFetchKeys.add(p.fetchKey);
641
+ let t = e;
642
+ if ([...(t.availableNexradTimestamps || [])].length || (await this._ensureLevel2ListingReady(t), t = this._nexradStateWithCoreListing(t)), ![...(t.availableNexradTimestamps || [])].length) {
643
+ y("preload.skip", {
644
+ reason: "noAvailableTimestamps",
645
+ site: t.nexradSite,
646
+ product: t.nexradProduct,
647
+ hint: "Listing empty after refreshNexradTimes"
648
+ });
649
+ return;
668
650
  }
669
- const curP = Number.isFinite(curUnix) ? this._buildFetchParamsForUnix(state, curUnix) : null;
670
- if (curP) validFetchKeys.add(curP.fetchKey);
671
- for (const key of this._frameCache.keys()) {
672
- if (!validFetchKeys.has(key)) {
673
- this._frameCache.delete(key);
674
- }
651
+ await this._ensureLevel2ListingReady(t), t = this._nexradStateWithCoreListing(t);
652
+ const a = [...(t.availableNexradTimestamps || [])].map(Number).filter(g => Number.isFinite(g));
653
+ if (!a.length) {
654
+ y("preload.skip", {
655
+ reason: "noValidListingAfterRefresh",
656
+ site: e.nexradSite,
657
+ product: e.nexradProduct
658
+ });
659
+ return;
675
660
  }
676
- // Do NOT clear `_nativeGpuReadyKeys` / JSON LRU / upload meta here: that forced a full
677
- // ~1MB JSON parse + native decode on every timeline scrub after prefetch. GPU cache keys
678
- // stay valid while Metal still holds the slot; `sync` falls back to full upload if needed.
679
- // (Controller `destroy()` still clears everything on site/mode teardown.)
680
-
681
- setNexradArchiveApiKey(this.core.apiKey || '');
682
- setNexradArchiveBundleId(this.core.bundleId || '');
683
- setNexradArchiveSiteOrigin(this.core.gridRequestSiteOrigin || 'https://localhost');
684
- setNexradSitesFetchAuth(this.core.apiKey || '', this.core.bundleId || '');
685
- if (isAguaceroRnDebugEnabled()) {
686
- aguaceroDebug('nexrad.authConfigured', getAguaceroAuthDiagnosticSnapshot(this.core, {
687
- phase: 'NexradAndroidController.preload',
688
- site: state.nexradSite,
689
- product: state.nexradProduct
690
- }));
661
+ const n = this._preloadTimelineSignature(t);
662
+ if (n === this._preloadTimelineSig) {
663
+ y("preload.skip", {
664
+ reason: "sameTimelineSig",
665
+ site: e.nexradSite,
666
+ times: a.length
667
+ });
668
+ return;
691
669
  }
692
- const snapshot = {
693
- ...state
694
- };
695
- const preloadBatch = nexradPerfSpan(`preload.batch site=${state.nexradSite} times=${times.length}`);
696
- let preloadCompleted = 0;
697
- let preloadFailed = 0;
698
- let preloadSkippedCached = 0;
699
- const run = async () => {
700
- // Prime the visible unix first so the active frame hits GPU before background slots.
701
- const curUx = snapshot.nexradTimestamp != null && Number.isFinite(Number(snapshot.nexradTimestamp)) ? Number(snapshot.nexradTimestamp) : NaN;
702
- if (Number.isFinite(curUx)) {
703
- const p0 = this._buildFetchParamsForUnix(snapshot, curUx);
704
- if (p0) {
705
- const fr0 = this._frameCache.get(p0.fetchKey);
706
- if (fr0) {
707
- this._primeNativeGpuUploadIfNeeded(snapshot, curUx, p0, fr0, signal);
708
- await yieldToJsEventLoop();
709
- }
670
+ this._preloadTimelineSig = n, this._preloadAbort?.abort(), this._preloadAbort = new AbortController();
671
+ const i = this._preloadAbort.signal;
672
+ let r = 0,
673
+ s = 0;
674
+ for (const g of a) this._buildFetchParamsForUnix(t, g, {
675
+ logDiag: !1
676
+ }) ? r++ : s++;
677
+ if (y("preload.start", {
678
+ site: t.nexradSite,
679
+ product: t.nexradProduct,
680
+ dataSource: t.nexradDataSource,
681
+ tilt: t.nexradTilt,
682
+ times: a.length,
683
+ validFetchParams: r,
684
+ invalidFetchParams: s,
685
+ displayUnix: t.nexradTimestamp,
686
+ timelineSigTail: n.slice(-80)
687
+ }), r === 0) {
688
+ this._logListingDiag("preload.allFetchParamsInvalid", t, t.nexradTimestamp, {
689
+ times: a.length
690
+ });
691
+ return;
692
+ }
693
+ const l = t.nexradTimestamp != null && Number.isFinite(Number(t.nexradTimestamp)) ? Number(t.nexradTimestamp) : NaN,
694
+ o = new Set();
695
+ for (const g of a) {
696
+ const f = this._buildFetchParamsForUnix(t, g);
697
+ f && o.add(f.fetchKey);
698
+ }
699
+ const m = Number.isFinite(l) ? this._buildFetchParamsForUnix(t, l) : null;
700
+ m && o.add(m.fetchKey);
701
+ for (const g of this._frameCache.keys()) o.has(g) || this._frameCache.delete(g);
702
+ L(this.core.apiKey || ""), R(this.core.bundleId || ""), w(this.core.gridRequestSiteOrigin || I), $(this.core.nexradUserId || "sdk-user"), B(this.core.apiKey || "", this.core.bundleId || ""), W() && z("nexrad.authConfigured", H(this.core, {
703
+ phase: "NexradAndroidController.preload",
704
+ site: t.nexradSite,
705
+ product: t.nexradProduct
706
+ }));
707
+ const u = {
708
+ ...t
709
+ },
710
+ d = h(`preload.batch site=${t.nexradSite} times=${a.length}`);
711
+ let N = 0,
712
+ p = 0,
713
+ F = 0;
714
+ await (async () => {
715
+ const g = u.nexradTimestamp != null && Number.isFinite(Number(u.nexradTimestamp)) ? Number(u.nexradTimestamp) : NaN;
716
+ if (Number.isFinite(g)) {
717
+ const x = this._buildFetchParamsForUnix(u, g);
718
+ if (x) {
719
+ const S = this._frameCache.get(x.fetchKey);
720
+ S && (this._primeNativeGpuUploadIfNeeded(u, g, x, S, i), await M());
710
721
  }
711
722
  }
712
- let cursor = 0;
713
- const work = async () => {
714
- while (cursor < times.length && !signal.aborted) {
715
- const i = cursor++;
716
- const unix = times[i];
717
- const slot = nexradPerfSpan(`preload.slot idx=${i + 1}/${times.length} unix=${unix}`);
718
- const p = this._buildFetchParamsForUnix(snapshot, unix);
719
- if (!p || signal.aborted) {
720
- slot.end({
721
- outcome: 'noParamsOrAborted'
723
+ let f = 0;
724
+ const _ = async () => {
725
+ for (; f < a.length && !i.aborted;) {
726
+ const x = f++,
727
+ S = a[x],
728
+ v = h(`preload.slot idx=${x + 1}/${a.length} unix=${S}`),
729
+ b = this._buildFetchParamsForUnix(u, S);
730
+ if (!b || i.aborted) v.end({
731
+ outcome: "noParamsOrAborted"
732
+ });else if (this._frameCache.has(b.fetchKey)) {
733
+ F++;
734
+ const T = this._frameCache.get(b.fetchKey);
735
+ this._primeNativeGpuUploadIfNeeded(u, S, b, T, i), await M(), v.end({
736
+ outcome: "alreadyCached",
737
+ fetchKeyTail: b.fetchKey.slice(-64)
738
+ });
739
+ } else try {
740
+ const T = await this._fetchFrame(u, S, {
741
+ signal: i,
742
+ priority: "prefetch"
722
743
  });
723
- } else if (this._frameCache.has(p.fetchKey)) {
724
- preloadSkippedCached++;
725
- const cachedFrame = this._frameCache.get(p.fetchKey);
726
- this._primeNativeGpuUploadIfNeeded(snapshot, unix, p, cachedFrame, signal);
727
- await yieldToJsEventLoop();
728
- slot.end({
729
- outcome: 'alreadyCached',
730
- fetchKeyTail: p.fetchKey.slice(-64)
744
+ T && !i.aborted ? (this._frameCache.set(b.fetchKey, T), N++, this._primeNativeGpuUploadIfNeeded(u, S, b, T, i), await M(), v.end({
745
+ outcome: "cachedFrame",
746
+ fetchKeyTail: b.fetchKey.slice(-64),
747
+ cacheSizeAfter: this._frameCache.size
748
+ })) : v.end({
749
+ outcome: "noFrame",
750
+ aborted: i.aborted
751
+ });
752
+ } catch (T) {
753
+ p++, v.end({
754
+ outcome: "error",
755
+ message: T?.message || String(T)
731
756
  });
732
- } else {
733
- try {
734
- const frame = await this._fetchFrame(snapshot, unix, {
735
- signal,
736
- priority: 'prefetch'
737
- });
738
- if (frame && !signal.aborted) {
739
- this._frameCache.set(p.fetchKey, frame);
740
- preloadCompleted++;
741
- this._primeNativeGpuUploadIfNeeded(snapshot, unix, p, frame, signal);
742
- await yieldToJsEventLoop();
743
- slot.end({
744
- outcome: 'cachedFrame',
745
- fetchKeyTail: p.fetchKey.slice(-64),
746
- cacheSizeAfter: this._frameCache.size
747
- });
748
- } else {
749
- slot.end({
750
- outcome: 'noFrame',
751
- aborted: signal.aborted
752
- });
753
- }
754
- } catch (err) {
755
- preloadFailed++;
756
- slot.end({
757
- outcome: 'error',
758
- message: err?.message || String(err)
759
- });
760
- }
761
757
  }
762
- await yieldToJsEventLoop();
758
+ await M();
763
759
  }
764
760
  };
765
- await Promise.all(Array.from({
766
- length: PRELOAD_CONCURRENCY
767
- }, () => work()));
768
-
769
- // Catch-up: any unix still missing a GPU slot (e.g. layer mounted mid-preload) gets one upload pass.
770
- if (!signal.aborted) {
771
- for (let i = 0; i < times.length && !signal.aborted; i++) {
772
- const unix = times[i];
773
- const p = this._buildFetchParamsForUnix(snapshot, unix);
774
- if (!p) continue;
775
- const frame = this._frameCache.get(p.fetchKey);
776
- if (!frame) continue;
777
- const syncKey = this._syncIdentity(snapshot, p, unix);
778
- if (this._nativeGpuReadyKeys.has(syncKey)) continue;
779
- this._primeNativeGpuUploadIfNeeded(snapshot, unix, p, frame, signal);
780
- await yieldToJsEventLoop();
781
- }
761
+ if (await Promise.all(Array.from({
762
+ length: be
763
+ }, () => _())), !i.aborted) for (let x = 0; x < a.length && !i.aborted; x++) {
764
+ const S = a[x],
765
+ v = this._buildFetchParamsForUnix(u, S);
766
+ if (!v) continue;
767
+ const b = this._frameCache.get(v.fetchKey);
768
+ if (!b) continue;
769
+ const T = this._syncIdentity(u, v, S);
770
+ this._nativeGpuReadyKeys.has(T) || (this._primeNativeGpuUploadIfNeeded(u, S, v, b, i), await M());
782
771
  }
783
- preloadBatch.end({
784
- outcome: signal.aborted ? 'aborted' : 'complete',
785
- completed: preloadCompleted,
786
- failed: preloadFailed,
787
- skippedCached: preloadSkippedCached,
772
+ const C = {
773
+ outcome: i.aborted ? "aborted" : "complete",
774
+ completed: N,
775
+ failed: p,
776
+ skippedCached: F,
788
777
  finalCacheSize: this._frameCache.size,
789
778
  gpuReadyCount: this._nativeGpuReadyKeys.size
779
+ };
780
+ d.end(C), y("preload.done", C);
781
+ })();
782
+ }
783
+ async sync(e) {
784
+ const t = e.nexradTimestamp != null ? Number(e.nexradTimestamp) : NaN,
785
+ a = h(`sync.total site=${e.nexradSite} unix=${t} product=${e.nexradProduct} source=${e.nexradDataSource} tilt=${e.nexradTilt}`);
786
+ if (!e.isNexrad || !e.nexradSite) {
787
+ y("sync.skip", {
788
+ reason: "notNexradOrNoSite",
789
+ isNexrad: e.isNexrad,
790
+ site: e.nexradSite
791
+ }), this.destroy(), a.end({
792
+ outcome: "skippedNotNexradOrNoSite"
790
793
  });
791
- };
792
- void run();
793
- }
794
- async sync(state) {
795
- const unixEarly = state.nexradTimestamp != null ? Number(state.nexradTimestamp) : NaN;
796
- const syncTotal = nexradPerfSpan(`sync.total site=${state.nexradSite} unix=${unixEarly} product=${state.nexradProduct} source=${state.nexradDataSource} tilt=${state.nexradTilt}`);
797
- if (!state.isNexrad || !state.nexradSite || state.nexradTimestamp == null) {
798
- this.destroy();
799
- syncTotal.end({
800
- outcome: 'skippedNotNexradOrMissing'
794
+ return;
795
+ }
796
+ if (!q("sync")) {
797
+ y("sync.skip", {
798
+ reason: "missingArchiveBindings",
799
+ site: e.nexradSite
800
+ }), a.end({
801
+ outcome: "skippedMissingArchiveBindings"
801
802
  });
802
803
  return;
803
804
  }
804
- if (!ensureRadarArchiveBindings('sync')) {
805
- syncTotal.end({
806
- outcome: 'skippedMissingArchiveBindings'
805
+ await this._ensureLevel2ListingReady(e), e = this._nexradStateWithCoreListing(e);
806
+ let n = e.nexradTimestamp != null ? Number(e.nexradTimestamp) : NaN;
807
+ if (!Number.isFinite(n) && this.core.state.nexradTimestamp != null && (n = Number(this.core.state.nexradTimestamp), e = {
808
+ ...e,
809
+ nexradTimestamp: n
810
+ }), !Number.isFinite(n) && Array.isArray(e.availableNexradTimestamps) && e.availableNexradTimestamps.length > 0 && (n = Number(e.availableNexradTimestamps[e.availableNexradTimestamps.length - 1]), e = {
811
+ ...e,
812
+ nexradTimestamp: n
813
+ }, this.core.state.nexradTimestamp == null && (this.core.state.nexradTimestamp = n, typeof this.core._emitStateChange == "function" && this.core._emitStateChange())), !Number.isFinite(n)) {
814
+ y("sync.skip", {
815
+ reason: "noTimestampYet",
816
+ site: e.nexradSite,
817
+ availableUnixCount: Array.isArray(e.availableNexradTimestamps) ? e.availableNexradTimestamps.length : 0
818
+ }), a.end({
819
+ outcome: "skippedNoTimestampYet"
807
820
  });
808
821
  return;
809
822
  }
810
- const tAuth = nexradPerfSpan('sync.setArchiveAuth');
811
- setNexradArchiveApiKey(this.core.apiKey || '');
812
- setNexradArchiveBundleId(this.core.bundleId || '');
813
- setNexradArchiveSiteOrigin(this.core.gridRequestSiteOrigin || 'https://localhost');
814
- setNexradSitesFetchAuth(this.core.apiKey || '', this.core.bundleId || '');
815
- tAuth.end({});
816
- const unix = Number(state.nexradTimestamp);
817
- const tParams = nexradPerfSpan('sync.buildFetchParams');
818
- const p = this._buildFetchParamsForUnix(state, unix);
819
- tParams.end({
820
- ok: !!p
823
+ y("sync.start", {
824
+ site: e.nexradSite,
825
+ product: e.nexradProduct,
826
+ dataSource: e.nexradDataSource,
827
+ tilt: e.nexradTilt,
828
+ unix: e.nexradTimestamp,
829
+ nativeLayerReady: !!this._native()?.uploadNexradFrame
821
830
  });
822
- if (!p) {
823
- const ctx = this._resolveListingContext(state);
824
- syncTotal.end({
825
- outcome: 'noFetchParams'
831
+ const i = h("sync.setArchiveAuth");
832
+ L(this.core.apiKey || ""), R(this.core.bundleId || ""), w(this.core.gridRequestSiteOrigin || I), $(this.core.nexradUserId || "sdk-user"), B(this.core.apiKey || "", this.core.bundleId || ""), i.end({});
833
+ const r = h("sync.buildFetchParams"),
834
+ s = this._buildFetchParamsForUnix(e, n);
835
+ if (r.end({
836
+ ok: !!s
837
+ }), !s) {
838
+ this._logListingDiag("sync.noFetchParams", e, n), a.end({
839
+ outcome: "noFetchParams"
840
+ }), y("sync.done", {
841
+ outcome: "noFetchParams",
842
+ site: e.nexradSite,
843
+ unix: n
826
844
  });
827
845
  return;
828
846
  }
829
- const tIdentity = nexradPerfSpan('sync.syncIdentity');
830
- const syncKey = this._syncIdentity(state, p, unix);
831
- tIdentity.end({
832
- syncKeyTail: syncKey.slice(-96),
833
- lastSyncKeyMatch: syncKey === this._lastSyncKey
847
+ const l = h("sync.syncIdentity"),
848
+ o = this._syncIdentity(e, s, n);
849
+ l.end({
850
+ syncKeyTail: o.slice(-96),
851
+ lastSyncKeyMatch: o === this._lastSyncKey
834
852
  });
835
- const jsCachedForShortCircuit = this._frameCache.get(p.fetchKey);
836
- if (syncKey === this._lastSyncKey && this._nativeFrameUploaded && jsCachedForShortCircuit) {
837
- const tStyle = nexradPerfSpan('sync.shortCircuit_styleOnly');
838
- this.applyStyleFromState(state);
839
- tStyle.end({});
840
- syncTotal.end({
841
- outcome: 'styleOnlyShortCircuit'
853
+ const m = this._frameCache.get(s.fetchKey);
854
+ if (o === this._lastSyncKey && this._nativeFrameUploaded && m) {
855
+ const f = h("sync.shortCircuit_styleOnly");
856
+ this.applyStyleFromState(e), f.end({}), a.end({
857
+ outcome: "styleOnlyShortCircuit"
842
858
  });
843
859
  return;
844
860
  }
845
- const tCacheLookup = nexradPerfSpan('sync.memoryCacheLookup');
846
- const cached = this._frameCache.get(p.fetchKey);
847
- tCacheLookup.end({
848
- hit: !!cached,
861
+ const u = h("sync.memoryCacheLookup"),
862
+ d = this._frameCache.get(s.fetchKey);
863
+ u.end({
864
+ hit: !!d,
849
865
  cacheSize: this._frameCache.size,
850
- fetchKeyTail: p.fetchKey.slice(-80)
866
+ fetchKeyTail: s.fetchKey.slice(-80)
851
867
  });
852
- const tGpuTry = nexradPerfSpan('sync.tryGpuCacheActivate');
853
- if (cached && this._nativeGpuReadyKeys.has(syncKey)) {
854
- const n = this._native();
855
- if (n?.activateNexradCachedFrame) {
856
- const tAct = nexradPerfSpan('sync.dispatchActivateCachedFrame');
857
- n.activateNexradCachedFrame(syncKey);
858
- tAct.end({
859
- keyLen: syncKey.length
868
+ const N = h("sync.tryGpuCacheActivate");
869
+ if (d && this._nativeGpuReadyKeys.has(o)) {
870
+ const f = this._native();
871
+ if (f?.activateNexradCachedFrame) {
872
+ const _ = h("sync.dispatchActivateCachedFrame");
873
+ f.activateNexradCachedFrame(o), _.end({
874
+ keyLen: o.length
860
875
  });
861
- const tStyle = nexradPerfSpan('sync.applyStyleAfterGpuActivate');
862
- this.applyStyleFromState(state);
863
- tStyle.end({});
864
- const meta = this._uploadMetaBySyncKey.get(syncKey);
865
- if (meta) {
866
- this._lastUploadMeta = {
867
- valueScale: meta.valueScale,
868
- valueOffset: meta.valueOffset
869
- };
870
- }
871
- this._lastSyncKey = syncKey;
872
- this._nativeFrameUploaded = true;
873
- tGpuTry.end({
874
- outcome: 'gpuCacheActivate',
876
+ const C = h("sync.applyStyleAfterGpuActivate");
877
+ this.applyStyleFromState(e), C.end({});
878
+ const x = this._uploadMetaBySyncKey.get(o);
879
+ x && (this._lastUploadMeta = {
880
+ valueScale: x.valueScale,
881
+ valueOffset: x.valueOffset
882
+ }), this._lastSyncKey = o, this._nativeFrameUploaded = !0, N.end({
883
+ outcome: "gpuCacheActivate",
875
884
  gpuReadySetSize: this._nativeGpuReadyKeys.size
876
- });
877
- syncTotal.end({
878
- outcome: 'gpuCacheActivate'
885
+ }), a.end({
886
+ outcome: "gpuCacheActivate"
879
887
  });
880
888
  return;
881
889
  }
882
890
  }
883
- tGpuTry.end({
884
- outcome: 'noGpuActivate',
885
- hasJsCachedFrame: !!cached,
886
- gpuReadyForSyncKey: this._nativeGpuReadyKeys.has(syncKey),
891
+ if (N.end({
892
+ outcome: "noGpuActivate",
893
+ hasJsCachedFrame: !!d,
894
+ gpuReadyForSyncKey: this._nativeGpuReadyKeys.has(o),
887
895
  hasActivateMethod: !!this._native()?.activateNexradCachedFrame
888
- });
889
- if (cached) {
890
- const tUpload = nexradPerfSpan('sync.uploadFromMemoryCache_toNative');
891
- this._uploadFrameToNative(state, cached, p, unix);
892
- tUpload.end({});
893
- this._lastSyncKey = syncKey;
894
- syncTotal.end({
895
- outcome: 'memoryCacheHit'
896
+ }), d) {
897
+ const f = h("sync.uploadFromMemoryCache_toNative");
898
+ this._uploadFrameToNative(e, d, s, n), f.end({}), this._lastSyncKey = o, a.end({
899
+ outcome: "memoryCacheHit"
896
900
  });
897
901
  return;
898
902
  }
899
- this._abort?.abort();
900
- this._abort = new AbortController();
901
- let frame;
903
+ this._abort?.abort(), this._abort = new AbortController();
904
+ let p;
902
905
  try {
903
- frame = await this._fetchFrame(state, unix, {
906
+ p = await this._fetchFrame(e, n, {
904
907
  signal: this._abort.signal,
905
- priority: 'display'
908
+ priority: "display"
906
909
  });
907
- } catch (err) {
908
- syncTotal.end({
909
- outcome: 'fetchThrew',
910
- message: err?.message || String(err)
910
+ } catch (f) {
911
+ const _ = f?.message || String(f);
912
+ a.end({
913
+ outcome: "fetchThrew",
914
+ message: _
915
+ }), y("sync.done", {
916
+ outcome: "fetchThrew",
917
+ site: e.nexradSite,
918
+ unix: n,
919
+ message: _
911
920
  });
912
921
  return;
913
922
  }
914
- if (!frame || this._abort.signal.aborted) {
915
- syncTotal.end({
916
- outcome: 'fetchNoFrame',
923
+ if (!p || this._abort.signal.aborted) {
924
+ const f = {
925
+ outcome: "fetchNoFrame",
917
926
  aborted: this._abort.signal.aborted,
918
- hadFrame: !!frame
927
+ hadFrame: !!p
928
+ };
929
+ a.end(f), y("sync.done", {
930
+ ...f,
931
+ site: e.nexradSite,
932
+ unix: n
919
933
  });
920
934
  return;
921
935
  }
922
- const tPut = nexradPerfSpan('sync.frameCacheSet');
923
- this._frameCache.set(p.fetchKey, frame);
924
- tPut.end({
936
+ const F = h("sync.frameCacheSet");
937
+ this._frameCache.set(s.fetchKey, p), F.end({
925
938
  cacheSizeAfter: this._frameCache.size
926
939
  });
927
- const tUploadFetched = nexradPerfSpan('sync.uploadFetchedFrame_toNative');
928
- this._uploadFrameToNative(state, frame, p, unix);
929
- tUploadFetched.end({});
930
- this._lastSyncKey = syncKey;
931
- syncTotal.end({
932
- outcome: 'fetchedAndUploaded'
940
+ const g = h("sync.uploadFetchedFrame_toNative");
941
+ this._uploadFrameToNative(e, p, s, n), g.end({}), this._lastSyncKey = o, a.end({
942
+ outcome: "fetchedAndUploaded"
943
+ }), y("sync.done", {
944
+ outcome: "fetchedAndUploaded",
945
+ site: e.nexradSite,
946
+ unix: n,
947
+ nGates: p.nGates,
948
+ nRays: p.nRays,
949
+ nativeFrameUploaded: this._nativeFrameUploaded
933
950
  });
934
951
  }
935
- getInspectPayload(lng, lat, state) {
936
- if (!state?.isNexrad || !state.nexradSite || state.nexradTimestamp == null) {
937
- return null;
938
- }
939
- if (state.visible === false || (state.opacity ?? 1) <= 0) {
940
- return null;
941
- }
942
- const unix = Number(state.nexradTimestamp);
943
- const p = this._buildFetchParamsForUnix(state, unix);
944
- if (!p) {
945
- return null;
946
- }
947
- const frame = this._frameCache.get(p.fetchKey);
948
- if (!frame) {
949
- return null;
950
- }
951
- const colormapFlat = state.colormap;
952
- if (!colormapFlat || colormapFlat.length < 2) {
953
- return null;
954
- }
955
- const rangeMin = colormapFlat[0];
956
- const rangeMax = colormapFlat[colormapFlat.length - 2];
957
- const radarVariable = (state.nexradProduct || 'REF').toUpperCase();
958
- const radarSource = state.nexradDataSource === 'level3' ? 'level3' : 'level2';
959
- const displayUnits = state.units && String(state.units).toLowerCase() !== 'none' ? state.units : isVelocityStyleRadarVar(radarVariable) ? 'm/s' : '';
960
- const uploadOptsForReadout = mapboxFrameUploadOptionsForNexradState(state);
961
- const gpuFrame = this._getPreparedReadoutFrame(frame, uploadOptsForReadout);
962
- const sample = sampleNexradFrameAtLatLon(gpuFrame, lat, lng, {
963
- smoothPolar: this._gateSmoothing
964
- });
965
- if (!sample) {
966
- return null;
967
- }
968
- const valueMs = sample.value;
969
- const isHydro = radarSource === 'level3' && nexradLevel3IsHydrometeorClassification(radarVariable);
970
- let valueOut;
971
- let unitOut = displayUnits || '';
972
- if (isVelocityStyleRadarVar(radarVariable)) {
973
- valueOut = velocityMsToDisplay(valueMs, displayUnits);
974
- } else if (isHydro) {
975
- const label = nexradHydrometeorLabelForClassIndex(valueMs);
976
- if (label == null) {
977
- return null;
978
- }
979
- valueOut = label;
980
- unitOut = '';
981
- } else {
982
- valueOut = formatNexradInspectNumeric(valueMs, radarVariable);
983
- const bu = state.colormapBaseUnit;
984
- if (bu != null && String(bu).length > 0 && String(bu).toLowerCase() !== 'none') {
985
- unitOut = bu;
986
- }
987
- }
988
- let inRange;
989
- if (isHydro) {
990
- const idx = Math.round(Number(valueMs));
991
- inRange = (rangeMin == null || idx >= rangeMin) && (rangeMax == null || idx <= rangeMax);
992
- } else if (isVelocityStyleRadarVar(radarVariable)) {
993
- inRange = (rangeMin == null || valueOut >= rangeMin) && (rangeMax == null || valueOut <= rangeMax);
952
+ getInspectPayload(e, t, a) {
953
+ if (!a?.isNexrad || !a.nexradSite || a.nexradTimestamp == null || a.visible === !1 || (a.opacity ?? 1) <= 0) return null;
954
+ const n = Number(a.nexradTimestamp),
955
+ i = this._buildFetchParamsForUnix(a, n);
956
+ if (!i) return null;
957
+ const r = this._frameCache.get(i.fetchKey);
958
+ if (!r) return null;
959
+ const s = a.colormap;
960
+ if (!s || s.length < 2) return null;
961
+ const l = s[0],
962
+ o = s[s.length - 2],
963
+ m = (a.nexradProduct || "REF").toUpperCase(),
964
+ u = this._nexradRadarSource(a) || "level3",
965
+ d = a.units && String(a.units).toLowerCase() !== "none" ? a.units : U(m) ? "m/s" : "",
966
+ N = V(a),
967
+ p = this._getPreparedReadoutFrame(r, N),
968
+ F = le(p, t, e, {
969
+ smoothPolar: this._gateSmoothing
970
+ });
971
+ if (!F) return null;
972
+ const g = F.value,
973
+ f = u === "level3" && fe(m);
974
+ let _,
975
+ C = d || "";
976
+ if (U(m)) _ = ve(g, d);else if (f) {
977
+ const K = xe(g);
978
+ if (K == null) return null;
979
+ _ = K, C = "";
994
980
  } else {
995
- // Do not apply the colormap *lower* stop as a hard readout floor: weak echoes below the first
996
- // legend tick can still be drawn (LUT / GL), and users expect a number there.
997
- inRange = rangeMax == null || valueOut <= rangeMax;
998
- }
999
- if (!inRange) {
1000
- return null;
1001
- }
1002
- const tiltDeg = Number.isFinite(state.nexradTilt) ? state.nexradTilt : getDefaultRadarTilt(state.nexradSite);
1003
- const bhKm = beamHeightKm(sample.groundRangeKm, tiltDeg);
1004
- const metric = state.units === 'metric';
1005
- const beamHeightDisplay = metric ? bhKm : bhKm * 3.280839895013123;
1006
- const beamUnit = metric ? 'km' : 'kft';
1007
- const fldKey = state.variable;
981
+ _ = Se(g, m);
982
+ const K = a.colormapBaseUnit;
983
+ K != null && String(K).length > 0 && String(K).toLowerCase() !== "none" && (C = K);
984
+ }
985
+ let x;
986
+ if (f) {
987
+ const K = Math.round(Number(g));
988
+ x = (l == null || K >= l) && (o == null || K <= o);
989
+ } else U(m) ? x = (l == null || _ >= l) && (o == null || _ <= o) : x = o == null || _ <= o;
990
+ if (!x) return null;
991
+ const S = Number.isFinite(a.nexradTilt) ? a.nexradTilt : Q(a.nexradSite),
992
+ v = _e(F.groundRangeKm, S),
993
+ b = a.units === "metric",
994
+ T = b ? v : v * 3.280839895013123,
995
+ P = b ? "km" : "kft",
996
+ A = a.variable;
1008
997
  return {
1009
998
  lngLat: {
1010
- lng,
1011
- lat
999
+ lng: e,
1000
+ lat: t
1012
1001
  },
1013
1002
  variable: {
1014
- code: fldKey,
1015
- name: this.core.getVariableDisplayName(fldKey)
1003
+ code: A,
1004
+ name: this.core.getVariableDisplayName(A)
1016
1005
  },
1017
- value: valueOut,
1018
- unit: unitOut,
1019
- beamHeight: Number.isFinite(beamHeightDisplay) && Number.isFinite(bhKm) ? {
1020
- value: beamHeightDisplay,
1021
- unit: beamUnit
1006
+ value: _,
1007
+ unit: C,
1008
+ beamHeight: Number.isFinite(T) && Number.isFinite(v) ? {
1009
+ value: T,
1010
+ unit: P
1022
1011
  } : null
1023
1012
  };
1024
1013
  }