@atmosx/event-product-parser 3.0.1 → 3.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -56,6 +56,7 @@ const Client = new Manager({
56
56
  webhook: "https://discord.com/api/webhooks/XXXXXXXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
57
57
  title: "AtmosphericX - (@atmosx/event-product-parser)",
58
58
  message: ``,
59
+ upload: true,
59
60
  events: [`Severe Thunderstorm Warning`, `Radar Indicated Tornado Warning`, `*Warning`, `*Thunderstorm*`],
60
61
  rate: 5,
61
62
  }
@@ -66,6 +67,7 @@ const Client = new Manager({
66
67
  DisableGeometryParsing: false,
67
68
  UseShapefileCoordinates: true,
68
69
  SPCWatchesOnly: true,
70
+ ShapefileSkipPoints: 0,
69
71
  NodeTTL: 60,
70
72
  NodeMinDistance: 120,
71
73
  EventFiltering: {
@@ -123,6 +125,7 @@ const Client = new Manager({
123
125
  - **webhook**: The URL of the webhook you want to send messages to.
124
126
  - **title**: The title of the message you want to send.
125
127
  - **message**: The message content you want to send. You can use placeholders like `<@&role_id>` to mention roles in Discord.
128
+ - **upload**: Whether to upload a JSON file as well with the message containing the event data.
126
129
  - **events**: An array of event types that will trigger the webhook when they are received by the parser. If this array is empty, the webhook will be triggered for all events.
127
130
  - **rate**: The rate limit in seconds for how often the webhook can be triggered. This is to prevent spamming the webhook with too many messages in a short period of time.
128
131
 
@@ -132,6 +135,7 @@ const Client = new Manager({
132
135
  - **DisableGeometryParsing**: Disable automatically appending GeoJSON geometry data to the events to save on memory consumption.
133
136
  - **UseShapefileCoordinates**: Whether to use the shapefile database to obtain the coordinates for events with specified UGC zones.
134
137
  - **SPCWatchesOnly**: Whether to only listen for SPC watches only (TOR/SVR) (If using the API, this is ignored).
138
+ - **ShapefileSkipPoints**: When using the shapefile database to obtain coordinates, you can choose to skip a certain amount of points to reduce the number of coordinates for large events. (Ex. If an event has 1000 coordinates and you set this to `2`, it will only use every other coordinate, therefore using 500 coordinates instead of 1000).
135
139
  - **NodeTTL**: How often nodes should be checked per event. (Tracking/Filtering)
136
140
  - **NodeMinDistance**: The minimum distance to filter events from the node (Miles)
137
141
  - **ListeningEvents**: Events you'd like to listen for. If this array is left empty, it will listen for **ALL** events and products.
@@ -290,6 +294,12 @@ const events = getEvents() // Returns in GeoJSON (Similar to the onEventCache li
290
294
  console.log(events)
291
295
  ```
292
296
 
297
+ ### Function `clearEvents`
298
+ Clears the event cache of all events.
299
+ ```ts
300
+ import { clearEvents } from "@atmosx/event-product-parser"
301
+ clearEvents() // Clears the event cache of all events.
302
+ ```
293
303
 
294
304
  ### Function `getNodes`
295
305
  Fetches the list of tracking nodes from the parser.
@@ -10490,6 +10490,7 @@ var require_form_data = __commonJS({
10490
10490
  var index_exports = {};
10491
10491
  __export(index_exports, {
10492
10492
  Manager: () => Manager,
10493
+ clearEvents: () => clearEvents,
10493
10494
  default: () => index_default,
10494
10495
  getCleanedEvent: () => getCleanedEvent,
10495
10496
  getEventGeometry: () => getEventGeometry,
@@ -10508,7 +10509,7 @@ module.exports = __toCommonJS(index_exports);
10508
10509
  var import_path = __toESM(require("path"));
10509
10510
  var import_node_events = require("events");
10510
10511
  var bootstrap = {
10511
- version: `3.0.1`,
10512
+ version: `3.0.3`,
10512
10513
  isReady: true,
10513
10514
  ratelimits: {},
10514
10515
  session_xmpp: null,
@@ -10790,8 +10791,8 @@ var setListener = (options) => {
10790
10791
  };
10791
10792
  };
10792
10793
 
10793
- // src/@core/core.listener.ts
10794
- var listener = (event, callback) => {
10794
+ // src/@core/core.createListener.ts
10795
+ var createListener = (event, callback) => {
10795
10796
  setListener({ event, callback });
10796
10797
  };
10797
10798
 
@@ -10901,14 +10902,14 @@ function Deferred() {
10901
10902
  function procedure(entity, stanza = null, handler) {
10902
10903
  return new Promise((resolve6, reject) => {
10903
10904
  function onError(err) {
10904
- entity.removeListener("nonza", listener3);
10905
+ entity.removeListener("nonza", listener2);
10905
10906
  reject(err);
10906
10907
  }
10907
10908
  function done(...args) {
10908
- entity.removeListener("nonza", listener3);
10909
+ entity.removeListener("nonza", listener2);
10909
10910
  resolve6(...args);
10910
10911
  }
10911
- function listener3(element) {
10912
+ function listener2(element) {
10912
10913
  return __async(this, null, function* () {
10913
10914
  try {
10914
10915
  yield handler(element, done);
@@ -10918,7 +10919,7 @@ function procedure(entity, stanza = null, handler) {
10918
10919
  });
10919
10920
  }
10920
10921
  stanza && entity.send(stanza).catch(onError);
10921
- entity.on("nonza", listener3);
10922
+ entity.on("nonza", listener2);
10922
10923
  });
10923
10924
  }
10924
10925
 
@@ -12062,7 +12063,7 @@ var OutgoingContext = class extends Context {
12062
12063
  };
12063
12064
 
12064
12065
  // node_modules/@xmpp/middleware/index.js
12065
- function listener2(entity, middleware2, Context2) {
12066
+ function listener(entity, middleware2, Context2) {
12066
12067
  return (stanza) => {
12067
12068
  const ctx = new Context2(entity, stanza);
12068
12069
  return (0, import_koa_compose.default)(middleware2)(ctx);
@@ -12076,8 +12077,8 @@ function errorHandler(entity) {
12076
12077
  function middleware({ entity }) {
12077
12078
  const incoming = [errorHandler(entity)];
12078
12079
  const outgoing = [];
12079
- const incomingListener = listener2(entity, incoming, IncomingContext);
12080
- const outgoingListener = listener2(entity, outgoing, OutgoingContext);
12080
+ const incomingListener = listener(entity, incoming, IncomingContext);
12081
+ const outgoingListener = listener(entity, outgoing, OutgoingContext);
12081
12082
  entity.on("element", incomingListener);
12082
12083
  entity.on("send", outgoingListener);
12083
12084
  return {
@@ -14387,7 +14388,16 @@ var eventTags = {
14387
14388
  "SLOW DOWN AND ALLOW EXTRA TIME": "Slow Down and Allow Extra Time",
14388
14389
  "SHOULD EXERCISE CAUTION": "Should Exercise Caution",
14389
14390
  "LAKE EFFECT SNOW EXPECTED": "Lake Effect Snow Expected",
14390
- "MODERATE LAKE EFFECT SNOWFALL RATES AND BLOWING SNOW": "Moderate Lake Effect Snowfall and Blowing Snow"
14391
+ "MODERATE LAKE EFFECT SNOWFALL RATES AND BLOWING SNOW": "Moderate Lake Effect Snowfall and Blowing Snow",
14392
+ "NO TSUNAMI THREAT": "No Active Tsunami Threat",
14393
+ "NO SIGNIFICANT TSUNAMI THREAT": "No Significant Tsunami Threat",
14394
+ "NO TSUNAMI IMPACTS ARE EXPECTED": "No Tsunami Impacts Expected",
14395
+ "A TSUNAMI THREAT EXISTS": "Tsunami Threat Exists",
14396
+ "TSUNAMI THREAT": "Active Tsunami Threat",
14397
+ "HEAT ILLNESSES": "Can cause heat illness",
14398
+ "WATCH POSSIBLE": "Watch Possible",
14399
+ "INTENSIFYING": "Intensifying",
14400
+ "CAPABLE OF PRODUCING A LANDSPOUT": "Landspout Possible"
14391
14401
  };
14392
14402
 
14393
14403
  // src/@building/building.tags.ts
@@ -14457,8 +14467,8 @@ var getEventHeader = (options) => {
14457
14467
  return `ZCZC-ATMOSX-${options.getType.prefix}-${ugc2}-${(_b = vtec2 == null ? void 0 : vtec2.status) != null ? _b : `Issued`}-${(/* @__PURE__ */ new Date()).toISOString().replace(/[-:]/g, "").split(".")[0]}-${(_c = properties2.geocode.office.office) != null ? _c : `KWNS`}`;
14458
14468
  };
14459
14469
 
14460
- // src/@dictionaries/dictionaries.eventsOffshore.ts
14461
- var eventsOffshore = {
14470
+ // src/@dictionaries/dictionaries.eventsMatchText.ts
14471
+ var eventsMatchText = {
14462
14472
  "Special Weather Statement": "Special Weather Statement",
14463
14473
  "Hurricane Warning": "Hurricane Warning",
14464
14474
  "Hurricane Force Wind Warning": "Hurricane Force Wind Warning",
@@ -14468,7 +14478,12 @@ var eventsOffshore = {
14468
14478
  "High Wind Warning": "High Wind Warning",
14469
14479
  "Gale Warning": "Gale Warning",
14470
14480
  "Small Craft Advisory": "Small Craft Advisory",
14471
- "Small Craft Warning": "Small Craft Warning"
14481
+ "Small Craft Warning": "Small Craft Warning",
14482
+ "Tsunami Warning": "Tsunami Warning",
14483
+ "Tsunami Watch": "Tsunami Watch",
14484
+ "Tsunami Advisory": "Tsunami Advisory",
14485
+ "Tsunami Information Statement": "Tsunami Information Statement",
14486
+ "Subscribers:": "National Weather Service Policy"
14472
14487
  };
14473
14488
 
14474
14489
  // src/@building/building.tracking.ts
@@ -14527,6 +14542,16 @@ var betterEventNames = {
14527
14542
  },
14528
14543
  "Radar Indicated Tornado Warning": {}
14529
14544
  },
14545
+ "Blizzard Warning": {
14546
+ "PDS Blizzard Warning": {
14547
+ description: "particularly dangerous situation"
14548
+ }
14549
+ },
14550
+ "Ice Storm Warning": {
14551
+ "PDS Ice Storm Warning": {
14552
+ description: "particularly dangerous situation"
14553
+ }
14554
+ },
14530
14555
  "Special Marine Warning": {
14531
14556
  "Special Marine Warning (TPROB)": {
14532
14557
  tornado: `POSSIBLE`
@@ -14608,17 +14633,18 @@ var getEventEnhancedName = (event) => {
14608
14633
 
14609
14634
  // src/@dictionaries/dictionaries.statusCorrelationText.ts
14610
14635
  var statusCorrelationText = [
14611
- { type: "Update", name: "Updated", isCancel: false, isUpdate: true, isIssued: false },
14612
- { type: "Cancel", name: "Cancelled", isCancel: true, isUpdate: false, isIssued: false },
14613
- { type: "Alert", name: "Issued", isCancel: false, isUpdate: false, isIssued: true },
14614
- { type: "Updated", name: "Updated", isCancel: false, isUpdate: true, isIssued: false },
14615
- { type: "Expired", name: "Expired", isCancel: true, isUpdate: false, isIssued: false },
14616
- { type: "Issued", name: "Issued", isCancel: false, isUpdate: false, isIssued: true },
14617
- { type: "Extended", name: "Extended", isCancel: false, isUpdate: true, isIssued: false },
14618
- { type: "Correction", name: "Correction", isCancel: false, isUpdate: true, isIssued: false },
14619
- { type: "Upgraded", name: "Upgraded", isCancel: false, isUpdate: true, isIssued: false },
14620
- { type: "Cancelled", name: "Cancelled", isCancel: true, isUpdate: false, isIssued: false },
14621
- { type: "Routine", name: "Routine", isCancel: false, isUpdate: true, isIssued: false }
14636
+ { type: "Statement", name: "Statement", isCancel: false, isUpdate: false, isIssued: true, isStatement: true },
14637
+ { type: "Update", name: "Updated", isCancel: false, isUpdate: true, isIssued: false, isStatement: false },
14638
+ { type: "Cancel", name: "Cancelled", isCancel: true, isUpdate: false, isIssued: false, isStatement: false },
14639
+ { type: "Alert", name: "Issued", isCancel: false, isUpdate: false, isIssued: true, isStatement: false },
14640
+ { type: "Updated", name: "Updated", isCancel: false, isUpdate: true, isIssued: false, isStatement: false },
14641
+ { type: "Expired", name: "Expired", isCancel: true, isUpdate: false, isIssued: false, isStatement: false },
14642
+ { type: "Issued", name: "Issued", isCancel: false, isUpdate: false, isIssued: true, isStatement: false },
14643
+ { type: "Extended", name: "Extended", isCancel: false, isUpdate: true, isIssued: false, isStatement: false },
14644
+ { type: "Correction", name: "Correction", isCancel: false, isUpdate: true, isIssued: false, isStatement: false },
14645
+ { type: "Upgraded", name: "Upgraded", isCancel: false, isUpdate: true, isIssued: false, isStatement: false },
14646
+ { type: "Cancelled", name: "Cancelled", isCancel: true, isUpdate: false, isIssued: false, isStatement: false },
14647
+ { type: "Routine", name: "Routine", isCancel: false, isUpdate: true, isIssued: false, isStatement: false }
14622
14648
  ];
14623
14649
 
14624
14650
  // src/@dictionaries/dictionaries.eventCancelMessages.ts
@@ -14678,7 +14704,7 @@ var getEventSignature = (event) => {
14678
14704
  }
14679
14705
  if (status) {
14680
14706
  properties2.status = (_d = status.name) != null ? _d : properties2.status;
14681
- properties2.status_metadata = __spreadProps(__spreadValues({}, properties2.status_metadata), { is_updated: !!status.isUpdate, is_issued: !!status.isIssued, is_expired: !!status.isCancel });
14707
+ properties2.status_metadata = __spreadProps(__spreadValues({}, properties2.status_metadata), { is_updated: !!status.isUpdate, is_issued: !!status.isIssued, is_expired: !!status.isCancel, is_statement: !!status.isStatement });
14682
14708
  }
14683
14709
  if (csig) {
14684
14710
  properties2.status_metadata = __spreadProps(__spreadValues({}, properties2.status_metadata), { is_expired: true });
@@ -14773,13 +14799,13 @@ var createHttp = (options) => __async(null, null, function* () {
14773
14799
  // src/@modules/@utilities/utilities.createWebhook.ts
14774
14800
  var import_form_data = __toESM(require_form_data());
14775
14801
  var createWebhook = (options) => __async(null, null, function* () {
14776
- var _a, _b, _c, _d, _e, _f, _g, _h;
14802
+ var _a, _b, _c, _d;
14777
14803
  const event = options.event.properties;
14778
14804
  const settings = options.webhook;
14779
14805
  let body = [
14780
14806
  event.locations ? `**Locations**: ${event.locations.slice(0, 100)}` : null,
14781
14807
  event.issued ? `**Issued**: <t:${Math.floor(new Date(event.issued).getTime() / 1e3)}:R>` : null,
14782
- event.expires ? `**Expires**: <t:${Math.floor(new Date(event.expires).getTime() / 1e3)}:R>` : null,
14808
+ event.expires && event.status != `Statement` ? `**Expires**: <t:${Math.floor(new Date(event.expires).getTime() / 1e3)}:R>` : null,
14783
14809
  (() => {
14784
14810
  var _a2, _b2;
14785
14811
  const val = (_a2 = event.parameters.estimated_wind_gusts) != null ? _a2 : null;
@@ -14796,16 +14822,28 @@ var createWebhook = (options) => __async(null, null, function* () {
14796
14822
  event.parameters.damage_threat ? `**Damage Threat**: ${event.parameters.damage_threat}` : null,
14797
14823
  event.parameters.flood_threat ? `**Flood Threat**: ${event.parameters.flood_threat}` : null,
14798
14824
  event.parameters.tornado_threat ? `**Tornado Threat**: ${event.parameters.tornado_threat}` : null,
14825
+ event.spc_parameters.spc_max_tornado ? `**Max Tornado Threat**: ${event.spc_parameters.spc_max_tornado}` : null,
14826
+ event.spc_parameters.spc_max_hail ? `**Max Hail Threat**: ${event.spc_parameters.spc_max_hail}` : null,
14827
+ event.spc_parameters.spc_max_wind ? `**Max Wind Threat**: ${event.spc_parameters.spc_max_wind}` : null,
14828
+ event.spc_parameters.spc_watch_issuance ? `**Watch Issuance**: ${event.spc_parameters.spc_watch_issuance}%` : null,
14829
+ event.watch_parameters.watch_number ? `**Watch Number**: ${event.watch_parameters.watch_number}` : null,
14830
+ event.watch_parameters.strong_tornadoes_probability ? `**Strong Tornadoes Probability**: ${event.watch_parameters.strong_tornadoes_probability}%` : null,
14831
+ event.watch_parameters.additional_tornadoes_probability ? `**Additional Tornadoes Probability**: ${event.watch_parameters.additional_tornadoes_probability}%` : null,
14832
+ event.watch_parameters.combined_hail_wind_probability ? `**Combined Hail/Wind Probability**: ${event.watch_parameters.combined_hail_wind_probability}%` : null,
14833
+ event.watch_parameters.severe_hail_probability ? `**Severe Hail Probability**: ${event.watch_parameters.severe_hail_probability}%` : null,
14834
+ event.watch_parameters.hail_2in_probability ? `**Hail \u22652in Probability**: ${event.watch_parameters.hail_2in_probability}%` : null,
14835
+ event.watch_parameters.max_hail_in ? `**Max Hail Inches**: ${event.watch_parameters.max_hail_in}` : null,
14836
+ event.watch_parameters.severe_wind_probability ? `**Severe Wind Probability**: ${event.watch_parameters.severe_wind_probability}%` : null,
14837
+ event.watch_parameters.max_wind_surface ? `**Max Surface Wind**: ${event.watch_parameters.max_wind_surface}` : null,
14838
+ event.watch_parameters.max_tops_x100feet ? `**Max Tops (x100 feet)**: ${event.watch_parameters.max_tops_x100feet}` : null,
14799
14839
  ((_a = event.parameters.tags) == null ? void 0 : _a.length) > 0 ? `**Tags**: ${event.parameters.tags.join(", ")}` : null,
14800
14840
  (() => {
14801
- var _a2, _b2, _c2, _d2, _e2, _f2;
14841
+ var _a2, _b2, _c2, _d2, _e, _f;
14802
14842
  const val = (_c2 = (_b2 = (_a2 = event.geocode) == null ? void 0 : _a2.office) == null ? void 0 : _b2.name) != null ? _c2 : `N/A`;
14803
- const th = (_f2 = (_e2 = (_d2 = event.geocode) == null ? void 0 : _d2.office) == null ? void 0 : _e2.office) != null ? _f2 : null;
14843
+ const th = (_f = (_e = (_d2 = event.geocode) == null ? void 0 : _d2.office) == null ? void 0 : _e.office) != null ? _f : null;
14804
14844
  return val || th ? `**Sender**: ${val} ${th ? `(${th})` : ""}` : null;
14805
14845
  })(),
14806
14846
  ((_b = event.metadata) == null ? void 0 : _b.tracking) ? `**Tracking**: ${event.metadata.tracking}` : null,
14807
- ((_d = (_c = event.metadata) == null ? void 0 : _c.vtec) == null ? void 0 : _d.vtec) ? `**VTEC**: ${(_e = event.metadata.vtec) == null ? void 0 : _e.vtec}` : null,
14808
- ((_f = event.metadata) == null ? void 0 : _f.filtered_proximity) != null ? `**Currently in polygon (Node)**: ${event.metadata.filtered_proximity ? "Yes" : "No"}` : null,
14809
14847
  (() => {
14810
14848
  const desc = (event.description || "").split("\n").map((l) => l.trim()).filter(Boolean).join("\n");
14811
14849
  return desc ? "```\n" + desc + "\n```" : null;
@@ -14829,14 +14867,16 @@ var createWebhook = (options) => __async(null, null, function* () {
14829
14867
  footer: { text: settings.title }
14830
14868
  };
14831
14869
  form.append("payload_json", JSON.stringify({
14832
- username: (_g = settings.title) != null ? _g : "AtmosphericX",
14833
- content: (_h = settings.message) != null ? _h : "",
14870
+ username: (_c = settings.title) != null ? _c : "AtmosphericX",
14871
+ content: (_d = settings.message) != null ? _d : "",
14834
14872
  embeds: [embed]
14835
14873
  }));
14836
- form.append("file", Buffer.from(JSON.stringify({ type: "FeatureCollection", features: [getCleanedEvent(options.event)] }, null, 2)), {
14837
- filename: `${event.event}_${event.status}_${event.metadata.tracking}.json`,
14838
- contentType: "application/json"
14839
- });
14874
+ if (settings.upload) {
14875
+ form.append("file", Buffer.from(JSON.stringify(getCleanedEvent(event), null, 2)), {
14876
+ filename: `${event.event}_${event.status}_${event.metadata.tracking}.json`,
14877
+ contentType: "application/json"
14878
+ });
14879
+ }
14840
14880
  yield createHttp({
14841
14881
  url: settings.webhook,
14842
14882
  timeout: 2e3,
@@ -15106,6 +15146,9 @@ var rmEvent = (event) => {
15106
15146
  var _a, _b, _c, _d;
15107
15147
  return ((_b = (_a = f == null ? void 0 : f.properties) == null ? void 0 : _a.metadata) == null ? void 0 : _b.tracking) === ((_d = (_c = event == null ? void 0 : event.properties) == null ? void 0 : _c.metadata) == null ? void 0 : _d.tracking);
15108
15148
  });
15149
+ const cachedStatus = event.properties.status;
15150
+ event.properties.expires = (/* @__PURE__ */ new Date()).toISOString();
15151
+ event.properties.status = `Expired`;
15109
15152
  if (getEvent) {
15110
15153
  setEventEmit({
15111
15154
  event: `onEventStatus`,
@@ -15116,7 +15159,7 @@ var rmEvent = (event) => {
15116
15159
  message: `[Removed] ${event.properties.event} (${event.properties.status}) (${event.properties.metadata.tracking})`
15117
15160
  });
15118
15161
  setEventEmit({ event: `onExpiredProduct`, metadata: event });
15119
- updateWebhooks(event);
15162
+ if (cachedStatus != `Statement`) updateWebhooks(event);
15120
15163
  bootstrap.cache.events.features.splice(bootstrap.cache.events.features.indexOf(getEvent), 1);
15121
15164
  bootstrap.cache.hashes = bootstrap.cache.hashes.filter((hash) => hash.tracking !== event.properties.metadata.tracking);
15122
15165
  }
@@ -15255,9 +15298,11 @@ var text = (stanza) => __async(null, null, function* () {
15255
15298
  const header = getEventHeader({ properties: props, getType: stanza.getType });
15256
15299
  const issued = new Date(attributes.issue);
15257
15300
  const expires = new Date(issued.getTime() + 12 * 60 * 60 * 1e3);
15258
- let event = Object.keys(eventsOffshore).find((event2) => message.toLowerCase().includes(event2.toLowerCase()));
15301
+ let event = Object.keys(eventsMatchText).find((event2) => message.toLowerCase().includes(event2.toLowerCase()));
15302
+ let isStatement = false;
15259
15303
  if (!event) {
15260
15304
  event = stanza.getType.type.split(`-`).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(` `);
15305
+ isStatement = true;
15261
15306
  }
15262
15307
  processed.push({
15263
15308
  type: `Feature`,
@@ -15268,9 +15313,9 @@ var text = (stanza) => __async(null, null, function* () {
15268
15313
  properties: __spreadProps(__spreadValues({
15269
15314
  event,
15270
15315
  parent: event,
15271
- status: `Issued`,
15316
+ status: isStatement ? `Statement` : `Issued`,
15272
15317
  issued: !isNaN(issued.getTime()) ? issued.toISOString() : (/* @__PURE__ */ new Date()).toISOString(),
15273
- expires: !isNaN(expires.getTime()) ? expires.toISOString() : new Date(Date.now() + 60 * 60 * 1e3).toISOString()
15318
+ expires: isStatement ? new Date(issued.getTime() + 120 * 1e3).toISOString() : !isNaN(expires.getTime()) ? expires.toISOString() : new Date(Date.now() + 60 * 60 * 1e3).toISOString()
15274
15319
  }, props), {
15275
15320
  metadata: {
15276
15321
  ms: performance.now() - tick,
@@ -15387,11 +15432,13 @@ var ugc = (stanza) => __async(null, null, function* () {
15387
15432
  if (ugc2 != null) {
15388
15433
  const props = properties({ message, attributes, ugc: ugc2 });
15389
15434
  const issued = new Date(attributes.issue);
15390
- const expires = new Date(issued.getTime() + 12 * 60 * 60 * 1e3);
15435
+ const expires = new Date(ugc2.expires);
15391
15436
  const header = getEventHeader({ properties: props, getType: stanza.getType });
15392
- let event = Object.keys(eventsOffshore).find((event2) => message.toLowerCase().includes(event2.toLowerCase()));
15437
+ let event = Object.keys(eventsMatchText).find((event2) => message.toLowerCase().includes(event2.toLowerCase()));
15438
+ let isStatement = false;
15393
15439
  if (!event) {
15394
15440
  event = stanza.getType.type.split(`-`).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(` `);
15441
+ isStatement = true;
15395
15442
  }
15396
15443
  processed.push({
15397
15444
  type: `Feature`,
@@ -15402,9 +15449,9 @@ var ugc = (stanza) => __async(null, null, function* () {
15402
15449
  properties: __spreadProps(__spreadValues({
15403
15450
  event,
15404
15451
  parent: event,
15405
- status: `Issued`,
15452
+ status: isStatement ? `Statement` : `Issued`,
15406
15453
  issued: !isNaN(issued.getTime()) ? issued.toISOString() : (/* @__PURE__ */ new Date()).toISOString(),
15407
- expires: !isNaN(expires.getTime()) ? expires.toISOString() : new Date(Date.now() + 60 * 60 * 1e3).toISOString()
15454
+ expires: isStatement ? new Date(issued.getTime() + 120 * 1e3).toISOString() : !isNaN(expires.getTime()) ? expires.toISOString() : new Date(Date.now() + 60 * 60 * 1e3).toISOString()
15408
15455
  }, props), {
15409
15456
  metadata: {
15410
15457
  ms: performance.now() - tick,
@@ -16079,6 +16126,26 @@ var setCronSchedule = () => __async(null, null, function* () {
16079
16126
  }
16080
16127
  });
16081
16128
 
16129
+ // src/@manager/manager.updateEvents.ts
16130
+ var updateEvents = (selectedEvent) => __async(null, null, function* () {
16131
+ const events = bootstrap.cache.events.features;
16132
+ function update(evt) {
16133
+ return __async(this, null, function* () {
16134
+ if (new Date(evt.properties.expires) < /* @__PURE__ */ new Date()) {
16135
+ rmEvent(evt);
16136
+ }
16137
+ });
16138
+ }
16139
+ if (!selectedEvent) {
16140
+ yield Promise.all(events.map((evt) => __async(null, null, function* () {
16141
+ yield update(evt);
16142
+ })));
16143
+ }
16144
+ if (selectedEvent) {
16145
+ yield update(selectedEvent);
16146
+ }
16147
+ });
16148
+
16082
16149
  // src/@core/core.start.ts
16083
16150
  var import_croner = require("croner");
16084
16151
  var startService = (settings) => __async(null, null, function* () {
@@ -16106,8 +16173,9 @@ var startService = (settings) => __async(null, null, function* () {
16106
16173
  bootstrap.cron = new import_croner.Cron(`*/${scheduleInterval} * * * * *`, () => __async(null, null, function* () {
16107
16174
  yield setCronSchedule();
16108
16175
  }));
16109
- bootstrap.cron = new import_croner.Cron(`*/1 * * * * *`, () => __async(null, null, function* () {
16176
+ bootstrap.cron = new import_croner.Cron(`* * * * * *`, () => __async(null, null, function* () {
16110
16177
  yield updateNode();
16178
+ yield updateEvents();
16111
16179
  }));
16112
16180
  });
16113
16181
 
@@ -16583,6 +16651,17 @@ var getRandomEvent = () => {
16583
16651
  return bootstrap.cache.events.features[Math.floor(Math.random() * bootstrap.cache.events.features.length)];
16584
16652
  };
16585
16653
 
16654
+ // src/@core/core.clearEvents.ts
16655
+ var clearEvents = () => {
16656
+ bootstrap.cache.events.features = [];
16657
+ bootstrap.cache.hashes = [];
16658
+ setEventEmit({
16659
+ event: `onEventCache`,
16660
+ metadata: bootstrap.cache.events,
16661
+ message: `Manually cleared event cache.`
16662
+ });
16663
+ };
16664
+
16586
16665
  // src/index.ts
16587
16666
  var Manager = class {
16588
16667
  constructor(settings) {
@@ -16590,7 +16669,7 @@ var Manager = class {
16590
16669
  startService(settings);
16591
16670
  }
16592
16671
  on(event, callback) {
16593
- listener(event, callback);
16672
+ createListener(event, callback);
16594
16673
  }
16595
16674
  trycatch() {
16596
16675
  process.on("uncaughtException", (err) => {
@@ -16616,6 +16695,7 @@ var index_default = Manager;
16616
16695
  // Annotate the CommonJS export names for ESM import in node:
16617
16696
  0 && (module.exports = {
16618
16697
  Manager,
16698
+ clearEvents,
16619
16699
  getCleanedEvent,
16620
16700
  getEventGeometry,
16621
16701
  getEvents,