@atmosx/event-product-parser 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +17 -0
- package/README.md +269 -0
- package/dist/cjs/index.cjs +7554 -0
- package/dist/esm/index.mjs +7542 -0
- package/dist/index.d.mts +1024 -0
- package/dist/index.d.ts +1024 -0
- package/package.json +55 -0
- package/src/@dictionaries/awips.ts +358 -0
- package/src/@dictionaries/events.ts +168 -0
- package/src/@dictionaries/icao.ts +250 -0
- package/src/@dictionaries/signatures.ts +139 -0
- package/src/@parsers/@events/api.ts +146 -0
- package/src/@parsers/@events/cap.ts +123 -0
- package/src/@parsers/@events/text.ts +104 -0
- package/src/@parsers/@events/ugc.ts +107 -0
- package/src/@parsers/@events/vtec.ts +76 -0
- package/src/@parsers/events.ts +392 -0
- package/src/@parsers/hvtec.ts +46 -0
- package/src/@parsers/pvtec.ts +72 -0
- package/src/@parsers/stanza.ts +97 -0
- package/src/@parsers/text.ts +165 -0
- package/src/@parsers/ugc.ts +247 -0
- package/src/@submodules/database.ts +162 -0
- package/src/@submodules/eas.ts +490 -0
- package/src/@submodules/utils.ts +222 -0
- package/src/@submodules/xmpp.ts +142 -0
- package/src/bootstrap.ts +190 -0
- package/src/index.ts +218 -0
- package/src/types.ts +259 -0
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
/*
|
|
2
|
+
_ _ __ __
|
|
3
|
+
/\ | | | | (_) \ \ / /
|
|
4
|
+
/ \ | |_ _ __ ___ ___ ___ _ __ | |__ ___ _ __ _ ___ \ V /
|
|
5
|
+
/ /\ \| __| "_ ` _ \ / _ \/ __| "_ \| "_ \ / _ \ "__| |/ __| > <
|
|
6
|
+
/ ____ \ |_| | | | | | (_) \__ \ |_) | | | | __/ | | | (__ / . \
|
|
7
|
+
/_/ \_\__|_| |_| |_|\___/|___/ .__/|_| |_|\___|_| |_|\___/_/ \_\
|
|
8
|
+
| |
|
|
9
|
+
|_|
|
|
10
|
+
|
|
11
|
+
Written by: KiyoWx (k3yomi)
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
export const icaos: Record<string, string> = {
|
|
15
|
+
"KLCH": "Lake Charles, LA",
|
|
16
|
+
"TSTL": "St. Louis, MO",
|
|
17
|
+
"PABC": "Bethel, AK",
|
|
18
|
+
"TCMH": "Columbus, OH",
|
|
19
|
+
"KEPZ": "El Paso, TX",
|
|
20
|
+
"KCYS": "Cheyenne, WY",
|
|
21
|
+
"KJKL": "Jackson, KY",
|
|
22
|
+
"KPAH": "Paducah, KY",
|
|
23
|
+
"KEMX": "Tucson, AZ",
|
|
24
|
+
"KMHX": "Morehead City, NC",
|
|
25
|
+
"PAPD": "Fairbanks, AK",
|
|
26
|
+
"KDLH": "Duluth, MN",
|
|
27
|
+
"TADW": "Andrews Air Force Base, MD",
|
|
28
|
+
"KOKX": "Brookhaven, NY",
|
|
29
|
+
"KLZK": "Little Rock, AR",
|
|
30
|
+
"KHGX": "Houston, TX",
|
|
31
|
+
"TMSY": "New Orleans, LA",
|
|
32
|
+
"KDGX": "Jackson/Brandon, MS",
|
|
33
|
+
"KCTP": "Caribou, ME",
|
|
34
|
+
"KAMA": "Amarillo, TX",
|
|
35
|
+
"PGUA": "Andersen AFB, GU",
|
|
36
|
+
"KAPX": "Gaylord, MI",
|
|
37
|
+
"PAHG": "Kenai, AK",
|
|
38
|
+
"KLWX": "Sterling, VA",
|
|
39
|
+
"HWPA2": "Homer, AK",
|
|
40
|
+
"KGRK": "Fort Hood, TX",
|
|
41
|
+
"KAKQ": "Wakefield, VA",
|
|
42
|
+
"ROCO2": "Norman, OK",
|
|
43
|
+
"KCLX": "Charleston, SC",
|
|
44
|
+
"TPHX": "Phoenix, AZ",
|
|
45
|
+
"KNKX": "San Diego, CA",
|
|
46
|
+
"TDEN": "Denver, CO",
|
|
47
|
+
"TLAS": "Las Vegas, NV",
|
|
48
|
+
"KBUF": "Buffalo, NY",
|
|
49
|
+
"KTLX": "Norman, OK",
|
|
50
|
+
"KILX": "Lincoln, IL",
|
|
51
|
+
"KHDC": "Hammond, LA",
|
|
52
|
+
"KVWX": "Evansville, IN",
|
|
53
|
+
"TCLT": "Charlotte, NC",
|
|
54
|
+
"TEWR": "Newark, NJ",
|
|
55
|
+
"KFSD": "Sioux Falls, SD",
|
|
56
|
+
"KEAX": "Pleasant Hill, MO",
|
|
57
|
+
"KICX": "Cedar City, UT",
|
|
58
|
+
"KHTX": "Huntsville, AL",
|
|
59
|
+
"PACG": "Sitka, AK",
|
|
60
|
+
"KSOX": "Santa Ana Mountains, CA",
|
|
61
|
+
"TPBI": "West Palm Beach, FL",
|
|
62
|
+
"TSLC": "Salt Lake City, UT",
|
|
63
|
+
"KGLD": "Goodland, KS",
|
|
64
|
+
"TRDU": "Raleigh-Durham, NC",
|
|
65
|
+
"KATX": "Seattle, WA",
|
|
66
|
+
"TICH": "Wichita, KS",
|
|
67
|
+
"TSDF": "Louisville, KY",
|
|
68
|
+
"TBOS": "Boston, MA",
|
|
69
|
+
"TDCA": "Washington, DC",
|
|
70
|
+
"KUEX": "Grand Island, NE",
|
|
71
|
+
"TLKA2": "Talkeetna, AK",
|
|
72
|
+
"KBGM": "Binghamton, NY",
|
|
73
|
+
"TLVE": "Cleveland, OH",
|
|
74
|
+
"KCAE": "Columbia, SC",
|
|
75
|
+
"KDVN": "Quad Cities, IA",
|
|
76
|
+
"KABR": "Aberdeen, SD",
|
|
77
|
+
"KBYX": "Key West, FL",
|
|
78
|
+
"KMPX": "Minneapolis, MN",
|
|
79
|
+
"KCRP": "Corpus Christi, TX",
|
|
80
|
+
"KCBW": "Caribou, ME",
|
|
81
|
+
"KMRX": "Knoxville, TN",
|
|
82
|
+
"KSHV": "Shreveport, LA",
|
|
83
|
+
"KIWA": "Phoenix, AZ",
|
|
84
|
+
"KRGX": "Reno, NV",
|
|
85
|
+
"PHKM": "Kamuela, HI",
|
|
86
|
+
"KABX": "Albuquerque, NM",
|
|
87
|
+
"KBMX": "Birmingham, AL",
|
|
88
|
+
"TMDW": "Chicago Midway, IL",
|
|
89
|
+
"KVAX": "Moody AFB, GA",
|
|
90
|
+
"KHDX": "Holloman AFB, NM",
|
|
91
|
+
"KBRO": "Brownsville, TX",
|
|
92
|
+
"KTWX": "Topeka, KS",
|
|
93
|
+
"KRTX": "Portland, OR",
|
|
94
|
+
"KCXX": "Burlington, VT",
|
|
95
|
+
"KFCX": "Roanoke, VA",
|
|
96
|
+
"KFFC": "Atlanta, GA",
|
|
97
|
+
"KBOX": "Boston, MA",
|
|
98
|
+
"KTLH": "Tallahassee, FL",
|
|
99
|
+
"KPUX": "Pueblo, CO",
|
|
100
|
+
"KFDR": "Altus AFB, OK",
|
|
101
|
+
"KGJX": "Grand Junction, CO",
|
|
102
|
+
"KDTX": "Detroit, MI",
|
|
103
|
+
"PHWA": "Waimea, HI",
|
|
104
|
+
"KMQT": "Marquette, MI",
|
|
105
|
+
"KSJT": "San Angelo, TX",
|
|
106
|
+
"KUDX": "Rapid City, SD",
|
|
107
|
+
"TIAH": "Houston, TX",
|
|
108
|
+
"KSRX": "Fort Smith, AR",
|
|
109
|
+
"TJFK": "New York City, NY",
|
|
110
|
+
"KDDC": "Dodge City, KS",
|
|
111
|
+
"PAKC": "King Salmon, AK",
|
|
112
|
+
"PAIH": "Middleton Island, AK",
|
|
113
|
+
"RODN": "Kadena AB, JA",
|
|
114
|
+
"TBWI": "Baltimore/Washington, MD",
|
|
115
|
+
"KIWX": "Northern Indiana, IN",
|
|
116
|
+
"KFDX": "Cannon AFB, NM",
|
|
117
|
+
"TMIA": "Miami, FL",
|
|
118
|
+
"KICT": "Wichita, KS",
|
|
119
|
+
"TMKE": "Milwaukee, WI",
|
|
120
|
+
"TFLL": "Fort Lauderdale, FL",
|
|
121
|
+
"KARX": "La Crosse, WI",
|
|
122
|
+
"KLRX": "Elko, NV",
|
|
123
|
+
"KDAX": "Sacramento, CA",
|
|
124
|
+
"KGRB": "Green Bay, WI",
|
|
125
|
+
"KLGX": "Langley Hill, WA",
|
|
126
|
+
"KFTG": "Denver, CO",
|
|
127
|
+
"KMKX": "Milwaukee, WI",
|
|
128
|
+
"TTUL": "Tulsa, OK",
|
|
129
|
+
"TDFW": "Dallas/Fort Worth, TX",
|
|
130
|
+
"TTPA": "Tampa Bay, FL",
|
|
131
|
+
"TDAL": "Dallas Love Field, TX",
|
|
132
|
+
"KDFX": "Laughlin AFB, TX",
|
|
133
|
+
"KSFX": "Pocatello, ID",
|
|
134
|
+
"KMTX": "Salt Lake City, UT",
|
|
135
|
+
"PAEC": "Nome, AK",
|
|
136
|
+
"RKSG": "Camp Humphreys, KR",
|
|
137
|
+
"KOAX": "Omaha, NE",
|
|
138
|
+
"PHMO": "Molokai, HI",
|
|
139
|
+
"TDTW": "Detroit, MI",
|
|
140
|
+
"THOU": "Houston, TX",
|
|
141
|
+
"AWPA2": "Anchorage, AK",
|
|
142
|
+
"KTYX": "Fort Drum, NY",
|
|
143
|
+
"KCCX": "State College, PA",
|
|
144
|
+
"TMSP": "Minneapolis, MN",
|
|
145
|
+
"KMVX": "Grand Forks, ND",
|
|
146
|
+
"KBIS": "Bismarck, ND",
|
|
147
|
+
"KBBX": "Beale AFB, CA",
|
|
148
|
+
"KVBX": "Vandenberg AFB, CA",
|
|
149
|
+
"KPOE": "Fort Polk, LA",
|
|
150
|
+
"KMOB": "Mobile, AL",
|
|
151
|
+
"KJGX": "Robins AFB, GA",
|
|
152
|
+
"KMUX": "San Francisco, CA",
|
|
153
|
+
"TMCI": "Kansas City, MO",
|
|
154
|
+
"KLSX": "St. Louis, MO",
|
|
155
|
+
"KMAX": "Medford, OR",
|
|
156
|
+
"KRAX": "Raleigh/Durham, NC",
|
|
157
|
+
"KINX": "Tulsa, OK",
|
|
158
|
+
"RKJK": "Kunsan AB, KR",
|
|
159
|
+
"KSGF": "Springfield, MO",
|
|
160
|
+
"TDAY": "Dayton, OH",
|
|
161
|
+
"KDOX": "Dover AFB, DE",
|
|
162
|
+
"KGGW": "Glasgow, MT",
|
|
163
|
+
"KAMX": "Miami, FL",
|
|
164
|
+
"KENX": "Albany, NY",
|
|
165
|
+
"KTFX": "Great Falls, MT",
|
|
166
|
+
"KPBZ": "Pittsburgh, PA",
|
|
167
|
+
"KMAF": "Midland/Odessa, TX",
|
|
168
|
+
"KPDT": "Pendleton, OR",
|
|
169
|
+
"KLNX": "North Platte, NE",
|
|
170
|
+
"KEOX": "Fort Rucker, AL",
|
|
171
|
+
"KGSP": "Greer, SC",
|
|
172
|
+
"KHPX": "Fort Campbell, KY",
|
|
173
|
+
"KGRR": "Grand Rapids, MI",
|
|
174
|
+
"KLOT": "Chicago, IL",
|
|
175
|
+
"TPIT": "Pittsburgh, PA",
|
|
176
|
+
"KEYX": "Edwards AFB, CA",
|
|
177
|
+
"TIAD": "Dulles, VA",
|
|
178
|
+
"KFWS": "Dallas/Fort Worth, TX",
|
|
179
|
+
"KMLB": "Melbourne, FL",
|
|
180
|
+
"KMBX": "Minot AFB, ND",
|
|
181
|
+
"KDMX": "Des Moines, IA",
|
|
182
|
+
"KEVX": "Eglin AFB, FL",
|
|
183
|
+
"TBNA": "Nashville, TN",
|
|
184
|
+
"KDYX": "Dyess AFB, TX",
|
|
185
|
+
"TOKC": "Oklahoma City, OK",
|
|
186
|
+
"PHKI": "South Kauai, HI",
|
|
187
|
+
"TMCO": "Orlando, FL",
|
|
188
|
+
"KDIX": "Philadelphia, PA",
|
|
189
|
+
"TORD": "Chicago, IL",
|
|
190
|
+
"KYUX": "Yuma, AZ",
|
|
191
|
+
"KVNX": "Vance AFB, OK",
|
|
192
|
+
"TJUA": "San Juan, PR",
|
|
193
|
+
"TATL": "Atlanta, GA",
|
|
194
|
+
"KVTX": "Los Angeles, CA",
|
|
195
|
+
"KIND": "Indianapolis, IN",
|
|
196
|
+
"KCBX": "Boise, ID",
|
|
197
|
+
"KGYX": "Portland, ME",
|
|
198
|
+
"KMXX": "Maxwell AFB, AL",
|
|
199
|
+
"TSJU": "San Juan, PR",
|
|
200
|
+
"KHNX": "San Joaquin Valley, CA",
|
|
201
|
+
"KLVX": "Louisville, KY",
|
|
202
|
+
"KMSX": "Missoula, MT",
|
|
203
|
+
"KJAX": "Jacksonville, FL",
|
|
204
|
+
"KNQA": "Memphis, TN",
|
|
205
|
+
"KRIW": "Riverton/Lander, WY",
|
|
206
|
+
"TCVG": "Covington, KY",
|
|
207
|
+
"KBLX": "Billings, MT",
|
|
208
|
+
"TPHL": "Philadelphia, PA",
|
|
209
|
+
"KRLX": "Charleston, WV",
|
|
210
|
+
"TMEM": "Memphis, TN",
|
|
211
|
+
"KCLE": "Cleveland, OH",
|
|
212
|
+
"KBHX": "Eureka, CA",
|
|
213
|
+
"KLBB": "Lubbock, TX",
|
|
214
|
+
"KOTX": "Spokane, WA",
|
|
215
|
+
"KEWX": "Austin/San Antonio, TX",
|
|
216
|
+
"KGWX": "Columbus AFB, MS",
|
|
217
|
+
"KESX": "Las Vegas, NV",
|
|
218
|
+
"KTBW": "Tampa, FL",
|
|
219
|
+
"KOHX": "Nashville, TN",
|
|
220
|
+
"KLTX": "Wilmington, NC",
|
|
221
|
+
"KFSX": "Flagstaff, AZ",
|
|
222
|
+
"TIDS": "Indianapolis, IN",
|
|
223
|
+
"KILN": "Cincinnati, OH",
|
|
224
|
+
"PAFG": "Fairbanks, AK",
|
|
225
|
+
"KPQR": "Portland, OR",
|
|
226
|
+
"KILM": "Wilmington, NC",
|
|
227
|
+
"KEKA": "Eureka, CA",
|
|
228
|
+
"KCHS": "Charleston, SC",
|
|
229
|
+
"KPHI": "Philadelphia/Mt. Holly, NJ",
|
|
230
|
+
"KUNR": "Rapid City, SD",
|
|
231
|
+
"KMFL": "Miami, FL",
|
|
232
|
+
"TJSJ": "San Juan, PR",
|
|
233
|
+
"KFGF": "Grand Forks, ND",
|
|
234
|
+
"KSEW": "Seattle, WA",
|
|
235
|
+
"PAFC": "Anchorage, AK",
|
|
236
|
+
"KLMK": "Louisville, KY",
|
|
237
|
+
"PHFO": "Honolulu, HI",
|
|
238
|
+
"KLIX": "New Orleans/Baton Rouge, LA",
|
|
239
|
+
"KBOI": "Boise, ID",
|
|
240
|
+
"KPIH": "Pocatello, ID",
|
|
241
|
+
"KMTR": "San Francisco/Monterey, CA",
|
|
242
|
+
"KGJT": "Grand Junction, CO",
|
|
243
|
+
"PAAQ": "Anchorage, AK",
|
|
244
|
+
"KABQ": "Albuquerque, NM",
|
|
245
|
+
"KTAE": "Tallahassee, FL",
|
|
246
|
+
"KCAR": "Caribou, ME",
|
|
247
|
+
"KMFR": "Medford, OR",
|
|
248
|
+
"PGUM": "Guam, GU",
|
|
249
|
+
"PAJK": "Juneau, AK"
|
|
250
|
+
};
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/*
|
|
2
|
+
_ _ __ __
|
|
3
|
+
/\ | | | | (_) \ \ / /
|
|
4
|
+
/ \ | |_ _ __ ___ ___ ___ _ __ | |__ ___ _ __ _ ___ \ V /
|
|
5
|
+
/ /\ \| __| "_ ` _ \ / _ \/ __| "_ \| "_ \ / _ \ "__| |/ __| > <
|
|
6
|
+
/ ____ \ |_| | | | | | (_) \__ \ |_) | | | | __/ | | | (__ / . \
|
|
7
|
+
/_/ \_\__|_| |_| |_|\___/|___/ .__/|_| |_|\___|_| |_|\___/_/ \_\
|
|
8
|
+
| |
|
|
9
|
+
|_|
|
|
10
|
+
|
|
11
|
+
Written by: KiyoWx (k3yomi)
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
export const tags: Record<string, string> = {
|
|
15
|
+
"FROSTBITE AND HYPOTHERMIA ARE LIKELY": "Frostbite and Hypothermia Likely",
|
|
16
|
+
"LICKELY BECOME SLICK AND HAZARDOUS": "Slick and Hazardous Roads",
|
|
17
|
+
"SLIPPERY ROAD CONDITIONS": "Slippery Roads",
|
|
18
|
+
"BLOWING SNOW WHICH COULD REDUCE VISIBILITY": "Blowing Snow Reducing Visibility",
|
|
19
|
+
"TRAVEL COULD BE VERY DIFFICULT": "Difficult Travel Conditions",
|
|
20
|
+
"DIFFICULT TRAVEL CONDITIONS": "Difficult Travel Conditions",
|
|
21
|
+
"EXPECT DISRUPTIONS": "Expect Disruptions to Travel",
|
|
22
|
+
"A LARGE AND EXTREMELY DANGEROUS TORNADO": "Large and Dangerous Tornado",
|
|
23
|
+
"THIS IS A PARTICULARLY DANGEROUS SITUATION": "Particularly Dangerous Situation",
|
|
24
|
+
"RADAR INDICATED ROTATION": "Radar Indicated Tornado",
|
|
25
|
+
"WEATHER SPOTTERS CONFIRMED TORNADO": "Confirmed by Storm Spotters",
|
|
26
|
+
"A SEVERE THUNDERSTORM CAPABLE OF PRODUCING A TORNADO": "Developing Tornado",
|
|
27
|
+
"LAW ENFORCEMENT CONFIRMED TORNADO": "Reported by Law Enforcement",
|
|
28
|
+
"A TORNADO IS ON THE GROUND": "Confirmed Tornado",
|
|
29
|
+
"WEATHER SPOTTERS REPORTED FUNNEL CLOUD": "Confirmed Funnel Cloud by Storm Spotters",
|
|
30
|
+
"PUBLIC CONFIRMED TORNADO": "Public reports of Tornado",
|
|
31
|
+
"RADAR CONFIRMED": "Radar Confirmed",
|
|
32
|
+
"TORNADO WAS REPORTED BRIEFLY ON THE GROUND": "Tornado no longer on ground",
|
|
33
|
+
"SPOTTERS INDICATE THAT A FUNNEL CLOUD CONTINUES WITH THIS STORM": "Funnel Cloud Continues",
|
|
34
|
+
"A TORNADO MAY DEVELOP AT ANY TIME": "Potentional still exists for Tornado to form",
|
|
35
|
+
"LIFE-THREATENING SITUATION": "Life Threating Situation",
|
|
36
|
+
"COMPLETE DESTRUCTION IS POSSIBLE": "Extremly Damaging Tornado",
|
|
37
|
+
"POTENTIALLY DEADLY TORNADO": "Deadly Tornado",
|
|
38
|
+
"RADAR INDICATED": "Radar Indicated",
|
|
39
|
+
"HAIL DAMAGE TO VEHICLES IS EXPECTED": "Damaging to Vehicles",
|
|
40
|
+
"EXPECT WIND DAMAGE": "Wind Damage",
|
|
41
|
+
"FREQUENT LIGHTNING": "Frequent Lightning",
|
|
42
|
+
"PEOPLE AND ANIMALS OUTDOORS WILL BE INJURED": "Capable of Injuring People and Animals",
|
|
43
|
+
"TRAINED WEATHER SPOTTERS": "Confirmed by Storm Spotters",
|
|
44
|
+
"SOURCE...PUBLIC": "Confirmed by Public",
|
|
45
|
+
"SMALL CRAFT COULD BE DAMAGED": "Potential Damage to Small Craft",
|
|
46
|
+
"A TORNADO WATCH REMAINS IN EFFECT": "Active Tornado Watch",
|
|
47
|
+
"TENNIS BALL SIZE HAIL": "Tennis Ball Size Hail",
|
|
48
|
+
"BASEBALL SIZE HAIL": "Baseball Size Hail",
|
|
49
|
+
"GOLF BALL SIZE HAIL": "Golf Ball Size Hail",
|
|
50
|
+
"QUARTER SIZE HAIL": "Quarter Size Hail",
|
|
51
|
+
"PING PONG BALL SIZE HAIL": "Ping Pong Ball Size Hail",
|
|
52
|
+
"NICKEL SIZE HAIL": "Nickel Size Hail",
|
|
53
|
+
"DOPPLER RADAR.": "Confirmed by Radar",
|
|
54
|
+
"DOPPLER RADAR AND AUTOMATED GAUGES.": "Confirmed by Radar and Gauges",
|
|
55
|
+
"FLASH FLOODING CAUSED BY THUNDERSTORMS.": "Caused by Thunderstorm",
|
|
56
|
+
"SOURCE...EMERGENCY MANAGEMENT.": "Confirmed by Emergency Management",
|
|
57
|
+
"FLASH FLOODING CAUSED BY HEAVY RAIN.": "Caused by heavy rain",
|
|
58
|
+
"SOURCE...LAW ENFORCEMENT REPORTED.": "Confirmed by Law Enforcement",
|
|
59
|
+
"MINOR FLOODING IS OCCURING": "Minor Flooding Occurring",
|
|
60
|
+
"VERY COLD TEMPERATURES CAN LEAD TO HYPOTHERMIA": "Hypothermia Risk",
|
|
61
|
+
"SENSITIVE VEGETATION AND POSSIBLY DAMAGE UNPROTECTED OUTDOOR": "Vegetation and Outdoor Plumbing Risk",
|
|
62
|
+
"RIP CURRENTS CAN SWEEP EVEN THE BEST SWIMMER": "Hazardous to All Swimmers",
|
|
63
|
+
"HYPOTHERMIA IF PRECAUTIONS ARE NOT TAKEN.": "Hypothermia Risk",
|
|
64
|
+
"FROSTBITE AND HYPOTHERMIA WILL OCCUR IF UNPROTECTED SKIN": "Frostbite and Hypothermia Risk on Unprotected Skin",
|
|
65
|
+
"TEMPERATURES COULD CAUSE RUPTURED WATER PIPES": "Risk of Ruptured Water Pipes",
|
|
66
|
+
"COULD RESULT IN HYPOTHERMIA OR FROSTBITE ON EXPOSED SKIN IF": "Hypothermia or Frostbite Risk on Exposed Skin",
|
|
67
|
+
"WINDS WILL STRENGTHEN": "Strengthening Winds",
|
|
68
|
+
"EXPECT ROADS TO RE-FREEZE": "Roads May Re-Freeze",
|
|
69
|
+
"SLICK AND ICY SPOTS ON ROADS": "Slick and Icy Roads",
|
|
70
|
+
"ICY PATCHES MAY BE MORE COMMON ON BRIDGES": "Icy Patches Likely on Bridges",
|
|
71
|
+
"SLICK SPOTS ON UNTREATED ROADS": "Slick Spots on Untreated Roads",
|
|
72
|
+
"TEMPERATURES ARE EXPECTED TO FALL BELOW FREEZING": "Temperatures Expected Below Freezing",
|
|
73
|
+
"HAZARDOUS ROADWAYS AND BLACK ICE": "Hazardous Roadways and Black Ice",
|
|
74
|
+
"SLOW DOWN AND ALLOW EXTRA TIME": "Slow Down and Allow Extra Time",
|
|
75
|
+
"SHOULD EXERCISE CAUTION": "Should Exercise Caution",
|
|
76
|
+
"LAKE EFFECT SNOW EXPECTED": "Lake Effect Snow Expected",
|
|
77
|
+
"MODERATE LAKE EFFECT SNOWFALL RATES AND BLOWING SNOW": "Moderate Lake Effect Snowfall and Blowing Snow",
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export const cancel_signatures: string[] = [
|
|
81
|
+
"subsided sufficiently for the advisory to be cancelled",
|
|
82
|
+
"has been cancelled",
|
|
83
|
+
"will be allowed to expire",
|
|
84
|
+
"has diminished",
|
|
85
|
+
"and no longer",
|
|
86
|
+
"has been replaced",
|
|
87
|
+
"The threat has ended",
|
|
88
|
+
"has weakened below severe"
|
|
89
|
+
]
|
|
90
|
+
|
|
91
|
+
export const message_signatures: { regex: RegExp, replacement: string }[] = [
|
|
92
|
+
{ regex: /\*/g, replacement: "" },
|
|
93
|
+
{ regex: /\.{3,}/g, replacement: "" },
|
|
94
|
+
{ regex: /\bUTC\b/g, replacement: 'Coordinated Universal Time' },
|
|
95
|
+
{ regex: /\bGMT\b/g, replacement: 'Greenwich Mean Time' },
|
|
96
|
+
{ regex: /\bEST\b(?!\w)/g, replacement: 'Eastern Standard Time' },
|
|
97
|
+
{ regex: /\bEDT\b(?!\w)/g, replacement: 'Eastern Daylight Time' },
|
|
98
|
+
{ regex: /\bCST\b(?!\w)/g, replacement: 'Central Standard Time' },
|
|
99
|
+
{ regex: /\bCDT\b(?!\w)/g, replacement: 'Central Daylight Time' },
|
|
100
|
+
{ regex: /\bMST\b(?!\w)/g, replacement: 'Mountain Standard Time' },
|
|
101
|
+
{ regex: /\bMDT\b(?!\w)/g, replacement: 'Mountain Daylight Time' },
|
|
102
|
+
{ regex: /\bPST\b(?!\w)/g, replacement: 'Pacific Standard Time' },
|
|
103
|
+
{ regex: /\bPDT\b(?!\w)/g, replacement: 'Pacific Daylight Time' },
|
|
104
|
+
{ regex: /\bAKST\b(?!\w)/g, replacement: 'Alaska Standard Time' },
|
|
105
|
+
{ regex: /\bAKDT\b(?!\w)/g, replacement: 'Alaska Daylight Time' },
|
|
106
|
+
{ regex: /\bHST\b(?!\w)/g, replacement: 'Hawaii Standard Time' },
|
|
107
|
+
{ regex: /\bHDT\b(?!\w)/g, replacement: 'Hawaii Daylight Time' },
|
|
108
|
+
{ regex: /\bmph\b(?!\w)/g, replacement: 'miles per hour' },
|
|
109
|
+
{ regex: /\bkm\/h\b(?!\w)/g, replacement: 'kilometers per hour' },
|
|
110
|
+
{ regex: /\bkmh\b(?!\w)/g, replacement: 'kilometers per hour' },
|
|
111
|
+
{ regex: /\bkt\b(?!\w)/g, replacement: 'knots' },
|
|
112
|
+
{ regex: /\bNE\b(?!\w)/g, replacement: 'northeast' },
|
|
113
|
+
{ regex: /\bNW\b(?!\w)/g, replacement: 'northwest' },
|
|
114
|
+
{ regex: /\bSE\b(?!\w)/g, replacement: 'southeast' },
|
|
115
|
+
{ regex: /\bSW\b(?!\w)/g, replacement: 'southwest' },
|
|
116
|
+
{ regex: /\bNM\b(?!\w)/g, replacement: 'nautical miles' },
|
|
117
|
+
{ regex: /\bdeg\b(?!\w)/g, replacement: 'degrees' },
|
|
118
|
+
{ regex: /\btstm\b(?!\w)/g, replacement: 'thunderstorm' },
|
|
119
|
+
{ regex: /\bmm\b(?!\w)/g, replacement: 'millimeters' },
|
|
120
|
+
{ regex: /\bcm\b(?!\w)/g, replacement: 'centimeters' },
|
|
121
|
+
{ regex: /\bin.\b(?!\w)/g, replacement: 'inches' },
|
|
122
|
+
{ regex: /\bft\b(?!\w)/g, replacement: 'feet' },
|
|
123
|
+
{ regex: /\bmi\b(?!\w)/g, replacement: 'miles' },
|
|
124
|
+
{ regex: /\bhr\b(?!\w)/g, replacement: 'hour' },
|
|
125
|
+
{ regex: /\bhourly\b(?!\w)/g, replacement: 'per hour' },
|
|
126
|
+
{ regex: /\bkg\b(?!\w)/g, replacement: 'kilograms' },
|
|
127
|
+
{ regex: /\bg\/kg\b(?!\w)/g, replacement: 'grams per kilogram' },
|
|
128
|
+
{ regex: /\bmb\b(?!\w)/g, replacement: 'millibars' },
|
|
129
|
+
{ regex: /\bhPa\b(?!\w)/g, replacement: 'hectopascals' },
|
|
130
|
+
{ regex: /\bPa\b(?!\w)/g, replacement: 'pascals' },
|
|
131
|
+
{ regex: /\bKPa\b(?!\w)/g, replacement: 'kilopascals' },
|
|
132
|
+
{ regex: /\bC\/hr\b(?!\w)/g, replacement: 'degrees Celsius per hour' },
|
|
133
|
+
{ regex: /\bF\/hr\b(?!\w)/g, replacement: 'degrees Fahrenheit per hour' },
|
|
134
|
+
{ regex: /\bC\/min\b(?!\w)/g, replacement: 'degrees Celsius per minute' },
|
|
135
|
+
{ regex: /\bF\/min\b(?!\w)/g, replacement: 'degrees Fahrenheit per minute' },
|
|
136
|
+
{ regex: /\bC\b(?!\w)/g, replacement: 'degrees Celsius' },
|
|
137
|
+
{ regex: /\bF\b(?!\w)/g, replacement: 'degrees Fahrenheit' },
|
|
138
|
+
];
|
|
139
|
+
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/*
|
|
2
|
+
_ _ __ __
|
|
3
|
+
/\ | | | | (_) \ \ / /
|
|
4
|
+
/ \ | |_ _ __ ___ ___ ___ _ __ | |__ ___ _ __ _ ___ \ V /
|
|
5
|
+
/ /\ \| __| "_ ` _ \ / _ \/ __| "_ \| "_ \ / _ \ "__| |/ __| > <
|
|
6
|
+
/ ____ \ |_| | | | | | (_) \__ \ |_) | | | | __/ | | | (__ / . \
|
|
7
|
+
/_/ \_\__|_| |_| |_|\___/|___/ .__/|_| |_|\___|_| |_|\___/_/ \_\
|
|
8
|
+
| |
|
|
9
|
+
|_|
|
|
10
|
+
|
|
11
|
+
Written by: KiyoWx (k3yomi)
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import * as types from '../../types';
|
|
15
|
+
import * as loader from '../../bootstrap';
|
|
16
|
+
import EventParser from '../events';
|
|
17
|
+
import TextParser from '../text';
|
|
18
|
+
|
|
19
|
+
export class APIAlerts {
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @function getTracking
|
|
23
|
+
* @description
|
|
24
|
+
* Generates a unique tracking identifier for a CAP alert based on extracted XML values.
|
|
25
|
+
* If VTEC information is available, it constructs the tracking ID from the VTEC components.
|
|
26
|
+
* Otherwise, it uses the WMO identifier along with TTAI and CCCC attributes.
|
|
27
|
+
*
|
|
28
|
+
* @private
|
|
29
|
+
* @static
|
|
30
|
+
* @param {Record<string, string>} extracted
|
|
31
|
+
* @returns {string}
|
|
32
|
+
*/
|
|
33
|
+
private static getTracking(extracted: Record<string, string>): string {
|
|
34
|
+
if (extracted.pVtec) {
|
|
35
|
+
const vtecValue = Array.isArray(extracted.pVtec)
|
|
36
|
+
? extracted.pVtec[0] : extracted.pVtec;
|
|
37
|
+
const splitPVTEC = vtecValue.split('.');
|
|
38
|
+
return `${splitPVTEC[2]}-${splitPVTEC[3]}-${splitPVTEC[4]}-${splitPVTEC[5]}`;
|
|
39
|
+
}
|
|
40
|
+
const wmoMatch = extracted.wmoidentifier?.match(/([A-Z]{4}\d{2})\s+([A-Z]{4})/);
|
|
41
|
+
const station = wmoMatch?.[2] ?? 'N/A';
|
|
42
|
+
if (extracted.featureId) {
|
|
43
|
+
const idMatch = extracted.featureId.match(/([a-f0-9]+)\.(\d+)\.(\d+)$/);
|
|
44
|
+
return `${station}-${idMatch?.[1] ?? 'N/A'}`;
|
|
45
|
+
}
|
|
46
|
+
const id = wmoMatch?.[1] ?? 'N/A';
|
|
47
|
+
return `${station}-${id}`;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* @function getICAO
|
|
52
|
+
* @description
|
|
53
|
+
* Extracts the sender's ICAO code and corresponding name from a VTEC string.
|
|
54
|
+
*
|
|
55
|
+
* @private
|
|
56
|
+
* @static
|
|
57
|
+
* @param {string} pVtec
|
|
58
|
+
* @returns {{ icao: any; name: any; }}
|
|
59
|
+
*/
|
|
60
|
+
private static getICAO(pVtec: string): { icao: any; name: any; } {
|
|
61
|
+
const icao = pVtec ? pVtec.split(`.`)[2] : null;
|
|
62
|
+
const name = loader.definitions.ICAO?.[icao] ?? null;
|
|
63
|
+
return { icao, name };
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* @function event
|
|
68
|
+
* @description
|
|
69
|
+
* Processes validated API alert messages, extracting relevant information and compiling it into structured event objects.
|
|
70
|
+
*
|
|
71
|
+
* @public
|
|
72
|
+
* @static
|
|
73
|
+
* @async
|
|
74
|
+
* @param {types.StanzaCompiled} validated
|
|
75
|
+
* @returns {*}
|
|
76
|
+
*/
|
|
77
|
+
public static async event(validated: types.StanzaCompiled): Promise<void> {
|
|
78
|
+
let processed = [] as unknown[];
|
|
79
|
+
const messages = Object.values(JSON.parse(validated.message).features) as types.EventCompiled[];
|
|
80
|
+
for (let feature of messages) {
|
|
81
|
+
const tick = performance.now();
|
|
82
|
+
const getPVTEC = feature?.properties?.parameters?.VTEC?.[0] ?? null;
|
|
83
|
+
const getWmo = feature?.properties?.parameters?.WMOidentifier?.[0] ?? null;
|
|
84
|
+
const getUgc = feature?.properties?.geocode?.UGC ?? null;
|
|
85
|
+
const getHeadline = feature?.properties?.parameters?.NWSheadline?.[0] ?? "";
|
|
86
|
+
const getDescription = `${getHeadline} ${feature?.properties?.description ?? ``}`
|
|
87
|
+
const getAWIP = feature?.properties?.parameters?.AWIPSidentifier?.[0] ?? null;
|
|
88
|
+
const getHeader = EventParser.getHeader({ ...{ getAwip: {prefix: getAWIP?.slice(0, -3) }},} as types.StanzaAttributes);
|
|
89
|
+
const getSource = TextParser.textProductToString(getDescription, `SOURCE...`, [`.`]) ?? null;
|
|
90
|
+
const getOffice = this.getICAO(getPVTEC ?? ``);
|
|
91
|
+
processed.push({
|
|
92
|
+
type: "Feature",
|
|
93
|
+
properties: {
|
|
94
|
+
locations: feature?.properties?.areaDesc ?? null,
|
|
95
|
+
event: feature?.properties?.event ?? null,
|
|
96
|
+
issued: feature?.properties?.sent ? new Date(feature?.properties?.sent).toISOString() : null,
|
|
97
|
+
expires: feature?.properties?.expires ? new Date(feature?.properties?.expires).toISOString() : null,
|
|
98
|
+
parent: feature?.properties?.event ?? null,
|
|
99
|
+
action_type: feature?.properties?.messageType ?? null,
|
|
100
|
+
description: feature?.properties?.description ?? null,
|
|
101
|
+
instruction: feature?.properties?.instruction ?? null,
|
|
102
|
+
sender_name: getOffice.name ?? null,
|
|
103
|
+
sender_icao: getOffice.icao ?? null,
|
|
104
|
+
attributes: validated.attributes,
|
|
105
|
+
geocode: {
|
|
106
|
+
UGC: feature?.properties?.geocode?.UGC ?? [],
|
|
107
|
+
generated: feature?.geometry?.coordinates.length > 0 ? Buffer.from(JSON.stringify([feature?.geometry?.coordinates[0]])).toString('base64') : null,
|
|
108
|
+
},
|
|
109
|
+
raw: {},
|
|
110
|
+
parameters: {
|
|
111
|
+
wmo: feature?.properties?.parameters?.WMOidentifier?.[0] ?? getWmo ?? null,
|
|
112
|
+
source: getSource,
|
|
113
|
+
max_hail_size: feature?.properties?.parameters?.maxHailSize ?? null,
|
|
114
|
+
max_wind_gust: feature?.properties?.parameters?.maxWindGust ?? null,
|
|
115
|
+
damage_threat: feature?.properties?.parameters?.thunderstormDamageThreat?.[0] ?? null,
|
|
116
|
+
tornado_detection: feature?.properties?.parameters?.tornadoDetection?.[0] ?? null,
|
|
117
|
+
flood_detection: feature?.properties?.parameters?.floodDetection?.[0] ?? null,
|
|
118
|
+
discussion_tornado_intensity: null,
|
|
119
|
+
discussion_wind_intensity: null,
|
|
120
|
+
discussion_hail_intensity: null,
|
|
121
|
+
},
|
|
122
|
+
details: {
|
|
123
|
+
performance: performance.now() - tick,
|
|
124
|
+
source: `api-parser`,
|
|
125
|
+
tracking: this.getTracking({
|
|
126
|
+
pVtec: getPVTEC,
|
|
127
|
+
wmoidentifier: getWmo,
|
|
128
|
+
featureId: feature?.id,
|
|
129
|
+
ugc: getUgc ? getUgc.join(`,`) : null
|
|
130
|
+
}),
|
|
131
|
+
header: getHeader,
|
|
132
|
+
pvtec: getPVTEC ?? null,
|
|
133
|
+
history: [{
|
|
134
|
+
description: feature?.properties?.description ?? null,
|
|
135
|
+
action: feature?.properties?.messageType ?? null,
|
|
136
|
+
time: feature?.properties?.sent ? new Date(feature?.properties?.sent).toISOString() : null
|
|
137
|
+
}],
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
})
|
|
141
|
+
}
|
|
142
|
+
EventParser.validateEvents(processed);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export default APIAlerts;
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/*
|
|
2
|
+
_ _ __ __
|
|
3
|
+
/\ | | | | (_) \ \ / /
|
|
4
|
+
/ \ | |_ _ __ ___ ___ ___ _ __ | |__ ___ _ __ _ ___ \ V /
|
|
5
|
+
/ /\ \| __| "_ ` _ \ / _ \/ __| "_ \| "_ \ / _ \ "__| |/ __| > <
|
|
6
|
+
/ ____ \ |_| | | | | | (_) \__ \ |_) | | | | __/ | | | (__ / . \
|
|
7
|
+
/_/ \_\__|_| |_| |_|\___/|___/ .__/|_| |_|\___|_| |_|\___/_/ \_\
|
|
8
|
+
| |
|
|
9
|
+
|_|
|
|
10
|
+
|
|
11
|
+
Written by: KiyoWx (k3yomi)
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import * as types from '../../types';
|
|
15
|
+
import * as loader from '../../bootstrap';
|
|
16
|
+
import EventParser from '../events';
|
|
17
|
+
import TextParser from '../text';
|
|
18
|
+
|
|
19
|
+
export class CapAlerts {
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @function getTracking
|
|
23
|
+
* @description
|
|
24
|
+
* Generates a unique tracking identifier for a CAP alert based on extracted XML values.
|
|
25
|
+
* If VTEC information is available, it constructs the tracking ID from the VTEC components.
|
|
26
|
+
* Otherwise, it uses the WMO identifier along with TTAI and CCCC attributes.
|
|
27
|
+
*
|
|
28
|
+
* @private
|
|
29
|
+
* @static
|
|
30
|
+
* @param {Record<string, string>} extracted
|
|
31
|
+
* @returns {string}
|
|
32
|
+
*/
|
|
33
|
+
private static getTracking(extracted: Record<string, string>, metadata: types.StanzaAttributes): string {
|
|
34
|
+
return extracted.vtec ? (() => {
|
|
35
|
+
const vtecValue = Array.isArray(extracted.vtec) ? extracted.vtec[0] : extracted.vtec;
|
|
36
|
+
const splitPVTEC = vtecValue.split('.');
|
|
37
|
+
return `${splitPVTEC[2]}-${splitPVTEC[3]}-${splitPVTEC[4]}-${splitPVTEC[5]}`;
|
|
38
|
+
})() : `${extracted.wmoidentifier.substring(extracted.wmoidentifier.length - 4)}-${metadata.attributes.ttaaii}-${metadata.attributes.id.slice(-4)}`;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @function event
|
|
43
|
+
* @description
|
|
44
|
+
* Processes validated CAP alert messages, extracting relevant information and compiling it into structured event objects.
|
|
45
|
+
*
|
|
46
|
+
* @public
|
|
47
|
+
* @static
|
|
48
|
+
* @async
|
|
49
|
+
* @param {types.StanzaCompiled} validated
|
|
50
|
+
* @returns {*}
|
|
51
|
+
*/
|
|
52
|
+
public static async event(validated: types.StanzaCompiled): Promise<void> {
|
|
53
|
+
let processed = [] as unknown[];
|
|
54
|
+
const messages = validated?.message?.split(/(?=\$\$)/g)?.map(msg => msg.trim())?.filter(msg => msg && msg !== "$$");
|
|
55
|
+
if (!messages || messages.length == 0) { return }
|
|
56
|
+
for (let i = 0; i < messages.length; i++) {
|
|
57
|
+
const tick = performance.now();
|
|
58
|
+
let message = messages[i]
|
|
59
|
+
const attributes = validated as types.StanzaAttributes;
|
|
60
|
+
message = message.substring(message.indexOf(`<?xml version="1.0"`), message.lastIndexOf(`>`) + 1);
|
|
61
|
+
const parser = new loader.packages.xml2js.Parser({ explicitArray: false, mergeAttrs: true, trim: true })
|
|
62
|
+
const parsed = await parser.parseStringPromise(message);
|
|
63
|
+
if (parsed == null || parsed.alert == null) continue;
|
|
64
|
+
const extracted = TextParser.getXmlValues(parsed, [
|
|
65
|
+
`vtec`, `wmoidentifier`, `ugc`, `areadesc`,
|
|
66
|
+
`expires`, `sent`, `msgtype`, `description`,
|
|
67
|
+
`event`, `sendername`, `tornadodetection`, `polygon`,
|
|
68
|
+
`maxHailSize`, `maxWindGust`, `thunderstormdamagethreat`,
|
|
69
|
+
`tornadodamagethreat`, `waterspoutdetection`, `flooddetection`,
|
|
70
|
+
]);
|
|
71
|
+
const getHeader = EventParser.getHeader({ ...validated.attributes,} as types.StanzaAttributes);
|
|
72
|
+
const getSource = TextParser.textProductToString(extracted.description, `SOURCE...`, [`.`]) ?? null;
|
|
73
|
+
processed.push({
|
|
74
|
+
type: "Feature",
|
|
75
|
+
properties: {
|
|
76
|
+
locations: extracted.areadesc ?? null,
|
|
77
|
+
event: extracted.event ?? null,
|
|
78
|
+
issued: extracted.sent ? new Date(extracted.sent).toISOString() : null,
|
|
79
|
+
expires: extracted.expires ? new Date(extracted.expires).toISOString() : null,
|
|
80
|
+
parent: extracted.event ?? null,
|
|
81
|
+
action_type: extracted.msgtype ?? null,
|
|
82
|
+
description: extracted.description ?? null,
|
|
83
|
+
instruction: null,
|
|
84
|
+
sender_name: extracted.sendername ?? null,
|
|
85
|
+
sender_icao: extracted.wmoidentifier ? extracted.wmoidentifier.substring(extracted.wmoidentifier.length - 4) : null,
|
|
86
|
+
attributes: attributes,
|
|
87
|
+
geocode: {
|
|
88
|
+
UGC: extracted.ugc ? (Array.isArray(extracted.ugc) ? extracted.ugc : [extracted.ugc]) : [],
|
|
89
|
+
generated: extracted?.polygon?.length > 0 ? Buffer.from(JSON.stringify([extracted.polygon.split(' ').map((coord: string) => {
|
|
90
|
+
const [lat, lon] = coord.split(',').map(Number);
|
|
91
|
+
return [lon, lat];
|
|
92
|
+
})])).toString('base64') : null,
|
|
93
|
+
},
|
|
94
|
+
raw: {attributes},
|
|
95
|
+
parameters: {
|
|
96
|
+
wmo: extracted.wmoidentifier ?? null,
|
|
97
|
+
source: getSource,
|
|
98
|
+
max_hail_size: extracted.maxHailSize ?? null,
|
|
99
|
+
max_wind_gust: extracted.maxWindGust ?? null,
|
|
100
|
+
damage_threat: extracted.thunderstormdamagethreat ?? null,
|
|
101
|
+
tornado_detection: extracted.tornadodetection ?? extracted.waterspoutdetection ?? null,
|
|
102
|
+
flood_detection: extracted.flooddetection ?? null,
|
|
103
|
+
discussion_tornado_intensity: null,
|
|
104
|
+
discussion_wind_intensity: null,
|
|
105
|
+
discussion_hail_intensity: null,
|
|
106
|
+
},
|
|
107
|
+
details: {
|
|
108
|
+
performance: performance.now() - tick,
|
|
109
|
+
source: `cap-parser`,
|
|
110
|
+
tracking: this.getTracking(extracted, attributes),
|
|
111
|
+
header: getHeader,
|
|
112
|
+
pvtec: extracted.vtec ?? null,
|
|
113
|
+
hvtec: null,
|
|
114
|
+
history: [{ description: extracted.description ?? null, issued: extracted.sent ? new Date(extracted.sent).toISOString() : null, type: extracted.msgtype ?? null }],
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
})
|
|
118
|
+
}
|
|
119
|
+
EventParser.validateEvents(processed);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export default CapAlerts;
|