@atmosx/event-product-parser 3.0.621 → 3.1.0

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 (200) hide show
  1. package/.github/CHANGELOGS.md +52 -0
  2. package/.github/CODE_OF_CONDUCT.md +24 -1
  3. package/.github/CONTRIBUTING.md +22 -3
  4. package/.github/FUNDING.yaml +3 -0
  5. package/.github/LICENSE +24 -1
  6. package/.github/SECURITY.md +25 -6
  7. package/.github/docs/chapters/general-configurations.md +109 -0
  8. package/.github/docs/chapters/sources-and-attributes.md +219 -0
  9. package/README.md +56 -146
  10. package/dist/index.cjs +25333 -0
  11. package/package.json +17 -11
  12. package/pnpm-workspace.yaml +4 -0
  13. package/src/bootstrap.ts +67 -52
  14. package/src/components/audio/GenerateAudioMessage.ts +149 -0
  15. package/src/{@modules/@eas → components/audio/components}/GetCleanDescription.ts +2 -2
  16. package/src/{@modules/@eas → components/audio/components}/GetFloatPCM16.ts +2 -2
  17. package/src/{@modules/@eas → components/audio/components}/GetMergedPCM16.ts +2 -2
  18. package/src/{@modules/@eas → components/audio/components}/GetPCM16.ts +13 -8
  19. package/src/{@modules/@eas → components/audio/components}/GetPCMToFloat.ts +2 -2
  20. package/src/{@modules/@eas → components/audio/components}/GetSampledPCM16.ts +14 -8
  21. package/src/{@modules/@eas → components/audio/components}/GetTTS.ts +17 -10
  22. package/src/{@modules/@eas → components/audio/components}/GetWavPCM16.ts +7 -7
  23. package/src/{@modules/@eas → components/audio/components}/SetAFSK.ts +13 -8
  24. package/src/{@modules/@eas → components/audio/components}/SetAsciiToBits.ts +2 -2
  25. package/src/{@modules/@eas → components/audio/components}/SetAttentionTone.ts +11 -6
  26. package/src/{@modules/@eas → components/audio/components}/SetNoise.ts +12 -7
  27. package/src/{@modules/@eas → components/audio/components}/SetRadioEffect.ts +12 -7
  28. package/src/{@modules/@eas → components/audio/components}/SetSameHeader.ts +22 -14
  29. package/src/components/database/CreateQuery.ts +39 -0
  30. package/src/components/database/InitializeDatabase.ts +71 -0
  31. package/src/components/database/imports/Boundaires.ts +168 -0
  32. package/src/{@modules/@database/ImportBroadcastify.ts → components/database/imports/Broadcastify.ts} +15 -25
  33. package/src/components/database/imports/Census.ts +87 -0
  34. package/src/{@modules/@database/ImportShapefiles.ts → components/database/imports/Shapefiles.ts} +24 -27
  35. package/src/{@modules/@database/ImportStanza.ts → components/database/imports/Stanza.ts} +15 -19
  36. package/src/components/events/CreateEvents.ts +88 -0
  37. package/src/components/events/FilterEvents.ts +149 -0
  38. package/src/{@building/CreateEvent.ts → components/events/ProcessStanza.ts} +22 -24
  39. package/src/components/events/RemoveEvents.ts +74 -0
  40. package/src/{@building → components/events/components}/GetCleanedEvent.ts +2 -2
  41. package/src/{@building → components/events/components}/GetEventAttachments.ts +14 -12
  42. package/src/components/events/components/GetEventDirection.ts +28 -0
  43. package/src/{@building → components/events/components}/GetEventEnhancedName.ts +5 -8
  44. package/src/{@building → components/events/components}/GetEventGeometry.ts +19 -13
  45. package/src/{@building → components/events/components}/GetEventHeader.ts +13 -13
  46. package/src/components/events/components/GetEventMerged.ts +51 -0
  47. package/src/{@building → components/events/components}/GetEventNodes.ts +22 -20
  48. package/src/{@building → components/events/components}/GetEventOffice.ts +13 -13
  49. package/src/components/events/components/GetEventPopulation.ts +58 -0
  50. package/src/components/events/components/GetEventProperties.ts +106 -0
  51. package/src/{@building → components/events/components}/GetEventSignature.ts +9 -9
  52. package/src/{@building → components/events/components}/GetEventTags.ts +3 -3
  53. package/src/components/events/components/GetEventTheme.ts +26 -0
  54. package/src/components/events/components/GetEventTracking.ts +64 -0
  55. package/src/{@modules/@database → components/events/utilities}/GetCachedEvents.ts +18 -15
  56. package/src/{@manager → components/events/utilities}/SetHash.ts +18 -13
  57. package/src/{@manager → components/events/utilities}/UpdateEvents.ts +12 -12
  58. package/src/{@manager → components/events/utilities}/UpdateNode.ts +14 -14
  59. package/src/{@parsers/@text → components/formatting}/GetEmbededText.ts +14 -8
  60. package/src/{@parsers/@text → components/formatting}/GetStringText.ts +15 -11
  61. package/src/{@modules/@utilities → components/geometry}/GetShapeNearestPoint.ts +24 -19
  62. package/src/components/geometry/GetUnionPolygon.ts +36 -0
  63. package/src/components/images/GenerateGraphic.ts +242 -0
  64. package/src/components/images/components/CreateRectangle.ts +22 -0
  65. package/src/components/images/components/CreateText.ts +22 -0
  66. package/src/components/images/modules/CreateSVG.ts +37 -0
  67. package/src/components/images/modules/GetGeographicalBoundaries.ts +72 -0
  68. package/src/components/images/modules/GetGeographicalCities.ts +58 -0
  69. package/src/components/images/modules/GetGeographicalEvents.ts +48 -0
  70. package/src/components/images/modules/GetGeometryBounds.ts +82 -0
  71. package/src/components/images/modules/GetParsedBoundary.ts +58 -0
  72. package/src/components/images/modules/GetSVGPath.ts +53 -0
  73. package/src/components/images/modules/NormalizePolygon.ts +57 -0
  74. package/src/{@modules/@stanza → components/stanza}/GetAwipsType.ts +16 -17
  75. package/src/{@modules/@stanza → components/stanza}/ValidateStanza.ts +27 -15
  76. package/src/{@modules/@utilities → components/utilities}/CreateHttp.ts +26 -26
  77. package/src/components/utilities/EmitThread.ts +97 -0
  78. package/src/{@modules/@utilities → components/utilities}/GetLatestIssuance.ts +2 -2
  79. package/src/{@modules/@utilities → components/utilities}/GetMatched.ts +10 -5
  80. package/src/components/utilities/QueueManager.ts +70 -0
  81. package/src/{@modules/@utilities → components/utilities}/SetDebug.ts +13 -13
  82. package/src/components/utilities/SetEventEmit.ts +42 -0
  83. package/src/{@modules/@utilities → components/utilities}/SetSettings.ts +7 -7
  84. package/src/{@modules/@utilities → components/utilities}/SetSleep.ts +5 -5
  85. package/src/components/utilities/SetTimeoutAction.ts +64 -0
  86. package/src/components/utilities/SetWarning.ts +47 -0
  87. package/src/{@modules/@xmpp → components/xmpp}/DeployXMPP.ts +20 -20
  88. package/src/{@core/CreateListener.ts → components/xmpp/ErrorXMPP.ts} +8 -5
  89. package/src/{@modules/@xmpp → components/xmpp}/OfflineXMPP.ts +13 -13
  90. package/src/{@modules/@xmpp → components/xmpp}/OnlineXMPP.ts +18 -18
  91. package/src/components/xmpp/ReconnectXMPP.ts +64 -0
  92. package/src/{@modules/@xmpp → components/xmpp}/StanzaXMPP.ts +26 -26
  93. package/src/{@enums → enums}/AWIPS.ts +2 -2
  94. package/src/{@enums → enums}/Actions.ts +2 -2
  95. package/src/{@enums → enums}/Cancellation.ts +2 -2
  96. package/src/{@enums → enums}/Causes.ts +2 -2
  97. package/src/{@enums → enums}/Correlations.ts +2 -2
  98. package/src/{@enums → enums}/Enhanced.ts +4 -3
  99. package/src/{@enums → enums}/Events.ts +2 -2
  100. package/src/{@enums → enums}/Expressions.ts +3 -3
  101. package/src/{@enums → enums}/GlobalFilter.ts +2 -2
  102. package/src/{@enums → enums}/Hail.ts +2 -2
  103. package/src/{@enums → enums}/ICAO.ts +2 -2
  104. package/src/{@enums → enums}/Matches.ts +8 -3
  105. package/src/{@enums → enums}/Products.ts +2 -2
  106. package/src/{@enums → enums}/Records.ts +2 -2
  107. package/src/{@enums → enums}/Severity.ts +2 -2
  108. package/src/{@enums → enums}/Shapefiles.ts +2 -2
  109. package/src/{@enums → enums}/States.ts +68 -4
  110. package/src/{@enums → enums}/Status.ts +2 -2
  111. package/src/{@enums → enums}/Strings.ts +2 -2
  112. package/src/{@enums → enums}/Tags.ts +9 -4
  113. package/src/{@enums → enums}/Testing.ts +2 -2
  114. package/src/enums/Themes.ts +70 -0
  115. package/src/events/ParseAPI.ts +133 -0
  116. package/src/{@events → events}/ParseText.ts +24 -22
  117. package/src/{@events → events}/ParseUGC.ts +27 -26
  118. package/src/{@events → events}/ParseVTEC.ts +37 -36
  119. package/src/{@core → exports}/ClearEvents.ts +9 -9
  120. package/src/{@core → exports}/GetEvents.ts +4 -4
  121. package/src/exports/GetNearestCity.ts +45 -0
  122. package/src/{@core → exports}/GetNodes.ts +4 -4
  123. package/src/{@core → exports}/GetRandomEvent.ts +4 -4
  124. package/src/{@core → exports}/GetVersion.ts +4 -4
  125. package/src/exports/ManualEvent.ts +55 -0
  126. package/src/{@core → exports}/QueryStanza.ts +12 -11
  127. package/src/exports/SetNode.ts +100 -0
  128. package/src/{@core → exports}/StartService.ts +23 -22
  129. package/src/{@core → exports}/StopService.ts +10 -10
  130. package/src/index.ts +57 -37
  131. package/src/{@parsers/@hvtec → parsers/hvtec}/HVExtract.ts +7 -7
  132. package/src/{@parsers/@text → parsers/text}/GetDescriptionFromProduct.ts +20 -21
  133. package/src/parsers/text/GetPolygonFromProduct.ts +71 -0
  134. package/src/{@parsers/@text → parsers/text}/GetTextFromProduct.ts +12 -12
  135. package/src/parsers/ugc/GetCache.ts +24 -0
  136. package/src/{@parsers/@ugc → parsers/ugc}/GetExpiry.ts +2 -2
  137. package/src/{@parsers/@ugc/GetUGCHeader.ts → parsers/ugc/GetHeader.ts} +4 -4
  138. package/src/{@parsers/@ugc → parsers/ugc}/GetLocations.ts +10 -10
  139. package/src/parsers/ugc/GetZonePolygon.ts +73 -0
  140. package/src/{@parsers/@ugc → parsers/ugc}/GetZones.ts +3 -3
  141. package/src/{@parsers/@ugc → parsers/ugc}/SetCache.ts +13 -8
  142. package/src/{@parsers/@ugc → parsers/ugc}/UGCExtract.ts +14 -14
  143. package/src/{@parsers/@pvtec → parsers/vtec}/GetExpiry.ts +2 -2
  144. package/src/{@parsers/@pvtec → parsers/vtec}/VTECExtract.ts +17 -17
  145. package/src/tasks/CreateTasks.ts +116 -0
  146. package/src/tasks/TaskGenerateJSON.ts +34 -0
  147. package/src/tasks/TaskGenerateText.ts +34 -0
  148. package/src/tasks/TaskSendNTFY.ts +96 -0
  149. package/src/tasks/TaskSendWebhook.ts +107 -0
  150. package/src/{@types → types/event}/Attributes.ts +2 -3
  151. package/src/{@types → types/event}/Event.ts +8 -7
  152. package/src/{@types → types/event}/HVTEC.ts +2 -2
  153. package/src/{@types → types/event}/Properties.ts +17 -3
  154. package/src/{@types → types/event}/Stanza.ts +2 -2
  155. package/src/{@types → types/event}/VTEC.ts +8 -8
  156. package/src/{@types → types/standard}/Actions.ts +3 -3
  157. package/src/{@types → types/standard}/Hash.ts +5 -5
  158. package/src/{@modules/@utilities/GetSettings.ts → types/standard/Nodes.ts} +15 -7
  159. package/src/{@types → types/standard}/Settings.ts +19 -12
  160. package/src/{@types → types/standard}/StanzaCompiled.ts +15 -15
  161. package/src/{@types → types/standard}/UGC.ts +5 -5
  162. package/tools/build.js +32 -0
  163. package/tsconfig.json +32 -1
  164. package/.github/SUPPORTED_EVENTS.md +0 -370
  165. package/.github/docs/docs-functions.md +0 -30
  166. package/.github/docs/docs-general-configurations.md +0 -209
  167. package/.github/docs/docs-integrations.md +0 -37
  168. package/.github/docs/docs-listeners.md +0 -28
  169. package/.github/docs/docs-source-configuration.md +0 -218
  170. package/.github/docs/docs-technical.md +0 -50
  171. package/.github/logo.png +0 -0
  172. package/.github/samples/SAMPLE_EAS_GENERATION.wav +0 -0
  173. package/.github/samples/SAMPLE_GEOJSON.json +0 -204
  174. package/.github/samples/SAMPLE_TEXT_PRODUCT.txt +0 -119
  175. package/dist/cjs/index.cjs +0 -8005
  176. package/dist/esm/index.mjs +0 -7985
  177. package/src/@building/GetEventProperties.ts +0 -96
  178. package/src/@building/GetEventTracking.ts +0 -68
  179. package/src/@core/ManualEvent.ts +0 -56
  180. package/src/@core/SetNode.ts +0 -81
  181. package/src/@events/ParseAPI.ts +0 -117
  182. package/src/@manager/MakeEvents.ts +0 -106
  183. package/src/@manager/RemoveEvent.ts +0 -70
  184. package/src/@manager/Tasks.ts +0 -246
  185. package/src/@manager/ValidateEvents.ts +0 -142
  186. package/src/@modules/@database/InitializeDatabase.ts +0 -59
  187. package/src/@modules/@eas/GenerateEASMessage.ts +0 -144
  188. package/src/@modules/@utilities/GetFormattedTime.ts +0 -43
  189. package/src/@modules/@utilities/SetCronSchedule.ts +0 -94
  190. package/src/@modules/@utilities/SetEventEmit.ts +0 -41
  191. package/src/@modules/@utilities/SetListener.ts +0 -30
  192. package/src/@modules/@utilities/SetTimeoutAction.ts +0 -64
  193. package/src/@modules/@utilities/SetWarning.ts +0 -34
  194. package/src/@modules/@xmpp/ErrorXMPP.ts +0 -27
  195. package/src/@modules/@xmpp/ReconnectXMPP.ts +0 -64
  196. package/src/@parsers/@text/GetPolygonFromProduct.ts +0 -53
  197. package/src/@parsers/@text/GetXML.ts +0 -61
  198. package/src/@parsers/@ugc/GetCache.ts +0 -24
  199. package/src/@parsers/@ugc/GetZonePolygon.ts +0 -111
  200. package/tsup.config.ts +0 -16
