wesam0099 commited on
Commit
a3b8ff3
Β·
verified Β·
1 Parent(s): 15d5f17

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +1102 -35
src/streamlit_app.py CHANGED
@@ -1,40 +1,1107 @@
1
- import altair as alt
2
- import numpy as np
3
- import pandas as pd
4
- import streamlit as st
 
5
 
 
 
6
  """
7
- # Welcome to Streamlit!
8
 
9
- Edit `/streamlit_app.py` to customize this app to your heart's desire :heart:.
10
- If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
11
- forums](https://discuss.streamlit.io).
12
 
13
- In the meantime, below is an example of what you can do with just a few lines of code:
14
- """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
 
16
- num_points = st.slider("Number of points in spiral", 1, 10000, 1100)
17
- num_turns = st.slider("Number of turns in spiral", 1, 300, 31)
18
-
19
- indices = np.linspace(0, 1, num_points)
20
- theta = 2 * np.pi * num_turns * indices
21
- radius = indices
22
-
23
- x = radius * np.cos(theta)
24
- y = radius * np.sin(theta)
25
-
26
- df = pd.DataFrame({
27
- "x": x,
28
- "y": y,
29
- "idx": indices,
30
- "rand": np.random.randn(num_points),
31
- })
32
-
33
- st.altair_chart(alt.Chart(df, height=700, width=700)
34
- .mark_point(filled=True)
35
- .encode(
36
- x=alt.X("x", axis=None),
37
- y=alt.Y("y", axis=None),
38
- color=alt.Color("idx", legend=None, scale=alt.Scale()),
39
- size=alt.Size("rand", legend=None, scale=alt.Scale(range=[1, 150])),
40
- ))
 
1
+ """
2
+ Traffic Accident Reconstruction System
3
+ ======================================
4
+ Main Streamlit Application
5
+ Huawei AI Innovation Challenge 2026
6
 
7
+ This system uses MindSpore AI to analyze traffic accidents
8
+ and generate probable scenarios with 2D simulation.
9
  """
 
10
 
11
+ import streamlit as st
12
+ import sys
13
+ from pathlib import Path
14
 
