@atmosx/event-product-parser 3.0.42 → 3.0.46

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 (87) hide show
  1. package/README.md +70 -22
  2. package/SUPPORTED_EVENTS.md +369 -0
  3. package/dist/cjs/index.cjs +1990 -1758
  4. package/dist/esm/index.mjs +1560 -1329
  5. package/dist/index.d.mts +44 -20
  6. package/dist/index.d.ts +44 -20
  7. package/package.json +1 -1
  8. package/src/@building/building.attachments.ts +42 -0
  9. package/src/@building/building.create.ts +2 -2
  10. package/src/@building/building.enhance.ts +8 -4
  11. package/src/@building/building.geometry.ts +1 -1
  12. package/src/@building/building.headers.ts +1 -1
  13. package/src/@building/building.office.ts +4 -4
  14. package/src/@building/building.properties.ts +15 -13
  15. package/src/@building/building.signature.ts +11 -11
  16. package/src/@building/building.tags.ts +2 -2
  17. package/src/@building/building.tracking.ts +6 -6
  18. package/src/@building/building.validate.ts +5 -3
  19. package/src/@core/core.createEvent.ts +82 -0
  20. package/src/@core/core.query.ts +1 -1
  21. package/src/@core/core.start.ts +1 -1
  22. package/src/@dictionaries/{dictionaries.eventActions.ts → dictionaries.actions.ts} +1 -1
  23. package/src/@dictionaries/{dictionaries.eventAwipAbreviations.ts → dictionaries.awips.ts} +1 -1
  24. package/src/@dictionaries/{dictionaries.eventCancelMessages.ts → dictionaries.cancellation.ts} +1 -1
  25. package/src/@dictionaries/{dictionaries.eventCauses.ts → dictionaries.causes.ts} +1 -1
  26. package/src/@dictionaries/{dictionaries.statusCorrelationText.ts → dictionaries.correlations.ts} +1 -1
  27. package/src/@dictionaries/{dictionaries.betterEventNames.ts → dictionaries.enhanced.ts} +13 -2
  28. package/src/@dictionaries/{dictionaries.eventTypes.ts → dictionaries.events.ts} +1 -1
  29. package/src/@dictionaries/{dictionaries.regExp.ts → dictionaries.expressions.ts} +1 -1
  30. package/src/@dictionaries/{dictionaries.hailStrings.ts → dictionaries.hail.ts} +4 -1
  31. package/src/@dictionaries/{dictionaries.officeICAOs.ts → dictionaries.icao.ts} +1 -1
  32. package/src/@dictionaries/{dictionaries.eventsMatchText.ts → dictionaries.matches.ts} +1 -1
  33. package/src/@dictionaries/{dictionaries.eventProducts.ts → dictionaries.products.ts} +1 -1
  34. package/src/@dictionaries/{dictionaries.eventRecords.ts → dictionaries.records.ts} +1 -1
  35. package/src/@dictionaries/{dictionaries.eventSeverity.ts → dictionaries.severity.ts} +1 -1
  36. package/src/@dictionaries/{dictionaries.shapefileLinks.ts → dictionaries.shapefiles.ts} +1 -1
  37. package/src/@dictionaries/{dictionaries.eventStatus.ts → dictionaries.status.ts} +1 -1
  38. package/src/@dictionaries/{dictionaries.eventTags.ts → dictionaries.tags.ts} +1 -1
  39. package/src/@dictionaries/{dictionaries.testSignatures.ts → dictionaries.test.ts} +3 -2
  40. package/src/@events/events.api.ts +19 -14
  41. package/src/@events/events.text.ts +5 -4
  42. package/src/@events/events.ugc.ts +5 -4
  43. package/src/@events/events.vtec.ts +5 -4
  44. package/src/@manager/manager.mkEvent.ts +4 -4
  45. package/src/@manager/manager.rmEvent.ts +3 -2
  46. package/src/@manager/manager.setHash.ts +1 -1
  47. package/src/@manager/manager.updateListener.ts +124 -0
  48. package/src/@modules/@database/database.cache.ts +1 -1
  49. package/src/@modules/@database/database.init.ts +1 -1
  50. package/src/@modules/@database/database.shapefiles.ts +3 -3
  51. package/src/@modules/@database/database.stanza.ts +2 -2
  52. package/src/@modules/@eas/eas.getCleanDescription.ts +91 -0
  53. package/src/@modules/@eas/eas.getTTS.ts +54 -0
  54. package/src/@modules/@eas/eas.setEasTone.ts +40 -30
  55. package/src/@modules/@stanza/stanza.getAwipsType.ts +3 -3
  56. package/src/@modules/@stanza/stanza.validate.ts +5 -5
  57. package/src/@modules/@utilities/utilities.getLatestIssuance.ts +32 -0
  58. package/src/@modules/@utilities/utilities.getSettings.ts +1 -1
  59. package/src/@modules/@utilities/utilities.setCronSchedule.ts +30 -2
  60. package/src/@modules/@utilities/utilities.setSettings.ts +1 -1
  61. package/src/@modules/@utilities/utilities.setWarning.ts +1 -1
  62. package/src/@modules/@xmpp/xmpp.xDeploy.ts +1 -1
  63. package/src/@modules/@xmpp/xmpp.xReconnect.ts +1 -1
  64. package/src/@modules/@xmpp/xmpp.xStanza.ts +1 -1
  65. package/src/@parsers/@hvtec/hvtec.extract.ts +9 -9
  66. package/src/@parsers/@pvtec/pvtec.extract.ts +13 -13
  67. package/src/@parsers/@text/text.getDescriptionFromProduct.ts +2 -2
  68. package/src/@parsers/@text/text.getEmbed.ts +60 -0
  69. package/src/@parsers/@ugc/ugc.extract.ts +1 -1
  70. package/src/@parsers/@ugc/ugc.header.ts +3 -3
  71. package/src/@types/{types.compiled.ts → type.compiled.ts} +1 -1
  72. package/src/@types/type.event.ts +6 -4
  73. package/src/@types/{types.webhook.ts → type.listener.ts} +11 -6
  74. package/src/@types/type.properties.ts +10 -8
  75. package/src/@types/{types.settings.ts → type.settings.ts} +7 -5
  76. package/src/bootstrap.ts +7 -5
  77. package/src/index.ts +3 -2
  78. package/test.js +19 -19
  79. package/src/@dictionaries/dictionaries.transcribedMessageReplacements.ts +0 -68
  80. package/src/@manager/manager.createWebhook.ts +0 -117
  81. package/src/@manager/manager.updateWebhooks.ts +0 -49
  82. /package/src/@types/{types.attributes.ts → type.attributes.ts} +0 -0
  83. /package/src/@types/{types.hash.ts → type.hash.ts} +0 -0
  84. /package/src/@types/{types.hvtec.ts → type.hvtec.ts} +0 -0
  85. /package/src/@types/{types.pvtec.ts → type.pvtec.ts} +0 -0
  86. /package/src/@types/{types.stanza.ts → type.stanza.ts} +0 -0
  87. /package/src/@types/{types.ugc.ts → type.ugc.ts} +0 -0
@@ -10491,7 +10491,7 @@ var require_form_data = __commonJS({
10491
10491
  import path from "path";
10492
10492
  import { EventEmitter } from "events";
10493
10493
  var bootstrap = {
10494
- version: `3.0.42`,
10494
+ version: `3.0.46`,
10495
10495
  isReady: true,
10496
10496
  ratelimits: {},
10497
10497
  session_xmpp: null,
@@ -10547,7 +10547,7 @@ var bootstrap = {
10547
10547
  CallbackInterval: 15,
10548
10548
  EventsEndpoint: `https://api.weather.gov/alerts/active`
10549
10549
  },
10550
- WebhookSettings: [],
10550
+ ListenerSettings: [],
10551
10551
  GlobalSettings: {
10552
10552
  EventManagement: true,
10553
10553
  BetterEventNames: true,
@@ -10567,9 +10567,11 @@ var bootstrap = {
10567
10567
  NodeLocationFiltering: false,
10568
10568
  IgnoreTestProducts: true
10569
10569
  },
10570
- EASSettings: {
10571
- ArchiveDirectory: null,
10572
- IntroWavFile: null
10570
+ ArchiveSettings: {
10571
+ TTL: 60,
10572
+ TextDirectory: null,
10573
+ EasDirectory: null,
10574
+ EasToneout: null
10573
10575
  }
10574
10576
  }
10575
10577
  }
@@ -13583,8 +13585,8 @@ var xError = () => {
13583
13585
  }));
13584
13586
  };
13585
13587
 
