@jablum/weather-mcp 1.7.0

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 (235) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1319 -0
  3. package/dist/analytics/anonymizer.d.ts +37 -0
  4. package/dist/analytics/anonymizer.d.ts.map +1 -0
  5. package/dist/analytics/anonymizer.js +112 -0
  6. package/dist/analytics/anonymizer.js.map +1 -0
  7. package/dist/analytics/collector.d.ts +72 -0
  8. package/dist/analytics/collector.d.ts.map +1 -0
  9. package/dist/analytics/collector.js +282 -0
  10. package/dist/analytics/collector.js.map +1 -0
  11. package/dist/analytics/config.d.ts +15 -0
  12. package/dist/analytics/config.d.ts.map +1 -0
  13. package/dist/analytics/config.js +172 -0
  14. package/dist/analytics/config.js.map +1 -0
  15. package/dist/analytics/index.d.ts +8 -0
  16. package/dist/analytics/index.d.ts.map +1 -0
  17. package/dist/analytics/index.js +7 -0
  18. package/dist/analytics/index.js.map +1 -0
  19. package/dist/analytics/middleware.d.ts +33 -0
  20. package/dist/analytics/middleware.d.ts.map +1 -0
  21. package/dist/analytics/middleware.js +99 -0
  22. package/dist/analytics/middleware.js.map +1 -0
  23. package/dist/analytics/transport.d.ts +11 -0
  24. package/dist/analytics/transport.d.ts.map +1 -0
  25. package/dist/analytics/transport.js +92 -0
  26. package/dist/analytics/transport.js.map +1 -0
  27. package/dist/analytics/types.d.ts +74 -0
  28. package/dist/analytics/types.d.ts.map +1 -0
  29. package/dist/analytics/types.js +6 -0
  30. package/dist/analytics/types.js.map +1 -0
  31. package/dist/config/api.d.ts +30 -0
  32. package/dist/config/api.d.ts.map +1 -0
  33. package/dist/config/api.js +32 -0
  34. package/dist/config/api.js.map +1 -0
  35. package/dist/config/cache.d.ts +31 -0
  36. package/dist/config/cache.d.ts.map +1 -0
  37. package/dist/config/cache.js +108 -0
  38. package/dist/config/cache.js.map +1 -0
  39. package/dist/config/displayThresholds.d.ts +83 -0
  40. package/dist/config/displayThresholds.d.ts.map +1 -0
  41. package/dist/config/displayThresholds.js +83 -0
  42. package/dist/config/displayThresholds.js.map +1 -0
  43. package/dist/config/tools.d.ts +44 -0
  44. package/dist/config/tools.d.ts.map +1 -0
  45. package/dist/config/tools.js +269 -0
  46. package/dist/config/tools.js.map +1 -0
  47. package/dist/errors/ApiError.d.ts +62 -0
  48. package/dist/errors/ApiError.d.ts.map +1 -0
  49. package/dist/errors/ApiError.js +171 -0
  50. package/dist/errors/ApiError.js.map +1 -0
  51. package/dist/handlers/airQualityHandler.d.ts +11 -0
  52. package/dist/handlers/airQualityHandler.d.ts.map +1 -0
  53. package/dist/handlers/airQualityHandler.js +154 -0
  54. package/dist/handlers/airQualityHandler.js.map +1 -0
  55. package/dist/handlers/alertsHandler.d.ts +11 -0
  56. package/dist/handlers/alertsHandler.d.ts.map +1 -0
  57. package/dist/handlers/alertsHandler.js +98 -0
  58. package/dist/handlers/alertsHandler.js.map +1 -0
  59. package/dist/handlers/currentConditionsHandler.d.ts +13 -0
  60. package/dist/handlers/currentConditionsHandler.d.ts.map +1 -0
  61. package/dist/handlers/currentConditionsHandler.js +296 -0
  62. package/dist/handlers/currentConditionsHandler.js.map +1 -0
  63. package/dist/handlers/forecastHandler.d.ts +16 -0
  64. package/dist/handlers/forecastHandler.d.ts.map +1 -0
  65. package/dist/handlers/forecastHandler.js +454 -0
  66. package/dist/handlers/forecastHandler.js.map +1 -0
  67. package/dist/handlers/historicalWeatherHandler.d.ts +12 -0
  68. package/dist/handlers/historicalWeatherHandler.d.ts.map +1 -0
  69. package/dist/handlers/historicalWeatherHandler.js +188 -0
  70. package/dist/handlers/historicalWeatherHandler.js.map +1 -0
  71. package/dist/handlers/lightningHandler.d.ts +14 -0
  72. package/dist/handlers/lightningHandler.d.ts.map +1 -0
  73. package/dist/handlers/lightningHandler.js +258 -0
  74. package/dist/handlers/lightningHandler.js.map +1 -0
  75. package/dist/handlers/locationHandler.d.ts +12 -0
  76. package/dist/handlers/locationHandler.d.ts.map +1 -0
  77. package/dist/handlers/locationHandler.js +149 -0
  78. package/dist/handlers/locationHandler.js.map +1 -0
  79. package/dist/handlers/marineConditionsHandler.d.ts +13 -0
  80. package/dist/handlers/marineConditionsHandler.d.ts.map +1 -0
  81. package/dist/handlers/marineConditionsHandler.js +270 -0
  82. package/dist/handlers/marineConditionsHandler.js.map +1 -0
  83. package/dist/handlers/riverConditionsHandler.d.ts +11 -0
  84. package/dist/handlers/riverConditionsHandler.d.ts.map +1 -0
  85. package/dist/handlers/riverConditionsHandler.js +176 -0
  86. package/dist/handlers/riverConditionsHandler.js.map +1 -0
  87. package/dist/handlers/savedLocationsHandler.d.ts +50 -0
  88. package/dist/handlers/savedLocationsHandler.d.ts.map +1 -0
  89. package/dist/handlers/savedLocationsHandler.js +397 -0
  90. package/dist/handlers/savedLocationsHandler.js.map +1 -0
  91. package/dist/handlers/statusHandler.d.ts +12 -0
  92. package/dist/handlers/statusHandler.d.ts.map +1 -0
  93. package/dist/handlers/statusHandler.js +115 -0
  94. package/dist/handlers/statusHandler.js.map +1 -0
  95. package/dist/handlers/weatherImageryHandler.d.ts +14 -0
  96. package/dist/handlers/weatherImageryHandler.d.ts.map +1 -0
  97. package/dist/handlers/weatherImageryHandler.js +143 -0
  98. package/dist/handlers/weatherImageryHandler.js.map +1 -0
  99. package/dist/handlers/wildfireHandler.d.ts +11 -0
  100. package/dist/handlers/wildfireHandler.d.ts.map +1 -0
  101. package/dist/handlers/wildfireHandler.js +186 -0
  102. package/dist/handlers/wildfireHandler.js.map +1 -0
  103. package/dist/index.d.ts +7 -0
  104. package/dist/index.d.ts.map +1 -0
  105. package/dist/index.js +735 -0
  106. package/dist/index.js.map +1 -0
  107. package/dist/services/blitzortung.d.ts +67 -0
  108. package/dist/services/blitzortung.d.ts.map +1 -0
  109. package/dist/services/blitzortung.js +475 -0
  110. package/dist/services/blitzortung.js.map +1 -0
  111. package/dist/services/geocoding.d.ts +57 -0
  112. package/dist/services/geocoding.d.ts.map +1 -0
  113. package/dist/services/geocoding.js +393 -0
  114. package/dist/services/geocoding.js.map +1 -0
  115. package/dist/services/locationStore.d.ts +62 -0
  116. package/dist/services/locationStore.d.ts.map +1 -0
  117. package/dist/services/locationStore.js +201 -0
  118. package/dist/services/locationStore.js.map +1 -0
  119. package/dist/services/ncei.d.ts +61 -0
  120. package/dist/services/ncei.d.ts.map +1 -0
  121. package/dist/services/ncei.js +126 -0
  122. package/dist/services/ncei.js.map +1 -0
  123. package/dist/services/nifc.d.ts +44 -0
  124. package/dist/services/nifc.d.ts.map +1 -0
  125. package/dist/services/nifc.js +159 -0
  126. package/dist/services/nifc.js.map +1 -0
  127. package/dist/services/noaa.d.ts +161 -0
  128. package/dist/services/noaa.d.ts.map +1 -0
  129. package/dist/services/noaa.js +681 -0
  130. package/dist/services/noaa.js.map +1 -0
  131. package/dist/services/nominatim.d.ts +62 -0
  132. package/dist/services/nominatim.d.ts.map +1 -0
  133. package/dist/services/nominatim.js +254 -0
  134. package/dist/services/nominatim.js.map +1 -0
  135. package/dist/services/openmeteo.d.ts +189 -0
  136. package/dist/services/openmeteo.d.ts.map +1 -0
  137. package/dist/services/openmeteo.js +936 -0
  138. package/dist/services/openmeteo.js.map +1 -0
  139. package/dist/services/rainviewer.d.ts +37 -0
  140. package/dist/services/rainviewer.d.ts.map +1 -0
  141. package/dist/services/rainviewer.js +115 -0
  142. package/dist/services/rainviewer.js.map +1 -0
  143. package/dist/types/imagery.d.ts +82 -0
  144. package/dist/types/imagery.d.ts.map +1 -0
  145. package/dist/types/imagery.js +6 -0
  146. package/dist/types/imagery.js.map +1 -0
  147. package/dist/types/lightning.d.ts +89 -0
  148. package/dist/types/lightning.d.ts.map +1 -0
  149. package/dist/types/lightning.js +6 -0
  150. package/dist/types/lightning.js.map +1 -0
  151. package/dist/types/noaa.d.ts +535 -0
  152. package/dist/types/noaa.d.ts.map +1 -0
  153. package/dist/types/noaa.js +5 -0
  154. package/dist/types/noaa.js.map +1 -0
  155. package/dist/types/nominatim.d.ts +72 -0
  156. package/dist/types/nominatim.d.ts.map +1 -0
  157. package/dist/types/nominatim.js +6 -0
  158. package/dist/types/nominatim.js.map +1 -0
  159. package/dist/types/openmeteo.d.ts +583 -0
  160. package/dist/types/openmeteo.d.ts.map +1 -0
  161. package/dist/types/openmeteo.js +6 -0
  162. package/dist/types/openmeteo.js.map +1 -0
  163. package/dist/types/savedLocations.d.ts +58 -0
  164. package/dist/types/savedLocations.d.ts.map +1 -0
  165. package/dist/types/savedLocations.js +5 -0
  166. package/dist/types/savedLocations.js.map +1 -0
  167. package/dist/types/wildfire.d.ts +83 -0
  168. package/dist/types/wildfire.d.ts.map +1 -0
  169. package/dist/types/wildfire.js +5 -0
  170. package/dist/types/wildfire.js.map +1 -0
  171. package/dist/utils/airQuality.d.ts +54 -0
  172. package/dist/utils/airQuality.d.ts.map +1 -0
  173. package/dist/utils/airQuality.js +251 -0
  174. package/dist/utils/airQuality.js.map +1 -0
  175. package/dist/utils/cache.d.ts +69 -0
  176. package/dist/utils/cache.d.ts.map +1 -0
  177. package/dist/utils/cache.js +164 -0
  178. package/dist/utils/cache.js.map +1 -0
  179. package/dist/utils/distance.d.ts +25 -0
  180. package/dist/utils/distance.d.ts.map +1 -0
  181. package/dist/utils/distance.js +40 -0
  182. package/dist/utils/distance.js.map +1 -0
  183. package/dist/utils/fireWeather.d.ts +76 -0
  184. package/dist/utils/fireWeather.d.ts.map +1 -0
  185. package/dist/utils/fireWeather.js +243 -0
  186. package/dist/utils/fireWeather.js.map +1 -0
  187. package/dist/utils/geography.d.ts +79 -0
  188. package/dist/utils/geography.d.ts.map +1 -0
  189. package/dist/utils/geography.js +266 -0
  190. package/dist/utils/geography.js.map +1 -0
  191. package/dist/utils/geohash.d.ts +62 -0
  192. package/dist/utils/geohash.d.ts.map +1 -0
  193. package/dist/utils/geohash.js +146 -0
  194. package/dist/utils/geohash.js.map +1 -0
  195. package/dist/utils/locationResolver.d.ts +34 -0
  196. package/dist/utils/locationResolver.d.ts.map +1 -0
  197. package/dist/utils/locationResolver.js +120 -0
  198. package/dist/utils/locationResolver.js.map +1 -0
  199. package/dist/utils/logger.d.ts +75 -0
  200. package/dist/utils/logger.d.ts.map +1 -0
  201. package/dist/utils/logger.js +153 -0
  202. package/dist/utils/logger.js.map +1 -0
  203. package/dist/utils/marine.d.ts +59 -0
  204. package/dist/utils/marine.d.ts.map +1 -0
  205. package/dist/utils/marine.js +215 -0
  206. package/dist/utils/marine.js.map +1 -0
  207. package/dist/utils/normals.d.ts +86 -0
  208. package/dist/utils/normals.d.ts.map +1 -0
  209. package/dist/utils/normals.js +223 -0
  210. package/dist/utils/normals.js.map +1 -0
  211. package/dist/utils/snow.d.ts +45 -0
  212. package/dist/utils/snow.d.ts.map +1 -0
  213. package/dist/utils/snow.js +144 -0
  214. package/dist/utils/snow.js.map +1 -0
  215. package/dist/utils/temperatureConversion.d.ts +12 -0
  216. package/dist/utils/temperatureConversion.d.ts.map +1 -0
  217. package/dist/utils/temperatureConversion.js +17 -0
  218. package/dist/utils/temperatureConversion.js.map +1 -0
  219. package/dist/utils/timezone.d.ts +56 -0
  220. package/dist/utils/timezone.d.ts.map +1 -0
  221. package/dist/utils/timezone.js +167 -0
  222. package/dist/utils/timezone.js.map +1 -0
  223. package/dist/utils/units.d.ts +69 -0
  224. package/dist/utils/units.d.ts.map +1 -0
  225. package/dist/utils/units.js +158 -0
  226. package/dist/utils/units.js.map +1 -0
  227. package/dist/utils/validation.d.ts +89 -0
  228. package/dist/utils/validation.d.ts.map +1 -0
  229. package/dist/utils/validation.js +177 -0
  230. package/dist/utils/validation.js.map +1 -0
  231. package/dist/utils/version.d.ts +15 -0
  232. package/dist/utils/version.d.ts.map +1 -0
  233. package/dist/utils/version.js +24 -0
  234. package/dist/utils/version.js.map +1 -0
  235. package/package.json +74 -0
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Type definitions for wildfire data from NIFC ArcGIS services
3
+ */
4
+ /**
5
+ * Fire perimeter feature attributes from NIFC WFIGS
6
+ */
7
+ export interface FirePerimeterAttributes {
8
+ poly_IncidentName: string;
9
+ attr_IncidentName?: string;
10
+ attr_IncidentTypeCategory?: string;
11
+ poly_GISAcres?: number;
12
+ attr_FinalAcres?: number;
13
+ attr_CalculatedAcres?: number;
14
+ attr_PercentContained?: number;
15
+ attr_ContainmentDateTime?: number;
16
+ poly_FeatureStatus?: string;
17
+ attr_FireDiscoveryDateTime?: number;
18
+ attr_InitialLatitude?: number;
19
+ attr_InitialLongitude?: number;
20
+ attr_POOState?: string;
21
+ attr_POOCounty?: string;
22
+ attr_POOCity?: string;
23
+ Shape__Area?: number;
24
+ Shape__Length?: number;
25
+ OBJECTID?: number;
26
+ }
27
+ /**
28
+ * ArcGIS polygon geometry
29
+ */
30
+ export interface ArcGISPolygonGeometry {
31
+ rings: number[][][];
32
+ spatialReference?: {
33
+ wkid: number;
34
+ latestWkid?: number;
35
+ };
36
+ }
37
+ /**
38
+ * Fire perimeter feature from NIFC ArcGIS REST API
39
+ */
40
+ export interface FirePerimeterFeature {
41
+ attributes: FirePerimeterAttributes;
42
+ geometry: ArcGISPolygonGeometry;
43
+ }
44
+ /**
45
+ * Response from NIFC ArcGIS query endpoint
46
+ */
47
+ export interface NIFCQueryResponse {
48
+ objectIdFieldName?: string;
49
+ globalIdFieldName?: string;
50
+ geometryType?: string;
51
+ spatialReference?: {
52
+ wkid: number;
53
+ latestWkid?: number;
54
+ };
55
+ fields?: Array<{
56
+ name: string;
57
+ type: string;
58
+ alias: string;
59
+ sqlType?: string;
60
+ domain?: unknown;
61
+ defaultValue?: unknown;
62
+ }>;
63
+ features: FirePerimeterFeature[];
64
+ exceededTransferLimit?: boolean;
65
+ }
66
+ /**
67
+ * Processed wildfire information for display
68
+ */
69
+ export interface WildfireInfo {
70
+ name: string;
71
+ distance: number;
72
+ acres: number;
73
+ containment: number;
74
+ discoveryDate: Date;
75
+ latitude?: number;
76
+ longitude?: number;
77
+ state?: string;
78
+ county?: string;
79
+ city?: string;
80
+ type: 'Wildfire' | 'Prescribed Fire' | 'Unknown';
81
+ status: string;
82
+ }
83
+ //# sourceMappingURL=wildfire.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wildfire.d.ts","sourceRoot":"","sources":["../../src/types/wildfire.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,WAAW,uBAAuB;IAEtC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,yBAAyB,CAAC,EAAE,MAAM,CAAC;IAGnC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAG9B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,0BAA0B,CAAC,EAAE,MAAM,CAAC;IAGpC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IAGtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IAGvB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IACpB,gBAAgB,CAAC,EAAE;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,uBAAuB,CAAC;IACpC,QAAQ,EAAE,qBAAqB,CAAC;CACjC;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,MAAM,CAAC,EAAE,KAAK,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,YAAY,CAAC,EAAE,OAAO,CAAC;KACxB,CAAC,CAAC;IACH,QAAQ,EAAE,oBAAoB,EAAE,CAAC;IACjC,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,UAAU,GAAG,iBAAiB,GAAG,SAAS,CAAC;IACjD,MAAM,EAAE,MAAM,CAAC;CAChB"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Type definitions for wildfire data from NIFC ArcGIS services
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=wildfire.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wildfire.js","sourceRoot":"","sources":["../../src/types/wildfire.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Air quality utility functions for AQI interpretation and health recommendations
3
+ */
4
+ /**
5
+ * US AQI health category information
6
+ */
7
+ export interface AQICategory {
8
+ level: string;
9
+ description: string;
10
+ healthImplications: string;
11
+ cautionaryStatement: string;
12
+ color: string;
13
+ }
14
+ /**
15
+ * UV index category information
16
+ */
17
+ export interface UVIndexCategory {
18
+ level: string;
19
+ description: string;
20
+ recommendation: string;
21
+ }
22
+ /**
23
+ * Get US AQI health category based on AQI value
24
+ * US EPA AQI scale: https://www.airnow.gov/aqi/aqi-basics/
25
+ */
26
+ export declare function getUSAQICategory(aqi: number): AQICategory;
27
+ /**
28
+ * Get European AQI health category based on EAQI value
29
+ * European Environment Agency EAQI scale: 0-20 (good) to 100+ (extremely poor)
30
+ */
31
+ export declare function getEuropeanAQICategory(aqi: number): AQICategory;
32
+ /**
33
+ * Get UV index category and recommendations
34
+ * WHO UV Index scale: https://www.who.int/news-room/questions-and-answers/item/radiation-the-ultraviolet-(uv)-index
35
+ */
36
+ export declare function getUVIndexCategory(uvIndex: number): UVIndexCategory;
37
+ /**
38
+ * Get pollutant description and health context
39
+ */
40
+ export declare function getPollutantInfo(pollutant: string): {
41
+ name: string;
42
+ description: string;
43
+ sources: string;
44
+ };
45
+ /**
46
+ * Format pollutant concentration with appropriate units and precision
47
+ */
48
+ export declare function formatPollutantConcentration(value: number | undefined, units: string | undefined): string;
49
+ /**
50
+ * Determine which AQI to prioritize based on location
51
+ * US locations should show US AQI, others show European AQI
52
+ */
53
+ export declare function shouldUseUSAQI(latitude: number, longitude: number): boolean;
54
+ //# sourceMappingURL=airQuality.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"airQuality.d.ts","sourceRoot":"","sources":["../../src/utils/airQuality.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAkDzD;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAkD/D;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,CAgCnE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CA4C1G;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAgBzG;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAgB3E"}
@@ -0,0 +1,251 @@
1
+ /**
2
+ * Air quality utility functions for AQI interpretation and health recommendations
3
+ */
4
+ /**
5
+ * Get US AQI health category based on AQI value
6
+ * US EPA AQI scale: https://www.airnow.gov/aqi/aqi-basics/
7
+ */
8
+ export function getUSAQICategory(aqi) {
9
+ if (aqi <= 50) {
10
+ return {
11
+ level: 'Good',
12
+ description: 'Air quality is satisfactory',
13
+ healthImplications: 'Air quality is considered satisfactory, and air pollution poses little or no risk.',
14
+ cautionaryStatement: 'None',
15
+ color: 'Green'
16
+ };
17
+ }
18
+ else if (aqi <= 100) {
19
+ return {
20
+ level: 'Moderate',
21
+ description: 'Air quality is acceptable',
22
+ healthImplications: 'Air quality is acceptable; however, unusually sensitive people may experience minor respiratory symptoms.',
23
+ cautionaryStatement: 'Unusually sensitive people should consider reducing prolonged outdoor exertion.',
24
+ color: 'Yellow'
25
+ };
26
+ }
27
+ else if (aqi <= 150) {
28
+ return {
29
+ level: 'Unhealthy for Sensitive Groups',
30
+ description: 'Sensitive groups may experience health effects',
31
+ healthImplications: 'Members of sensitive groups may experience health effects. The general public is not likely to be affected.',
32
+ cautionaryStatement: 'Children, elderly, and people with respiratory conditions should limit prolonged outdoor exertion.',
33
+ color: 'Orange'
34
+ };
35
+ }
36
+ else if (aqi <= 200) {
37
+ return {
38
+ level: 'Unhealthy',
39
+ description: 'Everyone may begin to experience health effects',
40
+ healthImplications: 'Everyone may begin to experience health effects; sensitive groups may experience more serious health effects.',
41
+ cautionaryStatement: 'Everyone should limit prolonged outdoor exertion, especially sensitive groups.',
42
+ color: 'Red'
43
+ };
44
+ }
45
+ else if (aqi <= 300) {
46
+ return {
47
+ level: 'Very Unhealthy',
48
+ description: 'Health alert: everyone may experience serious effects',
49
+ healthImplications: 'Health alert: everyone may experience more serious health effects.',
50
+ cautionaryStatement: 'Everyone should avoid prolonged outdoor exertion. Sensitive groups should remain indoors.',
51
+ color: 'Purple'
52
+ };
53
+ }
54
+ else {
55
+ return {
56
+ level: 'Hazardous',
57
+ description: 'Health warnings of emergency conditions',
58
+ healthImplications: 'Health warnings of emergency conditions. The entire population is more likely to be affected.',
59
+ cautionaryStatement: 'Everyone should avoid all outdoor exertion. Sensitive groups should remain indoors with air filtration.',
60
+ color: 'Maroon'
61
+ };
62
+ }
63
+ }
64
+ /**
65
+ * Get European AQI health category based on EAQI value
66
+ * European Environment Agency EAQI scale: 0-20 (good) to 100+ (extremely poor)
67
+ */
68
+ export function getEuropeanAQICategory(aqi) {
69
+ if (aqi <= 20) {
70
+ return {
71
+ level: 'Good',
72
+ description: 'Air quality is good',
73
+ healthImplications: 'The air quality is good. Enjoy your usual outdoor activities.',
74
+ cautionaryStatement: 'None',
75
+ color: 'Blue'
76
+ };
77
+ }
78
+ else if (aqi <= 40) {
79
+ return {
80
+ level: 'Fair',
81
+ description: 'Air quality is fair',
82
+ healthImplications: 'Enjoy your usual outdoor activities.',
83
+ cautionaryStatement: 'None',
84
+ color: 'Green'
85
+ };
86
+ }
87
+ else if (aqi <= 60) {
88
+ return {
89
+ level: 'Moderate',
90
+ description: 'Air quality is moderate',
91
+ healthImplications: 'Consider reducing intense outdoor activities if you experience symptoms.',
92
+ cautionaryStatement: 'Sensitive individuals should consider reducing intense activities.',
93
+ color: 'Yellow'
94
+ };
95
+ }
96
+ else if (aqi <= 80) {
97
+ return {
98
+ level: 'Poor',
99
+ description: 'Air quality is poor',
100
+ healthImplications: 'Consider reducing intense outdoor activities if you experience symptoms such as sore eyes, cough, or sore throat.',
101
+ cautionaryStatement: 'Sensitive groups should reduce outdoor activities.',
102
+ color: 'Orange'
103
+ };
104
+ }
105
+ else if (aqi <= 100) {
106
+ return {
107
+ level: 'Very Poor',
108
+ description: 'Air quality is very poor',
109
+ healthImplications: 'Consider reducing physical activities, particularly outdoors, especially if you experience symptoms.',
110
+ cautionaryStatement: 'Sensitive groups should avoid outdoor activities. General population should reduce outdoor activities.',
111
+ color: 'Red'
112
+ };
113
+ }
114
+ else {
115
+ return {
116
+ level: 'Extremely Poor',
117
+ description: 'Air quality is extremely poor',
118
+ healthImplications: 'Reduce physical activities outdoors. People with respiratory or heart conditions should remain indoors.',
119
+ cautionaryStatement: 'Everyone should avoid outdoor activities. Sensitive groups should remain indoors.',
120
+ color: 'Purple'
121
+ };
122
+ }
123
+ }
124
+ /**
125
+ * Get UV index category and recommendations
126
+ * WHO UV Index scale: https://www.who.int/news-room/questions-and-answers/item/radiation-the-ultraviolet-(uv)-index
127
+ */
128
+ export function getUVIndexCategory(uvIndex) {
129
+ if (uvIndex < 3) {
130
+ return {
131
+ level: 'Low',
132
+ description: 'Minimal protection required',
133
+ recommendation: 'No protection required. You can safely stay outside.'
134
+ };
135
+ }
136
+ else if (uvIndex < 6) {
137
+ return {
138
+ level: 'Moderate',
139
+ description: 'Protection recommended',
140
+ recommendation: 'Wear sunscreen, hat, and sunglasses. Seek shade during midday hours.'
141
+ };
142
+ }
143
+ else if (uvIndex < 8) {
144
+ return {
145
+ level: 'High',
146
+ description: 'Protection essential',
147
+ recommendation: 'Apply SPF 30+ sunscreen. Wear protective clothing, hat, and sunglasses. Reduce midday sun exposure.'
148
+ };
149
+ }
150
+ else if (uvIndex < 11) {
151
+ return {
152
+ level: 'Very High',
153
+ description: 'Extra protection required',
154
+ recommendation: 'Minimize sun exposure 10am-4pm. Apply SPF 30+ sunscreen every 2 hours. Wear protective clothing and sunglasses.'
155
+ };
156
+ }
157
+ else {
158
+ return {
159
+ level: 'Extreme',
160
+ description: 'Maximum protection required',
161
+ recommendation: 'Avoid sun exposure 10am-4pm. Stay in shade. Apply SPF 50+ sunscreen frequently. Wear full protective clothing.'
162
+ };
163
+ }
164
+ }
165
+ /**
166
+ * Get pollutant description and health context
167
+ */
168
+ export function getPollutantInfo(pollutant) {
169
+ const pollutants = {
170
+ pm2_5: {
171
+ name: 'PM2.5 (Fine Particulate Matter)',
172
+ description: 'Particles less than 2.5 micrometers. Can penetrate deep into lungs and bloodstream.',
173
+ sources: 'Vehicle emissions, industrial processes, wildfires, dust'
174
+ },
175
+ pm10: {
176
+ name: 'PM10 (Coarse Particulate Matter)',
177
+ description: 'Particles less than 10 micrometers. Can irritate airways and respiratory system.',
178
+ sources: 'Dust, pollen, mold, vehicle emissions, construction'
179
+ },
180
+ ozone: {
181
+ name: 'Ozone (O₃)',
182
+ description: 'Ground-level ozone can cause respiratory problems and aggravate asthma.',
183
+ sources: 'Formed by reactions between NOx and VOCs in sunlight'
184
+ },
185
+ nitrogen_dioxide: {
186
+ name: 'Nitrogen Dioxide (NO₂)',
187
+ description: 'Irritates airways and can worsen respiratory diseases.',
188
+ sources: 'Vehicle emissions, power plants, industrial facilities'
189
+ },
190
+ sulphur_dioxide: {
191
+ name: 'Sulfur Dioxide (SO₂)',
192
+ description: 'Can cause breathing difficulties and aggravate respiratory conditions.',
193
+ sources: 'Fossil fuel combustion, industrial processes, volcanoes'
194
+ },
195
+ carbon_monoxide: {
196
+ name: 'Carbon Monoxide (CO)',
197
+ description: 'Reduces oxygen delivery to body tissues. Dangerous in enclosed spaces.',
198
+ sources: 'Vehicle emissions, incomplete combustion, industrial processes'
199
+ },
200
+ ammonia: {
201
+ name: 'Ammonia (NH₃)',
202
+ description: 'Can irritate eyes, nose, throat, and respiratory system.',
203
+ sources: 'Agricultural activities, waste treatment, industrial processes'
204
+ }
205
+ };
206
+ return pollutants[pollutant] || {
207
+ name: pollutant.toUpperCase(),
208
+ description: 'Air pollutant',
209
+ sources: 'Various sources'
210
+ };
211
+ }
212
+ /**
213
+ * Format pollutant concentration with appropriate units and precision
214
+ */
215
+ export function formatPollutantConcentration(value, units) {
216
+ if (value === undefined || value === null) {
217
+ return 'N/A';
218
+ }
219
+ // Round to appropriate precision based on magnitude
220
+ let formatted;
221
+ if (value < 1) {
222
+ formatted = value.toFixed(2);
223
+ }
224
+ else if (value < 10) {
225
+ formatted = value.toFixed(1);
226
+ }
227
+ else {
228
+ formatted = Math.round(value).toString();
229
+ }
230
+ return units ? `${formatted} ${units}` : formatted;
231
+ }
232
+ /**
233
+ * Determine which AQI to prioritize based on location
234
+ * US locations should show US AQI, others show European AQI
235
+ */
236
+ export function shouldUseUSAQI(latitude, longitude) {
237
+ // Continental US, Alaska, Hawaii, and territories
238
+ // Continental US: roughly 24°N to 49°N, -125°W to -66°W
239
+ // Alaska: roughly 51°N to 71°N, -180°W to -130°W
240
+ // Hawaii: roughly 18°N to 28°N, -160°W to -154°W
241
+ // Puerto Rico: roughly 17.5°N to 18.5°N, -67.5°W to -65.5°W
242
+ // Other territories are less common but generally in Pacific/Caribbean
243
+ const isContiguousUS = latitude >= 24 && latitude <= 49 && longitude >= -125 && longitude <= -66;
244
+ const isAlaska = latitude >= 51 && latitude <= 71 && longitude >= -180 && longitude <= -130;
245
+ const isHawaii = latitude >= 18 && latitude <= 28 && longitude >= -160 && longitude <= -154;
246
+ const isPuertoRico = latitude >= 17.5 && latitude <= 18.5 && longitude >= -67.5 && longitude <= -65.5;
247
+ const isUSVirginIslands = latitude >= 17.5 && latitude <= 18.5 && longitude >= -65.5 && longitude <= -64.5;
248
+ const isGuam = latitude >= 13 && latitude <= 14 && longitude >= 144 && longitude <= 145;
249
+ return isContiguousUS || isAlaska || isHawaii || isPuertoRico || isUSVirginIslands || isGuam;
250
+ }
251
+ //# sourceMappingURL=airQuality.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"airQuality.js","sourceRoot":"","sources":["../../src/utils/airQuality.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * In-memory cache with TTL (Time To Live) and LRU (Least Recently Used) eviction
3
+ *
4
+ * Features:
5
+ * - Configurable TTL per cache entry
6
+ * - LRU eviction when max size is reached
7
+ * - Type-safe generic implementation
8
+ * - Cache statistics tracking (hits, misses, evictions)
9
+ */
10
+ export interface CacheStats {
11
+ hits: number;
12
+ misses: number;
13
+ evictions: number;
14
+ size: number;
15
+ maxSize: number;
16
+ }
17
+ export declare class Cache<T = any> {
18
+ private cache;
19
+ private stats;
20
+ private maxSize;
21
+ private cleanupInterval;
22
+ constructor(maxSize?: number, cleanupIntervalMs?: number);
23
+ /**
24
+ * Get a value from the cache
25
+ * @param key Cache key
26
+ * @returns Cached value or undefined if not found or expired
27
+ */
28
+ get(key: string): T | undefined;
29
+ /**
30
+ * Set a value in the cache with TTL
31
+ * @param key Cache key
32
+ * @param value Value to cache
33
+ * @param ttlMs Time to live in milliseconds (Infinity for no expiration)
34
+ */
35
+ set(key: string, value: T, ttlMs: number): void;
36
+ /**
37
+ * Evict the least recently used entry
38
+ */
39
+ private evictLRU;
40
+ /**
41
+ * Clear all entries from the cache
42
+ */
43
+ clear(): void;
44
+ /**
45
+ * Destroy the cache and clean up resources
46
+ * Call this when the cache is no longer needed to prevent memory leaks
47
+ */
48
+ destroy(): void;
49
+ /**
50
+ * Get cache statistics
51
+ */
52
+ getStats(): CacheStats;
53
+ /**
54
+ * Remove expired entries from cache
55
+ */
56
+ private cleanupExpired;
57
+ /**
58
+ * Generate a cache key from components
59
+ * @param components Parts to combine into a cache key (only primitives allowed)
60
+ * @returns Cache key string
61
+ * @throws {Error} If components contain objects or invalid types
62
+ */
63
+ static generateKey(...components: (string | number | boolean | null | undefined)[]): string;
64
+ /**
65
+ * Calculate hit rate percentage
66
+ */
67
+ getHitRate(): number;
68
+ }
69
+ //# sourceMappingURL=cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/utils/cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAQH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,KAAK,CAAC,CAAC,GAAG,GAAG;IACxB,OAAO,CAAC,KAAK,CAAyC;IACtD,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,eAAe,CAA+B;gBAE1C,OAAO,GAAE,MAAa,EAAE,iBAAiB,GAAE,MAAsB;IAgB7E;;;;OAIG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAuB/B;;;;;OAKG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAkB/C;;OAEG;IACH,OAAO,CAAC,QAAQ;IAiBhB;;OAEG;IACH,KAAK,IAAI,IAAI;IAKb;;;OAGG;IACH,OAAO,IAAI,IAAI;IAQf;;OAEG;IACH,QAAQ,IAAI,UAAU;IAUtB;;OAEG;IACH,OAAO,CAAC,cAAc;IActB;;;;;OAKG;IACH,MAAM,CAAC,WAAW,CAAC,GAAG,UAAU,EAAE,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,GAAG,MAAM;IAiB3F;;OAEG;IACH,UAAU,IAAI,MAAM;CAKrB"}
@@ -0,0 +1,164 @@
1
+ /**
2
+ * In-memory cache with TTL (Time To Live) and LRU (Least Recently Used) eviction
3
+ *
4
+ * Features:
5
+ * - Configurable TTL per cache entry
6
+ * - LRU eviction when max size is reached
7
+ * - Type-safe generic implementation
8
+ * - Cache statistics tracking (hits, misses, evictions)
9
+ */
10
+ export class Cache {
11
+ cache = new Map();
12
+ stats;
13
+ maxSize;
14
+ cleanupInterval = null;
15
+ constructor(maxSize = 1000, cleanupIntervalMs = 5 * 60 * 1000) {
16
+ this.maxSize = maxSize;
17
+ this.stats = {
18
+ hits: 0,
19
+ misses: 0,
20
+ evictions: 0,
21
+ size: 0,
22
+ maxSize: maxSize,
23
+ };
24
+ // Automatic cleanup of expired entries every 5 minutes by default
25
+ this.cleanupInterval = setInterval(() => {
26
+ this.cleanupExpired();
27
+ }, cleanupIntervalMs);
28
+ }
29
+ /**
30
+ * Get a value from the cache
31
+ * @param key Cache key
32
+ * @returns Cached value or undefined if not found or expired
33
+ */
34
+ get(key) {
35
+ const entry = this.cache.get(key);
36
+ if (!entry) {
37
+ this.stats.misses++;
38
+ return undefined;
39
+ }
40
+ // Check if expired
41
+ const now = Date.now();
42
+ if (entry.expiresAt < now) {
43
+ this.cache.delete(key);
44
+ this.stats.misses++;
45
+ this.stats.size = this.cache.size;
46
+ return undefined;
47
+ }
48
+ // Update last accessed time for LRU
49
+ entry.lastAccessedAt = now;
50
+ this.stats.hits++;
51
+ return entry.value;
52
+ }
53
+ /**
54
+ * Set a value in the cache with TTL
55
+ * @param key Cache key
56
+ * @param value Value to cache
57
+ * @param ttlMs Time to live in milliseconds (Infinity for no expiration)
58
+ */
59
+ set(key, value, ttlMs) {
60
+ const now = Date.now();
61
+ // If cache is at max size and key doesn't exist, evict LRU entry
62
+ if (this.cache.size >= this.maxSize && !this.cache.has(key)) {
63
+ this.evictLRU();
64
+ }
65
+ const entry = {
66
+ value,
67
+ expiresAt: ttlMs === Infinity ? Infinity : now + ttlMs,
68
+ lastAccessedAt: now,
69
+ };
70
+ this.cache.set(key, entry);
71
+ this.stats.size = this.cache.size;
72
+ }
73
+ /**
74
+ * Evict the least recently used entry
75
+ */
76
+ evictLRU() {
77
+ let oldestKey = null;
78
+ let oldestTime = Infinity;
79
+ for (const [key, entry] of this.cache.entries()) {
80
+ if (entry.lastAccessedAt < oldestTime) {
81
+ oldestTime = entry.lastAccessedAt;
82
+ oldestKey = key;
83
+ }
84
+ }
85
+ if (oldestKey) {
86
+ this.cache.delete(oldestKey);
87
+ this.stats.evictions++;
88
+ }
89
+ }
90
+ /**
91
+ * Clear all entries from the cache
92
+ */
93
+ clear() {
94
+ this.cache.clear();
95
+ this.stats.size = 0;
96
+ }
97
+ /**
98
+ * Destroy the cache and clean up resources
99
+ * Call this when the cache is no longer needed to prevent memory leaks
100
+ */
101
+ destroy() {
102
+ if (this.cleanupInterval) {
103
+ clearInterval(this.cleanupInterval);
104
+ this.cleanupInterval = null;
105
+ }
106
+ this.clear();
107
+ }
108
+ /**
109
+ * Get cache statistics
110
+ */
111
+ getStats() {
112
+ // Clean up expired entries before returning stats
113
+ this.cleanupExpired();
114
+ return {
115
+ ...this.stats,
116
+ size: this.cache.size,
117
+ };
118
+ }
119
+ /**
120
+ * Remove expired entries from cache
121
+ */
122
+ cleanupExpired() {
123
+ const now = Date.now();
124
+ const keysToDelete = [];
125
+ for (const [key, entry] of this.cache.entries()) {
126
+ if (entry.expiresAt < now) {
127
+ keysToDelete.push(key);
128
+ }
129
+ }
130
+ keysToDelete.forEach(key => this.cache.delete(key));
131
+ this.stats.size = this.cache.size;
132
+ }
133
+ /**
134
+ * Generate a cache key from components
135
+ * @param components Parts to combine into a cache key (only primitives allowed)
136
+ * @returns Cache key string
137
+ * @throws {Error} If components contain objects or invalid types
138
+ */
139
+ static generateKey(...components) {
140
+ // Validate and sanitize inputs to prevent cache poisoning
141
+ const sanitized = components.map((c, index) => {
142
+ if (c === null || c === undefined) {
143
+ return 'null';
144
+ }
145
+ if (typeof c === 'object') {
146
+ throw new Error(`Cache key generation error: Object not allowed at position ${index}. Only primitives (string, number, boolean) are supported.`);
147
+ }
148
+ // Convert to string safely
149
+ return String(c);
150
+ });
151
+ // Use colon separator instead of JSON.stringify to avoid circular reference issues
152
+ return sanitized.join(':');
153
+ }
154
+ /**
155
+ * Calculate hit rate percentage
156
+ */
157
+ getHitRate() {
158
+ const total = this.stats.hits + this.stats.misses;
159
+ if (total === 0)
160
+ return 0;
161
+ return (this.stats.hits / total) * 100;
162
+ }
163
+ }
164
+ //# sourceMappingURL=cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/utils/cache.ts"],"names":[],"mappings":"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"}