@atmosx/event-product-parser 3.0.62 → 3.0.75

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 (179) hide show
  1. package/.github/docs/docs-functions.md +1 -1
  2. package/.github/docs/docs-general-configurations.md +1 -11
  3. package/.github/docs/docs-integrations.md +3 -2
  4. package/README.md +10 -8
  5. package/dist/cjs/index.cjs +24482 -7207
  6. package/dist/esm/index.mjs +24275 -7003
  7. package/package.json +56 -47
  8. package/pnpm-workspace.yaml +4 -0
  9. package/src/bootstrap.ts +65 -48
  10. package/src/{@building → building}/CreateEvent.ts +22 -24
  11. package/src/{@building → building}/GetCleanedEvent.ts +2 -2
  12. package/src/{@building → building}/GetEventAttachments.ts +14 -12
  13. package/src/building/GetEventDirection.ts +28 -0
  14. package/src/{@building → building}/GetEventEnhancedName.ts +5 -8
  15. package/src/{@building → building}/GetEventGeometry.ts +19 -13
  16. package/src/{@building → building}/GetEventHeader.ts +13 -13
  17. package/src/{@building → building}/GetEventNodes.ts +22 -20
  18. package/src/{@building → building}/GetEventOffice.ts +13 -13
  19. package/src/building/GetEventPopulation.ts +58 -0
  20. package/src/building/GetEventProperties.ts +106 -0
  21. package/src/{@building → building}/GetEventSignature.ts +9 -9
  22. package/src/{@building → building}/GetEventTags.ts +3 -3
  23. package/src/building/GetEventTheme.ts +26 -0
  24. package/src/building/GetEventTracking.ts +64 -0
  25. package/src/components/audio/GenerateAudioMessage.ts +149 -0
  26. package/src/{@modules/@eas → components/audio/components}/GetCleanDescription.ts +2 -2
  27. package/src/{@modules/@eas → components/audio/components}/GetFloatPCM16.ts +2 -2
  28. package/src/{@modules/@eas → components/audio/components}/GetMergedPCM16.ts +2 -2
  29. package/src/{@modules/@eas → components/audio/components}/GetPCM16.ts +13 -8
  30. package/src/{@modules/@eas → components/audio/components}/GetPCMToFloat.ts +2 -2
  31. package/src/{@modules/@eas → components/audio/components}/GetSampledPCM16.ts +14 -8
  32. package/src/{@modules/@eas → components/audio/components}/GetTTS.ts +17 -10
  33. package/src/{@modules/@eas → components/audio/components}/GetWavPCM16.ts +7 -7
  34. package/src/{@modules/@eas → components/audio/components}/SetAFSK.ts +13 -8
  35. package/src/{@modules/@eas → components/audio/components}/SetAsciiToBits.ts +2 -2
  36. package/src/{@modules/@eas → components/audio/components}/SetAttentionTone.ts +11 -6
  37. package/src/{@modules/@eas → components/audio/components}/SetNoise.ts +12 -7
  38. package/src/{@modules/@eas → components/audio/components}/SetRadioEffect.ts +12 -7
  39. package/src/{@modules/@eas → components/audio/components}/SetSameHeader.ts +22 -14
  40. package/src/{@modules/@utilities/SetWarning.ts → components/database/CreateQuery.ts} +18 -13
  41. package/src/{@modules/@database → components/database}/GetCachedEvents.ts +18 -15
  42. package/src/components/database/ImportBoundaries.ts +168 -0
  43. package/src/{@modules/@database → components/database}/ImportBroadcastify.ts +14 -24
  44. package/src/components/database/ImportCities.ts +87 -0
  45. package/src/{@modules/@database → components/database}/ImportShapefiles.ts +23 -26
  46. package/src/{@modules/@database → components/database}/ImportStanza.ts +15 -19
  47. package/src/components/database/InitializeDatabase.ts +71 -0
  48. package/src/components/images/GenerateGraphic.ts +242 -0
  49. package/src/components/images/components/CreateRectangle.ts +22 -0
  50. package/src/components/images/components/CreateText.ts +22 -0
  51. package/src/components/images/modules/CreateSVG.ts +37 -0
  52. package/src/components/images/modules/GetGeographicalBoundaries.ts +72 -0
  53. package/src/components/images/modules/GetGeographicalCities.ts +58 -0
  54. package/src/components/images/modules/GetGeographicalEvents.ts +48 -0
  55. package/src/components/images/modules/GetGeometryBounds.ts +82 -0
  56. package/src/components/images/modules/GetParsedBoundary.ts +58 -0
  57. package/src/components/images/modules/GetSVGPath.ts +53 -0
  58. package/src/components/images/modules/NormalizePolygon.ts +57 -0
  59. package/src/{@modules/@stanza → components/stanza}/GetAwipsType.ts +16 -17
  60. package/src/{@modules/@stanza → components/stanza}/ValidateStanza.ts +27 -15
  61. package/src/{@modules/@utilities → components/utilities}/CreateHttp.ts +26 -26
  62. package/src/{@parsers/@text → components/utilities}/GetEmbededText.ts +8 -6
  63. package/src/{@modules/@utilities → components/utilities}/GetFormattedTime.ts +2 -2
  64. package/src/{@modules/@utilities → components/utilities}/GetLatestIssuance.ts +2 -2
  65. package/src/{@modules/@utilities → components/utilities}/GetMatched.ts +10 -5
  66. package/src/{@modules/@utilities → components/utilities}/GetShapeNearestPoint.ts +24 -19
  67. package/src/{@parsers/@text → components/utilities}/GetStringText.ts +9 -9
  68. package/src/components/utilities/GetUnionPolygon.ts +36 -0
  69. package/src/components/utilities/QueueManager.ts +70 -0
  70. package/src/components/utilities/SetCronSchedule.ts +106 -0
  71. package/src/{@modules/@utilities → components/utilities}/SetDebug.ts +12 -12
  72. package/src/components/utilities/SetEventEmit.ts +42 -0
  73. package/src/{@modules/@utilities → components/utilities}/SetSettings.ts +7 -7
  74. package/src/{@modules/@utilities → components/utilities}/SetSleep.ts +5 -5
  75. package/src/components/utilities/SetTimeoutAction.ts +64 -0
  76. package/src/components/utilities/SetWarning.ts +47 -0
  77. package/src/{@modules/@xmpp → components/xmpp}/DeployXMPP.ts +20 -20
  78. package/src/{@core/CreateListener.ts → components/xmpp/ErrorXMPP.ts} +8 -5
  79. package/src/{@modules/@xmpp → components/xmpp}/OfflineXMPP.ts +13 -13
  80. package/src/{@modules/@xmpp → components/xmpp}/OnlineXMPP.ts +18 -18
  81. package/src/components/xmpp/ReconnectXMPP.ts +64 -0
  82. package/src/{@modules/@xmpp → components/xmpp}/StanzaXMPP.ts +25 -25
  83. package/src/{@core → core}/ClearEvents.ts +9 -9
  84. package/src/{@core → core}/GetEvents.ts +4 -4
  85. package/src/{@core → core}/GetNodes.ts +4 -4
  86. package/src/{@core → core}/GetRandomEvent.ts +4 -4
  87. package/src/{@core → core}/GetVersion.ts +4 -4
  88. package/src/{@core → core}/ManualEvent.ts +23 -24
  89. package/src/{@core → core}/QueryStanza.ts +12 -11
  90. package/src/core/SetNode.ts +87 -0
  91. package/src/{@core → core}/StartService.ts +21 -20
  92. package/src/{@core → core}/StopService.ts +10 -10
  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 +38 -37
  119. package/src/index.ts +57 -37
  120. package/src/{@manager → manager}/MakeEvents.ts +38 -47
  121. package/src/manager/RemoveEvent.ts +74 -0
  122. package/src/{@manager → manager}/SetHash.ts +18 -13
  123. package/src/{@manager → manager}/UpdateEvents.ts +12 -12
  124. package/src/{@manager → manager}/UpdateNode.ts +14 -14
  125. package/src/{@manager → manager}/ValidateEvents.ts +55 -45
  126. package/src/{@parsers/@hvtec → parsers/hvtec}/HVExtract.ts +11 -11
  127. package/src/{@parsers/@text → parsers/text}/GetDescriptionFromProduct.ts +20 -21
  128. package/src/parsers/text/GetPolygonFromProduct.ts +71 -0
  129. package/src/{@parsers/@text → parsers/text}/GetTextFromProduct.ts +12 -12
  130. package/src/parsers/ugc/GetCache.ts +24 -0
  131. package/src/{@parsers/@ugc → parsers/ugc}/GetExpiry.ts +2 -2
  132. package/src/{@parsers/@ugc/GetUGCHeader.ts → parsers/ugc/GetHeader.ts} +4 -4
  133. package/src/{@parsers/@ugc → parsers/ugc}/GetLocations.ts +10 -10
  134. package/src/parsers/ugc/GetZonePolygon.ts +73 -0
  135. package/src/{@parsers/@ugc → parsers/ugc}/GetZones.ts +3 -3
  136. package/src/{@parsers/@ugc → parsers/ugc}/SetCache.ts +13 -8
  137. package/src/{@parsers/@ugc → parsers/ugc}/UGCExtract.ts +14 -14
  138. package/src/{@parsers/@pvtec → parsers/vtec}/GetExpiry.ts +2 -2
  139. package/src/parsers/vtec/VTECExtract.ts +49 -0
  140. package/src/{@types → static}/Attributes.ts +2 -3
  141. package/src/{@types → static}/Event.ts +8 -7
  142. package/src/{@types → static}/Properties.ts +17 -3
  143. package/src/{@types → static}/Stanza.ts +2 -2
  144. package/src/tasks/CreateTasks.ts +116 -0
  145. package/src/tasks/TaskGenerateJSON.ts +34 -0
  146. package/src/tasks/TaskGenerateText.ts +34 -0
  147. package/src/tasks/TaskSendNTFY.ts +95 -0
  148. package/src/tasks/TaskSendWebhook.ts +107 -0
  149. package/src/{@types → types}/Actions.ts +3 -3
  150. package/src/{@types → types}/HVTEC.ts +6 -6
  151. package/src/{@types → types}/Hash.ts +5 -5
  152. package/src/types/Nodes.ts +29 -0
  153. package/src/{@types → types}/Settings.ts +17 -8
  154. package/src/{@types → types}/StanzaCompiled.ts +15 -15
  155. package/src/{@types → types}/UGC.ts +5 -5
  156. package/src/{@modules/@utilities/GetSettings.ts → types/VTEC.ts} +12 -7
  157. package/tools/build.js +47 -0
  158. package/tsconfig.json +28 -1
  159. package/src/@building/GetEventProperties.ts +0 -96
  160. package/src/@building/GetEventTracking.ts +0 -68
  161. package/src/@core/SetNode.ts +0 -81
  162. package/src/@events/ParseAPI.ts +0 -117
  163. package/src/@manager/RemoveEvent.ts +0 -70
  164. package/src/@manager/Tasks.ts +0 -246
  165. package/src/@modules/@database/InitializeDatabase.ts +0 -59
  166. package/src/@modules/@eas/GenerateEASMessage.ts +0 -144
  167. package/src/@modules/@utilities/SetCronSchedule.ts +0 -94
  168. package/src/@modules/@utilities/SetEventEmit.ts +0 -41
  169. package/src/@modules/@utilities/SetListener.ts +0 -30
  170. package/src/@modules/@utilities/SetTimeoutAction.ts +0 -64
  171. package/src/@modules/@xmpp/ErrorXMPP.ts +0 -27
  172. package/src/@modules/@xmpp/ReconnectXMPP.ts +0 -64
  173. package/src/@parsers/@pvtec/VTECExtract.ts +0 -49
  174. package/src/@parsers/@text/GetPolygonFromProduct.ts +0 -53
  175. package/src/@parsers/@text/GetXML.ts +0 -61
  176. package/src/@parsers/@ugc/GetCache.ts +0 -24
  177. package/src/@parsers/@ugc/GetZonePolygon.ts +0 -111
  178. package/src/@types/VTEC.ts +0 -30
  179. package/tsup.config.ts +0 -16
