pwn 0.5.621 → 0.5.626

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 (124) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +2 -2
  3. data/Gemfile +1 -1
  4. data/README.md +7 -1
  5. data/bin/pwn_gqrx_scanner +78 -9
  6. data/documentation/Agent-Tool-Registry.md +3 -3
  7. data/documentation/Configuration.md +301 -47
  8. data/documentation/Cron.md +5 -3
  9. data/documentation/Diagrams.md +1 -1
  10. data/documentation/Extrospection.md +472 -26
  11. data/documentation/FFI.md +72 -8
  12. data/documentation/Home.md +4 -4
  13. data/documentation/How-PWN-Works.md +7 -3
  14. data/documentation/Mistakes.md +9 -0
  15. data/documentation/SDR.md +83 -10
  16. data/documentation/Skills-Memory-Learning.md +101 -11
  17. data/documentation/diagrams/agent-tool-registry.svg +56 -55
  18. data/documentation/diagrams/ai-integration-tool-calling.svg +24 -24
  19. data/documentation/diagrams/aws-cloud-security.svg +25 -25
  20. data/documentation/diagrams/burp-vs-zap-preference.svg +12 -12
  21. data/documentation/diagrams/code-scanning-sast.svg +25 -25
  22. data/documentation/diagrams/cron-scheduling.svg +23 -23
  23. data/documentation/diagrams/dot/agent-tool-registry.dot +2 -2
  24. data/documentation/diagrams/dot/extrospection-world-awareness.dot +33 -6
  25. data/documentation/diagrams/dot/hardware-hacking.dot +3 -1
  26. data/documentation/diagrams/dot/memory-skills-detailed.dot +4 -2
  27. data/documentation/diagrams/dot/mistakes-negative-feedback.dot +4 -2
  28. data/documentation/diagrams/dot/overall-pwn-architecture.dot +3 -3
  29. data/documentation/diagrams/dot/persistence-filesystem.dot +3 -3
  30. data/documentation/diagrams/dot/pwn-ai-feedback-learning-loop.dot +10 -4
  31. data/documentation/diagrams/dot/sdr-radio-flow.dot +39 -16
  32. data/documentation/diagrams/driver-framework.svg +13 -13
  33. data/documentation/diagrams/extrospection-world-awareness.svg +383 -177
  34. data/documentation/diagrams/fuzzing-workflow.svg +24 -24
  35. data/documentation/diagrams/hardware-hacking.svg +84 -69
  36. data/documentation/diagrams/history-to-drivers.svg +18 -18
  37. data/documentation/diagrams/memory-skills-detailed.svg +137 -120
  38. data/documentation/diagrams/mistakes-negative-feedback.svg +152 -137
  39. data/documentation/diagrams/network-infra-testing.svg +27 -27
  40. data/documentation/diagrams/overall-pwn-architecture.svg +97 -97
  41. data/documentation/diagrams/penetration-testing-workflow.svg +30 -30
  42. data/documentation/diagrams/persistence-filesystem.svg +100 -94
  43. data/documentation/diagrams/plugin-ecosystem.svg +35 -35
  44. data/documentation/diagrams/pwn-ai-feedback-learning-loop.svg +254 -207
  45. data/documentation/diagrams/pwn-repl-prototyping.svg +20 -20
  46. data/documentation/diagrams/reporting-pipeline.svg +18 -18
  47. data/documentation/diagrams/reverse-engineering-flow.svg +21 -21
  48. data/documentation/diagrams/sdr-radio-flow.svg +223 -91
  49. data/documentation/diagrams/sessions-cron-automation.svg +18 -18
  50. data/documentation/diagrams/swarm-multi-agent.svg +39 -39
  51. data/documentation/diagrams/web-application-testing.svg +26 -26
  52. data/documentation/diagrams/zero-day-research-flow.svg +25 -25
  53. data/documentation/pwn-ai-Agent.md +16 -10
  54. data/documentation/pwn_silent_help_learn_demo.gif +0 -0
  55. data/lib/pwn/ai/agent/assembly.rb +1 -1
  56. data/lib/pwn/ai/agent/btc.rb +1 -1
  57. data/lib/pwn/ai/agent/burp_suite.rb +1 -1
  58. data/lib/pwn/ai/agent/extrospection.rb +2562 -57
  59. data/lib/pwn/ai/agent/gqrx.rb +2 -2
  60. data/lib/pwn/ai/agent/hacker_one.rb +1 -1
  61. data/lib/pwn/ai/agent/learning.rb +16 -16
  62. data/lib/pwn/ai/agent/loop.rb +1 -1
  63. data/lib/pwn/ai/agent/{introspection.rb → reflect.rb} +12 -12
  64. data/lib/pwn/ai/agent/sast.rb +1 -1
  65. data/lib/pwn/ai/agent/tools/extrospection.rb +311 -8
  66. data/lib/pwn/ai/agent/tools/learning.rb +7 -7
  67. data/lib/pwn/ai/agent/transparent_browser.rb +1 -1
  68. data/lib/pwn/ai/agent/vuln_gen.rb +2 -2
  69. data/lib/pwn/ai/agent.rb +1 -1
  70. data/lib/pwn/ai/open_ai.rb +10 -6
  71. data/lib/pwn/config.rb +5 -4
  72. data/lib/pwn/ffi/adalm_pluto.rb +498 -0
  73. data/lib/pwn/ffi/fftw.rb +192 -0
  74. data/lib/pwn/ffi/hack_rf.rb +193 -0
  75. data/lib/pwn/ffi/liquid.rb +244 -0
  76. data/lib/pwn/ffi/rtl_sdr.rb +210 -0
  77. data/lib/pwn/ffi/soapy_sdr.rb +177 -0
  78. data/lib/pwn/ffi/stdio.rb +9 -1
  79. data/lib/pwn/ffi/volk.rb +241 -0
  80. data/lib/pwn/ffi.rb +45 -2
  81. data/lib/pwn/plugins/burp_suite.rb +2 -2
  82. data/lib/pwn/sast/pom_version.rb +2 -2
  83. data/lib/pwn/sast/test_case_engine.rb +1 -1
  84. data/lib/pwn/sdr/decoder/adsb.rb +201 -12
  85. data/lib/pwn/sdr/decoder/apt.rb +19 -5
  86. data/lib/pwn/sdr/decoder/base.rb +314 -1
  87. data/lib/pwn/sdr/decoder/bluetooth.rb +91 -18
  88. data/lib/pwn/sdr/decoder/dect.rb +81 -23
  89. data/lib/pwn/sdr/decoder/dsp.rb +229 -15
  90. data/lib/pwn/sdr/decoder/flex.rb +23 -6
  91. data/lib/pwn/sdr/decoder/gps.rb +80 -18
  92. data/lib/pwn/sdr/decoder/gsm.rb +83 -28
  93. data/lib/pwn/sdr/decoder/iridium.rb +80 -18
  94. data/lib/pwn/sdr/decoder/lora.rb +84 -28
  95. data/lib/pwn/sdr/decoder/lte.rb +80 -18
  96. data/lib/pwn/sdr/decoder/morse.rb +23 -6
  97. data/lib/pwn/sdr/decoder/p25.rb +90 -31
  98. data/lib/pwn/sdr/decoder/pager.rb +23 -6
  99. data/lib/pwn/sdr/decoder/pocsag.rb +23 -6
  100. data/lib/pwn/sdr/decoder/rds.rb +219 -52
  101. data/lib/pwn/sdr/decoder/rfid.rb +81 -27
  102. data/lib/pwn/sdr/decoder/rtl433.rb +85 -27
  103. data/lib/pwn/sdr/decoder/rtty.rb +23 -6
  104. data/lib/pwn/sdr/decoder/wifi.rb +86 -32
  105. data/lib/pwn/sdr/decoder/zigbee.rb +88 -35
  106. data/lib/pwn/sdr/decoder.rb +6 -5
  107. data/lib/pwn/sdr/frequency_allocation.rb +124 -81
  108. data/lib/pwn/sdr/gqrx.rb +1513 -165
  109. data/lib/pwn/version.rb +1 -1
  110. data/spec/lib/pwn/ai/agent/extrospection_spec.rb +96 -0
  111. data/spec/lib/pwn/ai/agent/{introspection_spec.rb → reflect_spec.rb} +3 -3
  112. data/spec/lib/pwn/ai/agent/tools/extrospection_spec.rb +8 -24
  113. data/spec/lib/pwn/ffi/adalm_pluto_spec.rb +37 -0
  114. data/spec/lib/pwn/ffi/fftw_spec.rb +26 -0
  115. data/spec/lib/pwn/ffi/hack_rf_spec.rb +25 -0
  116. data/spec/lib/pwn/ffi/liquid_spec.rb +42 -0
  117. data/spec/lib/pwn/ffi/rtl_sdr_spec.rb +24 -0
  118. data/spec/lib/pwn/ffi/soapy_sdr_spec.rb +25 -0
  119. data/spec/lib/pwn/ffi/volk_spec.rb +36 -0
  120. data/spec/lib/pwn/sdr/decoder/base_iq_spec.rb +65 -0
  121. data/spec/lib/pwn/sdr/decoder/dsp_spec.rb +50 -4
  122. data/spec/lib/pwn/sdr/decoder/rds_spec.rb +45 -4
  123. data/third_party/pwn_rdoc.jsonl +279 -30
  124. metadata +21 -5