@@ -11,21 +11,18 @@
11
11
  Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
12
12
  Discord: https://atmosphericx-discord.scriptkitty.cafe
13
13
  Ko-Fi: https://ko-fi.com/k3yomi
14
- Documentation: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
14
+ Documentation: https://atmosphericx.scriptkitty.cafe/documentation
15
15
 
16
- Internal Package: @atmosx/event-product-parser
16
+ Independent Package: @atmosx/event-product-parser
17
17
 
18
18
  */
19
19
 
20
- import { TypeEvent } from "../@types/Event";
21
- import { TypeSettings } from "../@types/Settings";
22
- import { EnumEnhanced } from "../@enums/Enhanced"
23
- import { bootstrap } from "../bootstrap"
20
+ import { TypeEvent } from "TypesEvent/Event"
21
+ import { EnumEnhanced } from "@Enums/Enhanced"
24
22
 
25
23
  export const GetEventEnhancedName = (event: TypeEvent): string => {
26
24
  let name = event?.properties?.event;
27
-
28
- const damage = event?.properties?.parameters?.damage_threat
25
+ const damage = event?.properties?.parameters?.damage_threat ?? event?.properties?.parameters?.flood_threat
29
26
  const tornado = event?.properties?.parameters?.tornado_threat;
30
27
  const pdswatch = event?.properties?.watch_parameters?.pds_watch;
31
28
  const description = event?.properties?.description?.toLowerCase()
@@ -11,32 +11,38 @@
11
11
  Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
12
12
  Discord: https://atmosphericx-discord.scriptkitty.cafe
13
13
  Ko-Fi: https://ko-fi.com/k3yomi
14
- Documentation: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
14
+ Documentation: https://atmosphericx.scriptkitty.cafe/documentation
15
15
 
16
- Internal Package: @atmosx/event-product-parser
16
+ Independent Package: @atmosx/event-product-parser
17
17
 
18
18
  */
19
19
 
20
- import { TypeSettings } from "../@types/Settings"
21
- import { TypeEvent } from "../@types/Event"
22
- import { GetSettings } from "../@modules/@utilities/GetSettings";
23
- import { getZonePolygon } from "../@parsers/@ugc/GetZonePolygon";
20
+ import { TypeSettings } from "TypesStandard/Settings"
21
+ import { TypeEvent } from "TypesEvent/Event"
22
+ import { Bootstrap } from "@Bootstrap"
23
+ import { GetZonePolygon } from "@ParsingUGC/GetZonePolygon"
24
24
 
25
- interface GetGeometryResponse {
25
+ interface GetEventGeometryOptions {
26
+ Event: TypeEvent
27
+ Union?: boolean
28
+ }
29
+
30
+ interface GetEventGeometryResponse {
26
31
  type: `Polygon` | `MultiPolygon`
27
32
  coordinates: any[]
28
33
  }
29
34
 
30
- export const GetEventGeometry = (event: TypeEvent): GetGeometryResponse => {
31
- const settings = GetSettings() as TypeSettings
32
- const generated = event?.properties?.geocode?.polygon ?? null;
33
- const ugc = event?.properties?.geocode?.ugc ?? null;
34
- let geo: GetGeometryResponse = {
35
+ export const GetEventGeometry = ({ Event, Union }: GetEventGeometryOptions): GetEventGeometryResponse => {
36
+ const { properties } = Event;
37
+ const settings = Bootstrap.Settings as TypeSettings
38
+ const generated = properties?.geocode?.polygon ?? null;
39
+ const ugc = properties?.geocode?.ugc ?? null;
40
+ let geo: GetEventGeometryResponse = {
35
41
  type: `Polygon`,
36
42
  coordinates: generated != null ? JSON.parse(Buffer.from(generated, 'base64').toString('utf-8')) : null
37
43
  }
38
44
  if (settings.GlobalSettings.UseShapefileCoordinates && generated == null && ugc != null) {
39
- geo = getZonePolygon({zones: ugc, isUnion: false})
45
+ geo = GetZonePolygon({Zones: ugc, Union: Union ?? false});
40
46
  if (geo == null) {
41
47
  geo = {
42
48
  type: `Polygon`,
@@ -11,27 +11,27 @@
11
11
  Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
12
12
  Discord: https://atmosphericx-discord.scriptkitty.cafe
13
13
  Ko-Fi: https://ko-fi.com/k3yomi
14
- Documentation: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
14
+ Documentation: https://atmosphericx.scriptkitty.cafe/documentation
15
15
 
16
- Internal Package: @atmosx/event-product-parser
16
+ Independent Package: @atmosx/event-product-parser
17
17
 
18
18
  */
19
19
 
20
- import { TypePVTEC } from "../@types/VTEC";
21
- import { TypeEventProperties } from "../@types/Properties";
20
+ import { TypeVTEC } from "TypesEvent/VTEC"
21
+ import { TypeEventProperties } from "TypesEvent/Properties"
22
22
 
23
23
  interface GetHeaderOptions {
24
- properties: TypeEventProperties
25
- vtec?: TypePVTEC
26
- getType: {
27
- type: string
28
- prefix: string
24
+ Properties: TypeEventProperties
25
+ VTEC?: TypeVTEC
26
+ Type: {
27
+ Type: string
28
+ Prefix: string
29
29
  }
30
30
  }
31
31
 
32
- export const GetEventHeader = (options: GetHeaderOptions): string => {
33
- const properties = options.properties
34
- const vtec = options.vtec ?? null
32
+ export const GetEventHeader = ({ Properties, VTEC, Type }: GetHeaderOptions): string => {
33
+ const properties = Properties
34
+ const vtec = VTEC ?? null
35
35
  const ugc = properties.geocode.ugc != null ? properties.geocode.ugc.join(`-`) : `0`;
36
- return `ZCZC-ATMOSX-${options.getType.prefix}-${ugc}-${vtec?.status ?? `Issued`}-${new Date().toISOString().replace(/[-:]/g, '').split('.')[0]}-${properties.geocode.office.office ?? `KWNS`}`
36
+ return `ZCZC-ATMOSX-${Type?.Prefix}-${ugc}-${vtec?.status ?? `Issued`}-${new Date().toISOString().replace(/[-:]/g, '').split('.')[0]}-${properties.geocode.office.office ?? `KWNS`}`
37
37
  }
@@ -0,0 +1,51 @@
1
+ /*
2
+ _ _ _ __ __
3
+ /\ | | | | (_) \ \ / /
4
+ / \ | |_ _ __ ___ ___ ___ _ __ | |__ ___ _ __ _ ___ \ V /
5
+ / /\ \| __| '_ ` _ \ / _ \/ __| '_ \| '_ \ / _ \ '__| |/ __| > <
6
+ / ____ \ |_| | | | | | (_) \__ \ |_) | | | | __/ | | | (__ / . \
7
+ /_/ \_\__|_| |_| |_|\___/|___/ .__/|_| |_|\___|_| |_|\___/_/ \_\
8
+ | |
9
+ |_|
10
+
11
+ Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
12
+ Discord: https://atmosphericx-discord.scriptkitty.cafe
13
+ Ko-Fi: https://ko-fi.com/k3yomi
14
+ Documentation: https://atmosphericx.scriptkitty.cafe/documentation
15
+
16
+ Independent Package: @atmosx/event-product-parser
17
+
18
+ */
19
+
20
+ import { TypeEvent } from "TypesEvent/Event"
21
+
22
+ interface GetMergedEventOptions {
23
+ Event1: TypeEvent
24
+ Event2: TypeEvent
25
+ }
26
+
27
+ const uniqueBy = <T>(items: T[], getKey: (item: T) => string ): T[] => {
28
+ const seen = new Set<string>();
29
+ return items.filter((item) => {
30
+ const key = getKey(item);
31
+ if (seen.has(key)) {
32
+ return false;
33
+ }
34
+ seen.add(key);
35
+ return true;
36
+ });
37
+ };
38
+
39
+ export const GetEventMerged = ({ Event1, Event2 }: GetMergedEventOptions): TypeEvent => {
40
+ const history = uniqueBy([ ...(Event1.properties.metadata?.history ?? []), ...(Event2.properties.metadata?.history ?? []) ],(item) => `${item.description}|${item.issued}`);
41
+ return {
42
+ ...Event2,
43
+ properties: {
44
+ ...Event2.properties,
45
+ metadata: {
46
+ ...Event2.properties?.metadata,
47
+ history
48
+ }
49
+ }
50
+ };
51
+ };
@@ -11,16 +11,16 @@
11
11
  Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
12
12
  Discord: https://atmosphericx-discord.scriptkitty.cafe
13
13
  Ko-Fi: https://ko-fi.com/k3yomi
14
- Documentation: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
14
+ Documentation: https://atmosphericx.scriptkitty.cafe/documentation
15
15
 
16
- Internal Package: @atmosx/event-product-parser
16
+ Independent Package: @atmosx/event-product-parser
17
17
 
18
18
  */
19
19
 
20
- import { TypeEvent } from "../@types/Event"
21
- import { bootstrap } from "../bootstrap"
22
- import { GetEventGeometry } from "./GetEventGeometry"
23
- import { GetShapeNearestPoint } from "../@modules/@utilities/GetShapeNearestPoint"
20
+ import { TypeEvent } from "TypesEvent/Event"
21
+ import { Bootstrap } from "@Bootstrap"
22
+ import { GetEventGeometry } from "@BuilderComponents/GetEventGeometry"
23
+ import { GetShapeNearestPoint } from "@Geometry/GetShapeNearestPoint"
24
24
 
25
25
  interface GetEventNodesResponse {
26
26
  nodes: {
@@ -36,34 +36,36 @@ interface GetEventNodesResponse {
36
36
  }
37
37
 
38
38
  export const GetEventNodes = async (event: TypeEvent): Promise<GetEventNodesResponse> => {
39
- const nodes = bootstrap.cache.nodes.features;
39
+ const nodes = Bootstrap.Cache.Nodes.features;
40
40
  if (!nodes || nodes.length === 0) {
41
- return { nodes: [], filtered: true, updated: Date.now() };
41
+ return { nodes: [], filtered: false, updated: Date.now() };
42
42
  }
43
- const metadata = { nodes: [], proximity: false, filtered: false };
44
- const geometry = await GetEventGeometry(event);
43
+ const metadata = { nodes: [] as GetEventNodesResponse['nodes'], proximity: false, filtered: false };
44
+ const geometry = await GetEventGeometry({ Event: event });;
45
45
  if (!geometry || !geometry.coordinates) {
46
46
  return { nodes: [], filtered: false, updated: Date.now() }
47
47
  }
48
48
  for (const node of nodes) {
49
- const [longitude, latitude] = node.geometry.coordinates;
50
- const getPoint = GetShapeNearestPoint(geometry.coordinates, [longitude, latitude])
51
- const miles = getPoint.distance ?? null;
52
- const kilometers = Number((miles * 1.609344).toFixed(3));
49
+ const [longitude, latitude] = (node?.geometry?.coordinates ?? []) as [number, number];
50
+
51
+ const getPoint = GetShapeNearestPoint({ Coordinates: geometry.coordinates, Point: [longitude, latitude] });
52
+ const miles = getPoint.Distance ?? null;
53
+ const kilometers = miles != null ? Number((miles * 1.609344).toFixed(3)) : null;
53
54
 
54
55
  const info = {
55
56
  id: node.properties?.identifier,
56
- coordinates: [longitude, latitude],
57
- nearest: getPoint.point,
57
+ coordinates: [longitude, latitude] as [number, number],
58
+ nearest: getPoint.Point as [number, number],
58
59
  miles,
59
60
  kilometers,
60
61
  proximity: false
61
- }
62
- metadata.nodes.push(info)
63
- if (miles != null && (bootstrap.settings.GlobalSettings.EventFiltering.NodeLocationFiltering) && (miles < bootstrap.settings.GlobalSettings.NodeMaxDistance)) {
64
- metadata.proximity = true;
62
+ };
63
+
64
+ if (miles != null && (miles < Bootstrap.Settings.GlobalSettings.NodeMaxDistance)) {
65
65
  info.proximity = true;
66
+ metadata.proximity = true;
66
67
  }
68
+ metadata.nodes.push(info);
67
69
  }
68
70
  return {
69
71
  nodes: metadata.nodes,
@@ -11,20 +11,20 @@
11
11
  Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
12
12
  Discord: https://atmosphericx-discord.scriptkitty.cafe
13
13
  Ko-Fi: https://ko-fi.com/k3yomi
14
- Documentation: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
14
+ Documentation: https://atmosphericx.scriptkitty.cafe/documentation
15
15
 
16
- Internal Package: @atmosx/event-product-parser
16
+ Independent Package: @atmosx/event-product-parser
17
17
 
18
18
  */
19
19
 
20
- import { TypeAttributes } from "../@types/Attributes";
21
- import { TypePVTEC } from "../@types/VTEC";
22
- import { EnumICAO } from "../@enums/ICAO";
20
+ import { TypeAttributes } from "TypesEvent/Attributes"
21
+ import { TypeVTEC } from "TypesEvent/VTEC"
22
+ import { EnumICAO } from "@Enums/ICAO"
23
23
 
24
24
  interface GetOfficeOptions {
25
- attributes: TypeAttributes
26
- organization: string
27
- pVtec: TypePVTEC
25
+ Attributes: TypeAttributes
26
+ Organization: string
27
+ VTEC: TypeVTEC
28
28
  }
29
29
 
30
30
  interface GetOfficeResponse {
@@ -32,11 +32,11 @@ interface GetOfficeResponse {
32
32
  name: string | null
33
33
  }
34
34
 
35
- export const GetEventOffice = (options: GetOfficeOptions): GetOfficeResponse => {
36
- const office = options.pVtec != null
37
- ? options.pVtec?.tracking?.split(`.`)[0] : (options.attributes?.cccc ??
38
- (options.organization != null ?
39
- (Array.isArray(options.organization) ? options.organization?.[0] : options.organization)
35
+ export const GetEventOffice = ({ Attributes, Organization, VTEC }: GetOfficeOptions): GetOfficeResponse => {
36
+ const office = VTEC != null
37
+ ? VTEC?.tracking?.split(`.`)[0] : (Attributes?.cccc ??
38
+ (Organization != null ?
39
+ (Array.isArray(Organization) ? Organization?.[0] : Organization)
40
40
  : null));
41
41
  const name = EnumICAO?.[office] ?? null;
42
42
  return { office, name };
@@ -0,0 +1,58 @@
1
+ /*
2
+ _ _ _ __ __
3
+ /\ | | | | (_) \ \ / /
4
+ / \ | |_ _ __ ___ ___ ___ _ __ | |__ ___ _ __ _ ___ \ V /
5
+ / /\ \| __| '_ ` _ \ / _ \/ __| '_ \| '_ \ / _ \ '__| |/ __| > <
6
+ / ____ \ |_| | | | | | (_) \__ \ |_) | | | | __/ | | | (__ / . \
7
+ /_/ \_\__|_| |_| |_|\___/|___/ .__/|_| |_|\___|_| |_|\___/_/ \_\
8
+ | |
9
+ |_|
10
+
11
+ Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
12
+ Discord: https://atmosphericx-discord.scriptkitty.cafe
13
+ Ko-Fi: https://ko-fi.com/k3yomi
14
+ Documentation: https://atmosphericx.scriptkitty.cafe/documentation
15
+
16
+ Independent Package: @atmosx/event-product-parser
17
+
18
+ */
19
+
20
+ import { TypeCities } from "TypesEvent/Properties"
21
+ import { Bootstrap } from "@Bootstrap"
22
+ import { CreateQuery } from "@Database/CreateQuery"
23
+ import { NormalizePolygon } from "@ImageModules/NormalizePolygon"
24
+
25
+ interface GetEventPopulationResponse {
26
+ population: number
27
+ cities: TypeCities[]
28
+ }
29
+
30
+ export const GetEventPopulation = (geometry: GeoJSON.Polygon | GeoJSON.MultiPolygon | null): GetEventPopulationResponse => {
31
+ const coordinates = geometry?.coordinates;
32
+ if (!coordinates || !Array.isArray(coordinates) || coordinates.length === 0 || !Bootstrap.Settings.GlobalSettings.CensusPopulationData) {
33
+ return { population: 0, cities: [] };
34
+ }
35
+ const normalized = NormalizePolygon(geometry) as GeoJSON.Polygon | GeoJSON.MultiPolygon;
36
+ const points = normalized.type === `Polygon` ? normalized.coordinates[0] : normalized.coordinates.flatMap(polygon => polygon[0]);
37
+ const latitudes = points.map(([lon, lat]) => lat);
38
+ const longitudes = points.map(([lon, lat]) => lon);
39
+ const minLat = Math.min(...latitudes);
40
+ const maxLat = Math.max(...latitudes);
41
+ const minLon = Math.min(...longitudes);
42
+ const maxLon = Math.max(...longitudes);
43
+ const A = CreateQuery({
44
+ Query: `SELECT * FROM cities WHERE LAT BETWEEN ? AND ? AND LON BETWEEN ? AND ?`,
45
+ Parameters: [ minLat, maxLat, minLon, maxLon ]
46
+ });
47
+ const population = A.reduce((acc: number, city: any) => {
48
+ const census = Number(city.population);
49
+ return acc + (isNaN(census) ? 0 : census);
50
+ }, 0);
51
+ const cities = A.map((city: any) => ({
52
+ name: city.name,
53
+ state: city.state,
54
+ county: city.county.replace(/ County$/i, ``),
55
+ population: Number(city.population)
56
+ }));
57
+ return { population, cities };
58
+ }
@@ -0,0 +1,106 @@
1
+ /*
2
+ _ _ _ __ __
3
+ /\ | | | | (_) \ \ / /
4
+ / \ | |_ _ __ ___ ___ ___ _ __ | |__ ___ _ __ _ ___ \ V /
5
+ / /\ \| __| '_ ` _ \ / _ \/ __| '_ \| '_ \ / _ \ '__| |/ __| > <
6
+ / ____ \ |_| | | | | | (_) \__ \ |_) | | | | __/ | | | (__ / . \
7
+ /_/ \_\__|_| |_| |_|\___/|___/ .__/|_| |_|\___|_| |_|\___/_/ \_\
8
+ | |
9
+ |_|
10
+
11
+ Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
12
+ Discord: https://atmosphericx-discord.scriptkitty.cafe
13
+ Ko-Fi: https://ko-fi.com/k3yomi
14
+ Documentation: https://atmosphericx.scriptkitty.cafe/documentation
15
+
16
+ Independent Package: @atmosx/event-product-parser
17
+
18
+ */
19
+
20
+ import { TypeEventProperties } from "TypesEvent/Properties"
21
+ import { TypeAttributes } from "TypesEvent/Attributes"
22
+ import { TypeUGC } from "TypesStandard/UGC"
23
+ import { TypeVTEC } from "TypesEvent/VTEC"
24
+ import { EnumExpressions } from "@Enums/Expressions"
25
+ import { GetDescriptionFromProduct } from "@ParsingText/GetDescriptionFromProduct"
26
+ import { GetPolygonFromProduct } from "@ParsingText/GetPolygonFromProduct"
27
+ import { GetTextFromProduct } from "@ParsingText/GetTextFromProduct"
28
+ import { GetEventOffice } from "@BuilderComponents/GetEventOffice"
29
+ import { GetEventTags } from "@BuilderComponents/GetEventTags"
30
+ import { GetEventDirection } from "@BuilderComponents/GetEventDirection"
31
+
32
+ interface GetEventPropertiesOptions {
33
+ Message: string
34
+ Attributes: TypeAttributes
35
+ UGC?: TypeUGC
36
+ VTEC?: TypeVTEC
37
+ }
38
+
39
+ export const GetEventProperties = ({ Message, Attributes, UGC, VTEC }: GetEventPropertiesOptions): TypeEventProperties => {
40
+ const organization = Message.match(EnumExpressions.wmo)?.[0] ?? null
41
+ const polygons = GetPolygonFromProduct(Message)
42
+ const properties = {
43
+ locations: UGC?.Locations?.join(`; `) ?? null,
44
+ locations_array: UGC?.Locations ?? [],
45
+ regions: [...new Set(
46
+ UGC?.Zones
47
+ ?.map((location: string) => location.match(/^([A-Z]{2})[CZ](\d{3})$/)?.[1])
48
+ .filter(Boolean) ?? []
49
+ )],
50
+ regions_string: (() => {
51
+ const abbrs = [...new Set(UGC?.Zones?.map((l: string) => l.match(/^([A-Z]{2})[CZ](\d{3})$/)?.[1]).filter(Boolean) ?? [])];
52
+ return abbrs.length ? abbrs.join(`-`) : null;
53
+ })(),
54
+ description: GetDescriptionFromProduct({ Message: Message, Handle: VTEC?.raw ?? null }),
55
+ attributes: Attributes,
56
+ geocode: {
57
+ office: GetEventOffice({ Attributes: Attributes, Organization: organization, VTEC: VTEC }),
58
+ organization: organization,
59
+ ugc: UGC?.Zones ?? [],
60
+ census: {},
61
+ polygon: polygons.length > 0 ? Buffer.from(JSON.stringify([polygons])).toString('base64') : null,
62
+ polygon_generated: polygons.length > 0 ? true : false
63
+ },
64
+ parameters: {
65
+ tags: GetEventTags(Message),
66
+ instructions: GetTextFromProduct({ Message: Message, Find: [`For your protection`, `do not`, `use extreme caution`], Append: `...`, Removal: [`.`]}) ?? null,
67
+ source: GetTextFromProduct({ Message: Message, Find: [`SOURCE...`], Removal: [`.`]}) ?? null,
68
+ hazards: GetTextFromProduct({ Message: Message, Find: [`HAZARD...`], Removal: [`.`]}) ?? null,
69
+ impacts: GetTextFromProduct({ Message: Message, Find: [`IMPACT...`], Removal: [`.`]}) ?? null,
70
+ estimated_hail_size: GetTextFromProduct({ Message: Message, Find: [`MAX HAIL SIZE...`, `HAIL...`], Removal: ['in']}) ?? null,
71
+ estimated_wind_gusts: GetTextFromProduct({ Message: Message, Find: [`MAX WIND GUST...`, `WIND...`]}) ?? null,
72
+ direction: GetEventDirection(Message) ?? null,
73
+ damage_threat: GetTextFromProduct({ Message: Message, Find: [`DAMAGE THREAT...`], Removal: []}) ?? null,
74
+ tornado_threat: GetTextFromProduct({ Message: Message, Find: [`TORNADO...`, `WATERSPOUT...`] }) ?? null,
75
+ flood_threat: GetTextFromProduct({ Message: Message, Find: [`FLASH FLOOD...`]}) ?? null,
76
+ wind_threat: GetTextFromProduct({ Message: Message, Find: [`WIND THREAT...`]}) ?? null,
77
+ hail_threat: GetTextFromProduct({ Message: Message, Find: [`HAIL THREAT...`], Removal: []}) ?? null,
78
+ },
79
+ discussion_parameters: {
80
+ discussion_number: GetTextFromProduct({ Message: Message, Find: [`Mesoscale Discussion `], Removal: [`Mesoscale Discussion`, `Number`, `...`] })?.toString()?.padStart(4, "0") ?? null,
81
+ discussion_concerning: GetTextFromProduct({ Message: Message, Find: [`Concerning...`] }) ?? null,
82
+ discussion_max_tornado: GetTextFromProduct({ Message: Message, Find: [`MOST PROBABLE PEAK TORNADO INTENSITY...`] }) ?? null,
83
+ discussion_max_hail: GetTextFromProduct({ Message: Message, Find: [`MOST PROBABLE PEAK HAIL SIZE...`] }) ?? null,
84
+ discussion_max_wind: GetTextFromProduct({ Message: Message, Find: [`MOST PROBABLE PEAK WIND GUST...`] }) ?? null,
85
+ discussion_watch_issuance: GetTextFromProduct({ Message: Message, Find: [`Probability of Watch Issuance...`], Removal: [`percent`]}) ?? null,
86
+ },
87
+ watch_parameters: {
88
+ watch_number: VTEC?.watch ? ( GetTextFromProduct({ Message: Message, Find: [`ITIES FOR`, `UPDATE FOR`, `Watch Number `], Removal: [`%`, `<`, `:`] })?.replace(/(WT|WS|)/g, '')?.trim()?.toString()?.padStart(4, "0") ?? VTEC?.tracking?.slice(-4)?.toString()?.padStart(4, "0") ?? null) : null,
89
+ watch_type: Message.includes(`TORNADO WATCH`) ? `Tornado` : Message.includes(`SEVERE`) ? `Severe` : null,
90
+ additional_tornadoes_probability: GetTextFromProduct({ Message: Message, Find: [`PROB OF 2 OR MORE TORNADOES`], Removal: [`%`, `<`, `:`] }) ?? null,
91
+ strong_tornadoes_probability: GetTextFromProduct({ Message: Message, Find: [`PROB OF 1 OR MORE STRONG /EF2-EF5/ TORNADOES`], Removal: [`%`, `<`, `:`] }) ?? null,
92
+ severe_wind_probability: GetTextFromProduct({ Message: Message, Find: [`PROB OF 10 OR MORE SEVERE WIND EVENTS`], Removal: [`%`, `<`, `:`] }) ?? null,
93
+ severe_hail_probability: GetTextFromProduct({ Message: Message, Find: [`PROB OF 10 OR MORE SEVERE HAIL EVENTS`], Removal: [`%`, `<`, `:`] }) ?? null,
94
+ hail_2in_probability: GetTextFromProduct({ Message: Message, Find: [`PROB OF 1 OR MORE HAIL EVENTS >= 2 INCHES`], Removal: [`%`, `<`, `:`] }) ?? null,
95
+ combined_hail_wind_probability: GetTextFromProduct({ Message: Message, Find: [`PROB OF 6 OR MORE COMBINED SEVERE HAIL/WIND EVENTS`], Removal: [`%`, `<`, `:`] }) ?? null,
96
+ max_hail_in: GetTextFromProduct({ Message: Message, Find: [`MAX HAIL /INCHES/`], Removal: [`%`, `<`, `:`] }) ?? null,
97
+ max_wind_surface: GetTextFromProduct({ Message: Message, Find: [`MAX WIND GUSTS SURFACE /KNOTS/`], Removal: [`%`, `<`, `:`] }) ?? null,
98
+ max_tops_x100feet: GetTextFromProduct({ Message: Message, Find: [`MAX TOPS /X 100 FEET/`], Removal: [`%`, `<`, `:`] }) ?? null,
99
+ pds_watch: (GetTextFromProduct({ Message: Message, Find: [`PARTICULARLY DANGEROUS SITUATION`], Removal: [`%`, `<`, `:`] }) === `YES` ? true : null)
100
+ }
101
+ }
102
+ if (isNaN(Number(properties.watch_parameters.watch_number))) {
103
+ properties.watch_parameters.watch_number = null
104
+ }
105
+ return properties;
106
+ }
@@ -11,18 +11,18 @@
11
11
  Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
12
12
  Discord: https://atmosphericx-discord.scriptkitty.cafe
13
13
  Ko-Fi: https://ko-fi.com/k3yomi
14
- Documentation: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
14
+ Documentation: https://atmosphericx.scriptkitty.cafe/documentation
15
15
 
16
- Internal Package: @atmosx/event-product-parser
16
+ Independent Package: @atmosx/event-product-parser
17
17
 
18
18
  */
19
19
 
20
- import { TypeEvent } from "../@types/Event";
21
- import { EnumCorrelations } from "../@enums/Correlations";
22
- import { EnumCancellation } from "../@enums/Cancellation";
23
- import { EnumTesting} from "../@enums/Testing"
24
- import { EnumProducts } from "../@enums/Products";
25
- import { EnumHail } from "../@enums/Hail"
20
+ import { TypeEvent } from "TypesEvent/Event"
21
+ import { EnumCorrelations } from "@Enums/Correlations"
22
+ import { EnumCancellation } from "@Enums/Cancellation"
23
+ import { EnumTesting} from "@Enums/Testing"
24
+ import { EnumProducts } from "@Enums/Products"
25
+ import { EnumHail } from "@Enums/Hail"
26
26
 
27
27
  export const GetEventSignature = (event: TypeEvent): TypeEvent => {
28
28
  const properties = event?.properties;
@@ -44,7 +44,7 @@ export const GetEventSignature = (event: TypeEvent): TypeEvent => {
44
44
  properties.status_metadata = { ...properties.status_metadata, is_expired: true };
45
45
  }
46
46
 
47
- const getProduct = vtec?.vtec?.split(`.`)[0]?.replace(`/`, ``)
47
+ const getProduct = vtec?.raw?.split(`.`)[0]?.replace(`/`, ``)
48
48
  const isTestProduct = EnumProducts[getProduct] == `Test Product`
49
49
  if (isTestProduct || EnumTesting.some(sig => properties.description?.toLowerCase().includes(sig.toLowerCase()) ?? properties?.parameters?.instructions?.toLowerCase().includes(sig.toLowerCase()))) {
50
50
  properties.status_metadata = { ...properties.status_metadata, is_test: true }
@@ -11,13 +11,13 @@
11
11
  Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
12
12
  Discord: https://atmosphericx-discord.scriptkitty.cafe
13
13
  Ko-Fi: https://ko-fi.com/k3yomi
14
- Documentation: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
14
+ Documentation: https://atmosphericx.scriptkitty.cafe/documentation
15
15
 
16
- Internal Package: @atmosx/event-product-parser
16
+ Independent Package: @atmosx/event-product-parser
17
17
 
18
18
  */
19
19
 
20
- import { EnumTags } from "../@enums/Tags";
20
+ import { EnumTags } from "@Enums/Tags"
21
21
 
22
22
  export const GetEventTags = (message: string): string[] => {
23
23
  if (!message) return [];
@@ -0,0 +1,26 @@
1
+ /*
2
+ _ _ _ __ __
3
+ /\ | | | | (_) \ \ / /
4
+ / \ | |_ _ __ ___ ___ ___ _ __ | |__ ___ _ __ _ ___ \ V /
5
+ / /\ \| __| '_ ` _ \ / _ \/ __| '_ \| '_ \ / _ \ '__| |/ __| > <
6
+ / ____ \ |_| | | | | | (_) \__ \ |_) | | | | __/ | | | (__ / . \
7
+ /_/ \_\__|_| |_| |_|\___/|___/ .__/|_| |_|\___|_| |_|\___/_/ \_\
8
+ | |
9
+ |_|
10
+
11
+ Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
12
+ Discord: https://atmosphericx-discord.scriptkitty.cafe
13
+ Ko-Fi: https://ko-fi.com/k3yomi
14
+ Documentation: https://atmosphericx.scriptkitty.cafe/documentation
15
+
16
+ Independent Package: @atmosx/event-product-parser
17
+
18
+ */
19
+
20
+ import { Bootstrap } from "@Bootstrap";
21
+ import { EnumThemes } from "@Enums/Themes"
22
+ import { GetMatched } from "@Utilities/GetMatched";
23
+
24
+ export const GetEventTheme = (Event: string): string => {
25
+ return Bootstrap.Settings.GlobalSettings.Themes.find(theme => GetMatched({Strings: [theme.Event], String: Event}))?.RGB ?? EnumThemes.find(theme => theme.Event === `Default`)?.RGB ?? `rgb(56, 72, 88)`;
26
+ };
@@ -0,0 +1,64 @@
1
+ /*
2
+ _ _ _ __ __
3
+ /\ | | | | (_) \ \ / /
4
+ / \ | |_ _ __ ___ ___ ___ _ __ | |__ ___ _ __ _ ___ \ V /
5
+ / /\ \| __| '_ ` _ \ / _ \/ __| '_ \| '_ \ / _ \ '__| |/ __| > <
6
+ / ____ \ |_| | | | | | (_) \__ \ |_) | | | | __/ | | | (__ / . \
7
+ /_/ \_\__|_| |_| |_|\___/|___/ .__/|_| |_|\___|_| |_|\___/_/ \_\
8
+ | |
9
+ |_|
10
+
11
+ Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
12
+ Discord: https://atmosphericx-discord.scriptkitty.cafe
13
+ Ko-Fi: https://ko-fi.com/k3yomi
14
+ Documentation: https://atmosphericx.scriptkitty.cafe/documentation
15
+
16
+ Independent Package: @atmosx/event-product-parser
17
+
18
+ */
19
+
20
+ import { TypeAttributes } from "TypesEvent/Attributes"
21
+ import { TypeEventProperties } from "TypesEvent/Properties"
22
+ import { TypeStanzaCompiled } from "TypesStandard/StanzaCompiled"
23
+ import { TypeVTEC } from "TypesEvent/VTEC"
24
+
25
+ interface GetTrackingOptions {
26
+ Type: `RAW` | `VTEC` | `API`
27
+ Stanza?: TypeStanzaCompiled
28
+ Attributes?: TypeAttributes
29
+ Properties?: TypeEventProperties
30
+ WMO?: {
31
+ Identifier: string
32
+ ID: string
33
+ }
34
+ VTEC?: TypeVTEC
35
+ }
36
+
37
+ export const GetEventTracking = ({ Type, Stanza, Attributes, Properties, WMO, VTEC }: GetTrackingOptions): string => {
38
+ if (Type === `RAW`) {
39
+ const getWatchNumber = Properties?.watch_parameters?.watch_number ?? null
40
+ if (getWatchNumber) {
41
+ return `${Properties.geocode.office.office}.${Stanza.Type.Prefix}.A.${getWatchNumber}`
42
+ }
43
+ return `${Properties.geocode.office.office}.${Attributes.ttaaii}.${Attributes.id.slice(-4).replace(`.`, ``) ?? '0'}`
44
+ }
45
+ if (Type === `VTEC`) {
46
+ return VTEC?.tracking;
47
+ }
48
+ if (Type === `API`) {
49
+ if (VTEC) {
50
+ const vtecValue = Array.isArray(VTEC)
51
+ ? VTEC[0].vtec : VTEC?.raw;
52
+ const splitVTEC = vtecValue.split('.');
53
+ return `${splitVTEC[2]}.${splitVTEC[3]}.${splitVTEC[4]}.${splitVTEC[5]}`;
54
+ }
55
+ const wmoMatch = WMO?.Identifier?.match(/([A-Z]{4}\d{2})\s+([A-Z]{4})/);
56
+ const station = wmoMatch?.[2] ?? '---';
57
+ if (WMO?.ID) {
58
+ const idMatch = WMO?.ID.match(/([a-f0-9]+)\.(\d+)\.(\d+)$/);
59
+ return `${station}.${idMatch?.[0]?.replace(/\./g, '') ?? '---'}`;
60
+ }
61
+ const id = wmoMatch?.[1] ?? '---';
62
+ return `${station}.${id?.replace(/\./g, '') ?? '---'}`;
63
+ }
64
+ }