oscura 0.7.0__py3-none-any.whl → 0.10.0__py3-none-any.whl

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 (175) hide show
  1. oscura/__init__.py +19 -19
  2. oscura/analyzers/__init__.py +2 -0
  3. oscura/analyzers/digital/extraction.py +2 -3
  4. oscura/analyzers/digital/quality.py +1 -1
  5. oscura/analyzers/digital/timing.py +1 -1
  6. oscura/analyzers/eye/__init__.py +5 -1
  7. oscura/analyzers/eye/generation.py +501 -0
  8. oscura/analyzers/jitter/__init__.py +6 -6
  9. oscura/analyzers/jitter/timing.py +419 -0
  10. oscura/analyzers/patterns/__init__.py +94 -0
  11. oscura/analyzers/patterns/reverse_engineering.py +991 -0
  12. oscura/analyzers/power/__init__.py +35 -12
  13. oscura/analyzers/power/basic.py +3 -3
  14. oscura/analyzers/power/soa.py +1 -1
  15. oscura/analyzers/power/switching.py +3 -3
  16. oscura/analyzers/signal_classification.py +529 -0
  17. oscura/analyzers/signal_integrity/sparams.py +3 -3
  18. oscura/analyzers/statistics/__init__.py +4 -0
  19. oscura/analyzers/statistics/basic.py +152 -0
  20. oscura/analyzers/statistics/correlation.py +47 -6
  21. oscura/analyzers/validation.py +1 -1
  22. oscura/analyzers/waveform/__init__.py +2 -0
  23. oscura/analyzers/waveform/measurements.py +329 -163
  24. oscura/analyzers/waveform/measurements_with_uncertainty.py +91 -35
  25. oscura/analyzers/waveform/spectral.py +498 -54
  26. oscura/api/dsl/commands.py +15 -6
  27. oscura/api/server/templates/base.html +137 -146
  28. oscura/api/server/templates/export.html +84 -110
  29. oscura/api/server/templates/home.html +248 -267
  30. oscura/api/server/templates/protocols.html +44 -48
  31. oscura/api/server/templates/reports.html +27 -35
  32. oscura/api/server/templates/session_detail.html +68 -78
  33. oscura/api/server/templates/sessions.html +62 -72
  34. oscura/api/server/templates/waveforms.html +54 -64
  35. oscura/automotive/__init__.py +1 -1
  36. oscura/automotive/can/session.py +1 -1
  37. oscura/automotive/dbc/generator.py +638 -23
  38. oscura/automotive/dtc/data.json +102 -17
  39. oscura/automotive/uds/decoder.py +99 -6
  40. oscura/cli/analyze.py +8 -2
  41. oscura/cli/batch.py +36 -5
  42. oscura/cli/characterize.py +18 -4
  43. oscura/cli/export.py +47 -5
  44. oscura/cli/main.py +2 -0
  45. oscura/cli/onboarding/wizard.py +10 -6
  46. oscura/cli/pipeline.py +585 -0
  47. oscura/cli/visualize.py +6 -4
  48. oscura/convenience.py +400 -32
  49. oscura/core/config/loader.py +0 -1
  50. oscura/core/measurement_result.py +286 -0
  51. oscura/core/progress.py +1 -1
  52. oscura/core/schemas/device_mapping.json +8 -2
  53. oscura/core/schemas/packet_format.json +24 -4
  54. oscura/core/schemas/protocol_definition.json +12 -2
  55. oscura/core/types.py +300 -199
  56. oscura/correlation/multi_protocol.py +1 -1
  57. oscura/export/legacy/__init__.py +11 -0
  58. oscura/export/legacy/wav.py +75 -0
  59. oscura/exporters/__init__.py +19 -0
  60. oscura/exporters/wireshark.py +809 -0
  61. oscura/hardware/acquisition/file.py +5 -19
  62. oscura/hardware/acquisition/saleae.py +10 -10
  63. oscura/hardware/acquisition/socketcan.py +4 -6
  64. oscura/hardware/acquisition/synthetic.py +1 -5
  65. oscura/hardware/acquisition/visa.py +6 -6
  66. oscura/hardware/security/side_channel_detector.py +5 -508
  67. oscura/inference/message_format.py +686 -1
  68. oscura/jupyter/display.py +2 -2
  69. oscura/jupyter/magic.py +3 -3
  70. oscura/loaders/__init__.py +17 -12
  71. oscura/loaders/binary.py +1 -1
  72. oscura/loaders/chipwhisperer.py +1 -2
  73. oscura/loaders/configurable.py +1 -1
  74. oscura/loaders/csv_loader.py +2 -2
  75. oscura/loaders/hdf5_loader.py +1 -1
  76. oscura/loaders/lazy.py +6 -1
  77. oscura/loaders/mmap_loader.py +0 -1
  78. oscura/loaders/numpy_loader.py +8 -7
  79. oscura/loaders/preprocessing.py +3 -5
  80. oscura/loaders/rigol.py +21 -7
  81. oscura/loaders/sigrok.py +2 -5
  82. oscura/loaders/tdms.py +3 -2
  83. oscura/loaders/tektronix.py +38 -32
  84. oscura/loaders/tss.py +20 -27
  85. oscura/loaders/vcd.py +13 -8
  86. oscura/loaders/wav.py +1 -6
  87. oscura/pipeline/__init__.py +76 -0
  88. oscura/pipeline/handlers/__init__.py +165 -0
  89. oscura/pipeline/handlers/analyzers.py +1045 -0
  90. oscura/pipeline/handlers/decoders.py +899 -0
  91. oscura/pipeline/handlers/exporters.py +1103 -0
  92. oscura/pipeline/handlers/filters.py +891 -0
  93. oscura/pipeline/handlers/loaders.py +640 -0
  94. oscura/pipeline/handlers/transforms.py +768 -0
  95. oscura/reporting/__init__.py +88 -1
  96. oscura/reporting/automation.py +348 -0
  97. oscura/reporting/citations.py +374 -0
  98. oscura/reporting/core.py +54 -0
  99. oscura/reporting/formatting/__init__.py +11 -0
  100. oscura/reporting/formatting/measurements.py +320 -0
  101. oscura/reporting/html.py +57 -0
  102. oscura/reporting/interpretation.py +431 -0
  103. oscura/reporting/summary.py +329 -0
  104. oscura/reporting/templates/enhanced/protocol_re.html +504 -503
  105. oscura/reporting/visualization.py +542 -0
  106. oscura/side_channel/__init__.py +38 -57
  107. oscura/utils/builders/signal_builder.py +5 -5
  108. oscura/utils/comparison/compare.py +7 -9
  109. oscura/utils/comparison/golden.py +1 -1
  110. oscura/utils/filtering/convenience.py +2 -2
  111. oscura/utils/math/arithmetic.py +38 -62
  112. oscura/utils/math/interpolation.py +20 -20
  113. oscura/utils/pipeline/__init__.py +4 -17
  114. oscura/utils/progressive.py +1 -4
  115. oscura/utils/triggering/edge.py +1 -1
  116. oscura/utils/triggering/pattern.py +2 -2
  117. oscura/utils/triggering/pulse.py +2 -2
  118. oscura/utils/triggering/window.py +3 -3
  119. oscura/validation/hil_testing.py +11 -11
  120. oscura/visualization/__init__.py +47 -284
  121. oscura/visualization/batch.py +160 -0
  122. oscura/visualization/plot.py +542 -53
  123. oscura/visualization/styles.py +184 -318
  124. oscura/workflows/__init__.py +2 -0
  125. oscura/workflows/batch/advanced.py +1 -1
  126. oscura/workflows/batch/aggregate.py +7 -8
  127. oscura/workflows/complete_re.py +251 -23
  128. oscura/workflows/digital.py +27 -4
  129. oscura/workflows/multi_trace.py +136 -17
  130. oscura/workflows/waveform.py +788 -0
  131. {oscura-0.7.0.dist-info → oscura-0.10.0.dist-info}/METADATA +59 -79
  132. {oscura-0.7.0.dist-info → oscura-0.10.0.dist-info}/RECORD +135 -149
  133. oscura/side_channel/dpa.py +0 -1025
  134. oscura/utils/optimization/__init__.py +0 -19
  135. oscura/utils/optimization/parallel.py +0 -443
  136. oscura/utils/optimization/search.py +0 -532
  137. oscura/utils/pipeline/base.py +0 -338
  138. oscura/utils/pipeline/composition.py +0 -248
  139. oscura/utils/pipeline/parallel.py +0 -449
  140. oscura/utils/pipeline/pipeline.py +0 -375
  141. oscura/utils/search/__init__.py +0 -16
  142. oscura/utils/search/anomaly.py +0 -424
  143. oscura/utils/search/context.py +0 -294
  144. oscura/utils/search/pattern.py +0 -288
  145. oscura/utils/storage/__init__.py +0 -61
  146. oscura/utils/storage/database.py +0 -1166
  147. oscura/visualization/accessibility.py +0 -526
  148. oscura/visualization/annotations.py +0 -371
  149. oscura/visualization/axis_scaling.py +0 -305
  150. oscura/visualization/colors.py +0 -451
  151. oscura/visualization/digital.py +0 -436
  152. oscura/visualization/eye.py +0 -571
  153. oscura/visualization/histogram.py +0 -281
  154. oscura/visualization/interactive.py +0 -1035
  155. oscura/visualization/jitter.py +0 -1042
  156. oscura/visualization/keyboard.py +0 -394
  157. oscura/visualization/layout.py +0 -400
  158. oscura/visualization/optimization.py +0 -1079
  159. oscura/visualization/palettes.py +0 -446
  160. oscura/visualization/power.py +0 -508
  161. oscura/visualization/power_extended.py +0 -955
  162. oscura/visualization/presets.py +0 -469
  163. oscura/visualization/protocols.py +0 -1246
  164. oscura/visualization/render.py +0 -223
  165. oscura/visualization/rendering.py +0 -444
  166. oscura/visualization/reverse_engineering.py +0 -838
  167. oscura/visualization/signal_integrity.py +0 -989
  168. oscura/visualization/specialized.py +0 -643
  169. oscura/visualization/spectral.py +0 -1226
  170. oscura/visualization/thumbnails.py +0 -340
  171. oscura/visualization/time_axis.py +0 -351
  172. oscura/visualization/waveform.py +0 -454
  173. {oscura-0.7.0.dist-info → oscura-0.10.0.dist-info}/WHEEL +0 -0
  174. {oscura-0.7.0.dist-info → oscura-0.10.0.dist-info}/entry_points.txt +0 -0
  175. {oscura-0.7.0.dist-info → oscura-0.10.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,525 +1,526 @@
1
- <!DOCTYPE html>
1
+ <!doctype html>
2
2
  <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>{{ title }}</title>
7
7
  <script src="https://cdn.plot.ly/plotly-2.27.0.min.js"></script>
8
8
  <style>
9
- :root {
10
- --bg-color: {{ theme.background_color }};
11
- --text-color: {{ theme.text_color }};
12
- --primary-color: {{ theme.primary_color }};
13
- --secondary-color: {{ theme.secondary_color }};
14
- --border-color: {{ theme.border_color }};
15
- --code-bg: {{ theme.code_background }};
16
- }
17
-
18
- * {
19
- box-sizing: border-box;
20
- margin: 0;
21
- padding: 0;
22
- }
23
-
24
- body {
25
- font-family: 'Segoe UI', -apple-system, BlinkMacSystemFont, Roboto, sans-serif;
26
- line-height: 1.6;
27
- background-color: var(--bg-color);
28
- color: var(--text-color);
29
- padding: 0;
30
- }
31
-
32
- .container {
33
- max-width: 1400px;
34
- margin: 0 auto;
35
- padding: 40px 20px;
36
- }
37
-
38
- /* Header */
39
- .header {
40
- background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
41
- color: white;
42
- padding: 60px 40px;
43
- margin: -40px -20px 40px -20px;
44
- box-shadow: 0 4px 6px rgba(0,0,0,0.1);
45
- }
46
-
47
- .header h1 {
48
- font-size: 2.5rem;
49
- margin-bottom: 10px;
50
- font-weight: 600;
51
- }
52
-
53
- .header .meta {
54
- opacity: 0.9;
55
- font-size: 0.95rem;
56
- }
57
-
58
- /* Table of Contents */
59
- .toc {
60
- background: var(--code-bg);
61
- border-left: 4px solid var(--primary-color);
62
- padding: 20px;
63
- margin: 30px 0;
64
- border-radius: 4px;
65
- }
66
-
67
- .toc h2 {
68
- margin-bottom: 15px;
69
- font-size: 1.3rem;
70
- }
71
-
72
- .toc ul {
73
- list-style: none;
74
- }
75
-
76
- .toc li {
77
- margin: 8px 0;
78
- }
79
-
80
- .toc a {
81
- color: var(--secondary-color);
82
- text-decoration: none;
83
- transition: color 0.2s;
84
- }
85
-
86
- .toc a:hover {
87
- color: var(--primary-color);
88
- text-decoration: underline;
89
- }
90
-
91
- /* Sections */
92
- .section {
93
- margin: 50px 0;
94
- scroll-margin-top: 20px;
95
- }
96
-
97
- .section h2 {
98
- color: var(--primary-color);
99
- border-bottom: 3px solid var(--primary-color);
100
- padding-bottom: 12px;
101
- margin-bottom: 25px;
102
- font-size: 1.8rem;
103
- }
104
-
105
- .section h3 {
106
- color: var(--secondary-color);
107
- margin-top: 30px;
108
- margin-bottom: 15px;
109
- font-size: 1.4rem;
110
- }
111
-
112
- /* Cards */
113
- .card {
114
- background: var(--code-bg);
115
- border: 1px solid var(--border-color);
116
- border-radius: 8px;
117
- padding: 25px;
118
- margin: 20px 0;
119
- box-shadow: 0 2px 4px rgba(0,0,0,0.05);
120
- }
121
-
122
- .card-header {
123
- font-weight: 600;
124
- color: var(--primary-color);
125
- margin-bottom: 15px;
126
- font-size: 1.1rem;
127
- }
128
-
129
- /* Tables */
130
- table {
131
- width: 100%;
132
- border-collapse: collapse;
133
- margin: 20px 0;
134
- background: white;
135
- box-shadow: 0 2px 4px rgba(0,0,0,0.05);
136
- }
137
-
138
- th {
139
- background: var(--primary-color);
140
- color: white;
141
- padding: 15px;
142
- text-align: left;
143
- font-weight: 600;
144
- }
145
-
146
- td {
147
- padding: 12px 15px;
148
- border-bottom: 1px solid var(--border-color);
149
- }
150
-
151
- tr:nth-child(even) {
152
- background-color: rgba(0,0,0,0.02);
153
- }
154
-
155
- tr:hover {
156
- background-color: rgba(0,0,0,0.05);
157
- }
158
-
159
- /* Badges */
160
- .badge {
161
- display: inline-block;
162
- padding: 4px 12px;
163
- border-radius: 12px;
164
- font-size: 0.85rem;
165
- font-weight: 600;
166
- }
167
-
168
- .badge-success {
169
- background: #d4edda;
170
- color: #155724;
171
- }
172
-
173
- .badge-warning {
174
- background: #fff3cd;
175
- color: #856404;
176
- }
177
-
178
- .badge-danger {
179
- background: #f8d7da;
180
- color: #721c24;
181
- }
182
-
183
- /* Warnings */
184
- .warning {
185
- background: #fff3cd;
186
- border-left: 4px solid #ffc107;
187
- padding: 15px;
188
- margin: 15px 0;
189
- border-radius: 4px;
190
- }
191
-
192
- .warning::before {
193
- content: "⚠ ";
194
- font-weight: bold;
195
- }
196
-
197
- /* Plots */
198
- .plot-container {
199
- margin: 30px 0;
200
- padding: 20px;
201
- background: white;
202
- border-radius: 8px;
203
- box-shadow: 0 2px 8px rgba(0,0,0,0.1);
204
- }
205
-
206
- .plot-title {
207
- font-size: 1.2rem;
208
- font-weight: 600;
209
- margin-bottom: 15px;
210
- color: var(--primary-color);
211
- }
212
-
213
- .plot-container img {
214
- max-width: 100%;
215
- height: auto;
216
- display: block;
217
- margin: 0 auto;
218
- }
219
-
220
- /* Artifacts List */
221
- .artifacts-list {
222
- list-style: none;
223
- padding: 0;
224
- }
225
-
226
- .artifacts-list li {
227
- background: var(--code-bg);
228
- padding: 15px;
229
- margin: 10px 0;
230
- border-left: 4px solid var(--secondary-color);
231
- border-radius: 4px;
232
- }
233
-
234
- .artifacts-list strong {
235
- color: var(--primary-color);
236
- }
237
-
238
- /* Metrics Grid */
239
- .metrics-grid {
240
- display: grid;
241
- grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
242
- gap: 20px;
243
- margin: 20px 0;
244
- }
245
-
246
- .metric-card {
247
- background: var(--code-bg);
248
- padding: 20px;
249
- border-radius: 8px;
250
- text-align: center;
251
- border: 1px solid var(--border-color);
252
- }
253
-
254
- .metric-value {
255
- font-size: 2rem;
256
- font-weight: 700;
257
- color: var(--primary-color);
258
- margin: 10px 0;
259
- }
260
-
261
- .metric-label {
262
- font-size: 0.9rem;
263
- color: var(--text-color);
264
- opacity: 0.8;
265
- }
266
-
267
- /* Code blocks */
268
- code {
269
- background: var(--code-bg);
270
- padding: 2px 6px;
271
- border-radius: 3px;
272
- font-family: 'Consolas', 'Monaco', monospace;
273
- font-size: 0.9em;
274
- }
275
-
276
- /* Responsive */
277
- @media (max-width: 768px) {
278
- .header {
279
- padding: 40px 20px;
280
- }
281
-
282
- .header h1 {
283
- font-size: 2rem;
284
- }
285
-
286
- .section h2 {
287
- font-size: 1.5rem;
288
- }
289
-
290
- .metrics-grid {
291
- grid-template-columns: 1fr;
292
- }
293
- }
294
-
295
- /* Print styles */
296
- @media print {
297
- .header {
298
- background: white !important;
299
- color: black !important;
300
- box-shadow: none !important;
301
- }
302
-
303
- .toc {
304
- display: none;
305
- }
306
-
307
- .section {
308
- page-break-inside: avoid;
309
- }
310
- }
9
+ :root {
10
+ --bg-color: {{ theme.background_color }};
11
+ --text-color: {{ theme.text_color }};
12
+ --primary-color: {{ theme.primary_color }};
13
+ --secondary-color: {{ theme.secondary_color }};
14
+ --border-color: {{ theme.border_color }};
15
+ --code-bg: {{ theme.code_background }};
16
+ }
17
+
18
+ * {
19
+ box-sizing: border-box;
20
+ margin: 0;
21
+ padding: 0;
22
+ }
23
+
24
+ body {
25
+ font-family: 'Segoe UI', -apple-system, BlinkMacSystemFont, Roboto, sans-serif;
26
+ line-height: 1.6;
27
+ background-color: var(--bg-color);
28
+ color: var(--text-color);
29
+ padding: 0;
30
+ }
31
+
32
+ .container {
33
+ max-width: 1400px;
34
+ margin: 0 auto;
35
+ padding: 40px 20px;
36
+ }
37
+
38
+ /* Header */
39
+ .header {
40
+ background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
41
+ color: white;
42
+ padding: 60px 40px;
43
+ margin: -40px -20px 40px -20px;
44
+ box-shadow: 0 4px 6px rgba(0,0,0,0.1);
45
+ }
46
+
47
+ .header h1 {
48
+ font-size: 2.5rem;
49
+ margin-bottom: 10px;
50
+ font-weight: 600;
51
+ }
52
+
53
+ .header .meta {
54
+ opacity: 0.9;
55
+ font-size: 0.95rem;
56
+ }
57
+
58
+ /* Table of Contents */
59
+ .toc {
60
+ background: var(--code-bg);
61
+ border-left: 4px solid var(--primary-color);
62
+ padding: 20px;
63
+ margin: 30px 0;
64
+ border-radius: 4px;
65
+ }
66
+
67
+ .toc h2 {
68
+ margin-bottom: 15px;
69
+ font-size: 1.3rem;
70
+ }
71
+
72
+ .toc ul {
73
+ list-style: none;
74
+ }
75
+
76
+ .toc li {
77
+ margin: 8px 0;
78
+ }
79
+
80
+ .toc a {
81
+ color: var(--secondary-color);
82
+ text-decoration: none;
83
+ transition: color 0.2s;
84
+ }
85
+
86
+ .toc a:hover {
87
+ color: var(--primary-color);
88
+ text-decoration: underline;
89
+ }
90
+
91
+ /* Sections */
92
+ .section {
93
+ margin: 50px 0;
94
+ scroll-margin-top: 20px;
95
+ }
96
+
97
+ .section h2 {
98
+ color: var(--primary-color);
99
+ border-bottom: 3px solid var(--primary-color);
100
+ padding-bottom: 12px;
101
+ margin-bottom: 25px;
102
+ font-size: 1.8rem;
103
+ }
104
+
105
+ .section h3 {
106
+ color: var(--secondary-color);
107
+ margin-top: 30px;
108
+ margin-bottom: 15px;
109
+ font-size: 1.4rem;
110
+ }
111
+
112
+ /* Cards */
113
+ .card {
114
+ background: var(--code-bg);
115
+ border: 1px solid var(--border-color);
116
+ border-radius: 8px;
117
+ padding: 25px;
118
+ margin: 20px 0;
119
+ box-shadow: 0 2px 4px rgba(0,0,0,0.05);
120
+ }
121
+
122
+ .card-header {
123
+ font-weight: 600;
124
+ color: var(--primary-color);
125
+ margin-bottom: 15px;
126
+ font-size: 1.1rem;
127
+ }
128
+
129
+ /* Tables */
130
+ table {
131
+ width: 100%;
132
+ border-collapse: collapse;
133
+ margin: 20px 0;
134
+ background: white;
135
+ box-shadow: 0 2px 4px rgba(0,0,0,0.05);
136
+ }
137
+
138
+ th {
139
+ background: var(--primary-color);
140
+ color: white;
141
+ padding: 15px;
142
+ text-align: left;
143
+ font-weight: 600;
144
+ }
145
+
146
+ td {
147
+ padding: 12px 15px;
148
+ border-bottom: 1px solid var(--border-color);
149
+ }
150
+
151
+ tr:nth-child(even) {
152
+ background-color: rgba(0,0,0,0.02);
153
+ }
154
+
155
+ tr:hover {
156
+ background-color: rgba(0,0,0,0.05);
157
+ }
158
+
159
+ /* Badges */
160
+ .badge {
161
+ display: inline-block;
162
+ padding: 4px 12px;
163
+ border-radius: 12px;
164
+ font-size: 0.85rem;
165
+ font-weight: 600;
166
+ }
167
+
168
+ .badge-success {
169
+ background: #d4edda;
170
+ color: #155724;
171
+ }
172
+
173
+ .badge-warning {
174
+ background: #fff3cd;
175
+ color: #856404;
176
+ }
177
+
178
+ .badge-danger {
179
+ background: #f8d7da;
180
+ color: #721c24;
181
+ }
182
+
183
+ /* Warnings */
184
+ .warning {
185
+ background: #fff3cd;
186
+ border-left: 4px solid #ffc107;
187
+ padding: 15px;
188
+ margin: 15px 0;
189
+ border-radius: 4px;
190
+ }
191
+
192
+ .warning::before {
193
+ content: "⚠ ";
194
+ font-weight: bold;
195
+ }
196
+
197
+ /* Plots */
198
+ .plot-container {
199
+ margin: 30px 0;
200
+ padding: 20px;
201
+ background: white;
202
+ border-radius: 8px;
203
+ box-shadow: 0 2px 8px rgba(0,0,0,0.1);
204
+ }
205
+
206
+ .plot-title {
207
+ font-size: 1.2rem;
208
+ font-weight: 600;
209
+ margin-bottom: 15px;
210
+ color: var(--primary-color);
211
+ }
212
+
213
+ .plot-container img {
214
+ max-width: 100%;
215
+ height: auto;
216
+ display: block;
217
+ margin: 0 auto;
218
+ }
219
+
220
+ /* Artifacts List */
221
+ .artifacts-list {
222
+ list-style: none;
223
+ padding: 0;
224
+ }
225
+
226
+ .artifacts-list li {
227
+ background: var(--code-bg);
228
+ padding: 15px;
229
+ margin: 10px 0;
230
+ border-left: 4px solid var(--secondary-color);
231
+ border-radius: 4px;
232
+ }
233
+
234
+ .artifacts-list strong {
235
+ color: var(--primary-color);
236
+ }
237
+
238
+ /* Metrics Grid */
239
+ .metrics-grid {
240
+ display: grid;
241
+ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
242
+ gap: 20px;
243
+ margin: 20px 0;
244
+ }
245
+
246
+ .metric-card {
247
+ background: var(--code-bg);
248
+ padding: 20px;
249
+ border-radius: 8px;
250
+ text-align: center;
251
+ border: 1px solid var(--border-color);
252
+ }
253
+
254
+ .metric-value {
255
+ font-size: 2rem;
256
+ font-weight: 700;
257
+ color: var(--primary-color);
258
+ margin: 10px 0;
259
+ }
260
+
261
+ .metric-label {
262
+ font-size: 0.9rem;
263
+ color: var(--text-color);
264
+ opacity: 0.8;
265
+ }
266
+
267
+ /* Code blocks */
268
+ code {
269
+ background: var(--code-bg);
270
+ padding: 2px 6px;
271
+ border-radius: 3px;
272
+ font-family: 'Consolas', 'Monaco', monospace;
273
+ font-size: 0.9em;
274
+ }
275
+
276
+ /* Responsive */
277
+ @media (max-width: 768px) {
278
+ .header {
279
+ padding: 40px 20px;
280
+ }
281
+
282
+ .header h1 {
283
+ font-size: 2rem;
284
+ }
285
+
286
+ .section h2 {
287
+ font-size: 1.5rem;
288
+ }
289
+
290
+ .metrics-grid {
291
+ grid-template-columns: 1fr;
292
+ }
293
+ }
294
+
295
+ /* Print styles */
296
+ @media print {
297
+ .header {
298
+ background: white !important;
299
+ color: black !important;
300
+ box-shadow: none !important;
301
+ }
302
+
303
+ .toc {
304
+ display: none;
305
+ }
306
+
307
+ .section {
308
+ page-break-inside: avoid;
309
+ }
310
+ }
311
311
  </style>
312
- </head>
313
- <body>
312
+ </head>
313
+ <body>
314
314
  <div class="container">
315
- <div class="header">
316
- <h1>{{ title }}</h1>
317
- <div class="meta">
318
- {% if config.show_timestamps %}
319
- <p>Generated: {{ generated_at|format_timestamp }}</p>
320
- {% endif %}
321
- <p>Author: {{ author }}</p>
322
- <p>Report Type: Protocol Reverse Engineering</p>
323
- </div>
315
+ <div class="header">
316
+ <h1>{{ title }}</h1>
317
+ <div class="meta">
318
+ {% if config.show_timestamps %}
319
+ <p>Generated: {{ generated_at|format_timestamp }}</p>
320
+ {% endif %}
321
+ <p>Author: {{ author }}</p>
322
+ <p>Report Type: Protocol Reverse Engineering</p>
324
323
  </div>
325
-
326
- {% if config.show_toc %}
327
- <div class="toc">
328
- <h2>Table of Contents</h2>
329
- <ul>
330
- <li><a href="#executive-summary">Executive Summary</a></li>
331
- <li><a href="#protocol-spec">Protocol Specification</a></li>
332
- {% if plots %}<li><a href="#visualizations">Visualizations</a></li>{% endif %}
333
- {% if artifacts %}<li><a href="#artifacts">Generated Artifacts</a></li>{% endif %}
334
- {% if partial_results %}<li><a href="#analysis">Detailed Analysis</a></li>{% endif %}
335
- {% if warnings %}<li><a href="#warnings">Warnings</a></li>{% endif %}
336
- </ul>
324
+ </div>
325
+
326
+ {% if config.show_toc %}
327
+ <div class="toc">
328
+ <h2>Table of Contents</h2>
329
+ <ul>
330
+ <li><a href="#executive-summary">Executive Summary</a></li>
331
+ <li><a href="#protocol-spec">Protocol Specification</a></li>
332
+ {% if plots %}
333
+ <li><a href="#visualizations">Visualizations</a></li>
334
+ {% endif %} {% if artifacts %}
335
+ <li><a href="#artifacts">Generated Artifacts</a></li>
336
+ {% endif %} {% if partial_results %}
337
+ <li><a href="#analysis">Detailed Analysis</a></li>
338
+ {% endif %} {% if warnings %}
339
+ <li><a href="#warnings">Warnings</a></li>
340
+ {% endif %}
341
+ </ul>
342
+ </div>
343
+ {% endif %}
344
+
345
+ <!-- Executive Summary -->
346
+ <div class="section" id="executive-summary">
347
+ <h2>Executive Summary</h2>
348
+ <div class="card">
349
+ <p>
350
+ This report presents the results of automated protocol reverse engineering performed by the Oscura
351
+ framework. The analysis identified protocol characteristics, decoded message structures, and generated
352
+ working dissectors for further analysis.
353
+ </p>
337
354
  </div>
338
- {% endif %}
339
355
 
340
- <!-- Executive Summary -->
341
- <div class="section" id="executive-summary">
342
- <h2>Executive Summary</h2>
343
- <div class="card">
344
- <p>This report presents the results of automated protocol reverse engineering
345
- performed by the Oscura framework. The analysis identified protocol characteristics,
346
- decoded message structures, and generated working dissectors for further analysis.</p>
347
- </div>
348
-
349
- {% if confidence_score %}
350
- <div class="metrics-grid">
351
- <div class="metric-card">
352
- <div class="metric-label">Overall Confidence</div>
353
- <div class="metric-value">{{ (confidence_score * 100)|round(1) }}%</div>
354
- {% if confidence_score >= 0.8 %}
355
- <span class="badge badge-success">High</span>
356
- {% elif confidence_score >= 0.6 %}
357
- <span class="badge badge-warning">Medium</span>
358
- {% else %}
359
- <span class="badge badge-danger">Low</span>
360
- {% endif %}
361
- </div>
362
-
363
- {% if execution_time %}
364
- <div class="metric-card">
365
- <div class="metric-label">Execution Time</div>
366
- <div class="metric-value">{{ execution_time|round(1) }}s</div>
367
- </div>
368
- {% endif %}
369
-
370
- {% if protocol_spec %}
371
- <div class="metric-card">
372
- <div class="metric-label">Fields Detected</div>
373
- <div class="metric-value">{{ protocol_spec.fields|length }}</div>
374
- </div>
375
- {% endif %}
376
-
377
- {% if artifacts %}
378
- <div class="metric-card">
379
- <div class="metric-label">Artifacts Generated</div>
380
- <div class="metric-value">{{ artifacts|length }}</div>
381
- </div>
382
- {% endif %}
383
- </div>
356
+ {% if confidence_score %}
357
+ <div class="metrics-grid">
358
+ <div class="metric-card">
359
+ <div class="metric-label">Overall Confidence</div>
360
+ <div class="metric-value">{{ (confidence_score * 100)|round(1) }}%</div>
361
+ {% if confidence_score >= 0.8 %}
362
+ <span class="badge badge-success">High</span>
363
+ {% elif confidence_score >= 0.6 %}
364
+ <span class="badge badge-warning">Medium</span>
365
+ {% else %}
366
+ <span class="badge badge-danger">Low</span>
384
367
  {% endif %}
368
+ </div>
369
+
370
+ {% if execution_time %}
371
+ <div class="metric-card">
372
+ <div class="metric-label">Execution Time</div>
373
+ <div class="metric-value">{{ execution_time|round(1) }}s</div>
374
+ </div>
375
+ {% endif %} {% if protocol_spec %}
376
+ <div class="metric-card">
377
+ <div class="metric-label">Fields Detected</div>
378
+ <div class="metric-value">{{ protocol_spec.fields|length }}</div>
379
+ </div>
380
+ {% endif %} {% if artifacts %}
381
+ <div class="metric-card">
382
+ <div class="metric-label">Artifacts Generated</div>
383
+ <div class="metric-value">{{ artifacts|length }}</div>
384
+ </div>
385
+ {% endif %}
385
386
  </div>
386
-
387
- <!-- Protocol Specification -->
388
- {% if protocol_spec %}
389
- <div class="section" id="protocol-spec">
390
- <h2>Protocol Specification</h2>
391
-
392
- <div class="card">
393
- <div class="card-header">Overview</div>
394
- <table>
395
- <tr>
396
- <th>Property</th>
397
- <th>Value</th>
398
- </tr>
399
- <tr>
400
- <td><strong>Protocol Name</strong></td>
401
- <td>{{ protocol_spec.name }}</td>
402
- </tr>
403
- <tr>
404
- <td><strong>Baud Rate</strong></td>
405
- <td>{{ protocol_spec.baud_rate|format_number }} bps</td>
406
- </tr>
407
- <tr>
408
- <td><strong>Frame Format</strong></td>
409
- <td><code>{{ protocol_spec.frame_format }}</code></td>
410
- </tr>
411
- <tr>
412
- <td><strong>Sync Pattern</strong></td>
413
- <td><code>{{ protocol_spec.sync_pattern }}</code></td>
414
- </tr>
415
- <tr>
416
- <td><strong>Frame Length</strong></td>
417
- <td>{{ protocol_spec.frame_length or "Variable" }} bytes</td>
418
- </tr>
419
- <tr>
420
- <td><strong>Checksum Type</strong></td>
421
- <td>{{ protocol_spec.checksum_type or "None detected" }}</td>
422
- </tr>
423
- {% if protocol_spec.checksum_position %}
424
- <tr>
425
- <td><strong>Checksum Position</strong></td>
426
- <td>Byte {{ protocol_spec.checksum_position }}</td>
427
- </tr>
428
- {% endif %}
429
- <tr>
430
- <td><strong>Detection Confidence</strong></td>
431
- <td>{{ (protocol_spec.confidence * 100)|round(1) }}%</td>
432
- </tr>
433
- </table>
434
- </div>
435
-
436
- {% if protocol_spec.fields %}
437
- <h3>Field Structure</h3>
438
- <div class="card">
439
- <table>
440
- <thead>
441
- <tr>
442
- <th>Field Name</th>
443
- <th>Offset (bytes)</th>
444
- <th>Size (bytes)</th>
445
- <th>Type</th>
446
- </tr>
447
- </thead>
448
- <tbody>
449
- {% for field in protocol_spec.fields %}
450
- <tr>
451
- <td><code>{{ field.name }}</code></td>
452
- <td>{{ field.offset }}</td>
453
- <td>{{ field.size }}</td>
454
- <td>{{ field.type }}</td>
455
- </tr>
456
- {% endfor %}
457
- </tbody>
458
- </table>
459
- </div>
387
+ {% endif %}
388
+ </div>
389
+
390
+ <!-- Protocol Specification -->
391
+ {% if protocol_spec %}
392
+ <div class="section" id="protocol-spec">
393
+ <h2>Protocol Specification</h2>
394
+
395
+ <div class="card">
396
+ <div class="card-header">Overview</div>
397
+ <table>
398
+ <tr>
399
+ <th>Property</th>
400
+ <th>Value</th>
401
+ </tr>
402
+ <tr>
403
+ <td><strong>Protocol Name</strong></td>
404
+ <td>{{ protocol_spec.name }}</td>
405
+ </tr>
406
+ <tr>
407
+ <td><strong>Baud Rate</strong></td>
408
+ <td>{{ protocol_spec.baud_rate|format_number }} bps</td>
409
+ </tr>
410
+ <tr>
411
+ <td><strong>Frame Format</strong></td>
412
+ <td><code>{{ protocol_spec.frame_format }}</code></td>
413
+ </tr>
414
+ <tr>
415
+ <td><strong>Sync Pattern</strong></td>
416
+ <td><code>{{ protocol_spec.sync_pattern }}</code></td>
417
+ </tr>
418
+ <tr>
419
+ <td><strong>Frame Length</strong></td>
420
+ <td>{{ protocol_spec.frame_length or "Variable" }} bytes</td>
421
+ </tr>
422
+ <tr>
423
+ <td><strong>Checksum Type</strong></td>
424
+ <td>{{ protocol_spec.checksum_type or "None detected" }}</td>
425
+ </tr>
426
+ {% if protocol_spec.checksum_position %}
427
+ <tr>
428
+ <td><strong>Checksum Position</strong></td>
429
+ <td>Byte {{ protocol_spec.checksum_position }}</td>
430
+ </tr>
460
431
  {% endif %}
432
+ <tr>
433
+ <td><strong>Detection Confidence</strong></td>
434
+ <td>{{ (protocol_spec.confidence * 100)|round(1) }}%</td>
435
+ </tr>
436
+ </table>
461
437
  </div>
462
- {% endif %}
463
438
 
464
- <!-- Visualizations -->
465
- {% if plots %}
466
- <div class="section" id="visualizations">
467
- <h2>Visualizations</h2>
468
- {% for plot in plots %}
469
- <div class="plot-container">
470
- <div class="plot-title">{{ plot.title }}</div>
471
- {% if plot.type == "embedded" %}
472
- <img src="{{ plot.data }}" alt="{{ plot.title }}">
473
- {% else %}
474
- <img src="{{ plot.path }}" alt="{{ plot.title }}">
475
- {% endif %}
476
- </div>
477
- {% endfor %}
439
+ {% if protocol_spec.fields %}
440
+ <h3>Field Structure</h3>
441
+ <div class="card">
442
+ <table>
443
+ <thead>
444
+ <tr>
445
+ <th>Field Name</th>
446
+ <th>Offset (bytes)</th>
447
+ <th>Size (bytes)</th>
448
+ <th>Type</th>
449
+ </tr>
450
+ </thead>
451
+ <tbody>
452
+ {% for field in protocol_spec.fields %}
453
+ <tr>
454
+ <td><code>{{ field.name }}</code></td>
455
+ <td>{{ field.offset }}</td>
456
+ <td>{{ field.size }}</td>
457
+ <td>{{ field.type }}</td>
458
+ </tr>
459
+ {% endfor %}
460
+ </tbody>
461
+ </table>
478
462
  </div>
479
463
  {% endif %}
480
-
481
- <!-- Generated Artifacts -->
482
- {% if artifacts %}
483
- <div class="section" id="artifacts">
484
- <h2>Generated Artifacts</h2>
485
- <div class="card">
486
- <p>The following artifacts were generated and can be used for further analysis:</p>
487
- <ul class="artifacts-list">
488
- {% for artifact in artifacts %}
489
- <li>
490
- <strong>{{ artifact.name }}</strong><br>
491
- <code>{{ artifact.path }}</code>
492
- </li>
493
- {% endfor %}
494
- </ul>
495
- </div>
464
+ </div>
465
+ {% endif %}
466
+
467
+ <!-- Visualizations -->
468
+ {% if plots %}
469
+ <div class="section" id="visualizations">
470
+ <h2>Visualizations</h2>
471
+ {% for plot in plots %}
472
+ <div class="plot-container">
473
+ <div class="plot-title">{{ plot.title }}</div>
474
+ {% if plot.type == "embedded" %}
475
+ <img src="{{ plot.data }}" alt="{{ plot.title }}" />
476
+ {% else %}
477
+ <img src="{{ plot.path }}" alt="{{ plot.title }}" />
478
+ {% endif %}
496
479
  </div>
497
- {% endif %}
498
-
499
- <!-- Detailed Analysis -->
500
- {% if partial_results %}
501
- <div class="section" id="analysis">
502
- <h2>Detailed Analysis Results</h2>
503
- {% for key, value in partial_results.items() %}
504
- {% if key not in ['traces'] %}
505
- <div class="card">
506
- <div class="card-header">{{ key|replace('_', ' ')|title }}</div>
507
- <p>{{ value }}</p>
508
- </div>
509
- {% endif %}
480
+ {% endfor %}
481
+ </div>
482
+ {% endif %}
483
+
484
+ <!-- Generated Artifacts -->
485
+ {% if artifacts %}
486
+ <div class="section" id="artifacts">
487
+ <h2>Generated Artifacts</h2>
488
+ <div class="card">
489
+ <p>The following artifacts were generated and can be used for further analysis:</p>
490
+ <ul class="artifacts-list">
491
+ {% for artifact in artifacts %}
492
+ <li>
493
+ <strong>{{ artifact.name }}</strong><br />
494
+ <code>{{ artifact.path }}</code>
495
+ </li>
510
496
  {% endfor %}
497
+ </ul>
511
498
  </div>
512
- {% endif %}
513
-
514
- <!-- Warnings -->
515
- {% if warnings %}
516
- <div class="section" id="warnings">
517
- <h2>Warnings and Notes</h2>
518
- {% for warning in warnings %}
519
- <div class="warning">{{ warning }}</div>
520
- {% endfor %}
499
+ </div>
500
+ {% endif %}
501
+
502
+ <!-- Detailed Analysis -->
503
+ {% if partial_results %}
504
+ <div class="section" id="analysis">
505
+ <h2>Detailed Analysis Results</h2>
506
+ {% for key, value in partial_results.items() %} {% if key not in ['traces'] %}
507
+ <div class="card">
508
+ <div class="card-header">{{ key|replace('_', ' ')|title }}</div>
509
+ <p>{{ value }}</p>
521
510
  </div>
522
- {% endif %}
511
+ {% endif %} {% endfor %}
512
+ </div>
513
+ {% endif %}
514
+
515
+ <!-- Warnings -->
516
+ {% if warnings %}
517
+ <div class="section" id="warnings">
518
+ <h2>Warnings and Notes</h2>
519
+ {% for warning in warnings %}
520
+ <div class="warning">{{ warning }}</div>
521
+ {% endfor %}
522
+ </div>
523
+ {% endif %}
523
524
  </div>
524
- </body>
525
+ </body>
525
526
  </html>