@@ -4,163 +4,295 @@
4
4
  <!-- Generated by graphviz version 14.1.2 (0)
5
5
  -->
6
6
  <!-- Title: PWN_SDR Pages: 1 -->
7
- <svg width="917pt" height="599pt"
8
- viewBox="0.00 0.00 917.00 599.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
9
- <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(43.2 556.2)">
7
+ <svg width="1835pt" height="916pt"
8
+ viewBox="0.00 0.00 1835.00 916.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
9
+ <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(43.2 872.44)">
10
10
  <title>PWN_SDR</title>
11
- <polygon fill="#0f172a" stroke="none" points="-43.2,43.2 -43.2,-556.2 873.45,-556.2 873.45,43.2 -43.2,43.2"/>
12
- <text xml:space="preserve" text-anchor="start" x="169.88" y="-491" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="20.00" fill="#e2e8f0">PWN::SDR — Software&#45;Defined Radio &amp; RF Hacking</text>
13
- <text xml:space="preserve" text-anchor="start" x="197.62" y="-479.55" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#94a3b8">GQRX · FlipperZero · RFIDler · SonMicro · FrequencyAllocation · Decoder::* (20 protocols)</text>
11
+ <polygon fill="#0f172a" stroke="none" points="-43.2,43.2 -43.2,-872.44 1792.2,-872.44 1792.2,43.2 -43.2,43.2"/>
12
+ <text xml:space="preserve" text-anchor="start" x="629.25" y="-807.24" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="20.00" fill="#e2e8f0">PWN::SDR — Software&#45;Defined Radio &amp; RF Hacking</text>
13
+ <text xml:space="preserve" text-anchor="start" x="576.38" y="-795.79" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#94a3b8">GQRX · FlipperZero · RFIDler · FrequencyAllocation · Decoder::* (20) · FFI::{Volk,Liquid,FFTW,HackRF,RTLSdr,SoapySDR}</text>
14
14
  <g id="clust1" class="cluster">
15
15
  <title>cluster_hw</title>
16
- <path fill="#022c22" stroke="#047857" d="M228.5,-239C228.5,-239 346,-239 346,-239 352,-239 358,-245 358,-251 358,-251 358,-446 358,-446 358,-452 352,-458 346,-458 346,-458 228.5,-458 228.5,-458 222.5,-458 216.5,-452 216.5,-446 216.5,-446 216.5,-251 216.5,-251 216.5,-245 222.5,-239 228.5,-239"/>
17
- <text xml:space="preserve" text-anchor="middle" x="287.25" y="-435" font-family="Helvetica,sans-Serif" font-size="20.00" fill="#a7f3d0">Hardware</text>
16
+ <path fill="#022c22" stroke="#047857" d="M223.5,-81.24C223.5,-81.24 486.25,-81.24 486.25,-81.24 492.25,-81.24 498.25,-87.24 498.25,-93.24 498.25,-93.24 498.25,-220.24 498.25,-220.24 498.25,-226.24 492.25,-232.24 486.25,-232.24 486.25,-232.24 223.5,-232.24 223.5,-232.24 217.5,-232.24 211.5,-226.24 211.5,-220.24 211.5,-220.24 211.5,-93.24 211.5,-93.24 211.5,-87.24 217.5,-81.24 223.5,-81.24"/>
17
+ <text xml:space="preserve" text-anchor="middle" x="354.88" y="-209.24" font-family="Helvetica,sans-Serif" font-size="20.00" fill="#a7f3d0">Hardware</text>
18
18
  </g>
19
19
  <g id="clust2" class="cluster">
20
- <title>cluster_ctrl</title>
21
- <path fill="#422006" stroke="#a16207" d="M440,-219C440,-219 564.25,-219 564.25,-219 570.25,-219 576.25,-225 576.25,-231 576.25,-231 576.25,-454 576.25,-454 576.25,-460 570.25,-466 564.25,-466 564.25,-466 440,-466 440,-466 434,-466 428,-460 428,-454 428,-454 428,-231 428,-231 428,-225 434,-219 440,-219"/>
22
- <text xml:space="preserve" text-anchor="middle" x="502.12" y="-443" font-family="Helvetica,sans-Serif" font-size="20.00" fill="#fde68a">Control · Scan</text>
20
+ <title>cluster_ffi</title>
21
+ <path fill="#0c4a6e" stroke="#0369a1" d="M534.25,-343.24C534.25,-343.24 986.62,-343.24 986.62,-343.24 992.62,-343.24 998.62,-349.24 998.62,-355.24 998.62,-355.24 998.62,-550.24 998.62,-550.24 998.62,-556.24 992.62,-562.24 986.62,-562.24 986.62,-562.24 534.25,-562.24 534.25,-562.24 528.25,-562.24 522.25,-556.24 522.25,-550.24 522.25,-550.24 522.25,-355.24 522.25,-355.24 522.25,-349.24 528.25,-343.24 534.25,-343.24"/>
22
+ <text xml:space="preserve" text-anchor="middle" x="760.44" y="-539.24" font-family="Helvetica,sans-Serif" font-size="20.00" fill="#bae6fd">PWN::FFI native backends</text>
23
23
  </g>
24
24
  <g id="clust3" class="cluster">
25
+ <title>cluster_ctrl</title>
26
+ <path fill="#422006" stroke="#a16207" d="M551.5,-113.24C551.5,-113.24 1002.75,-113.24 1002.75,-113.24 1008.75,-113.24 1014.75,-119.24 1014.75,-125.24 1014.75,-125.24 1014.75,-280.24 1014.75,-280.24 1014.75,-286.24 1008.75,-292.24 1002.75,-292.24 1002.75,-292.24 551.5,-292.24 551.5,-292.24 545.5,-292.24 539.5,-286.24 539.5,-280.24 539.5,-280.24 539.5,-125.24 539.5,-125.24 539.5,-119.24 545.5,-113.24 551.5,-113.24"/>
27
+ <text xml:space="preserve" text-anchor="middle" x="777.12" y="-269.24" font-family="Helvetica,sans-Serif" font-size="20.00" fill="#fde68a">Control · Scan</text>
28
+ </g>
29
+ <g id="clust4" class="cluster">
25
30
  <title>cluster_dec</title>
