@atmosx/event-product-parser 3.0.51 → 3.0.52

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 (139) hide show
  1. package/.vscode/settings.json +3 -3
  2. package/CODE_OF_CONDUCT.md +9 -9
  3. package/CONTRIBUTING.md +29 -29
  4. package/LICENSE +17 -17
  5. package/README.md +443 -444
  6. package/SECURITY.md +20 -20
  7. package/SUPPORTED_EVENTS.md +369 -368
  8. package/dist/cjs/index.cjs +161 -204
  9. package/dist/esm/index.mjs +160 -203
  10. package/package.json +52 -52
  11. package/src/@building/building.attachments.ts +82 -82
  12. package/src/@building/building.clean.ts +29 -29
  13. package/src/@building/building.create.ts +55 -55
  14. package/src/@building/building.enhance.ts +59 -59
  15. package/src/@building/building.geometry.ts +47 -47
  16. package/src/@building/building.headers.ts +36 -36
  17. package/src/@building/building.office.ts +42 -42
  18. package/src/@building/building.polygon.ts +69 -69
  19. package/src/@building/building.properties.ts +95 -95
  20. package/src/@building/building.signature.ts +60 -60
  21. package/src/@building/building.tags.ts +23 -23
  22. package/src/@building/building.tracking.ts +67 -67
  23. package/src/@building/building.validate.ts +152 -151
  24. package/src/@core/core.clearEvents.ts +30 -30
  25. package/src/@core/core.createListener.ts +23 -23
  26. package/src/@core/core.getEvents.ts +23 -23
  27. package/src/@core/core.getNodes.ts +23 -23
  28. package/src/@core/core.getRandomEvent.ts +23 -23
  29. package/src/@core/core.getVersion.ts +23 -23
  30. package/src/@core/core.manualEvent.ts +38 -0
  31. package/src/@core/core.query.ts +38 -38
  32. package/src/@core/core.setNode.ts +80 -80
  33. package/src/@core/core.start.ts +60 -60
  34. package/src/@core/core.stop.ts +31 -31
  35. package/src/@dictionaries/dictionaries.actions.ts +27 -27
  36. package/src/@dictionaries/dictionaries.awips.ts +363 -363
  37. package/src/@dictionaries/dictionaries.cancellation.ts +30 -30
  38. package/src/@dictionaries/dictionaries.causes.ts +35 -35
  39. package/src/@dictionaries/dictionaries.correlations.ts +42 -42
  40. package/src/@dictionaries/dictionaries.enhanced.ts +66 -109
  41. package/src/@dictionaries/dictionaries.events.ts +82 -82
  42. package/src/@dictionaries/dictionaries.expressions.ts +28 -28
  43. package/src/@dictionaries/dictionaries.global.ts +24 -0
  44. package/src/@dictionaries/dictionaries.hail.ts +35 -35
  45. package/src/@dictionaries/dictionaries.icao.ts +258 -258
  46. package/src/@dictionaries/dictionaries.matches.ts +54 -35
  47. package/src/@dictionaries/dictionaries.products.ts +24 -24
  48. package/src/@dictionaries/dictionaries.records.ts +25 -25
  49. package/src/@dictionaries/dictionaries.severity.ts +27 -27
  50. package/src/@dictionaries/dictionaries.shapefiles.ts +35 -35
  51. package/src/@dictionaries/dictionaries.states.ts +71 -71
  52. package/src/@dictionaries/dictionaries.status.ts +30 -30
  53. package/src/@dictionaries/dictionaries.tags.ts +92 -92
  54. package/src/@dictionaries/dictionaries.testing.ts +24 -24
  55. package/src/@events/events.api.ts +116 -116
  56. package/src/@events/events.text.ts +84 -80
  57. package/src/@events/events.ugc.ts +89 -85
  58. package/src/@events/events.vtec.ts +86 -86
  59. package/src/@manager/manager.mkEvent.ts +97 -93
  60. package/src/@manager/manager.rmEvent.ts +56 -51
  61. package/src/@manager/manager.setHash.ts +35 -35
  62. package/src/@manager/manager.updateEvents.ts +32 -32
  63. package/src/@manager/manager.updateListener.ts +154 -154
  64. package/src/@manager/manager.updateNodes.ts +53 -53
  65. package/src/@modules/@database/database.broadcastify.ts +66 -66
  66. package/src/@modules/@database/database.cache.ts +49 -49
  67. package/src/@modules/@database/database.init.ts +58 -58
  68. package/src/@modules/@database/database.shapefiles.ts +92 -92
  69. package/src/@modules/@database/database.stanza.ts +46 -46
  70. package/src/@modules/@eas/eas.getCleanDescription.ts +91 -91
  71. package/src/@modules/@eas/eas.getFloatPCM16.ts +29 -29
  72. package/src/@modules/@eas/eas.getMergedPCM16.ts +32 -32
  73. package/src/@modules/@eas/eas.getPCM16.ts +52 -52
  74. package/src/@modules/@eas/eas.getPCMToFloat.ts +26 -26
  75. package/src/@modules/@eas/eas.getSampledPCM16.ts +36 -36
  76. package/src/@modules/@eas/eas.getTTS.ts +54 -54
  77. package/src/@modules/@eas/eas.getWavPCM16.ts +52 -52
  78. package/src/@modules/@eas/eas.setAFSK.ts +51 -51
  79. package/src/@modules/@eas/eas.setAsciiToBits.ts +31 -31
  80. package/src/@modules/@eas/eas.setAttentionTone.ts +40 -40
  81. package/src/@modules/@eas/eas.setEasTone.ts +151 -151
  82. package/src/@modules/@eas/eas.setNoise.ts +32 -32
  83. package/src/@modules/@eas/eas.setRadioEffect.ts +50 -50
  84. package/src/@modules/@eas/eas.setSameHeader.ts +44 -44
  85. package/src/@modules/@stanza/stanza.getAwipsType.ts +45 -45
  86. package/src/@modules/@stanza/stanza.validate.ts +49 -49
  87. package/src/@modules/@utilities/utilities.createHttp.ts +70 -70
  88. package/src/@modules/@utilities/utilities.getFormattedTime.ts +43 -43
  89. package/src/@modules/@utilities/utilities.getLatestIssuance.ts +32 -32
  90. package/src/@modules/@utilities/utilities.getMatched.ts +33 -33
  91. package/src/@modules/@utilities/utilities.getSettings.ts +25 -25
  92. package/src/@modules/@utilities/utilities.getShapeNearestPoint.ts +114 -114
  93. package/src/@modules/@utilities/utilities.setCronSchedule.ts +94 -94
  94. package/src/@modules/@utilities/utilities.setDebug.ts +38 -38
  95. package/src/@modules/@utilities/utilities.setEventEmit.ts +41 -41
  96. package/src/@modules/@utilities/utilities.setListener.ts +30 -30
  97. package/src/@modules/@utilities/utilities.setSettings.ts +42 -42
  98. package/src/@modules/@utilities/utilities.setSleep.ts +33 -33
  99. package/src/@modules/@utilities/utilities.setTimeoutAction.ts +62 -62
  100. package/src/@modules/@utilities/utilities.setWarning.ts +34 -34
  101. package/src/@modules/@xmpp/xmpp.xDeploy.ts +57 -57
  102. package/src/@modules/@xmpp/xmpp.xError.ts +26 -26
  103. package/src/@modules/@xmpp/xmpp.xOffline.ts +36 -36
  104. package/src/@modules/@xmpp/xmpp.xOnline.ts +45 -44
  105. package/src/@modules/@xmpp/xmpp.xReconnect.ts +64 -64
  106. package/src/@modules/@xmpp/xmpp.xStanza.ts +62 -62
  107. package/src/@parsers/@hvtec/hvtec.extract.ts +39 -39
  108. package/src/@parsers/@pvtec/pvtec.expires.ts +25 -25
  109. package/src/@parsers/@pvtec/pvtec.extract.ts +48 -48
  110. package/src/@parsers/@text/text.getDescriptionFromProduct.ts +52 -52
  111. package/src/@parsers/@text/text.getEmbed.ts +55 -55
  112. package/src/@parsers/@text/text.getPolygonFromProduct.ts +53 -32
  113. package/src/@parsers/@text/text.getTextFromProduct.ts +42 -42
  114. package/src/@parsers/@text/text.getXML.ts +60 -60
  115. package/src/@parsers/@ugc/ugc.coordinates.ts +110 -110
  116. package/src/@parsers/@ugc/ugc.expiry.ts +31 -31
  117. package/src/@parsers/@ugc/ugc.extract.ts +36 -36
  118. package/src/@parsers/@ugc/ugc.getCache.ts +23 -23
  119. package/src/@parsers/@ugc/ugc.header.ts +29 -29
  120. package/src/@parsers/@ugc/ugc.locations.ts +56 -56
  121. package/src/@parsers/@ugc/ugc.setCache.ts +27 -27
  122. package/src/@parsers/@ugc/ugc.zones.ts +51 -51
  123. package/src/@types/type.attributes.ts +28 -28
  124. package/src/@types/type.compiled.ts +34 -34
  125. package/src/@types/type.event.ts +69 -69
  126. package/src/@types/type.hash.ts +24 -24
  127. package/src/@types/type.hvtec.ts +25 -25
  128. package/src/@types/type.listener.ts +32 -32
  129. package/src/@types/type.properties.ts +77 -77
  130. package/src/@types/type.pvtec.ts +30 -30
  131. package/src/@types/type.settings.ts +84 -84
  132. package/src/@types/type.stanza.ts +37 -37
  133. package/src/@types/type.ugc.ts +24 -24
  134. package/src/bootstrap.ts +115 -115
  135. package/src/index.ts +74 -74
  136. package/test.js +92 -92
  137. package/tsconfig.json +13 -13
  138. package/tsup.config.ts +15 -15
  139. package/src/@core/core.createEvent.ts +0 -82