15
+ # Add project root to path
16
+ sys.path.insert(0, str(Path(__file__).parent))
17
+
18
+ from config import STREAMLIT_CONFIG, CASE_STUDY_LOCATION, COLORS
19
+ from ui.components import render_sidebar, render_header, render_footer
20
+ from ui.map_viewer import render_map_section
21
+ from ui.vehicle_input import render_vehicle_input
22
+ from ui.party_input import render_party_input, render_evidence_upload, render_party_summary
23
+ from ui.results_display import render_results
24
+
25
+ # ============================================================
26
+ # PAGE CONFIGURATION
27
+ # ============================================================
28
+
29
+ st.set_page_config(
30
+ page_title=STREAMLIT_CONFIG["page_title"],
31
+ page_icon=STREAMLIT_CONFIG["page_icon"],
32
+ layout=STREAMLIT_CONFIG["layout"],
33
+ initial_sidebar_state=STREAMLIT_CONFIG["initial_sidebar_state"]
34
+ )
35
+
36
+ # ============================================================
37
+ # CUSTOM CSS - CrashLens Modern Design
38
+ # ============================================================
39
+
40
+ st.markdown("""
41
+ <style>
42
+ /* Layout - Dark theme with modern spacing */
43
+ .block-container {
44
+ padding-top: 1.4rem;
45
+ padding-bottom: 2.5rem;
46
+ max-width: 1200px;
47
+ }
48
+
49
+ [data-testid="stSidebar"] {
50
+ min-width: 340px;
51
+ max-width: 340px;
52
+ background: linear-gradient(180deg, #0e1117 0%, #1a1f2e 100%);
53
+ }
54
+
55
+ /* Main container with gradient background */
56
+ .main {
57
+ background: linear-gradient(135deg, #0a0e27 0%, #1a1f3a 50%, #0f1419 100%);
58
+ color: rgba(255, 255, 255, 0.95);
59
+ }
60
+
61
+ /* Header styling - Modern minimal */
62
+ .main-header {
63
+ background: linear-gradient(135deg, rgba(30, 58, 95, 0.3) 0%, rgba(45, 90, 135, 0.2) 100%);
64
+ padding: 2rem;
65
+ border-radius: 16px;
66
+ border: 1px solid rgba(255, 255, 255, 0.12);
67
+ color: white;
68
+ margin-bottom: 2rem;
69
+ text-align: center;
70
+ box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
71
+ }
72
+
73
+ .main-header h1 {
74
+ margin: 0;
75
+ font-size: 2.8rem;
76
+ font-weight: 800;
77
+ letter-spacing: 0.5px;
78
+ background: linear-gradient(135deg, #60a5fa 0%, #3b82f6 100%);
79
+ -webkit-background-clip: text;
80
+ -webkit-text-fill-color: transparent;
81
+ }
82
+
83
+ .main-header p {
84
+ margin: 0.8rem 0 0 0;
85
+ opacity: 0.75;
86
+ font-size: 1.05rem;
87
+ color: rgba(255, 255, 255, 0.72);
88
+ }
89
+
90
+ /* Card styling - Glass morphism effect */
91
+ .info-card {
92
+ background: rgba(255, 255, 255, 0.04);
93
+ backdrop-filter: blur(10px);
94
+ padding: 1.5rem;
95
+ border-radius: 16px;
96
+ border: 1px solid rgba(255, 255, 255, 0.12);
97
+ margin: 1rem 0;
98
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15);
99
+ }
100
+
101
+ /* Step indicator - Modern pills */
102
+ .step-indicator {
103
+ display: flex;
104
+ justify-content: space-between;
105
+ margin: 2rem 0;
106
+ gap: 0.5rem;
107
+ }
108
+
109
+ .step {
110
+ flex: 1;
111
+ text-align: center;
112
+ padding: 1rem;
113
+ background: rgba(255, 255, 255, 0.05);
114
+ border: 1px solid rgba(255, 255, 255, 0.1);
115
+ margin: 0;
116
+ border-radius: 12px;
117
+ position: relative;
118
+ transition: all 0.3s ease;
119
+ }
120
+
121
+ .step.active {
122
+ background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);
123
+ border-color: #3b82f6;
124
+ color: white;
125
+ box-shadow: 0 8px 24px rgba(59, 130, 246, 0.3);
126
+ }
127
+
128
+ .step.completed {
129
+ background: linear-gradient(135deg, #10b981 0%, #059669 100%);
130
+ border-color: #10b981;
131
+ color: white;
132
+ }
133
+
134
+ /* Vehicle cards - Dark theme */
135
+ .vehicle-card {
136
+ background: rgba(255, 255, 255, 0.06);
137
+ border: 1px solid rgba(255, 255, 255, 0.15);
138
+ border-radius: 12px;
139
+ padding: 1.5rem;
140
+ margin: 1rem 0;
141
+ }
142
+
143
+ .vehicle-card.vehicle-1 {
144
+ border-color: rgba(255, 75, 75, 0.4);
145
+ background: rgba(255, 75, 75, 0.08);
146
+ }
147
+
148
+ .vehicle-card.vehicle-2 {
149
+ border-color: rgba(75, 123, 255, 0.4);
150
+ background: rgba(75, 123, 255, 0.08);
151
+ }
152
+
153
+ /* Results styling - Modern cards */
154
+ .scenario-card {
155
+ background: rgba(255, 255, 255, 0.06);
156
+ border-radius: 12px;
157
+ padding: 1.5rem;
158
+ margin: 1rem 0;
159
+ box-shadow: 0 4px 12px rgba(0,0,0,0.2);
160
+ border: 1px solid rgba(255, 255, 255, 0.1);
161
+ }
162
+
163
+ .probability-high {
164
+ color: #10b981;
165
+ font-weight: bold;
166
+ }
167
+
168
+ .probability-medium {
169
+ color: #f59e0b;
170
+ font-weight: bold;
171
+ }
172
+
173
+ .probability-low {
174
+ color: #ef4444;
175
+ font-weight: bold;
176
+ }
177
+
178
+ /* Button styling - Modern gradient */
179
+ .stButton > button {
180
+ width: 100%;
181
+ background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);
182
+ color: white;
183
+ border: none;
184
+ padding: 0.85rem 1.5rem;
185
+ border-radius: 12px;
186
+ font-weight: 600;
187
+ font-size: 1rem;
188
+ transition: all 0.3s ease;
189
+ box-shadow: 0 4px 12px rgba(59, 130, 246, 0.3);
190
+ }
191
+
192
+ .stButton > button:hover {
193
+ background: linear-gradient(135deg, #2563eb 0%, #1d4ed8 100%);
194
+ box-shadow: 0 6px 16px rgba(59, 130, 246, 0.4);
195
+ transform: translateY(-2px);
196
+ }
197
+
198
+ /* Input fields - Dark theme with better contrast */
199
+ .stTextInput > div > div > input,
200
+ .stTextArea > div > div > textarea,
201
+ .stSelectbox > div > div > select,
202
+ .stNumberInput > div > div > input {
203
+ background: rgba(255, 255, 255, 0.08) !important;
204
+ border: 1px solid rgba(255, 255, 255, 0.15) !important;
205
+ border-radius: 10px !important;
206
+ color: white !important;
207
+ padding: 0.75rem !important;
208
+ }
209
+
210
+ .stTextInput > div > div > input:focus,
211
+ .stTextArea > div > div > textarea:focus,
212
+ .stSelectbox > div > div > select:focus,
213
+ .stNumberInput > div > div > input:focus {
214
+ border-color: #3b82f6 !important;
215
+ box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.15) !important;
216
+ }
217
+
218
+ /* Labels - Better visibility */
219
+ label, .stTextInput > label, .stTextArea > label, .stSelectbox > label, .stSlider > label, .stNumberInput > label {
220
+ color: rgba(255, 255, 255, 0.85) !important;
221
+ font-weight: 500 !important;
222
+ font-size: 0.95rem !important;
223
+ }
224
+
225
+ /* Metric cards - Modern design */
226
+ [data-testid="stMetricValue"] {
227
+ font-size: 2.2rem;
228
+ font-weight: 700;
229
+ color: white;
230
+ }
231
+
232
+ [data-testid="stMetricLabel"] {
233
+ color: rgba(255, 255, 255, 0.7);
234
+ font-size: 0.95rem;
235
+ font-weight: 500;
236
+ }
237
+
238
+ /* Tabs styling - Modern */
239
+ .stTabs [data-baseweb="tab-list"] {
240
+ gap: 8px;
241
+ background: rgba(255, 255, 255, 0.03);
242
+ padding: 0.5rem;
243
+ border-radius: 12px;
244
+ }
245
+
246
+ .stTabs [data-baseweb="tab"] {
247
+ background: transparent;
248
+ border-radius: 8px;
249
+ color: rgba(255, 255, 255, 0.7);
250
+ font-weight: 500;
251
+ padding: 0.75rem 1.5rem;
252
+ border: 1px solid transparent;
253
+ }
254
+
255
+ .stTabs [aria-selected="true"] {
256
+ background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);
257
+ color: white !important;
258
+ border-color: #3b82f6;
259
+ }
260
+
261
+ /* Messages - Modern alerts */
262
+ .stSuccess, .element-container:has(.stSuccess) {
263
+ background: rgba(16, 185, 129, 0.15) !important;
264
+ border: 1px solid rgba(16, 185, 129, 0.3) !important;
265
+ border-radius: 12px !important;
266
+ padding: 1rem !important;
267
+ }
268
+
269
+ .stSuccess [data-testid="stMarkdownContainer"] p {
270
+ color: #10b981 !important;
271
+ }
272
+
273
+ .stError {
274
+ background: rgba(239, 68, 68, 0.15) !important;
275
+ border: 1px solid rgba(239, 68, 68, 0.3) !important;
276
+ border-radius: 12px !important;
277
+ }
278
+
279
+ .stWarning {
280
+ background: rgba(245, 158, 11, 0.15) !important;
281
+ border: 1px solid rgba(245, 158, 11, 0.3) !important;
282
+ border-radius: 12px !important;
283
+ }
284
+
285
+ .stInfo {
286
+ background: rgba(59, 130, 246, 0.15) !important;
287
+ border: 1px solid rgba(59, 130, 246, 0.3) !important;
288
+ border-radius: 12px !important;
289
+ }
290
+
291
+ /* Sidebar - Better styling */
292
+ [data-testid="stSidebar"] h1, [data-testid="stSidebar"] h2, [data-testid="stSidebar"] h3 {
293
+ color: white !important;
294
+ }
295
+
296
+ [data-testid="stSidebar"] p, [data-testid="stSidebar"] span {
297
+ color: rgba(255, 255, 255, 0.85) !important;
298
+ }
299
+
300
+ /* Expander - Modern style */
301
+ .streamlit-expanderHeader {
302
+ background: rgba(255, 255, 255, 0.05) !important;
303
+ border-radius: 10px !important;
304
+ border: 1px solid rgba(255, 255, 255, 0.1) !important;
305
+ color: white !important;
306
+ font-weight: 500 !important;
307
+ }
308
+
309
+ .streamlit-expanderContent {
310
+ background: rgba(255, 255, 255, 0.02) !important;
311
+ border: 1px solid rgba(255, 255, 255, 0.08) !important;
312
+ border-radius: 0 0 10px 10px !important;
313
+ }
314
+
315
+ /* Checkbox and Radio - Better visibility */
316
+ .stCheckbox label, .stRadio label {
317
+ color: rgba(255, 255, 255, 0.85) !important;
318
+ }
319
+
320
+ /* Slider - Modern */
321
+ .stSlider [data-baseweb="slider"] {
322
+ background: rgba(59, 130, 246, 0.2);
323
+ }
324
+
325
+ /* Headings - Better hierarchy */
326
+ h1, h2, h3, h4, h5, h6 {
327
+ color: white !important;
328
+ }
329
+
330
+ h1 {
331
+ font-weight: 800 !important;
332
+ letter-spacing: -0.5px;
333
+ }
334
+
335
+ h2 {
336
+ font-weight: 700 !important;
337
+ letter-spacing: -0.3px;
338
+ }
339
+
340
+ h3 {
341
+ font-weight: 600 !important;
342
+ }
343
+
344
+ /* Markdown text - Better readability */
345
+ p, span, div {
346
+ color: rgba(255, 255, 255, 0.9);
347
+ }
348
+
349
+ /* Code blocks - Dark theme */
350
+ code {
351
+ background: rgba(255, 255, 255, 0.08) !important;
352
+ color: #60a5fa !important;
353
+ padding: 0.2rem 0.4rem !important;
354
+ border-radius: 4px !important;
355
+ }
356
+
357
+ /* Dataframe - Dark theme */
358
+ [data-testid="stDataFrame"] {
359
+ background: rgba(255, 255, 255, 0.05);
360
+ border-radius: 12px;
361
+ border: 1px solid rgba(255, 255, 255, 0.1);
362
+ }
363
+
364
+ /* Hide Streamlit branding */
365
+ #MainMenu {visibility: hidden;}
366
+ footer {visibility: hidden;}
367
+
368
+ /* Progress bar */
369
+ .stProgress > div > div {
370
+ background: linear-gradient(90deg, #3b82f6 0%, #8b5cf6 100%);
371
+ border-radius: 8px;
372
+ }
373
+ </style>
374
+ """, unsafe_allow_html=True)
375
+
376
+ # ============================================================
377
+ # SESSION STATE INITIALIZATION
378
+ # ============================================================
379
+
380
+ def init_session_state():
381
+ """Initialize all session state variables."""
382
+
383
+ # Application state
384
+ if 'current_step' not in st.session_state:
385
+ st.session_state.current_step = 1
386
+
387
+ # Accident information
388
+ if 'accident_info' not in st.session_state:
389
+ st.session_state.accident_info = {
390
+ 'location': CASE_STUDY_LOCATION.copy(),
391
+ 'datetime': None,
392
+ 'road_type': 'roundabout',
393
+ 'weather': 'clear',
394
+ 'road_condition': 'dry',
395
+ 'visibility': 1.0,
396
+ 'lighting': 'daylight',
397
+ 'notes': ''
398
+ }
399
+
400
+ # Vehicle 1 data (for analysis)
401
+ if 'vehicle_1' not in st.session_state:
402
+ st.session_state.vehicle_1 = {
403
+ 'type': 'sedan',
404
+ 'speed': 50,
405
+ 'direction': 'north',
406
+ 'action': 'entering_roundabout',
407
+ 'braking': False,
408
+ 'signaling': False,
409
+ 'lights_on': True,
410
+ 'horn_used': False,
411
+ 'path': [],
412
+ 'description': ''
413
+ }
414
+
415
+ # Vehicle 2 data (for analysis)
416
+ if 'vehicle_2' not in st.session_state:
417
+ st.session_state.vehicle_2 = {
418
+ 'type': 'sedan',
419
+ 'speed': 50,
420
+ 'direction': 'east',
421
+ 'action': 'going_straight',
422
+ 'braking': False,
423
+ 'signaling': False,
424
+ 'lights_on': True,
425
+ 'horn_used': False,
426
+ 'path': [],
427
+ 'description': ''
428
+ }
429
+
430
+ # Party 1 data (driver details)
431
+ if 'party_1' not in st.session_state:
432
+ st.session_state.party_1 = {
433
+ 'full_name': '',
434
+ 'id_iqama': '',
435
+ 'phone': '',
436
+ 'role': 'Driver',
437
+ 'vehicle_make_model': '',
438
+ 'plate_number': '',
439
+ 'insurance': '',
440
+ 'damage_notes': '',
441
+ 'statement': ''
442
+ }
443
+
444
+ # Party 2 data (driver details)
445
+ if 'party_2' not in st.session_state:
446
+ st.session_state.party_2 = {
447
+ 'full_name': '',
448
+ 'id_iqama': '',
449
+ 'phone': '',
450
+ 'role': 'Driver',
451
+ 'vehicle_make_model': '',
452
+ 'plate_number': '',
453
+ 'insurance': '',
454
+ 'damage_notes': '',
455
+ 'statement': ''
456
+ }
457
+
458
+ # Evidence photos
459
+ if 'evidence_photos' not in st.session_state:
460
+ st.session_state.evidence_photos = []
461
+
462
+ # Analysis results
463
+ if 'analysis_results' not in st.session_state:
464
+ st.session_state.analysis_results = None
465
+
466
+ # Generated scenarios
467
+ if 'scenarios' not in st.session_state:
468
+ st.session_state.scenarios = []
469
+
470
+ # Map data
471
+ if 'map_data' not in st.session_state:
472
+ st.session_state.map_data = None
473
+
474
+ # Analysis ready flag
475
+ if 'analysis_ready' not in st.session_state:
476
+ st.session_state.analysis_ready = False
477
+
478
+ # ============================================================
479
+ # MAIN APPLICATION
480
+ # ============================================================
481
+
482
+ def main():
483
+ """Main application entry point."""
484
+
485
+ # Initialize session state
486
+ init_session_state()
487
+
488
+ # Render modern header - clean without logo
489
+ col1, col2, col3 = st.columns([1, 6, 1])
490
+ with col1:
491
+ st.markdown("## πŸš—")
492
+ with col2:
493
+ st.markdown("""
494
+ <div style='padding-top: 0.5rem;'>
495
+ <h1 style='margin: 0; font-size: 2.5rem; font-weight: 800; background: linear-gradient(135deg, #60a5fa 0%, #3b82f6 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent;'>CrashLens AI</h1>
496
+ <p style='margin: 0.3rem 0 0 0; color: rgba(255, 255, 255, 0.7); font-size: 1rem;'>Traffic Accident Scenario Analysis β€’ MindSpore-ready β€’ PDF report</p>
497
+ </div>
498
+ """, unsafe_allow_html=True)
499
+ with col3:
500
+ st.write("")
501
+
502
+ st.markdown("<br>", unsafe_allow_html=True)
503
+
504
+ # Render sidebar
505
+ render_sidebar()
506
+
507
+ # Modern step indicator with pills - Using columns to avoid HTML rendering issues
508
+ steps = ["πŸ“ Location", "πŸš™ Vehicle 1", "πŸš— Vehicle 2", "πŸ‘₯ Parties", "πŸ“„ Evidence", "πŸ” Analysis", "πŸ“Š Results"]
509
+ cols = st.columns(len(steps))
510
+
511
+ for i, (col, step_name) in enumerate(zip(cols, steps), 1):
512
+ with col:
513
+ if i < st.session_state.current_step:
514
+ # Completed step - Green
515
+ st.markdown(f"""
516
+ <div style='text-align: center; padding: 0.75rem 0.25rem;
517
+ background: linear-gradient(135deg, #10b981 0%, #059669 100%);
518
+ color: white; border-radius: 10px; font-size: 0.8rem; font-weight: 600;
519
+ box-shadow: 0 4px 12px rgba(16, 185, 129, 0.3);'>
520
+ βœ“ {step_name.split()[-1]}
521
+ </div>
522
+ """, unsafe_allow_html=True)
523
+ elif i == st.session_state.current_step:
524
+ # Active step - Blue gradient
525
+ st.markdown(f"""
526
+ <div style='text-align: center; padding: 0.75rem 0.25rem;
527
+ background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);
528
+ color: white; border-radius: 10px; font-size: 0.8rem; font-weight: 600;
529
+ box-shadow: 0 6px 16px rgba(59, 130, 246, 0.4);
530
+ border: 2px solid rgba(96, 165, 250, 0.5);'>
531
+ {step_name}
532
+ </div>
533
+ """, unsafe_allow_html=True)
534
+ else:
535
+ # Future step - Dark gray
536
+ st.markdown(f"""
537
+ <div style='text-align: center; padding: 0.75rem 0.25rem;
538
+ background: rgba(255, 255, 255, 0.05);
539
+ color: rgba(255, 255, 255, 0.4); border-radius: 10px; font-size: 0.8rem;
540
+ border: 1px solid rgba(255, 255, 255, 0.1);'>
541
+ {step_name.split()[-1]}
542
+ </div>
543
+ """, unsafe_allow_html=True)
544
+
545
+ st.markdown("<div style='margin: 1.5rem 0; height: 1px; background: linear-gradient(90deg, transparent, rgba(255,255,255,0.1), transparent);'></div>", unsafe_allow_html=True)
546
+
547
+ # Main content based on current step
548
+ if st.session_state.current_step == 1:
549
+ render_step_1_location()
550
+ elif st.session_state.current_step == 2:
551
+ render_step_2_vehicle1()
552
+ elif st.session_state.current_step == 3:
553
+ render_step_3_vehicle2()
554
+ elif st.session_state.current_step == 4:
555
+ render_step_4_parties()
556
+ elif st.session_state.current_step == 5:
557
+ render_step_5_evidence()
558
+ elif st.session_state.current_step == 6:
559
+ render_step_6_analysis()
560
+ elif st.session_state.current_step == 7:
561
+ render_step_7_results()
562
+
563
+ # Render footer
564
+ render_footer()
565
+
566
+
567
+ # ============================================================
568
+ # STEP 1: LOCATION SELECTION
569
+ # ============================================================
570
+
571
+ def render_step_1_location():
572
+ """Render the location selection step."""
573
+
574
+ st.header("πŸ“ Step 1: Accident Location")
575
+
576
+ st.markdown("""
577
+ <div class="info-card">
578
+ <h4>Accident Details</h4>
579
+ <p>Enter the location and conditions where the accident occurred.</p>
580
+ </div>
581
+ """, unsafe_allow_html=True)
582
+
583
+ col1, col2 = st.columns([2, 1])
584
+
585
+ with col1:
586
+ # Map display
587
+ render_map_section()
588
+
589
+ with col2:
590
+ st.subheader("Location Details")
591
+
592
+ # Location name
593
+ location_name = st.text_input(
594
+ "Location Name",
595
+ value=st.session_state.accident_info['location']['name']
596
+ )
597
+
598
+ # Coordinates
599
+ lat = st.number_input(
600
+ "Latitude",
601
+ value=st.session_state.accident_info['location']['latitude'],
602
+ format="%.6f",
603
+ step=0.0001
604
+ )
605
+
606
+ lon = st.number_input(
607
+ "Longitude",
608
+ value=st.session_state.accident_info['location']['longitude'],
609
+ format="%.6f",
610
+ step=0.0001
611
+ )
612
+
613
+ # Road type - expanded options
614
+ road_types = [
615
+ 'roundabout', 'crossroad', 't_junction', 'highway_merge',
616
+ 'parking', 'highway', 'urban_road', 'other'
617
+ ]
618
+ road_type_labels = {
619
+ 'roundabout': 'Roundabout (دوار)',
620
+ 'crossroad': 'Crossroad (ΨͺΩ‚Ψ§Ψ·ΨΉ)',
621
+ 't_junction': 'T-Junction',
622
+ 'highway_merge': 'Highway Merge',
623
+ 'parking': 'Parking / Low Speed',
624
+ 'highway': 'Highway',
625
+ 'urban_road': 'Urban Road',
626
+ 'other': 'Other'
627
+ }
628
+
629
+ road_type = st.selectbox(
630
+ "Road Type",
631
+ options=road_types,
632
+ format_func=lambda x: road_type_labels.get(x, x.title()),
633
+ index=road_types.index(st.session_state.accident_info.get('road_type', 'roundabout'))
634
+ )
635
+
636
+ # Date and time
637
+ accident_date = st.date_input("Accident Date")
638
+ accident_time = st.time_input("Accident Time")
639
+
640
+ # Weather conditions
641
+ weather = st.selectbox(
642
+ "Weather Conditions",
643
+ options=['clear', 'cloudy', 'rainy', 'foggy', 'sandstorm'],
644
+ format_func=lambda x: x.title()
645
+ )
646
+
647
+ # Road condition
648
+ road_condition = st.selectbox(
649
+ "Road Condition",
650
+ options=['dry', 'wet', 'sandy', 'oily'],
651
+ format_func=lambda x: x.title()
652
+ )
653
+
654
+ # Notes
655
+ notes = st.text_area(
656
+ "Notes (optional)",
657
+ value=st.session_state.accident_info.get('notes', ''),
658
+ placeholder="Any extra context about the accident...",
659
+ height=80
660
+ )
661
+
662
+ # Update session state
663
+ st.session_state.accident_info.update({
664
+ 'location': {
665
+ 'name': location_name,
666
+ 'latitude': lat,
667
+ 'longitude': lon,
668
+ 'radius_meters': 200
669
+ },
670
+ 'road_type': road_type,
671
+ 'datetime': f"{accident_date} {accident_time}",
672
+ 'weather': weather,
673
+ 'road_condition': road_condition,
674
+ 'notes': notes
675
+ })
676
+
677
+ # Navigation buttons
678
+ col1, col2, col3 = st.columns([1, 2, 1])
679
+ with col3:
680
+ if st.button("Next: Vehicle 1 β†’", type="primary"):
681
+ st.session_state.current_step = 2
682
+ st.rerun()
683
+
684
+
685
+ # ============================================================
686
+ # STEP 2: VEHICLE 1 INPUT
687
+ # ============================================================
688
+
689
+ def render_step_2_vehicle1():
690
+ """Render Vehicle 1 input step."""
691
+
692
+ st.header("πŸš™ Step 2: First Vehicle Information")
693
+
694
+ st.markdown("""
695
+ <div class="info-card" style="border-color: #FF4B4B;">
696
+ <h4>Vehicle 1 (Red)</h4>
697
+ <p>Enter the details of the first vehicle involved in the accident.</p>
698
+ </div>
699
+ """, unsafe_allow_html=True)
700
+
701
+ col1, col2 = st.columns([2, 1])
702
+
703
+ with col1:
704
+ # Map with path drawing
705
+ render_map_section(vehicle_id=1)
706
+
707
+ with col2:
708
+ render_vehicle_input(1)
709
+
710
+ # Navigation buttons
711
+ col1, col2, col3 = st.columns([1, 2, 1])
712
+ with col1:
713
+ if st.button("← Back"):
714
+ st.session_state.current_step = 1
715
+ st.rerun()
716
+ with col3:
717
+ if st.button("Next: Vehicle 2 β†’", type="primary"):
718
+ st.session_state.current_step = 3
719
+ st.rerun()
720
+
721
+
722
+ # ============================================================
723
+ # STEP 3: VEHICLE 2 INPUT
724
+ # ============================================================
725
+
726
+ def render_step_3_vehicle2():
727
+ """Render Vehicle 2 input step."""
728
+
729
+ st.header("πŸš— Step 3: Second Vehicle Information")
730
+
731
+ st.markdown("""
732
+ <div class="info-card" style="border-color: #4B7BFF;">
733
+ <h4>Vehicle 2 (Blue)</h4>
734
+ <p>Enter the details of the second vehicle involved in the accident.</p>
735
+ </div>
736
+ """, unsafe_allow_html=True)
737
+
738
+ col1, col2 = st.columns([2, 1])
739
+
740
+ with col1:
741
+ # Map with path drawing (showing both vehicles)
742
+ render_map_section(vehicle_id=2)
743
+
744
+ with col2:
745
+ render_vehicle_input(2)
746
+
747
+ # Navigation buttons
748
+ col1, col2, col3 = st.columns([1, 2, 1])
749
+ with col1:
750
+ if st.button("← Back"):
751
+ st.session_state.current_step = 2
752
+ st.rerun()
753
+ with col3:
754
+ if st.button("Analyze Accident β†’", type="primary"):
755
+ st.session_state.current_step = 4
756
+ st.rerun()
757
+
758
+
759
+ # ============================================================
760
+ # STEP 4: PARTIES INFORMATION
761
+ # ============================================================
762
+
763
+ def render_step_4_parties():
764
+ """Render the parties (driver details) input step."""
765
+
766
+ st.header("πŸ‘₯ Step 4: Parties Information")
767
+
768
+ st.markdown("""
769
+ <div class="info-card">
770
+ <h4>Driver & Vehicle Details</h4>
771
+ <p>Enter information about the parties involved in the accident. This information will be included in the official report.</p>
772
+ </div>
773
+ """, unsafe_allow_html=True)
774
+
775
+ # Two columns for both parties
776
+ col1, col2 = st.columns(2)
777
+
778
+ with col1:
779
+ render_party_input(1)
780
+
781
+ with col2:
782
+ render_party_input(2)
783
+
784
+ # Navigation buttons
785
+ st.markdown("---")
786
+ col1, col2, col3 = st.columns([1, 2, 1])
787
+ with col1:
788
+ if st.button("← Back to Vehicle 2"):
789
+ st.session_state.current_step = 3
790
+ st.rerun()
791
+ with col3:
792
+ if st.button("Next: Evidence β†’", type="primary"):
793
+ st.session_state.current_step = 5
794
+ st.rerun()
795
+
796
+
797
+ # ============================================================
798
+ # STEP 5: EVIDENCE UPLOAD
799
+ # ============================================================
800
+
801
+ def render_step_5_evidence():
802
+ """Render the evidence upload step."""
803
+
804
+ st.header("πŸ“· Step 5: Evidence (Optional)")
805
+
806
+ st.markdown("""
807
+ <div class="info-card">
808
+ <h4>Upload Evidence Photos</h4>
809
+ <p>Upload photos of the accident scene, vehicle damage, or any other relevant evidence. This is optional but recommended.</p>
810
+ </div>
811
+ """, unsafe_allow_html=True)
812
+
813
+ # Evidence upload
814
+ render_evidence_upload()
815
+
816
+ # Quick summary of data entered so far
817
+ st.markdown("---")
818
+ st.subheader("πŸ“‹ Data Summary")
819
+
820
+ col1, col2, col3 = st.columns(3)
821
+
822
+ with col1:
823
+ st.markdown("**πŸ“ Location**")
824
+ st.write(f"{st.session_state.accident_info['location'].get('name', 'Not set')}")
825
+ st.write(f"Type: {st.session_state.accident_info.get('road_type', 'N/A').replace('_', ' ').title()}")
826
+
827
+ with col2:
828
+ st.markdown("**πŸš™ Vehicle 1**")
829
+ # Defensive check - ensure vehicle_1 is a dict
830
+ v1 = st.session_state.vehicle_1
831
+ if isinstance(v1, dict):
832
+ st.write(f"{v1.get('type', 'sedan').title()} @ {v1.get('speed', 50)} km/h")
833
+ else:
834
+ st.write("Vehicle 1 data")
835
+ party1_name = st.session_state.party_1.get('full_name', '') if isinstance(st.session_state.party_1, dict) else ''
836
+ if party1_name:
837
+ st.write(f"Driver: {party1_name}")
838
+
839
+ with col3:
840
+ st.markdown("**πŸš— Vehicle 2**")
841
+ # Defensive check - ensure vehicle_2 is a dict
842
+ v2 = st.session_state.vehicle_2
843
+ if isinstance(v2, dict):
844
+ st.write(f"{v2.get('type', 'sedan').title()} @ {v2.get('speed', 50)} km/h")
845
+ else:
846
+ st.write("Vehicle 2 data")
847
+ party2_name = st.session_state.party_2.get('full_name', '') if isinstance(st.session_state.party_2, dict) else ''
848
+ if party2_name:
849
+ st.write(f"Driver: {party2_name}")
850
+
851
+ # Navigation buttons
852
+ st.markdown("---")
853
+ col1, col2, col3 = st.columns([1, 2, 1])
854
+ with col1:
855
+ if st.button("← Back to Parties"):
856
+ st.session_state.current_step = 4
857
+ st.rerun()
858
+ with col3:
859
+ if st.button("Run Analysis β†’", type="primary"):
860
+ st.session_state.current_step = 6
861
+ st.rerun()
862
+
863
+
864
+ # ============================================================
865
+ # STEP 6: AI ANALYSIS
866
+ # ============================================================
867
+
868
+ def render_step_6_analysis():
869
+ """Render the AI analysis step."""
870
+
871
+ st.header("πŸ€– Step 4: AI Analysis")
872
+
873
+ st.markdown("""
874
+ <div class="info-card">
875
+ <h4>MindSpore AI Analysis</h4>
876
+ <p>Review the accident data below and click "Run AI Analysis" to generate possible scenarios.</p>
877
+ </div>
878
+ """, unsafe_allow_html=True)
879
+
880
+ # Data validation
881
+ validation_passed = True
882
+ validation_messages = []
883
+
884
+ # Check paths
885
+ if not st.session_state.vehicle_1.get('path'):
886
+ validation_messages.append("⚠️ Vehicle 1 path not defined - will use direction-based estimation")
887
+ if not st.session_state.vehicle_2.get('path'):
888
+ validation_messages.append("⚠️ Vehicle 2 path not defined - will use direction-based estimation")
889
+
890
+ # Summary of inputs in cards
891
+ st.subheader("πŸ“‹ Input Data Summary")
892
+
893
+ col1, col2, col3 = st.columns(3)
894
+
895
+ with col1:
896
+ st.markdown("""
897
+ <div style='background: rgba(59, 130, 246, 0.15); padding: 1rem; border-radius: 12px; border-left: 4px solid #3b82f6; box-shadow: 0 4px 12px rgba(0,0,0,0.2);'>
898
+ <h4 style='margin:0; color:#60a5fa; font-weight: 700;'>πŸ“ Location</h4>
899
+ </div>
900
+ """, unsafe_allow_html=True)
901
+ st.write(f"**{st.session_state.accident_info['location'].get('name', 'Unknown')}**")
902
+ st.write(f"πŸ›£οΈ Type: `{st.session_state.accident_info['road_type']}`")
903
+ st.write(f"🌀️ Weather: `{st.session_state.accident_info['weather']}`")
904
+ st.write(f"πŸ›€οΈ Road: `{st.session_state.accident_info['road_condition']}`")
905
+ st.write(f"πŸ“… {st.session_state.accident_info.get('datetime', 'Not specified')}")
906
+
907
+ with col2:
908
+ st.markdown("""
909
+ <div style='background: rgba(255, 75, 75, 0.15); padding: 1rem; border-radius: 12px; border-left: 4px solid #FF4B4B; box-shadow: 0 4px 12px rgba(0,0,0,0.2);'>
910
+ <h4 style='margin:0; color:#ff6b6b; font-weight: 700;'>πŸš™ Vehicle 1 (Red)</h4>
911
+ </div>
912
+ """, unsafe_allow_html=True)
913
+ v1 = st.session_state.vehicle_1 if isinstance(st.session_state.vehicle_1, dict) else {'type': 'sedan', 'speed': 50, 'direction': 'north', 'action': 'going_straight', 'path': []}
914
+ st.write(f"**Type:** {v1.get('type', 'sedan').title()}")
915
+ st.write(f"**Speed:** {v1.get('speed', 50)} km/h")
916
+ st.write(f"**Direction:** {v1.get('direction', 'north').title()}")
917
+ st.write(f"**Action:** {v1.get('action', 'going_straight').replace('_', ' ').title()}")
918
+ path_status = "βœ… Defined" if v1.get('path') else "⚠️ Not set"
919
+ st.write(f"**Path:** {path_status}")
920
+
921
+ with col3:
922
+ st.markdown("""
923
+ <div style='background: rgba(75, 123, 255, 0.15); padding: 1rem; border-radius: 12px; border-left: 4px solid #4B7BFF; box-shadow: 0 4px 12px rgba(0,0,0,0.2);'>
924
+ <h4 style='margin:0; color:#6b9bff; font-weight: 700;'>πŸš— Vehicle 2 (Blue)</h4>
925
+ </div>
926
+ """, unsafe_allow_html=True)
927
+ v2 = st.session_state.vehicle_2 if isinstance(st.session_state.vehicle_2, dict) else {'type': 'sedan', 'speed': 50, 'direction': 'east', 'action': 'going_straight', 'path': []}
928
+ st.write(f"**Type:** {v2.get('type', 'sedan').title()}")
929
+ st.write(f"**Speed:** {v2.get('speed', 50)} km/h")
930
+ st.write(f"**Direction:** {v2.get('direction', 'east').title()}")
931
+ st.write(f"**Action:** {v2.get('action', 'going_straight').replace('_', ' ').title()}")
932
+ path_status = "βœ… Defined" if v2.get('path') else "⚠️ Not set"
933
+ st.write(f"**Path:** {path_status}")
934
+
935
+ # Show validation messages
936
+ if validation_messages:
937
+ st.markdown("---")
938
+ for msg in validation_messages:
939
+ st.warning(msg)
940
+
941
+ st.markdown("---")
942
+
943
+ # Analysis section
944
+ st.subheader("πŸš€ Run Analysis")
945
+
946
+ col1, col2, col3 = st.columns([1, 2, 1])
947
+
948
+ with col2:
949
+ if st.button("🧠 Run MindSpore AI Analysis", type="primary", use_container_width=True):
950
+
951
+ # Progress bar
952
+ progress_bar = st.progress(0)
953
+ status_text = st.empty()
954
+
955
+ try:
956
+ # Step 1: Validate data
957
+ status_text.text("Step 1/4: Validating input data...")
958
+ progress_bar.progress(10)
959
+ import time
960
+ time.sleep(0.5)
961
+
962
+ # Step 2: Extract features
963
+ status_text.text("Step 2/4: Extracting features...")
964
+ progress_bar.progress(30)
965
+ time.sleep(0.5)
966
+
967
+ # Step 3: Run AI model
968
+ status_text.text("Step 3/4: Running MindSpore AI model...")
969
+ progress_bar.progress(50)
970
+
971
+ # Import and run analysis
972
+ from analysis.scenario_analyzer import analyze_accident
973
+
974
+ results = analyze_accident(
975
+ accident_info=st.session_state.accident_info,
976
+ vehicle_1=st.session_state.vehicle_1,
977
+ vehicle_2=st.session_state.vehicle_2
978
+ )
979
+
980
+ progress_bar.progress(80)
981
+ time.sleep(0.3)
982
+
983
+ # Step 4: Generate scenarios
984
+ status_text.text("Step 4/4: Generating scenarios...")
985
+ progress_bar.progress(100)
986
+
987
+ # Store results
988
+ st.session_state.analysis_results = results
989
+ st.session_state.scenarios = results.get('scenarios', [])
990
+ st.session_state.analysis_ready = True
991
+
992
+ status_text.empty()
993
+ progress_bar.empty()
994
+
995
+ # Success message
996
+ st.success(f"""
997
+ βœ… **Analysis Complete!**
998
+
999
+ - Generated **{len(st.session_state.scenarios)}** possible scenarios
1000
+ - Most likely: **{results.get('most_likely_scenario', {}).get('type', 'Unknown').replace('_', ' ').title()}**
1001
+ - Confidence: **{results.get('overall_collision_probability', 0)*100:.1f}%**
1002
+ """)
1003
+
1004
+ except Exception as e:
1005
+ st.error(f"❌ Analysis failed: {str(e)}")
1006
+ progress_bar.empty()
1007
+ status_text.empty()
1008
+
1009
+ # Show results preview if available
1010
+ if st.session_state.analysis_results:
1011
+ st.markdown("---")
1012
+ st.subheader("πŸ“Š Quick Results Preview")
1013
+
1014
+ results = st.session_state.analysis_results
1015
+ scenarios = st.session_state.scenarios
1016
+
1017
+ # Quick metrics
1018
+ metric_cols = st.columns(4)
1019
+
1020
+ with metric_cols[0]:
1021
+ st.metric(
1022
+ "Scenarios Generated",
1023
+ len(scenarios)
1024
+ )
1025
+
1026
+ with metric_cols[1]:
1027
+ most_likely = results.get('most_likely_scenario', {})
1028
+ st.metric(
1029
+ "Most Likely",
1030
+ f"#{most_likely.get('id', 1)}"
1031
+ )
1032
+
1033
+ with metric_cols[2]:
1034
+ prob = results.get('overall_collision_probability', 0) * 100
1035
+ st.metric(
1036
+ "Collision Certainty",
1037
+ f"{prob:.1f}%"
1038
+ )
1039
+
1040
+ with metric_cols[3]:
1041
+ fault = results.get('preliminary_fault_assessment', {})
1042
+ st.metric(
1043
+ "Primary Factor",
1044
+ fault.get('primary_factor', 'Unknown').replace('_', ' ').title()[:15]
1045
+ )
1046
+
1047
+ # Top scenarios
1048
+ st.write("**Top Scenarios:**")
1049
+ for i, scenario in enumerate(scenarios[:3], 1):
1050
+ prob_pct = scenario['probability'] * 100
1051
+ st.write(f"{i}. **{scenario['accident_type'].replace('_', ' ').title()}** - {prob_pct:.1f}%")
1052
+
1053
+ # Navigation
1054
+ st.markdown("---")
1055
+ col1, col2, col3 = st.columns([1, 2, 1])
1056
+ with col1:
1057
+ if st.button("← Back to Evidence"):
1058
+ st.session_state.current_step = 5
1059
+ st.rerun()
1060
+
1061
+ with col3:
1062
+ if st.session_state.analysis_results:
1063
+ if st.button("View Full Results β†’", type="primary"):
1064
+ st.session_state.current_step = 7
1065
+ st.rerun()
1066
+
1067
+
1068
+ # ============================================================
1069
+ # STEP 7: RESULTS
1070
+ # ============================================================
1071
+
1072
+ def render_step_7_results():
1073
+ """Render the results step."""
1074
+
1075
+ st.header("πŸ“Š Step 7: Analysis Results")
1076
+
1077
+ if not st.session_state.analysis_results:
1078
+ st.warning("No analysis results available. Please run the analysis first.")
1079
+ if st.button("← Go to Analysis"):
1080
+ st.session_state.current_step = 6
1081
+ st.rerun()
1082
+ return
1083
+
1084
+ # Render full results
1085
+ render_results()
1086
+
1087
+ # Navigation
1088
+ col1, col2, col3 = st.columns([1, 2, 1])
1089
+ with col1:
1090
+ if st.button("← Back to Analysis"):
1091
+ st.session_state.current_step = 6
1092
+ st.rerun()
1093
+
1094
+ with col3:
1095
+ if st.button("πŸ”„ Start New Analysis"):
1096
+ # Reset session state
1097
+ for key in list(st.session_state.keys()):
1098
+ del st.session_state[key]
1099
+ st.rerun()
1100
+
1101
+
1102
+ # ============================================================
1103
+ # RUN APPLICATION
1104
+ # ============================================================
1105
 
1106
+ if __name__ == "__main__":
1107
+ main()