26
- <path fill="#2e1065" stroke="#6d28d9" d="M20,-8C20,-8 810.25,-8 810.25,-8 816.25,-8 822.25,-14 822.25,-20 822.25,-20 822.25,-199 822.25,-199 822.25,-205 816.25,-211 810.25,-211 810.25,-211 20,-211 20,-211 14,-211 8,-205 8,-199 8,-199 8,-20 8,-20 8,-14 14,-8 20,-8"/>
27
- <text xml:space="preserve" text-anchor="middle" x="415.12" y="-188" font-family="Helvetica,sans-Serif" font-size="20.00" fill="#ddd6fe">Decode · Record</text>
31
+ <path fill="#2e1065" stroke="#6d28d9" d="M20,-570.24C20,-570.24 1729,-570.24 1729,-570.24 1735,-570.24 1741,-576.24 1741,-582.24 1741,-582.24 1741,-770.24 1741,-770.24 1741,-776.24 1735,-782.24 1729,-782.24 1729,-782.24 20,-782.24 20,-782.24 14,-782.24 8,-776.24 8,-770.24 8,-770.24 8,-582.24 8,-582.24 8,-576.24 14,-570.24 20,-570.24"/>
32
+ <text xml:space="preserve" text-anchor="middle" x="874.5" y="-759.24" font-family="Helvetica,sans-Serif" font-size="20.00" fill="#ddd6fe">Decode · Sense · Record</text>
28
33
  </g>
29
34
  <!-- RF -->
30
35
  <g id="node1" class="node">
31
36
  <title>RF</title>
32
- <path fill="#fda4af" stroke="#334155" stroke-width="1.3" d="M111.88,-351C111.88,-351 42.62,-351 42.62,-351 36.62,-351 30.62,-345 30.62,-339 30.62,-339 30.62,-327 30.62,-327 30.62,-321 36.62,-315 42.62,-315 42.62,-315 111.88,-315 111.88,-315 117.88,-315 123.88,-321 123.88,-327 123.88,-327 123.88,-339 123.88,-339 123.88,-345 117.88,-351 111.88,-351"/>
33
- <text xml:space="preserve" text-anchor="middle" x="77.25" y="-329.88" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">📡 &#160;RF Spectrum</text>
37
+ <path fill="#fda4af" stroke="#334155" stroke-width="1.3" d="M111.88,-125.24C111.88,-125.24 42.62,-125.24 42.62,-125.24 36.62,-125.24 30.62,-119.24 30.62,-113.24 30.62,-113.24 30.62,-101.24 30.62,-101.24 30.62,-95.24 36.62,-89.24 42.62,-89.24 42.62,-89.24 111.88,-89.24 111.88,-89.24 117.88,-89.24 123.88,-95.24 123.88,-101.24 123.88,-101.24 123.88,-113.24 123.88,-113.24 123.88,-119.24 117.88,-125.24 111.88,-125.24"/>
38
+ <text xml:space="preserve" text-anchor="middle" x="77.25" y="-104.11" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">📡 &#160;RF Spectrum</text>
34
39
  </g>
35
40
  <!-- SDRhw -->
36
41
  <g id="node2" class="node">
37
42
  <title>SDRhw</title>
38
- <path fill="#6ee7b7" stroke="#334155" stroke-width="1.3" d="M338,-283C338,-283 236.5,-283 236.5,-283 230.5,-283 224.5,-277 224.5,-271 224.5,-271 224.5,-259 224.5,-259 224.5,-253 230.5,-247 236.5,-247 236.5,-247 338,-247 338,-247 344,-247 350,-253 350,-259 350,-259 350,-271 350,-271 350,-277 344,-283 338,-283"/>
39
- <text xml:space="preserve" text-anchor="middle" x="287.25" y="-267.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">RTL&#45;SDR / HackRF</text>
40
- <text xml:space="preserve" text-anchor="middle" x="287.25" y="-255.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">(via GQRX / SoapySDR)</text>
43
+ <path fill="#6ee7b7" stroke="#334155" stroke-width="1.3" d="M357,-193.24C357,-193.24 231.5,-193.24 231.5,-193.24 225.5,-193.24 219.5,-187.24 219.5,-181.24 219.5,-181.24 219.5,-169.24 219.5,-169.24 219.5,-163.24 225.5,-157.24 231.5,-157.24 231.5,-157.24 357,-157.24 357,-157.24 363,-157.24 369,-163.24 369,-169.24 369,-169.24 369,-181.24 369,-181.24 369,-187.24 363,-193.24 357,-193.24"/>
44
+ <text xml:space="preserve" text-anchor="middle" x="294.25" y="-177.74" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">RTL&#45;SDR / HackRF / Airspy</text>
45
+ <text xml:space="preserve" text-anchor="middle" x="294.25" y="-165.74" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">(via GQRX / SoapySDR / FFI)</text>
41
46
  </g>
42
47
  <!-- RF&#45;&gt;SDRhw -->
43
48
  <g id="edge1" class="edge">
44
49
  <title>RF&#45;&gt;SDRhw</title>
45
- <path fill="none" stroke="#fb7185" stroke-width="1.3" d="M124.41,-317.91C152.63,-308.69 189.17,-296.74 220.38,-286.53"/>
46
- <polygon fill="#fb7185" stroke="#fb7185" stroke-width="1.3" points="220.86,-289.32 227.59,-284.18 219.12,-284 220.86,-289.32"/>
50
+ <path fill="none" stroke="#fb7185" stroke-width="1.3" d="M124.37,-121.82C153.81,-131.13 192.48,-143.37 225.39,-153.77"/>
51
+ <polygon fill="#fb7185" stroke="#fb7185" stroke-width="1.3" points="224.16,-156.32 232.63,-156.06 225.84,-150.98 224.16,-156.32"/>
47
52
  </g>
48
53
  <!-- Flipper -->
49
54
  <g id="node3" class="node">
50
55
  <title>Flipper</title>
51
- <path fill="#6ee7b7" stroke="#334155" stroke-width="1.3" d="M321.5,-351C321.5,-351 253,-351 253,-351 247,-351 241,-345 241,-339 241,-339 241,-327 241,-327 241,-321 247,-315 253,-315 253,-315 321.5,-315 321.5,-315 327.5,-315 333.5,-321 333.5,-327 333.5,-327 333.5,-339 333.5,-339 333.5,-345 327.5,-351 321.5,-351"/>
52
- <text xml:space="preserve" text-anchor="middle" x="287.25" y="-329.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">SDR::FlipperZero</text>
56
+ <path fill="#6ee7b7" stroke="#334155" stroke-width="1.3" d="M328.5,-125.24C328.5,-125.24 260,-125.24 260,-125.24 254,-125.24 248,-119.24 248,-113.24 248,-113.24 248,-101.24 248,-101.24 248,-95.24 254,-89.24 260,-89.24 260,-89.24 328.5,-89.24 328.5,-89.24 334.5,-89.24 340.5,-95.24 340.5,-101.24 340.5,-101.24 340.5,-113.24 340.5,-113.24 340.5,-119.24 334.5,-125.24 328.5,-125.24"/>
57
+ <text xml:space="preserve" text-anchor="middle" x="294.25" y="-103.74" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">SDR::FlipperZero</text>
53
58
  </g>
54
59
  <!-- RF&#45;&gt;Flipper -->
55
60
  <g id="edge2" class="edge">
56
61
  <title>RF&#45;&gt;Flipper</title>
57
- <path fill="none" stroke="#fb7185" stroke-width="1.3" d="M124.41,-333C155.89,-333 197.74,-333 231,-333"/>
58
- <polygon fill="#fb7185" stroke="#fb7185" stroke-width="1.3" points="230.61,-335.8 238.61,-333 230.61,-330.2 230.61,-335.8"/>
62
+ <path fill="none" stroke="#fb7185" stroke-width="1.3" d="M124.37,-107.24C157.64,-107.24 202.71,-107.24 237.92,-107.24"/>
63
+ <polygon fill="#fb7185" stroke="#fb7185" stroke-width="1.3" points="237.61,-110.04 245.61,-107.24 237.61,-104.44 237.61,-110.04"/>
59
64
  </g>
60
65
  <!-- RFID -->
61
66
  <g id="node4" class="node">
62
67
  <title>RFID</title>
