@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,7 +1104,7 @@ var require_main3 = __commonJS({
1104
1104
  import path from "path";
1105
1105
  import { EventEmitter } from "events";
1106
1106
  var bootstrap = {
1107
- version: `3.0.51`,
1107
+ version: `3.0.52`,
1108
1108
  isReady: true,
1109
1109
  ratelimits: {},
1110
1110
  session_xmpp: null,
@@ -1135,7 +1135,7 @@ var bootstrap = {
1135
1135
  },
1136
1136
  settings: {
1137
1137
  Database: path.join(process.cwd(), "shapefiles.db"),
1138
- EnableWireService: true,
1138
+ EnableWireService: false,
1139
1139
  EnableDebugging: false,
1140
1140
  EnableJournal: true,
1141
1141
  NOAAWeatherWireServiceSettings: {
@@ -1173,7 +1173,7 @@ var bootstrap = {
1173
1173
  EventManagement: true,
1174
1174
  BetterEventNames: true,
1175
1175
  DisableGeometryParsing: false,
1176
- UseShapefileCoordinates: false,
1176
+ UseShapefileCoordinates: true,
1177
1177
  SPCWatchesOnly: true,
1178
1178
  ShapefileSkipPoints: 15,
1179
1179
  NodeTTL: 60,
@@ -1305,7 +1305,7 @@ var getZonePolygon = (options) => {
1305
1305
  };
1306
1306
 
1307
1307
  // src/@building/building.geometry.ts
1308
- var getEventGeometry = (event) => __async(null, null, function* () {
1308
+ var getEventGeometry = (event) => {
1309
1309
  var _a, _b, _c, _d, _e, _f;
1310
1310
  const settings = getSettings();
1311
1311
  const generated = (_c = (_b = (_a = event == null ? void 0 : event.properties) == null ? void 0 : _a.geocode) == null ? void 0 : _b.polygon) != null ? _c : null;
@@ -1315,7 +1315,7 @@ var getEventGeometry = (event) => __async(null, null, function* () {
1315
1315
  coordinates: generated != null ? JSON.parse(Buffer.from(generated, "base64").toString("utf-8")) : null
1316
1316
  };
1317
1317
  if (settings.GlobalSettings.UseShapefileCoordinates && generated == null && ugc2 != null) {
1318
- geo = yield getZonePolygon({ zones: ugc2, isUnion: false });
1318
+ geo = getZonePolygon({ zones: ugc2, isUnion: false });
1319
1319
  if (geo == null) {
1320
1320
  geo = {
1321
1321
  type: `Polygon`,
@@ -1324,7 +1324,7 @@ var getEventGeometry = (event) => __async(null, null, function* () {
1324
1324
  }
1325
1325
  }
1326
1326
  return geo;
1327
- });
1327
+ };
1328
1328
 
1329
1329
  // src/@building/building.clean.ts
1330
1330
  var getCleanedEvent = (event) => {
@@ -4180,7 +4180,8 @@ var xOnline = () => {
4180
4180
  data: {},
4181
4181
  type: `online`,
4182
4182
  error: false
4183
- }
4183
+ },
4184
+ message: `Succesfully connected to NOAA Weather Wire Service as "${nickname}"`
4184
4185
  });
4185
4186
  }));
4186
4187
  };
@@ -4502,9 +4503,9 @@ var dict_awips = {
4502
4503
  SVR: `severe-thunderstorm-warning`,
4503
4504
  SVS: `severe-weather-statement`,
4504
4505
  SWOMCD: `mesoscale-discussion`,
4505
- SWODY1: `spc-day-1-outlook`,
4506
- SWODY2: `spc-day-2-outlook`,
4507
- SWODY3: `spc-day-3-outlook`,
4506
+ SWODY1: `SPC-day-1-outlook`,
4507
+ SWODY2: `SPC-day-2-outlook`,
4508
+ SWODY3: `SPC-day-3-outlook`,
4508
4509
  SWS: `state-weather-summary`,
4509
4510
  SYN: `regional-weather-synopsis`,
4510
4511
  TAF: `terminal-aerodrome-forecast`,
@@ -4524,7 +4525,7 @@ var dict_awips = {
4524
4525
  TOE: `telephone-outage-emergency`,
4525
4526
  TOR: `tornado-warning`,
4526
4527
  TPT: `temperature-precipitation-table`,
4527
- TSU: `tsunami-watch`,
4528
+ TSU: `tsunami-information-statement`,
4528
4529
  TUV: `ultraviolet-index`,
4529
4530
  TVL: `travelers-forecast`,
4530
4531
  TWB: `transcribed-weather-broadcast`,
@@ -4620,21 +4621,39 @@ var validate = (options) => {
4620
4621
 
4621
4622
  // src/@dictionaries/dictionaries.matches.ts
4622
4623
  var dict_matches = {
4623
- "Special Weather Statement": "Special Weather Statement",
4624
- "Hurricane Warning": "Hurricane Warning",
4625
- "Hurricane Force Wind Warning": "Hurricane Force Wind Warning",
4626
- "Hurricane Watch": "Hurricane Watch",
4627
- "Tropical Storm Warning": "Tropical Storm Warning",
4628
- "Tropical Storm Watch": "Tropical Storm Watch",
4629
- "High Wind Warning": "High Wind Warning",
4630
- "Gale Warning": "Gale Warning",
4631
- "Small Craft Advisory": "Small Craft Advisory",
4632
- "Small Craft Warning": "Small Craft Warning",
4633
- "Tsunami Warning": "Tsunami Warning",
4634
- "Tsunami Watch": "Tsunami Watch",
4635
- "Tsunami Advisory": "Tsunami Advisory",
4636
- "Tsunami Information Statement": "Tsunami Information Statement",
4637
- "Subscribers:": "National Weather Service Policy"
4624
+ SPS: [
4625
+ { match: /STRONG THUNDERSTORM/i, label: "Convective Special Weather Statement", statement: false },
4626
+ { match: /SPECIAL WEATHER STATEMENT/i, label: "Special Weather Statement", statement: false }
4627
+ ],
4628
+ TSU: [
4629
+ { match: /TSUNAMI WARNING/i, label: "Tsunami Warning", statement: false },
4630
+ { match: /TSUNAMI WATCH/i, label: "Tsunami Watch", statement: false },
4631
+ { match: /TSUNAMI ADVISORY/i, label: "Tsunami Advisory", statement: false },
4632
+ { match: /TSUNAMI INFORMATION STATEMENT/i, label: "Tsunami Information Statement", statement: false },
4633
+ { match: /TSUNAMI WARNING CANCELLATION/i, label: "Tsunami Cancellation", statement: false }
4634
+ ],
4635
+ TCP: [
4636
+ { match: /HURRICANE WARNING/i, label: "Hurricane Warning", statement: false },
4637
+ { match: /HURRICANE WATCH/i, label: "Hurricane Watch", statement: false },
4638
+ { match: /TROPICAL STORM WARNING/i, label: "Tropical Storm Warning", statement: false },
4639
+ { match: /TROPICAL STORM WATCH/i, label: "Tropical Storm Watch", statement: false },
4640
+ { match: /STORM SURGE WARNING/i, label: "Storm Surge Warning", statement: false },
4641
+ { match: /STORM SURGE WATCH/i, label: "Storm Surge Watch", statement: false }
4642
+ ],
4643
+ MWW: [
4644
+ { match: /SMALL CRAFT ADVISORY/i, label: "Small Craft Advisory", statement: false },
4645
+ { match: /GALE WARNING/i, label: "Gale Warning", statement: false },
4646
+ { match: /STORM WARNING/i, label: "Storm Warning", statement: false },
4647
+ { match: /HURRICANE FORCE WIND WARNING/i, label: "Hurricane Force Wind Warning", statement: false },
4648
+ { match: /HAZARDOUS SEAS WARNING/i, label: "Hazardous Seas Warning", statement: false },
4649
+ { match: /DENSE FOG ADVISORY/i, label: "Dense Fog Advisory", statement: false },
4650
+ { match: /THUNDERSTORMS/i, label: "Convective Marine Weather Statement", statement: false },
4651
+ { match: /MARINE WEATHER STATEMENT/i, label: "Marine Weather Statement", statement: false }
4652
+ ],
4653
+ PNS: [
4654
+ { match: /NOAA WEATHER WIRE SERVICE/i, label: "NOAA Weather Wire Service Report", statement: true },
4655
+ { match: /Public Information Statement/i, label: "Public Information Statement", statement: true }
4656
+ ]
4638
4657
  };
4639
4658
 
4640
4659
  // src/@parsers/@text/text.getDescriptionFromProduct.ts
@@ -4669,18 +4688,32 @@ var getDescriptionFromProduct = (options) => {
4669
4688
  // src/@parsers/@text/text.getPolygonFromProduct.ts
4670
4689
  var getPolygonFromProduct = (message) => {
4671
4690
  const coordinates = [];
4672
- const match = message.match(/LAT\.{3}LON\s+([\d\s]+)/i);
4673
- if (!match || !match[1]) return coordinates;
4674
- const coordStrings = match[1].replace(/\n/g, " ").trim().split(/\s+/);
4675
- for (let i = 0; i < coordStrings.length - 1; i += 2) {
4676
- const lat = parseFloat(coordStrings[i]) / 100;
4677
- const lon = -parseFloat(coordStrings[i + 1]) / 100;
4678
- if (!isNaN(lat) && !isNaN(lon)) {
4679
- coordinates.push([lon, lat]);
4691
+ const match = message.match(
4692
+ /LAT\.\.\.LON\s+([\s\S]*?)(?=\n[A-Z]{2,}(?:\.\.\.|:)|\$\$|&&|$)/i
4693
+ );
4694
+ if (!match) return coordinates;
4695
+ const text2 = match[1];
4696
+ const values = text2.match(/\d{4,8}/g);
4697
+ if (!values) return coordinates;
4698
+ if (values.every((v) => v.length === 8)) {
4699
+ for (const value of values) {
4700
+ const lat = parseInt(value.slice(0, 4), 10) / 100;
4701
+ const lon = -parseInt(value.slice(4, 8), 10) / 100;
4702
+ if (Number.isFinite(lat) && Number.isFinite(lon)) {
4703
+ coordinates.push([lon, lat]);
4704
+ }
4705
+ }
4706
+ } else {
4707
+ for (let i = 0; i + 1 < values.length; i += 2) {
4708
+ const lat = parseInt(values[i], 10) / 100;
4709
+ const lon = -parseInt(values[i + 1], 10) / 100;
4710
+ if (Number.isFinite(lat) && Number.isFinite(lon)) {
4711
+ coordinates.push([lon, lat]);
4712
+ }
4680
4713
  }
4681
4714
  }
4682
4715
  if (coordinates.length > 2) {
4683
- coordinates.push(coordinates[0]);
4716
+ coordinates.push([...coordinates[0]]);
4684
4717
  }
4685
4718
  return coordinates;
4686
4719
  };
@@ -5156,7 +5189,7 @@ var setDebug = (options) => {
5156
5189
 
5157
5190
  // src/@events/events.text.ts
5158
5191
  var text = (stanza) => __async(null, null, function* () {
5159
- var _a, _b, _c;
5192
+ var _a, _b, _c, _d, _e;
5160
5193
  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 !== "$$");
5161
5194
  if (!getMessages || (getMessages == null ? void 0 : getMessages.length) == 0) return;
5162
5195
  for (const message of getMessages) {
@@ -5166,8 +5199,9 @@ var text = (stanza) => __async(null, null, function* () {
5166
5199
  const header = getEventHeader({ properties: props, getType: stanza.getType });
5167
5200
  const issued = new Date(attributes.issue);
5168
5201
  const expires = new Date(issued.getTime() + 12 * 60 * 60 * 1e3);
5169
- let event = Object.keys(dict_matches).find((event2) => message.toLowerCase().includes(event2.toLowerCase()));
5170
- let isStatement = false;
5202
+ const matches = (_d = dict_matches[stanza.getType.prefix]) == null ? void 0 : _d.find((match) => match.match.test(message.toUpperCase()));
5203
+ let event = matches == null ? void 0 : matches.label;
5204
+ let isStatement = (_e = matches == null ? void 0 : matches.statement) != null ? _e : false;
5171
5205
  if (!event) {
5172
5206
  event = stanza.getType.type.split(`-`).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(` `);
5173
5207
  isStatement = true;
@@ -5325,7 +5359,7 @@ var ugcExtract = (message) => __async(null, null, function* () {
5325
5359
 
5326
5360
  // src/@events/events.ugc.ts
5327
5361
  var ugc = (stanza) => __async(null, null, function* () {
5328
- var _a, _b, _c;
5362
+ var _a, _b, _c, _d, _e;
5329
5363
  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 !== "$$");
5330
5364
  if (!getMessages || (getMessages == null ? void 0 : getMessages.length) == 0) return;
5331
5365
  for (const message of getMessages) {
@@ -5337,8 +5371,9 @@ var ugc = (stanza) => __async(null, null, function* () {
5337
5371
  const issued = new Date(attributes.issue);
5338
5372
  const expires = new Date(ugc2.expires);
5339
5373
  const header = getEventHeader({ properties: props, getType: stanza.getType });
5340
- let event = Object.keys(dict_matches).find((event2) => message.toLowerCase().includes(event2.toLowerCase()));
5341
- let isStatement = false;
5374
+ const matches = (_d = dict_matches[stanza.getType.prefix]) == null ? void 0 : _d.find((match) => match.match.test(message.toUpperCase()));
5375
+ let event = matches == null ? void 0 : matches.label;
5376
+ let isStatement = (_e = matches == null ? void 0 : matches.statement) != null ? _e : false;
5342
5377
  if (!event) {
5343
5378
  event = stanza.getType.type.split(`-`).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(` `);
5344
5379
  isStatement = true;
@@ -5715,85 +5750,42 @@ var api = (stanza) => __async(null, null, function* () {
5715
5750
  // src/@dictionaries/dictionaries.enhanced.ts
5716
5751
  var dict_enhanced = {
5717
5752
  "Tornado Warning": {
5718
- "Tornado Emergency": {
5719
- description: "tornado emergency"
5720
- },
5721
- "PDS Tornado Warning": {
5722
- description: "particularly dangerous situation",
5723
- damage: `CONSIDERABLE`
5724
- },
5725
- "Radar Confirmed Tornado Warning": {
5726
- description: "source...radar confirmed tornado.",
5727
- tornado: `OBSERVED`
5728
- },
5729
- "Confirmed Tornado Warning": {
5730
- tornado: `OBSERVED`
5731
- },
5753
+ "Tornado Emergency": { description: "tornado emergency" },
5754
+ "PDS Tornado Warning": { description: "particularly dangerous situation", damage: `CONSIDERABLE` },
5755
+ "Radar Confirmed Tornado Warning": { description: "source...radar confirmed tornado.", tornado: `OBSERVED` },
5756
+ "Confirmed Tornado Warning": { tornado: `OBSERVED` },
5732
5757
  "Radar Indicated Tornado Warning": {}
5733
5758
  },
5734
5759
  "Fire Weather Warning": {
5735
- "PDS Fire Weather Warning": {
5736
- description: "particularly dangerous situation"
5737
- }
5760
+ "PDS Fire Weather Warning": { description: "particularly dangerous situation" }
5738
5761
  },
5739
5762
  "Blizzard Warning": {
5740
- "PDS Blizzard Warning": {
5741
- description: "particularly dangerous situation"
5742
- }
5763
+ "PDS Blizzard Warning": { description: "particularly dangerous situation" }
5743
5764
  },
5744
5765
  "Ice Storm Warning": {
5745
- "PDS Ice Storm Warning": {
5746
- description: "particularly dangerous situation"
5747
- }
5766
+ "PDS Ice Storm Warning": { description: "particularly dangerous situation" }
5748
5767
  },
5749
5768
  "Special Marine Warning": {
5750
- "Special Marine Warning (TPROB)": {
5751
- tornado: `POSSIBLE`
5752
- }
5769
+ "Special Marine Warning (TPROB)": { tornado: `POSSIBLE` }
5753
5770
  },
5754
5771
  "Tornado Watch": {
5755
- "PDS Tornado Watch": {
5756
- pdswatch: true
5757
- }
5772
+ "PDS Tornado Watch": { pdswatch: true }
5758
5773
  },
5759
5774
  "Severe Thunderstorm Watch": {
5760
- "PDS Severe Thunderstorm Watch": {
5761
- pdswatch: true
5762
- }
5775
+ "PDS Severe Thunderstorm Watch": { pdswatch: true }
5763
5776
  },
5764
5777
  "Flash Flood Warning": {
5765
- "Flash Flood Emergency": {
5766
- description: "flash flood emergency"
5767
- },
5768
- "Considerable Flash Flood Warning": {
5769
- damage: `CONSIDERABLE`
5770
- }
5778
+ "Flash Flood Emergency": { description: "flash flood emergency" },
5779
+ "Considerable Flash Flood Warning": { damage: `CONSIDERABLE` }
5771
5780
  },
5772
5781
  "Severe Thunderstorm Warning": {
5773
- "EDS Severe Thunderstorm Warning (TPROB)": {
5774
- description: "extremely dangerous situation",
5775
- tornado: "POSSIBLE"
5776
- },
5777
- "EDS Severe Thunderstorm Warning": {
5778
- description: "extremely dangerous situation"
5779
- },
5780
- "Destructive Severe Thunderstorm Warning (TPROB)": {
5781
- damage: `DESTRUCTIVE`,
5782
- tornado: `POSSIBLE`
5783
- },
5784
- "Destructive Severe Thunderstorm Warning": {
5785
- damage: `DESTRUCTIVE`
5786
- },
5787
- "Considerable Severe Thunderstorm Warning (TPROB)": {
5788
- damage: `CONSIDERABLE`,
5789
- tornado: `POSSIBLE`
5790
- },
5791
- "Considerable Severe Thunderstorm Warning": {
5792
- damage: `CONSIDERABLE`
5793
- },
5794
- "Severe Thunderstorm Warning (TPROB)": {
5795
- tornado: `POSSIBLE`
5796
- }
5782
+ "EDS Severe Thunderstorm Warning (TPROB)": { description: "extremely dangerous situation", tornado: "POSSIBLE" },
5783
+ "EDS Severe Thunderstorm Warning": { description: "extremely dangerous situation" },
5784
+ "Destructive Severe Thunderstorm Warning (TPROB)": { damage: `DESTRUCTIVE`, tornado: `POSSIBLE` },
5785
+ "Destructive Severe Thunderstorm Warning": { damage: `DESTRUCTIVE` },
5786
+ "Considerable Severe Thunderstorm Warning (TPROB)": { damage: `CONSIDERABLE`, tornado: `POSSIBLE` },
5787
+ "Considerable Severe Thunderstorm Warning": { damage: `CONSIDERABLE` },
5788
+ "Severe Thunderstorm Warning (TPROB)": { tornado: `POSSIBLE` }
5797
5789
  }
5798
5790
  };
5799
5791
 
@@ -5924,6 +5916,13 @@ var getEventSignature = (event) => {
5924
5916
  return event;
5925
5917
  };
5926
5918
 
5919
+ // src/@dictionaries/dictionaries.global.ts
5920
+ var dict_global = [
5921
+ "spc day 1 outlook",
5922
+ "spc day 2 outlook",
5923
+ "spc day 3 outlook"
5924
+ ];
5925
+
5927
5926
  // src/@manager/manager.setHash.ts
5928
5927
  var setHash = (event, entry) => {
5929
5928
  if (entry) {
@@ -6784,7 +6783,7 @@ var mkEvent = (event) => __async(null, null, function* () {
6784
6783
  if (isHashed || event.properties.status_metadata.is_expired) return;
6785
6784
  setHash(event, isEntry);
6786
6785
  const isFilteredLocation = yield updateNode(event).then(() => event.properties.metadata.filtered_proximity);
6787
- if (!isFilteredLocation && settings.GlobalSettings.EventFiltering.NodeLocationFiltering) {
6786
+ if (!isFilteredLocation && !dict_global.includes(event.properties.event.toLowerCase()) && settings.GlobalSettings.EventFiltering.NodeLocationFiltering) {
6788
6787
  return;
6789
6788
  }
6790
6789
  const isRatelimited = setTimeoutAction({ identifier: getTracking, interval: 1, max: 1, addTime: true });
@@ -6842,15 +6841,17 @@ var rmEvent = (event) => __async(null, null, function* () {
6842
6841
  event.properties.status = `Expired`;
6843
6842
  event.properties.status_metadata.is_expired = true;
6844
6843
  if (getEvent) {
6845
- setEventEmit({
6846
- event: `onEventStatus`,
6847
- metadata: {
6848
- type: `Removed`,
6849
- event
6850
- },
6851
- message: `[Removed] ${event.properties.event} (${event.properties.status}) (${event.properties.metadata.tracking})`
6852
- });
6853
- setEventEmit({ event: `onExpiredProduct`, metadata: event });
6844
+ if (!event.properties.status_metadata.is_statement) {
6845
+ setEventEmit({
6846
+ event: `onEventStatus`,
6847
+ metadata: {
6848
+ type: `Removed`,
6849
+ event
6850
+ },
6851
+ message: `[Removed] ${event.properties.event} (${event.properties.status}) (${event.properties.metadata.tracking})`
6852
+ });
6853
+ setEventEmit({ event: `onExpiredProduct`, metadata: event });
6854
+ }
6854
6855
  if (cachedStatus != `Statement`) yield updateListener(event);
6855
6856
  bootstrap.cache.events.features.splice(bootstrap.cache.events.features.indexOf(getEvent), 1);
6856
6857
  bootstrap.cache.hashes = bootstrap.cache.hashes.filter((hash) => hash.tracking !== event.properties.metadata.tracking);
@@ -6951,7 +6952,7 @@ var getEventAttachments = (event) => {
6951
6952
  { target: "PDS Severe Thunderstorm Watch", attachment: `https://www.spc.noaa.gov/products/watch/ww${watchNumber}_radar_big.gif` }
6952
6953
  ];
6953
6954
  if (events.find((e) => e.target === event.properties.event)) {
6954
- attachments.push({ name: `Image: Graphic`, link: events.find((e) => e.target === event.properties.event).attachment });
6955
+ attachments.push({ name: `Image: Graphic`, link: events.find((e) => e.target.toLowerCase() === event.properties.event.toLowerCase()).attachment });
6955
6956
  }
6956
6957
  for (const location of locations) {
6957
6958
  if (dict_expressions.location.test(location)) {
@@ -6981,7 +6982,6 @@ var getEventAttachments = (event) => {
6981
6982
  // src/@building/building.validate.ts
6982
6983
  import { createHash } from "crypto";
6983
6984
  var validateEvents = (events) => __async(null, null, function* () {
6984
- var _a;
6985
6985
  const tick = performance.now();
6986
6986
  if (events.length === 0) return;
6987
6987
  const configurations = bootstrap.settings;
@@ -6997,39 +6997,28 @@ var validateEvents = (events) => __async(null, null, function* () {
6997
6997
  bools[key] = setting;
6998
6998
  }
6999
6999
  }
7000
- const filterd = events.filter((event) => {
7001
- var _a2, _b, _c, _d, _e;
7002
- bootstrap.cache.processed = bootstrap.cache.processed.filter((e) => e !== event);
7003
- const define2 = getEventSignature(event);
7000
+ const isFiltered = (define2) => {
7001
+ var _a, _b, _c, _d;
7004
7002
  const properties2 = define2.properties;
7005
7003
  const zones = properties2.geocode.ugc;
7006
7004
  const icao = properties2.geocode.office.office;
7007
- const enhancedEventName = properties2.event = getEventEnhancedName(event);
7008
- const filteredProperties = JSON.parse(JSON.stringify(properties2));
7009
- if ((filteredProperties == null ? void 0 : filteredProperties.metadata) && "ms" in filteredProperties.metadata) {
7010
- delete filteredProperties.metadata.ms;
7011
- }
7012
- filteredProperties.metadata = (_a2 = filteredProperties.metadata) != null ? _a2 : {};
7013
- properties2.metadata.hash = createHash("sha256").update(JSON.stringify(filteredProperties)).digest("hex");
7014
- properties2.metadata.attachments = getEventAttachments(event);
7015
- setEventEmit({ event: `onProductType${enhancedEventName.replace(/\s+/g, "")}`, metadata: define2 });
7016
7005
  if (properties2.status_metadata.is_test) {
7017
7006
  setEventEmit({ event: `onTestProduct`, metadata: define2 });
7018
- if (bools == null ? void 0 : bools.IgnoreTestProducts) return false;
7007
+ if (bools == null ? void 0 : bools.IgnoreTestProducts) return true;
7019
7008
  }
7020
7009
  if (properties2.status_metadata.is_expired) {
7021
7010
  setEventEmit({ event: `onExpiredProduct`, metadata: define2 });
7022
7011
  rmEvent(define2);
7023
- return false;
7012
+ return true;
7024
7013
  }
7025
- if (((_c = (_b = properties2.metadata) == null ? void 0 : _b.vtec) == null ? void 0 : _c.is_watch) && properties2.metadata.source != `events.api`) {
7026
- const isSPC = (_e = (_d = properties2.metadata) == null ? void 0 : _d.vtec) == null ? void 0 : _e.prediction_center;
7014
+ if (((_b = (_a = properties2.metadata) == null ? void 0 : _a.vtec) == null ? void 0 : _b.is_watch) && properties2.metadata.source != `events.api`) {
7015
+ const isSPC = (_d = (_c = properties2.metadata) == null ? void 0 : _c.vtec) == null ? void 0 : _d.prediction_center;
7027
7016
  setEventEmit({ event: isSPC ? `onStormPredictionWatch` : `onNonStormPredictionWatch`, metadata: define2 });
7028
7017
  if ((bools == null ? void 0 : bools.SPCWatchesOnly) && !isSPC) {
7029
- return false;
7018
+ return true;
7030
7019
  }
7031
7020
  if (!(bools == null ? void 0 : bools.SPCWatchesOnly) && isSPC) {
7032
- return false;
7021
+ return true;
7033
7022
  }
7034
7023
  }
7035
7024
  for (const key in sets) {
@@ -7040,53 +7029,64 @@ var validateEvents = (events) => __async(null, null, function* () {
7040
7029
  event: `onFilteredEvent`,
7041
7030
  metadata: define2
7042
7031
  });
7043
- return false;
7032
+ return true;
7044
7033
  }
7045
7034
  if (key === "IgnoredEvents" && setting.size > 0 && getMatched(values, define2.properties.event)) {
7046
7035
  setEventEmit({
7047
7036
  event: `onIgnoredEvent`,
7048
7037
  metadata: define2
7049
7038
  });
7050
- return false;
7039
+ return true;
7051
7040
  }
7052
7041
  if (key === "ListeningICAO" && setting.size > 0 && icao != null && !setting.has(icao.toLowerCase())) {
7053
7042
  setEventEmit({
7054
7043
  event: `onFilteredICAO`,
7055
7044
  metadata: define2
7056
7045
  });
7057
- return false;
7046
+ return true;
7058
7047
  }
7059
7048
  if (key === "IgnoredICAO" && setting.size > 0 && icao != null && setting.has(icao.toLowerCase())) {
7060
7049
  setEventEmit({
7061
7050
  event: `onIgnoredICAO`,
7062
7051
  metadata: define2
7063
7052
  });
7064
- return false;
7053
+ return true;
7065
7054
  }
7066
7055
  if (key === "ListeningUGC" && setting.size > 0 && zones.length > 0 && !zones.some((ugc2) => setting.has(ugc2.toLowerCase()))) {
7067
7056
  setEventEmit({
7068
7057
  event: `onFilteredUGC`,
7069
7058
  metadata: define2
7070
7059
  });
7071
- return false;
7060
+ return true;
7072
7061
  }
7073
7062
  if (key === "ListeningStates" && setting.size > 0 && zones.length > 0 && !zones.some((ugc2) => setting.has(ugc2.substring(0, 2).toLowerCase()))) {
7074
7063
  setEventEmit({
7075
7064
  event: `onFilteredState`,
7076
7065
  metadata: define2
7077
7066
  });
7078
- return false;
7067
+ return true;
7079
7068
  }
7080
7069
  }
7081
- return true;
7070
+ return false;
7071
+ };
7072
+ const filtering = events.filter((event) => {
7073
+ var _a;
7074
+ bootstrap.cache.processed = bootstrap.cache.processed.filter((e) => e !== event);
7075
+ const define2 = getEventSignature(event);
7076
+ const properties2 = define2.properties;
7077
+ (_a = properties2 == null ? void 0 : properties2.metadata) == null ? true : delete _a.ms;
7078
+ const enhanced = properties2.event = getEventEnhancedName(event);
7079
+ const filtered = isFiltered(define2);
7080
+ if (!filtered) {
7081
+ event.geometry = !(bools == null ? void 0 : bools.DisableGeometryParsing) ? getEventGeometry(event) : null;
7082
+ properties2.metadata.attachments = getEventAttachments(event);
7083
+ }
7084
+ properties2.metadata.hash = createHash("sha256").update(JSON.stringify(properties2)).digest("hex");
7085
+ setEventEmit({ event: `onProductType${enhanced.replace(/\s+/g, "")}`, metadata: define2 });
7086
+ return !filtered;
7082
7087
  });
7083
- if (!((_a = configurations == null ? void 0 : configurations.GlobalSettings) == null ? void 0 : _a.DisableGeometryParsing)) {
7084
- for (const event of filterd) {
7085
- event.geometry = yield getEventGeometry(event);
7086
- }
7087
- }
7088
- if (filterd.length > 0) {
7089
- for (const event of filterd) {
7088
+ if (filtering.length > 0) {
7089
+ for (const event of filtering) {
7090
7090
  yield mkEvent(event);
7091
7091
  }
7092
7092
  }
@@ -7096,7 +7096,7 @@ var validateEvents = (events) => __async(null, null, function* () {
7096
7096
  metadata: bootstrap.cache.events,
7097
7097
  limited: true
7098
7098
  });
7099
- setDebug({ title: `@building.validate`, message: `Filtered ${filterd.length} events which took ${performance.now() - tick} ms` });
7099
+ setDebug({ title: `@building.validate`, message: `Filtered ${filtering.length} events which took ${performance.now() - tick} ms` });
7100
7100
  });
7101
7101
 
7102
7102
  // src/@building/building.create.ts
@@ -7646,59 +7646,16 @@ var getNodes = () => {
7646
7646
  return bootstrap.cache.nodes;
7647
7647
  };
7648
7648
 
7649
- // src/@core/core.createEvent.ts
7650
- var createEvent2 = (options) => {
7651
- var _a;
7652
- const tick = performance.now();
7653
- validateEvents([{
7654
- type: `Feature`,
7655
- geometry: {
7656
- type: `Point`,
7657
- coordinates: options.coordinates
7658
- },
7659
- properties: {
7660
- event: options.event,
7661
- parent: options.event,
7662
- status: options.status,
7663
- issued: options.issued.toISOString(),
7664
- expires: options.expires.toISOString(),
7665
- locations: options.locations,
7666
- locations_array: options.locations ? options.locations.split(";") : [],
7667
- description: options.description,
7668
- geocode: {
7669
- office: {
7670
- office: `ATMX`,
7671
- name: `AtmosphericX Manual Event`
7672
- },
7673
- organization: `AtmosphericX`,
7674
- ugc: [],
7675
- polygon: options.coordinates.length > 0 ? Buffer.from(JSON.stringify([options.coordinates[0]])).toString("base64") : null,
7676
- polygon_generated: options.coordinates.length > 0 ? true : false
7677
- },
7678
- status_metadata: {
7679
- is_issued: options.status == `Issued`,
7680
- is_updated: options.status == `Updated`,
7681
- is_expired: options.status == `Expired`,
7682
- is_test: options.status == `Test`,
7683
- is_statement: options.status == `Statement`
7684
- },
7685
- metadata: {
7686
- ms: performance.now() - tick,
7687
- source: `events.manual`,
7688
- tracking: `ATMX-M-W-01`,
7689
- header: `ZCZC-ATMOSX-ATMX-M-W-01`,
7690
- raw: options.description,
7691
- history: [
7692
- {
7693
- description: options.description,
7694
- issued: options.issued.toISOString(),
7695
- status: (_a = options.status) != null ? _a : null
7696
- }
7697
- ]
7698
- }
7699
- }
7700
- }]);
7701
- };
7649
+ // src/@core/core.manualEvent.ts
7650
+ var manualEvent = (options) => __async(null, null, function* () {
7651
+ const isCapEvent = options.message.includes(`<?xml`);
7652
+ const isCapAreaDescription = options.message.includes(`<areaDesc>`);
7653
+ const isVTEC = options.message.match(dict_expressions.pvtec) != null;
7654
+ const isUGC = options.message.match(dict_expressions.ugc1) != null;
7655
+ const getType = getAwipsType({ attributes: options.attributes });
7656
+ const result = { message: options.message, attributes: options.attributes, isCapEvent, isVTEC, isUGC, isCapAreaDescription, isIgnored: false, isNWWS: true, getType };
7657
+ yield createEvent(result);
7658
+ });
7702
7659
 
7703
7660
  // src/@core/core.getRandomEvent.ts
7704
7661
  var getRandomEvent = () => {
@@ -7759,13 +7716,13 @@ var index_default = Manager;
7759
7716
  export {
7760
7717
  Manager,
7761
7718
  clearEvents,
7762
- createEvent2 as createEvent,
7763
7719
  index_default as default,
7764
7720
  getCleanedEvent,
7765
7721
  getEventGeometry,
7766
7722
  getEvents,
7767
7723
  getNodes,
7768
7724
  getRandomEvent,
7725
+ manualEvent,
7769
7726
  query,
7770
7727
  setEasTone,
7771
7728
  setNode,