@@ -11,33 +11,40 @@
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
20
 
21
- import { platform } from 'os'
22
- import { writeFileSync } from "fs"
23
- import { execSync } from 'child_process'
21
+ import { platform } from "os"
22
+ import { writeFileSync, unlinkSync} from "fs"
23
+ import { execSync } from "child_process"
24
24
 
25
- export const GetTTS = async (text: string, outputPath: string): Promise<void> => {
25
+
26
+ interface GetTTSOptions {
27
+ Text: string
28
+ OutputPath: string
29
+ }
30
+
31
+ export const GetTTS = async ({ Text, OutputPath }: GetTTSOptions): Promise<void> => {
26
32
  const vPlatform = platform();
27
33
  switch (vPlatform) {
28
34
  case 'win32': {
29
35
  try {
30
- const txtPath = outputPath + ".txt";
31
- writeFileSync(txtPath, text, "utf8");
36
+ const txtPath = OutputPath + ".txt";
37
+ writeFileSync(txtPath, Text, "utf8");
32
38
  const command = [
33
39
  "Add-Type -AssemblyName System.Speech;",
34
40
  `$speak = New-Object System.Speech.Synthesis.SpeechSynthesizer;`,
35
41
  `$text = Get-Content -Raw -LiteralPath '${txtPath}';`,
36
- `$speak.SetOutputToWaveFile('${outputPath}');`,
42
+ `$speak.SetOutputToWaveFile('${OutputPath}');`,
37
43
  `$speak.Speak($text);`,
38
44
  `$speak.Dispose();`
39
45
  ].join(" ");
40
46
  execSync(`powershell -Command "${command}"`, { stdio: 'inherit' })
47
+ try{ unlinkSync(txtPath) } catch {}
41
48
  } catch(error) {
42
49
  console.error('Error occurred while generating TTS:', error);
43
50
  }
@@ -45,7 +52,7 @@ export const GetTTS = async (text: string, outputPath: string): Promise<void> =>
45
52
  }
46
53
  case 'linux':
47
54
  try {
48
- execSync(`espeak -w "${outputPath}" "${text.replace(/"/g, '\\"')}"`);
55
+ execSync(`espeak -w "${OutputPath}" "${Text.replace(/"/g, '\\"')}"`);
49
56
  } catch {}
50
57
  break;
51
58
  default: break;
@@ -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
20
 
21
21
  interface getWavPCM16Response {
22
- samples: Int16Array
23
- sampleRate: number
24
- channels: number
25
- bitsPerSample: number
22
+ Samples: Int16Array
23
+ SampleRate: number
24
+ Channels: number
25
+ BitsPerSample: number
26
26
  }
27
27
 
28
28
  export const GetWavPCM16 = (buffer: Buffer): getWavPCM16Response => {
@@ -46,7 +46,7 @@ export const GetWavPCM16 = (buffer: Buffer): getWavPCM16Response => {
46
46
  const bitsPerSample = fmt.readUInt16LE(14);
47
47
  if (audioFormat !== 1 || bitsPerSample !== 16 || channels !== 1) { return null; }
48
48
  const samples = new Int16Array(data.buffer, data.byteOffset, data.length / 2);
49
- return { samples: new Int16Array(samples), sampleRate, channels, bitsPerSample };
49
+ return { Samples: new Int16Array(samples), SampleRate: sampleRate, Channels: channels, BitsPerSample: bitsPerSample };
50
50
  }
51
51
 
52
52
 
@@ -11,14 +11,19 @@
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
20
 
21
- export const SetAFSK = (bits: number[], sampleRate: number): Int16Array => {
21
+ interface SetAFSKOptions {
22
+ Bits: number[]
23
+ SampleRate: number
24
+ }
25
+
26
+ export const SetAFSK = ({ Bits, SampleRate }: SetAFSKOptions): Int16Array => {
22
27
  const baud = 520.83;
23
28
  const markFreq = 2083.3;
24
29
  const spaceFreq = 1562.5;
@@ -27,20 +32,20 @@ export const SetAFSK = (bits: number[], sampleRate: number): Int16Array => {
27
32
  const result = [];
28
33
  let phase = 0;
29
34
  let frac = 0;
30
- for (let b = 0; b < bits.length; b++) {
31
- const bit = bits[b];
35
+ for (let b = 0; b < Bits.length; b++) {
36
+ const bit = Bits[b];
32
37
  const freq = bit ? markFreq : spaceFreq;
33
- const samplesPerBit = sampleRate / baud + frac;
38
+ const samplesPerBit = SampleRate / baud + frac;
34
39
  const n = Math.round(samplesPerBit);
35
40
  frac = samplesPerBit - n;
36
- const inc = twoPi * freq / sampleRate;
41
+ const inc = twoPi * freq / SampleRate;
37
42
  for (let i = 0; i < n; i++) {
38
43
  result.push(Math.round(Math.sin(phase) * amplitude * 32767));
39
44
  phase += inc;
40
45
  if (phase > twoPi) phase -= twoPi;
41
46
  }
42
47
  }
43
- const fadeSamples = Math.floor(sampleRate * 0.002);
48
+ const fadeSamples = Math.floor(SampleRate * 0.002);
44
49
  for (let i = 0; i < fadeSamples; i++) {
45
50
  const gain = i / fadeSamples;
46
51
  result[i] = Math.round(result[i] * gain);
@@ -11,9 +11,9 @@
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
  */
@@ -11,23 +11,28 @@
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
20
 
21
- export const SetAttentionTone = (ms: number, sampleRate: number): Int16Array => {
22
- const len = Math.floor(ms * sampleRate);
21
+ interface SetAttentionToneOptions {
22
+ MS: number
23
+ SampleRate: number
24
+ }
25
+
26
+ export const SetAttentionTone = ({ MS, SampleRate }: SetAttentionToneOptions): Int16Array => {
27
+ const len = Math.floor(MS * SampleRate);
23
28
  const out = new Int16Array(len);
24
29
  const f1 = 853;
25
30
  const f2 = 960;
26
31
  const twoPi = Math.PI * 2;
27
32
  const amp = 0.1;
28
- const fadeLen = Math.floor(sampleRate * 0.00);
33
+ const fadeLen = Math.floor(SampleRate * 0.00);
29
34
  for (let i = 0; i < len; i++) {
30
- const t = i / sampleRate;
35
+ const t = i / SampleRate;
31
36
  const s = Math.sin(twoPi * f1 * t) + Math.sin(twoPi * f2 * t);
32
37
  let gain = 1;
33
38
  if (i < fadeLen) gain = i / fadeLen;
@@ -11,19 +11,24 @@
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
20
 
21
- import { GetPCMToFloat } from "./GetPCMToFloat";
22
- import { GetFloatPCM16 } from "./GetFloatPCM16";
21
+ import { GetPCMToFloat } from "@AudioComponents/GetPCMToFloat"
22
+ import { GetFloatPCM16 } from "@AudioComponents/GetFloatPCM16"
23
23
 
24
- export const SetNoise = (int16: Int16Array, noiseLevel: number = 0.02): Int16Array => {
25
- const x = GetPCMToFloat(int16);
26
- for (let i = 0; i < x.length; i++) x[i] += (Math.random() * 2 - 1) * noiseLevel;
24
+ interface SetNoiseOptions {
25
+ Int16: Int16Array
26
+ NoiseLevel?: number
27
+ }
28
+
29
+ export const SetNoise = ({ Int16, NoiseLevel }: SetNoiseOptions): Int16Array => {
30
+ const x = GetPCMToFloat(Int16);
31
+ for (let i = 0; i < x.length; i++) x[i] += (Math.random() * 2 - 1) * (NoiseLevel ?? 0.02);
27
32
  let peak = 0;
28
33
  for (let i = 0; i < x.length; i++) peak = Math.max(peak, Math.abs(x[i]));
29
34
  if (peak > 1) for (let i = 0; i < x.length; i++) x[i] *= 0.98 / peak;
@@ -11,21 +11,26 @@
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
20
 
21
- import { GetPCMToFloat } from "./GetPCMToFloat";
22
- import { GetFloatPCM16 } from "./GetFloatPCM16";
21
+ import { GetPCMToFloat } from "@AudioComponents/GetPCMToFloat"
22
+ import { GetFloatPCM16 } from "@AudioComponents/GetFloatPCM16"
23
23
 
24
- export const SetRadioEffect = (int16: Int16Array, sampleRate: number): Int16Array => {
24
+ interface SetRadioEffectOptions {
25
+ Int16: Int16Array
26
+ SampleRate: number
27
+ }
28
+
29
+ export const SetRadioEffect = ({ Int16, SampleRate }: SetRadioEffectOptions): Int16Array => {
25
30
  const hpCut = 3555;
26
31
  const lpCut = 1600;
27
- const x = GetPCMToFloat(int16);
28
- const dt = 1 / sampleRate;
32
+ const x = GetPCMToFloat(Int16);
33
+ const dt = 1 / SampleRate;
29
34
  const rcHP = 1 / (2 * Math.PI * hpCut);
30
35
  const aHP = rcHP / (rcHP + dt);
31
36
  let yHP = 0, xPrev = 0;
@@ -11,33 +11,41 @@
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
20
 
21
- import { SetAFSK } from "./SetAFSK";
22
- import { SetAsciiToBits } from "./SetAsciiToBits";
23
- import { GetMergedPCM16 } from "./GetMergedPCM16";
21
+ import { SetAFSK } from "@AudioComponents/SetAFSK"
22
+ import { SetAsciiToBits } from "@AudioComponents/SetAsciiToBits"
23
+ import { GetMergedPCM16 } from "@AudioComponents/GetMergedPCM16"
24
24
 
25
- export const SetSameHeader = (vtec: string, repeats: number, sampleRate: number = 8000, options: {preMarkSec?: number, gapSec?: number} = {}): Int16Array => {
26
- const preMarkSec = options.preMarkSec ?? 0.3;
27
- const gapSec = options.gapSec ?? 0.1;
25
+ interface SetSameHeaderOptions {
26
+ VTEC: string
27
+ Repeats: number
28
+ SampleRate?: number
29
+ PreMarkSec?: number
30
+ GapSec?: number
31
+ }
32
+
33
+ export const SetSameHeader = ({ VTEC, Repeats, SampleRate, PreMarkSec, GapSec }: SetSameHeaderOptions): Int16Array => {
34
+ const preMarkSec = PreMarkSec ?? 0.3;
35
+ const gapSec = GapSec ?? 0.1;
28
36
  const bursts = [];
29
- const gap = new Int16Array(Math.floor(gapSec * sampleRate));
30
- for (let i = 0; i < repeats; i++) {
31
- const bodyBits = SetAsciiToBits(vtec);
32
- const body = SetAFSK(bodyBits, sampleRate);
33
- const extendedBodyDuration = Math.round(preMarkSec * sampleRate);
37
+ const gap = new Int16Array(Math.floor(gapSec * SampleRate));
38
+ for (let i = 0; i < Repeats; i++) {
39
+ const bodyBits = SetAsciiToBits(VTEC);
40
+ const body = SetAFSK({ Bits: bodyBits, SampleRate: SampleRate});
41
+ const extendedBodyDuration = Math.round(preMarkSec * SampleRate);
34
42
  const extendedBody = new Int16Array(extendedBodyDuration + gap.length);
35
43
  for (let j = 0; j < extendedBodyDuration; j++) {
36
44
  extendedBody[j] = Math.round(body[j % body.length] * 0.2);
37
45
  }
38
46
  extendedBody.set(gap, extendedBodyDuration);
39
47
  bursts.push(extendedBody);
40
- if (i !== repeats - 1) bursts.push(gap);
48
+ if (i !== Repeats - 1) bursts.push(gap);
41
49
  }
42
50
  return GetMergedPCM16(bursts);
43
51
  }
@@ -11,24 +11,29 @@
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 { bootstrap } from "../../bootstrap"
21
- import { TypeSettings } from "../../@types/Settings";
20
+ import { Bootstrap } from "@Bootstrap"
21
+ import { SetWarning } from "@Utilities/SetWarning"
22
22
 
23
- interface SetWarningOptions {
24
- title?: string
25
- message: string
23
+ interface CreateQueryOptions {
24
+ Query: string
25
+ Parameters?: unknown[]
26
26
  }
27
27
 
28
- export const SetWarning = (options: SetWarningOptions): void => {
29
- const settings = bootstrap.settings as TypeSettings;
30
- bootstrap.listener.emit(`log`, `${options.title ?? `[${bootstrap.ansi_colors.YELLOW}@atmosx/product-parser${bootstrap.ansi_colors.RESET}]`} ${options.message}`)
31
- if (settings.EnableJournal) {
32
- console.log(`${options.title ?? `[${bootstrap.ansi_colors.YELLOW}@atmosx/product-parser${bootstrap.ansi_colors.RESET}]`} ${options.message}`)
28
+ export const CreateQuery = function({ Query, Parameters }: CreateQueryOptions): any {
29
+ try {
30
+ const parameters = Array.isArray(Parameters) ? Parameters : [];
31
+ const statement = Bootstrap.Database.prepare(Query);
32
+ return /^\s*select/i.test(Query)
33
+ ? statement.all(...parameters)
34
+ : statement.run(...parameters);
35
+ } catch (error) {
36
+ SetWarning({Message: `Database Query Error: ${error instanceof Error ? error.stack ?? error.message : String(error)}`})
37
+ throw error;
33
38
  }
34
- }
39
+ };
@@ -11,26 +11,29 @@
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 { bootstrap } from '../../bootstrap'
22
- import { SetWarning } from '../@utilities/SetWarning';
23
- import { CreateEvent } from '../../@building/CreateEvent';
24
- import { ValidateEvents } from "../../@manager/ValidateEvents";
20
+ import { TypeSettings } from "Types/Settings"
21
+ import { Bootstrap } from "@Bootstrap"
22
+ import { SetWarning } from "@Utilities/SetWarning"
23
+ import { CreateEvent } from "@Building/CreateEvent"
24
+ import { CreateQuery } from "@Database/CreateQuery"
25
25
 
26
26
  export const GetCachedEvents = async (): Promise<void> => {
27
27
  try {
28
- const settings = bootstrap.settings as TypeSettings;
28
+ const settings = Bootstrap.Settings as TypeSettings;
29
29
  const tick = performance.now();
30
30
  if (settings.NOAAWeatherWireServiceSettings.CacheSettings.Enabled) {
31
31
  const max = settings.NOAAWeatherWireServiceSettings.CacheSettings.MaxRetentionHistory ?? 500;
32
- const get = await bootstrap.database.prepare(`SELECT * FROM stanzas ORDER BY rowid DESC LIMIT ?`).all(max) as { rowid: number; stanza: string }[];
33
- SetWarning({ message: `Fetched ${get.length} cached stanzas from the database in ${Math.floor(performance.now() - tick)} ms` })
32
+ const get = await CreateQuery({
33
+ Query: `SELECT * FROM stanzas ORDER BY rowid DESC LIMIT ?`,
34
+ Parameters: [max]
35
+ }) as { rowid: number; stanza: string }[];
36
+ SetWarning({ Message: `Fetched ${get.length} cached stanzas from the database in ${Math.floor(performance.now() - tick)} ms` })
34
37
  let events = get.map((row) => JSON.parse(row.stanza))
35
38
  .filter(stanza => {
36
39
  if (!stanza) { return }
@@ -40,11 +43,11 @@ export const GetCachedEvents = async (): Promise<void> => {
40
43
  return !isSkippable
41
44
  });
42
45
  events = events.sort((a, b) => b.issued - a.issued)
43
- await Promise.all(events.map(event => CreateEvent(event, true)))
44
- SetWarning({ message: `Processed ${events.length} cached stanzas in ${Math.floor(performance.now() - tick)} ms` })
45
- await ValidateEvents(bootstrap.cache.processed)
46
+ await Promise.all(events.map(event => CreateEvent(event)))
47
+ SetWarning({ Message: `Processed ${events.length} cached stanzas in ${Math.floor(performance.now() - tick)} ms` })
46
48
  }
47
- } catch (error) {
48
- SetWarning({ message: `An error occurred while fetching cached stanzas: ${error.message} -> ${error.stack}` })
49
+ } catch (error: unknown) {
50
+ const message = error instanceof Error ? error.message : String(error);
51
+ SetWarning({ Message: `An error occurred while fetching cached stanzas: ${message}` })
49
52
  }
50
53
  }
@@ -0,0 +1,168 @@
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 { EnumStateFIPS } from "@Enums/States"
21
+ import { Bootstrap } from "@Bootstrap"
22
+ import { CreateHttp } from "@Utilities/CreateHttp"
23
+ import { CreateQuery } from "@Database/CreateQuery"
24
+ import { SetWarning } from "@Utilities/SetWarning"
25
+ import { feature } from "topojson-client"
26
+
27
+ type BoundaryRow = {
28
+ id: string
29
+ type: `state` | `county`
30
+ state: string
31
+ name: string
32
+ geometry: string
33
+ }
34
+
35
+ export const ImportBoundaries = async (): Promise<void> => {
36
+ try {
37
+ const existing = CreateQuery({ Query: `SELECT type, COUNT(*) AS count FROM boundaries GROUP BY type`}) as { type: string, count: number }[]
38
+ const existingStates = existing.find(row => row.type === `state`)?.count ?? 0
39
+ const existingCounties = existing.find(row => row.type === `county`)?.count ?? 0
40
+
41
+ if (existingStates > 0 || existingCounties > 0) {
42
+ SetWarning({ Message: `Boundary database already contains ${existingStates} states and ${existingCounties} counties, skipping import` })
43
+ return
44
+ }
45
+
46
+ const boundaries = await CreateHttp({
47
+ URL: Bootstrap.Settings.BoundarySettings.BoundaryDatabase,
48
+ Timeout: 5000
49
+ })
50
+
51
+ if (boundaries.error || !boundaries.message) {
52
+ SetWarning({ Message: `Failed to download boundary database` })
53
+ return
54
+ }
55
+
56
+ let database: any
57
+
58
+ try {
59
+ database = JSON.parse(boundaries.message)
60
+ } catch {
61
+ SetWarning({ Message: `Failed to parse boundary database` })
62
+ return
63
+ }
64
+
65
+ if (database?.type !== `Topology` || !database?.objects?.states || !database?.objects?.counties) {
66
+ SetWarning({ Message: `Boundary database is missing states or counties` })
67
+ return
68
+ }
69
+
70
+ let states: any
71
+ let counties: any
72
+
73
+ try {
74
+ states = feature(database, database.objects.states)
75
+ counties = feature(database, database.objects.counties)
76
+ } catch (error: unknown) {
77
+ const message = error instanceof Error ? error.message : String(error)
78
+ SetWarning({ Message: `Failed to convert boundary database: ${message}` })
79
+ return
80
+ }
81
+
82
+ if (!Array.isArray(states?.features) || !Array.isArray(counties?.features)) {
83
+ SetWarning({ Message: `Boundary database contains invalid state or county data` })
84
+ return
85
+ }
86
+
87
+ const insert = `INSERT OR REPLACE INTO boundaries (id, type, state, name, geometry) VALUES (?, ?, ?, ?, ?)`
88
+ const stateRows: BoundaryRow[] = []
89
+ const countyRows: BoundaryRow[] = []
90
+ let skippedStates = 0
91
+ let skippedCounties = 0
92
+
93
+ for (const state of states.features) {
94
+ if (!state?.geometry || state.id === undefined || state.id === null) {
95
+ skippedStates++
96
+ continue
97
+ }
98
+
99
+ const fips = String(state.id).padStart(2, `0`)
100
+ const abbreviation = EnumStateFIPS[fips]
101
+
102
+ if (!abbreviation) {
103
+ skippedStates++
104
+ continue
105
+ }
106
+
107
+ stateRows.push({
108
+ id: fips,
109
+ type: `state`,
110
+ state: abbreviation,
111
+ name: state.properties?.name ?? abbreviation,
112
+ geometry: JSON.stringify(state.geometry)
113
+ })
114
+ }
115
+
116
+ for (const county of counties.features) {
117
+ if (!county?.geometry || county.id === undefined || county.id === null) {
118
+ skippedCounties++
119
+ continue
120
+ }
121
+
122
+ const fips = String(county.id).padStart(5, `0`)
123
+ const stateFIPS = fips.slice(0, 2)
124
+ const abbreviation = EnumStateFIPS[stateFIPS]
125
+
126
+ if (!abbreviation) {
127
+ skippedCounties++
128
+ continue
129
+ }
130
+
131
+ countyRows.push({
132
+ id: fips,
133
+ type: `county`,
134
+ state: abbreviation,
135
+ name: county.properties?.name ?? fips,
136
+ geometry: JSON.stringify(county.geometry)
137
+ })
138
+ }
139
+
140
+ SetWarning({ Message: `Importing ${stateRows.length} states and ${countyRows.length} counties` })
141
+
142
+ const transaction = Bootstrap.Database.transaction((rows: BoundaryRow[]) => {
143
+ for (const row of rows) {
144
+ CreateQuery({
145
+ Query: insert,
146
+ Parameters: [row.id, row.type, row.state, row.name, row.geometry]
147
+ })
148
+ }
149
+ })
150
+
151
+ transaction(stateRows)
152
+ transaction(countyRows)
153
+
154
+ const imported = CreateQuery({ Query: `SELECT type, COUNT(*) AS count FROM boundaries GROUP BY type`}) as { type: string, count: number }[]
155
+ const importedStates = imported.find(row => row.type === `state`)?.count ?? 0
156
+ const importedCounties = imported.find(row => row.type === `county`)?.count ?? 0
157
+
158
+ if (importedStates !== stateRows.length || importedCounties !== countyRows.length) {
159
+ SetWarning({ Message: `Boundary import verification failed: ${importedStates} states and ${importedCounties} counties` })
160
+ return
161
+ }
162
+
163
+ SetWarning({ Message: `Imported ${importedStates} states and ${importedCounties} counties` })
164
+ } catch (error: unknown) {
165
+ const message = error instanceof Error ? error.message : String(error)
166
+ SetWarning({ Message: `An error occurred while importing boundaries: ${message}` })
167
+ }
168
+ }
@@ -11,44 +11,34 @@
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 { bootstrap } from "../../bootstrap"
21
- import { CreateHttp } from '../@utilities/CreateHttp'
22
- import { SetWarning } from "../@utilities/SetWarning";
20
+ import { Bootstrap } from "@Bootstrap"
21
+ import { CreateHttp } from "@Utilities/CreateHttp"
22
+ import { SetWarning } from "@Utilities/SetWarning"
23
+ import { CreateQuery } from "@Database/CreateQuery";
23
24
 
24
25
  export const ImportBroadcastify = async (): Promise<void> => {
25
- const settings = bootstrap.settings;
26
-
27
- const isBroadcastifyImported = bootstrap.database
28
- .prepare(`SELECT name FROM sqlite_master WHERE type='table' AND name='broadcastify';`)
29
- .get();
30
-
31
-
32
- if (!settings.BroadcastifySettings.BroadcastifyAttachments) { return }
33
- if (isBroadcastifyImported) { return }
34
-
26
+ const settings = Bootstrap.Settings;
35
27
  const broadcastify = await CreateHttp({
36
- url: settings.BroadcastifySettings.BroadcastifyDatabase,
37
- timeout: 5000,
28
+ URL: settings.BroadcastifySettings.BroadcastifyDatabase,
29
+ Timeout: 5000,
38
30
  });
39
31
  if (!broadcastify.error) {
40
- bootstrap.database.prepare(`CREATE TABLE broadcastify ( state TEXT, county TEXT, feed TEXT, type TEXT, link TEXT);`)
41
- .run();
42
32
  const states = JSON.parse(broadcastify.message);
43
- const insert = bootstrap.database.prepare(`INSERT INTO broadcastify (state, county, feed, type, link) VALUES (?, ?, ?, ?, ?)`);
44
- const transaction = bootstrap.database.transaction((rows: any[]) => {
33
+ const insert = `INSERT INTO broadcastify (state, county, feed, type, link) VALUES (?, ?, ?, ?, ?)`;
34
+ const transaction = Bootstrap.Database.transaction((rows: any[]) => {
45
35
  for (const row of rows) {
46
- insert.run(row);
36
+ CreateQuery({ Query: insert, Parameters: row });
47
37
  }
48
38
  });
49
39
  const batch: any[] = [];
50
40
  for (const state of states) {
51
- SetWarning({ message: `Importing ${state.counties.length} counties from ${state.state} for Broadcastify` });
41
+ SetWarning({ Message: `Importing ${state.counties.length} counties from ${state.state} for Broadcastify` });
52
42
  for (const county of state.counties) {
53
43
  const countyName = county.county;
54
44
  for (const feed of county.feeds) {
@@ -65,6 +55,6 @@ export const ImportBroadcastify = async (): Promise<void> => {
65
55
  transaction(batch);
66
56
  }
67
57
  if (broadcastify.error) {
68
- SetWarning({ message: `Error importing Broadcastify data: ${broadcastify.message}` });
58
+ SetWarning({ Message: `Error importing Broadcastify data: ${broadcastify.message}` });
69
59
  }
70
60
  };