63
- <path fill="#6ee7b7" stroke="#334155" stroke-width="1.3" d="M315.88,-419C315.88,-419 258.62,-419 258.62,-419 252.62,-419 246.62,-413 246.62,-407 246.62,-407 246.62,-395 246.62,-395 246.62,-389 252.62,-383 258.62,-383 258.62,-383 315.88,-383 315.88,-383 321.88,-383 327.88,-389 327.88,-395 327.88,-395 327.88,-407 327.88,-407 327.88,-413 321.88,-419 315.88,-419"/>
64
- <text xml:space="preserve" text-anchor="middle" x="287.25" y="-403.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">SDR::RFIDler</text>
65
- <text xml:space="preserve" text-anchor="middle" x="287.25" y="-391.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">SonMicroRFID</text>
68
+ <path fill="#6ee7b7" stroke="#334155" stroke-width="1.3" d="M478.25,-125.24C478.25,-125.24 421,-125.24 421,-125.24 415,-125.24 409,-119.24 409,-113.24 409,-113.24 409,-101.24 409,-101.24 409,-95.24 415,-89.24 421,-89.24 421,-89.24 478.25,-89.24 478.25,-89.24 484.25,-89.24 490.25,-95.24 490.25,-101.24 490.25,-101.24 490.25,-113.24 490.25,-113.24 490.25,-119.24 484.25,-125.24 478.25,-125.24"/>
69
+ <text xml:space="preserve" text-anchor="middle" x="449.62" y="-109.74" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">SDR::RFIDler</text>
70
+ <text xml:space="preserve" text-anchor="middle" x="449.62" y="-97.74" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">SonMicroRFID</text>
66
71
  </g>
67
72
  <!-- RF&#45;&gt;RFID -->
68
73
  <g id="edge3" class="edge">
69
74
  <title>RF&#45;&gt;RFID</title>
70
- <path fill="none" stroke="#fb7185" stroke-width="1.3" d="M124.27,-348.51C151.14,-357.52 185.7,-369.02 216.5,-379 223.06,-381.13 229.98,-383.34 236.8,-385.51"/>
71
- <polygon fill="#fb7185" stroke="#fb7185" stroke-width="1.3" points="235.66,-388.09 244.14,-387.83 237.36,-382.75 235.66,-388.09"/>
75
+ <path fill="none" stroke="#fb7185" stroke-width="1.3" d="M94.43,-88.94C112.82,-69.34 144.7,-38.82 178.5,-22.24 191.96,-15.63 196.59,-16.8 211.5,-15.24 281.12,-7.93 305.33,13.86 369,-15.24 398.17,-28.57 420.75,-58.45 434.3,-80.56"/>
76
+ <polygon fill="#fb7185" stroke="#fb7185" stroke-width="1.3" points="431.73,-81.73 438.21,-87.2 436.56,-78.89 431.73,-81.73"/>
77
+ </g>
78
+ <!-- Front -->
79
+ <g id="node8" class="node">
80
+ <title>Front</title>
81
+ <path fill="#7dd3fc" stroke="#334155" stroke-width="1.3" d="M685,-421.24C685,-421.24 542.25,-421.24 542.25,-421.24 536.25,-421.24 530.25,-415.24 530.25,-409.24 530.25,-409.24 530.25,-397.24 530.25,-397.24 530.25,-391.24 536.25,-385.24 542.25,-385.24 542.25,-385.24 685,-385.24 685,-385.24 691,-385.24 697,-391.24 697,-397.24 697,-397.24 697,-409.24 697,-409.24 697,-415.24 691,-421.24 685,-421.24"/>
82
+ <text xml:space="preserve" text-anchor="middle" x="613.62" y="-405.74" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">FFI::{HackRF,RTLSdr,SoapySDR}</text>
83
+ <text xml:space="preserve" text-anchor="middle" x="613.62" y="-393.74" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">inventory · raw I/Q</text>
84
+ </g>
85
+ <!-- SDRhw&#45;&gt;Front -->
86
+ <g id="edge4" class="edge">
87
+ <title>SDRhw&#45;&gt;Front</title>
88
+ <path fill="none" stroke="#38bdf8" stroke-width="1.3" d="M306.43,-193.49C324.75,-222.12 363.68,-277.85 409,-312.24 449.44,-342.92 501.85,-366.04 543.38,-381.3"/>
89
+ <polygon fill="#38bdf8" stroke="#38bdf8" stroke-width="1.3" points="542.27,-383.88 550.75,-383.96 544.17,-378.61 542.27,-383.88"/>
72
90
  </g>
73
91
  <!-- GQRX -->
74
- <g id="node5" class="node">
92
+ <g id="node9" class="node">
75
93
  <title>GQRX</title>
76
- <path fill="#fcd34d" stroke="#334155" stroke-width="1.3" d="M548.75,-283C548.75,-283 455.5,-283 455.5,-283 449.5,-283 443.5,-277 443.5,-271 443.5,-271 443.5,-239 443.5,-239 443.5,-233 449.5,-227 455.5,-227 455.5,-227 548.75,-227 548.75,-227 554.75,-227 560.75,-233 560.75,-239 560.75,-239 560.75,-271 560.75,-271 560.75,-277 554.75,-283 548.75,-283"/>
77
- <text xml:space="preserve" text-anchor="middle" x="502.12" y="-269.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">SDR::GQRX</text>
78
- <text xml:space="preserve" text-anchor="middle" x="502.12" y="-257.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">remote control</text>
79
- <text xml:space="preserve" text-anchor="middle" x="502.12" y="-245.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">spectrum snapshot</text>
80
- <text xml:space="preserve" text-anchor="middle" x="502.12" y="-233.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">(median floor · DC null)</text>
94
+ <path fill="#fcd34d" stroke="#334155" stroke-width="1.3" d="M994.75,-253.24C994.75,-253.24 843.75,-253.24 843.75,-253.24 837.75,-253.24 831.75,-247.24 831.75,-241.24 831.75,-241.24 831.75,-209.24 831.75,-209.24 831.75,-203.24 837.75,-197.24 843.75,-197.24 843.75,-197.24 994.75,-197.24 994.75,-197.24 1000.75,-197.24 1006.75,-203.24 1006.75,-209.24 1006.75,-209.24 1006.75,-241.24 1006.75,-241.24 1006.75,-247.24 1000.75,-253.24 994.75,-253.24"/>
95
+ <text xml:space="preserve" text-anchor="middle" x="919.25" y="-239.74" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">SDR::GQRX</text>
96
+ <text xml:space="preserve" text-anchor="middle" x="919.25" y="-227.74" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">remote control</text>
97
+ <text xml:space="preserve" text-anchor="middle" x="919.25" y="-215.74" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">spectrum + FFT geometry</text>
98
+ <text xml:space="preserve" text-anchor="middle" x="919.25" y="-203.74" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">(RAW panorama · plan&#45;param refine)</text>
81
99
  </g>
82
100
  <!-- SDRhw&#45;&gt;GQRX -->
83
- <g id="edge4" class="edge">
101
+ <g id="edge5" class="edge">
84
102
  <title>SDRhw&#45;&gt;GQRX</title>
85
- <path fill="none" stroke="#f59e0b" stroke-width="1.3" d="M350.39,-262.08C376.41,-260.86 406.72,-259.43 433.31,-258.19"/>
86
- <polygon fill="#f59e0b" stroke="#f59e0b" stroke-width="1.3" points="433.09,-261 440.95,-257.83 432.83,-255.41 433.09,-261"/>
87
- </g>
88
- <!-- Xrf -->
89
- <g id="node10" class="node">
90
- <title>Xrf</title>
91
- <path fill="#c4b5fd" stroke="#334155" stroke-width="1.3" d="M126.5,-112C126.5,-112 28,-112 28,-112 22,-112 16,-106 16,-100 16,-100 16,-88 16,-88 16,-82 22,-76 28,-76 28,-76 126.5,-76 126.5,-76 132.5,-76 138.5,-82 138.5,-88 138.5,-88 138.5,-100 138.5,-100 138.5,-106 132.5,-112 126.5,-112"/>
92
- <text xml:space="preserve" text-anchor="middle" x="77.25" y="-96.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">extro_snapshot :rf</text>
93
- <text xml:space="preserve" text-anchor="middle" x="77.25" y="-84.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">probe_rf → hw inventory</text>
94
- </g>
95
- <!-- SDRhw&#45;&gt;Xrf -->
96
- <g id="edge10" class="edge">
97
- <title>SDRhw&#45;&gt;Xrf</title>
98
- <path fill="none" stroke="#fbbf24" stroke-width="1.3" stroke-dasharray="5,2" d="M223.87,-247.2C221.33,-245.89 218.86,-244.49 216.5,-243 164.82,-210.3 119.75,-153.58 96.03,-120.36"/>
99
- <polygon fill="#fbbf24" stroke="#fbbf24" stroke-width="1.3" points="98.49,-118.99 91.6,-114.05 93.91,-122.21 98.49,-118.99"/>
103
+ <path fill="none" stroke="#f59e0b" stroke-width="1.3" d="M369.54,-168.75C467.22,-161.9 643.79,-155.32 791.75,-181.24 807.64,-184.02 824.21,-188.53 839.92,-193.62"/>
104
+ <polygon fill="#f59e0b" stroke="#f59e0b" stroke-width="1.3" points="838.72,-196.17 847.2,-196.05 840.5,-190.86 838.72,-196.17"/>
100
105
  </g>