13586
- // src/@dictionaries/dictionaries.regExp.ts
13587
- var regExp = {
13588
+ // src/@dictionaries/dictionaries.expressions.ts
13589
+ var dict_expressions = {
13588
13590
  pvtec: new RegExp(`[OTEX].(NEW|CON|EXT|EXA|EXB|UPG|CAN|EXP|COR|ROU).[A-Z]{4}.[A-Z]{2}.[WAYSFON].[0-9]{4}.[0-9]{6}T[0-9]{4}Z-[0-9]{6}T[0-9]{4}Z`, "g"),
13589
13591
  hvtec: new RegExp(`[a-zA-Z0-9]{4}.[A-Z0-9].[A-Z]{2}.[0-9]{6}T[0-9]{4}Z.[0-9]{6}T[0-9]{4}Z.[0-9]{6}T[0-9]{4}Z.[A-Z]{2}`, "imu"),
13590
13592
  wmo: new RegExp(`[A-Z0-9]{6}\\s[A-Z]{4}\\s\\d{6}`, "imu"),
@@ -13594,8 +13596,8 @@ var regExp = {
13594
13596
  dateline: new RegExp(`\\d{3,4}\\s*(AM|PM)?\\s*[A-Z]{2,4}\\s+[A-Z]{3,}\\s+[A-Z]{3,}\\s+\\d{1,2}\\s+\\d{4}`, "gim")
13595
13597
  };
13596
13598
 
13597
- // src/@dictionaries/dictionaries.eventAwipAbreviations.ts
13598
- var eventAwipAbreviations = {
13599
+ // src/@dictionaries/dictionaries.awips.ts
13600
+ var dict_awips = {
13599
13601
  ABV: `rawinsonde-data-above-100-millibars`,
13600
13602
  ADA: `alarm-alert-administrative-message`,
13601
13603
  ADM: `alert-administrative-message`,
@@ -13950,7 +13952,7 @@ var getAwipsType = (options) => {
13950
13952
  prefix: null
13951
13953
  };
13952
13954
  }
13953
- for (const [prefix, type] of Object.entries(eventAwipAbreviations)) {
13955
+ for (const [prefix, type] of Object.entries(dict_awips)) {
13954
13956
  if (attributes.awipsid.startsWith(prefix)) {
13955
13957
  return { type, prefix };
13956
13958
  }
@@ -13968,8 +13970,8 @@ var validate = (options) => {
13968
13970
  if (attributes.awipsid && attributes.awipsid.length > 1) {
13969
13971
  const isCapEvent = message.includes(`<?xml`);
13970
13972
  const isCapAreaDescription = message.includes(`<areaDesc>`);
13971
- const isVTEC = message.match(regExp.pvtec) != null;
13972
- const isUGC = message.match(regExp.ugc1) != null;
13973
+ const isVTEC = message.match(dict_expressions.pvtec) != null;
13974
+ const isUGC = message.match(dict_expressions.ugc1) != null;
13973
13975
  const getType = getAwipsType({ attributes });
13974
13976
  if (getType.type != null) {
13975
13977
  return {
@@ -13993,7 +13995,7 @@ var validate = (options) => {
13993
13995
  // src/@parsers/@text/text.getDescriptionFromProduct.ts
13994
13996
  var getDescriptionFromProduct = (options) => {
13995
13997
  let message = options.message;
13996
- const dates = Array.from(message.matchAll(regExp.dateline));
13998
+ const dates = Array.from(message.matchAll(dict_expressions.dateline));
13997
13999
  if (dates.length) {
13998
14000
  const lastMatch = dates[dates.length - 1][0];
13999
14001
  const sIndx = message.lastIndexOf(lastMatch);
@@ -14059,8 +14061,8 @@ var getTextFromProduct = (options) => {
14059
14061
  return null;
14060
14062
  };
14061
14063
 
14062
- // src/@dictionaries/dictionaries.officeICAOs.ts
14063
- var officeICAOs = {
14064
+ // src/@dictionaries/dictionaries.icao.ts
14065
+ var dict_icao = {
14064
14066
  "KLUB": "Lubbock, TX",
14065
14067
  "KLCH": "Lake Charles, LA",
14066
14068
  "TSTL": "St. Louis, MO",
@@ -14305,12 +14307,12 @@ var officeICAOs = {
14305
14307
  var getEventOffice = (options) => {
14306
14308
  var _a, _b, _c, _d, _e, _f, _g;
14307
14309
  const office = options.pVtec != null ? (_b = (_a = options.pVtec) == null ? void 0 : _a.tracking) == null ? void 0 : _b.split(`.`)[0] : (_e = (_c = options.attributes) == null ? void 0 : _c.cccc) != null ? _e : options.organization != null ? Array.isArray(options.organization) ? (_d = options.organization) == null ? void 0 : _d[0] : options.organization : null;
14308
- const name = (_g = (_f = officeICAOs) == null ? void 0 : _f[office]) != null ? _g : null;
14310
+ const name = (_g = (_f = dict_icao) == null ? void 0 : _f[office]) != null ? _g : null;
14309
14311
  return { office, name };
14310
14312
  };
14311
14313
 
14312
- // src/@dictionaries/dictionaries.eventTags.ts
14313
- var eventTags = {
14314
+ // src/@dictionaries/dictionaries.tags.ts
14315
+ var dict_tags = {
14314
14316
  "FROSTBITE AND HYPOTHERMIA ARE LIKELY": "Frostbite and Hypothermia Likely",
14315
14317
  "LICKELY BECOME SLICK AND HAZARDOUS": "Slick and Hazardous Roads",
14316
14318
  "SLIPPERY ROAD CONDITIONS": "Slippery Roads",
@@ -14387,13 +14389,13 @@ var eventTags = {
14387
14389
 
14388
14390
  // src/@building/building.tags.ts
14389
14391
  var getEventTags = (message) => {
14390
- return Object.entries(eventTags).filter(([key]) => message == null ? void 0 : message.toLowerCase().includes(key.toLowerCase())).map(([, value]) => value);
14392
+ return Object.entries(dict_tags).filter(([key]) => message == null ? void 0 : message.toLowerCase().includes(key.toLowerCase())).map(([, value]) => value);
14391
14393
  };
14392
14394
 
14393
14395
  // src/@building/building.properties.ts
14394
14396
  var properties = (options) => {
14395
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J;
14396
- const organization = (_b = (_a = options.message.match(regExp.wmo)) == null ? void 0 : _a[0]) != null ? _b : null;
14397
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V;
14398
+ const organization = (_b = (_a = options.message.match(dict_expressions.wmo)) == null ? void 0 : _a[0]) != null ? _b : null;
14397
14399
  const polygons = getPolygonFromProduct(options.message);
14398
14400
  const properties2 = {
14399
14401
  locations: (_e = (_d = (_c = options == null ? void 0 : options.ugc) == null ? void 0 : _c.locations) == null ? void 0 : _d.join(`; `)) != null ? _e : null,
@@ -14420,25 +14422,27 @@ var properties = (options) => {
14420
14422
  wind_threat: (_s = getTextFromProduct({ message: options.message, find: [`WIND THREAT...`] })) != null ? _s : null,
14421
14423
  hail_threat: (_t = getTextFromProduct({ message: options.message, find: [`HAIL THREAT...`], removal: [] })) != null ? _t : null
14422
14424
  },
14423
- spc_parameters: {
14424
- spc_max_tornado: (_u = getTextFromProduct({ message: options.message, find: [`MOST PROBABLE PEAK TORNADO INTENSITY...`] })) != null ? _u : null,
14425
- spc_max_hail: (_v = getTextFromProduct({ message: options.message, find: [`MOST PROBABLE PEAK HAIL SIZE...`] })) != null ? _v : null,
14426
- spc_max_wind: (_w = getTextFromProduct({ message: options.message, find: [`MOST PROBABLE PEAK WIND GUST...`] })) != null ? _w : null,
14427
- spc_watch_issuance: (_x = getTextFromProduct({ message: options.message, find: [`Probability of Watch Issuance...`], removal: [`percent`] })) != null ? _x : null
14425
+ discussion_parameters: {
14426
+ discussion_number: (_w = (_v = (_u = getTextFromProduct({ message: options.message, find: [`Mesoscale Discussion `], removal: [`Mesoscale Discussion`, `Number`, `...`] })) == null ? void 0 : _u.toString()) == null ? void 0 : _v.padStart(4, "0")) != null ? _w : null,
14427
+ discussion_concerning: (_x = getTextFromProduct({ message: options.message, find: [`Concerning...`] })) != null ? _x : null,
14428
+ discussion_max_tornado: (_y = getTextFromProduct({ message: options.message, find: [`MOST PROBABLE PEAK TORNADO INTENSITY...`] })) != null ? _y : null,
14429
+ discussion_max_hail: (_z = getTextFromProduct({ message: options.message, find: [`MOST PROBABLE PEAK HAIL SIZE...`] })) != null ? _z : null,
14430
+ discussion_max_wind: (_A = getTextFromProduct({ message: options.message, find: [`MOST PROBABLE PEAK WIND GUST...`] })) != null ? _A : null,
14431
+ discussion_watch_issuance: (_B = getTextFromProduct({ message: options.message, find: [`Probability of Watch Issuance...`], removal: [`percent`] })) != null ? _B : null
14428
14432
  },
14429
14433
  watch_parameters: {
14430
- watch_number: (_A = (_z = (_y = getTextFromProduct({ message: options.message, find: [`ITIES FOR`, `UPDATE FOR`, `Watch Number `], removal: [`%`, `<`, `:`] })) == null ? void 0 : _y.replace(/(WT|WS|)/g, "")) == null ? void 0 : _z.trim()) != null ? _A : null,
14434
+ watch_number: ((_C = options == null ? void 0 : options.pVtec) == null ? void 0 : _C.is_watch) && ((_M = (_L = (_G = (_F = (_E = (_D = getTextFromProduct({ message: options.message, find: [`ITIES FOR`, `UPDATE FOR`, `Watch Number `], removal: [`%`, `<`, `:`] })) == null ? void 0 : _D.replace(/(WT|WS|)/g, "")) == null ? void 0 : _E.trim()) == null ? void 0 : _F.toString()) == null ? void 0 : _G.padStart(4, "0")) != null ? _L : (_K = (_J = (_I = (_H = options == null ? void 0 : options.pVtec) == null ? void 0 : _H.tracking) == null ? void 0 : _I.slice(-4)) == null ? void 0 : _J.toString()) == null ? void 0 : _K.padStart(4, "0")) != null ? _M : null),
14431
14435
  watch_type: options.message.includes(`TORNADO WATCH`) ? `Tornado` : (options == null ? void 0 : options.message.includes(`SEVERE`)) ? `Severe` : null,
14432
- additional_tornadoes_probability: (_B = getTextFromProduct({ message: options.message, find: [`PROB OF 2 OR MORE TORNADOES`], removal: [`%`, `<`, `:`] })) != null ? _B : null,
14433
- strong_tornadoes_probability: (_C = getTextFromProduct({ message: options.message, find: [`PROB OF 1 OR MORE STRONG /EF2-EF5/ TORNADOES`], removal: [`%`, `<`, `:`] })) != null ? _C : null,
14434
- severe_wind_probability: (_D = getTextFromProduct({ message: options.message, find: [`PROB OF 10 OR MORE SEVERE WIND EVENTS`], removal: [`%`, `<`, `:`] })) != null ? _D : null,
14435
- severe_hail_probability: (_E = getTextFromProduct({ message: options.message, find: [`PROB OF 10 OR MORE SEVERE HAIL EVENTS`], removal: [`%`, `<`, `:`] })) != null ? _E : null,
14436
- hail_2in_probability: (_F = getTextFromProduct({ message: options.message, find: [`PROB OF 1 OR MORE HAIL EVENTS >= 2 INCHES`], removal: [`%`, `<`, `:`] })) != null ? _F : null,
14437
- combined_hail_wind_probability: (_G = getTextFromProduct({ message: options.message, find: [`PROB OF 6 OR MORE COMBINED SEVERE HAIL/WIND EVENTS`], removal: [`%`, `<`, `:`] })) != null ? _G : null,
14438
- max_hail_in: (_H = getTextFromProduct({ message: options.message, find: [`MAX HAIL /INCHES/`], removal: [`%`, `<`, `:`] })) != null ? _H : null,
14439
- max_wind_surface: (_I = getTextFromProduct({ message: options.message, find: [`MAX WIND GUSTS SURFACE /KNOTS/`], removal: [`%`, `<`, `:`] })) != null ? _I : null,
14440
- max_tops_x100feet: (_J = getTextFromProduct({ message: options.message, find: [`MAX TOPS /X 100 FEET/`], removal: [`%`, `<`, `:`] })) != null ? _J : null,
14441
- pds_watch: getTextFromProduct({ message: options.message, find: [`PARTICULARLY DANGEROUS SITUATION`], removal: [`%`, `<`, `:`] }) === `YES`
14436
+ additional_tornadoes_probability: (_N = getTextFromProduct({ message: options.message, find: [`PROB OF 2 OR MORE TORNADOES`], removal: [`%`, `<`, `:`] })) != null ? _N : null,
14437
+ strong_tornadoes_probability: (_O = getTextFromProduct({ message: options.message, find: [`PROB OF 1 OR MORE STRONG /EF2-EF5/ TORNADOES`], removal: [`%`, `<`, `:`] })) != null ? _O : null,
14438
+ severe_wind_probability: (_P = getTextFromProduct({ message: options.message, find: [`PROB OF 10 OR MORE SEVERE WIND EVENTS`], removal: [`%`, `<`, `:`] })) != null ? _P : null,
14439
+ severe_hail_probability: (_Q = getTextFromProduct({ message: options.message, find: [`PROB OF 10 OR MORE SEVERE HAIL EVENTS`], removal: [`%`, `<`, `:`] })) != null ? _Q : null,
14440
+ hail_2in_probability: (_R = getTextFromProduct({ message: options.message, find: [`PROB OF 1 OR MORE HAIL EVENTS >= 2 INCHES`], removal: [`%`, `<`, `:`] })) != null ? _R : null,
14441
+ combined_hail_wind_probability: (_S = getTextFromProduct({ message: options.message, find: [`PROB OF 6 OR MORE COMBINED SEVERE HAIL/WIND EVENTS`], removal: [`%`, `<`, `:`] })) != null ? _S : null,
14442
+ max_hail_in: (_T = getTextFromProduct({ message: options.message, find: [`MAX HAIL /INCHES/`], removal: [`%`, `<`, `:`] })) != null ? _T : null,
14443
+ max_wind_surface: (_U = getTextFromProduct({ message: options.message, find: [`MAX WIND GUSTS SURFACE /KNOTS/`], removal: [`%`, `<`, `:`] })) != null ? _U : null,
14444
+ max_tops_x100feet: (_V = getTextFromProduct({ message: options.message, find: [`MAX TOPS /X 100 FEET/`], removal: [`%`, `<`, `:`] })) != null ? _V : null,
14445
+ pds_watch: getTextFromProduct({ message: options.message, find: [`PARTICULARLY DANGEROUS SITUATION`], removal: [`%`, `<`, `:`] }) === `YES` ? true : null
14442
14446
  }
14443
14447
  };
14444
14448
  if (isNaN(Number(properties2.watch_parameters.watch_number))) {
@@ -14456,8 +14460,8 @@ var getEventHeader = (options) => {
14456
14460
  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`}`;
14457
14461
  };
14458
14462
 
14459
- // src/@dictionaries/dictionaries.eventsMatchText.ts
14460
- var eventsMatchText = {
14463
+ // src/@dictionaries/dictionaries.matches.ts
14464
+ var dict_matches = {
14461
14465
  "Special Weather Statement": "Special Weather Statement",
14462
14466
  "Hurricane Warning": "Hurricane Warning",
14463
14467
  "Hurricane Force Wind Warning": "Hurricane Force Wind Warning",
@@ -14477,7 +14481,7 @@ var eventsMatchText = {
14477
14481
 
14478
14482
  // src/@building/building.tracking.ts
14479
14483
  var getEventTracking = (options) => {
14480
- var _a, _b, _c, _d, _e, _f, _g;
14484
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
14481
14485
  const properties2 = options.properties;
14482
14486
  const attributes = options.attributes;
14483
14487
  const stanza = options.stanza;
@@ -14494,26 +14498,26 @@ var getEventTracking = (options) => {
14494
14498
  }
14495
14499
  if (options.type === `API`) {
14496
14500
  if (options.vtec) {
14497
- const vtecValue = Array.isArray(options.vtec) ? options.vtec[0] : options.vtec;
14501
+ const vtecValue = Array.isArray(options.vtec) ? options.vtec[0].vtec : (_c = options.vtec) == null ? void 0 : _c.vtec;
14498
14502
  const splitPVTEC = vtecValue.split(".");
14499
14503
  return `${splitPVTEC[2]}.${splitPVTEC[3]}.${splitPVTEC[4]}.${splitPVTEC[5]}`;
14500
14504
  }
14501
- const wmoMatch = (_d = (_c = options.organization) == null ? void 0 : _c.wmoidentifier) == null ? void 0 : _d.match(/([A-Z]{4}\d{2})\s+([A-Z]{4})/);
14502
- const station = (_e = wmoMatch == null ? void 0 : wmoMatch[2]) != null ? _e : "N/A";
14505
+ const wmoMatch = (_e = (_d = options.organization) == null ? void 0 : _d.wmoidentifier) == null ? void 0 : _e.match(/([A-Z]{4}\d{2})\s+([A-Z]{4})/);
14506
+ const station = (_f = wmoMatch == null ? void 0 : wmoMatch[2]) != null ? _f : "N/A";
14503
14507
  if (options.organization.featureId) {
14504
14508
  const idMatch = options.organization.featureId.match(/([a-f0-9]+)\.(\d+)\.(\d+)$/);
14505
- return `${station}.${(_f = idMatch == null ? void 0 : idMatch[1]) != null ? _f : "N/A"}`;
14509
+ return `${station}.${(_h = (_g = idMatch == null ? void 0 : idMatch[0]) == null ? void 0 : _g.replace(/\./g, "")) != null ? _h : "N/A"}`;
14506
14510
  }
14507
- const id2 = (_g = wmoMatch == null ? void 0 : wmoMatch[1]) != null ? _g : "N/A";
14508
- return `${station}.${id2}`;
14511
+ const id2 = (_i = wmoMatch == null ? void 0 : wmoMatch[1]) != null ? _i : "N/A";
14512
+ return `${station}.${(_j = id2 == null ? void 0 : id2.replace(/\./g, "")) != null ? _j : "N/A"}`;
14509
14513
  }
14510
14514
  };
14511
14515
 
14512
14516
  // src/@building/building.validate.ts
14513
14517
  import { createHash } from "crypto";
14514
14518
 
14515
- // src/@dictionaries/dictionaries.betterEventNames.ts
14516
- var betterEventNames = {
14519
+ // src/@dictionaries/dictionaries.enhanced.ts
14520
+ var dict_enhanced = {
14517
14521
  "Tornado Warning": {
14518
14522
  "Tornado Emergency": {
14519
14523
  description: "tornado emergency"
@@ -14531,6 +14535,11 @@ var betterEventNames = {
14531
14535
  },
14532
14536
  "Radar Indicated Tornado Warning": {}
14533
14537
  },
14538
+ "Fire Weather Warning": {
14539
+ "PDS Fire Weather Warning": {
14540
+ description: "particularly dangerous situation"
14541
+ }
14542
+ },
14534
14543
  "Blizzard Warning": {
14535
14544
  "PDS Blizzard Warning": {
14536
14545
  description: "particularly dangerous situation"
@@ -14548,7 +14557,12 @@ var betterEventNames = {
14548
14557
  },
14549
14558
  "Tornado Watch": {
14550
14559
  "PDS Tornado Watch": {
14551
- description: "particularly dangerous situation"
14560
+ pdswatch: true
14561
+ }
14562
+ },
14563
+ "Severe Thunderstorm Watch": {
14564
+ "PDS Severe Thunderstorm Watch": {
14565
+ pdswatch: true
14552
14566
  }
14553
14567
  },
14554
14568
  "Flash Flood Warning": {
@@ -14589,16 +14603,17 @@ var betterEventNames = {
14589
14603
 
14590
14604
  // src/@building/building.enhance.ts
14591
14605
  var getEventEnhancedName = (event) => {
14592
- var _a, _b, _c, _d, _e, _f, _g;
14606
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
14593
14607
  const configurations = bootstrap.settings;
14594
14608
  let name = (_a = event == null ? void 0 : event.properties) == null ? void 0 : _a.event;
14595
14609
  if (!((_b = configurations == null ? void 0 : configurations.GlobalSettings) == null ? void 0 : _b.BetterEventNames)) {
14596
14610
  return name;
14597
14611
  }
14598
14612
  const damage = (_d = (_c = event == null ? void 0 : event.properties) == null ? void 0 : _c.parameters) == null ? void 0 : _d.damage_threat;
14599
- const tornado = (_e = event == null ? void 0 : event.properties) == null ? void 0 : _e.parameters.tornado_threat;
14600
- const description = (_g = (_f = event == null ? void 0 : event.properties) == null ? void 0 : _f.description) == null ? void 0 : _g.toLowerCase();
14601
- for (const [eventKey, eventConfig] of Object.entries(betterEventNames)) {
14613
+ const tornado = (_f = (_e = event == null ? void 0 : event.properties) == null ? void 0 : _e.parameters) == null ? void 0 : _f.tornado_threat;
14614
+ const pdswatch = (_h = (_g = event == null ? void 0 : event.properties) == null ? void 0 : _g.watch_parameters) == null ? void 0 : _h.pds_watch;
14615
+ const description = (_j = (_i = event == null ? void 0 : event.properties) == null ? void 0 : _i.description) == null ? void 0 : _j.toLowerCase();
14616
+ for (const [eventKey, eventConfig] of Object.entries(dict_enhanced)) {
14602
14617
  if (eventKey !== name) continue;
14603
14618
  for (const [paramKey, paramValue] of Object.entries(eventConfig)) {
14604
14619
  let matches = true;
@@ -14611,6 +14626,9 @@ var getEventEnhancedName = (event) => {
14611
14626
  if (paramValue == null ? void 0 : paramValue.tornado) {
14612
14627
  if (paramValue.tornado !== tornado) matches = false;
14613
14628
  }
14629
+ if (paramValue == null ? void 0 : paramValue.pdswatch) {
14630
+ if (paramValue.pdswatch !== pdswatch) matches = false;
14631
+ }
14614
14632
  if (matches) {
14615
14633
  name = paramKey;
14616
14634
  break;
@@ -14620,8 +14638,8 @@ var getEventEnhancedName = (event) => {
14620
14638
  return name;
14621
14639
  };
14622
14640
 
14623
- // src/@dictionaries/dictionaries.statusCorrelationText.ts
14624
- var statusCorrelationText = [
14641
+ // src/@dictionaries/dictionaries.correlations.ts
14642
+ var dict_correlations = [
14625
14643
  { type: "Statement", name: "Statement", isCancel: false, isUpdate: false, isIssued: true, isStatement: true },
14626
14644
  { type: "Update", name: "Updated", isCancel: false, isUpdate: true, isIssued: false, isStatement: false },
14627
14645
  { type: "Cancel", name: "Cancelled", isCancel: true, isUpdate: false, isIssued: false, isStatement: false },
@@ -14636,8 +14654,8 @@ var statusCorrelationText = [
14636
14654
  { type: "Routine", name: "Routine", isCancel: false, isUpdate: true, isIssued: false, isStatement: false }
14637
14655
  ];
14638
14656
 
14639
- // src/@dictionaries/dictionaries.eventCancelMessages.ts
14640
- var eventCancelMessages = [
14657
+ // src/@dictionaries/dictionaries.cancellation.ts
14658
+ var dict_cancellation = [
14641
14659
  "has been cancelled",
14642
14660
  "subsided sufficiently for the advisory to be cancelled",
14643
14661
  "has been cancelled",
@@ -14649,24 +14667,28 @@ var eventCancelMessages = [
14649
14667
  "has weakened below severe"
14650
14668
  ];
14651
14669
 
14652
- // src/@dictionaries/dictionaries.testSignatures.ts
14653
- var testSignatures = [
14670
+ // src/@dictionaries/dictionaries.test.ts
14671
+ var dict_testing = [
14654
14672
  `This is a test message`,
14655
14673
  `Monitoring message only.`,
14656
- `THIS_MESSAGE_IS_FOR_TEST_PURPOSES_ONLY`
14674
+ `THIS_MESSAGE_IS_FOR_TEST_PURPOSES_ONLY`,
14675
+ "TEST MESSAGE"
14657
14676
  ];
14658
14677
 
14659
- // src/@dictionaries/dictionaries.eventProducts.ts
14660
- var eventProducts = {
14678
+ // src/@dictionaries/dictionaries.products.ts
14679
+ var dict_products = {
14661
14680
  "O": "Operational Product",
14662
14681
  "T": "Test Product",
14663
14682
  "E": "Experimental Product",
14664
14683
  "X": "Experimental Product (Non-Operational)"
14665
14684
  };
14666
14685
 
14667
- // src/@dictionaries/dictionaries.hailStrings.ts
14668
- var hailStrings = {
14686
+ // src/@dictionaries/dictionaries.hail.ts
14687
+ var dict_hail = {
14688
+ ".25": "Pea",
14689
+ ".50": "Penny",
14669
14690
  ".75": "Penny",
14691
+ "Up to .75": "Penny",
14670
14692
  ".88": "Nickel",
14671
14693
  "0.75": "Penny",
14672
14694
  "0.88": "Nickel",
@@ -14682,25 +14704,25 @@ var hailStrings = {
14682
14704
 
14683
14705
  // src/@building/building.signature.ts
14684
14706
  var getEventSignature = (event) => {
14685
- var _a, _b, _c, _d, _e, _f;
14707
+ var _a, _b, _c, _d, _e, _f, _g, _h;
14686
14708
  const properties2 = event == null ? void 0 : event.properties;
14687
14709
  const vtec2 = (_b = (_a = event == null ? void 0 : event.properties) == null ? void 0 : _a.metadata) == null ? void 0 : _b.vtec;
14688
- const status = statusCorrelationText.find((c) => c.type === (properties2 == null ? void 0 : properties2.status));
14689
- const csig = eventCancelMessages.find((sig) => properties2.description.toLowerCase().includes(sig.toLowerCase()));
14710
+ const status = dict_correlations.find((c) => c.type === (properties2 == null ? void 0 : properties2.status));
14711
+ const csig = dict_cancellation.find((sig) => properties2.description.toLowerCase().includes(sig.toLowerCase()));
14690
14712
  properties2.status_metadata = __spreadProps(__spreadValues({}, properties2.status_metadata), { is_issued: true, is_test: false });
14691
- if (properties2.parameters.estimated_hail_size) {
14692
- properties2.parameters.estimated_hail_size += ` (${(_c = hailStrings[properties2.parameters.estimated_hail_size]) != null ? _c : "--"})`;
14713
+ if ((_c = properties2 == null ? void 0 : properties2.parameters) == null ? void 0 : _c.estimated_hail_size) {
14714
+ properties2.parameters.estimated_hail_size += ` (${(_e = dict_hail[(_d = properties2 == null ? void 0 : properties2.parameters) == null ? void 0 : _d.estimated_hail_size]) != null ? _e : "--"})`;
14693
14715
  }
14694
14716
  if (status) {
14695
- properties2.status = (_d = status.name) != null ? _d : properties2.status;
14717
+ properties2.status = (_f = status.name) != null ? _f : properties2.status;
14696
14718
  properties2.status_metadata = __spreadProps(__spreadValues({}, properties2.status_metadata), { is_updated: !!status.isUpdate, is_issued: !!status.isIssued, is_expired: !!status.isCancel, is_statement: !!status.isStatement });
14697
14719
  }
14698
14720
  if (csig) {
14699
14721
  properties2.status_metadata = __spreadProps(__spreadValues({}, properties2.status_metadata), { is_expired: true });
14700
14722
  }
14701
- const getProduct = (_f = (_e = vtec2 == null ? void 0 : vtec2.vtec) == null ? void 0 : _e.split(`.`)[0]) == null ? void 0 : _f.replace(`/`, ``);
14702
- const isTestProduct = eventProducts[getProduct] == `Test Product`;
14703
- if (isTestProduct || testSignatures.some((sig) => {
14723
+ const getProduct = (_h = (_g = vtec2 == null ? void 0 : vtec2.vtec) == null ? void 0 : _g.split(`.`)[0]) == null ? void 0 : _h.replace(`/`, ``);
14724
+ const isTestProduct = dict_products[getProduct] == `Test Product`;
14725
+ if (isTestProduct || dict_testing.some((sig) => {
14704
14726
  var _a2, _b2, _c2, _d2;
14705
14727
  return (_d2 = (_a2 = properties2.description) == null ? void 0 : _a2.toLowerCase().includes(sig.toLowerCase())) != null ? _d2 : (_c2 = (_b2 = properties2 == null ? void 0 : properties2.parameters) == null ? void 0 : _b2.instructions) == null ? void 0 : _c2.toLowerCase().includes(sig.toLowerCase());
14706
14728
  })) {
@@ -14727,674 +14749,1185 @@ var setHash = (event, entry) => {
14727
14749
  }
14728
14750
  };
14729
14751
 
14730
- // src/@modules/@utilities/utilities.createHttp.ts
14731
- import request from "request";
14732
- var createHttp = (options) => __async(null, null, function* () {
14733
- return new Promise((resolve6, reject) => {
14734
- var _a, _b, _c, _d, _e;
14735
- const requestOptions = {
14736
- url: (_a = options.url) != null ? _a : `https://api.weather.gov/alerts/active`,
14737
- headers: (_b = options.headers) != null ? _b : {
14738
- "User-Agent": "AtmosphericX",
14739
- "Accept": "application/geo+json, text/plain, */*; q=0.9",
14740
- "Accept-Language": "en-US,en;q=0.9"
14741
- },
14742
- method: (_c = options.method) != null ? _c : `GET`,
14743
- timeout: (_d = options.timeout) != null ? _d : 1e4,
14744
- proxy: (_e = options.proxy) != null ? _e : null,
14745
- maxRedirects: 1
14746
- };
14747
- if (options.formData) {
14748
- requestOptions["formData"] = options.formData;
14749
- } else if (options.body) {
14750
- requestOptions["body"] = options.body;
14751
- }
14752
- request(requestOptions, (error, response2, body) => {
14753
- var _a2, _b2, _c2, _d2, _e2;
14754
- if (error) {
14755
- return resolve6({
14756
- error: true,
14757
- options: requestOptions,
14758
- status: -1,
14759
- message: (_a2 = error.message) != null ? _a2 : `Unknown Error`
14760
- });
14761
- }
14762
- if (response2.statusCode < 200 || response2.statusCode >= 300) {
14763
- return resolve6({
14764
- error: true,
14765
- options: requestOptions,
14766
- status: (_b2 = response2.statusCode) != null ? _b2 : -1,
14767
- message: `HTTP Status Code ${(_c2 = response2.statusCode) != null ? _c2 : `Unknown Status Code`} (${body})`
14768
- });
14769
- }
14770
- if (body == void 0 || body == null) {
14771
- return resolve6({
14772
- error: true,
14773
- options: requestOptions,
14774
- status: (_d2 = response2.statusCode) != null ? _d2 : -1,
14775
- message: `Empty Response Body`
14776
- });
14777
- }
14778
- resolve6({
14779
- error: false,
14780
- options: requestOptions,
14781
- status: (_e2 = response2.statusCode) != null ? _e2 : -1,
14782
- message: body
14783
- });
14784
- });
14785
- });
14786
- });
14752
+ // src/@modules/@eas/eas.getWavPCM16.ts
14753
+ var getWavPCM16 = (buffer) => {
14754
+ if (buffer.toString("ascii", 0, 4) !== "RIFF" || buffer.toString("ascii", 8, 12) !== "WAVE") {
14755
+ return null;
14756
+ }
14757
+ let fmt = null;
14758
+ let data = null;
14759
+ let i = 12;
14760
+ while (i + 8 <= buffer.length) {
14761
+ const id2 = buffer.toString("ascii", i, i + 4);
14762
+ const size = buffer.readUInt32LE(i + 4);
14763
+ const start = i + 8;
14764
+ const end = start + size;
14765
+ if (id2 === "fmt ") fmt = buffer.slice(start, end);
14766
+ if (id2 === "data") data = buffer.slice(start, end);
14767
+ i = end + size % 2;
14768
+ }
14769
+ if (!fmt || !data) return null;
14770
+ const audioFormat = fmt.readUInt16LE(0);
14771
+ const channels = fmt.readUInt16LE(2);
14772
+ const sampleRate = fmt.readUInt32LE(4);
14773
+ const bitsPerSample = fmt.readUInt16LE(14);
14774
+ if (audioFormat !== 1 || bitsPerSample !== 16 || channels !== 1) {
14775
+ return null;
14776
+ }
14777
+ const samples = new Int16Array(data.buffer, data.byteOffset, data.length / 2);
14778
+ return { samples: new Int16Array(samples), sampleRate, channels, bitsPerSample };
14779
+ };
14787
14780
 
14788
- // src/@manager/manager.createWebhook.ts
14789
- var import_form_data = __toESM(require_form_data());
14790
- var createWebhook = (options) => __async(null, null, function* () {
14791
- var _a, _b, _c, _d, _e, _f;
14792
- const event = options.event.properties;
14793
- const settings = options.webhook;
14794
- let body = [
14795
- event.locations ? `**Locations**: ${event.locations.slice(0, 100)}` : null,
14796
- event.issued && event.status != `Expired` ? `**Issued**: <t:${Math.floor(new Date(event.issued).getTime() / 1e3)}:R>` : null,
14797
- event.expires && event.status != `Statement` ? `**Expires**: <t:${Math.floor(new Date(event.expires).getTime() / 1e3)}:R>` : null,
14798
- (() => {
14799
- var _a2, _b2;
14800
- const val = (_a2 = event.parameters.estimated_wind_gusts) != null ? _a2 : null;
14801
- const th = (_b2 = event.parameters.wind_threat) != null ? _b2 : null;
14802
- const combined = [val, th].filter(Boolean).join(" ");
14803
- return combined ? `**Wind Gusts**: ${val} ${th ? `(${th})` : ""}` : null;
14804
- })(),
14805
- (() => {
14806
- var _a2, _b2;
14807
- const val = (_a2 = event.parameters.estimated_hail_size) != null ? _a2 : null;
14808
- const th = (_b2 = event.parameters.hail_threat) != null ? _b2 : null;
14809
- return (val != null ? val : th) ? `**Hail Threat**: ${val} ${th ? `(${th})` : ""}` : null;
14810
- })(),
14811
- event.parameters.damage_threat ? `**Damage Threat**: ${event.parameters.damage_threat}` : null,
14812
- event.parameters.flood_threat ? `**Flood Threat**: ${event.parameters.flood_threat}` : null,
14813
- event.parameters.tornado_threat ? `**Tornado Threat**: ${event.parameters.tornado_threat}` : null,
14814
- event.spc_parameters.spc_max_tornado ? `**Max Tornado Threat**: ${event.spc_parameters.spc_max_tornado}` : null,
14815
- event.spc_parameters.spc_max_hail ? `**Max Hail Threat**: ${event.spc_parameters.spc_max_hail}` : null,
14816
- event.spc_parameters.spc_max_wind ? `**Max Wind Threat**: ${event.spc_parameters.spc_max_wind}` : null,
14817
- event.spc_parameters.spc_watch_issuance ? `**Watch Issuance**: ${event.spc_parameters.spc_watch_issuance}%` : null,
14818
- event.watch_parameters.watch_number ? `**Watch Number**: ${event.watch_parameters.watch_number}` : null,
14819
- event.watch_parameters.strong_tornadoes_probability ? `**Strong Tornadoes Probability**: ${event.watch_parameters.strong_tornadoes_probability}%` : null,
14820
- event.watch_parameters.additional_tornadoes_probability ? `**Additional Tornadoes Probability**: ${event.watch_parameters.additional_tornadoes_probability}%` : null,
14821
- event.watch_parameters.combined_hail_wind_probability ? `**Combined Hail/Wind Probability**: ${event.watch_parameters.combined_hail_wind_probability}%` : null,
14822
- event.watch_parameters.severe_hail_probability ? `**Severe Hail Probability**: ${event.watch_parameters.severe_hail_probability}%` : null,
14823
- event.watch_parameters.hail_2in_probability ? `**Hail \u22652in Probability**: ${event.watch_parameters.hail_2in_probability}%` : null,
14824
- event.watch_parameters.max_hail_in ? `**Max Hail Inches**: ${event.watch_parameters.max_hail_in}` : null,
14825
- event.watch_parameters.severe_wind_probability ? `**Severe Wind Probability**: ${event.watch_parameters.severe_wind_probability}%` : null,
14826
- event.watch_parameters.max_wind_surface ? `**Max Surface Wind**: ${event.watch_parameters.max_wind_surface}` : null,
14827
- event.watch_parameters.max_tops_x100feet ? `**Max Tops (x100 feet)**: ${event.watch_parameters.max_tops_x100feet}` : null,
14828
- ((_a = event.parameters.tags) == null ? void 0 : _a.length) > 0 ? `**Tags**: ${event.parameters.tags.join(", ")}` : null,
14829
- (() => {
14830
- var _a2, _b2, _c2, _d2, _e2, _f2;
14831
- const val = (_c2 = (_b2 = (_a2 = event.geocode) == null ? void 0 : _a2.office) == null ? void 0 : _b2.name) != null ? _c2 : `N/A`;
14832
- const th = (_f2 = (_e2 = (_d2 = event.geocode) == null ? void 0 : _d2.office) == null ? void 0 : _e2.office) != null ? _f2 : null;
14833
- return (val != null ? val : th) ? `**Sender**: ${val} ${th ? `(${th})` : ""}` : null;
14834
- })(),
14835
- ((_b = event.metadata) == null ? void 0 : _b.tracking) ? `**Tracking**: ${event.metadata.tracking}` : null,
14836
- ((_c = event.metadata.history) == null ? void 0 : _c.length) > 0 ? `**Logs**: ${event.metadata.history.length}` : null,
14837
- (() => {
14838
- var _a2;
14839
- if (event.status == `Expired`) {
14840
- return null;
14841
- }
14842
- const desc = ((_a2 = event.description) != null ? _a2 : "").split("\n").map((l) => l.trim()).filter(Boolean).join("\n");
14843
- return desc ? "```\n" + desc + "\n```" : null;
14844
- })()
14845
- ].filter(Boolean).join("\n");
14846
- const isLimited = setTimeoutAction({ identifier: options.webhook.webhook, interval: options.webhook.rate, max: options.webhook.rate, addTime: true });
14847
- if (isLimited.limited) {
14848
- return;
14781
+ // src/@modules/@eas/eas.getSampledPCM16.ts
14782
+ var getSampledPCM16 = (int16, originalRate, targetRate) => {
14783
+ if (originalRate === targetRate) return int16;
14784
+ const ratio = targetRate / originalRate;
14785
+ const outLen = Math.max(1, Math.round(int16.length * ratio));
14786
+ const out = new Int16Array(outLen);
14787
+ for (let i = 0; i < outLen; i++) {
14788
+ const pos = i / ratio;
14789
+ const i0 = Math.floor(pos);
14790
+ const i1 = Math.min(i0 + 1, int16.length - 1);
14791
+ const frac = pos - i0;
14792
+ const v = int16[i0] * (1 - frac) + int16[i1] * frac;
14793
+ out[i] = Math.round(v);
14849
14794
  }
14850
- if (body.length > 1900) {
14851
- body = body.substring(0, 1900) + "\n\n[Message truncated due to length]";
14852
- const blocks = ((_d = body.match(/```/g)) != null ? _d : []).length;
14853
- if (blocks % 2 !== 0) body += "```";
14854
- }
14855
- const form = new import_form_data.default();
14856
- const embed = {
14857
- title: `${event.event} (${event.status})`,
14858
- description: body,
14859
- color: 16711680,
14860
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
14861
- footer: { text: settings.title }
14862
- };
14863
- form.append("payload_json", JSON.stringify({
14864
- username: (_e = settings.title) != null ? _e : "AtmosphericX",
14865
- content: (_f = settings.message) != null ? _f : "",
14866
- embeds: [embed]
14867
- }));
14868
- if (settings.upload) {
14869
- form.append("file", Buffer.from(JSON.stringify(getCleanedEvent(event), null, 2)), {
14870
- filename: `${event.event}_${event.status}_${event.metadata.tracking}.json`,
14871
- contentType: "application/json"
14872
- });
14795
+ return out;
14796
+ };
14797
+
14798
+ // src/@modules/@eas/eas.getPCMToFloat.ts
14799
+ var getPCMToFloat = (int16) => {
14800
+ const out = new Float32Array(int16.length);
14801
+ for (let i = 0; i < int16.length; i++) out[i] = int16[i] / 32768;
14802
+ return out;
14803
+ };
14804
+
14805
+ // src/@modules/@eas/eas.getFloatPCM16.ts
14806
+ var getFloatPCM16 = (float32) => {
14807
+ const out = new Int16Array(float32.length);
14808
+ for (let i = 0; i < float32.length; i++) {
14809
+ let v = Math.max(-1, Math.min(1, float32[i]));
14810
+ out[i] = Math.round(v * 32767);
14873
14811
  }
14874
- yield createHttp({
14875
- url: settings.webhook,
14876
- timeout: 2e3,
14877
- method: `POST`,
14878
- headers: form.getHeaders(),
14879
- body: form
14880
- });
14881
- });
14812
+ return out;
14813
+ };
14882
14814
 
14883
- // src/@manager/manager.updateWebhooks.ts
14884
- var updateWebhooks = (event) => __async(null, null, function* () {
14885
- const settings = bootstrap.settings;
14886
- const webhooks = settings.WebhookSettings;
14887
- const eventName = event.properties.event;
14888
- for (const socket of webhooks) {
14889
- const events = socket.events;
14890
- if (!events || events.length === 0) {
14891
- yield createWebhook({ webhook: socket, event });
14892
- continue;
14893
- }
14894
- const matched = events.some((pattern) => {
14895
- if (!pattern) return false;
14896
- if (pattern === "*" || pattern === eventName) return true;
14897
- if (pattern.includes("*")) {
14898
- const regex = "^" + pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*") + "$";
14899
- return new RegExp(regex).test(eventName);
14900
- }
14901
- return false;
14902
- });
14903
- if (matched) {
14904
- yield createWebhook({ webhook: socket, event });
14815
+ // src/@modules/@eas/eas.setRadioEffect.ts
14816
+ var setRadioEffect = (int16, sampleRate) => {
14817
+ const hpCut = 3555;
14818
+ const lpCut = 1600;
14819
+ const x = getPCMToFloat(int16);
14820
+ const dt = 1 / sampleRate;
14821
+ const rcHP = 1 / (2 * Math.PI * hpCut);
14822
+ const aHP = rcHP / (rcHP + dt);
14823
+ let yHP = 0, xPrev = 0;
14824
+ for (let i = 0; i < x.length; i++) {
14825
+ const xi = x[i];
14826
+ yHP = aHP * (yHP + xi - xPrev);
14827
+ xPrev = xi;
14828
+ x[i] = yHP;
14829
+ }
14830
+ const rcLP = 1 / (2 * Math.PI * lpCut);
14831
+ const aLP = dt / (rcLP + dt);
14832
+ let yLP = 0;
14833
+ for (let i = 0; i < x.length; i++) {
14834
+ yLP = yLP + aLP * (x[i] - yLP);
14835
+ x[i] = yLP;
14836
+ }
14837
+ const compGain = 2;
14838
+ const norm = Math.tanh(compGain);
14839
+ for (let i = 0; i < x.length; i++) x[i] = Math.tanh(x[i] * compGain) / norm;
14840
+ return getFloatPCM16(x);
14841
+ };
14842
+
14843
+ // src/@modules/@eas/eas.setAFSK.ts
14844
+ var setAFSK = (bits, sampleRate) => {
14845
+ const baud = 520.83;
14846
+ const markFreq = 2083.3;
14847
+ const spaceFreq = 1562.5;
14848
+ const amplitude = 0.6;
14849
+ const twoPi = Math.PI * 2;
14850
+ const result = [];
14851
+ let phase = 0;
14852
+ let frac = 0;
14853
+ for (let b = 0; b < bits.length; b++) {
14854
+ const bit = bits[b];
14855
+ const freq = bit ? markFreq : spaceFreq;
14856
+ const samplesPerBit = sampleRate / baud + frac;
14857
+ const n = Math.round(samplesPerBit);
14858
+ frac = samplesPerBit - n;
14859
+ const inc = twoPi * freq / sampleRate;
14860
+ for (let i = 0; i < n; i++) {
14861
+ result.push(Math.round(Math.sin(phase) * amplitude * 32767));
14862
+ phase += inc;
14863
+ if (phase > twoPi) phase -= twoPi;
14905
14864
  }
14906
14865
  }
14907
- });
14866
+ const fadeSamples = Math.floor(sampleRate * 2e-3);
14867
+ for (let i = 0; i < fadeSamples; i++) {
14868
+ const gain = i / fadeSamples;
14869
+ result[i] = Math.round(result[i] * gain);
14870
+ result[result.length - 1 - i] = Math.round(result[result.length - 1 - i] * gain);
14871
+ }
14872
+ return Int16Array.from(result);
14873
+ };
14908
14874
 
14909
- // src/@modules/@utilities/utilities.getShapeNearestPoint.ts
14910
- var getShapeNearestPoint = (coordinates, point) => {
14911
- if (!coordinates || !point) {
14912
- return { proximity: false, point: [0, 0], distance: null };
14875
+ // src/@modules/@eas/eas.setAsciiToBits.ts
14876
+ var setAsciiToBits = (str) => {
14877
+ const bits = [];
14878
+ for (let i = 0; i < str.length; i++) {
14879
+ const c = str.charCodeAt(i) & 255;
14880
+ bits.push(0);
14881
+ for (let b = 0; b < 8; b++) bits.push(c >> b & 1);
14882
+ bits.push(1, 1);
14913
14883
  }
14914
- const normalize = (coords) => {
14915
- if (!Array.isArray(coords)) return [];
14916
- if (typeof coords[0] === "number" && typeof coords[1] === "number") return [];
14917
- if (Array.isArray(coords[0]) && typeof coords[0][0] === "number") {
14918
- return [[coords]];
14919
- }
14920
- if (Array.isArray(coords[0]) && Array.isArray(coords[0][0]) && typeof coords[0][0][0] === "number") {
14921
- return [coords];
14922
- }
14923
- if (Array.isArray(coords[0]) && Array.isArray(coords[0][0]) && Array.isArray(coords[0][0][0]) && typeof coords[0][0][0][0] === "number") {
14924
- return coords;
14925
- }
14926
- return [];
14927
- };
14928
- const polys = normalize(coordinates);
14929
- if (polys.length === 0) return { proximity: false, point: [0, 0], distance: null };
14930
- const lon = point[0];
14931
- const lat = point[1];
14932
- const pointInRing = (pt, ring) => {
14933
- let x = pt[0], y = pt[1];
14934
- let inside = false;
14935
- for (let i = 0, j2 = ring.length - 1; i < ring.length; j2 = i++) {
14936
- const xi = ring[i][0], yi = ring[i][1];
14937
- const xj = ring[j2][0], yj = ring[j2][1];
14938
- const intersect = yi > y !== yj > y && x < (xj - xi) * (y - yi) / (yj - yi + 0) + xi;
14939
- if (intersect) inside = !inside;
14940
- }
14941
- return inside;
14942
- };
14943
- const toRadians = (deg) => deg * Math.PI / 180;
14944
- const haversineMiles = (a, b) => {
14945
- const R = 3958.8;
14946
- const dLat = toRadians(b[1] - a[1]);
14947
- const dLon = toRadians(b[0] - a[0]);
14948
- const lat1 = toRadians(a[1]);
14949
- const lat2 = toRadians(b[1]);
14950
- const sinDLat = Math.sin(dLat / 2);
14951
- const sinDLon = Math.sin(dLon / 2);
14952
- const c = 2 * Math.asin(Math.sqrt(sinDLat * sinDLat + Math.cos(lat1) * Math.cos(lat2) * sinDLon * sinDLon));
14953
- return R * c;
14954
- };
14955
- let minDistance = Infinity;
14956
- let closestPoint = null;
14957
- for (const poly of polys) {
14958
- const outer = poly[0];
14959
- const holes = poly.slice(1);
14960
- if (pointInRing(point, outer)) {
14961
- let inHole = false;
14962
- for (const hole of holes) {
14963
- if (pointInRing(point, hole)) {
14964
- inHole = true;
14965
- break;
14966
- }
14967
- }
14968
- if (!inHole) {
14969
- return { proximity: true, point, distance: 0 };
14970
- }
14971
- }
14972
- for (const ring of poly) {
14973
- for (let i = 0; i < ring.length - 1; i++) {
14974
- const start = [ring[i][0], ring[i][1]];
14975
- const end = [ring[i + 1][0], ring[i + 1][1]];
14976
- const A = lon - start[0];
14977
- const B = lat - start[1];
14978
- const C = end[0] - start[0];
14979
- const D = end[1] - start[1];
14980
- const lenSq = C * C + D * D;
14981
- const t = lenSq === 0 ? 0 : Math.max(0, Math.min(1, (A * C + B * D) / lenSq));
14982
- const candidate = [start[0] + t * C, start[1] + t * D];
14983
- const dist = haversineMiles([lon, lat], candidate);
14984
- if (!isNaN(dist) && dist < minDistance) {
14985
- minDistance = Number(dist.toFixed(3));
14986
- closestPoint = candidate;
14987
- }
14988
- }
14884
+ return bits;
14885
+ };
14886
+
14887
+ // src/@modules/@eas/eas.getMergedPCM16.ts
14888
+ var getMergedPCM16 = (arrays) => {
14889
+ let total = 0;
14890
+ for (const a of arrays) total += a.length;
14891
+ const out = new Int16Array(total);
14892
+ let o = 0;
14893
+ for (const a of arrays) {
14894
+ out.set(a, o);
14895
+ o += a.length;
14896
+ }
14897
+ return out;
14898
+ };
14899
+
14900
+ // src/@modules/@eas/eas.setSameHeader.ts
14901
+ var setSameHeader = (vtec2, repeats, sampleRate = 8e3, options = {}) => {
14902
+ var _a, _b;
14903
+ const preMarkSec = (_a = options.preMarkSec) != null ? _a : 0.3;
14904
+ const gapSec = (_b = options.gapSec) != null ? _b : 0.1;
14905
+ const bursts = [];
14906
+ const gap = new Int16Array(Math.floor(gapSec * sampleRate));
14907
+ for (let i = 0; i < repeats; i++) {
14908
+ const bodyBits = setAsciiToBits(vtec2);
14909
+ const body = setAFSK(bodyBits, sampleRate);
14910
+ const extendedBodyDuration = Math.round(preMarkSec * sampleRate);
14911
+ const extendedBody = new Int16Array(extendedBodyDuration + gap.length);
14912
+ for (let j2 = 0; j2 < extendedBodyDuration; j2++) {
14913
+ extendedBody[j2] = Math.round(body[j2 % body.length] * 0.2);
14989
14914
  }
14915
+ extendedBody.set(gap, extendedBodyDuration);
14916
+ bursts.push(extendedBody);
14917
+ if (i !== repeats - 1) bursts.push(gap);
14990
14918
  }
14991
- if (!isFinite(minDistance) || closestPoint == null) {
14992
- return { proximity: false, point: [0, 0], distance: null };
14919
+ return getMergedPCM16(bursts);
14920
+ };
14921
+
14922
+ // src/@modules/@eas/eas.setAttentionTone.ts
14923
+ var setAttentionTone = (ms, sampleRate) => {
14924
+ const len = Math.floor(ms * sampleRate);
14925
+ const out = new Int16Array(len);
14926
+ const f1 = 853;
14927
+ const f2 = 960;
14928
+ const twoPi = Math.PI * 2;
14929
+ const amp = 0.1;
14930
+ const fadeLen = Math.floor(sampleRate * 0);
14931
+ for (let i = 0; i < len; i++) {
14932
+ const t = i / sampleRate;
14933
+ const s = Math.sin(twoPi * f1 * t) + Math.sin(twoPi * f2 * t);
14934
+ let gain = 1;
14935
+ if (i < fadeLen) gain = i / fadeLen;
14936
+ else if (i > len - fadeLen) gain = (len - i) / fadeLen;
14937
+ const v = Math.max(-1, Math.min(1, s / 2 * amp * gain));
14938
+ out[i] = Math.round(v * 32767);
14993
14939
  }
14994
- const distanceMiles = minDistance;
14995
- const distanceKm = Number((distanceMiles * 1.609344).toFixed(3));
14996
- const distanceMeters = Math.round(distanceKm * 1e3);
14997
- return { proximity: distanceMiles === 0, point: closestPoint, distance: distanceMiles, distanceKm, distanceMeters };
14940
+ return out;
14998
14941
  };
14999
14942
 
15000
- // src/@building/building.polygon.ts
15001
- var getEventNodes = (event) => __async(null, null, function* () {
15002
- var _a, _b;
15003
- const metadata = { nodes: [], proximity: false, filtered: false };
15004
- const geometry = yield getEventGeometry(event);
15005
- if (!geometry || !geometry.coordinates) {
15006
- return { nodes: [], filtered: false, updated: Date.now() };
14943
+ // src/@modules/@eas/eas.setNoise.ts
14944
+ var setNoise = (int16, noiseLevel = 0.02) => {
14945
+ const x = getPCMToFloat(int16);
14946
+ for (let i = 0; i < x.length; i++) x[i] += (Math.random() * 2 - 1) * noiseLevel;
14947
+ let peak = 0;
14948
+ for (let i = 0; i < x.length; i++) peak = Math.max(peak, Math.abs(x[i]));
14949
+ if (peak > 1) for (let i = 0; i < x.length; i++) x[i] *= 0.98 / peak;
14950
+ return getFloatPCM16(x);
14951
+ };
14952
+
14953
+ // src/@modules/@eas/eas.getPCM16.ts
14954
+ var getPCM16 = (samples, sampleRate) => {
14955
+ let o = 0;
14956
+ const bytesPerSample = 2;
14957
+ const blockAlign = 1 * bytesPerSample;
14958
+ const byteRate = sampleRate * blockAlign;
14959
+ const subchunk2Size = samples.length * bytesPerSample;
14960
+ const chunkSize = 36 + subchunk2Size;
14961
+ const buffer = Buffer.alloc(44 + subchunk2Size);
14962
+ buffer.write("RIFF", o);
14963
+ o += 4;
14964
+ buffer.writeUInt32LE(chunkSize, o);
14965
+ o += 4;
14966
+ buffer.write("WAVE", o);
14967
+ o += 4;
14968
+ buffer.write("fmt ", o);
14969
+ o += 4;
14970
+ buffer.writeUInt32LE(16, o);
14971
+ o += 4;
14972
+ buffer.writeUInt16LE(1, o);
14973
+ o += 2;
14974
+ buffer.writeUInt16LE(1, o);
14975
+ o += 2;
14976
+ buffer.writeUInt32LE(sampleRate, o);
14977
+ o += 4;
14978
+ buffer.writeUInt32LE(byteRate, o);
14979
+ o += 4;
14980
+ buffer.writeUInt16LE(blockAlign, o);
14981
+ o += 2;
14982
+ buffer.writeUInt16LE(16, o);
14983
+ o += 2;
14984
+ buffer.write("data", o);
14985
+ o += 4;
14986
+ buffer.writeUInt32LE(subchunk2Size, o);
14987
+ o += 4;
14988
+ for (let i = 0; i < samples.length; i++, o += 2) {
14989
+ buffer.writeInt16LE(samples[i].value, o);
15007
14990
  }
15008
- const nodes = bootstrap.cache.nodes.features;
15009
- for (const node of nodes) {
15010
- const [longitude, latitude] = node.geometry.coordinates;
15011
- const getPoint = getShapeNearestPoint(geometry.coordinates, [longitude, latitude]);
15012
- const miles = (_a = getPoint.distance) != null ? _a : null;
15013
- const kilometers = Number((miles * 1.609344).toFixed(3));
15014
- const info = {
15015
- id: (_b = node.properties) == null ? void 0 : _b.identifier,
15016
- coordinates: [longitude, latitude],
15017
- nearest: getPoint.point,
15018
- miles,
15019
- kilometers,
15020
- proximity: getPoint.proximity
15021
- };
15022
- metadata.nodes.push(info);
15023
- if (bootstrap.settings.GlobalSettings.EventFiltering.NodeLocationFiltering && miles < bootstrap.settings.GlobalSettings.NodeMinDistance) {
15024
- metadata.proximity = true;
15025
- info.proximity = true;
14991
+ return buffer;
14992
+ };
14993
+
14994
+ // src/@modules/@eas/eas.getTTS.ts
14995
+ import { platform } from "os";
14996
+ import { writeFileSync } from "fs";
14997
+ import { execSync } from "child_process";
14998
+ var getTTS = (text2, outputPath) => __async(null, null, function* () {
14999
+ const vPlatform = platform();
15000
+ switch (vPlatform) {
15001
+ case "win32": {
15002
+ try {
15003
+ const txtPath = outputPath + ".txt";
15004
+ writeFileSync(txtPath, text2, "utf8");
15005
+ const command = [
15006
+ "Add-Type -AssemblyName System.Speech;",
15007
+ `$speak = New-Object System.Speech.Synthesis.SpeechSynthesizer;`,
15008
+ `$text = Get-Content -Raw -LiteralPath '${txtPath}';`,
15009
+ `$speak.SetOutputToWaveFile('${outputPath}');`,
15010
+ `$speak.Speak($text);`,
15011
+ `$speak.Dispose();`
15012
+ ].join(" ");
15013
+ execSync(`powershell -Command "${command}"`, { stdio: "inherit" });
15014
+ } catch (error) {
15015
+ console.error("Error occurred while generating TTS:", error);
15016
+ }
15017
+ break;
15026
15018
  }
15019
+ case "linux":
15020
+ try {
15021
+ execSync(`espeak -w "${outputPath}" "${text2.replace(/"/g, '\\"')}"`);
15022
+ } catch (e) {
15023
+ }
15024
+ break;
15025
+ default:
15026
+ break;
15027
15027
  }
15028
- return {
15029
- nodes: metadata.nodes,
15030
- filtered: metadata.proximity,
15031
- updated: Date.now()
15032
- };
15033
15028
  });
15034
15029
 
15035
- // src/@manager/manager.updateNodes.ts
15036
- var updateNode = (selectedEvent) => __async(null, null, function* () {
15037
- const events = bootstrap.cache.events.features;
15038
- const ttl = bootstrap.settings.GlobalSettings.NodeTTL * 1e3;
15039
- let total = 0;
15040
- function update(evt) {
15041
- return __async(this, null, function* () {
15042
- var _a, _b, _c;
15043
- const lastUpdate = (_c = (_b = (_a = evt == null ? void 0 : evt.properties) == null ? void 0 : _a.metadata) == null ? void 0 : _b.updated) != null ? _c : null;
15044
- if (lastUpdate != null && Date.now() - lastUpdate < ttl) {
15045
- return evt;
15046
- }
15047
- const node = yield getEventNodes(evt);
15048
- if (node.nodes.length > 0) {
15049
- total++;
15050
- }
15051
- evt.properties.metadata.nodes = node.nodes;
15052
- evt.properties.metadata.filtered_proximity = node.filtered;
15053
- evt.properties.metadata.updated = node.updated;
15030
+ // src/@modules/@eas/eas.getCleanDescription.ts
15031
+ var getCleanDescription = (message) => {
15032
+ const patches = [
15033
+ { regex: /\.{3,}/g, replacement: ". " },
15034
+ { regex: /\bUTC\b/g, replacement: "Coordinated Universal Time" },
15035
+ { regex: /\bGMT\b/g, replacement: "Greenwich Mean Time" },
15036
+ { regex: /\bEST\b(?!\w)/g, replacement: "Eastern Standard Time" },
15037
+ { regex: /\bEDT\b(?!\w)/g, replacement: "Eastern Daylight Time" },
15038
+ { regex: /\bCST\b(?!\w)/g, replacement: "Central Standard Time" },
15039
+ { regex: /\bCDT\b(?!\w)/g, replacement: "Central Daylight Time" },
15040
+ { regex: /\bMST\b(?!\w)/g, replacement: "Mountain Standard Time" },
15041
+ { regex: /\bMDT\b(?!\w)/g, replacement: "Mountain Daylight Time" },
15042
+ { regex: /\bPST\b(?!\w)/g, replacement: "Pacific Standard Time" },
15043
+ { regex: /\bPDT\b(?!\w)/g, replacement: "Pacific Daylight Time" },
15044
+ { regex: /\bAKST\b(?!\w)/g, replacement: "Alaska Standard Time" },
15045
+ { regex: /\bAKDT\b(?!\w)/g, replacement: "Alaska Daylight Time" },
15046
+ { regex: /\bHST\b(?!\w)/g, replacement: "Hawaii Standard Time" },
15047
+ { regex: /\bHDT\b(?!\w)/g, replacement: "Hawaii Daylight Time" },
15048
+ { regex: /\bmph\b(?!\w)/g, replacement: "miles per hour" },
15049
+ { regex: /\bkm\/h\b(?!\w)/g, replacement: "kilometers per hour" },
15050
+ { regex: /\bkmh\b(?!\w)/g, replacement: "kilometers per hour" },
15051
+ { regex: /\bkt\b(?!\w)/g, replacement: "knots" },
15052
+ { regex: /\bNE\b(?!\w)/g, replacement: "northeast" },
15053
+ { regex: /\bNW\b(?!\w)/g, replacement: "northwest" },
15054
+ { regex: /\bSE\b(?!\w)/g, replacement: "southeast" },
15055
+ { regex: /\bSW\b(?!\w)/g, replacement: "southwest" },
15056
+ { regex: /\bNM\b(?!\w)/g, replacement: "nautical miles" },
15057
+ { regex: /\bdeg\b(?!\w)/g, replacement: "degrees" },
15058
+ { regex: /\btstm\b(?!\w)/g, replacement: "thunderstorm" },
15059
+ { regex: /\bmm\b(?!\w)/g, replacement: "millimeters" },
15060
+ { regex: /\bcm\b(?!\w)/g, replacement: "centimeters" },
15061
+ { regex: /\bin.\b(?!\w)/g, replacement: "inches" },
15062
+ { regex: /\bft\b(?!\w)/g, replacement: "feet" },
15063
+ { regex: /\bmi\b(?!\w)/g, replacement: "miles" },
15064
+ { regex: /\bhr\b(?!\w)/g, replacement: "hour" },
15065
+ { regex: /\bhourly\b(?!\w)/g, replacement: "per hour" },
15066
+ { regex: /\bkg\b(?!\w)/g, replacement: "kilograms" },
15067
+ { regex: /\bg\/kg\b(?!\w)/g, replacement: "grams per kilogram" },
15068
+ { regex: /\bmb\b(?!\w)/g, replacement: "millibars" },
15069
+ { regex: /\bhPa\b(?!\w)/g, replacement: "hectopascals" },
15070
+ { regex: /\bPa\b(?!\w)/g, replacement: "pascals" },
15071
+ { regex: /\bKPa\b(?!\w)/g, replacement: "kilopascals" },
15072
+ { regex: /\bC\/hr\b(?!\w)/g, replacement: "degrees Celsius per hour" },
15073
+ { regex: /\bF\/hr\b(?!\w)/g, replacement: "degrees Fahrenheit per hour" },
15074
+ { regex: /\bC\/min\b(?!\w)/g, replacement: "degrees Celsius per minute" },
15075
+ { regex: /\bF\/min\b(?!\w)/g, replacement: "degrees Fahrenheit per minute" },
15076
+ { regex: /\bC\b(?!\w)/g, replacement: "degrees Celsius" },
15077
+ { regex: /\bF\b(?!\w)/g, replacement: "degrees Fahrenheit" }
15078
+ ];
15079
+ const hours = {
15080
+ 0: "twelve",
15081
+ 1: "one",
15082
+ 2: "two",
15083
+ 3: "three",
15084
+ 4: "four",
15085
+ 5: "five",
15086
+ 6: "six",
15087
+ 7: "seven",
15088
+ 8: "eight",
15089
+ 9: "nine",
15090
+ 10: "ten",
15091
+ 11: "eleven",
15092
+ 12: "twelve"
15093
+ };
15094
+ const minWord = (m) => m === 0 ? "o'clock" : m < 10 ? `oh ${m}` : `${m}`;
15095
+ const fmt = (h, m, ap) => `${hours[h % 12]} ${minWord(m)} ${ap}`;
15096
+ for (const { regex, replacement } of patches) {
15097
+ message = message.replace(regex, replacement);
15098
+ }
15099
+ return message.replace(/'/g, "''").replace(/\b(\d{1,2}):(\d{2})\s*(AM|PM)\b/gi, (_, h, m, ap) => fmt(+h, +m, ap.toUpperCase())).replace(/\b(\d{1,2})\s+(\d{2})\s+(AM|PM)\b/gi, (_, h, m, ap) => fmt(+h, +m, ap.toUpperCase())).replace(/\b(\d{2})(\d{2})\s+(AM|PM)\b/gi, (_, hh, mm, ap) => fmt(+hh, +mm, ap.toUpperCase())).replace(/\b(\d{1,2})\s+(AM|PM)\b/gi, (_, h, ap) => fmt(+h, 0, ap.toUpperCase())).replace(/\*+/g, " ").replace(/-/g, " ").replace(/\n/g, " ").trim();
15100
+ };
15101
+
15102
+ // src/@modules/@eas/eas.setEasTone.ts
15103
+ import { join } from "path";
15104
+ import { existsSync, mkdirSync, readFileSync, writeFileSync as writeFileSync2, unlinkSync } from "fs";
15105
+ import { execSync as execSync2 } from "child_process";
15106
+ import { platform as platform2 } from "os";
15107
+ var setEasTone = (options) => __async(null, null, function* () {
15108
+ var _a;
15109
+ const settings = bootstrap.settings;
15110
+ const directory = settings.GlobalSettings.ArchiveSettings.EasDirectory;
15111
+ const prefix = settings.GlobalSettings.ArchiveSettings.EasToneout;
15112
+ let message = options.message;
15113
+ let header = options.header;
15114
+ let title = (_a = options.title) != null ? _a : `${Math.random().toString(36).substring(2, 15)}-${header.replace(/[^a-zA-Z0-9]/g, "")}`;
15115
+ if (!message || !header) {
15116
+ setWarning({
15117
+ title: `EAS`,
15118
+ message: `Message and header are required to generate an EAS tone.`
15054
15119
  });
15120
+ return null;
15055
15121
  }
15056
- if (!selectedEvent) {
15057
- yield Promise.all(events.map((evt) => __async(null, null, function* () {
15058
- yield update(evt);
15059
- })));
15122
+ let buffTTS;
15123
+ let buffRadio;
15124
+ let buffFull = [];
15125
+ if (!existsSync(directory)) {
15126
+ mkdirSync(directory, { recursive: true });
15060
15127
  }
15061
- if (selectedEvent) {
15062
- yield update(selectedEvent);
15128
+ if (!existsSync(join(directory, `/tts`))) {
15129
+ mkdirSync(join(directory, `/tts`), { recursive: true });
15063
15130
  }
15064
- if (total > 0) {
15065
- setEventEmit({
15066
- event: `onNodeUpdate`,
15067
- metadata: {
15068
- type: `global-update`,
15069
- updated: total
15070
- }
15131
+ if (!existsSync(join(directory, `/encoded`))) {
15132
+ mkdirSync(join(directory, `/encoded`), { recursive: true });
15133
+ }
15134
+ const tmpTTS = join(directory, `/tts/${title}.wav`);
15135
+ const outTTS = join(directory, `/encoded/${title}.wav`);
15136
+ const vPlatform = platform2();
15137
+ if (vPlatform === "darwin") {
15138
+ setWarning({
15139
+ title: `EAS`,
15140
+ message: `EAS tone generation is not supported on macOS.`
15071
15141
  });
15142
+ return null;
15072
15143
  }
15073
- });
15074
-
15075
- // src/@manager/manager.mkEvent.ts
15076
- var mkEvent = (event) => __async(null, null, function* () {
15077
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w;
15078
- const settings = bootstrap.settings;
15079
- const features = bootstrap.cache.events.features;
15080
- const getHash = event.properties.metadata.hash;
15081
- const getTracking = event.properties.metadata.tracking;
15082
- const isEntry = (_a = bootstrap.cache.hashes) == null ? void 0 : _a.find((hash) => hash.tracking === getTracking);
15083
- const isHashed = (_c = (_b = isEntry == null ? void 0 : isEntry.hashes) == null ? void 0 : _b.includes(getHash)) != null ? _c : false;
15084
- const getFeature = features.find((feature) => feature.properties.metadata.tracking === getTracking);
15085
- if (isHashed || event.properties.status_metadata.is_expired) return;
15086
- setHash(event, isEntry);
15087
- const isFilteredLocation = yield updateNode(event).then(() => event.properties.metadata.filtered_proximity);
15088
- if (!isFilteredLocation && settings.GlobalSettings.EventFiltering.NodeLocationFiltering) {
15089
- return;
15090
- }
15091
- setEventEmit({
15092
- event: `onEventStatus`,
15093
- metadata: {
15094
- type: getFeature ? `Updated` : `New`,
15095
- event
15096
- },
15097
- message: `[${getFeature ? "Updated" : "New"}] ${event.properties.event} (${event.properties.status}) (${event.properties.metadata.tracking})`
15144
+ yield new Promise((resolve6, reject) => {
15145
+ const tMsg = getCleanDescription(message);
15146
+ getTTS(tMsg, tmpTTS).then(() => {
15147
+ resolve6();
15148
+ });
15098
15149
  });
15099
- if (settings.GlobalSettings.EventManagement) {
15100
- if (event.properties.status_metadata.is_issued || event.properties.status_metadata.is_updated) {
15101
- if (getFeature) {
15102
- const getIndex = features.indexOf(getFeature);
15103
- const cHistory = (_f = (_e = (_d = getFeature == null ? void 0 : getFeature.properties) == null ? void 0 : _d.metadata) == null ? void 0 : _e.history) != null ? _f : [];
15104
- const cLocations = (_i = (_h = (_g = getFeature == null ? void 0 : getFeature.properties) == null ? void 0 : _g.locations) == null ? void 0 : _h.split(";").map((l) => l.trim())) != null ? _i : [];
15105
- const cUgc = (_l = (_k = (_j = getFeature == null ? void 0 : getFeature.properties) == null ? void 0 : _j.geocode) == null ? void 0 : _k.ugc) != null ? _l : [];
15106
- const iHistory = (_o = (_n = (_m = event.properties) == null ? void 0 : _m.metadata) == null ? void 0 : _n.history) != null ? _o : [];
15107
- const iLocations = (_r = (_q = (_p = event.properties) == null ? void 0 : _p.locations) == null ? void 0 : _q.split(";").map((l) => l.trim())) != null ? _r : [];
15108
- const iUgc = (_u = (_t = (_s = event.properties) == null ? void 0 : _s.geocode) == null ? void 0 : _t.ugc) != null ? _u : [];
15109
- const mHistory = [...cHistory, ...iHistory].filter((v, i, a) => a.indexOf(v) === i).filter((v, i, a) => a.findIndex((h) => h.description === v.description && h.issued === v.issued) === i);
15110
- const mLocations = [...cLocations, ...iLocations].filter((v, i, a) => a.indexOf(v) === i).join("; ");
15111
- const mUgc = [...cUgc, ...iUgc].filter((v, i, a) => a.indexOf(v) === i);
15112
- bootstrap.cache.events.features[getIndex] = __spreadProps(__spreadValues({}, event), {
15113
- properties: __spreadProps(__spreadValues({}, event.properties), {
15114
- metadata: __spreadProps(__spreadValues({}, (_v = event == null ? void 0 : event.properties) == null ? void 0 : _v.metadata), {
15115
- history: mHistory
15116
- }),
15117
- locations: mLocations,
15118
- geocode: __spreadProps(__spreadValues({}, (_w = event == null ? void 0 : event.properties) == null ? void 0 : _w.geocode), {
15119
- ugc: mUgc
15120
- })
15121
- })
15122
- });
15123
- updateWebhooks(bootstrap.cache.events.features[getIndex]);
15124
- } else {
15125
- features.push(event);
15126
- updateWebhooks(event);
15150
+ if (!existsSync(tmpTTS)) {
15151
+ return null;
15152
+ }
15153
+ buffTTS = readFileSync(tmpTTS);
15154
+ const vWav = getWavPCM16(buffTTS);
15155
+ const vSamples = getSampledPCM16(vWav.samples, vWav.sampleRate, 8e3);
15156
+ const vRadio = setRadioEffect(vSamples, 8e3);
15157
+ if (existsSync(prefix)) {
15158
+ let tBuffer = readFileSync(prefix);
15159
+ let tWav = getWavPCM16(tBuffer);
15160
+ if (tWav == null) {
15161
+ try {
15162
+ const converted = join(directory, `/tts/${title}.converted.wav`);
15163
+ execSync2(`ffmpeg -y -i "${prefix}" -ar 8000 -ac 1 -sample_fmt s16 "${converted}"`, { stdio: "ignore" });
15164
+ if (existsSync(converted)) {
15165
+ tBuffer = readFileSync(converted);
15166
+ tWav = getWavPCM16(tBuffer);
15167
+ try {
15168
+ unlinkSync(converted);
15169
+ } catch (e) {
15170
+ }
15171
+ }
15172
+ } catch (e) {
15127
15173
  }
15128
15174
  }
15175
+ if (tWav == null) {
15176
+ setWarning({ title: `EAS`, message: `Intro tone isn't a valid .WAV file or isn't in PCM 16-bit format. Converted attempt failed; please convert it then try again.` });
15177
+ return null;
15178
+ }
15179
+ const tSamples = tWav.sampleRate != 8e3 ? getSampledPCM16(tWav.samples, tWav.sampleRate, 8e3) : tWav.samples;
15180
+ buffRadio = setRadioEffect(tSamples, 8e3);
15181
+ }
15182
+ buffFull = buffRadio != null ? [buffRadio, new Int16Array(Math.floor(0.5 * 8e3))] : [];
15183
+ buffFull.push(
15184
+ setSameHeader(header, 3, 8e3, {
15185
+ preMarkSec: 1.1,
15186
+ gapSec: 0.5
15187
+ }),
15188
+ new Int16Array(Math.floor(0.5 * 8e3)),
15189
+ setAttentionTone(8, 8e3),
15190
+ new Int16Array(Math.floor(0.5 * 8e3)),
15191
+ vRadio
15192
+ );
15193
+ for (let i = 0; i < 3; i++) {
15194
+ buffFull.push(setSameHeader(header, 1, 8e3, { preMarkSec: 0.5, gapSec: 0.1 }));
15195
+ buffFull.push(new Int16Array(Math.floor(0.5 * 8e3)));
15196
+ }
15197
+ const aSamples = getMergedPCM16(buffFull);
15198
+ const aFinal = setNoise(aSamples, 2e-3);
15199
+ const aBuffer = getPCM16(Array.from(aFinal).map((v) => ({ value: v })), 8e3);
15200
+ writeFileSync2(outTTS, aBuffer);
15201
+ try {
15202
+ unlinkSync(tmpTTS);
15203
+ } catch (e) {
15129
15204
  }
15205
+ return outTTS;
15130
15206
  });
15131
15207
 
15132
- // src/@manager/manager.rmEvent.ts
15133
- var rmEvent = (event) => {
15134
- const getEvent = bootstrap.cache.events.features.find((f) => {
15135
- var _a, _b, _c, _d;
15136
- 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);
15137
- });
15138
- const cachedStatus = event.properties.status;
15139
- event.properties.expires = (/* @__PURE__ */ new Date()).toISOString();
15140
- event.properties.status = `Expired`;
15141
- if (getEvent) {
15142
- setEventEmit({
15143
- event: `onEventStatus`,
15144
- metadata: {
15145
- type: `Removed`,
15146
- event
15147
- },
15148
- message: `[Removed] ${event.properties.event} (${event.properties.status}) (${event.properties.metadata.tracking})`
15149
- });
15150
- setEventEmit({ event: `onExpiredProduct`, metadata: event });
15151
- if (cachedStatus != `Statement`) updateWebhooks(event);
15152
- bootstrap.cache.events.features.splice(bootstrap.cache.events.features.indexOf(getEvent), 1);
15153
- bootstrap.cache.hashes = bootstrap.cache.hashes.filter((hash) => hash.tracking !== event.properties.metadata.tracking);
15154
- }
15155
- setEventEmit({
15156
- event: `onEventCache`,
15157
- metadata: bootstrap.cache.events,
15158
- limited: true
15159
- });
15208
+ // src/@parsers/@text/text.getEmbed.ts
15209
+ var getEmebed = (event) => {
15210
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, __, _$, _aa, _ba, _ca, _da, _ea, _fa, _ga, _ha, _ia, _ja, _ka, _la, _ma, _na, _oa, _pa, _qa, _ra, _sa, _ta, _ua, _va, _wa, _xa, _ya, _za, _Aa, _Ba, _Ca, _Da, _Ea, _Fa, _Ga, _Ha, _Ia, _Ja, _Ka, _La, _Ma, _Na, _Oa, _Pa, _Qa, _Ra, _Sa, _Ta, _Ua;
15211
+ const line = (label, value, condition = true) => condition && value ? `${label} ${value}` : null;
15212
+ const isStatement = event.properties.status_metadata.is_statement;
15213
+ const isExpired = event.properties.status_metadata.is_expired;
15214
+ return [
15215
+ line(`**Locations:**`, (_b = (_a = event == null ? void 0 : event.properties) == null ? void 0 : _a.locations) == null ? void 0 : _b.slice(0, 100)),
15216
+ line(`**Issued:**`, `<t:${Math.floor(new Date(event.properties.issued).getTime() / 1e3)}:R>`, !isExpired),
15217
+ line(`**Expires:**`, `<t:${Math.floor(new Date(event.properties.expires).getTime() / 1e3)}:R>`, !isStatement),
15218
+ line(`**Damage Threat:**`, (_d = (_c = event == null ? void 0 : event.properties) == null ? void 0 : _c.parameters) == null ? void 0 : _d.damage_threat, !isExpired),
15219
+ line(`**Flood Threat:**`, (_f = (_e = event == null ? void 0 : event.properties) == null ? void 0 : _e.parameters) == null ? void 0 : _f.flood_threat, !isExpired),
15220
+ line(`**Tornado Threat:**`, (_h = (_g = event == null ? void 0 : event.properties) == null ? void 0 : _g.parameters) == null ? void 0 : _h.tornado_threat, !isExpired),
15221
+ line(`**Estimated Wind Gusts:**`, `${(_j = (_i = event == null ? void 0 : event.properties) == null ? void 0 : _i.parameters) == null ? void 0 : _j.estimated_wind_gusts} ${((_l = (_k = event == null ? void 0 : event.properties) == null ? void 0 : _k.parameters) == null ? void 0 : _l.wind_threat) ? ` (${(_n = (_m = event == null ? void 0 : event.properties) == null ? void 0 : _m.parameters) == null ? void 0 : _n.wind_threat})` : ""}`, !isExpired && ((_p = (_o = event == null ? void 0 : event.properties) == null ? void 0 : _o.parameters) == null ? void 0 : _p.estimated_wind_gusts) != null),
15222
+ line(`**Estimated Hail Size:**`, `${(_r = (_q = event == null ? void 0 : event.properties) == null ? void 0 : _q.parameters) == null ? void 0 : _r.estimated_hail_size} ${((_t = (_s = event == null ? void 0 : event.properties) == null ? void 0 : _s.parameters) == null ? void 0 : _t.hail_threat) ? ` (${(_v = (_u = event == null ? void 0 : event.properties) == null ? void 0 : _u.parameters) == null ? void 0 : _v.hail_threat})` : ""}`, !isExpired && ((_x = (_w = event == null ? void 0 : event.properties) == null ? void 0 : _w.parameters) == null ? void 0 : _x.estimated_hail_size) != null),
15223
+ line(`**Discussion:**`, (_z = (_y = event == null ? void 0 : event.properties) == null ? void 0 : _y.discussion_parameters) == null ? void 0 : _z.discussion_number, !isExpired),
15224
+ line(`**Concern:**`, (_B = (_A = event == null ? void 0 : event.properties) == null ? void 0 : _A.discussion_parameters) == null ? void 0 : _B.discussion_concerning, !isExpired),
15225
+ line(`**SPC Max Tornado Threat:**`, (_D = (_C = event == null ? void 0 : event.properties) == null ? void 0 : _C.discussion_parameters) == null ? void 0 : _D.discussion_max_tornado, !isExpired),
15226
+ line(`**SPC Max Hail Threat:**`, (_F = (_E = event == null ? void 0 : event.properties) == null ? void 0 : _E.discussion_parameters) == null ? void 0 : _F.discussion_max_hail, !isExpired),
15227
+ line(`**SPC Max Wind Threat:**`, (_H = (_G = event == null ? void 0 : event.properties) == null ? void 0 : _G.discussion_parameters) == null ? void 0 : _H.discussion_max_wind, !isExpired),
15228
+ line(`**SPC Watch Issuance Probability:**`, ((_J = (_I = event == null ? void 0 : event.properties) == null ? void 0 : _I.discussion_parameters) == null ? void 0 : _J.discussion_watch_issuance) ? `${(_L = (_K = event == null ? void 0 : event.properties) == null ? void 0 : _K.discussion_parameters) == null ? void 0 : _L.discussion_watch_issuance}%` : null, !isExpired),
15229
+ line(`**Watch Number:**`, (_N = (_M = event == null ? void 0 : event.properties) == null ? void 0 : _M.watch_parameters) == null ? void 0 : _N.watch_number, !isExpired),
15230
+ line(`**Strong Tornadoes Probability:**`, ((_P = (_O = event == null ? void 0 : event.properties) == null ? void 0 : _O.watch_parameters) == null ? void 0 : _P.strong_tornadoes_probability) ? `${(_R = (_Q = event == null ? void 0 : event.properties) == null ? void 0 : _Q.watch_parameters) == null ? void 0 : _R.strong_tornadoes_probability}%` : null, !isExpired),
15231
+ line(`**Additional Tornadoes Probability:**`, ((_T = (_S = event == null ? void 0 : event.properties) == null ? void 0 : _S.watch_parameters) == null ? void 0 : _T.additional_tornadoes_probability) ? `${(_V = (_U = event == null ? void 0 : event.properties) == null ? void 0 : _U.watch_parameters) == null ? void 0 : _V.additional_tornadoes_probability}%` : null, !isExpired),
15232
+ line(`**Combined Hail/Wind Probability:**`, ((_X = (_W = event == null ? void 0 : event.properties) == null ? void 0 : _W.watch_parameters) == null ? void 0 : _X.combined_hail_wind_probability) ? `${(_Z = (_Y = event == null ? void 0 : event.properties) == null ? void 0 : _Y.watch_parameters) == null ? void 0 : _Z.combined_hail_wind_probability}%` : null, !isExpired),
15233
+ line(`**Severe Hail Probability:**`, ((_$ = (__ = event == null ? void 0 : event.properties) == null ? void 0 : __.watch_parameters) == null ? void 0 : _$.severe_hail_probability) ? `${(_ba = (_aa = event == null ? void 0 : event.properties) == null ? void 0 : _aa.watch_parameters) == null ? void 0 : _ba.severe_hail_probability}%` : null, !isExpired),
15234
+ line(`**Hail >2in Probability:**`, ((_da = (_ca = event == null ? void 0 : event.properties) == null ? void 0 : _ca.watch_parameters) == null ? void 0 : _da.hail_2in_probability) ? `${(_fa = (_ea = event == null ? void 0 : event.properties) == null ? void 0 : _ea.watch_parameters) == null ? void 0 : _fa.hail_2in_probability}%` : null, !isExpired),
15235
+ line(`**Max Hail Inches:**`, (_ha = (_ga = event == null ? void 0 : event.properties) == null ? void 0 : _ga.watch_parameters) == null ? void 0 : _ha.max_hail_in, !isExpired),
15236
+ line(`**Severe Wind Probability:**`, ((_ja = (_ia = event == null ? void 0 : event.properties) == null ? void 0 : _ia.watch_parameters) == null ? void 0 : _ja.severe_wind_probability) ? `${(_la = (_ka = event == null ? void 0 : event.properties) == null ? void 0 : _ka.watch_parameters) == null ? void 0 : _la.severe_wind_probability}%` : null, !isExpired),
15237
+ line(`**Max Surface Wind:**`, (_na = (_ma = event == null ? void 0 : event.properties) == null ? void 0 : _ma.watch_parameters) == null ? void 0 : _na.max_wind_surface, !isExpired),
15238
+ line(`**Max Tops (x100 feet):**`, (_pa = (_oa = event == null ? void 0 : event.properties) == null ? void 0 : _oa.watch_parameters) == null ? void 0 : _pa.max_tops_x100feet, !isExpired),
15239
+ line(`**Tags:**`, ((_sa = (_ra = (_qa = event == null ? void 0 : event.properties) == null ? void 0 : _qa.parameters) == null ? void 0 : _ra.tags) == null ? void 0 : _sa.length) > 0 ? (_ua = (_ta = event == null ? void 0 : event.properties) == null ? void 0 : _ta.parameters) == null ? void 0 : _ua.tags.join(", ") : null, !isExpired),
15240
+ line(`**Sender:**`, ((_xa = (_wa = (_va = event == null ? void 0 : event.properties) == null ? void 0 : _va.geocode) == null ? void 0 : _wa.office) == null ? void 0 : _xa.name) ? `${(_Aa = (_za = (_ya = event == null ? void 0 : event.properties) == null ? void 0 : _ya.geocode) == null ? void 0 : _za.office) == null ? void 0 : _Aa.name} (${(_Da = (_Ca = (_Ba = event == null ? void 0 : event.properties) == null ? void 0 : _Ba.geocode) == null ? void 0 : _Ca.office) == null ? void 0 : _Da.office})` : (_Ga = (_Fa = (_Ea = event == null ? void 0 : event.properties) == null ? void 0 : _Ea.geocode) == null ? void 0 : _Fa.office) == null ? void 0 : _Ga.office),
15241
+ line(`**Tracking:**`, (_Ia = (_Ha = event == null ? void 0 : event.properties) == null ? void 0 : _Ha.metadata) == null ? void 0 : _Ia.tracking),
15242
+ line(`**Logs:**`, ((_La = (_Ka = (_Ja = event == null ? void 0 : event.properties) == null ? void 0 : _Ja.metadata) == null ? void 0 : _Ka.history) == null ? void 0 : _La.length) > 0 ? (_Na = (_Ma = event == null ? void 0 : event.properties) == null ? void 0 : _Ma.metadata) == null ? void 0 : _Na.history.length : null),
15243
+ line(``, ((_Qa = (_Pa = (_Oa = event == null ? void 0 : event.properties) == null ? void 0 : _Oa.metadata) == null ? void 0 : _Pa.attachments) == null ? void 0 : _Qa.length) > 0 ? `**Attachments:** ${(_Sa = (_Ra = event == null ? void 0 : event.properties) == null ? void 0 : _Ra.metadata) == null ? void 0 : _Sa.attachments.map((attachment) => {
15244
+ var _a2, _b2;
15245
+ return `[Attachment #${((_b2 = (_a2 = event == null ? void 0 : event.properties) == null ? void 0 : _a2.metadata) == null ? void 0 : _b2.attachments.indexOf(attachment)) + 1}](${attachment})`;
15246
+ }).join(" | ")}` : null),
15247
+ line(``, ((_Ta = event == null ? void 0 : event.properties) == null ? void 0 : _Ta.description) ? "```\n" + ((_Ua = event == null ? void 0 : event.properties) == null ? void 0 : _Ua.description.split("\n").map((l) => l.trim()).filter(Boolean).join("\n")) + "\n```" : null, !isExpired)
15248
+ ].filter(Boolean).join("\n");
15160
15249
  };
15161
15250
 
15162
- // src/@building/building.validate.ts
15163
- var validateEvents = (events) => __async(null, null, function* () {
15164
- var _a;
15165
- if (events.length === 0) return;
15166
- const configurations = bootstrap.settings;
15167
- const sets = {};
15168
- const bools = {};
15169
- const megered = __spreadValues(__spreadValues({}, configurations.GlobalSettings), configurations.GlobalSettings.EventFiltering);
15170
- for (const key in megered) {
15171
- const setting = megered[key];
15172
- if (Array.isArray(setting)) {
15173
- sets[key] = new Set(setting.map((item) => item.toLowerCase()));
15174
- }
15175
- if (typeof setting === "boolean") {
15176
- bools[key] = setting;
15177
- }
15178
- }
15179
- const filterd = events.filter((event) => {
15180
- var _a2, _b, _c, _d, _e;
15181
- const define2 = getEventSignature(event);
15182
- const properties2 = define2.properties;
15183
- const zones = properties2.geocode.ugc;
15184
- const icao = properties2.geocode.office.office;
15185
- const enhancedEventName = properties2.event = getEventEnhancedName(event);
15186
- const filteredProperties = JSON.parse(JSON.stringify(properties2));
15187
- if ((filteredProperties == null ? void 0 : filteredProperties.metadata) && "ms" in filteredProperties.metadata) {
15188
- delete filteredProperties.metadata.ms;
15189
- }
15190
- filteredProperties.metadata = (_a2 = filteredProperties.metadata) != null ? _a2 : {};
15191
- properties2.metadata.hash = createHash("sha256").update(JSON.stringify(filteredProperties)).digest("hex");
15192
- setEventEmit({ event: `onProductType${enhancedEventName.replace(/\s+/g, "")}`, metadata: define2 });
15193
- if (properties2.status_metadata.is_test) {
15194
- setEventEmit({ event: `onTestProduct`, metadata: define2 });
15195
- if (bools == null ? void 0 : bools.IgnoreTestProducts) return false;
15196
- }
15197
- if (properties2.status_metadata.is_expired) {
15198
- setEventEmit({ event: `onExpiredProduct`, metadata: define2 });
15199
- rmEvent(define2);
15200
- return false;
15201
- }
15202
- if ((_c = (_b = properties2.metadata) == null ? void 0 : _b.vtec) == null ? void 0 : _c.is_watch) {
15203
- const isSPC = (_e = (_d = properties2.metadata) == null ? void 0 : _d.vtec) == null ? void 0 : _e.prediction_center;
15204
- setEventEmit({ event: isSPC ? `onStormPredictionWatch` : `onNonStormPredictionWatch`, metadata: define2 });
15205
- if ((bools == null ? void 0 : bools.SPCWatchesOnly) && !isSPC) {
15206
- return false;
15207
- }
15208
- if (!(bools == null ? void 0 : bools.SPCWatchesOnly) && isSPC) {
15209
- return false;
15210
- }
15251
+ // src/@modules/@utilities/utilities.createHttp.ts
15252
+ import request from "request";
15253
+ var createHttp = (options) => __async(null, null, function* () {
15254
+ return new Promise((resolve6, reject) => {
15255
+ var _a, _b, _c, _d, _e;
15256
+ const requestOptions = {
15257
+ url: (_a = options.url) != null ? _a : `https://api.weather.gov/alerts/active`,
15258
+ headers: (_b = options.headers) != null ? _b : {
15259
+ "User-Agent": "AtmosphericX",
15260
+ "Accept": "application/geo+json, text/plain, */*; q=0.9",
15261
+ "Accept-Language": "en-US,en;q=0.9"
15262
+ },
15263
+ method: (_c = options.method) != null ? _c : `GET`,
15264
+ timeout: (_d = options.timeout) != null ? _d : 1e4,
15265
+ proxy: (_e = options.proxy) != null ? _e : null,
15266
+ maxRedirects: 1
15267
+ };
15268
+ if (options.formData) {
15269
+ requestOptions["formData"] = options.formData;
15270
+ } else if (options.body) {
15271
+ requestOptions["body"] = options.body;
15211
15272
  }
15212
- for (const key in sets) {
15213
- const setting = sets[key];
15214
- if (key === "ListeningEvents" && setting.size > 0 && !setting.has(define2.properties.event.toLowerCase())) {
15215
- setEventEmit({
15216
- event: `onFilteredEvent`,
15217
- metadata: define2
15273
+ request(requestOptions, (error, response2, body) => {
15274
+ var _a2, _b2, _c2, _d2, _e2;
15275
+ if (error) {
15276
+ return resolve6({
15277
+ error: true,
15278
+ options: requestOptions,
15279
+ status: -1,
15280
+ message: (_a2 = error.message) != null ? _a2 : `Unknown Error`
15218
15281
  });
15219
- return false;
15220
15282
  }
15221
- if (key === "IgnoredEvents" && setting.size > 0 && setting.has(define2.properties.event.toLowerCase())) {
15222
- setEventEmit({
15223
- event: `onIgnoredEvent`,
15224
- metadata: define2
15283
+ if (response2.statusCode < 200 || response2.statusCode >= 300) {
15284
+ return resolve6({
15285
+ error: true,
15286
+ options: requestOptions,
15287
+ status: (_b2 = response2.statusCode) != null ? _b2 : -1,
15288
+ message: `HTTP Status Code ${(_c2 = response2.statusCode) != null ? _c2 : `Unknown Status Code`} (${body})`
15225
15289
  });
15226
- return false;
15227
15290
  }
15228
- if (key === "ListeningICAO" && setting.size > 0 && icao != null && !setting.has(icao.toLowerCase())) {
15229
- setEventEmit({
15230
- event: `onFilteredICAO`,
15231
- metadata: define2
15291
+ if (body == void 0 || body == null) {
15292
+ return resolve6({
15293
+ error: true,
15294
+ options: requestOptions,
15295
+ status: (_d2 = response2.statusCode) != null ? _d2 : -1,
15296
+ message: `Empty Response Body`
15232
15297
  });
15233
- return false;
15234
15298
  }
15235
- if (key === "IgnoredICAO" && setting.size > 0 && icao != null && setting.has(icao.toLowerCase())) {
15236
- setEventEmit({
15237
- event: `onIgnoredICAO`,
15238
- metadata: define2
15239
- });
15240
- return false;
15299
+ resolve6({
15300
+ error: false,
15301
+ options: requestOptions,
15302
+ status: (_e2 = response2.statusCode) != null ? _e2 : -1,
15303
+ message: body
15304
+ });
15305
+ });
15306
+ });
15307
+ });
15308
+
15309
+ // src/@manager/manager.updateListener.ts
15310
+ var import_form_data = __toESM(require_form_data());
15311
+ import { existsSync as existsSync2, mkdirSync as mkdirSync2, writeFileSync as writeFileSync3, readFileSync as readFileSync2, appendFileSync } from "fs";
15312
+ var updateListener = (event) => __async(null, null, function* () {
15313
+ var _a, _b, _c, _d;
15314
+ const settings = bootstrap.settings;
15315
+ const listeners2 = settings.ListenerSettings;
15316
+ const properties2 = event.properties;
15317
+ for (const socket of listeners2) {
15318
+ const events = socket.events;
15319
+ const sWebhook = socket == null ? void 0 : socket.webhook;
15320
+ const sUploads = socket == null ? void 0 : socket.uploads;
15321
+ const matched = events.some((pattern) => {
15322
+ if (!pattern) return false;
15323
+ if (pattern === "*" || pattern === properties2.event) return true;
15324
+ if (pattern.includes("*")) {
15325
+ const regex = "^" + pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*") + "$";
15326
+ return new RegExp(regex).test(properties2.event);
15241
15327
  }
15242
- if (key === "ListeningUGC" && setting.size > 0 && zones.length > 0 && !zones.some((ugc2) => setting.has(ugc2.toLowerCase()))) {
15243
- setEventEmit({
15244
- event: `onFilteredUGC`,
15245
- metadata: define2
15328
+ return false;
15329
+ });
15330
+ if ((events == null ? void 0 : events.length) == 0 || matched) {
15331
+ let eas;
15332
+ let file;
15333
+ if (sUploads == null ? void 0 : sUploads.eas) {
15334
+ eas = yield setEasTone({
15335
+ title: `${properties2.event}_${properties2.status}_${properties2.metadata.tracking}`,
15336
+ message: properties2.description,
15337
+ header: properties2.metadata.header
15246
15338
  });
15247
- return false;
15248
15339
  }
15249
- if (key === "ListeningStates" && setting.size > 0 && zones.length > 0 && !zones.some((ugc2) => setting.has(ugc2.substring(0, 2).toLowerCase()))) {
15250
- setEventEmit({
15251
- event: `onFilteredState`,
15252
- metadata: define2
15253
- });
15254
- return false;
15340
+ if (sUploads == null ? void 0 : sUploads.file) {
15341
+ const destination = bootstrap.settings.GlobalSettings.ArchiveSettings.TextDirectory;
15342
+ if (destination) {
15343
+ if (!existsSync2(destination)) {
15344
+ mkdirSync2(destination, { recursive: true });
15345
+ }
15346
+ if (existsSync2(`${destination}/${properties2.event}_${properties2.status}_${properties2.metadata.tracking}.txt`)) {
15347
+ appendFileSync(`${destination}/${properties2.event}_${properties2.status}_${properties2.metadata.tracking}.txt`, properties2.metadata.raw);
15348
+ } else {
15349
+ writeFileSync3(`${destination}/${properties2.event}_${properties2.status}_${properties2.metadata.tracking}.txt`, properties2.metadata.raw);
15350
+ }
15351
+ }
15352
+ file = properties2.metadata.raw;
15255
15353
  }
15256
- }
15257
- return true;
15258
- });
15259
- if (!((_a = configurations == null ? void 0 : configurations.GlobalSettings) == null ? void 0 : _a.DisableGeometryParsing)) {
15260
- for (const event of filterd) {
15261
- event.geometry = yield getEventGeometry(event);
15262
- }
15263
- }
15264
- if (filterd.length > 0) {
15265
- for (const event of filterd) {
15266
- yield mkEvent(event);
15267
- }
15268
- }
15269
- yield updateNode();
15270
- setEventEmit({
15271
- event: `onEventCache`,
15272
- metadata: bootstrap.cache.events,
15273
- limited: true
15274
- });
15275
- });
15276
-
15277
- // src/@events/events.text.ts
15278
- var text = (stanza) => __async(null, null, function* () {
15279
- var _a, _b, _c;
15280
- let processed = [];
15281
- 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 !== "$$");
15282
- if (!getMessages || (getMessages == null ? void 0 : getMessages.length) == 0) return;
15283
- for (const message of getMessages) {
15284
- const tick = performance.now();
15285
- const attributes = stanza == null ? void 0 : stanza.attributes;
15286
- const props = properties({ message, attributes });
15287
- const header = getEventHeader({ properties: props, getType: stanza.getType });
15288
- const issued = new Date(attributes.issue);
15289
- const expires = new Date(issued.getTime() + 12 * 60 * 60 * 1e3);
15290
- let event = Object.keys(eventsMatchText).find((event2) => message.toLowerCase().includes(event2.toLowerCase()));
15291
- let isStatement = false;
15292
- if (!event) {
15293
- event = stanza.getType.type.split(`-`).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(` `);
15294
- isStatement = true;
15295
- }
15296
- processed.push({
15297
- type: `Feature`,
15298
- geometry: {
15299
- type: `Point`,
15300
- coordinates: []
15301
- },
15302
- properties: __spreadProps(__spreadValues({
15303
- event,
15304
- parent: event,
15305
- status: isStatement ? `Statement` : `Issued`,
15306
- issued: !isNaN(issued.getTime()) ? issued.toISOString() : (/* @__PURE__ */ new Date()).toISOString(),
15307
- expires: isStatement ? new Date(issued.getTime() + 120 * 1e3).toISOString() : !isNaN(expires.getTime()) ? expires.toISOString() : new Date(Date.now() + 60 * 60 * 1e3).toISOString()
15308
- }, props), {
15309
- metadata: {
15310
- ms: performance.now() - tick,
15311
- source: `events.text`,
15312
- tracking: getEventTracking({ type: `RAW`, stanza, attributes, properties: props }),
15313
- header,
15314
- vtec: null,
15315
- hvtec: null,
15316
- history: [
15317
- {
15318
- description: props.description,
15319
- issued: !isNaN(issued.getTime()) ? issued.toISOString() : (/* @__PURE__ */ new Date()).toISOString(),
15320
- status: `Issued`
15354
+ if (sWebhook == null ? void 0 : sWebhook.enabled) {
15355
+ const isLimited = setTimeoutAction({ identifier: sWebhook.destination, interval: sWebhook.ratelimit, max: sWebhook.ratelimit, addTime: true });
15356
+ if (!isLimited.limited) {
15357
+ let body = getEmebed(event);
15358
+ if (body.length > 1900) {
15359
+ body = body.substring(0, 1900) + "\n\n[Message truncated due to length]";
15360
+ const blocks = ((_a = body.match(/```/g)) != null ? _a : []).length;
15361
+ if (blocks % 2 !== 0) body += "```";
15362
+ }
15363
+ if (properties2.description.length < 25) {
15364
+ continue;
15365
+ }
15366
+ const form = new import_form_data.default();
15367
+ const embed = {
15368
+ title: `${properties2.event} (${properties2.status})`,
15369
+ description: body,
15370
+ color: 16711680,
15371
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
15372
+ image: {},
15373
+ footer: { text: (_b = sWebhook.title) != null ? _b : `AtmosphericX` }
15374
+ };
15375
+ form.append("payload_json", JSON.stringify({
15376
+ username: (_c = sWebhook.title) != null ? _c : "AtmosphericX",
15377
+ content: (_d = sWebhook.message) != null ? _d : "",
15378
+ embeds: [embed]
15379
+ }));
15380
+ if (sUploads == null ? void 0 : sUploads.file) {
15381
+ form.append("fUpload", Buffer.from(file), { filename: `${properties2.event}_${properties2.status}_${properties2.metadata.tracking}.txt`, contentType: "application/text" });
15382
+ }
15383
+ if (sUploads == null ? void 0 : sUploads.eas) {
15384
+ if (eas) {
15385
+ const file2 = readFileSync2(eas);
15386
+ form.append("fEas", Buffer.from(file2), { filename: `${properties2.event}_${properties2.status}_${properties2.metadata.tracking}_eas.mp3`, contentType: "audio/mpeg" });
15321
15387
  }
15322
- ]
15388
+ }
15389
+ const a = yield createHttp({
15390
+ url: sWebhook.destination,
15391
+ timeout: 5e3,
15392
+ method: `POST`,
15393
+ headers: form.getHeaders(),
15394
+ body: form
15395
+ });
15323
15396
  }
15324
- })
15325
- });
15397
+ }
15398
+ }
15326
15399
  }
15327
- validateEvents(processed);
15328
15400
  });
15329
15401
 
15330
- // src/@parsers/@ugc/ugc.header.ts
15331
- var getUGCHeader = (message) => {
15332
- const start = message.search(regExp.ugc1);
15333
- const sub = message.substring(start);
15334
- const end = sub.search(regExp.ugc2);
15335
- const fin = sub.substring(0, end).replace(/\s+/g, "").slice(0, -1);
15336
- return fin != null ? fin : null;
15337
- };
15338
-
15339
- // src/@parsers/@ugc/ugc.zones.ts
15340
- var getZones = (header) => {
15341
- const splits = header.split("-");
15342
- const zones = [];
15343
- let state = splits[0].substring(0, 2);
15344
- const format = splits[0].substring(2, 3);
15345
- for (const part of splits) {
15346
- if (/^[A-Z]/.test(part)) {
15347
- state = part.substring(0, 2);
15348
- if (part.includes(">")) {
15349
- const [start, end] = part.split(">");
15350
- const startNum = parseInt(start.substring(3), 10);
15351
- const endNum = parseInt(end, 10);
15352
- for (let j2 = startNum; j2 <= endNum; j2++) {
15353
- zones.push(`${state}${format}${j2.toString().padStart(3, "0")}`);
15402
+ // src/@modules/@utilities/utilities.getShapeNearestPoint.ts
15403
+ var getShapeNearestPoint = (coordinates, point) => {
15404
+ if (!coordinates || !point) {
15405
+ return { proximity: false, point: [0, 0], distance: null };
15406
+ }
15407
+ const normalize = (coords) => {
15408
+ if (!Array.isArray(coords)) return [];
15409
+ if (typeof coords[0] === "number" && typeof coords[1] === "number") return [];
15410
+ if (Array.isArray(coords[0]) && typeof coords[0][0] === "number") {
15411
+ return [[coords]];
15412
+ }
15413
+ if (Array.isArray(coords[0]) && Array.isArray(coords[0][0]) && typeof coords[0][0][0] === "number") {
15414
+ return [coords];
15415
+ }
15416
+ if (Array.isArray(coords[0]) && Array.isArray(coords[0][0]) && Array.isArray(coords[0][0][0]) && typeof coords[0][0][0][0] === "number") {
15417
+ return coords;
15418
+ }
15419
+ return [];
15420
+ };
15421
+ const polys = normalize(coordinates);
15422
+ if (polys.length === 0) return { proximity: false, point: [0, 0], distance: null };
15423
+ const lon = point[0];
15424
+ const lat = point[1];
15425
+ const pointInRing = (pt, ring) => {
15426
+ let x = pt[0], y = pt[1];
15427
+ let inside = false;
15428
+ for (let i = 0, j2 = ring.length - 1; i < ring.length; j2 = i++) {
15429
+ const xi = ring[i][0], yi = ring[i][1];
15430
+ const xj = ring[j2][0], yj = ring[j2][1];
15431
+ const intersect = yi > y !== yj > y && x < (xj - xi) * (y - yi) / (yj - yi + 0) + xi;
15432
+ if (intersect) inside = !inside;
15433
+ }
15434
+ return inside;
15435
+ };
15436
+ const toRadians = (deg) => deg * Math.PI / 180;
15437
+ const haversineMiles = (a, b) => {
15438
+ const R = 3958.8;
15439
+ const dLat = toRadians(b[1] - a[1]);
15440
+ const dLon = toRadians(b[0] - a[0]);
15441
+ const lat1 = toRadians(a[1]);
15442
+ const lat2 = toRadians(b[1]);
15443
+ const sinDLat = Math.sin(dLat / 2);
15444
+ const sinDLon = Math.sin(dLon / 2);
15445
+ const c = 2 * Math.asin(Math.sqrt(sinDLat * sinDLat + Math.cos(lat1) * Math.cos(lat2) * sinDLon * sinDLon));
15446
+ return R * c;
15447
+ };
15448
+ let minDistance = Infinity;
15449
+ let closestPoint = null;
15450
+ for (const poly of polys) {
15451
+ const outer = poly[0];
15452
+ const holes = poly.slice(1);
15453
+ if (pointInRing(point, outer)) {
15454
+ let inHole = false;
15455
+ for (const hole of holes) {
15456
+ if (pointInRing(point, hole)) {
15457
+ inHole = true;
15458
+ break;
15354
15459
  }
15355
- } else {
15356
- zones.push(part);
15357
15460
  }
15358
- continue;
15461
+ if (!inHole) {
15462
+ return { proximity: true, point, distance: 0 };
15463
+ }
15359
15464
  }
15360
- if (part.includes(">")) {
15361
- const [start, end] = part.split(">");
15362
- const startNum = parseInt(start, 10);
15363
- const endNum = parseInt(end, 10);
15364
- for (let j2 = startNum; j2 <= endNum; j2++) {
15365
- zones.push(`${state}${format}${j2.toString().padStart(3, "0")}`);
15465
+ for (const ring of poly) {
15466
+ for (let i = 0; i < ring.length - 1; i++) {
15467
+ const start = [ring[i][0], ring[i][1]];
15468
+ const end = [ring[i + 1][0], ring[i + 1][1]];
15469
+ const A = lon - start[0];
15470
+ const B = lat - start[1];
15471
+ const C = end[0] - start[0];
15472
+ const D = end[1] - start[1];
15473
+ const lenSq = C * C + D * D;
15474
+ const t = lenSq === 0 ? 0 : Math.max(0, Math.min(1, (A * C + B * D) / lenSq));
15475
+ const candidate = [start[0] + t * C, start[1] + t * D];
15476
+ const dist = haversineMiles([lon, lat], candidate);
15477
+ if (!isNaN(dist) && dist < minDistance) {
15478
+ minDistance = Number(dist.toFixed(3));
15479
+ closestPoint = candidate;
15480
+ }
15366
15481
  }
15367
- } else {
15368
- zones.push(`${state}${format}${part}`);
15369
15482
  }
15370
15483
  }
15371
- return zones.filter((item) => item !== "");
15372
- };
15373
-
15374
- // src/@parsers/@ugc/ugc.expiry.ts
15375
- var getExpiry = (message) => {
15376
- const match = message.match(/\b(\d{6})-/);
15377
- if (!match) {
15378
- return null;
15484
+ if (!isFinite(minDistance) || closestPoint == null) {
15485
+ return { proximity: false, point: [0, 0], distance: null };
15379
15486
  }
15380
- const date = match == null ? void 0 : match[1];
15381
- const day = parseInt(date == null ? void 0 : date.slice(0, 2), 10);
15382
- const hour = parseInt(date == null ? void 0 : date.slice(2, 4), 10);
15383
- const minute = parseInt(date == null ? void 0 : date.slice(4, 6), 10);
15384
- const now = /* @__PURE__ */ new Date();
15385
- const expires = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), day, hour, minute));
15386
- return expires.toISOString();
15487
+ const distanceMiles = minDistance;
15488
+ const distanceKm = Number((distanceMiles * 1.609344).toFixed(3));
15489
+ const distanceMeters = Math.round(distanceKm * 1e3);
15490
+ return { proximity: distanceMiles === 0, point: closestPoint, distance: distanceMiles, distanceKm, distanceMeters };
15387
15491
  };
15388
15492
 
15389
- // src/@parsers/@ugc/ugc.locations.ts
15390
- var getLocations = (zones) => __async(null, null, function* () {
15391
- const sites = Array.from(new Set(zones));
15392
- const placeholders = sites.map(() => "?").join(",");
15393
- const rows = yield bootstrap.database.prepare(`SELECT id, location FROM shapefiles WHERE id IN (${placeholders})`).all(...sites);
15394
- return rows.map((row) => row.location).sort();
15493
+ // src/@building/building.polygon.ts
15494
+ var getEventNodes = (event) => __async(null, null, function* () {
15495
+ var _a, _b;
15496
+ const metadata = { nodes: [], proximity: false, filtered: false };
15497
+ const geometry = yield getEventGeometry(event);
15498
+ if (!geometry || !geometry.coordinates) {
15499
+ return { nodes: [], filtered: false, updated: Date.now() };
15500
+ }
15501
+ const nodes = bootstrap.cache.nodes.features;
15502
+ for (const node of nodes) {
15503
+ const [longitude, latitude] = node.geometry.coordinates;
15504
+ const getPoint = getShapeNearestPoint(geometry.coordinates, [longitude, latitude]);
15505
+ const miles = (_a = getPoint.distance) != null ? _a : null;
15506
+ const kilometers = Number((miles * 1.609344).toFixed(3));
15507
+ const info = {
15508
+ id: (_b = node.properties) == null ? void 0 : _b.identifier,
15509
+ coordinates: [longitude, latitude],
15510
+ nearest: getPoint.point,
15511
+ miles,
15512
+ kilometers,
15513
+ proximity: getPoint.proximity
15514
+ };
15515
+ metadata.nodes.push(info);
15516
+ if (bootstrap.settings.GlobalSettings.EventFiltering.NodeLocationFiltering && miles < bootstrap.settings.GlobalSettings.NodeMinDistance) {
15517
+ metadata.proximity = true;
15518
+ info.proximity = true;
15519
+ }
15520
+ }
15521
+ return {
15522
+ nodes: metadata.nodes,
15523
+ filtered: metadata.proximity,
15524
+ updated: Date.now()
15525
+ };
15395
15526
  });
15396
15527
 
15397
- // src/@parsers/@ugc/ugc.extract.ts
15528
+ // src/@manager/manager.updateNodes.ts
15529
+ var updateNode = (selectedEvent) => __async(null, null, function* () {
15530
+ const events = bootstrap.cache.events.features;
15531
+ const ttl = bootstrap.settings.GlobalSettings.NodeTTL * 1e3;
15532
+ let total = 0;
15533
+ function update(evt) {
15534
+ return __async(this, null, function* () {
15535
+ var _a, _b, _c;
15536
+ const lastUpdate = (_c = (_b = (_a = evt == null ? void 0 : evt.properties) == null ? void 0 : _a.metadata) == null ? void 0 : _b.updated) != null ? _c : null;
15537
+ if (lastUpdate != null && Date.now() - lastUpdate < ttl) {
15538
+ return evt;
15539
+ }
15540
+ const node = yield getEventNodes(evt);
15541
+ if (node.nodes.length > 0) {
15542
+ total++;
15543
+ }
15544
+ evt.properties.metadata.nodes = node.nodes;
15545
+ evt.properties.metadata.filtered_proximity = node.filtered;
15546
+ evt.properties.metadata.updated = node.updated;
15547
+ });
15548
+ }
15549
+ if (!selectedEvent) {
15550
+ yield Promise.all(events.map((evt) => __async(null, null, function* () {
15551
+ yield update(evt);
15552
+ })));
15553
+ }
15554
+ if (selectedEvent) {
15555
+ yield update(selectedEvent);
15556
+ }
15557
+ if (total > 0) {
15558
+ setEventEmit({
15559
+ event: `onNodeUpdate`,
15560
+ metadata: {
15561
+ type: `global-update`,
15562
+ updated: total
15563
+ }
15564
+ });
15565
+ }
15566
+ });
15567
+
15568
+ // src/@manager/manager.mkEvent.ts
15569
+ var mkEvent = (event) => __async(null, null, function* () {
15570
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w;
15571
+ const settings = bootstrap.settings;
15572
+ const features = bootstrap.cache.events.features;
15573
+ const getHash = event.properties.metadata.hash;
15574
+ const getTracking = event.properties.metadata.tracking;
15575
+ const isEntry = (_a = bootstrap.cache.hashes) == null ? void 0 : _a.find((hash) => hash.tracking === getTracking);
15576
+ const isHashed = (_c = (_b = isEntry == null ? void 0 : isEntry.hashes) == null ? void 0 : _b.includes(getHash)) != null ? _c : false;
15577
+ const getFeature = features.find((feature) => feature.properties.metadata.tracking === getTracking);
15578
+ if (isHashed || event.properties.status_metadata.is_expired) return;
15579
+ setHash(event, isEntry);
15580
+ const isFilteredLocation = yield updateNode(event).then(() => event.properties.metadata.filtered_proximity);
15581
+ if (!isFilteredLocation && settings.GlobalSettings.EventFiltering.NodeLocationFiltering) {
15582
+ return;
15583
+ }
15584
+ setEventEmit({
15585
+ event: `onEventStatus`,
15586
+ metadata: {
15587
+ type: getFeature ? `Updated` : `New`,
15588
+ event
15589
+ },
15590
+ message: `[${getFeature ? "Updated" : "New"}] ${event.properties.event} (${event.properties.status}) (${event.properties.metadata.tracking})`
15591
+ });
15592
+ if (settings.GlobalSettings.EventManagement) {
15593
+ if (event.properties.status_metadata.is_issued || event.properties.status_metadata.is_updated) {
15594
+ if (getFeature) {
15595
+ const getIndex = features.indexOf(getFeature);
15596
+ const cHistory = (_f = (_e = (_d = getFeature == null ? void 0 : getFeature.properties) == null ? void 0 : _d.metadata) == null ? void 0 : _e.history) != null ? _f : [];
15597
+ const cLocations = (_i = (_h = (_g = getFeature == null ? void 0 : getFeature.properties) == null ? void 0 : _g.locations) == null ? void 0 : _h.split(";").map((l) => l.trim())) != null ? _i : [];
15598
+ const cUgc = (_l = (_k = (_j = getFeature == null ? void 0 : getFeature.properties) == null ? void 0 : _j.geocode) == null ? void 0 : _k.ugc) != null ? _l : [];
15599
+ const iHistory = (_o = (_n = (_m = event.properties) == null ? void 0 : _m.metadata) == null ? void 0 : _n.history) != null ? _o : [];
15600
+ const iLocations = (_r = (_q = (_p = event.properties) == null ? void 0 : _p.locations) == null ? void 0 : _q.split(";").map((l) => l.trim())) != null ? _r : [];
15601
+ const iUgc = (_u = (_t = (_s = event.properties) == null ? void 0 : _s.geocode) == null ? void 0 : _t.ugc) != null ? _u : [];
15602
+ const mHistory = [...cHistory, ...iHistory].filter((v, i, a) => a.indexOf(v) === i).filter((v, i, a) => a.findIndex((h) => h.description === v.description && h.issued === v.issued) === i);
15603
+ const mLocations = [...cLocations, ...iLocations].filter((v, i, a) => a.indexOf(v) === i).join("; ");
15604
+ const mUgc = [...cUgc, ...iUgc].filter((v, i, a) => a.indexOf(v) === i);
15605
+ bootstrap.cache.events.features[getIndex] = __spreadProps(__spreadValues({}, event), {
15606
+ properties: __spreadProps(__spreadValues({}, event.properties), {
15607
+ metadata: __spreadProps(__spreadValues({}, (_v = event == null ? void 0 : event.properties) == null ? void 0 : _v.metadata), {
15608
+ history: mHistory
15609
+ }),
15610
+ locations: mLocations,
15611
+ geocode: __spreadProps(__spreadValues({}, (_w = event == null ? void 0 : event.properties) == null ? void 0 : _w.geocode), {
15612
+ ugc: mUgc
15613
+ })
15614
+ })
15615
+ });
15616
+ updateListener(bootstrap.cache.events.features[getIndex]);
15617
+ } else {
15618
+ features.push(event);
15619
+ updateListener(event);
15620
+ }
15621
+ }
15622
+ }
15623
+ });
15624
+
15625
+ // src/@manager/manager.rmEvent.ts
15626
+ var rmEvent = (event) => {
15627
+ const getEvent = bootstrap.cache.events.features.find((f) => {
15628
+ var _a, _b, _c, _d;
15629
+ 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);
15630
+ });
15631
+ const cachedStatus = event.properties.status;
15632
+ event.properties.expires = (/* @__PURE__ */ new Date()).toISOString();
15633
+ event.properties.status = `Expired`;
15634
+ event.properties.status_metadata.is_expired = true;
15635
+ if (getEvent) {
15636
+ setEventEmit({
15637
+ event: `onEventStatus`,
15638
+ metadata: {
15639
+ type: `Removed`,
15640
+ event
15641
+ },
15642
+ message: `[Removed] ${event.properties.event} (${event.properties.status}) (${event.properties.metadata.tracking})`
15643
+ });
15644
+ setEventEmit({ event: `onExpiredProduct`, metadata: event });
15645
+ if (cachedStatus != `Statement`) updateListener(event);
15646
+ bootstrap.cache.events.features.splice(bootstrap.cache.events.features.indexOf(getEvent), 1);
15647
+ bootstrap.cache.hashes = bootstrap.cache.hashes.filter((hash) => hash.tracking !== event.properties.metadata.tracking);
15648
+ }
15649
+ setEventEmit({
15650
+ event: `onEventCache`,
15651
+ metadata: bootstrap.cache.events,
15652
+ limited: true
15653
+ });
15654
+ };
15655
+
15656
+ // src/@modules/@utilities/utilities.getLatestIssuance.ts
15657
+ var getLatestIssuance = () => {
15658
+ const now = /* @__PURE__ */ new Date();
15659
+ const current = now.getUTCHours() * 100 + now.getUTCMinutes();
15660
+ const issuances = [100, 600, 1300, 1630, 2e3];
15661
+ let latest = issuances[0];
15662
+ for (const issuance of issuances) {
15663
+ if (current >= issuance) {
15664
+ latest = issuance;
15665
+ }
15666
+ }
15667
+ return latest.toString().padStart(4, "0");
15668
+ };
15669
+
15670
+ // src/@building/building.attachments.ts
15671
+ var getEventAttachments = (event) => {
15672
+ var _a, _b, _c, _d;
15673
+ const latestTime = getLatestIssuance();
15674
+ const spcNumber = (_b = (_a = event == null ? void 0 : event.properties) == null ? void 0 : _a.discussion_parameters) == null ? void 0 : _b.discussion_number;
15675
+ const watchNumber = (_d = (_c = event == null ? void 0 : event.properties) == null ? void 0 : _c.watch_parameters) == null ? void 0 : _d.watch_number;
15676
+ const validEvents = [
15677
+ { target: "Day 1", attachment: `https://www.spc.noaa.gov/products/outlook/day1otlk_${latestTime}.png` },
15678
+ { target: "Day 2", attachment: `https://www.spc.noaa.gov/products/outlook/day2otlk.png` },
15679
+ { target: "Day 3", attachment: `https://www.spc.noaa.gov/products/outlook/day3otlk.png` },
15680
+ { target: "Mesoscale Discussion", attachment: `https://www.spc.noaa.gov/products/md/mcd${spcNumber}.png` },
15681
+ { target: "Tornado Watch", attachment: `https://www.spc.noaa.gov/products/watch/ww${watchNumber}_radar_big.gif` },
15682
+ { target: "PDS Tornado Watch", attachment: `https://www.spc.noaa.gov/products/watch/ww${watchNumber}_radar_big.gif` },
15683
+ { target: "Severe Thunderstorm Watch", attachment: `https://www.spc.noaa.gov/products/watch/ww${watchNumber}_radar_big.gif` },
15684
+ { target: "PDS Severe Thunderstorm Watch", attachment: `https://www.spc.noaa.gov/products/watch/ww${watchNumber}_radar_big.gif` }
15685
+ ];
15686
+ const isValid = validEvents.find((outlook) => outlook.target == event.properties.event);
15687
+ if (isValid) {
15688
+ return (isValid == null ? void 0 : isValid.attachment) ? [isValid.attachment] : [];
15689
+ }
15690
+ return null;
15691
+ };
15692
+
15693
+ // src/@building/building.validate.ts
15694
+ var validateEvents = (events) => __async(null, null, function* () {
15695
+ var _a;
15696
+ if (events.length === 0) return;
15697
+ const configurations = bootstrap.settings;
15698
+ const sets = {};
15699
+ const bools = {};
15700
+ const megered = __spreadValues(__spreadValues({}, configurations.GlobalSettings), configurations.GlobalSettings.EventFiltering);
15701
+ for (const key in megered) {
15702
+ const setting = megered[key];
15703
+ if (Array.isArray(setting)) {
15704
+ sets[key] = new Set(setting.map((item) => item.toLowerCase()));
15705
+ }
15706
+ if (typeof setting === "boolean") {
15707
+ bools[key] = setting;
15708
+ }
15709
+ }
15710
+ const filterd = events.filter((event) => {
15711
+ var _a2, _b, _c, _d, _e;
15712
+ const define2 = getEventSignature(event);
15713
+ const properties2 = define2.properties;
15714
+ const zones = properties2.geocode.ugc;
15715
+ const icao = properties2.geocode.office.office;
15716
+ const enhancedEventName = properties2.event = getEventEnhancedName(event);
15717
+ const filteredProperties = JSON.parse(JSON.stringify(properties2));
15718
+ if ((filteredProperties == null ? void 0 : filteredProperties.metadata) && "ms" in filteredProperties.metadata) {
15719
+ delete filteredProperties.metadata.ms;
15720
+ }
15721
+ filteredProperties.metadata = (_a2 = filteredProperties.metadata) != null ? _a2 : {};
15722
+ properties2.metadata.hash = createHash("sha256").update(JSON.stringify(filteredProperties)).digest("hex");
15723
+ properties2.metadata.attachments = getEventAttachments(event);
15724
+ setEventEmit({ event: `onProductType${enhancedEventName.replace(/\s+/g, "")}`, metadata: define2 });
15725
+ if (properties2.status_metadata.is_test) {
15726
+ setEventEmit({ event: `onTestProduct`, metadata: define2 });
15727
+ if (bools == null ? void 0 : bools.IgnoreTestProducts) return false;
15728
+ }
15729
+ if (properties2.status_metadata.is_expired) {
15730
+ setEventEmit({ event: `onExpiredProduct`, metadata: define2 });
15731
+ rmEvent(define2);
15732
+ return false;
15733
+ }
15734
+ if (((_c = (_b = properties2.metadata) == null ? void 0 : _b.vtec) == null ? void 0 : _c.is_watch) && properties2.metadata.source != `events.api`) {
15735
+ const isSPC = (_e = (_d = properties2.metadata) == null ? void 0 : _d.vtec) == null ? void 0 : _e.prediction_center;
15736
+ setEventEmit({ event: isSPC ? `onStormPredictionWatch` : `onNonStormPredictionWatch`, metadata: define2 });
15737
+ if ((bools == null ? void 0 : bools.SPCWatchesOnly) && !isSPC) {
15738
+ return false;
15739
+ }
15740
+ if (!(bools == null ? void 0 : bools.SPCWatchesOnly) && isSPC) {
15741
+ return false;
15742
+ }
15743
+ }
15744
+ for (const key in sets) {
15745
+ const setting = sets[key];
15746
+ if (key === "ListeningEvents" && setting.size > 0 && !setting.has(define2.properties.event.toLowerCase())) {
15747
+ setEventEmit({
15748
+ event: `onFilteredEvent`,
15749
+ metadata: define2
15750
+ });
15751
+ return false;
15752
+ }
15753
+ if (key === "IgnoredEvents" && setting.size > 0 && setting.has(define2.properties.event.toLowerCase())) {
15754
+ setEventEmit({
15755
+ event: `onIgnoredEvent`,
15756
+ metadata: define2
15757
+ });
15758
+ return false;
15759
+ }
15760
+ if (key === "ListeningICAO" && setting.size > 0 && icao != null && !setting.has(icao.toLowerCase())) {
15761
+ setEventEmit({
15762
+ event: `onFilteredICAO`,
15763
+ metadata: define2
15764
+ });
15765
+ return false;
15766
+ }
15767
+ if (key === "IgnoredICAO" && setting.size > 0 && icao != null && setting.has(icao.toLowerCase())) {
15768
+ setEventEmit({
15769
+ event: `onIgnoredICAO`,
15770
+ metadata: define2
15771
+ });
15772
+ return false;
15773
+ }
15774
+ if (key === "ListeningUGC" && setting.size > 0 && zones.length > 0 && !zones.some((ugc2) => setting.has(ugc2.toLowerCase()))) {
15775
+ setEventEmit({
15776
+ event: `onFilteredUGC`,
15777
+ metadata: define2
15778
+ });
15779
+ return false;
15780
+ }
15781
+ if (key === "ListeningStates" && setting.size > 0 && zones.length > 0 && !zones.some((ugc2) => setting.has(ugc2.substring(0, 2).toLowerCase()))) {
15782
+ setEventEmit({
15783
+ event: `onFilteredState`,
15784
+ metadata: define2
15785
+ });
15786
+ return false;
15787
+ }
15788
+ }
15789
+ return true;
15790
+ });
15791
+ if (!((_a = configurations == null ? void 0 : configurations.GlobalSettings) == null ? void 0 : _a.DisableGeometryParsing)) {
15792
+ for (const event of filterd) {
15793
+ event.geometry = yield getEventGeometry(event);
15794
+ }
15795
+ }
15796
+ if (filterd.length > 0) {
15797
+ for (const event of filterd) {
15798
+ yield mkEvent(event);
15799
+ }
15800
+ }
15801
+ yield updateNode();
15802
+ setEventEmit({
15803
+ event: `onEventCache`,
15804
+ metadata: bootstrap.cache.events,
15805
+ limited: true
15806
+ });
15807
+ });
15808
+
15809
+ // src/@events/events.text.ts
15810
+ var text = (stanza) => __async(null, null, function* () {
15811
+ var _a, _b, _c;
15812
+ let processed = [];
15813
+ 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 !== "$$");
15814
+ if (!getMessages || (getMessages == null ? void 0 : getMessages.length) == 0) return;
15815
+ for (const message of getMessages) {
15816
+ const tick = performance.now();
15817
+ const attributes = stanza == null ? void 0 : stanza.attributes;
15818
+ const props = properties({ message, attributes });
15819
+ const header = getEventHeader({ properties: props, getType: stanza.getType });
15820
+ const issued = new Date(attributes.issue);
15821
+ const expires = new Date(issued.getTime() + 12 * 60 * 60 * 1e3);
15822
+ let event = Object.keys(dict_matches).find((event2) => message.toLowerCase().includes(event2.toLowerCase()));
15823
+ let isStatement = false;
15824
+ if (!event) {
15825
+ event = stanza.getType.type.split(`-`).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(` `);
15826
+ isStatement = true;
15827
+ }
15828
+ processed.push({
15829
+ type: `Feature`,
15830
+ geometry: {
15831
+ type: `Point`,
15832
+ coordinates: []
15833
+ },
15834
+ properties: __spreadProps(__spreadValues({
15835
+ event,
15836
+ parent: event,
15837
+ status: isStatement ? `Statement` : `Issued`,
15838
+ issued: !isNaN(issued.getTime()) ? issued.toISOString() : (/* @__PURE__ */ new Date()).toISOString(),
15839
+ expires: isStatement ? new Date(issued.getTime() + 120 * 1e3).toISOString() : !isNaN(expires.getTime()) ? expires.toISOString() : new Date(Date.now() + 60 * 60 * 1e3).toISOString()
15840
+ }, props), {
15841
+ metadata: {
15842
+ ms: performance.now() - tick,
15843
+ source: `events.text`,
15844
+ tracking: getEventTracking({ type: `RAW`, stanza, attributes, properties: props }),
15845
+ header,
15846
+ vtec: null,
15847
+ hvtec: null,
15848
+ raw: message,
15849
+ history: [
15850
+ {
15851
+ description: props.description,
15852
+ issued: !isNaN(issued.getTime()) ? issued.toISOString() : (/* @__PURE__ */ new Date()).toISOString(),
15853
+ status: `Issued`
15854
+ }
15855
+ ]
15856
+ }
15857
+ })
15858
+ });
15859
+ }
15860
+ validateEvents(processed);
15861
+ });
15862
+
15863
+ // src/@parsers/@ugc/ugc.header.ts
15864
+ var getUGCHeader = (message) => {
15865
+ const start = message.search(dict_expressions.ugc1);
15866
+ const sub = message.substring(start);
15867
+ const end = sub.search(dict_expressions.ugc2);
15868
+ const fin = sub.substring(0, end).replace(/\s+/g, "").slice(0, -1);
15869
+ return fin != null ? fin : null;
15870
+ };
15871
+
15872
+ // src/@parsers/@ugc/ugc.zones.ts
15873
+ var getZones = (header) => {
15874
+ const splits = header.split("-");
15875
+ const zones = [];
15876
+ let state = splits[0].substring(0, 2);
15877
+ const format = splits[0].substring(2, 3);
15878
+ for (const part of splits) {
15879
+ if (/^[A-Z]/.test(part)) {
15880
+ state = part.substring(0, 2);
15881
+ if (part.includes(">")) {
15882
+ const [start, end] = part.split(">");
15883
+ const startNum = parseInt(start.substring(3), 10);
15884
+ const endNum = parseInt(end, 10);
15885
+ for (let j2 = startNum; j2 <= endNum; j2++) {
15886
+ zones.push(`${state}${format}${j2.toString().padStart(3, "0")}`);
15887
+ }
15888
+ } else {
15889
+ zones.push(part);
15890
+ }
15891
+ continue;
15892
+ }
15893
+ if (part.includes(">")) {
15894
+ const [start, end] = part.split(">");
15895
+ const startNum = parseInt(start, 10);
15896
+ const endNum = parseInt(end, 10);
15897
+ for (let j2 = startNum; j2 <= endNum; j2++) {
15898
+ zones.push(`${state}${format}${j2.toString().padStart(3, "0")}`);
15899
+ }
15900
+ } else {
15901
+ zones.push(`${state}${format}${part}`);
15902
+ }
15903
+ }
15904
+ return zones.filter((item) => item !== "");
15905
+ };
15906
+
15907
+ // src/@parsers/@ugc/ugc.expiry.ts
15908
+ var getExpiry = (message) => {
15909
+ const match = message.match(/\b(\d{6})-/);
15910
+ if (!match) {
15911
+ return null;
15912
+ }
15913
+ const date = match == null ? void 0 : match[1];
15914
+ const day = parseInt(date == null ? void 0 : date.slice(0, 2), 10);
15915
+ const hour = parseInt(date == null ? void 0 : date.slice(2, 4), 10);
15916
+ const minute = parseInt(date == null ? void 0 : date.slice(4, 6), 10);
15917
+ const now = /* @__PURE__ */ new Date();
15918
+ const expires = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), day, hour, minute));
15919
+ return expires.toISOString();
15920
+ };
15921
+
15922
+ // src/@parsers/@ugc/ugc.locations.ts
15923
+ var getLocations = (zones) => __async(null, null, function* () {
15924
+ const sites = Array.from(new Set(zones));
15925
+ const placeholders = sites.map(() => "?").join(",");
15926
+ const rows = yield bootstrap.database.prepare(`SELECT id, location FROM shapefiles WHERE id IN (${placeholders})`).all(...sites);
15927
+ return rows.map((row) => row.location).sort();
15928
+ });
15929
+
15930
+ // src/@parsers/@ugc/ugc.extract.ts
15398
15931
  var ugcExtract = (message) => __async(null, null, function* () {
15399
15932
  const head = getUGCHeader(message);
15400
15933
  const ugcs = getZones(head);
@@ -15423,7 +15956,7 @@ var ugc = (stanza) => __async(null, null, function* () {
15423
15956
  const issued = new Date(attributes.issue);
15424
15957
  const expires = new Date(ugc2.expires);
15425
15958
  const header = getEventHeader({ properties: props, getType: stanza.getType });
15426
- let event = Object.keys(eventsMatchText).find((event2) => message.toLowerCase().includes(event2.toLowerCase()));
15959
+ let event = Object.keys(dict_matches).find((event2) => message.toLowerCase().includes(event2.toLowerCase()));
15427
15960
  let isStatement = false;
15428
15961
  if (!event) {
15429
15962
  event = stanza.getType.type.split(`-`).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(` `);
@@ -15449,6 +15982,7 @@ var ugc = (stanza) => __async(null, null, function* () {
15449
15982
  header,
15450
15983
  vtec: null,
15451
15984
  hvtec: null,
15985
+ raw: message,
15452
15986
  history: [
15453
15987
  {
15454
15988
  description: props.description,
@@ -15464,8 +15998,8 @@ var ugc = (stanza) => __async(null, null, function* () {
15464
15998
  validateEvents(processed);
15465
15999
  });
15466
16000
 
15467
- // src/@dictionaries/dictionaries.eventTypes.ts
15468
- var eventTypes = {
16001
+ // src/@dictionaries/dictionaries.events.ts
16002
+ var dict_events = {
15469
16003
  "AF": "Ashfall",
15470
16004
  "AS": "Air Stagnation",
15471
16005
  "BH": "Beach Hazard",
@@ -15529,8 +16063,8 @@ var eventTypes = {
15529
16063
  "ZY": "Freezing Spray"
15530
16064
  };
15531
16065
 
15532
- // src/@dictionaries/dictionaries.eventActions.ts
15533
- var eventActions = {
16066
+ // src/@dictionaries/dictionaries.actions.ts
16067
+ var dict_actions = {
15534
16068
  "W": "Warning",
15535
16069
  "F": "Forecast",
15536
16070
  "A": "Watch",
@@ -15540,8 +16074,8 @@ var eventActions = {
15540
16074
  "S": "Statement"
15541
16075
  };
15542
16076
 
15543
- // src/@dictionaries/dictionaries.eventStatus.ts
15544
- var eventStatus = {
16077
+ // src/@dictionaries/dictionaries.status.ts
16078
+ var dict_status = {
15545
16079
  "NEW": "Issued",
15546
16080
  "CON": "Updated",
15547
16081
  "EXT": "Extended",
@@ -15566,7 +16100,8 @@ var getExpiry2 = (dates) => {
15566
16100
  // src/@parsers/@pvtec/pvtec.extract.ts
15567
16101
  var pvExtract = (message) => {
15568
16102
  var _a, _b, _c, _d;
15569
- const getVTECs = (_a = message.match(regExp.pvtec)) != null ? _a : [];
16103
+ if (!message) return null;
16104
+ const getVTECs = (_a = message.match(dict_expressions.pvtec)) != null ? _a : [];
15570
16105
  const vtecs = [];
15571
16106
  for (const vtec2 of getVTECs) {
15572
16107
  const sub = vtec2.split(`.`);
@@ -15574,11 +16109,11 @@ var pvExtract = (message) => {
15574
16109
  const dates = (_b = sub[6]) == null ? void 0 : _b.split(`-`);
15575
16110
  vtecs.push({
15576
16111
  vtec: vtec2,
15577
- product: eventProducts[sub[0]],
16112
+ product: dict_products[sub[0]],
15578
16113
  tracking: `${sub[2]}.${sub[3]}.${sub[4]}.${sub[5]}`,
15579
- event: `${eventTypes[sub[3]]} ${eventActions[sub[4]]}`,
15580
- status: eventStatus[sub[1]],
15581
- organization: (_d = (_c = message.match(regExp.wmo)) == null ? void 0 : _c[0]) != null ? _d : null,
16114
+ event: `${dict_events[sub[3]]} ${dict_actions[sub[4]]}`,
16115
+ status: dict_status[sub[1]],
16116
+ organization: (_d = (_c = message.match(dict_expressions.wmo)) == null ? void 0 : _c[0]) != null ? _d : null,
15582
16117
  expires: getExpiry2(dates),
15583
16118
  is_watch: (sub[4] == `A` || sub[4] == `Y`) && (sub[3] == `TO` || sub[3] == `SV`),
15584
16119
  prediction_center: sub[2] == `KWNS` ? true : false
@@ -15587,8 +16122,8 @@ var pvExtract = (message) => {
15587
16122
  return vtecs.length > 0 ? vtecs : null;
15588
16123
  };
15589
16124
 
15590
- // src/@dictionaries/dictionaries.eventCauses.ts
15591
- var eventCauses = {
16125
+ // src/@dictionaries/dictionaries.causes.ts
16126
+ var dict_causes = {
15592
16127
  "SM": "Snow Melt",
15593
16128
  "RS": "Rain/Snow Melt",
15594
16129
  "ER": "Excessive Rain",
@@ -15606,16 +16141,16 @@ var eventCauses = {
15606
16141
  "OT": "Other Effects"
15607
16142
  };
15608
16143
 
15609
- // src/@dictionaries/dictionaries.eventRecords.ts
15610
- var eventRecords = {
16144
+ // src/@dictionaries/dictionaries.records.ts
16145
+ var dict_records = {
15611
16146
  "NO": "No Record Expected",
15612
16147
  "NR": "Near Record or possible record",
15613
16148
  "UU": "Unknown history of records",
15614
16149
  "OO": "Other"
15615
16150
  };
15616
16151
 
15617
- // src/@dictionaries/dictionaries.eventSeverity.ts
15618
- var eventSeverity = {
16152
+ // src/@dictionaries/dictionaries.severity.ts
16153
+ var dict_severity = {
15619
16154
  N: "Not Expected",
15620
16155
  0: "Areal Flood or FF Product",
15621
16156
  1: "Minor",
@@ -15627,16 +16162,16 @@ var eventSeverity = {
15627
16162
  // src/@parsers/@hvtec/hvtec.extract.ts
15628
16163
  var hvExtract = (message) => {
15629
16164
  var _a;
15630
- const getHVTECs = (_a = message.match(regExp.hvtec)) != null ? _a : [];
16165
+ const getHVTECs = (_a = message.match(dict_expressions.hvtec)) != null ? _a : [];
15631
16166
  const vtecs = [];
15632
16167
  for (const vtec2 of getHVTECs) {
15633
16168
  const sub = vtec2.split(`.`);
15634
16169
  if (sub.length < 7) continue;
15635
16170
  vtecs.push({
15636
16171
  hvtec: vtec2,
15637
- severity: eventSeverity[sub[1]],
15638
- cause: eventCauses[sub[2]],
15639
- record: eventRecords[sub[6]]
16172
+ severity: dict_severity[sub[1]],
16173
+ cause: dict_causes[sub[2]],
16174
+ record: dict_records[sub[6]]
15640
16175
  });
15641
16176
  }
15642
16177
  return vtecs.length > 0 ? vtecs : null;
@@ -15681,6 +16216,7 @@ var vtec = (stanza) => __async(null, null, function* () {
15681
16216
  header,
15682
16217
  vtec: pv,
15683
16218
  hvtec: hVtec,
16219
+ raw: message,
15684
16220
  history: [
15685
16221
  {
15686
16222
  description: props.description,
@@ -15699,12 +16235,12 @@ var vtec = (stanza) => __async(null, null, function* () {
15699
16235
 
15700
16236
  // src/@events/events.api.ts
15701
16237
  var api = (stanza) => __async(null, null, function* () {
15702
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, __, _$, _aa, _ba, _ca, _da, _ea, _fa, _ga, _ha, _ia, _ja, _ka, _la, _ma, _na, _oa, _pa, _qa, _ra, _sa, _ta, _ua, _va, _wa, _xa, _ya, _za, _Aa, _Ba, _Ca, _Da, _Ea, _Fa, _Ga, _Ha, _Ia, _Ja, _Ka, _La, _Ma, _Na, _Oa, _Pa, _Qa, _Ra, _Sa, _Ta, _Ua, _Va, _Wa, _Xa, _Ya, _Za, __a, _$a, _ab, _bb;
16238
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, __, _$, _aa, _ba, _ca, _da, _ea, _fa, _ga, _ha, _ia, _ja, _ka, _la, _ma, _na, _oa, _pa, _qa, _ra, _sa, _ta, _ua, _va, _wa, _xa, _ya, _za, _Aa, _Ba, _Ca, _Da, _Ea, _Fa, _Ga, _Ha, _Ia, _Ja, _Ka, _La, _Ma, _Na, _Oa, _Pa, _Qa, _Ra, _Sa, _Ta, _Ua, _Va, _Wa, _Xa, _Ya, _Za, __a, _$a, _ab, _bb, _cb, _db, _eb, _fb, _gb, _hb, _ib, _jb, _kb, _lb, _mb, _nb, _ob, _pb, _qb, _rb, _sb;
15703
16239
  let processed = [];
15704
16240
  const messages = Object.values(JSON.parse(stanza.message).features);
15705
16241
  for (const feature of messages) {
15706
16242
  const tick = performance.now();
15707
- const pVtec = (_d = (_c = (_b = (_a = feature == null ? void 0 : feature.properties) == null ? void 0 : _a.parameters) == null ? void 0 : _b.VTEC) == null ? void 0 : _c[0]) != null ? _d : null;
16243
+ const pVtec = (_d = pvExtract((_c = (_b = (_a = feature == null ? void 0 : feature.properties) == null ? void 0 : _a.parameters) == null ? void 0 : _b.VTEC) == null ? void 0 : _c[0])) != null ? _d : null;
15708
16244
  processed.push({
15709
16245
  type: `Feature`,
15710
16246
  geometry: {
@@ -15722,60 +16258,63 @@ var api = (stanza) => __async(null, null, function* () {
15722
16258
  attributes: (_t = (_s = feature == null ? void 0 : feature.properties) == null ? void 0 : _s.attributes) != null ? _t : {},
15723
16259
  geocode: {
15724
16260
  office: {
15725
- office: pVtec ? pVtec.split(`.`)[2] : null,
15726
- name: (_u = officeICAOs[pVtec ? pVtec.split(`.`)[2] : null]) != null ? _u : null
16261
+ office: pVtec ? (_u = pVtec == null ? void 0 : pVtec[0]) == null ? void 0 : _u.tracking.split(`.`)[0] : null,
16262
+ name: (_w = dict_icao[pVtec ? (_v = pVtec == null ? void 0 : pVtec[0]) == null ? void 0 : _v.tracking.split(`.`)[0] : null]) != null ? _w : null
15727
16263
  },
15728
- organization: (_x = (_w = (_v = feature == null ? void 0 : feature.properties) == null ? void 0 : _v.parameters) == null ? void 0 : _w.WMOidentifier) == null ? void 0 : _x[0],
15729
- ugc: (_A = (_z = (_y = feature == null ? void 0 : feature.properties) == null ? void 0 : _y.geocode) == null ? void 0 : _z.UGC) != null ? _A : [],
15730
- polygon: ((_B = feature == null ? void 0 : feature.geometry) == null ? void 0 : _B.coordinates.length) > 0 ? Buffer.from(JSON.stringify([(_C = feature == null ? void 0 : feature.geometry) == null ? void 0 : _C.coordinates[0]])).toString("base64") : null,
15731
- polygon_generated: ((_D = feature == null ? void 0 : feature.geometry) == null ? void 0 : _D.coordinates.length) > 0 ? true : false
16264
+ organization: (_z = (_y = (_x = feature == null ? void 0 : feature.properties) == null ? void 0 : _x.parameters) == null ? void 0 : _y.WMOidentifier) == null ? void 0 : _z[0],
16265
+ ugc: (_C = (_B = (_A = feature == null ? void 0 : feature.properties) == null ? void 0 : _A.geocode) == null ? void 0 : _B.UGC) != null ? _C : [],
16266
+ polygon: ((_D = feature == null ? void 0 : feature.geometry) == null ? void 0 : _D.coordinates.length) > 0 ? Buffer.from(JSON.stringify([(_E = feature == null ? void 0 : feature.geometry) == null ? void 0 : _E.coordinates[0]])).toString("base64") : null,
16267
+ polygon_generated: ((_F = feature == null ? void 0 : feature.geometry) == null ? void 0 : _F.coordinates.length) > 0 ? true : false
15732
16268
  },
15733
16269
  parameters: {
15734
- tags: getEventTags((_E = feature == null ? void 0 : feature.properties) == null ? void 0 : _E.description),
15735
- instructions: (_G = (_F = feature == null ? void 0 : feature.properties) == null ? void 0 : _F.instruction) != null ? _G : null,
15736
- source: (_I = getTextFromProduct({ message: (_H = feature == null ? void 0 : feature.properties) == null ? void 0 : _H.description, find: [`SOURCE...`], removal: [`.`] })) != null ? _I : null,
15737
- hazards: (_K = getTextFromProduct({ message: (_J = feature == null ? void 0 : feature.properties) == null ? void 0 : _J.description, find: [`HAZARD...`], removal: [`.`] })) != null ? _K : null,
15738
- impacts: (_M = getTextFromProduct({ message: (_L = feature == null ? void 0 : feature.properties) == null ? void 0 : _L.description, find: [`IMPACT...`], removal: [`.`] })) != null ? _M : null,
15739
- estimated_hail_size: (_Q = (_P = (_O = (_N = feature == null ? void 0 : feature.properties) == null ? void 0 : _N.parameters) == null ? void 0 : _O.maxHailSize) == null ? void 0 : _P[0]) != null ? _Q : null,
15740
- estimated_wind_gusts: (_U = (_T = (_S = (_R = feature == null ? void 0 : feature.properties) == null ? void 0 : _R.parameters) == null ? void 0 : _S.maxWindGust) == null ? void 0 : _T[0]) != null ? _U : null,
15741
- damage_threat: (_Y = (_X = (_W = (_V = feature == null ? void 0 : feature.properties) == null ? void 0 : _V.parameters) == null ? void 0 : _W.thunderstormDamageThreat) == null ? void 0 : _X[0]) != null ? _Y : null,
15742
- tornado_threat: (_aa = (_$ = (__ = (_Z = feature == null ? void 0 : feature.properties) == null ? void 0 : _Z.parameters) == null ? void 0 : __.tornadoDetection) == null ? void 0 : _$[0]) != null ? _aa : null,
15743
- flood_threat: (_ea = (_da = (_ca = (_ba = feature == null ? void 0 : feature.properties) == null ? void 0 : _ba.parameters) == null ? void 0 : _ca.floodDetection) == null ? void 0 : _da[0]) != null ? _ea : null,
15744
- wind_threat: (_ia = (_ha = (_ga = (_fa = feature == null ? void 0 : feature.properties) == null ? void 0 : _fa.parameters) == null ? void 0 : _ga.windThreat) == null ? void 0 : _ha[0]) != null ? _ia : null,
15745
- hail_threat: (_ma = (_la = (_ka = (_ja = feature == null ? void 0 : feature.properties) == null ? void 0 : _ja.parameters) == null ? void 0 : _ka.hailThreat) == null ? void 0 : _la[0]) != null ? _ma : null
16270
+ tags: getEventTags((_G = feature == null ? void 0 : feature.properties) == null ? void 0 : _G.description),
16271
+ instructions: (_I = (_H = feature == null ? void 0 : feature.properties) == null ? void 0 : _H.instruction) != null ? _I : null,
16272
+ source: (_K = getTextFromProduct({ message: (_J = feature == null ? void 0 : feature.properties) == null ? void 0 : _J.description, find: [`SOURCE...`], removal: [`.`] })) != null ? _K : null,
16273
+ hazards: (_M = getTextFromProduct({ message: (_L = feature == null ? void 0 : feature.properties) == null ? void 0 : _L.description, find: [`HAZARD...`], removal: [`.`] })) != null ? _M : null,
16274
+ impacts: (_O = getTextFromProduct({ message: (_N = feature == null ? void 0 : feature.properties) == null ? void 0 : _N.description, find: [`IMPACT...`], removal: [`.`] })) != null ? _O : null,
16275
+ estimated_hail_size: (_S = (_R = (_Q = (_P = feature == null ? void 0 : feature.properties) == null ? void 0 : _P.parameters) == null ? void 0 : _Q.maxHailSize) == null ? void 0 : _R[0]) != null ? _S : null,
16276
+ estimated_wind_gusts: (_W = (_V = (_U = (_T = feature == null ? void 0 : feature.properties) == null ? void 0 : _T.parameters) == null ? void 0 : _U.maxWindGust) == null ? void 0 : _V[0]) != null ? _W : null,
16277
+ damage_threat: (__ = (_Z = (_Y = (_X = feature == null ? void 0 : feature.properties) == null ? void 0 : _X.parameters) == null ? void 0 : _Y.thunderstormDamageThreat) == null ? void 0 : _Z[0]) != null ? __ : null,
16278
+ tornado_threat: (_ca = (_ba = (_aa = (_$ = feature == null ? void 0 : feature.properties) == null ? void 0 : _$.parameters) == null ? void 0 : _aa.tornadoDetection) == null ? void 0 : _ba[0]) != null ? _ca : null,
16279
+ flood_threat: (_ga = (_fa = (_ea = (_da = feature == null ? void 0 : feature.properties) == null ? void 0 : _da.parameters) == null ? void 0 : _ea.floodDetection) == null ? void 0 : _fa[0]) != null ? _ga : null,
16280
+ wind_threat: (_ka = (_ja = (_ia = (_ha = feature == null ? void 0 : feature.properties) == null ? void 0 : _ha.parameters) == null ? void 0 : _ia.windThreat) == null ? void 0 : _ja[0]) != null ? _ka : null,
16281
+ hail_threat: (_oa = (_na = (_ma = (_la = feature == null ? void 0 : feature.properties) == null ? void 0 : _la.parameters) == null ? void 0 : _ma.hailThreat) == null ? void 0 : _na[0]) != null ? _oa : null
15746
16282
  },
15747
- spc_parameters: {
15748
- spc_max_tornado: (_oa = getTextFromProduct({ message: (_na = feature == null ? void 0 : feature.properties) == null ? void 0 : _na.description, find: [`MOST PROBABLE PEAK TORNADO INTENSITY...`] })) != null ? _oa : null,
15749
- spc_max_hail: (_qa = getTextFromProduct({ message: (_pa = feature == null ? void 0 : feature.properties) == null ? void 0 : _pa.description, find: [`MOST PROBABLE PEAK HAIL SIZE...`] })) != null ? _qa : null,
15750
- spc_max_wind: (_sa = getTextFromProduct({ message: (_ra = feature == null ? void 0 : feature.properties) == null ? void 0 : _ra.description, find: [`MOST PROBABLE PEAK WIND GUST...`] })) != null ? _sa : null,
15751
- spc_watch_issuance: (_ua = getTextFromProduct({ message: (_ta = feature == null ? void 0 : feature.properties) == null ? void 0 : _ta.description, find: [`Probability of Watch Issuance...`], removal: [`percent`] })) != null ? _ua : null
16283
+ discussion_parameters: {
16284
+ discussion_number: (_sa = (_ra = (_qa = getTextFromProduct({ message: (_pa = feature == null ? void 0 : feature.properties) == null ? void 0 : _pa.description, find: [`Mesoscale Discussion `], removal: [`Mesoscale Discussion`, `Number`, `...`] })) == null ? void 0 : _qa.toString()) == null ? void 0 : _ra.padStart(4, "0")) != null ? _sa : null,
16285
+ discussion_concerning: (_ua = getTextFromProduct({ message: (_ta = feature == null ? void 0 : feature.properties) == null ? void 0 : _ta.description, find: [`Concerning...`] })) != null ? _ua : null,
16286
+ discussion_max_tornado: (_wa = getTextFromProduct({ message: (_va = feature == null ? void 0 : feature.properties) == null ? void 0 : _va.description, find: [`MOST PROBABLE PEAK TORNADO INTENSITY...`] })) != null ? _wa : null,
16287
+ discussion_max_hail: (_ya = getTextFromProduct({ message: (_xa = feature == null ? void 0 : feature.properties) == null ? void 0 : _xa.description, find: [`MOST PROBABLE PEAK HAIL SIZE...`] })) != null ? _ya : null,
16288
+ discussion_max_wind: (_Aa = getTextFromProduct({ message: (_za = feature == null ? void 0 : feature.properties) == null ? void 0 : _za.description, find: [`MOST PROBABLE PEAK WIND GUST...`] })) != null ? _Aa : null,
16289
+ discussion_watch_issuance: (_Ca = getTextFromProduct({ message: (_Ba = feature == null ? void 0 : feature.properties) == null ? void 0 : _Ba.description, find: [`Probability of Watch Issuance...`], removal: [`percent`] })) != null ? _Ca : null
15752
16290
  },
15753
16291
  watch_parameters: {
15754
- watch_number: (_ya = (_xa = (_wa = getTextFromProduct({ message: (_va = feature == null ? void 0 : feature.properties) == null ? void 0 : _va.description, find: [`ITIES FOR`, `UPDATE FOR`, `Watch Number `], removal: [`%`, `<`, `:`] })) == null ? void 0 : _wa.replace(/(WT|WS|)/g, "")) == null ? void 0 : _xa.trim()) != null ? _ya : null,
15755
- watch_type: ((_za = feature == null ? void 0 : feature.properties) == null ? void 0 : _za.description.includes(`TORNADO WATCH`)) ? `Tornado` : ((_Aa = feature == null ? void 0 : feature.properties) == null ? void 0 : _Aa.description.includes(`SEVERE`)) ? `Severe` : null,
15756
- additional_tornadoes_probability: (_Ca = getTextFromProduct({ message: (_Ba = feature == null ? void 0 : feature.properties) == null ? void 0 : _Ba.description, find: [`PROB OF 2 OR MORE TORNADOES`], removal: [`%`, `<`, `:`] })) != null ? _Ca : null,
15757
- strong_tornadoes_probability: (_Ea = getTextFromProduct({ message: (_Da = feature == null ? void 0 : feature.properties) == null ? void 0 : _Da.description, find: [`PROB OF 1 OR MORE STRONG /EF2-EF5/ TORNADOES`], removal: [`%`, `<`, `:`] })) != null ? _Ea : null,
15758
- severe_wind_probability: (_Ga = getTextFromProduct({ message: (_Fa = feature == null ? void 0 : feature.properties) == null ? void 0 : _Fa.description, find: [`PROB OF 10 OR MORE SEVERE WIND EVENTS`], removal: [`%`, `<`, `:`] })) != null ? _Ga : null,
15759
- severe_hail_probability: (_Ia = getTextFromProduct({ message: (_Ha = feature == null ? void 0 : feature.properties) == null ? void 0 : _Ha.description, find: [`PROB OF 10 OR MORE SEVERE HAIL EVENTS`], removal: [`%`, `<`, `:`] })) != null ? _Ia : null,
15760
- hail_2in_probability: (_Ka = getTextFromProduct({ message: (_Ja = feature == null ? void 0 : feature.properties) == null ? void 0 : _Ja.description, find: [`PROB OF 1 OR MORE HAIL EVENTS >= 2 INCHES`], removal: [`%`, `<`, `:`] })) != null ? _Ka : null,
15761
- combined_hail_wind_probability: (_Ma = getTextFromProduct({ message: (_La = feature == null ? void 0 : feature.properties) == null ? void 0 : _La.description, find: [`PROB OF 6 OR MORE COMBINED SEVERE HAIL/WIND EVENTS`], removal: [`%`, `<`, `:`] })) != null ? _Ma : null,
15762
- max_hail_in: (_Oa = getTextFromProduct({ message: (_Na = feature == null ? void 0 : feature.properties) == null ? void 0 : _Na.description, find: [`MAX HAIL /INCHES/`], removal: [`%`, `<`, `:`] })) != null ? _Oa : null,
15763
- max_wind_surface: (_Qa = getTextFromProduct({ message: (_Pa = feature == null ? void 0 : feature.properties) == null ? void 0 : _Pa.description, find: [`MAX WIND GUSTS SURFACE /KNOTS/`], removal: [`%`, `<`, `:`] })) != null ? _Qa : null,
15764
- max_tops_x100feet: (_Sa = getTextFromProduct({ message: (_Ra = feature == null ? void 0 : feature.properties) == null ? void 0 : _Ra.description, find: [`MAX TOPS /X 100 FEET/`], removal: [`%`, `<`, `:`] })) != null ? _Sa : null,
15765
- pds_watch: getTextFromProduct({ message: (_Ta = feature == null ? void 0 : feature.properties) == null ? void 0 : _Ta.description, find: [`PARTICULARLY DANGEROUS SITUATION`], removal: [`%`, `<`, `:`] }) === `YES`
16292
+ watch_number: ((_Da = pVtec == null ? void 0 : pVtec[0]) == null ? void 0 : _Da.is_watch) && ((_Oa = (_Na = (_Ia = (_Ha = (_Ga = (_Fa = getTextFromProduct({ message: (_Ea = feature == null ? void 0 : feature.properties) == null ? void 0 : _Ea.description, find: [`ITIES FOR`, `UPDATE FOR`, `Watch Number `], removal: [`%`, `<`, `:`] })) == null ? void 0 : _Fa.replace(/(WT|WS|)/g, "")) == null ? void 0 : _Ga.trim()) == null ? void 0 : _Ha.toString()) == null ? void 0 : _Ia.padStart(4, "0")) != null ? _Na : (_Ma = (_La = (_Ka = (_Ja = pVtec == null ? void 0 : pVtec[0]) == null ? void 0 : _Ja.tracking) == null ? void 0 : _Ka.slice(-4)) == null ? void 0 : _La.toString()) == null ? void 0 : _Ma.padStart(4, "0")) != null ? _Oa : null),
16293
+ watch_type: ((_Pa = feature == null ? void 0 : feature.properties) == null ? void 0 : _Pa.description.includes(`TORNADO WATCH`)) ? `Tornado` : ((_Qa = feature == null ? void 0 : feature.properties) == null ? void 0 : _Qa.description.includes(`SEVERE`)) ? `Severe` : null,
16294
+ additional_tornadoes_probability: (_Sa = getTextFromProduct({ message: (_Ra = feature == null ? void 0 : feature.properties) == null ? void 0 : _Ra.description, find: [`PROB OF 2 OR MORE TORNADOES`], removal: [`%`, `<`, `:`] })) != null ? _Sa : null,
16295
+ strong_tornadoes_probability: (_Ua = getTextFromProduct({ message: (_Ta = feature == null ? void 0 : feature.properties) == null ? void 0 : _Ta.description, find: [`PROB OF 1 OR MORE STRONG /EF2-EF5/ TORNADOES`], removal: [`%`, `<`, `:`] })) != null ? _Ua : null,
16296
+ severe_wind_probability: (_Wa = getTextFromProduct({ message: (_Va = feature == null ? void 0 : feature.properties) == null ? void 0 : _Va.description, find: [`PROB OF 10 OR MORE SEVERE WIND EVENTS`], removal: [`%`, `<`, `:`] })) != null ? _Wa : null,
16297
+ severe_hail_probability: (_Ya = getTextFromProduct({ message: (_Xa = feature == null ? void 0 : feature.properties) == null ? void 0 : _Xa.description, find: [`PROB OF 10 OR MORE SEVERE HAIL EVENTS`], removal: [`%`, `<`, `:`] })) != null ? _Ya : null,
16298
+ hail_2in_probability: (__a = getTextFromProduct({ message: (_Za = feature == null ? void 0 : feature.properties) == null ? void 0 : _Za.description, find: [`PROB OF 1 OR MORE HAIL EVENTS >= 2 INCHES`], removal: [`%`, `<`, `:`] })) != null ? __a : null,
16299
+ combined_hail_wind_probability: (_ab = getTextFromProduct({ message: (_$a = feature == null ? void 0 : feature.properties) == null ? void 0 : _$a.description, find: [`PROB OF 6 OR MORE COMBINED SEVERE HAIL/WIND EVENTS`], removal: [`%`, `<`, `:`] })) != null ? _ab : null,
16300
+ max_hail_in: (_cb = getTextFromProduct({ message: (_bb = feature == null ? void 0 : feature.properties) == null ? void 0 : _bb.description, find: [`MAX HAIL /INCHES/`], removal: [`%`, `<`, `:`] })) != null ? _cb : null,
16301
+ max_wind_surface: (_eb = getTextFromProduct({ message: (_db = feature == null ? void 0 : feature.properties) == null ? void 0 : _db.description, find: [`MAX WIND GUSTS SURFACE /KNOTS/`], removal: [`%`, `<`, `:`] })) != null ? _eb : null,
16302
+ max_tops_x100feet: (_gb = getTextFromProduct({ message: (_fb = feature == null ? void 0 : feature.properties) == null ? void 0 : _fb.description, find: [`MAX TOPS /X 100 FEET/`], removal: [`%`, `<`, `:`] })) != null ? _gb : null,
16303
+ pds_watch: getTextFromProduct({ message: (_hb = feature == null ? void 0 : feature.properties) == null ? void 0 : _hb.description, find: [`PARTICULARLY DANGEROUS SITUATION`], removal: [`%`, `<`, `:`] }) === `YES`
15766
16304
  },
15767
16305
  metadata: {
15768
16306
  ms: performance.now() - tick,
15769
16307
  source: `events.api`,
15770
- tracking: getEventTracking({ type: `API`, organization: { wmoidentifier: (_Wa = (_Va = (_Ua = feature == null ? void 0 : feature.properties) == null ? void 0 : _Ua.parameters) == null ? void 0 : _Va.WMOidentifier) == null ? void 0 : _Wa[0], featureId: feature == null ? void 0 : feature.id }, vtec: pVtec }),
15771
- header: `ZCZC-ATMOSX-${(_Ya = (_Xa = feature == null ? void 0 : feature.properties) == null ? void 0 : _Xa.parameters) == null ? void 0 : _Ya.WMOidentifier}`,
15772
- vtec: pVtec,
16308
+ tracking: getEventTracking({ type: `API`, organization: { wmoidentifier: (_kb = (_jb = (_ib = feature == null ? void 0 : feature.properties) == null ? void 0 : _ib.parameters) == null ? void 0 : _jb.WMOidentifier) == null ? void 0 : _kb[0], featureId: feature == null ? void 0 : feature.id }, vtec: pVtec == null ? void 0 : pVtec[0] }),
16309
+ header: `ZCZC-ATMOSX-${(_mb = (_lb = feature == null ? void 0 : feature.properties) == null ? void 0 : _lb.parameters) == null ? void 0 : _mb.WMOidentifier}`,
16310
+ vtec: pVtec == null ? void 0 : pVtec[0],
15773
16311
  hvtec: null,
16312
+ raw: (_nb = feature == null ? void 0 : feature.properties) == null ? void 0 : _nb.description,
15774
16313
  history: [
15775
16314
  {
15776
- description: (_Za = feature == null ? void 0 : feature.properties) == null ? void 0 : _Za.description,
15777
- issued: ((__a = feature == null ? void 0 : feature.properties) == null ? void 0 : __a.sent) ? new Date((_$a = feature == null ? void 0 : feature.properties) == null ? void 0 : _$a.sent).toISOString() : null,
15778
- status: (_bb = (_ab = feature == null ? void 0 : feature.properties) == null ? void 0 : _ab.messageType) != null ? _bb : null
16315
+ description: (_ob = feature == null ? void 0 : feature.properties) == null ? void 0 : _ob.description,
16316
+ issued: ((_pb = feature == null ? void 0 : feature.properties) == null ? void 0 : _pb.sent) ? new Date((_qb = feature == null ? void 0 : feature.properties) == null ? void 0 : _qb.sent).toISOString() : null,
16317
+ status: (_sb = (_rb = feature == null ? void 0 : feature.properties) == null ? void 0 : _rb.messageType) != null ? _sb : null
15779
16318
  }
15780
16319
  ]
15781
16320
  }
@@ -15911,8 +16450,8 @@ var setSleep = (options) => __async(null, null, function* () {
15911
16450
  });
15912
16451
  });
15913
16452
 
15914
- // src/@dictionaries/dictionaries.shapefileLinks.ts
15915
- var shapefileLinks = [
16453
+ // src/@dictionaries/dictionaries.shapefiles.ts
16454
+ var dict_shapefiles = [
15916
16455
  { name: "us_counties", id: "C", link: "https://www.weather.gov/source/gis/Shapefiles/County/c_16ap26.zip" },
15917
16456
  { name: "us_states_territories", id: "Z", link: "https://www.weather.gov/source/gis/Shapefiles/County/s_16ap26.zip" },
15918
16457
  { name: "fire_weather_zones", id: "Z", link: "https://www.weather.gov/source/gis/Shapefiles/WSOM/fz16ap26.zip" },
@@ -15933,7 +16472,7 @@ var importShapefiles = () => __async(null, null, function* () {
15933
16472
  if (tShapefiles === 0) {
15934
16473
  yield setSleep({ timeout: 1e3 });
15935
16474
  setWarning({ message: `Shapefiles are currently building, please DO NOT close your terminal. The shapefiles will not finish and will remain incomplete. If you do mess up, you will need to delete ${settings.Database} and restart the application.` });
15936
- for (const shapefile of shapefileLinks) {
16475
+ for (const shapefile of dict_shapefiles) {
15937
16476
  const response2 = yield fetch(shapefile.link);
15938
16477
  const arrayBuff = yield response2.arrayBuffer();
15939
16478
  const content = yield loadAsync(arrayBuff);
@@ -15963,613 +16502,251 @@ var importShapefiles = () => __async(null, null, function* () {
15963
16502
  if (properties2.FIPS) {
15964
16503
  final2 = `${properties2.STATE}${shapefile.id}${properties2.FIPS.substring(2)}`;
15965
16504
  location = `${properties2.COUNTYNAME}, ${properties2.STATE}`;
15966
- } else if (properties2.FULLSTAID) {
15967
- final2 = `${properties2.ST}${shapefile.id}${properties2.WFO}`;
15968
- location = `${properties2.CITY}, ${properties2.STATE}`;
15969
- } else if (properties2.STATE) {
15970
- final2 = `${properties2.STATE}${shapefile.id}${(_a2 = properties2.ZONE) != null ? _a2 : properties2.SITE_ID}`;
15971
- location = `${(_b2 = properties2.NAME) != null ? _b2 : `${properties2.RFC_NAME} ${properties2.RFC_CITY}`}, ${properties2.STATE}`;
15972
- } else {
15973
- final2 = (_c = properties2.ID) != null ? _c : properties2.WFO;
15974
- location = properties2.NAME;
15975
- }
15976
- insert.run(final2, location, JSON.stringify(geometry));
15977
- }
15978
- });
15979
- fs.unlinkSync(`${filepath}.shp`);
15980
- fs.unlinkSync(`${filepath}.dbf`);
15981
- setWarning({ message: `Cleaned up temporary files for ${shapefile.name}_${shapefile.id}` });
15982
- transaction(features);
15983
- }
15984
- setWarning({ message: `Shapefiles have finished compiling, you can now continue and close this terminal` });
15985
- fs.rm(resolve5(__dirname, "../../shapefiles"), { recursive: true, force: true }, () => {
15986
- });
15987
- }
15988
- } catch (error) {
15989
- setWarning({ message: `An error occurred while compiling shapefiles: ${error.message}` });
15990
- }
15991
- });
15992
-
15993
- // src/@modules/@database/database.init.ts
15994
- var initializeDatabase = () => __async(null, null, function* () {
15995
- const settings = bootstrap.settings;
15996
- try {
15997
- if (!fs2.existsSync(settings.Database)) {
15998
- fs2.writeFileSync(settings.Database, "");
15999
- setWarning({ message: `Creating new database at ${settings.Database}` });
16000
- }
16001
- bootstrap.database = new sqlite3(settings.Database);
16002
- bootstrap.database.prepare(`CREATE TABLE IF NOT EXISTS stanzas ( id INTEGER PRIMARY KEY AUTOINCREMENT, type TEXT, issued TEXT, stanza TEXT )`).run();
16003
- bootstrap.database.prepare(`CREATE TABLE IF NOT EXISTS shapefiles (id TEXT PRIMARY KEY, location TEXT, geometry TEXT)`).run();
16004
- yield importShapefiles();
16005
- } catch (error) {
16006
- setWarning({ message: `An error occurred while initializing the database: ${error.message}` });
16007
- }
16008
- });
16009
-
16010
- // src/@modules/@database/database.cache.ts
16011
- var getCachedEvents = () => __async(null, null, function* () {
16012
- var _a;
16013
- try {
16014
- const settings = bootstrap.settings;
16015
- const tick = performance.now();
16016
- if (settings.NOAAWeatherWireServiceSettings.CacheSettings.Enabled) {
16017
- const max = (_a = settings.NOAAWeatherWireServiceSettings.CacheSettings.MaxRetentionHistory) != null ? _a : 500;
16018
- const get = yield bootstrap.database.prepare(`SELECT * FROM stanzas ORDER BY rowid DESC LIMIT ?`).all(max);
16019
- setWarning({ message: `Fetched ${get.length} cached events from the database in ${Math.floor(performance.now() - tick)} ms` });
16020
- let events = get.map((row) => JSON.parse(row.stanza)).filter((stanza) => {
16021
- if (!stanza) {
16022
- return;
16023
- }
16024
- const isSkippable = stanza.isIgnored || stanza.isCapEvent || stanza.isCapEvent && !stanza.isCapAreaDescription;
16025
- return !isSkippable;
16026
- });
16027
- events = events.sort((a, b) => b.issued - a.issued);
16028
- yield Promise.all(events.map((event) => createEvent(event)));
16029
- setWarning({ message: `Processed ${events.length} cached events in ${Math.floor(performance.now() - tick)} ms` });
16030
- }
16031
- } catch (error) {
16032
- setWarning({ message: `An error occurred while fetching cached events: ${error.message} -> ${error.stack}` });
16033
- }
16034
- });
16035
-
16036
- // src/@modules/@xmpp/xmpp.xReconnect.ts
16037
- var xReconnect = (interval) => __async(null, null, function* () {
16038
- const settings = bootstrap.settings;
16039
- const lastStanza = Date.now() - bootstrap.cache.lastStanza;
16040
- if (interval < 15) {
16041
- setWarning({ message: `Reconnection interval of ${interval} seconds is too low, setting to 15 seconds` });
16042
- interval = 15;
16043
- bootstrap.settings.NOAAWeatherWireServiceSettings.ReconnectionSettings.ReconnectionInterval = 15;
16044
- }
16045
- const reconnectThreshold = interval * 1e3;
16046
- if (!bootstrap.cache.isConnected && !bootstrap.cache.sigHault || !bootstrap.session_xmpp) {
16047
- return;
16048
- }
16049
- if (lastStanza > reconnectThreshold) {
16050
- if (!bootstrap.cache.isReconnecting) {
16051
- bootstrap.cache.isReconnecting = true;
16052
- bootstrap.cache.isConnected = false;
16053
- bootstrap.cache.tReconnects += 1;
16054
- try {
16055
- setEventEmit({
16056
- event: `onServiceStatus`,
16057
- metadata: {
16058
- message: `Attempting to reconnect to XMPP Service (Reconnect Attempt ${bootstrap.cache.tReconnects})`,
16059
- data: {
16060
- last_stanza: lastStanza,
16061
- nickname: settings.NOAAWeatherWireServiceSettings.CredentialSettings.Nickname
16062
- },
16063
- type: `reconnect`,
16064
- error: true
16065
- }
16066
- });
16067
- yield bootstrap.session_xmpp.stop().catch(() => {
16068
- });
16069
- yield bootstrap.session_xmpp.start().catch(() => {
16070
- });
16071
- } catch (error) {
16072
- setWarning({ message: `XMPP Reconnect Failed - ${error.message}` });
16073
- } finally {
16074
- bootstrap.cache.isReconnecting = false;
16075
- }
16076
- }
16077
- }
16078
- });
16079
-
16080
- // src/@modules/@utilities/utilities.setCronSchedule.ts
16081
- var setCronSchedule = () => __async(null, null, function* () {
16082
- const settings = bootstrap.settings;
16083
- if (settings.EnableWireService) {
16084
- if (settings.NOAAWeatherWireServiceSettings.ReconnectionSettings.Enabled) {
16085
- void xReconnect(settings.NOAAWeatherWireServiceSettings.ReconnectionSettings.ReconnectionInterval);
16086
- }
16087
- } else {
16088
- const response2 = yield createHttp({
16089
- url: settings.NationalWeatherServiceSettings.EventsEndpoint,
16090
- headers: {
16091
- "User-Agent": "@atmosx/event-product-parser"
16092
- }
16093
- });
16094
- if (response2.error) {
16095
- return setEventEmit({
16096
- event: `onServiceStatus`,
16097
- metadata: {
16098
- type: "fetch-api",
16099
- message: `Failed to fetch latest events from National Weather Service API - ${response2.message}`,
16100
- data: {},
16101
- error: true
16102
- }
16103
- });
16104
- }
16105
- setEventEmit({
16106
- event: `onServiceStatus`,
16107
- metadata: {
16108
- message: `Fetched latest events from National Weather Service API`,
16109
- data: {},
16110
- type: "fetch-api",
16111
- error: false
16112
- }
16113
- });
16114
- createEvent({ message: response2.message, isNWWS: false });
16115
- }
16116
- });
16117
-
16118
- // src/@manager/manager.updateEvents.ts
16119
- var updateEvents = (selectedEvent) => __async(null, null, function* () {
16120
- const events = bootstrap.cache.events.features;
16121
- function update(evt) {
16122
- return __async(this, null, function* () {
16123
- if (new Date(evt.properties.expires) < /* @__PURE__ */ new Date()) {
16124
- rmEvent(evt);
16125
- }
16126
- });
16127
- }
16128
- if (!selectedEvent) {
16129
- yield Promise.all(events.map((evt) => __async(null, null, function* () {
16130
- yield update(evt);
16131
- })));
16132
- }
16133
- if (selectedEvent) {
16134
- yield update(selectedEvent);
16135
- }
16136
- });
16137
-
16138
- // src/@core/core.start.ts
16139
- import { Cron } from "croner";
16140
- var startService = (configurations) => __async(null, null, function* () {
16141
- if (!bootstrap.isReady) {
16142
- return setWarning({
16143
- message: `You can not create another instance without shutting down the current one first, please make sure to call the stop() method first!`
16144
- });
16145
- }
16146
- const settings = setSettings(configurations);
16147
- bootstrap.isReady = true;
16148
- yield initializeDatabase();
16149
- if (settings.EnableWireService) {
16150
- (() => __async(null, null, function* () {
16151
- yield getCachedEvents();
16152
- yield xDeploy();
16153
- }))();
16154
- }
16155
- yield setCronSchedule();
16156
- let scheduleInterval = !settings.EnableWireService ? settings.NationalWeatherServiceSettings.CallbackInterval : 1;
16157
- if (!settings.EnableWireService && scheduleInterval < 15) {
16158
- setWarning({ message: `Schedule interval of ${scheduleInterval} seconds is too low, setting to 15 seconds` });
16159
- bootstrap.settings.NationalWeatherServiceSettings.CallbackInterval = 15;
16160
- scheduleInterval = 15;
16161
- }
16162
- bootstrap.cron = new Cron(`*/${scheduleInterval} * * * * *`, () => __async(null, null, function* () {
16163
- yield setCronSchedule();
16164
- }));
16165
- bootstrap.cron = new Cron(`* * * * * *`, () => __async(null, null, function* () {
16166
- yield updateNode();
16167
- yield updateEvents();
16168
- }));
16169
- });
16170
-
16171
- // src/@core/core.stop.ts
16172
- var stopService = () => __async(null, null, function* () {
16173
- if (bootstrap.isReady) {
16174
- bootstrap.isReady = false;
16175
- if (bootstrap.session_xmpp) {
16176
- try {
16177
- yield bootstrap.session_xmpp.stop();
16178
- } catch (e) {
16505
+ } else if (properties2.FULLSTAID) {
16506
+ final2 = `${properties2.ST}${shapefile.id}${properties2.WFO}`;
16507
+ location = `${properties2.CITY}, ${properties2.STATE}`;
16508
+ } else if (properties2.STATE) {
16509
+ final2 = `${properties2.STATE}${shapefile.id}${(_a2 = properties2.ZONE) != null ? _a2 : properties2.SITE_ID}`;
16510
+ location = `${(_b2 = properties2.NAME) != null ? _b2 : `${properties2.RFC_NAME} ${properties2.RFC_CITY}`}, ${properties2.STATE}`;
16511
+ } else {
16512
+ final2 = (_c = properties2.ID) != null ? _c : properties2.WFO;
16513
+ location = properties2.NAME;
16514
+ }
16515
+ insert.run(final2, location, JSON.stringify(geometry));
16516
+ }
16517
+ });
16518
+ fs.unlinkSync(`${filepath}.shp`);
16519
+ fs.unlinkSync(`${filepath}.dbf`);
16520
+ setWarning({ message: `Cleaned up temporary files for ${shapefile.name}_${shapefile.id}` });
16521
+ transaction(features);
16179
16522
  }
16180
- bootstrap.cache.isConnected = false;
16181
- bootstrap.cache.sigHault = true;
16182
- bootstrap.session_xmpp = null;
16523
+ setWarning({ message: `Shapefiles have finished compiling, you can now continue and close this terminal` });
16524
+ fs.rm(resolve5(__dirname, "../../shapefiles"), { recursive: true, force: true }, () => {
16525
+ });
16183
16526
  }
16527
+ } catch (error) {
16528
+ setWarning({ message: `An error occurred while compiling shapefiles: ${error.message}` });
16184
16529
  }
16185
16530
  });
16186
16531
 
16187
- // src/@dictionaries/dictionaries.transcribedMessageReplacements.ts
16188
- var transcribedMessageReplacements = [
16189
- { regex: /\*/g, replacement: "" },
16190
- { regex: /\.{3,}/g, replacement: "" },
16191
- { regex: /\bUTC\b/g, replacement: "Coordinated Universal Time" },
16192
- { regex: /\bGMT\b/g, replacement: "Greenwich Mean Time" },
16193
- { regex: /\bEST\b(?!\w)/g, replacement: "Eastern Standard Time" },
16194
- { regex: /\bEDT\b(?!\w)/g, replacement: "Eastern Daylight Time" },
16195
- { regex: /\bCST\b(?!\w)/g, replacement: "Central Standard Time" },
16196
- { regex: /\bCDT\b(?!\w)/g, replacement: "Central Daylight Time" },
16197
- { regex: /\bMST\b(?!\w)/g, replacement: "Mountain Standard Time" },
16198
- { regex: /\bMDT\b(?!\w)/g, replacement: "Mountain Daylight Time" },
16199
- { regex: /\bPST\b(?!\w)/g, replacement: "Pacific Standard Time" },
16200
- { regex: /\bPDT\b(?!\w)/g, replacement: "Pacific Daylight Time" },
16201
- { regex: /\bAKST\b(?!\w)/g, replacement: "Alaska Standard Time" },
16202
- { regex: /\bAKDT\b(?!\w)/g, replacement: "Alaska Daylight Time" },
16203
- { regex: /\bHST\b(?!\w)/g, replacement: "Hawaii Standard Time" },
16204
- { regex: /\bHDT\b(?!\w)/g, replacement: "Hawaii Daylight Time" },
16205
- { regex: /\bmph\b(?!\w)/g, replacement: "miles per hour" },
16206
- { regex: /\bkm\/h\b(?!\w)/g, replacement: "kilometers per hour" },
16207
- { regex: /\bkmh\b(?!\w)/g, replacement: "kilometers per hour" },
16208
- { regex: /\bkt\b(?!\w)/g, replacement: "knots" },
16209
- { regex: /\bNE\b(?!\w)/g, replacement: "northeast" },
16210
- { regex: /\bNW\b(?!\w)/g, replacement: "northwest" },
16211
- { regex: /\bSE\b(?!\w)/g, replacement: "southeast" },
16212
- { regex: /\bSW\b(?!\w)/g, replacement: "southwest" },
16213
- { regex: /\bNM\b(?!\w)/g, replacement: "nautical miles" },
16214
- { regex: /\bdeg\b(?!\w)/g, replacement: "degrees" },
16215
- { regex: /\btstm\b(?!\w)/g, replacement: "thunderstorm" },
16216
- { regex: /\bmm\b(?!\w)/g, replacement: "millimeters" },
16217
- { regex: /\bcm\b(?!\w)/g, replacement: "centimeters" },
16218
- { regex: /\bin.\b(?!\w)/g, replacement: "inches" },
16219
- { regex: /\bft\b(?!\w)/g, replacement: "feet" },
16220
- { regex: /\bmi\b(?!\w)/g, replacement: "miles" },
16221
- { regex: /\bhr\b(?!\w)/g, replacement: "hour" },
16222
- { regex: /\bhourly\b(?!\w)/g, replacement: "per hour" },
16223
- { regex: /\bkg\b(?!\w)/g, replacement: "kilograms" },
16224
- { regex: /\bg\/kg\b(?!\w)/g, replacement: "grams per kilogram" },
16225
- { regex: /\bmb\b(?!\w)/g, replacement: "millibars" },
16226
- { regex: /\bhPa\b(?!\w)/g, replacement: "hectopascals" },
16227
- { regex: /\bPa\b(?!\w)/g, replacement: "pascals" },
16228
- { regex: /\bKPa\b(?!\w)/g, replacement: "kilopascals" },
16229
- { regex: /\bC\/hr\b(?!\w)/g, replacement: "degrees Celsius per hour" },
16230
- { regex: /\bF\/hr\b(?!\w)/g, replacement: "degrees Fahrenheit per hour" },
16231
- { regex: /\bC\/min\b(?!\w)/g, replacement: "degrees Celsius per minute" },
16232
- { regex: /\bF\/min\b(?!\w)/g, replacement: "degrees Fahrenheit per minute" },
16233
- { regex: /\bC\b(?!\w)/g, replacement: "degrees Celsius" },
16234
- { regex: /\bF\b(?!\w)/g, replacement: "degrees Fahrenheit" }
16235
- ];
16236
-
16237
- // src/@modules/@eas/eas.getWavPCM16.ts
16238
- var getWavPCM16 = (buffer) => {
16239
- if (buffer.toString("ascii", 0, 4) !== "RIFF" || buffer.toString("ascii", 8, 12) !== "WAVE") {
16240
- return null;
16241
- }
16242
- let fmt = null;
16243
- let data = null;
16244
- let i = 12;
16245
- while (i + 8 <= buffer.length) {
16246
- const id2 = buffer.toString("ascii", i, i + 4);
16247
- const size = buffer.readUInt32LE(i + 4);
16248
- const start = i + 8;
16249
- const end = start + size;
16250
- if (id2 === "fmt ") fmt = buffer.slice(start, end);
16251
- if (id2 === "data") data = buffer.slice(start, end);
16252
- i = end + size % 2;
16253
- }
16254
- if (!fmt || !data) return null;
16255
- const audioFormat = fmt.readUInt16LE(0);
16256
- const channels = fmt.readUInt16LE(2);
16257
- const sampleRate = fmt.readUInt32LE(4);
16258
- const bitsPerSample = fmt.readUInt16LE(14);
16259
- if (audioFormat !== 1 || bitsPerSample !== 16 || channels !== 1) {
16260
- return null;
16261
- }
16262
- const samples = new Int16Array(data.buffer, data.byteOffset, data.length / 2);
16263
- return { samples: new Int16Array(samples), sampleRate, channels, bitsPerSample };
16264
- };
16265
-
16266
- // src/@modules/@eas/eas.getSampledPCM16.ts
16267
- var getSampledPCM16 = (int16, originalRate, targetRate) => {
16268
- if (originalRate === targetRate) return int16;
16269
- const ratio = targetRate / originalRate;
16270
- const outLen = Math.max(1, Math.round(int16.length * ratio));
16271
- const out = new Int16Array(outLen);
16272
- for (let i = 0; i < outLen; i++) {
16273
- const pos = i / ratio;
16274
- const i0 = Math.floor(pos);
16275
- const i1 = Math.min(i0 + 1, int16.length - 1);
16276
- const frac = pos - i0;
16277
- const v = int16[i0] * (1 - frac) + int16[i1] * frac;
16278
- out[i] = Math.round(v);
16279
- }
16280
- return out;
16281
- };
16282
-
16283
- // src/@modules/@eas/eas.getPCMToFloat.ts
16284
- var getPCMToFloat = (int16) => {
16285
- const out = new Float32Array(int16.length);
16286
- for (let i = 0; i < int16.length; i++) out[i] = int16[i] / 32768;
16287
- return out;
16288
- };
16289
-
16290
- // src/@modules/@eas/eas.getFloatPCM16.ts
16291
- var getFloatPCM16 = (float32) => {
16292
- const out = new Int16Array(float32.length);
16293
- for (let i = 0; i < float32.length; i++) {
16294
- let v = Math.max(-1, Math.min(1, float32[i]));
16295
- out[i] = Math.round(v * 32767);
16296
- }
16297
- return out;
16298
- };
16299
-
16300
- // src/@modules/@eas/eas.setRadioEffect.ts
16301
- var setRadioEffect = (int16, sampleRate) => {
16302
- const hpCut = 3555;
16303
- const lpCut = 1600;
16304
- const x = getPCMToFloat(int16);
16305
- const dt = 1 / sampleRate;
16306
- const rcHP = 1 / (2 * Math.PI * hpCut);
16307
- const aHP = rcHP / (rcHP + dt);
16308
- let yHP = 0, xPrev = 0;
16309
- for (let i = 0; i < x.length; i++) {
16310
- const xi = x[i];
16311
- yHP = aHP * (yHP + xi - xPrev);
16312
- xPrev = xi;
16313
- x[i] = yHP;
16314
- }
16315
- const rcLP = 1 / (2 * Math.PI * lpCut);
16316
- const aLP = dt / (rcLP + dt);
16317
- let yLP = 0;
16318
- for (let i = 0; i < x.length; i++) {
16319
- yLP = yLP + aLP * (x[i] - yLP);
16320
- x[i] = yLP;
16532
+ // src/@modules/@database/database.init.ts
16533
+ var initializeDatabase = () => __async(null, null, function* () {
16534
+ const settings = bootstrap.settings;
16535
+ try {
16536
+ if (!fs2.existsSync(settings.Database)) {
16537
+ fs2.writeFileSync(settings.Database, "");
16538
+ setWarning({ message: `Creating new database at ${settings.Database}` });
16539
+ }
16540
+ bootstrap.database = new sqlite3(settings.Database);
16541
+ bootstrap.database.prepare(`CREATE TABLE IF NOT EXISTS stanzas ( id INTEGER PRIMARY KEY AUTOINCREMENT, type TEXT, issued TEXT, stanza TEXT )`).run();
16542
+ bootstrap.database.prepare(`CREATE TABLE IF NOT EXISTS shapefiles (id TEXT PRIMARY KEY, location TEXT, geometry TEXT)`).run();
16543
+ yield importShapefiles();
16544
+ } catch (error) {
16545
+ setWarning({ message: `An error occurred while initializing the database: ${error.message}` });
16321
16546
  }
16322
- const compGain = 2;
16323
- const norm = Math.tanh(compGain);
16324
- for (let i = 0; i < x.length; i++) x[i] = Math.tanh(x[i] * compGain) / norm;
16325
- return getFloatPCM16(x);
16326
- };
16547
+ });
16327
16548
 
16328
- // src/@modules/@eas/eas.setAFSK.ts
16329
- var setAFSK = (bits, sampleRate) => {
16330
- const baud = 520.83;
16331
- const markFreq = 2083.3;
16332
- const spaceFreq = 1562.5;
16333
- const amplitude = 0.6;
16334
- const twoPi = Math.PI * 2;
16335
- const result = [];
16336
- let phase = 0;
16337
- let frac = 0;
16338
- for (let b = 0; b < bits.length; b++) {
16339
- const bit = bits[b];
16340
- const freq = bit ? markFreq : spaceFreq;
16341
- const samplesPerBit = sampleRate / baud + frac;
16342
- const n = Math.round(samplesPerBit);
16343
- frac = samplesPerBit - n;
16344
- const inc = twoPi * freq / sampleRate;
16345
- for (let i = 0; i < n; i++) {
16346
- result.push(Math.round(Math.sin(phase) * amplitude * 32767));
16347
- phase += inc;
16348
- if (phase > twoPi) phase -= twoPi;
16549
+ // src/@modules/@database/database.cache.ts
16550
+ var getCachedEvents = () => __async(null, null, function* () {
16551
+ var _a;
16552
+ try {
16553
+ const settings = bootstrap.settings;
16554
+ const tick = performance.now();
16555
+ if (settings.NOAAWeatherWireServiceSettings.CacheSettings.Enabled) {
16556
+ const max = (_a = settings.NOAAWeatherWireServiceSettings.CacheSettings.MaxRetentionHistory) != null ? _a : 500;
16557
+ const get = yield bootstrap.database.prepare(`SELECT * FROM stanzas ORDER BY rowid DESC LIMIT ?`).all(max);
16558
+ setWarning({ message: `Fetched ${get.length} cached events from the database in ${Math.floor(performance.now() - tick)} ms` });
16559
+ let events = get.map((row) => JSON.parse(row.stanza)).filter((stanza) => {
16560
+ if (!stanza) {
16561
+ return;
16562
+ }
16563
+ const isSkippable = stanza.isIgnored || stanza.isCapEvent || stanza.isCapEvent && !stanza.isCapAreaDescription;
16564
+ return !isSkippable;
16565
+ });
16566
+ events = events.sort((a, b) => b.issued - a.issued);
16567
+ yield Promise.all(events.map((event) => createEvent(event)));
16568
+ setWarning({ message: `Processed ${events.length} cached events in ${Math.floor(performance.now() - tick)} ms` });
16349
16569
  }
16570
+ } catch (error) {
16571
+ setWarning({ message: `An error occurred while fetching cached events: ${error.message} -> ${error.stack}` });
16350
16572
  }
16351
- const fadeSamples = Math.floor(sampleRate * 2e-3);
16352
- for (let i = 0; i < fadeSamples; i++) {
16353
- const gain = i / fadeSamples;
16354
- result[i] = Math.round(result[i] * gain);
16355
- result[result.length - 1 - i] = Math.round(result[result.length - 1 - i] * gain);
16356
- }
16357
- return Int16Array.from(result);
16358
- };
16573
+ });
16359
16574
 
16360
- // src/@modules/@eas/eas.setAsciiToBits.ts
16361
- var setAsciiToBits = (str) => {
16362
- const bits = [];
16363
- for (let i = 0; i < str.length; i++) {
16364
- const c = str.charCodeAt(i) & 255;
16365
- bits.push(0);
16366
- for (let b = 0; b < 8; b++) bits.push(c >> b & 1);
16367
- bits.push(1, 1);
16575
+ // src/@modules/@xmpp/xmpp.xReconnect.ts
16576
+ var xReconnect = (interval) => __async(null, null, function* () {
16577
+ const settings = bootstrap.settings;
16578
+ const lastStanza = Date.now() - bootstrap.cache.lastStanza;
16579
+ if (interval < 15) {
16580
+ setWarning({ message: `Reconnection interval of ${interval} seconds is too low, setting to 15 seconds` });
16581
+ interval = 15;
16582
+ bootstrap.settings.NOAAWeatherWireServiceSettings.ReconnectionSettings.ReconnectionInterval = 15;
16368
16583
  }
16369
- return bits;
16370
- };
16371
-
16372
- // src/@modules/@eas/eas.getMergedPCM16.ts
16373
- var getMergedPCM16 = (arrays) => {
16374
- let total = 0;
16375
- for (const a of arrays) total += a.length;
16376
- const out = new Int16Array(total);
16377
- let o = 0;
16378
- for (const a of arrays) {
16379
- out.set(a, o);
16380
- o += a.length;
16584
+ const reconnectThreshold = interval * 1e3;
16585
+ if (!bootstrap.cache.isConnected && !bootstrap.cache.sigHault || !bootstrap.session_xmpp) {
16586
+ return;
16381
16587
  }
16382
- return out;
16383
- };
16384
-
16385
- // src/@modules/@eas/eas.setSameHeader.ts
16386
- var setSameHeader = (vtec2, repeats, sampleRate = 8e3, options = {}) => {
16387
- var _a, _b;
16388
- const preMarkSec = (_a = options.preMarkSec) != null ? _a : 0.3;
16389
- const gapSec = (_b = options.gapSec) != null ? _b : 0.1;
16390
- const bursts = [];
16391
- const gap = new Int16Array(Math.floor(gapSec * sampleRate));
16392
- for (let i = 0; i < repeats; i++) {
16393
- const bodyBits = setAsciiToBits(vtec2);
16394
- const body = setAFSK(bodyBits, sampleRate);
16395
- const extendedBodyDuration = Math.round(preMarkSec * sampleRate);
16396
- const extendedBody = new Int16Array(extendedBodyDuration + gap.length);
16397
- for (let j2 = 0; j2 < extendedBodyDuration; j2++) {
16398
- extendedBody[j2] = Math.round(body[j2 % body.length] * 0.2);
16588
+ if (lastStanza > reconnectThreshold) {
16589
+ if (!bootstrap.cache.isReconnecting) {
16590
+ bootstrap.cache.isReconnecting = true;
16591
+ bootstrap.cache.isConnected = false;
16592
+ bootstrap.cache.tReconnects += 1;
16593
+ try {
16594
+ setEventEmit({
16595
+ event: `onServiceStatus`,
16596
+ metadata: {
16597
+ message: `Attempting to reconnect to XMPP Service (Reconnect Attempt ${bootstrap.cache.tReconnects})`,
16598
+ data: {
16599
+ last_stanza: lastStanza,
16600
+ nickname: settings.NOAAWeatherWireServiceSettings.CredentialSettings.Nickname
16601
+ },
16602
+ type: `reconnect`,
16603
+ error: true
16604
+ }
16605
+ });
16606
+ yield bootstrap.session_xmpp.stop().catch(() => {
16607
+ });
16608
+ yield bootstrap.session_xmpp.start().catch(() => {
16609
+ });
16610
+ } catch (error) {
16611
+ setWarning({ message: `XMPP Reconnect Failed - ${error.message}` });
16612
+ } finally {
16613
+ bootstrap.cache.isReconnecting = false;
16614
+ }
16399
16615
  }
16400
- extendedBody.set(gap, extendedBodyDuration);
16401
- bursts.push(extendedBody);
16402
- if (i !== repeats - 1) bursts.push(gap);
16403
- }
16404
- return getMergedPCM16(bursts);
16405
- };
16406
-
16407
- // src/@modules/@eas/eas.setAttentionTone.ts
16408
- var setAttentionTone = (ms, sampleRate) => {
16409
- const len = Math.floor(ms * sampleRate);
16410
- const out = new Int16Array(len);
16411
- const f1 = 853;
16412
- const f2 = 960;
16413
- const twoPi = Math.PI * 2;
16414
- const amp = 0.1;
16415
- const fadeLen = Math.floor(sampleRate * 0);
16416
- for (let i = 0; i < len; i++) {
16417
- const t = i / sampleRate;
16418
- const s = Math.sin(twoPi * f1 * t) + Math.sin(twoPi * f2 * t);
16419
- let gain = 1;
16420
- if (i < fadeLen) gain = i / fadeLen;
16421
- else if (i > len - fadeLen) gain = (len - i) / fadeLen;
16422
- const v = Math.max(-1, Math.min(1, s / 2 * amp * gain));
16423
- out[i] = Math.round(v * 32767);
16424
- }
16425
- return out;
16426
- };
16427
-
16428
- // src/@modules/@eas/eas.setNoise.ts
16429
- var setNoise = (int16, noiseLevel = 0.02) => {
16430
- const x = getPCMToFloat(int16);
16431
- for (let i = 0; i < x.length; i++) x[i] += (Math.random() * 2 - 1) * noiseLevel;
16432
- let peak = 0;
16433
- for (let i = 0; i < x.length; i++) peak = Math.max(peak, Math.abs(x[i]));
16434
- if (peak > 1) for (let i = 0; i < x.length; i++) x[i] *= 0.98 / peak;
16435
- return getFloatPCM16(x);
16436
- };
16437
-
16438
- // src/@modules/@eas/eas.getPCM16.ts
16439
- var getPCM16 = (samples, sampleRate) => {
16440
- let o = 0;
16441
- const bytesPerSample = 2;
16442
- const blockAlign = 1 * bytesPerSample;
16443
- const byteRate = sampleRate * blockAlign;
16444
- const subchunk2Size = samples.length * bytesPerSample;
16445
- const chunkSize = 36 + subchunk2Size;
16446
- const buffer = Buffer.alloc(44 + subchunk2Size);
16447
- buffer.write("RIFF", o);
16448
- o += 4;
16449
- buffer.writeUInt32LE(chunkSize, o);
16450
- o += 4;
16451
- buffer.write("WAVE", o);
16452
- o += 4;
16453
- buffer.write("fmt ", o);
16454
- o += 4;
16455
- buffer.writeUInt32LE(16, o);
16456
- o += 4;
16457
- buffer.writeUInt16LE(1, o);
16458
- o += 2;
16459
- buffer.writeUInt16LE(1, o);
16460
- o += 2;
16461
- buffer.writeUInt32LE(sampleRate, o);
16462
- o += 4;
16463
- buffer.writeUInt32LE(byteRate, o);
16464
- o += 4;
16465
- buffer.writeUInt16LE(blockAlign, o);
16466
- o += 2;
16467
- buffer.writeUInt16LE(16, o);
16468
- o += 2;
16469
- buffer.write("data", o);
16470
- o += 4;
16471
- buffer.writeUInt32LE(subchunk2Size, o);
16472
- o += 4;
16473
- for (let i = 0; i < samples.length; i++, o += 2) {
16474
- buffer.writeInt16LE(samples[i].value, o);
16475
16616
  }
16476
- return buffer;
16477
- };
16617
+ });
16478
16618
 
16479
- // src/@modules/@eas/eas.setEasTone.ts
16480
- import { join } from "path";
16481
- import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync } from "fs";
16482
- import { execSync } from "child_process";
16483
- import { platform } from "os";
16484
- import say from "say";
16485
- var setEasTone = (options) => __async(null, null, function* () {
16619
+ // src/@modules/@utilities/utilities.setCronSchedule.ts
16620
+ import { readdirSync, unlinkSync as unlinkSync2, statSync, existsSync as existsSync3 } from "fs";
16621
+ import { join as join2 } from "path";
16622
+ var setCronSchedule = () => __async(null, null, function* () {
16486
16623
  const settings = bootstrap.settings;
16487
- const directory = settings.GlobalSettings.EASSettings.ArchiveDirectory;
16488
- const prefix = settings.GlobalSettings.EASSettings.IntroWavFile;
16489
- let message = options.message;
16490
- let header = options.header;
16491
- let buffTTS;
16492
- let buffRadio;
16493
- let buffFull = [];
16494
- const tmpTTS = join(directory, `/temp/${Math.random().toString(36).substring(2, 15)}-${header.replace(/[^a-zA-Z0-9]/g, "")}.wav`);
16495
- const outTTS = join(directory, `/output/${Math.random().toString(36).substring(2, 15)}-${header.replace(/[^a-zA-Z0-9]/g, "")}.wav`);
16496
- const vTTS = process.platform === `win32` ? `Microsoft David Desktop` : `en-US-GuyNerual`;
16497
- const vPlatform = platform();
16498
- if (!existsSync(directory)) {
16499
- mkdirSync(directory, { recursive: true });
16624
+ const TTL = settings.GlobalSettings.ArchiveSettings.TTL;
16625
+ const TTLCUT = Date.now() - TTL * 1e3;
16626
+ const walk = (dir) => {
16627
+ if (existsSync3(dir)) {
16628
+ const entries = readdirSync(dir, { withFileTypes: true });
16629
+ for (const entry of entries) {
16630
+ const fullPath = join2(dir, entry.name);
16631
+ if (entry.isDirectory()) {
16632
+ walk(fullPath);
16633
+ continue;
16634
+ }
16635
+ const stats = statSync(fullPath);
16636
+ if (stats.mtime.getTime() < TTLCUT) {
16637
+ try {
16638
+ unlinkSync2(fullPath);
16639
+ } catch (err) {
16640
+ console.error(`Failed to delete ${fullPath}:`, err);
16641
+ }
16642
+ }
16643
+ }
16644
+ }
16645
+ };
16646
+ walk(settings.GlobalSettings.ArchiveSettings.TextDirectory);
16647
+ walk(settings.GlobalSettings.ArchiveSettings.EasDirectory);
16648
+ if (settings.EnableWireService) {
16649
+ if (settings.NOAAWeatherWireServiceSettings.ReconnectionSettings.Enabled) {
16650
+ void xReconnect(settings.NOAAWeatherWireServiceSettings.ReconnectionSettings.ReconnectionInterval);
16651
+ }
16652
+ } else {
16653
+ const response2 = yield createHttp({
16654
+ url: settings.NationalWeatherServiceSettings.EventsEndpoint,
16655
+ headers: {
16656
+ "User-Agent": "@atmosx/event-product-parser"
16657
+ }
16658
+ });
16659
+ if (response2.error) {
16660
+ return setEventEmit({
16661
+ event: `onServiceStatus`,
16662
+ metadata: {
16663
+ type: "fetch-api",
16664
+ message: `Failed to fetch latest events from National Weather Service API - ${response2.message}`,
16665
+ data: {},
16666
+ error: true
16667
+ }
16668
+ });
16669
+ }
16670
+ setEventEmit({
16671
+ event: `onServiceStatus`,
16672
+ metadata: {
16673
+ message: `Fetched latest events from National Weather Service API`,
16674
+ data: {},
16675
+ type: "fetch-api",
16676
+ error: false
16677
+ }
16678
+ });
16679
+ createEvent({ message: response2.message, isNWWS: false });
16500
16680
  }
16501
- if (!existsSync(join(directory, `/temp`))) {
16502
- mkdirSync(join(directory, `/temp`), { recursive: true });
16681
+ });
16682
+
16683
+ // src/@manager/manager.updateEvents.ts
16684
+ var updateEvents = (selectedEvent) => __async(null, null, function* () {
16685
+ const events = bootstrap.cache.events.features;
16686
+ function update(evt) {
16687
+ return __async(this, null, function* () {
16688
+ if (new Date(evt.properties.expires) < /* @__PURE__ */ new Date()) {
16689
+ rmEvent(evt);
16690
+ }
16691
+ });
16503
16692
  }
16504
- if (!existsSync(join(directory, `/output`))) {
16505
- mkdirSync(join(directory, `/output`), { recursive: true });
16693
+ if (!selectedEvent) {
16694
+ yield Promise.all(events.map((evt) => __async(null, null, function* () {
16695
+ yield update(evt);
16696
+ })));
16506
16697
  }
16507
- for (const { regex, replacement } of transcribedMessageReplacements) {
16508
- message = message.replace(regex, replacement);
16698
+ if (selectedEvent) {
16699
+ yield update(selectedEvent);
16509
16700
  }
16510
- if (vPlatform != `win32`) {
16511
- setWarning({
16512
- title: `EAS`,
16513
- message: `Generation isn't supported with this OS. Please wait for further updates before trying again`
16701
+ });
16702
+
16703
+ // src/@core/core.start.ts
16704
+ import { Cron } from "croner";
16705
+ var startService = (configurations) => __async(null, null, function* () {
16706
+ if (!bootstrap.isReady) {
16707
+ return setWarning({
16708
+ message: `You can not create another instance without shutting down the current one first, please make sure to call the stop() method first!`
16514
16709
  });
16515
- return null;
16516
16710
  }
16517
- say.export(message, vTTS, 1, tmpTTS);
16518
- while (!existsSync(tmpTTS) || (buffTTS = readFileSync(tmpTTS)).length == 0) {
16519
- yield setSleep({ timeout: 25 });
16711
+ const settings = setSettings(configurations);
16712
+ bootstrap.isReady = true;
16713
+ yield initializeDatabase();
16714
+ if (settings.EnableWireService) {
16715
+ (() => __async(null, null, function* () {
16716
+ yield getCachedEvents();
16717
+ yield xDeploy();
16718
+ }))();
16520
16719
  }
16521
- const vWav = getWavPCM16(buffTTS);
16522
- const vSamples = getSampledPCM16(vWav.samples, vWav.sampleRate, 8e3);
16523
- const vRadio = setRadioEffect(vSamples, 8e3);
16524
- if (existsSync(prefix)) {
16525
- let tBuffer = readFileSync(prefix);
16526
- let tWav = getWavPCM16(tBuffer);
16527
- if (tWav == null) {
16720
+ yield setCronSchedule();
16721
+ let scheduleInterval = !settings.EnableWireService ? settings.NationalWeatherServiceSettings.CallbackInterval : 1;
16722
+ if (!settings.EnableWireService && scheduleInterval < 15) {
16723
+ setWarning({ message: `Schedule interval of ${scheduleInterval} seconds is too low, setting to 15 seconds` });
16724
+ bootstrap.settings.NationalWeatherServiceSettings.CallbackInterval = 15;
16725
+ scheduleInterval = 15;
16726
+ }
16727
+ bootstrap.cron = new Cron(`*/${scheduleInterval} * * * * *`, () => __async(null, null, function* () {
16728
+ yield setCronSchedule();
16729
+ }));
16730
+ bootstrap.cron = new Cron(`* * * * * *`, () => __async(null, null, function* () {
16731
+ yield updateNode();
16732
+ yield updateEvents();
16733
+ }));
16734
+ });
16735
+
16736
+ // src/@core/core.stop.ts
16737
+ var stopService = () => __async(null, null, function* () {
16738
+ if (bootstrap.isReady) {
16739
+ bootstrap.isReady = false;
16740
+ if (bootstrap.session_xmpp) {
16528
16741
  try {
16529
- const converted = join(directory, `/temp/${Math.random().toString(36).substring(2, 15)}.converted.wav`);
16530
- execSync(`ffmpeg -y -i "${prefix}" -ar 8000 -ac 1 -sample_fmt s16 "${converted}"`, { stdio: "ignore" });
16531
- if (existsSync(converted)) {
16532
- tBuffer = readFileSync(converted);
16533
- tWav = getWavPCM16(tBuffer);
16534
- try {
16535
- unlinkSync(converted);
16536
- } catch (e) {
16537
- }
16538
- }
16742
+ yield bootstrap.session_xmpp.stop();
16539
16743
  } catch (e) {
16540
16744
  }
16745
+ bootstrap.cache.isConnected = false;
16746
+ bootstrap.cache.sigHault = true;
16747
+ bootstrap.session_xmpp = null;
16541
16748
  }
16542
- if (tWav == null) {
16543
- setWarning({ title: `EAS`, message: `Intro tone isn't a valid .WAV file or isn't in PCM 16-bit format. Converted attempt failed; please convert it then try again.` });
16544
- return null;
16545
- }
16546
- const tSamples = tWav.sampleRate != 8e3 ? getSampledPCM16(tWav.samples, tWav.sampleRate, 8e3) : tWav.samples;
16547
- buffRadio = setRadioEffect(tSamples, 8e3);
16548
- }
16549
- buffFull = buffRadio != null ? [buffRadio, new Int16Array(Math.floor(0.5 * 8e3))] : [];
16550
- buffFull.push(
16551
- setSameHeader(header, 3, 8e3, {
16552
- preMarkSec: 1.1,
16553
- gapSec: 0.5
16554
- }),
16555
- new Int16Array(Math.floor(0.5 * 8e3)),
16556
- setAttentionTone(8, 8e3),
16557
- new Int16Array(Math.floor(0.5 * 8e3)),
16558
- vRadio
16559
- );
16560
- for (let i = 0; i < 3; i++) {
16561
- buffFull.push(setSameHeader(header, 1, 8e3, { preMarkSec: 0.5, gapSec: 0.1 }));
16562
- buffFull.push(new Int16Array(Math.floor(0.5 * 8e3)));
16563
- }
16564
- const aSamples = getMergedPCM16(buffFull);
16565
- const aFinal = setNoise(aSamples, 2e-3);
16566
- const aBuffer = getPCM16(Array.from(aFinal).map((v) => ({ value: v })), 8e3);
16567
- writeFileSync(outTTS, aBuffer);
16568
- try {
16569
- unlinkSync(tmpTTS);
16570
- } catch (e) {
16571
16749
  }
16572
- return outTTS;
16573
16750
  });
16574
16751
 
16575
16752
  // src/@core/core.setNode.ts
@@ -16635,6 +16812,59 @@ var getNodes = () => {
16635
16812
  return bootstrap.cache.nodes;
16636
16813
  };
16637
16814
 
16815
+ // src/@core/core.createEvent.ts
16816
+ var createEvent2 = (options) => {
16817
+ var _a;
16818
+ const tick = performance.now();
16819
+ validateEvents([{
16820
+ type: `Feature`,
16821
+ geometry: {
16822
+ type: `Point`,
16823
+ coordinates: options.coordinates
16824
+ },
16825
+ properties: {
16826
+ event: options.event,
16827
+ parent: options.event,
16828
+ status: options.status,
16829
+ issued: options.issued.toISOString(),
16830
+ expires: options.expires.toISOString(),
16831
+ locations: options.locations,
16832
+ description: options.description,
16833
+ geocode: {
16834
+ office: {
16835
+ office: `ATMX`,
16836
+ name: `AtmosphericX Manual Event`
16837
+ },
16838
+ organization: `AtmosphericX`,
16839
+ ugc: [],
16840
+ polygon: options.coordinates.length > 0 ? Buffer.from(JSON.stringify([options.coordinates[0]])).toString("base64") : null,
16841
+ polygon_generated: options.coordinates.length > 0 ? true : false
16842
+ },
16843
+ status_metadata: {
16844
+ is_issued: options.status == `Issued`,
16845
+ is_updated: options.status == `Updated`,
16846
+ is_expired: options.status == `Expired`,
16847
+ is_test: options.status == `Test`,
16848
+ is_statement: options.status == `Statement`
16849
+ },
16850
+ metadata: {
16851
+ ms: performance.now() - tick,
16852
+ source: `events.manual`,
16853
+ tracking: `ATMX-M-W-01`,
16854
+ header: `ZCZC-ATMOSX-ATMX-M-W-01`,
16855
+ raw: options.description,
16856
+ history: [
16857
+ {
16858
+ description: options.description,
16859
+ issued: options.issued.toISOString(),
16860
+ status: (_a = options.status) != null ? _a : null
16861
+ }
16862
+ ]
16863
+ }
16864
+ }
16865
+ }]);
16866
+ };
16867
+
16638
16868
  // src/@core/core.getRandomEvent.ts
16639
16869
  var getRandomEvent = () => {
16640
16870
  return bootstrap.cache.events.features[Math.floor(Math.random() * bootstrap.cache.events.features.length)];
@@ -16694,6 +16924,7 @@ var index_default = Manager;
16694
16924
  export {
16695
16925
  Manager,
16696
16926
  clearEvents,
16927
+ createEvent2 as createEvent,
16697
16928
  index_default as default,
16698
16929
  getCleanedEvent,
16699
16930
  getEventGeometry,