@@ -1104,13 +1104,13 @@ var index_exports = {};
1104
1104
  __export(index_exports, {
1105
1105
  Manager: () => Manager,
1106
1106
  clearEvents: () => clearEvents,
1107
- createEvent: () => createEvent2,
1108
1107
  default: () => index_default,
1109
1108
  getCleanedEvent: () => getCleanedEvent,
1110
1109
  getEventGeometry: () => getEventGeometry,
1111
1110
  getEvents: () => getEvents,
1112
1111
  getNodes: () => getNodes,
1113
1112
  getRandomEvent: () => getRandomEvent,
1113
+ manualEvent: () => manualEvent,
1114
1114
  query: () => query,
1115
1115
  setEasTone: () => setEasTone,
1116
1116
  setNode: () => setNode,
@@ -1124,7 +1124,7 @@ module.exports = __toCommonJS(index_exports);
1124
1124
  var import_path = __toESM(require("path"));
1125
1125
  var import_node_events = require("events");
1126
1126
  var bootstrap = {
1127
- version: `3.0.51`,
1127
+ version: `3.0.52`,
1128
1128
  isReady: true,
1129
1129
  ratelimits: {},
1130
1130
  session_xmpp: null,
@@ -1155,7 +1155,7 @@ var bootstrap = {
1155
1155
  },
1156
1156
  settings: {
1157
1157
  Database: import_path.default.join(process.cwd(), "shapefiles.db"),
1158
- EnableWireService: true,
1158
+ EnableWireService: false,
1159
1159
  EnableDebugging: false,
1160
1160
  EnableJournal: true,
1161
1161
  NOAAWeatherWireServiceSettings: {
@@ -1193,7 +1193,7 @@ var bootstrap = {
1193
1193
  EventManagement: true,
1194
1194
  BetterEventNames: true,
1195
1195
  DisableGeometryParsing: false,
1196
- UseShapefileCoordinates: false,
1196
+ UseShapefileCoordinates: true,
1197
1197
  SPCWatchesOnly: true,
1198
1198
  ShapefileSkipPoints: 15,
1199
1199
  NodeTTL: 60,
@@ -1325,7 +1325,7 @@ var getZonePolygon = (options) => {
1325
1325
  };
1326
1326
 
1327
1327
  // src/@building/building.geometry.ts
1328
- var getEventGeometry = (event) => __async(null, null, function* () {
1328
+ var getEventGeometry = (event) => {
1329
1329
  var _a, _b, _c, _d, _e, _f;
1330
1330
  const settings = getSettings();
1331
1331
  const generated = (_c = (_b = (_a = event == null ? void 0 : event.properties) == null ? void 0 : _a.geocode) == null ? void 0 : _b.polygon) != null ? _c : null;
@@ -1335,7 +1335,7 @@ var getEventGeometry = (event) => __async(null, null, function* () {
1335
1335
  coordinates: generated != null ? JSON.parse(Buffer.from(generated, "base64").toString("utf-8")) : null
1336
1336
  };
1337
1337
  if (settings.GlobalSettings.UseShapefileCoordinates && generated == null && ugc2 != null) {
1338
- geo = yield getZonePolygon({ zones: ugc2, isUnion: false });
1338
+ geo = getZonePolygon({ zones: ugc2, isUnion: false });
1339
1339
  if (geo == null) {
1340
1340
  geo = {
1341
1341
  type: `Polygon`,
@@ -1344,7 +1344,7 @@ var getEventGeometry = (event) => __async(null, null, function* () {
1344
1344
  }
1345
1345
  }
1346
1346
  return geo;
1347
- });
1347
+ };
1348
1348
 
1349
1349
  // src/@building/building.clean.ts
1350
1350
  var getCleanedEvent = (event) => {
@@ -4200,7 +4200,8 @@ var xOnline = () => {
4200
4200
  data: {},
4201
4201
  type: `online`,
4202
4202
  error: false
4203
- }
4203
+ },
4204
+ message: `Succesfully connected to NOAA Weather Wire Service as "${nickname}"`
4204
4205
  });
4205
4206
  }));
4206
4207
  };
@@ -4522,9 +4523,9 @@ var dict_awips = {
4522
4523
  SVR: `severe-thunderstorm-warning`,
4523
4524
  SVS: `severe-weather-statement`,
4524
4525
  SWOMCD: `mesoscale-discussion`,
4525
- SWODY1: `spc-day-1-outlook`,
4526
- SWODY2: `spc-day-2-outlook`,
4527
- SWODY3: `spc-day-3-outlook`,
4526
+ SWODY1: `SPC-day-1-outlook`,
4527
+ SWODY2: `SPC-day-2-outlook`,
4528
+ SWODY3: `SPC-day-3-outlook`,
4528
4529
  SWS: `state-weather-summary`,
4529
4530
  SYN: `regional-weather-synopsis`,
4530
4531
  TAF: `terminal-aerodrome-forecast`,
@@ -4544,7 +4545,7 @@ var dict_awips = {
4544
4545
  TOE: `telephone-outage-emergency`,
4545
4546
  TOR: `tornado-warning`,
4546
4547
  TPT: `temperature-precipitation-table`,
4547
- TSU: `tsunami-watch`,
4548
+ TSU: `tsunami-information-statement`,
4548
4549
  TUV: `ultraviolet-index`,
4549
4550
  TVL: `travelers-forecast`,
4550
4551
  TWB: `transcribed-weather-broadcast`,
@@ -4640,21 +4641,39 @@ var validate = (options) => {
4640
4641
 
4641
4642
  // src/@dictionaries/dictionaries.matches.ts
4642
4643
  var dict_matches = {
4643
- "Special Weather Statement": "Special Weather Statement",
4644
- "Hurricane Warning": "Hurricane Warning",
4645
- "Hurricane Force Wind Warning": "Hurricane Force Wind Warning",
4646
- "Hurricane Watch": "Hurricane Watch",
4647
- "Tropical Storm Warning": "Tropical Storm Warning",
4648
- "Tropical Storm Watch": "Tropical Storm Watch",
4649
- "High Wind Warning": "High Wind Warning",
4650
- "Gale Warning": "Gale Warning",
4651
- "Small Craft Advisory": "Small Craft Advisory",
4652
- "Small Craft Warning": "Small Craft Warning",
4653
- "Tsunami Warning": "Tsunami Warning",
4654
- "Tsunami Watch": "Tsunami Watch",
4655
- "Tsunami Advisory": "Tsunami Advisory",
4656
- "Tsunami Information Statement": "Tsunami Information Statement",
4657
- "Subscribers:": "National Weather Service Policy"
4644
+ SPS: [
4645
+ { match: /STRONG THUNDERSTORM/i, label: "Convective Special Weather Statement", statement: false },
4646
+ { match: /SPECIAL WEATHER STATEMENT/i, label: "Special Weather Statement", statement: false }
4647
+ ],
4648
+ TSU: [
4649
+ { match: /TSUNAMI WARNING/i, label: "Tsunami Warning", statement: false },
4650
+ { match: /TSUNAMI WATCH/i, label: "Tsunami Watch", statement: false },
4651
+ { match: /TSUNAMI ADVISORY/i, label: "Tsunami Advisory", statement: false },
4652
+ { match: /TSUNAMI INFORMATION STATEMENT/i, label: "Tsunami Information Statement", statement: false },
4653
+ { match: /TSUNAMI WARNING CANCELLATION/i, label: "Tsunami Cancellation", statement: false }
4654
+ ],
4655
+ TCP: [
4656
+ { match: /HURRICANE WARNING/i, label: "Hurricane Warning", statement: false },
4657
+ { match: /HURRICANE WATCH/i, label: "Hurricane Watch", statement: false },
4658
+ { match: /TROPICAL STORM WARNING/i, label: "Tropical Storm Warning", statement: false },
4659
+ { match: /TROPICAL STORM WATCH/i, label: "Tropical Storm Watch", statement: false },
4660
+ { match: /STORM SURGE WARNING/i, label: "Storm Surge Warning", statement: false },
4661
+ { match: /STORM SURGE WATCH/i, label: "Storm Surge Watch", statement: false }
4662
+ ],
4663
+ MWW: [
4664
+ { match: /SMALL CRAFT ADVISORY/i, label: "Small Craft Advisory", statement: false },
4665
+ { match: /GALE WARNING/i, label: "Gale Warning", statement: false },
4666
+ { match: /STORM WARNING/i, label: "Storm Warning", statement: false },
4667
+ { match: /HURRICANE FORCE WIND WARNING/i, label: "Hurricane Force Wind Warning", statement: false },
4668
+ { match: /HAZARDOUS SEAS WARNING/i, label: "Hazardous Seas Warning", statement: false },
4669
+ { match: /DENSE FOG ADVISORY/i, label: "Dense Fog Advisory", statement: false },
4670
+ { match: /THUNDERSTORMS/i, label: "Convective Marine Weather Statement", statement: false },
4671
+ { match: /MARINE WEATHER STATEMENT/i, label: "Marine Weather Statement", statement: false }
4672
+ ],
4673
+ PNS: [
4674
+ { match: /NOAA WEATHER WIRE SERVICE/i, label: "NOAA Weather Wire Service Report", statement: true },
4675
+ { match: /Public Information Statement/i, label: "Public Information Statement", statement: true }
4676
+ ]
4658
4677
  };
4659
4678
 
4660
4679
  // src/@parsers/@text/text.getDescriptionFromProduct.ts
@@ -4689,18 +4708,32 @@ var getDescriptionFromProduct = (options) => {
4689
4708
  // src/@parsers/@text/text.getPolygonFromProduct.ts
4690
4709
  var getPolygonFromProduct = (message) => {
4691
4710
  const coordinates = [];
4692
- const match = message.match(/LAT\.{3}LON\s+([\d\s]+)/i);
4693
- if (!match || !match[1]) return coordinates;
4694
- const coordStrings = match[1].replace(/\n/g, " ").trim().split(/\s+/);
4695
- for (let i = 0; i < coordStrings.length - 1; i += 2) {
4696
- const lat = parseFloat(coordStrings[i]) / 100;
4697
- const lon = -parseFloat(coordStrings[i + 1]) / 100;
4698
- if (!isNaN(lat) && !isNaN(lon)) {
4699
- coordinates.push([lon, lat]);
4711
+ const match = message.match(
4712
+ /LAT\.\.\.LON\s+([\s\S]*?)(?=\n[A-Z]{2,}(?:\.\.\.|:)|\$\$|&&|$)/i
4713
+ );
4714
+ if (!match) return coordinates;
4715
+ const text2 = match[1];
4716
+ const values = text2.match(/\d{4,8}/g);
4717
+ if (!values) return coordinates;
4718
+ if (values.every((v) => v.length === 8)) {
4719
+ for (const value of values) {
4720
+ const lat = parseInt(value.slice(0, 4), 10) / 100;
4721
+ const lon = -parseInt(value.slice(4, 8), 10) / 100;
4722
+ if (Number.isFinite(lat) && Number.isFinite(lon)) {
4723
+ coordinates.push([lon, lat]);
4724
+ }
4725
+ }
4726
+ } else {
4727
+ for (let i = 0; i + 1 < values.length; i += 2) {
4728
+ const lat = parseInt(values[i], 10) / 100;
4729
+ const lon = -parseInt(values[i + 1], 10) / 100;
4730
+ if (Number.isFinite(lat) && Number.isFinite(lon)) {
4731
+ coordinates.push([lon, lat]);
4732
+ }
4700
4733
  }
4701
4734
  }
4702
4735
  if (coordinates.length > 2) {
4703
- coordinates.push(coordinates[0]);
4736
+ coordinates.push([...coordinates[0]]);
4704
4737
  }
4705
4738
  return coordinates;
4706
4739
  };
@@ -5176,7 +5209,7 @@ var setDebug = (options) => {
5176
5209
 
5177
5210
  // src/@events/events.text.ts
5178
5211
  var text = (stanza) => __async(null, null, function* () {
5179
- var _a, _b, _c;
5212
+ var _a, _b, _c, _d, _e;
5180
5213
  const getMessages = (_c = (_b = (_a = stanza == null ? void 0 : stanza.message) == null ? void 0 : _a.split(/(?=\$\$)/g)) == null ? void 0 : _b.map((message) => message.trim())) == null ? void 0 : _c.filter((message) => message && message !== "$$");
5181
5214
  if (!getMessages || (getMessages == null ? void 0 : getMessages.length) == 0) return;
5182
5215
  for (const message of getMessages) {
@@ -5186,8 +5219,9 @@ var text = (stanza) => __async(null, null, function* () {
5186
5219
  const header = getEventHeader({ properties: props, getType: stanza.getType });
5187
5220
  const issued = new Date(attributes.issue);
5188
5221
  const expires = new Date(issued.getTime() + 12 * 60 * 60 * 1e3);
5189
- let event = Object.keys(dict_matches).find((event2) => message.toLowerCase().includes(event2.toLowerCase()));
5190
- let isStatement = false;
5222
+ const matches = (_d = dict_matches[stanza.getType.prefix]) == null ? void 0 : _d.find((match) => match.match.test(message.toUpperCase()));
5223
+ let event = matches == null ? void 0 : matches.label;
5224
+ let isStatement = (_e = matches == null ? void 0 : matches.statement) != null ? _e : false;
5191
5225
  if (!event) {
5192
5226
  event = stanza.getType.type.split(`-`).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(` `);
5193
5227
  isStatement = true;
@@ -5345,7 +5379,7 @@ var ugcExtract = (message) => __async(null, null, function* () {
5345
5379
 
5346
5380
  // src/@events/events.ugc.ts
5347
5381
  var ugc = (stanza) => __async(null, null, function* () {
5348
- var _a, _b, _c;
5382
+ var _a, _b, _c, _d, _e;
5349
5383
  const getMessages = (_c = (_b = (_a = stanza == null ? void 0 : stanza.message) == null ? void 0 : _a.split(/(?=\$\$)/g)) == null ? void 0 : _b.map((message) => message.trim())) == null ? void 0 : _c.filter((message) => message && message !== "$$");
5350
5384
  if (!getMessages || (getMessages == null ? void 0 : getMessages.length) == 0) return;
5351
5385
  for (const message of getMessages) {
@@ -5357,8 +5391,9 @@ var ugc = (stanza) => __async(null, null, function* () {
5357
5391
  const issued = new Date(attributes.issue);
5358
5392
  const expires = new Date(ugc2.expires);
5359
5393
  const header = getEventHeader({ properties: props, getType: stanza.getType });
5360
- let event = Object.keys(dict_matches).find((event2) => message.toLowerCase().includes(event2.toLowerCase()));
5361
- let isStatement = false;
5394
+ const matches = (_d = dict_matches[stanza.getType.prefix]) == null ? void 0 : _d.find((match) => match.match.test(message.toUpperCase()));
5395
+ let event = matches == null ? void 0 : matches.label;
5396
+ let isStatement = (_e = matches == null ? void 0 : matches.statement) != null ? _e : false;
5362
5397
  if (!event) {
5363
5398
  event = stanza.getType.type.split(`-`).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(` `);
5364
5399
  isStatement = true;
@@ -5735,85 +5770,42 @@ var api = (stanza) => __async(null, null, function* () {
5735
5770
  // src/@dictionaries/dictionaries.enhanced.ts
5736
5771
  var dict_enhanced = {
5737
5772
  "Tornado Warning": {
5738
- "Tornado Emergency": {
5739
- description: "tornado emergency"
5740
- },
5741
- "PDS Tornado Warning": {
5742
- description: "particularly dangerous situation",
5743
- damage: `CONSIDERABLE`
5744
- },
5745
- "Radar Confirmed Tornado Warning": {
5746
- description: "source...radar confirmed tornado.",
5747
- tornado: `OBSERVED`
5748
- },
5749
- "Confirmed Tornado Warning": {
5750
- tornado: `OBSERVED`
5751
- },
5773
+ "Tornado Emergency": { description: "tornado emergency" },
5774
+ "PDS Tornado Warning": { description: "particularly dangerous situation", damage: `CONSIDERABLE` },
5775
+ "Radar Confirmed Tornado Warning": { description: "source...radar confirmed tornado.", tornado: `OBSERVED` },
5776
+ "Confirmed Tornado Warning": { tornado: `OBSERVED` },
5752
5777
  "Radar Indicated Tornado Warning": {}
5753
5778
  },
5754
5779
  "Fire Weather Warning": {
5755
- "PDS Fire Weather Warning": {
5756
- description: "particularly dangerous situation"
5757
- }
5780
+ "PDS Fire Weather Warning": { description: "particularly dangerous situation" }
5758
5781
  },
5759
5782
  "Blizzard Warning": {
5760
- "PDS Blizzard Warning": {
5761
- description: "particularly dangerous situation"
5762
- }
5783
+ "PDS Blizzard Warning": { description: "particularly dangerous situation" }
5763
5784
  },
5764
5785
  "Ice Storm Warning": {
5765
- "PDS Ice Storm Warning": {
5766
- description: "particularly dangerous situation"
5767
- }
5786
+ "PDS Ice Storm Warning": { description: "particularly dangerous situation" }
5768
5787
  },
5769
5788
  "Special Marine Warning": {
5770
- "Special Marine Warning (TPROB)": {
5771
- tornado: `POSSIBLE`
5772
- }
5789
+ "Special Marine Warning (TPROB)": { tornado: `POSSIBLE` }
5773
5790
  },
5774
5791
  "Tornado Watch": {
5775
- "PDS Tornado Watch": {
5776
- pdswatch: true
5777
- }
5792
+ "PDS Tornado Watch": { pdswatch: true }
5778
5793
  },
5779
5794
  "Severe Thunderstorm Watch": {
5780
- "PDS Severe Thunderstorm Watch": {
5781
- pdswatch: true
5782
- }
5795
+ "PDS Severe Thunderstorm Watch": { pdswatch: true }
5783
5796
  },
5784
5797
  "Flash Flood Warning": {
5785
- "Flash Flood Emergency": {
5786
- description: "flash flood emergency"
5787
- },
5788
- "Considerable Flash Flood Warning": {
5789
- damage: `CONSIDERABLE`
5790
- }
5798
+ "Flash Flood Emergency": { description: "flash flood emergency" },
5799
+ "Considerable Flash Flood Warning": { damage: `CONSIDERABLE` }
5791
5800
  },
5792
5801
  "Severe Thunderstorm Warning": {
5793
- "EDS Severe Thunderstorm Warning (TPROB)": {
5794
- description: "extremely dangerous situation",
5795
- tornado: "POSSIBLE"
5796
- },
5797
- "EDS Severe Thunderstorm Warning": {
5798
- description: "extremely dangerous situation"
5799
- },
5800
- "Destructive Severe Thunderstorm Warning (TPROB)": {
5801
- damage: `DESTRUCTIVE`,
5802
- tornado: `POSSIBLE`
5803
- },
5804
- "Destructive Severe Thunderstorm Warning": {
5805
- damage: `DESTRUCTIVE`
5806
- },
5807
- "Considerable Severe Thunderstorm Warning (TPROB)": {
5808
- damage: `CONSIDERABLE`,
5809
- tornado: `POSSIBLE`
5810
- },
5811
- "Considerable Severe Thunderstorm Warning": {
5812
- damage: `CONSIDERABLE`
5813
- },
5814
- "Severe Thunderstorm Warning (TPROB)": {
5815
- tornado: `POSSIBLE`
5816
- }
5802
+ "EDS Severe Thunderstorm Warning (TPROB)": { description: "extremely dangerous situation", tornado: "POSSIBLE" },
5803
+ "EDS Severe Thunderstorm Warning": { description: "extremely dangerous situation" },
5804
+ "Destructive Severe Thunderstorm Warning (TPROB)": { damage: `DESTRUCTIVE`, tornado: `POSSIBLE` },
5805
+ "Destructive Severe Thunderstorm Warning": { damage: `DESTRUCTIVE` },
5806
+ "Considerable Severe Thunderstorm Warning (TPROB)": { damage: `CONSIDERABLE`, tornado: `POSSIBLE` },
5807
+ "Considerable Severe Thunderstorm Warning": { damage: `CONSIDERABLE` },
5808
+ "Severe Thunderstorm Warning (TPROB)": { tornado: `POSSIBLE` }
5817
5809
  }
5818
5810
  };
5819
5811
 
@@ -5944,6 +5936,13 @@ var getEventSignature = (event) => {
5944
5936
  return event;
5945
5937
  };
5946
5938
 
5939
+ // src/@dictionaries/dictionaries.global.ts
5940
+ var dict_global = [
5941
+ "spc day 1 outlook",
5942
+ "spc day 2 outlook",
5943
+ "spc day 3 outlook"
5944
+ ];
5945
+
5947
5946
  // src/@manager/manager.setHash.ts
5948
5947
  var setHash = (event, entry) => {
5949
5948
  if (entry) {
@@ -6804,7 +6803,7 @@ var mkEvent = (event) => __async(null, null, function* () {
6804
6803
  if (isHashed || event.properties.status_metadata.is_expired) return;
6805
6804
  setHash(event, isEntry);
6806
6805
  const isFilteredLocation = yield updateNode(event).then(() => event.properties.metadata.filtered_proximity);
6807
- if (!isFilteredLocation && settings.GlobalSettings.EventFiltering.NodeLocationFiltering) {
6806
+ if (!isFilteredLocation && !dict_global.includes(event.properties.event.toLowerCase()) && settings.GlobalSettings.EventFiltering.NodeLocationFiltering) {
6808
6807
  return;
6809
6808
  }
6810
6809
  const isRatelimited = setTimeoutAction({ identifier: getTracking, interval: 1, max: 1, addTime: true });
@@ -6862,15 +6861,17 @@ var rmEvent = (event) => __async(null, null, function* () {
6862
6861
  event.properties.status = `Expired`;
6863
6862
  event.properties.status_metadata.is_expired = true;
6864
6863
  if (getEvent) {
6865
- setEventEmit({
6866
- event: `onEventStatus`,
6867
- metadata: {
6868
- type: `Removed`,
6869
- event
6870
- },
6871
- message: `[Removed] ${event.properties.event} (${event.properties.status}) (${event.properties.metadata.tracking})`
6872
- });
6873
- setEventEmit({ event: `onExpiredProduct`, metadata: event });
6864
+ if (!event.properties.status_metadata.is_statement) {
6865
+ setEventEmit({
6866
+ event: `onEventStatus`,
6867
+ metadata: {
6868
+ type: `Removed`,
6869
+ event
6870
+ },
6871
+ message: `[Removed] ${event.properties.event} (${event.properties.status}) (${event.properties.metadata.tracking})`
6872
+ });
6873
+ setEventEmit({ event: `onExpiredProduct`, metadata: event });
6874
+ }
6874
6875
  if (cachedStatus != `Statement`) yield updateListener(event);
6875
6876
  bootstrap.cache.events.features.splice(bootstrap.cache.events.features.indexOf(getEvent), 1);
6876
6877
  bootstrap.cache.hashes = bootstrap.cache.hashes.filter((hash) => hash.tracking !== event.properties.metadata.tracking);
@@ -6971,7 +6972,7 @@ var getEventAttachments = (event) => {
6971
6972
  { target: "PDS Severe Thunderstorm Watch", attachment: `https://www.spc.noaa.gov/products/watch/ww${watchNumber}_radar_big.gif` }
6972
6973
  ];
6973
6974
  if (events.find((e) => e.target === event.properties.event)) {
6974
- attachments.push({ name: `Image: Graphic`, link: events.find((e) => e.target === event.properties.event).attachment });
6975
+ attachments.push({ name: `Image: Graphic`, link: events.find((e) => e.target.toLowerCase() === event.properties.event.toLowerCase()).attachment });
6975
6976
  }
6976
6977
  for (const location of locations) {
6977
6978
  if (dict_expressions.location.test(location)) {
@@ -7001,7 +7002,6 @@ var getEventAttachments = (event) => {
7001
7002
  // src/@building/building.validate.ts
7002
7003
  var import_crypto = require("crypto");
7003
7004
  var validateEvents = (events) => __async(null, null, function* () {
7004
- var _a;
7005
7005
  const tick = performance.now();
7006
7006
  if (events.length === 0) return;
7007
7007
  const configurations = bootstrap.settings;
@@ -7017,39 +7017,28 @@ var validateEvents = (events) => __async(null, null, function* () {
7017
7017
  bools[key] = setting;
7018
7018
  }
7019
7019
  }
7020
- const filterd = events.filter((event) => {
7021
- var _a2, _b, _c, _d, _e;
7022
- bootstrap.cache.processed = bootstrap.cache.processed.filter((e) => e !== event);
7023
- const define2 = getEventSignature(event);
7020
+ const isFiltered = (define2) => {
7021
+ var _a, _b, _c, _d;
7024
7022
  const properties2 = define2.properties;
7025
7023
  const zones = properties2.geocode.ugc;
7026
7024
  const icao = properties2.geocode.office.office;
7027
- const enhancedEventName = properties2.event = getEventEnhancedName(event);
7028
- const filteredProperties = JSON.parse(JSON.stringify(properties2));
7029
- if ((filteredProperties == null ? void 0 : filteredProperties.metadata) && "ms" in filteredProperties.metadata) {
7030
- delete filteredProperties.metadata.ms;
7031
- }
7032
- filteredProperties.metadata = (_a2 = filteredProperties.metadata) != null ? _a2 : {};
7033
- properties2.metadata.hash = (0, import_crypto.createHash)("sha256").update(JSON.stringify(filteredProperties)).digest("hex");
7034
- properties2.metadata.attachments = getEventAttachments(event);
7035
- setEventEmit({ event: `onProductType${enhancedEventName.replace(/\s+/g, "")}`, metadata: define2 });
7036
7025
  if (properties2.status_metadata.is_test) {
7037
7026
  setEventEmit({ event: `onTestProduct`, metadata: define2 });
7038
- if (bools == null ? void 0 : bools.IgnoreTestProducts) return false;
7027
+ if (bools == null ? void 0 : bools.IgnoreTestProducts) return true;
7039
7028
  }
7040
7029
  if (properties2.status_metadata.is_expired) {
7041
7030
  setEventEmit({ event: `onExpiredProduct`, metadata: define2 });
7042
7031
  rmEvent(define2);
7043
- return false;
7032
+ return true;
7044
7033
  }
7045
- if (((_c = (_b = properties2.metadata) == null ? void 0 : _b.vtec) == null ? void 0 : _c.is_watch) && properties2.metadata.source != `events.api`) {
7046
- const isSPC = (_e = (_d = properties2.metadata) == null ? void 0 : _d.vtec) == null ? void 0 : _e.prediction_center;
7034
+ if (((_b = (_a = properties2.metadata) == null ? void 0 : _a.vtec) == null ? void 0 : _b.is_watch) && properties2.metadata.source != `events.api`) {
7035
+ const isSPC = (_d = (_c = properties2.metadata) == null ? void 0 : _c.vtec) == null ? void 0 : _d.prediction_center;
7047
7036
  setEventEmit({ event: isSPC ? `onStormPredictionWatch` : `onNonStormPredictionWatch`, metadata: define2 });
7048
7037
  if ((bools == null ? void 0 : bools.SPCWatchesOnly) && !isSPC) {
7049
- return false;
7038
+ return true;
7050
7039
  }
7051
7040
  if (!(bools == null ? void 0 : bools.SPCWatchesOnly) && isSPC) {
7052
- return false;
7041
+ return true;
7053
7042
  }
7054
7043
  }
7055
7044
  for (const key in sets) {
@@ -7060,53 +7049,64 @@ var validateEvents = (events) => __async(null, null, function* () {
7060
7049
  event: `onFilteredEvent`,
7061
7050
  metadata: define2
7062
7051
  });
7063
- return false;
7052
+ return true;
7064
7053
  }
7065
7054
  if (key === "IgnoredEvents" && setting.size > 0 && getMatched(values, define2.properties.event)) {
7066
7055
  setEventEmit({
7067
7056
  event: `onIgnoredEvent`,
7068
7057
  metadata: define2
7069
7058
  });
7070
- return false;
7059
+ return true;
7071
7060
  }
7072
7061
  if (key === "ListeningICAO" && setting.size > 0 && icao != null && !setting.has(icao.toLowerCase())) {
7073
7062
  setEventEmit({
7074
7063
  event: `onFilteredICAO`,
7075
7064
  metadata: define2
7076
7065
  });
7077
- return false;
7066
+ return true;
7078
7067
  }
7079
7068
  if (key === "IgnoredICAO" && setting.size > 0 && icao != null && setting.has(icao.toLowerCase())) {
7080
7069
  setEventEmit({
7081
7070
  event: `onIgnoredICAO`,
7082
7071
  metadata: define2
7083
7072
  });
7084
- return false;
7073
+ return true;
7085
7074
  }
7086
7075
  if (key === "ListeningUGC" && setting.size > 0 && zones.length > 0 && !zones.some((ugc2) => setting.has(ugc2.toLowerCase()))) {
7087
7076
  setEventEmit({
7088
7077
  event: `onFilteredUGC`,
7089
7078
  metadata: define2
7090
7079
  });
7091
- return false;
7080
+ return true;
7092
7081
  }
7093
7082
  if (key === "ListeningStates" && setting.size > 0 && zones.length > 0 && !zones.some((ugc2) => setting.has(ugc2.substring(0, 2).toLowerCase()))) {
7094
7083
  setEventEmit({
7095
7084
  event: `onFilteredState`,
7096
7085
  metadata: define2
7097
7086
  });
7098
- return false;
7087
+ return true;
7099
7088
  }
7100
7089
  }
7101
- return true;
7090
+ return false;
7091
+ };
7092
+ const filtering = events.filter((event) => {
7093
+ var _a;
7094
+ bootstrap.cache.processed = bootstrap.cache.processed.filter((e) => e !== event);
7095
+ const define2 = getEventSignature(event);
7096
+ const properties2 = define2.properties;
7097
+ (_a = properties2 == null ? void 0 : properties2.metadata) == null ? true : delete _a.ms;
7098
+ const enhanced = properties2.event = getEventEnhancedName(event);
7099
+ const filtered = isFiltered(define2);
7100
+ if (!filtered) {
7101
+ event.geometry = !(bools == null ? void 0 : bools.DisableGeometryParsing) ? getEventGeometry(event) : null;
7102
+ properties2.metadata.attachments = getEventAttachments(event);
7103
+ }
7104
+ properties2.metadata.hash = (0, import_crypto.createHash)("sha256").update(JSON.stringify(properties2)).digest("hex");
7105
+ setEventEmit({ event: `onProductType${enhanced.replace(/\s+/g, "")}`, metadata: define2 });
7106
+ return !filtered;
7102
7107
  });
7103
- if (!((_a = configurations == null ? void 0 : configurations.GlobalSettings) == null ? void 0 : _a.DisableGeometryParsing)) {
7104
- for (const event of filterd) {
7105
- event.geometry = yield getEventGeometry(event);
7106
- }
7107
- }
7108
- if (filterd.length > 0) {
7109
- for (const event of filterd) {
7108
+ if (filtering.length > 0) {
7109
+ for (const event of filtering) {
7110
7110
  yield mkEvent(event);
7111
7111
  }
7112
7112
  }
@@ -7116,7 +7116,7 @@ var validateEvents = (events) => __async(null, null, function* () {
7116
7116
  metadata: bootstrap.cache.events,
7117
7117
  limited: true
7118
7118
  });
7119
- setDebug({ title: `@building.validate`, message: `Filtered ${filterd.length} events which took ${performance.now() - tick} ms` });
7119
+ setDebug({ title: `@building.validate`, message: `Filtered ${filtering.length} events which took ${performance.now() - tick} ms` });
7120
7120
  });
7121
7121
 
7122
7122
  // src/@building/building.create.ts
@@ -7666,59 +7666,16 @@ var getNodes = () => {
7666
7666
  return bootstrap.cache.nodes;
7667
7667
  };
7668
7668
 
7669
- // src/@core/core.createEvent.ts
7670
- var createEvent2 = (options) => {
7671
- var _a;
7672
- const tick = performance.now();
7673
- validateEvents([{
7674
- type: `Feature`,
7675
- geometry: {
7676
- type: `Point`,
7677
- coordinates: options.coordinates
7678
- },
7679
- properties: {
7680
- event: options.event,
7681
- parent: options.event,
7682
- status: options.status,
7683
- issued: options.issued.toISOString(),
7684
- expires: options.expires.toISOString(),
7685
- locations: options.locations,
7686
- locations_array: options.locations ? options.locations.split(";") : [],
7687
- description: options.description,
7688
- geocode: {
7689
- office: {
7690
- office: `ATMX`,
7691
- name: `AtmosphericX Manual Event`
7692
- },
7693
- organization: `AtmosphericX`,
7694
- ugc: [],
7695
- polygon: options.coordinates.length > 0 ? Buffer.from(JSON.stringify([options.coordinates[0]])).toString("base64") : null,
7696
- polygon_generated: options.coordinates.length > 0 ? true : false
7697
- },
7698
- status_metadata: {
7699
- is_issued: options.status == `Issued`,
7700
- is_updated: options.status == `Updated`,
7701
- is_expired: options.status == `Expired`,
7702
- is_test: options.status == `Test`,
7703
- is_statement: options.status == `Statement`
7704
- },
7705
- metadata: {
7706
- ms: performance.now() - tick,
7707
- source: `events.manual`,
7708
- tracking: `ATMX-M-W-01`,
7709
- header: `ZCZC-ATMOSX-ATMX-M-W-01`,
7710
- raw: options.description,
7711
- history: [
7712
- {
7713
- description: options.description,
7714
- issued: options.issued.toISOString(),
7715
- status: (_a = options.status) != null ? _a : null
7716
- }
7717
- ]
7718
- }
7719
- }
7720
- }]);
7721
- };
7669
+ // src/@core/core.manualEvent.ts
7670
+ var manualEvent = (options) => __async(null, null, function* () {
7671
+ const isCapEvent = options.message.includes(`<?xml`);
7672
+ const isCapAreaDescription = options.message.includes(`<areaDesc>`);
7673
+ const isVTEC = options.message.match(dict_expressions.pvtec) != null;
7674
+ const isUGC = options.message.match(dict_expressions.ugc1) != null;
7675
+ const getType = getAwipsType({ attributes: options.attributes });
7676
+ const result = { message: options.message, attributes: options.attributes, isCapEvent, isVTEC, isUGC, isCapAreaDescription, isIgnored: false, isNWWS: true, getType };
7677
+ yield createEvent(result);
7678
+ });
7722
7679
 
7723
7680
  // src/@core/core.getRandomEvent.ts
7724
7681
  var getRandomEvent = () => {
@@ -7780,12 +7737,12 @@ var index_default = Manager;
7780
7737
  0 && (module.exports = {
7781
7738
  Manager,
7782
7739
  clearEvents,
7783
- createEvent,
7784
7740
  getCleanedEvent,
7785
7741
  getEventGeometry,
7786
7742
  getEvents,
7787
7743
  getNodes,
7788
7744
  getRandomEvent,
7745
+ manualEvent,
7789
7746
  query,
7790
7747
  setEasTone,
7791
7748
  setNode,