101
106
  <!-- Freq -->
102
- <g id="node6" class="node">
107
+ <g id="node10" class="node">
103
108
  <title>Freq</title>
104
- <path fill="#fcd34d" stroke="#334155" stroke-width="1.3" d="M556.25,-351C556.25,-351 448,-351 448,-351 442,-351 436,-345 436,-339 436,-339 436,-327 436,-327 436,-321 442,-315 448,-315 448,-315 556.25,-315 556.25,-315 562.25,-315 568.25,-321 568.25,-327 568.25,-327 568.25,-339 568.25,-339 568.25,-345 562.25,-351 556.25,-351"/>
105
- <text xml:space="preserve" text-anchor="middle" x="502.12" y="-335.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">SDR::FrequencyAllocation</text>
106
- <text xml:space="preserve" text-anchor="middle" x="502.12" y="-323.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">band lookup</text>
109
+ <path fill="#fcd34d" stroke="#334155" stroke-width="1.3" d="M667.75,-253.24C667.75,-253.24 559.5,-253.24 559.5,-253.24 553.5,-253.24 547.5,-247.24 547.5,-241.24 547.5,-241.24 547.5,-221.24 547.5,-221.24 547.5,-215.24 553.5,-209.24 559.5,-209.24 559.5,-209.24 667.75,-209.24 667.75,-209.24 673.75,-209.24 679.75,-215.24 679.75,-221.24 679.75,-221.24 679.75,-241.24 679.75,-241.24 679.75,-247.24 673.75,-253.24 667.75,-253.24"/>
110
+ <text xml:space="preserve" text-anchor="middle" x="613.62" y="-239.74" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">SDR::FrequencyAllocation</text>
111
+ <text xml:space="preserve" text-anchor="middle" x="613.62" y="-227.74" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">band lookup</text>
112
+ <text xml:space="preserve" text-anchor="middle" x="613.62" y="-215.74" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">plan_bw · precision</text>
107
113
  </g>
108
114
  <!-- Flipper&#45;&gt;Freq -->
109
- <g id="edge5" class="edge">
115
+ <g id="edge16" class="edge">
110
116
  <title>Flipper&#45;&gt;Freq</title>
111
- <path fill="none" stroke="#f59e0b" stroke-width="1.3" d="M333.92,-333C360.7,-333 395.22,-333 425.92,-333"/>
112
- <polygon fill="#f59e0b" stroke="#f59e0b" stroke-width="1.3" points="425.77,-335.8 433.77,-333 425.77,-330.2 425.77,-335.8"/>
117
+ <path fill="none" stroke="#f59e0b" stroke-width="1.3" d="M341.06,-125.14C394.7,-146.09 484.01,-180.99 545.47,-205"/>
118
+ <polygon fill="#f59e0b" stroke="#f59e0b" stroke-width="1.3" points="544.41,-207.59 552.88,-207.89 546.45,-202.37 544.41,-207.59"/>
113
119
  </g>
114
120
  <!-- Scan -->
115
- <g id="node7" class="node">
121
+ <g id="node11" class="node">
116
122
  <title>Scan</title>
117
- <path fill="#fcd34d" stroke="#334155" stroke-width="1.3" d="M546.88,-427C546.88,-427 457.38,-427 457.38,-427 451.38,-427 445.38,-421 445.38,-415 445.38,-415 445.38,-395 445.38,-395 445.38,-389 451.38,-383 457.38,-383 457.38,-383 546.88,-383 546.88,-383 552.88,-383 558.88,-389 558.88,-395 558.88,-395 558.88,-415 558.88,-415 558.88,-421 552.88,-427 546.88,-427"/>
118
- <text xml:space="preserve" text-anchor="middle" x="502.12" y="-413.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">bin/pwn_gqrx_scanner</text>
119
- <text xml:space="preserve" text-anchor="middle" x="502.12" y="-401.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">&#45;&#45;fft&#45;scan · iterative</text>
120
- <text xml:space="preserve" text-anchor="middle" x="502.12" y="-389.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">&#45;&#45;min&#45;snr&#45;db · &#45;&#45;avg</text>
123
+ <path fill="#fcd34d" stroke="#334155" stroke-width="1.3" d="M967.38,-165.24C967.38,-165.24 871.12,-165.24 871.12,-165.24 865.12,-165.24 859.12,-159.24 859.12,-153.24 859.12,-153.24 859.12,-133.24 859.12,-133.24 859.12,-127.24 865.12,-121.24 871.12,-121.24 871.12,-121.24 967.38,-121.24 967.38,-121.24 973.38,-121.24 979.38,-127.24 979.38,-133.24 979.38,-133.24 979.38,-153.24 979.38,-153.24 979.38,-159.24 973.38,-165.24 967.38,-165.24"/>
124
+ <text xml:space="preserve" text-anchor="middle" x="919.25" y="-151.74" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">bin/pwn_gqrx_scanner</text>
125
+ <text xml:space="preserve" text-anchor="middle" x="919.25" y="-139.74" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">&#45;&#45;fft&#45;scan · iterative</text>
126
+ <text xml:space="preserve" text-anchor="middle" x="919.25" y="-127.74" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">&#45;&#45;min&#45;snr&#45;db · &#45;&#45;no&#45;refine</text>
121
127
  </g>
122
128
  <!-- RFID&#45;&gt;Scan -->
123
- <g id="edge6" class="edge">
129
+ <g id="edge17" class="edge">
124
130
  <title>RFID&#45;&gt;Scan</title>
