drguilhermeapolinario commited on
Commit
9ce4842
·
verified ·
1 Parent(s): fa8af2c

Update views/pdf_chat.py

Browse files
Files changed (1) hide show
  1. views/pdf_chat.py +498 -1
views/pdf_chat.py CHANGED
@@ -137,8 +137,505 @@ if nested_menu == "Incidências radiológicas":
137
  Feito com ❤️ e ☕ por **[Dr. Guilherme]**
138
  """)
139
 
140
- elif nested_menu == "RAG":
 
 
 
 
 
 
141
  st.header("RAG")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
142
 
143
  elif nested_menu == "Geral":
144
  st.header("Geral")
 
137
  Feito com ❤️ e ☕ por **[Dr. Guilherme]**
138
  """)
139
 
140
+ elif nested_menu == "RAG":
141
+ import pathlib
142
+
143
+ import streamlit as st
144
+ import streamlit.components.v1 as components
145
+ from streamlit_extras.add_vertical_space import add_vertical_space
146
+
147
  st.header("RAG")
148
+
149
+ static_dir = pathlib.Path('static').absolute()
150
+ html_with_js= ''
151
+
152
+ @st.fragment
153
+ def estilo():
154
+ css_file_path = static_dir / 'styles.css'
155
+ if css_file_path.exists():
156
+ with open(css_file_path, "r", encoding="utf-8") as f:
157
+ st_css = st.html(f"<style>{f.read()}</style>")
158
+ return st_css
159
+ else:
160
+ st.error(f"CSS file not found: {css_file_path}")
161
+ return None
162
+
163
+ @st.fragment
164
+ def linha_vertical(altura=300, cor='black', espessura=2):
165
+ """
166
+ Cria uma linha vertical
167
+ """
168
+ css = f"""
169
+ <style>
170
+ .linha-vertical {{
171
+ border-left: {espessura}px solid {cor};
172
+ height: {altura}px;
173
+ position: absolute;
174
+ left: 50%;
175
+ margin-left: -{espessura/2}px;
176
+ }}
177
+ </style>
178
+ """
179
+ html = f"{css}<div class='linha-vertical'></div>"
180
+ linha=st.markdown(html, unsafe_allow_html=True)
181
+ return linha
182
+
183
+
184
+ @st.fragment
185
+ def calc(html_with_js):
186
+ html_with_js = '''
187
+ <!DOCTYPE html>
188
+ <html lang="pt-BR">
189
+ <head>
190
+ <meta charset="UTF-8">
191
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
192
+ <title>Calculadora CKD-EPI</title>
193
+ <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
194
+ <style>
195
+ body {
196
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
197
+ background-color: #e0e5ec;
198
+ color: #333;
199
+ line-height: 1.6;
200
+ padding: 20px;
201
+ margin: 0;
202
+ }
203
+ .container {
204
+ width: 300px;
205
+ max-height: 600px;
206
+ margin: 0 auto;
207
+ background-color: #e0e5ec;
208
+ border-radius: 20px;
209
+ padding: 20px;
210
+ box-shadow:
211
+ 8px 8px 15px #a3b1c6,
212
+ -8px -8px 15px #ffffff;
213
+ }
214
+ h2 {
215
+ color: #4a4a4a;
216
+ text-shadow: 2px 2px 4px rgba(255,255,255,0.5);
217
+ text-align: center;
218
+ margin-bottom: 20px;
219
+ }
220
+ .input-group {
221
+ margin-bottom: 20px;
222
+ position: relative;
223
+ }
224
+ .input-group label {
225
+ display: block;
226
+ margin-bottom: 5px;
227
+ color: #4a4a4a;
228
+ padding-left: 40px;
229
+ }
230
+ .input-field {
231
+ width: 50%;
232
+ padding: 12px 20px;
233
+ margin-left: 50px;
234
+ border: none;
235
+ border-radius: 25px;
236
+ background-color: #e0e5ec;
237
+ color: #333;
238
+ font-size: 16px;
239
+ box-shadow:
240
+ inset 5px 5px 10px #a3b1c6,
241
+ inset -5px -5px 10px #ffffff;
242
+ }
243
+ .icon-wrapper {
244
+ position: absolute;
245
+ left: 0;
246
+ top: 0;
247
+ width: 36px;
248
+ height: 36px;
249
+ background-color: #e0e5ec;
250
+ border-radius: 50%;
251
+ display: flex;
252
+ align-items: center;
253
+ justify-content: center;
254
+ box-shadow:
255
+ 5px 5px 10px #a3b1c6,
256
+ -5px -5px 10px #ffffff;
257
+ }
258
+ .input-icon {
259
+ color: #4a4a4a;
260
+ font-size: 18px;
261
+ }
262
+ .toggle-container {
263
+ display: flex;
264
+ justify-content: space-between;
265
+ align-items: center;
266
+ margin-bottom: 20px;
267
+ }
268
+ .toggle-switch {
269
+ position: relative;
270
+ display: inline-block;
271
+ width: 60px;
272
+ height: 34px;
273
+ }
274
+ .toggle-switch input {
275
+ opacity: 0;
276
+ width: 0;
277
+ height: 0;
278
+ }
279
+ .slider {
280
+ position: absolute;
281
+ cursor: pointer;
282
+ top: 0;
283
+ left: 0;
284
+ right: 0;
285
+ bottom: 0;
286
+ background-color: #e0e5ec;
287
+ transition: .4s;
288
+ border-radius: 34px;
289
+ box-shadow:
290
+ inset 4px 4px 6px #a3b1c6,
291
+ inset -4px -4px 6px #ffffff;
292
+ }
293
+ .slider:before {
294
+ position: absolute;
295
+ content: "";
296
+ height: 26px;
297
+ width: 26px;
298
+ left: 4px;
299
+ bottom: 4px;
300
+ background-color: #e0e5ec;
301
+ transition: .4s;
302
+ border-radius: 50%;
303
+ box-shadow:
304
+ 2px 2px 3px #a3b1c6,
305
+ -2px -2px 3px #ffffff;
306
+ }
307
+ input:checked + .slider:before {
308
+ transform: translateX(26px);
309
+ }
310
+ .button-group {
311
+ display: flex;
312
+ justify-content: space-between;
313
+ margin-top: 20px;
314
+ }
315
+ .button {
316
+ flex: 1;
317
+ padding: 12px 24px;
318
+ background-color: #e0e5ec;
319
+ border: none;
320
+ border-radius: 50px;
321
+ color: #4a4a4a;
322
+ font-weight: bold;
323
+ text-decoration: none;
324
+ transition: all 0.3s ease;
325
+ box-shadow:
326
+ 5px 5px 10px #a3b1c6,
327
+ -5px -5px 10px #ffffff;
328
+ cursor: pointer;
329
+ margin: 0 5px;
330
+ }
331
+ .button:hover {
332
+ box-shadow:
333
+ inset 5px 5px 10px #a3b1c6,
334
+ inset -5px -5px 10px #ffffff;
335
+ }
336
+ #result {
337
+ display: none;
338
+ margin-top: 10px;
339
+ padding: 10px;
340
+ border-radius: 15px;
341
+ background-color: #e0e5ec;
342
+ box-shadow:
343
+ inset 5px 5px 10px #a3b1c6,
344
+ inset -5px -5px 10px #ffffff;
345
+ }
346
+ #result h3 {
347
+ margin-top: 0;
348
+ color: #4a4a4a;
349
+ }
350
+
351
+ }
352
+ .toggle-container {
353
+ display: flex;
354
+ justify-content: space-between;
355
+ align-items: center;
356
+ margin-bottom: 20px;
357
+ }
358
+
359
+ .gender-label {
360
+ display: flex;
361
+ align-items: center;
362
+ color: #4a4a4a;
363
+ }
364
+ .gender-icon {
365
+ margin-right: 5px;
366
+ font-size: 18px;
367
+ }
368
+ .toggle-switch {
369
+ position: relative;
370
+ display: inline-block;
371
+ width: 60px;
372
+ height: 34px;
373
+ }
374
+ .toggle-switch input {
375
+ opacity: 0;
376
+ width: 0;
377
+ height: 0;
378
+ }
379
+ .slider {
380
+ position: absolute;
381
+ cursor: pointer;
382
+ top: 0;
383
+ left: 0;
384
+ right: 0;
385
+ bottom: 0;
386
+ background-color: #e0e5ec;
387
+ transition: .4s;
388
+ border-radius: 34px;
389
+ box-shadow:
390
+ inset 4px 4px 6px #a3b1c6,
391
+ inset -4px -4px 6px #ffffff;
392
+ }
393
+ .slider:before {
394
+ position: absolute;
395
+ content: "";
396
+ height: 26px;
397
+ width: 26px;
398
+ left: 4px;
399
+ bottom: 4px;
400
+ background-color: #e0e5ec;
401
+ transition: .4s;
402
+ border-radius: 50%;
403
+ box-shadow:
404
+ 2px 2px 3px #a3b1c6,
405
+ -2px -2px 3px #ffffff;
406
+ }
407
+ input:checked + .slider:before {
408
+ transform: translateX(26px);
409
+ }
410
+ </style>
411
+ </head>
412
+ <body>
413
+ <div class="container">
414
+ <h2>Calculadora CKD-EPI</h2>
415
+ <form id="ckd-epi-form">
416
+ <div class="input-group">
417
+ <div class="icon-wrapper">
418
+ <i class="fas fa-birthday-cake input-icon"></i>
419
+ </div>
420
+ <label for="age">Idade</label>
421
+ <input type="number" id="age" class="input-field" required>
422
+ </div>
423
+ <div class="toggle-container">
424
+ <span class="gender-label">
425
+ <i class="fas fa-mars gender-icon"></i>
426
+ Masculino
427
+ </span>
428
+ <label class="toggle-switch">
429
+ <input type="checkbox" id="gender-toggle">
430
+ <span class="slider"></span>
431
+ </label>
432
+ <span class="gender-label">
433
+ <i class="fas fa-venus gender-icon"></i>
434
+ Feminino
435
+ </span>
436
+ </div>
437
+ <div class="input-group">
438
+ <div class="icon-wrapper">
439
+ <i class="fas fa-vial input-icon"></i>
440
+ </div>
441
+ <label for="serumCreatinine">Creatinina Sérica (mg/dL)</label>
442
+ <input type="number" id="serumCreatinine" class="input-field" step="0.01" required>
443
+ </div>
444
+ <div class="button-group">
445
+ <button type="button" id="calcular" class="button">Calcular</button>
446
+ <button type="button" id="clear-button" class="button">Limpar</button>
447
+ </div>
448
+ </form>
449
+ <div id="result"></div>
450
+ </div>
451
+
452
+ <script>
453
+ document.getElementById("calcular").addEventListener("click", calculate);
454
+
455
+ function calculate() {
456
+ const age = parseFloat(document.getElementById("age").value);
457
+ const serumCreatinine = parseFloat(document.getElementById("serumCreatinine").value);
458
+ const gender = document.getElementById('gender-toggle').checked ? 'female' : 'male';
459
+
460
+ if (!isNaN(age) && !isNaN(serumCreatinine)) {
461
+ let A, B = 0;
462
+ if (serumCreatinine <= 0.7) {
463
+ A = gender === "male" ? 0.9 : 0.7;
464
+ B = gender === "male" ? -0.302 : -0.241;
465
+ } else {
466
+ A = gender === "male" ? 0.9 : 0.7;
467
+ B = -1.2;
468
+ }
469
+ let result = 142 * Math.pow((serumCreatinine/A), B) * Math.pow(0.9938, age);
470
+ if (gender == 'female') result = result * 1.012;
471
+
472
+ const stage = getCKDStage(result);
473
+
474
+ const resultElement = document.getElementById('result');
475
+ resultElement.innerHTML = `
476
+ <h4>Resultado:</h4>
477
+ <p>eGFR CKD-EPI: <strong><span class="h3">${result.toFixed(0)} <span class="h4">mL/min/1.73 m²</span></span></strong></p>
478
+ <p>Estágio DRC: <strong>${stage}</strong></p>
479
+ `;
480
+ resultElement.style.display = 'block';
481
+ } else {
482
+ alert("Por favor, preencha todos os campos corretamente.");
483
+ }
484
+ }
485
+
486
+ function getCKDStage(gfr) {
487
+ if (gfr >= 90) return "Estágio 1";
488
+ if (gfr >= 60) return "Estágio 2";
489
+ if (gfr >= 45) return "Estágio 3a";
490
+ if (gfr >= 30) return "Estágio 3b";
491
+ if (gfr >= 15) return "Estágio 4";
492
+ return "Estágio 5";
493
+ }
494
+
495
+ document.getElementById('clear-button').addEventListener('click', function() {
496
+ document.getElementById('ckd-epi-form').reset();
497
+ document.getElementById('result').innerHTML = '';
498
+ document.getElementById('result').style.display = 'none';
499
+ });
500
+
501
+ </script>
502
+ </body>
503
+ </html>
504
+ '''
505
+ calculadora = components.html(html_with_js, width=400,height=900)
506
+ return calculadora
507
+
508
+ @st.fragment
509
+ def icon_close():
510
+ st.markdown("""
511
+ <style>
512
+ .stKey-icon-wrapper {
513
+ position: absolute;
514
+ left: -22px;
515
+ top: 0;
516
+ width: 180px;
517
+ height: 180px;
518
+ background-color: #e0e5ec;
519
+ border-radius: 50%;
520
+ display: flex;
521
+ align-items: center;
522
+ justify-content: center;
523
+ padding: 5px;
524
+
525
+ box-shadow:
526
+ 5px 5px 10px #a3b1c6,
527
+ -5px -5px 10px #ffffff;
528
+ }
529
+ .stKey-icon-wrapper img {
530
+ width: 24px;
531
+ height: 24px;
532
+ filter: invert(20%) sepia(10%) saturate(2076%) hue-rotate(86deg) brightness(95%) contrast(86%);
533
+ }
534
+ </style>
535
+ """, unsafe_allow_html=True)
536
+
537
+ with st.container():
538
+ st.markdown('<div class="stKey-icon-wrapper">', unsafe_allow_html=True)
539
+ st.image('icon/rim.svg', use_column_width=False, width=140)
540
+ icon_top= st.markdown('</div>', unsafe_allow_html=True)
541
+ return icon_top
542
+
543
+ def main():
544
+ estilo()
545
+ cx1,cx2,cx3=st.columns([3,1,6])
546
+
547
+ with cx1:
548
+ icon_close()
549
+ with cx2:
550
+ st.write('')
551
+
552
+ cx3.title('''
553
+ :blue[Calculadora TFG] :blue[| CKD-EPI] 📝
554
+ ''' )
555
+
556
+ c1, c2, c3, c4 = st.columns([2,0.5,3,3])
557
+ with c1:
558
+ calc(html_with_js)
559
+ with c2:
560
+ add_vertical_space()
561
+ # linha_vertical(altura=800, cor='#73A6E2', espessura=2)
562
+ with c3:
563
+ expander = st.expander("Estágios da DRC", expanded=False, icon='📝')
564
+ expander.write('''
565
+ # Estagios da IRC:
566
+
567
+ - **Estágio 1:**
568
+ - TFG ≥ 90 mL/min/1.73m²
569
+ - (Função renal normal ou aumentada)
570
+
571
+ - **Estágio 2:**
572
+ - TFG 60-89 mL/min/1.73m²
573
+ - (Diminuição leve da função renal)
574
+
575
+ - **Estágio 3a:**
576
+ - TFG 45-59 mL/min/1.73m²
577
+ - (Diminuição leve a moderada da função renal)
578
+
579
+ - **Estágio 3b:**
580
+ - TFG 30-44 mL/min/1.73m²
581
+ - :blue[(Diminuição moderada a severa da função renal)]
582
+
583
+ - **Estágio 4:**
584
+ - TFG 15-29 mL/min/1.73m²
585
+ - :orange[(Diminuição severa da função renal)]
586
+
587
+ - **Estágio 5:**
588
+ - TFG < 15 mL/min/1.73m²
589
+ - :red[(Falência renal)]
590
+
591
+
592
+ ''')
593
+
594
+ with c4:
595
+ recomendacoes= ('''
596
+
597
+ ## Recomendações gerais para pacientes com DRC
598
+ :green[As diretrizes KDIGO 2024 incorporou a TFG e a albuminúria como fatores críticos.]
599
+
600
+ :blue[**1. Estágios 1 e 2 (TFG ≥ 60 mL/min/1,73m²):**]
601
+ ###### Monitoramento Regular: Avaliação periódica da função renal e da albuminúria é recomendada para detectar progressão da doença.
602
+
603
+ ###### Controle de Fatores de Risco: Controle rigoroso da pressão arterial e glicemia, especialmente em pacientes com diabetes, é essencial.
604
+
605
+ ###### Modificações no Estilo de Vida: Incentivar dieta saudável, cessação do tabagismo e atividade física regular.
606
+
607
+ :blue[**2. Estágio 3a e 3b (TFG 30-59 mL/min/1,73m²):**]
608
+
609
+ ###### Ajuste de Medicamentos: Revisão e ajuste de dosagens de medicamentos que são excretados pelos rins.
610
+
611
+ ###### Avaliação de Risco Cardiovascular: A albuminúria e a TFG devem ser usadas para avaliar o risco cardiovascular e ajustar o tratamento.
612
+
613
+ ###### Referência a Nefrologista: Considerar encaminhamento para um nefrologista para manejo especializado.
614
+
615
+ :blue[**3. Estágio 4 (TFG 15-29 mL/min/1,73m²):**]
616
+
617
+ ###### Preparação para Terapia de Substituição Renal: Discussão sobre opções de diálise e transplante renal deve ser iniciada.
618
+ ###### Monitoramento Intensivo: Acompanhamento mais frequente para monitorar a progressão da doença e complicações associadas.
619
+
620
+ :blue[**4. Estágio 5 (TFG < 15 mL/min/1,73m²):**]
621
+ ###### Terapia de Substituição Renal: Início de diálise ou avaliação para transplante renal.
622
+ ###### Cuidados Paliativos: Considerar cuidados paliativos para pacientes que não são candidatos a diálise ou transplante.
623
+
624
+ _Além disso, a quantificação da albuminúria é crucial em todos os estágios
625
+ para guiar decisões terapêuticas, como a escolha de medicamentos anti-
626
+ hipertensivos. A avaliação individualizada, considerando a situação clínica
627
+ do paciente, é fundamental para o manejo eficaz da DRC._
628
+
629
+ ''')
630
+
631
+ with st.expander(label='Recomendações', expanded=False, icon="🔥"):
632
+ st.markdown(recomendacoes, unsafe_allow_html=True)
633
+
634
+ if __name__ == '__main__':
635
+ main()
636
+
637
+
638
+
639
 
640
  elif nested_menu == "Geral":
641
  st.header("Geral")