atmosx-nwws-parser 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/LICENSE +17 -0
  2. package/README.md +6 -0
  3. package/dist/cjs/bootstrap.cjs +1009 -0
  4. package/dist/cjs/database.cjs +1114 -0
  5. package/dist/cjs/dictionaries/awips.cjs +379 -0
  6. package/dist/cjs/dictionaries/events.cjs +139 -0
  7. package/dist/cjs/dictionaries/icao.cjs +265 -0
  8. package/dist/cjs/dictionaries/offshore.cjs +40 -0
  9. package/dist/cjs/dictionaries/signatures.cjs +132 -0
  10. package/dist/cjs/eas.cjs +2857 -0
  11. package/dist/cjs/helper.cjs +3014 -0
  12. package/dist/cjs/parsers/events.cjs +2857 -0
  13. package/dist/cjs/parsers/stanza.cjs +1108 -0
  14. package/dist/cjs/parsers/text.cjs +1142 -0
  15. package/dist/cjs/parsers/types/api.cjs +2857 -0
  16. package/dist/cjs/parsers/types/cap.cjs +2857 -0
  17. package/dist/cjs/parsers/types/text.cjs +2857 -0
  18. package/dist/cjs/parsers/types/ugc.cjs +2857 -0
  19. package/dist/cjs/parsers/types/vtec.cjs +2857 -0
  20. package/dist/cjs/parsers/ugc.cjs +1139 -0
  21. package/dist/cjs/parsers/vtec.cjs +1060 -0
  22. package/dist/cjs/types.cjs +17 -0
  23. package/dist/cjs/utils.cjs +2857 -0
  24. package/dist/cjs/xmpp.cjs +2857 -0
  25. package/dist/esm/bootstrap.mjs +972 -0
  26. package/dist/esm/database.mjs +1079 -0
  27. package/dist/esm/dictionaries/awips.mjs +355 -0
  28. package/dist/esm/dictionaries/events.mjs +111 -0
  29. package/dist/esm/dictionaries/icao.mjs +241 -0
  30. package/dist/esm/dictionaries/offshore.mjs +16 -0
  31. package/dist/esm/dictionaries/signatures.mjs +106 -0
  32. package/dist/esm/eas.mjs +2824 -0
  33. package/dist/esm/helper.mjs +2974 -0
  34. package/dist/esm/parsers/events.mjs +2824 -0
  35. package/dist/esm/parsers/stanza.mjs +1072 -0
  36. package/dist/esm/parsers/text.mjs +1106 -0
  37. package/dist/esm/parsers/types/api.mjs +2824 -0
  38. package/dist/esm/parsers/types/cap.mjs +2824 -0
  39. package/dist/esm/parsers/types/text.mjs +2824 -0
  40. package/dist/esm/parsers/types/ugc.mjs +2824 -0
  41. package/dist/esm/parsers/types/vtec.mjs +2824 -0
  42. package/dist/esm/parsers/ugc.mjs +1104 -0
  43. package/dist/esm/parsers/vtec.mjs +1025 -0
  44. package/dist/esm/types.mjs +0 -0
  45. package/dist/esm/utils.mjs +2824 -0
  46. package/dist/esm/xmpp.mjs +2824 -0
  47. package/package.json +47 -0
  48. package/shapefiles/FireCounties.dbf +0 -0
  49. package/shapefiles/FireCounties.shp +0 -0
  50. package/shapefiles/FireZones.dbf +0 -0
  51. package/shapefiles/FireZones.shp +0 -0
  52. package/shapefiles/ForecastZones.dbf +0 -0
  53. package/shapefiles/ForecastZones.shp +0 -0
  54. package/shapefiles/Marine.dbf +0 -0
  55. package/shapefiles/Marine.shp +0 -0
  56. package/shapefiles/OffShoreZones.dbf +0 -0
  57. package/shapefiles/OffShoreZones.shp +0 -0
  58. package/shapefiles/USCounties.dbf +0 -0
  59. package/shapefiles/USCounties.shp +0 -0
  60. package/src/bootstrap.ts +171 -0
  61. package/src/database.ts +99 -0
  62. package/src/dictionaries/awips.ts +351 -0
  63. package/src/dictionaries/events.ts +109 -0
  64. package/src/dictionaries/icao.ts +237 -0
  65. package/src/dictionaries/offshore.ts +12 -0
  66. package/src/dictionaries/signatures.ts +103 -0
  67. package/src/eas.ts +428 -0
  68. package/src/helper.ts +167 -0
  69. package/src/parsers/events.ts +289 -0
  70. package/src/parsers/stanza.ts +103 -0
  71. package/src/parsers/text.ts +167 -0
  72. package/src/parsers/types/api.ts +94 -0
  73. package/src/parsers/types/cap.ts +89 -0
  74. package/src/parsers/types/text.ts +54 -0
  75. package/src/parsers/types/ugc.ts +85 -0
  76. package/src/parsers/types/vtec.ts +60 -0
  77. package/src/parsers/ugc.ts +148 -0
  78. package/src/parsers/vtec.ts +66 -0
  79. package/src/types.ts +187 -0
  80. package/src/utils.ts +216 -0
  81. package/src/xmpp.ts +123 -0
  82. package/test.js +1 -0
  83. package/tsconfig.json +14 -0
  84. package/tsup.config.ts +11 -0
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "atmosx-nwws-parser",
3
+ "version": "1.0.2",
4
+ "description": "NOAA Weather Wire Parser - Built for standalone and Project AtmosphericX Integration.",
5
+ "main": "dist/cjs/helper.cjs",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/K3YOMI/atmosx-nwws-parser.git",
9
+ "branch": "1.0.2"
10
+ },
11
+ "scripts": {
12
+ "start": "cd ./test && node ./index.js",
13
+ "build:tsup": "tsup && cd ./test && node ./index.js",
14
+ "publish": "tsup && npm publish --access public",
15
+ "publish-beta": "tsup && npm publish --tag beta --access public"
16
+ },
17
+ "keywords": [
18
+ "NWWS",
19
+ "NOAA Weather Wire Service",
20
+ "TypeScript",
21
+ "XMPP",
22
+ "Parser",
23
+ "JavaScript",
24
+ "CommonJS",
25
+ "ESM"
26
+ ],
27
+ "author": "k3yomi, StarflightWx",
28
+ "license": "MIT",
29
+ "bugs": {
30
+ "url": "https://github.com/K3YOMI/atmosx-nwws-parser/issues"
31
+ },
32
+ "homepage": "https://github.com/K3YOMI/atmosx-nwws-parser#readme",
33
+ "dependencies": {
34
+ "@xmpp/client": "^0.7.3",
35
+ "axios": "^1.12.2",
36
+ "better-sqlite3": "^11.10.0",
37
+ "node-cron": "^4.2.1",
38
+ "say": "^0.16.0",
39
+ "shapefile": "^0.6.6",
40
+ "typescript": "^5.9.2",
41
+ "xml2js": "^0.6.2"
42
+ },
43
+ "devDependencies": {
44
+ "@types/node": "^24.5.2",
45
+ "tsup": "^8.5.0"
46
+ }
47
+ }
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,171 @@
1
+ /*
2
+ _ _ __ __
3
+ /\ | | | | (_) \ \ / /
4
+ / \ | |_ _ __ ___ ___ ___ _ __ | |__ ___ _ __ _ ___ \ V /
5
+ / /\ \| __| '_ ` _ \ / _ \/ __| '_ \| '_ \ / _ \ '__| |/ __| > <
6
+ / ____ \ |_| | | | | | (_) \__ \ |_) | | | | __/ | | | (__ / . \
7
+ /_/ \_\__|_| |_| |_|\___/|___/ .__/|_| |_|\___|_| |_|\___/_/ \_\
8
+ | |
9
+ |_|
10
+
11
+ Written by: k3yomi@GitHub
12
+ */
13
+
14
+
15
+ import * as fs from 'fs';
16
+ import * as path from 'path';
17
+ import * as events from 'events';
18
+ import * as xmpp from '@xmpp/client';
19
+ import * as shapefile from 'shapefile';
20
+ import * as xml2js from 'xml2js';
21
+ import * as cron from 'node-cron';
22
+ import sqlite3 from 'better-sqlite3';
23
+ import axios from 'axios';
24
+ import crypto from 'crypto';
25
+ import os from 'os';
26
+ import say from 'say';
27
+
28
+
29
+ import * as dictEvents from './dictionaries/events';
30
+ import * as dictOffshore from './dictionaries/offshore';
31
+ import * as dictAwips from './dictionaries/awips';
32
+ import * as dictSignatures from './dictionaries/signatures';
33
+ import * as dictICAOs from './dictionaries/icao';
34
+
35
+
36
+ export const packages = {
37
+ fs,
38
+ path,
39
+ events,
40
+ xmpp,
41
+ shapefile,
42
+ xml2js,
43
+ sqlite3,
44
+ cron,
45
+ axios,
46
+ crypto,
47
+ os,
48
+ say
49
+ };
50
+
51
+ export const cache = {
52
+ isReady: true,
53
+ sigHalt: false,
54
+ isConnected: false,
55
+ attemptingReconnect: false,
56
+ totalReconnects: 0,
57
+ lastStanza: null,
58
+ session: null,
59
+ lastConnect: null,
60
+ db: null,
61
+ events: new events.EventEmitter(),
62
+ isProcessingAudioQueue: false,
63
+ audioQueue: []
64
+ };
65
+
66
+ export const settings = {
67
+ database: path.join(process.cwd(), 'shapefiles.db'),
68
+ isNWWS: true,
69
+ NoaaWeatherWireService: {
70
+ clientReconnections: {
71
+ canReconnect: true,
72
+ currentInterval: 60,
73
+ },
74
+ clientCredentials: {
75
+ username: null,
76
+ password: null,
77
+ nickname: "AtmosphericX Standalone Parser",
78
+ },
79
+ cache: {
80
+ read: false,
81
+ maxSizeMB: 5,
82
+ maxHistory: 5000,
83
+ directory: null,
84
+ },
85
+ alertPreferences: {
86
+ isCapOnly: false,
87
+ isShapefileUGC: false,
88
+ }
89
+ },
90
+ NationalWeatherService: {
91
+ checkInterval: 15,
92
+ endpoint: "https://api.weather.gov/alerts/active",
93
+ },
94
+ global: {
95
+ useParentEvents: true,
96
+ betterEventParsing: true,
97
+ alertFiltering: {
98
+ filteredEvents: [],
99
+ filteredICOAs: [],
100
+ ignoredICOAs: [`KWNS`],
101
+ ignoredEvents: [`Unknown`, `Test Message`],
102
+ ugcFilter: [],
103
+ stateFilter: [],
104
+ checkExpired: true,
105
+ },
106
+ easSettings: {
107
+ easAlerts: [],
108
+ easDirectory: null,
109
+ easIntroWav: null,
110
+ }
111
+ }
112
+ }
113
+
114
+
115
+ export const definitions = {
116
+ events: dictEvents.EVENTS,
117
+ actions: dictEvents.ACTIONS,
118
+ status: dictEvents.STATUS,
119
+ productTypes: dictEvents.TYPES,
120
+ correlations: dictEvents.STATUS_CORRELATIONS,
121
+ offshore: dictOffshore.OFFSHORE,
122
+ awips: dictAwips.AWIPS,
123
+ cancelSignatures: dictSignatures.CANCEL_SIGNATURES,
124
+ messageSignatures: dictSignatures.MESSAGE_SIGNATURES,
125
+ tags: dictSignatures.TAGS,
126
+ ICAO: dictICAOs.ICAOs,
127
+ enhancedEvents: [
128
+ {"Tornado Warning": {
129
+ "Tornado Emergency": { description: "tornado emergency", condition: (tornadoThreatTag: string) => tornadoThreatTag === 'OBSERVED'},
130
+ "PDS Tornado Warning": { description: "particularly dangerous situation", condition: (damageThreatTag: string) => damageThreatTag === 'CONSIDERABLE'},
131
+ "Confirmed Tornado Warning": { condition: (tornadoThreatTag: string) => tornadoThreatTag === 'OBSERVED'},
132
+ "Radar Indicated Tornado Warning": {condition: (tornadoThreatTag: string) => tornadoThreatTag !== 'OBSERVED'},
133
+ }},
134
+ {"Tornado Watch": {
135
+ "PDS Tornado Watch": { description: "particularly dangerous situation"}
136
+ }},
137
+ {"Flash Flood Warning": {
138
+ "Flash Flood Emergency": { description: "flash flood emergency", },
139
+ "Considerable Flash Flood Warning": { condition: (damageThreatTag: string) => damageThreatTag === 'CONSIDERABLE' },
140
+ }},
141
+ {"Severe Thunderstorm Warning": {
142
+ "EDS Severe Thunderstorm Warning": {description: "extremely dangerous situation"},
143
+ "Destructive Severe Thunderstorm Warning": {condition: (damageThreatTag: string) => damageThreatTag === 'DESTRUCTIVE'},
144
+ "Considerable Severe Thunderstorm Warning": {condition: (damageThreatTag: string) => damageThreatTag === 'CONSIDERABLE'},
145
+ }},
146
+ ],
147
+ expressions: {
148
+ vtec: `[OTEX].(NEW|CON|EXT|EXA|EXB|UPG|CAN|EXP|COR|ROU).[A-Z]{4}.[A-Z]{2}.[WAYSFON].[0-9]{4}.[0-9]{6}T[0-9]{4}Z-[0-9]{6}T[0-9]{4}Z`,
149
+ wmo: `[A-Z0-9]{6}\\s[A-Z]{4}\\s\\d{6}`,
150
+ ugc1: `(\\w{2}[CZ](\\d{3}((-|>)\\s?(\n\n)?))+)`,
151
+ ugc2: `(\\d{6}(-|>)\\s?(\n\n)?)`,
152
+ ugc3: `(\\d{6})(?=-|$)`,
153
+ dateline: `/\d{3,4}\s*(AM|PM)?\s*[A-Z]{2,4}\s+[A-Z]{3,}\s+[A-Z]{3,}\s+\d{1,2}\s+\d{4}`,
154
+ wmoID: `[A-Z0-9]{2}([A-Z]{3})`,
155
+ },
156
+ shapefiles: [
157
+ { id: `C`, file: `USCounties` },
158
+ { id: `Z`, file: `ForecastZones` },
159
+ { id: `Z`, file: `FireZones` },
160
+ { id: `Z`, file: `OffShoreZones` },
161
+ { id: `Z`, file: `FireCounties` },
162
+ { id: `Z`, file: `Marine` }
163
+ ],
164
+ messages: {
165
+ shapefile_creation: `[NOTICE] DO NOT CLOSE THIS PROJECT UNTIL THE SHAPEFILES ARE DONE COMPLETING!\n\t THIS COULD TAKE A WHILE DEPENDING ON THE SPEED OF YOUR STORAGE!!\n\t IF YOU CLOSE YOUR PROJECT, THE SHAPEFILES WILL NOT BE CREATED AND YOU WILL NEED TO DELETE ${settings.database} AND RESTART TO CREATE THEM AGAIN!`,
166
+ shapefile_creation_finished: `[NOTICE] SHAPEFILES HAVE BEEN SUCCESSFULLY CREATED AND THE DATABASE IS READY FOR USE!`,
167
+ not_ready: "[ERROR] You can NOT create another instance without shutting down the current one first, please make sure to call the stop() method first!",
168
+ invalid_nickname: "[WARNING] The nickname you provided is invalid, please provide a valid nickname to continue.",
169
+ eas_no_directory: "[WARNING] You have not set a directory for EAS audio files to be saved to, please set the 'easDirectory' setting in the global settings to enable EAS audio generation.",
170
+ }
171
+ };
@@ -0,0 +1,99 @@
1
+ /*
2
+ _ _ __ __
3
+ /\ | | | | (_) \ \ / /
4
+ / \ | |_ _ __ ___ ___ ___ _ __ | |__ ___ _ __ _ ___ \ V /
5
+ / /\ \| __| "_ ` _ \ / _ \/ __| "_ \| "_ \ / _ \ "__| |/ __| > <
6
+ / ____ \ |_| | | | | | (_) \__ \ |_) | | | | __/ | | | (__ / . \
7
+ /_/ \_\__|_| |_| |_|\___/|___/ .__/|_| |_|\___|_| |_|\___/_/ \_\
8
+ | |
9
+ |_|
10
+
11
+ Written by: KiyoWx (k3yomi)
12
+ */
13
+
14
+
15
+ import * as loader from './bootstrap';
16
+ import * as types from './types';
17
+
18
+
19
+ export class Database {
20
+
21
+ /**
22
+ * handleAlertCache stores a unique alert in the SQLite database and ensures the total number of alerts does not exceed 5000.
23
+ *
24
+ * @public
25
+ * @static
26
+ * @async
27
+ * @param {*} alert
28
+ * @returns {*}
29
+ */
30
+ public static async stanzaCacheImport(stanza: string) {
31
+ const settings = loader.settings as types.ClientSettings;
32
+ loader.cache.db.prepare(`INSERT OR IGNORE INTO stanzas (stanza) VALUES (?)`).run(stanza);
33
+ const count = loader.cache.db.prepare(`SELECT COUNT(*) as total FROM stanzas`).get() as { total: number };
34
+ if (count.total > settings.NoaaWeatherWireService.cache.maxHistory) {
35
+ loader.cache.db.prepare(`DELETE FROM stanzas WHERE rowid IN (SELECT rowid FROM stanzas ORDER BY rowid ASC LIMIT ?)`).run(count.total - settings.NoaaWeatherWireService.cache.maxHistory / 2);
36
+ }
37
+ }
38
+
39
+ /**
40
+ * loadDatabase initializes the SQLite database and imports shapefile data if the database or table does not exist.
41
+ *
42
+ * @public
43
+ * @static
44
+ * @async
45
+ * @returns {Promise<void>}
46
+ */
47
+ public static async loadDatabase(): Promise<void> {
48
+ const settings = loader.settings as types.ClientSettings;
49
+ try {
50
+ if (!loader.packages.fs.existsSync(settings.database)) { loader.packages.fs.writeFileSync(settings.database, ''); }
51
+ loader.cache.db = new loader.packages.sqlite3(settings.database);
52
+ const shapfileTable = loader.cache.db.prepare(`SELECT name FROM sqlite_master WHERE type='table' AND name='shapefiles'`).get();
53
+ const stanzaTable = loader.cache.db.prepare(`SELECT name FROM sqlite_master WHERE type='table' AND name='stanzas'`).get();
54
+ if (!stanzaTable) { loader.cache.db.prepare(`CREATE TABLE stanzas (id INTEGER PRIMARY KEY AUTOINCREMENT, stanza TEXT)`).run(); }
55
+ if (!shapfileTable) {
56
+ loader.cache.db.prepare(`CREATE TABLE shapefiles (id TEXT PRIMARY KEY, location TEXT, geometry TEXT)`).run();
57
+ console.log(loader.definitions.messages.shapefile_creation);
58
+ for (const shape of loader.definitions.shapefiles) {
59
+ const { id, file } = shape;
60
+ const filepath = loader.packages.path.join(__dirname, `../../shapefiles`, file);
61
+ const { features } = await loader.packages.shapefile.read(filepath, filepath);
62
+ console.log(`Importing ${features.length} entries from ${file}...`);
63
+ const insertStmt = loader.cache.db.prepare(`INSERT OR REPLACE INTO shapefiles (id, location, geometry)VALUES (?, ?, ?)`);
64
+ const insertTransaction = loader.cache.db.transaction((entries: any[]) => {
65
+ for (const feature of entries) {
66
+ const { properties, geometry } = feature;
67
+ let final: string, location: string;
68
+ switch (true) {
69
+ case !!properties.FIPS:
70
+ final = `${properties.STATE}${id}${properties.FIPS.substring(2)}`;
71
+ location = `${properties.COUNTYNAME}, ${properties.STATE}`;
72
+ break;
73
+ case !!properties.FULLSTAID:
74
+ final = `${properties.ST}${id}${properties.WFO}`;
75
+ location = `${properties.CITY}, ${properties.STATE}`;
76
+ break;
77
+ case !!properties.STATE:
78
+ final = `${properties.STATE}${id}${properties.ZONE}`;
79
+ location = `${properties.NAME}, ${properties.STATE}`;
80
+ break;
81
+ default:
82
+ final = properties.ID;
83
+ location = properties.NAME;
84
+ break;
85
+ }
86
+ insertStmt.run(final, location, JSON.stringify(geometry));
87
+ }
88
+ });
89
+ await insertTransaction(features);
90
+ }
91
+ console.log(loader.definitions.messages.shapefile_creation_finished);
92
+ }
93
+ } catch (error: any) {
94
+ loader.cache.events.emit('onError', { code: 'error-load-database', message: `Failed to load database: ${error.message}`});
95
+ }
96
+ }
97
+ }
98
+
99
+ export default Database;
@@ -0,0 +1,351 @@
1
+ export const AWIPS: Record<string, string> = {
2
+ ABV: `abv`,
3
+ ADA: `administrative-message`,
4
+ ADM: `administrative-message`,
5
+ ADR: `administrative-message`,
6
+ AHD: `area-hydrological-discussion`,
7
+ AHONT1: `high-density-observations-usaf-noaa`,
8
+ AHOPA1: `high-density-observations-usaf-noaa-west-pac`,
9
+ AHOPN1: `high-density-observations-usaf-noaa`,
10
+ AFD: `area-forecast-discussion`,
11
+ AQA: `air-quality-alert`,
12
+ AQI: `ground-level-ozone-forecast`,
13
+ AVA: `avalanche-watch`,
14
+ AVW: `avalanche-warning`,
15
+ AWU: `area-weather-update`,
16
+ AVG: `avalanche-weather-guidance`,
17
+ AWW: `airport-weather-warning`,
18
+ BLU: `blue-alert`,
19
+ CAE: `child-abduction-emergency`,
20
+ CDW: `civil-danger-warning`,
21
+ CEM: `civil-emergency-message`,
22
+ CFW: `coastal-hazard-message`,
23
+ CGR: `coastal-weather-observations`,
24
+ CLI: `daily-climate-report`,
25
+ CLM: `monthly-climate-report`,
26
+ CRF: `contingency-river-forecast`,
27
+ CWA: `center-weather-advisory`,
28
+ CWF: `coastal-waters-forecast`,
29
+ DGT: `drought-information`,
30
+ DSA: `tropical-disturbance-statement`,
31
+ DSW: `dust-storm-warning`,
32
+ EQI: `earthquake-information`,
33
+ EQR: `earthquake-report`,
34
+ EQW: `earthquake-warning`,
35
+ ESF: `hydrologic-outlook`,
36
+ EVI: `evacuation-immediate`,
37
+ EWW: `extreme-wind-warning`,
38
+ FFA: `flood-watch`,
39
+ FFG: `flash-flood-guidance`,
40
+ FFGMPD: `mesoscale-precipitation-discussion`,
41
+ FLS: `flood-advisory`,
42
+ FLW: `flood-warning`,
43
+ FFS: `flash-flood-statement`,
44
+ FFW: `flash-flood-warning`,
45
+ MWS: `marine-weather-statement`,
46
+ MWW: `marine-weather-warning`,
47
+ NMN: `network-message-notification`,
48
+ NOW: `short-term-forecast`,
49
+ NPW: `non-convective-advisory`,
50
+ NSH: `nearshore-marine-forecast`,
51
+ NUW: `nuclear-power-plant-warning`,
52
+ PMDAK: `alaska-discussion`,
53
+ PMDCA: `tropical-discussion`,
54
+ PMDEPD: `extended-forecast-discussion`,
55
+ PMDHI: `hawaii-discussion`,
56
+ PMDHMD: `model-diagnostic-discussion`,
57
+ PMDSA: `south-america-forecast-discussion`,
58
+ PMDSPD: `short-range-forecast-discussion`,
59
+ PNS: `public-information-statement`,
60
+ FRW: `fire-warning`,
61
+ FTM: `free-text-message`,
62
+ FWF: `fire-weather-planning-forecast`,
63
+ FWA: `fire-weather-administrative-message`,
64
+ FWS: `fire-weather-spot-forecast`,
65
+ GLF: `open-lake-forecast`,
66
+ HCM: `hydromet-coordination-message`,
67
+ HMT: `hmt`,
68
+ HMW: `hazardous-materials-warning`,
69
+ HPA: `high-pollution-advisory`,
70
+ HLS: `hurricane-local-statement`,
71
+ HMD: `rainfall-and-flood-outlook-product`,
72
+ HSF: `high-seas-forecast`,
73
+ HWO: `hazardous-weather-outlook`,
74
+ HYD: `supplementary-temp-and-precip`,
75
+ LAE: `local-area-emergency`,
76
+ LCO: `local-cooperative-observation`,
77
+ LEW: `law-enforcement-warning`,
78
+ LSR: `local-storm-report`,
79
+ ICE: `ice-outlook`,
80
+ MIS: `meteorological-impact-statement`,
81
+ OAV: `other-aviation-report`,
82
+ OEP: `taf-collaboration-product`,
83
+ OFF: `offshore-waters-forecast`,
84
+ OMR: `other-marine-reports`,
85
+ OSO: `weather-roundup`,
86
+ PFM: `point-forecast-matrices`,
87
+ PSH: `post-tropical-event-report`,
88
+ PWO: `public-severe-weather-outlook`,
89
+ QPFERD: `excessive-rainfall-discussion`,
90
+ QPFHSD: `heavy-snow-discussion`,
91
+ QPS: `quantitative-precipitation-forecast`,
92
+ REC: `recreational-forecast`,
93
+ REPNT0: `recco-observations-non-tropical-cyclone`,
94
+ REPNT1: `recco-observations-tropical-cyclone`,
95
+ REPNT2: `vortex-data-message`,
96
+ REPNTS: `supplementary-vortex-data-message`,
97
+ REPNT3: `dropsonde-observations`,
98
+ REPPN0: `recco-observations-non-tropical-cyclone`,
99
+ REPPN1: `recco-observations-tropical-cyclone`,
100
+ REPPN2: `vortex-data-message`,
101
+ REPPNS: `supplementary-vortex-data-message`,
102
+ REPPN3: `dropsonde-observations`,
103
+ REPPA0: `recco-observations-west-pac-non-tropical-cyclone`,
104
+ REPPA1: `recco-observations-west-pac-tropical-cyclone`,
105
+ REPPA2: `vortex-data-message-west-pac`,
106
+ REPPAS: `supplementary-vortex-data-message-west-pac`,
107
+ REPPA3: `dropsonde-observations-west-pac`,
108
+ REPRPD: `weather-reconnaissance-flights`,
109
+ RER: `record-event-report`,
110
+ RFD: `grassland-fire-danger`,
111
+ RFW: `red-flag-warning`,
112
+ RHW: `radiological-hazard-warning`,
113
+ RRM: `rainfall-storm-total`,
114
+ RTP: `regional-temperature-and-precipitation`,
115
+ RVA: `hydrologic-summary`,
116
+ RVD: `river-and-lake-summary`,
117
+ RVF: `river-forecast`,
118
+ RVS: `hydrologic-statement`,
119
+ RWR: `weather-roundup`,
120
+ RWS: `regional-weather-summary`,
121
+ SAB: `special-avalanche-bulletin`,
122
+ SCC: `storm-summary`,
123
+ SFT: `state-forecast-tabular-product`,
124
+ SIG: `convective-sigment`,
125
+ SMF: `smoke-management-weather-forecast`,
126
+ SMW: `special-marine-warning`,
127
+ SPS: `special-weather-statement`,
128
+ SPW: `shelter-in-place-warning`,
129
+ SQW: `snow-squall-warning`,
130
+ SRF: `surf-zone-forecast`,
131
+ STF: `tabular-state-forecast`,
132
+ STQ: `spot-forecast-request`,
133
+ SVR: `severe-thunderstorm-warning`,
134
+ SVS: `severe-weather-statement`,
135
+ SWOMCD: `mesoscale-convective-discussion`,
136
+ TAF: `terminal-aerodrome-forecast`,
137
+ TCD: `tropical-cyclone-discussion`,
138
+ TCE: `tropical-cyclone-position-estimate`,
139
+ TCM: `tropical-storm-forecast`,
140
+ TCU: `tropical-cyclone-update`,
141
+ TCV: `tropical-watch-warning-local-statement`,
142
+ TIB: `tsunami-information-statement`,
143
+ TID: `tide-data`,
144
+ TMA: `tsunami-message-acknowledgement`,
145
+ TOE: `telephone-outage-emergency`,
146
+ TOR: `tornado-warning`,
147
+ TWD: `tropical-weather-discussion`,
148
+ TWO: `tropical-weather-outlook`,
149
+ VAA: `volcanic-ash-advisory`,
150
+ VOW: `volcano-warning`,
151
+ WCN: `watch-county-notification`,
152
+ WRK: `work-product`,
153
+ WSV: `volcanic-ash-sigmet`,
154
+ WSW: `winter-weather-message`,
155
+ XTEUS: `wpc-contiguous-us-daily-max-min-temps`,
156
+ ZFP: `zone-forecast-package`,
157
+ RR1: `hydro-meteorological-data-report-pt1`,
158
+ RR2: `hydro-meteorological-data-report-pt2`,
159
+ RR3: `hydro-meteorological-data-report-pt3`,
160
+ RR4: `hydro-meteorological-data-report-pt4`,
161
+ RR5: `hydro-meteorological-data-report-pt5`,
162
+ RR6: `hydro-meteorological-data-report-pt6`,
163
+ RR7: `hydro-meteorological-data-report-pt7`,
164
+ RR8: `hydro-meteorological-data-report-pt8`,
165
+ RR9: `hydro-meteorological-data-report-pt9`,
166
+ SFP: `state-forecast-product`,
167
+ AFM: `area-forecast-matrices`,
168
+ AAG: `aag`,
169
+ ADV: `adv`,
170
+ AFP: `afp`,
171
+ AFW: `afw`,
172
+ AGO: `ago`,
173
+ AIR: `air`,
174
+ ALG: `alg`,
175
+ ALT: `alt`,
176
+ AVD: `avd`,
177
+ AWO: `awo`,
178
+ BOY: `boy`,
179
+ BRT: `brt`,
180
+ CF6: `cf6`,
181
+ CFP: `cfp`,
182
+ CLS: `cls`,
183
+ CMM: `cmm`,
184
+ COD: `cod`,
185
+ CRN: `crn`,
186
+ CUR: `cur`,
187
+ CWD: `cwd`,
188
+ CWS: `cws`,
189
+ DAY: `day`,
190
+ DDO: `ddo`,
191
+ DMO: `dmo`,
192
+ DSM: `dsm`,
193
+ ECD: `ecd`,
194
+ EFP: `efp`,
195
+ EOL: `eol`,
196
+ EOM: `eom`,
197
+ ESG: `esg`,
198
+ ESP: `esp`,
199
+ ESS: `ess`,
200
+ ETT: `ett`,
201
+ FA0: `fa0`,
202
+ FA7: `fa7`,
203
+ FA8: `fa8`,
204
+ FA9: `fa9`,
205
+ FD0: `fd0`,
206
+ FD1: `fd1`,
207
+ FD3: `fd3`,
208
+ FD5: `fd5`,
209
+ FD8: `fd8`,
210
+ FD9: `fd9`,
211
+ FDI: `fdi`,
212
+ FFH: `ffh`,
213
+ FFP: `ffp`,
214
+ FLR: `flr`,
215
+ FOP: `fop`,
216
+ FRH: `frh`,
217
+ FSH: `fsh`,
218
+ FTP: `ftp`,
219
+ FWD: `fwd`,
220
+ FWL: `fwl`,
221
+ FWM: `fwm`,
222
+ FWN: `fwn`,
223
+ FWO: `fwo`,
224
+ FZL: `fzl`,
225
+ GEN: `gen`,
226
+ GMT: `gmt`,
227
+ HD0: `hd0`,
228
+ HD2: `hd2`,
229
+ HD3: `hd3`,
230
+ HD4: `hd4`,
231
+ HD6: `hd6`,
232
+ HD8: `hd8`,
233
+ HML: `hml`,
234
+ HWR: `hwr`,
235
+ LAK: `lak`,
236
+ LEV: `lev`,
237
+ LLL: `lll`,
238
+ HP2: `hp2`,
239
+ HRR: `hrr`,
240
+ HYM: `hym`,
241
+ ICO: `ico`,
242
+ IDM: `idm`,
243
+ MAN: `man`,
244
+ MAP: `map`,
245
+ MAR: `mar`,
246
+ MAV: `mav`,
247
+ MCG: `mcg`,
248
+ MCX: `mcx`,
249
+ MET: `met`,
250
+ MEX: `mex`,
251
+ MFM: `mfm`,
252
+ MFP: `mfp`,
253
+ MHF: `mhf`,
254
+ MME: `mme`,
255
+ MMG: `mmg`,
256
+ MRP: `mrp`,
257
+ MSM: `msm`,
258
+ MTR: `mtr`,
259
+ MTT: `mtt`,
260
+ MVF: `mvf`,
261
+ NWR: `nwr`,
262
+ OFA: `ofa`,
263
+ OPU: `opu`,
264
+ OPW: `opw`,
265
+ OSB: `osb`,
266
+ PFW: `pfw`,
267
+ PLS: `pls`,
268
+ PMD: `pmd`,
269
+ POE: `poe`,
270
+ PRB: `prb`,
271
+ PTS: `pts`,
272
+ PWS: `pws`,
273
+ QPF: `qpf`,
274
+ QPG: `qpg`,
275
+ RBG: `rbg`,
276
+ REP: `rep`,
277
+ RFM: `rfm`,
278
+ RFR: `rfr`,
279
+ RRA: `rra`,
280
+ RRS: `rrs`,
281
+ RRY: `rry`,
282
+ RRZ: `rrz`,
283
+ RVC: `rvc`,
284
+ RVG: `rvg`,
285
+ RVK: `rvk`,
286
+ RVM: `rvm`,
287
+ RVO: `rvo`,
288
+ RVR: `rvr`,
289
+ RVU: `rvu`,
290
+ SAF: `saf`,
291
+ SAG: `sag`,
292
+ SAT: `sat`,
293
+ SAW: `saw`,
294
+ SCN: `scn`,
295
+ SCP: `scp`,
296
+ SCS: `scs`,
297
+ SCV: `scv`,
298
+ SEL: `sel`,
299
+ SGL: `sgl`,
300
+ SPE: `spe`,
301
+ SPN: `spn`,
302
+ SRG: `srg`,
303
+ SSM: `ssm`,
304
+ STA: `sta`,
305
+ SUM: `sum`,
306
+ SWE: `swe`,
307
+ SYN: `syn`,
308
+ TAP: `tap`,
309
+ TCA: `tca`,
310
+ TCP: `tcp`,
311
+ TCS: `tcs`,
312
+ TPT: `tpt`,
313
+ TST: `tst`,
314
+ TSU: `tsu`,
315
+ TUV: `tuv`,
316
+ TVL: `tvl`,
317
+ TWS: `tws`,
318
+ TXT: `txt`,
319
+ UVI: `uvi`,
320
+ VFT: `vft`,
321
+ WA0: `wa0`,
322
+ WA1: `wa1`,
323
+ WA2: `wa2`,
324
+ WA3: `wa3`,
325
+ WA4: `wa4`,
326
+ WA5: `wa5`,
327
+ WA6: `wa6`,
328
+ WA7: `wa7`,
329
+ WA8: `wa8`,
330
+ WA9: `wa9`,
331
+ WAR: `war`,
332
+ WAT: `wat`,
333
+ WCL: `wcl`,
334
+ WEE: `wee`,
335
+ WEK: `wek`,
336
+ WOU: `wou`,
337
+ WRM: `wrm`,
338
+ WS1: `ws1`,
339
+ WS2: `ws2`,
340
+ WS3: `ws3`,
341
+ WS4: `ws4`,
342
+ WS5: `ws5`,
343
+ WS6: `ws6`,
344
+ WSC: `wsc`,
345
+ WST: `wst`,
346
+ WTA: `wta`,
347
+ WWA: `wwa`,
348
+ WWP: `wwp`,
349
+ XF0: `xf0`,
350
+ XOB: `xob`,
351
+ };