125
- <path fill="none" stroke="#f59e0b" stroke-width="1.3" d="M328.29,-401.75C358.34,-402.32 400.16,-403.1 435.13,-403.76"/>
126
- <polygon fill="#f59e0b" stroke="#f59e0b" stroke-width="1.3" points="434.78,-406.55 442.83,-403.9 434.88,-400.95 434.78,-406.55"/>
131
+ <path fill="none" stroke="#f59e0b" stroke-width="1.3" d="M490.9,-110.34C570.68,-116.48 749.66,-130.26 848.82,-137.89"/>
132
+ <polygon fill="#f59e0b" stroke="#f59e0b" stroke-width="1.3" points="848.59,-140.68 856.78,-138.5 849.02,-135.1 848.59,-140.68"/>
133
+ </g>
134
+ <!-- Volk -->
135
+ <g id="node5" class="node">
136
+ <title>Volk</title>
137
+ <path fill="#7dd3fc" stroke="#334155" stroke-width="1.3" d="M978.62,-523.24C978.62,-523.24 859.88,-523.24 859.88,-523.24 853.88,-523.24 847.88,-517.24 847.88,-511.24 847.88,-511.24 847.88,-499.24 847.88,-499.24 847.88,-493.24 853.88,-487.24 859.88,-487.24 859.88,-487.24 978.62,-487.24 978.62,-487.24 984.62,-487.24 990.62,-493.24 990.62,-499.24 990.62,-499.24 990.62,-511.24 990.62,-511.24 990.62,-517.24 984.62,-523.24 978.62,-523.24"/>
138
+ <text xml:space="preserve" text-anchor="middle" x="919.25" y="-507.74" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">FFI::Volk</text>
139
+ <text xml:space="preserve" text-anchor="middle" x="919.25" y="-495.74" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">SIMD s16→f32 · accumulate</text>
140
+ </g>
141
+ <!-- DSP -->
142
+ <g id="node12" class="node">
143
+ <title>DSP</title>
144
+ <path fill="#c4b5fd" stroke="#334155" stroke-width="1.3" d="M1265.12,-698.24C1265.12,-698.24 1158.38,-698.24 1158.38,-698.24 1152.38,-698.24 1146.38,-692.24 1146.38,-686.24 1146.38,-686.24 1146.38,-666.24 1146.38,-666.24 1146.38,-660.24 1152.38,-654.24 1158.38,-654.24 1158.38,-654.24 1265.12,-654.24 1265.12,-654.24 1271.12,-654.24 1277.12,-660.24 1277.12,-666.24 1277.12,-666.24 1277.12,-686.24 1277.12,-686.24 1277.12,-692.24 1271.12,-698.24 1265.12,-698.24"/>
145
+ <text xml:space="preserve" text-anchor="middle" x="1211.75" y="-684.74" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">Decoder::DSP</text>
146
+ <text xml:space="preserve" text-anchor="middle" x="1211.75" y="-672.74" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">pure&#45;Ruby + FFI accel</text>
147
+ <text xml:space="preserve" text-anchor="middle" x="1211.75" y="-660.74" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">(unpack · resample · FSK)</text>
148
+ </g>
149
+ <!-- Volk&#45;&gt;DSP -->
150
+ <g id="edge9" class="edge">
151
+ <title>Volk&#45;&gt;DSP</title>
152
+ <path fill="none" stroke="#a78bfa" stroke-width="1.3" d="M938.5,-523.84C961.86,-546.83 1004.41,-586.01 1046.75,-611.24 1074.65,-627.86 1107.56,-641.86 1136.56,-652.57"/>
153
+ <polygon fill="#a78bfa" stroke="#a78bfa" stroke-width="1.3" points="1135.5,-655.16 1143.98,-655.25 1137.41,-649.89 1135.5,-655.16"/>
154
+ </g>
155
+ <!-- Liquid -->
156
+ <g id="node6" class="node">
157
+ <title>Liquid</title>
158
+ <path fill="#7dd3fc" stroke="#334155" stroke-width="1.3" d="M973,-455.24C973,-455.24 865.5,-455.24 865.5,-455.24 859.5,-455.24 853.5,-449.24 853.5,-443.24 853.5,-443.24 853.5,-431.24 853.5,-431.24 853.5,-425.24 859.5,-419.24 865.5,-419.24 865.5,-419.24 973,-419.24 973,-419.24 979,-419.24 985,-425.24 985,-431.24 985,-431.24 985,-443.24 985,-443.24 985,-449.24 979,-455.24 973,-455.24"/>
159
+ <text xml:space="preserve" text-anchor="middle" x="919.25" y="-439.74" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">FFI::Liquid</text>
160
+ <text xml:space="preserve" text-anchor="middle" x="919.25" y="-427.74" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">freqdem · msresamp · FIR</text>
161
+ </g>
162
+ <!-- Liquid&#45;&gt;DSP -->
163
+ <g id="edge10" class="edge">
164
+ <title>Liquid&#45;&gt;DSP</title>
165
+ <path fill="none" stroke="#a78bfa" stroke-width="1.3" d="M985.37,-451.8C996.22,-456.57 1006.59,-462.88 1014.75,-471.24 1046.17,-503.41 1020.51,-530.71 1046.75,-567.24 1054.39,-577.87 1129.75,-631.15 1140.75,-638.24 1146.42,-641.89 1152.48,-645.53 1158.57,-649.04"/>
166
+ <polygon fill="#a78bfa" stroke="#a78bfa" stroke-width="1.3" points="1156.79,-651.25 1165.14,-652.74 1159.55,-646.37 1156.79,-651.25"/>
167
+ </g>
168
+ <!-- FFTW -->
169
+ <g id="node7" class="node">
170
+ <title>FFTW</title>
171
+ <path fill="#7dd3fc" stroke="#334155" stroke-width="1.3" d="M958,-387.24C958,-387.24 880.5,-387.24 880.5,-387.24 874.5,-387.24 868.5,-381.24 868.5,-375.24 868.5,-375.24 868.5,-363.24 868.5,-363.24 868.5,-357.24 874.5,-351.24 880.5,-351.24 880.5,-351.24 958,-351.24 958,-351.24 964,-351.24 970,-357.24 970,-363.24 970,-363.24 970,-375.24 970,-375.24 970,-381.24 964,-387.24 958,-387.24"/>
172
+ <text xml:space="preserve" text-anchor="middle" x="919.25" y="-371.74" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">FFI::FFTW</text>
173
+ <text xml:space="preserve" text-anchor="middle" x="919.25" y="-359.74" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">rfft · cfft · power&#45;dB</text>
174
+ </g>
175
+ <!-- FFTW&#45;&gt;DSP -->
176
+ <g id="edge11" class="edge">
177
+ <title>FFTW&#45;&gt;DSP</title>
178
+ <path fill="none" stroke="#a78bfa" stroke-width="1.3" d="M970.42,-377.89C986.44,-382.9 1003.03,-390.8 1014.75,-403.24 1049.37,-439.99 1020.37,-469.19 1046.75,-512.24 1064,-540.38 1080.72,-537 1100.75,-563.24 1123.67,-593.27 1114.14,-611.43 1140.75,-638.24 1144.25,-641.77 1148.15,-645.05 1152.27,-648.1"/>
179
+ <polygon fill="#a78bfa" stroke="#a78bfa" stroke-width="1.3" points="1150.59,-650.34 1158.78,-652.54 1153.75,-645.72 1150.59,-650.34"/>
180
+ </g>
181
+ <!-- Front&#45;&gt;Volk -->
182
+ <g id="edge6" class="edge">
183
+ <title>Front&#45;&gt;Volk</title>
184
+ <path fill="none" stroke="#38bdf8" stroke-width="1.3" stroke-dasharray="5,2" d="M669.96,-421.83C721.7,-439.21 798.97,-465.17 853.55,-483.5"/>
185
+ <polygon fill="#38bdf8" stroke="#38bdf8" stroke-width="1.3" points="852.44,-486.08 860.92,-485.98 854.22,-480.77 852.44,-486.08"/>
186
+ </g>
187
+ <!-- Front&#45;&gt;Liquid -->
188
+ <g id="edge7" class="edge">
189
+ <title>Front&#45;&gt;Liquid</title>
190
+ <path fill="none" stroke="#38bdf8" stroke-width="1.3" stroke-dasharray="5,2" d="M697.59,-412.53C743.13,-417.63 799.16,-423.9 843.37,-428.85"/>
191
+ <polygon fill="#38bdf8" stroke="#38bdf8" stroke-width="1.3" points="842.97,-431.62 851.23,-429.73 843.59,-426.06 842.97,-431.62"/>
192
+ </g>
193
+ <!-- Front&#45;&gt;FFTW -->
194
+ <g id="edge8" class="edge">
195
+ <title>Front&#45;&gt;FFTW</title>
196
+ <path fill="none" stroke="#38bdf8" stroke-width="1.3" stroke-dasharray="5,2" d="M697.59,-393.95C748.46,-388.25 812.42,-381.09 858.37,-375.94"/>
197
+ <polygon fill="#38bdf8" stroke="#38bdf8" stroke-width="1.3" points="858.58,-378.74 866.22,-375.06 857.96,-373.17 858.58,-378.74"/>
198
+ </g>
199
+ <!-- Xrf -->
200
+ <g id="node15" class="node">
201
+ <title>Xrf</title>
202
+ <path fill="#c4b5fd" stroke="#334155" stroke-width="1.3" d="M126.5,-678.24C126.5,-678.24 28,-678.24 28,-678.24 22,-678.24 16,-672.24 16,-666.24 16,-666.24 16,-654.24 16,-654.24 16,-648.24 22,-642.24 28,-642.24 28,-642.24 126.5,-642.24 126.5,-642.24 132.5,-642.24 138.5,-648.24 138.5,-654.24 138.5,-654.24 138.5,-666.24 138.5,-666.24 138.5,-672.24 132.5,-678.24 126.5,-678.24"/>
203
+ <text xml:space="preserve" text-anchor="middle" x="77.25" y="-662.74" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">extro_snapshot :rf</text>
204
+ <text xml:space="preserve" text-anchor="middle" x="77.25" y="-650.74" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">probe_rf → hw inventory</text>
205
+ </g>
206
+ <!-- Front&#45;&gt;Xrf -->
207
+ <g id="edge20" class="edge">
208
+ <title>Front&#45;&gt;Xrf</title>
209
+ <path fill="none" stroke="#fbbf24" stroke-width="1.3" stroke-dasharray="5,2" d="M590.92,-384.75C568.08,-365.4 530.97,-334.27 498.25,-308.24 459.23,-277.19 436.22,-282.02 409,-240.24 367.34,-176.29 428.92,-120.5 369,-73.24 314.04,-29.89 266.2,-29.56 211.5,-73.24 122,-144.7 88.07,-524.15 80.17,-631.77"/>
210
+ <polygon fill="#fbbf24" stroke="#fbbf24" stroke-width="1.3" points="77.39,-631.45 79.61,-639.63 82.97,-631.85 77.39,-631.45"/>
211
+ </g>
212
+ <!-- GQRX&#45;&gt;DSP -->
213
+ <g id="edge12" class="edge">
214
+ <title>GQRX&#45;&gt;DSP</title>
215
+ <path fill="none" stroke="#a78bfa" stroke-width="1.3" d="M951.31,-253.71C972.14,-274.42 998.61,-304.18 1014.75,-335.24 1041.39,-386.51 1016.47,-412.03 1046.75,-461.24 1063.43,-488.33 1083.41,-481.56 1100.75,-508.24 1133.7,-558.92 1102.46,-591.46 1140.75,-638.24 1143.54,-641.64 1146.71,-644.78 1150.13,-647.68"/>
216
+ <polygon fill="#a78bfa" stroke="#a78bfa" stroke-width="1.3" points="1148.33,-649.83 1156.4,-652.44 1151.72,-645.37 1148.33,-649.83"/>
217
+ </g>
218
+ <!-- Tune -->
219
+ <g id="node16" class="node">
220
+ <title>Tune</title>
221
+ <path fill="#c4b5fd" stroke="#334155" stroke-width="2" d="M1270.75,-622.61C1270.75,-622.61 1152.75,-622.61 1152.75,-622.61 1146.75,-622.61 1140.75,-616.61 1140.75,-610.61 1140.75,-610.61 1140.75,-589.86 1140.75,-589.86 1140.75,-583.86 1146.75,-577.86 1152.75,-577.86 1152.75,-577.86 1270.75,-577.86 1270.75,-577.86 1276.75,-577.86 1282.75,-583.86 1282.75,-589.86 1282.75,-589.86 1282.75,-610.61 1282.75,-610.61 1282.75,-616.61 1276.75,-622.61 1270.75,-622.61"/>
222
+ <text xml:space="preserve" text-anchor="middle" x="1211.75" y="-609.11" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">extro_rf_tune &#160;📡</text>
223
+ <text xml:space="preserve" text-anchor="middle" x="1211.75" y="-596.36" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">tune · demod · strength</text>
224
+ <text xml:space="preserve" text-anchor="middle" x="1211.75" y="-584.36" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">RDS.sample → now_playing</text>
225
+ </g>
226
+ <!-- GQRX&#45;&gt;Tune -->
227
+ <g id="edge13" class="edge">
228
+ <title>GQRX&#45;&gt;Tune</title>
229
+ <path fill="none" stroke="#f59e0b" stroke-width="2" d="M945.71,-253.7C965.07,-275.63 992.14,-306.89 1014.75,-335.24 1080.25,-417.36 1152.6,-517.97 1188.29,-568.33"/>
230
+ <polygon fill="#f59e0b" stroke="#f59e0b" stroke-width="2" points="1185.86,-569.74 1192.77,-574.66 1190.44,-566.51 1185.86,-569.74"/>
231
+ <text xml:space="preserve" text-anchor="middle" x="1073.75" y="-444.93" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#cbd5e1">remote :7356</text>
232
+ </g>
233
+ <!-- Freq&#45;&gt;Scan -->
234
+ <g id="edge18" class="edge">
235
+ <title>Freq&#45;&gt;Scan</title>
236
+ <path fill="none" stroke="#f59e0b" stroke-width="1.3" d="M680.13,-212.25C729.92,-197.82 798.25,-178.02 848.95,-163.32"/>
237
+ <polygon fill="#f59e0b" stroke="#f59e0b" stroke-width="1.3" points="849.73,-166.01 856.63,-161.1 848.17,-160.63 849.73,-166.01"/>
238
+ <text xml:space="preserve" text-anchor="middle" x="764.38" y="-197.07" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#cbd5e1">plan_bw/step</text>
127
239
  </g>
128
240
  <!-- Dec -->
129
- <g id="node8" class="node">
241
+ <g id="node13" class="node">
130
242
  <title>Dec</title>
131
- <path fill="#c4b5fd" stroke="#334155" stroke-width="1.3" d="M802.25,-96C802.25,-96 666.25,-96 666.25,-96 660.25,-96 654.25,-90 654.25,-84 654.25,-84 654.25,-28 654.25,-28 654.25,-22 660.25,-16 666.25,-16 666.25,-16 802.25,-16 802.25,-16 808.25,-16 814.25,-22 814.25,-28 814.25,-28 814.25,-84 814.25,-84 814.25,-90 808.25,-96 802.25,-96"/>
132
- <text xml:space="preserve" text-anchor="middle" x="734.25" y="-82.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">SDR::Decoder::*</text>
133
- <text xml:space="preserve" text-anchor="middle" x="734.25" y="-70.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">ADSB · APT · BT · DECT · GPS</text>
134
- <text xml:space="preserve" text-anchor="middle" x="734.25" y="-58.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">GSM · Iridium · LoRa · LTE</text>
135
- <text xml:space="preserve" text-anchor="middle" x="734.25" y="-46.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">Morse · P25 · POCSAG/FLEX</text>
136
- <text xml:space="preserve" text-anchor="middle" x="734.25" y="-34.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">RDS · RFID · rtl_433 · RTTY</text>
137
- <text xml:space="preserve" text-anchor="middle" x="734.25" y="-22.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">WiFi · ZigBee</text>
138
- </g>
139
- <!-- GQRX&#45;&gt;Dec -->
140
- <g id="edge7" class="edge">
141
- <title>GQRX&#45;&gt;Dec</title>
142
- <path fill="none" stroke="#a78bfa" stroke-width="1.3" d="M561.17,-233.24C566.51,-230.18 571.64,-226.77 576.25,-223 622.93,-184.83 611.7,-154.72 654.25,-112 657.34,-108.9 660.61,-105.85 664,-102.88"/>
143
- <polygon fill="#a78bfa" stroke="#a78bfa" stroke-width="1.3" points="665.77,-105.05 670.09,-97.76 662.16,-100.77 665.77,-105.05"/>
243
+ <path fill="#c4b5fd" stroke="#334155" stroke-width="1.3" d="M1562.5,-658.24C1562.5,-658.24 1426.5,-658.24 1426.5,-658.24 1420.5,-658.24 1414.5,-652.24 1414.5,-646.24 1414.5,-646.24 1414.5,-590.24 1414.5,-590.24 1414.5,-584.24 1420.5,-578.24 1426.5,-578.24 1426.5,-578.24 1562.5,-578.24 1562.5,-578.24 1568.5,-578.24 1574.5,-584.24 1574.5,-590.24 1574.5,-590.24 1574.5,-646.24 1574.5,-646.24 1574.5,-652.24 1568.5,-658.24 1562.5,-658.24"/>
244
+ <text xml:space="preserve" text-anchor="middle" x="1494.5" y="-644.74" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">SDR::Decoder::*</text>
245
+ <text xml:space="preserve" text-anchor="middle" x="1494.5" y="-632.74" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">ADSB · APT · BT · DECT · GPS</text>
246
+ <text xml:space="preserve" text-anchor="middle" x="1494.5" y="-620.74" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">GSM · Iridium · LoRa · LTE</text>
247
+ <text xml:space="preserve" text-anchor="middle" x="1494.5" y="-608.74" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">Morse · P25 · POCSAG/FLEX</text>
248
+ <text xml:space="preserve" text-anchor="middle" x="1494.5" y="-596.74" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">RDS · RFID · rtl_433 · RTTY</text>
249
+ <text xml:space="preserve" text-anchor="middle" x="1494.5" y="-584.74" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">WiFi · ZigBee</text>
144
250
  </g>
145
251
  <!-- Freq&#45;&gt;Dec -->
146
- <g id="edge8" class="edge">
252
+ <g id="edge15" class="edge">
147
253
  <title>Freq&#45;&gt;Dec</title>
148
- <path fill="none" stroke="#a78bfa" stroke-width="1.3" d="M568.68,-316.86C571.37,-315.1 573.91,-313.16 576.25,-311 646.1,-246.61 595.72,-186.82 654.25,-112 656.7,-108.87 659.37,-105.84 662.19,-102.92"/>
149
- <polygon fill="#a78bfa" stroke="#a78bfa" stroke-width="1.3" points="663.82,-105.25 667.64,-97.68 659.93,-101.22 663.82,-105.25"/>
254
+ <path fill="none" stroke="#a78bfa" stroke-width="1.3" d="M680.13,-245.67C759.96,-263.85 898.58,-297.33 1014.75,-335.24 1179.42,-388.97 1348.41,-506.37 1434.79,-571.82"/>
255
+ <polygon fill="#a78bfa" stroke="#a78bfa" stroke-width="1.3" points="1433.01,-573.98 1441.07,-576.6 1436.4,-569.53 1433.01,-573.98"/>
150
256
  </g>
151
257
  <!-- Obs -->
152
- <g id="node9" class="node">
258
+ <g id="node14" class="node">
153
259
  <title>Obs</title>
154
- <path fill="#c4b5fd" stroke="#334155" stroke-width="1.3" d="M768.5,-172C768.5,-172 700,-172 700,-172 694,-172 688,-166 688,-160 688,-160 688,-140 688,-140 688,-134 694,-128 700,-128 700,-128 768.5,-128 768.5,-128 774.5,-128 780.5,-134 780.5,-140 780.5,-140 780.5,-160 780.5,-160 780.5,-166 774.5,-172 768.5,-172"/>
155
- <text xml:space="preserve" text-anchor="middle" x="734.25" y="-158.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">extro_observe</text>
156
- <text xml:space="preserve" text-anchor="middle" x="734.25" y="-146.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">category: :rf</text>
157
- <text xml:space="preserve" text-anchor="middle" x="734.25" y="-134.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">record signal intel</text>
260
+ <path fill="#c4b5fd" stroke="#334155" stroke-width="1.3" d="M1721,-636.24C1721,-636.24 1667.5,-636.24 1667.5,-636.24 1661.5,-636.24 1655.5,-630.24 1655.5,-624.24 1655.5,-624.24 1655.5,-612.24 1655.5,-612.24 1655.5,-606.24 1661.5,-600.24 1667.5,-600.24 1667.5,-600.24 1721,-600.24 1721,-600.24 1727,-600.24 1733,-606.24 1733,-612.24 1733,-612.24 1733,-624.24 1733,-624.24 1733,-630.24 1727,-636.24 1721,-636.24"/>
261
+ <text xml:space="preserve" text-anchor="middle" x="1694.25" y="-620.74" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">extro_observe</text>
262
+ <text xml:space="preserve" text-anchor="middle" x="1694.25" y="-608.74" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#0f172a">category: :rf</text>
158
263
  </g>
159
264
  <!-- Scan&#45;&gt;Obs -->
160
- <g id="edge9" class="edge">
265
+ <g id="edge19" class="edge">
161
266
  <title>Scan&#45;&gt;Obs</title>
162
- <path fill="none" stroke="#a78bfa" stroke-width="1.3" d="M559.35,-389.21C565.35,-386.32 571.12,-382.94 576.25,-379 646.6,-324.88 696.97,-230.14 719.71,-181.21"/>
163
- <polygon fill="#a78bfa" stroke="#a78bfa" stroke-width="1.3" points="722.17,-182.58 722.94,-174.14 717.07,-180.25 722.17,-182.58"/>
267
+ <path fill="none" stroke="#a78bfa" stroke-width="1.3" d="M980,-165.26C991.71,-170.13 1003.76,-175.55 1014.75,-181.24 1275.96,-316.32 1564.92,-523.64 1660.56,-593.95"/>
268
+ <polygon fill="#a78bfa" stroke="#a78bfa" stroke-width="1.3" points="1658.74,-596.09 1666.84,-598.58 1662.06,-591.58 1658.74,-596.09"/>
269
+ </g>
270
+ <!-- DSP&#45;&gt;Dec -->
271
+ <g id="edge14" class="edge">
272
+ <title>DSP&#45;&gt;Dec</title>
273
+ <path fill="none" stroke="#a78bfa" stroke-width="1.3" d="M1277.51,-662.86C1315.14,-655.08 1363.1,-645.18 1404.27,-636.67"/>
274
+ <polygon fill="#a78bfa" stroke="#a78bfa" stroke-width="1.3" points="1404.83,-639.41 1412.1,-635.05 1403.7,-633.93 1404.83,-639.41"/>
275
+ </g>
276
+ <!-- Dec&#45;&gt;Obs -->
277
+ <g id="edge21" class="edge">
278
+ <title>Dec&#45;&gt;Obs</title>
279
+ <path fill="none" stroke="#c4b5fd" stroke-width="1.3" stroke-dasharray="5,2" d="M1575.08,-618.24C1598.89,-618.24 1624.25,-618.24 1645.35,-618.24"/>
280
+ <polygon fill="#c4b5fd" stroke="#c4b5fd" stroke-width="1.3" points="1645.07,-621.04 1653.07,-618.24 1645.07,-615.44 1645.07,-621.04"/>
281
+ </g>
282
+ <!-- Tune&#45;&gt;Dec -->
283
+ <g id="edge23" class="edge">
284
+ <title>Tune&#45;&gt;Dec</title>
285
+ <path fill="none" stroke="#c4b5fd" stroke-width="1.3" stroke-dasharray="5,2" d="M1283.6,-604.78C1320.21,-607.13 1365.27,-610.02 1404.24,-612.51"/>
286
+ <polygon fill="#c4b5fd" stroke="#c4b5fd" stroke-width="1.3" points="1403.88,-615.3 1412.04,-613.01 1404.24,-609.71 1403.88,-615.3"/>
287
+ <text xml:space="preserve" text-anchor="middle" x="1348.62" y="-612.26" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#cbd5e1">RDS.sample</text>
288
+ </g>
289
+ <!-- Tune&#45;&gt;Obs -->
290
+ <g id="edge22" class="edge">
291
+ <title>Tune&#45;&gt;Obs</title>
292
+ <path fill="none" stroke="#a78bfa" stroke-width="2" d="M1261.15,-623.48C1301.2,-641.36 1360.14,-664.58 1414.5,-674.24 1484.52,-686.67 1505.11,-689.78 1574.5,-674.24 1602.59,-667.94 1631.87,-654.23 1654.33,-641.95"/>
293
+ <polygon fill="#a78bfa" stroke="#a78bfa" stroke-width="2" points="1655.58,-644.46 1661.18,-638.1 1652.84,-639.57 1655.58,-644.46"/>
294
+ <text xml:space="preserve" text-anchor="middle" x="1494.5" y="-697.21" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#cbd5e1">category::rf</text>
295
+ <text xml:space="preserve" text-anchor="middle" x="1494.5" y="-686.71" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#cbd5e1">ttl 300s</text>
164
296
  </g>
165
297
  </g>
166
298
  </svg>