
    byjO                       d Z ddlmZ ddlZddlZddlZddlZddlZddlm	Z	 ddl
m
Z
 ddlmZ ddlmZ ddlmZ  ej"                         d	z  d
z  dz  Zedz  Zedz  ZddlZej,                  j/                  d eedz               ddlmZmZmZmZmZ ddlm Z!m"Z#m$Z% g dZ&ddZ'ddZ(d dZ)d!dZ*d"dZ+d#dZ,d$dZ-d%dZ.d&dZ/d'dZ0d(dZ1e2dk(  r e1        yy))a  JARVIS Health Dashboard v3.1.

Robust Chart.js dashboard:
- laboratory trend charts with reference ranges and clinical-event markers
- Apple Health Auto Export modules (sleep/HRV/pulse/activity/SpO2/respiration)
- nutrition adherence
- doctor-report PDF link / Drive upload metadata
    )annotationsN)defaultdict)datetime)Path)mean)Anyz.hermesassets
Gesundheitzhealth_data.dbreportsscripts)best_reference_xlsxparse_reference_xlsxget_lab_matrixsplit_reference	db_counts)daily_seriesunit_forsummary))
step_countSchrittesum)walking_running_distancezGeh-/Laufdistanzr   )resting_heart_rateRuhepulsavg)
heart_rateHerzfrequenzr   )heart_rate_variabilityHRVr   )sleep_analysisSchlafdauerr   )blood_oxygen_saturationu   SpO₂r   )respiratory_rateAtemfrequenzr   )active_energyzAktive Energier   )physical_effortzPhysical Effortr   )weight_body_massGewichtr   c                 b    t        j                  t              } t         j                  | _        | S N)sqlite3connectDBRowrow_factory)cs    D/home/agent/.hermes/assets/Gesundheit/scripts/health_dashboard_v3.pyconnr2   /   s     AKKAMH    c                 j   | D ]  }|st        |      }t        t        j                  j	                  |            t
        |z  t        d      |z  t        |j                  dt        t
                          fD ]'  }	 |j                         r|j                         c c S )  y # t        $ r Y 8w xY w)Nz/home/agentz/home/agent/Gesundheit)
strr   ospath
expanduserBASEreplaceexistsresolveOSError)valuesvaluerawps       r1   resolve_doc_pathrB   5   s     	%jrww))#./T-=PSV=VX\]`]h]h  jB  DG  HL  DM  ^N  YO  P 	A88:99;& 			   s   =B&&	B21B2c                    | j                         }d|v r| d   rt        | d         S g }d|v r|j                  | d          d|v r|j                  | d          t        | }|rdt        |      z   S d S )Ndrive_web_urllocal_original_path	dateipfadzfile://)keysr5   appendrB   )rowrG   valsrA   s       r1   doc_urlrK   C   s    88:D$3#73'((D$dkk#6K2L&MdDKKK(89$A!"9s1v,,r3   c                    t        j                  t        | d               }t        |       }|rdt        j                  |       d| dS |S )N
datei_namez	<a href='z' target='_blank'>z</a>)htmlescaper5   rK   )rI   nameurls      r1   link_docrR   N   sK    ;;s3|,-.D
#,CILYt{{3'((:4&EVRVVr3   c                    	 t        t        |       j                  dd      j                  dd      j                  dd      j                               S # t        $ r Y y w xY w)N,.< >)floatr5   r:   strip	Exception)xs    r1   numr]   T   sV    SV^^C-55c2>FFsBOUUWXX s   AA 	A A c                L    t        |       \  }}}t        |      t        |      fS r*   )r   r]   )refrminrmax_s       r1   ref_numsrc   [   s%    #C(MD$t9c$ir3   c                   | xs dj                         g dg dg dg dg dg dg dd	}g d
g dg dd}t        |j                         D ch c]  \  }}t        fd|D              s| c}}      }t        |j                         D ch c]  \  }}t        fd|D              s| c}}      }t	        dt        dddt        |      z  z   dt        |      z  z
              }|||d|v rdndd|v rdndd|v rdndt        d|v       t        d|v       t        d|v       t        d|v       d|v rdndd|v rdnd d!|v rd"d$S d#d$S c c}}w c c}}w )%NrW   )schwein	bratwurstsalamispeckschinken)u   hörnlihoernliweizenpastabrotpizza	teigwaren)tortekuchenu   süsssuesszuckerdessertglace)u   alter käsekaeserotweinrg   fermentbierwein)tomate	aubergine	kartoffelpaprikapeperoni)butterrf   kokosrahmsahnerh   )alkoholry   rz   u   panachépanache)SchweinefleischWeizen/GlutenIndustriezuckerHistaminNachtschatten   Gesättigte FetteAlkohol)lachssardinemakreleforellefischu   algenölalgenoel)haferlinsenbohnenu   gemüsegemuesesalatbeeren)skyrquarkhuhnpouleteitofur   )Fisch/Omega-3BallaststoffeProtein gutc              3  &   K   | ]  }|v  
 y wr*    .0wts     r1   	<genexpr>z"nutrition_score.<locals>.<genexpr>p        I`UV!q&I`   c              3  &   K   | ]  }|v  
 y wr*   r   r   s     r1   r   z"nutrition_score.<locals>.<genexpr>q   r   r   r   d   U         r   r   r   r   r   r   r   r   F      r      r   P   
   )scoreneg_hitspos_hits	histaminesatfatsugarglutenpork
nightshadealcoholfiberproteinomega3)lowersorteditemsanymaxminlenint)	text	negatives	positiveslabelwordsr   r   r   r   s	           @r1   nutrition_scorer   `   sC   	AR`^\TWEI e_QI
 1BacI`Z_I`F`uabH1BacI`Z_I`F`uabH3sBS]!22R#h-5GGHIEh\fjr\rUXxy  M`  dl  Ml  FI  rs  EV  Zb  Eb  ~A  hi  ux  yH  LT  yT  uU  _b  ct  x@  c@  _A  QT  Ud  hp  Up  Qq  ~A  BK  OW  BW  ~X  ix  |D  iD  ce  JL  _l  px  _x  Y[  ~@  Ra  em  Rm  LN  v  v  su  v  v bas   E
/E
E
0E
c                "   t        t              }| j                  d      D ]K  |t        d         d d    j	                  dj                  fdj                         D                     M | j                  d      D ]K  |t        d         d d    j	                  dj                  fdj                         D                     M |j                         D ]  \  }}t        dj                  |            }| j                  d||d	   |d
   |d   |d   |d   |d   |d   |d   |d   |d   |d   dj                  |d         dj                  |d         df        | j                          t        | j                  d            S )NzHSELECT datum,beschreibung,wirkung,notizen FROM ernaehrung ORDER BY datumdatumr    c              3  N   K   | ]  }|d k7  s	t        |   xs d        ywr   rW   Nr5   r   krs     r1   r   z-compute_nutrition_features.<locals>.<genexpr>y   &     4gZ[_fZfS1_4g   
%%zqSELECT datum,kategori,titel,inhalt,wirkung,notizen FROM tagebuch WHERE lower(kategori) LIKE 'ern%' ORDER BY datumc              3  N   K   | ]  }|d k7  s	t        |   xs d        ywr   r   r   s     r1   r   z-compute_nutrition_features.<locals>.<genexpr>{   r   r   a{  
            INSERT OR REPLACE INTO nutrition_daily_features
            (datum, plan_adherence_score, histamine_score, saturated_fat_score, sugar_score, gluten_flag, pork_flag, nightshade_flag, alcohol_flag, fiber_proxy, protein_proxy, omega3_proxy, positive_hits, negative_hits, source, computed_at)
            VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,CURRENT_TIMESTAMP)
        r   r   r   r   r   r   r   r   r   r   r   , r   r   dashboard_v31_keyword_heuristicz5SELECT * FROM nutrition_daily_features ORDER BY datum)
r   listexecuter5   rH   joinrG   r   r   commit)r0   by_daydaytextssr   s        @r1   compute_nutrition_featuresr   v   s   #.t#4FYYab is1W:s#$++CHH4gaffh4g,ghiYY  K  L is1W:s#$++CHH4gaffh4g,ghilln ~
UCHHUO,			  1W:q~q{AgJ(UVW]U^`abn`oqrs|q}  @A  BI  @J  LM  NW  LX  Z[  \d  Ze  gk  gp  gp  qr  s}  q~  g  AE  AJ  AJ  KL  MW  KX  AY  [|  }		~~ HHJ		QRSSr3   c                *   t        ||      }|sy t        |      }|D cg c]  }||   	 }}t        |      }|||t        |      |d   |d   |d   t	        t        |      d      t	        t        |      d      t	        t        |      d      d
S c c}w )Nr      )
labelsdataunitcountfirstlastlatestr   r   r   )canonical_apple_dailyr   canonical_apple_unitr   roundr   r   r   )r0   metricmodeseriesr   dr   r   s           r1   apple_seriesr      s    #640FF^F%&!F1I&D&'DdD3t9W]^_W`jpqsjt  AE  FH  AI  RW  X\  ]a  Xb  de  Rf  ot  ux  y}  u~  @A  oB  KP  QT  UY  QZ  \]  K^  _  _ 's   Bc                     t         dz  } | j                         sy 	 t        j                  | j	                  d            S # t
        $ r Y y w xY w)Nzarztbericht_drive_link.jsonutf-8encoding)REPORTSr;   jsonloads	read_textr[   )rA   s    r1   load_doctor_report_metar     sJ    //A88:zz!++w+788 s   $A 	AAc                    t         j                  dd       t               } t               j	                         rt        t                     ng }|rt        |      ng g i i i f\  }}}}}t               }	 t        |j                  d            }t        |j                  d            }	t        |j                  d            }
t        |j                  d            }t        |j                  d            }t        |      }t        D ci c]  \  }}}|t        |||       }}}}|j                          g d}t        t              }|
D ]H  }|t        |d	         d d
    j!                  |d    d|d    d|d   xs d j#                                J |D ]6  }|t        |d         d d
    j!                  d|d    d|d   xs d d       8 g }|D ]  }g }|D ]T  }|j%                  ||f      }|st'        |j(                        /|j!                  |t'        |j(                        f       V |sb|D cg c]  \  }}|	 }}}|D cg c]  \  }}|	 }}}|D cg c]!  }||v s|dj+                  ||         d d d# }}t-        |j%                  |            \  }}t/        j0                  dd|      } |j!                  dt3        j4                  |       dt3        j4                  |j%                  |d             d|  d |  d!t7        j8                  |       d"t7        j8                  |       d"t7        j8                  |       d"t7        j8                  |       d"t7        j8                  |       d"t7        j8                  |d#$       d%        g }!g }"t        D ]^  \  }}#}|j%                  |      }$|$sd&t/        j0                  dd|      z   } |!j!                  dt3        j4                  |#       d't3        j4                  |$d(          d)|$d*    d+|$d,    d-|d.k(  rd/nd0 d1|  d2|  d!t7        j8                  |#       d"t7        j8                  |$d3          d"t7        j8                  |$d4          d"t7        j8                  |$d(          d%       |"j!                  d5t3        j4                  |#       d6|$d*    d+|$d,    d6|$d7    d6|$d8    dt3        j4                  |$d(          d6|$d9    d6|$d:    d6|$d;    d<       a dj+                  d= | j;                         D              }%dj+                  d> |D              }&dj+                  d? |	D              }'dj+                  d@ |
dAd  D              }(dj+                  dB |dAd  D              })dj+                  dC |D              xs dD}*|D cg c]  }|d   	 }+}|D cg c]  }|dE   	 },}|D cg c]  }|dF   xs dG }-}dj+                  dH |dAd  D              }.t=               }/t         dIz  }0|0j	                         r"dJt3        j4                  t        |0             dKndL}1d}2|/rw|/j%                  dM      xs i }3|3j%                  dN      xs4 |3j%                  dOi       j%                  dN      xs |3j%                  dP      }4|4rdQt3        j4                  |4       dR}2t?        j@                         jC                  dS      }5t         dTz  }6dj+                  g dU|5 dV|1 |2 dWtD         dXtD         dY|% dZdj+                  |"       d[dj+                  |!      xs d\ d]dj+                  |      xs d^ d_t7        j8                  |+       d"t7        j8                  |,       d"t7        j8                  |-d#$       d`|. da|* db|' dc|( |) dd|& de      }7|6jG                  |7dfg       t               }|j                  dhdit        |6      djf       |jI                          |j                          tK        |6       y c c}}}w # |j                          w xY wc c}}w c c}}w c c}w c c}w c c}w c c}w )kNT)parentsexist_okzSELECT id,datei_name,dateipfad,kategorie,status,review_status,upload_datum,drive_web_url,local_original_path,length(COALESCE(extrahierte_inhalte,'')) text_len FROM dokumente ORDER BY id DESC LIMIT 25zSELECT id,datei_name,dateipfad,kategorie,status,drive_web_url,local_original_path FROM dokumente WHERE upper(COALESCE(kategorie,'')) LIKE '%LABOR%' ORDER BY id DESC LIMIT 40z
            SELECT date,category,parameter,value,notes,source FROM health_events
            WHERE date IS NOT NULL AND date(date) IS NOT NULL AND upper(COALESCE(category,'')) NOT IN ('LABOR','PROFIL','BEFUNDE')
            ORDER BY date
        zkSELECT datum,kategori,symptom,schwergrad,notizen FROM symptome WHERE date(datum) IS NOT NULL ORDER BY datumzSELECT start_date,end_date,event_type,label,severity,location,notes FROM health_event_periods ORDER BY start_date DESC LIMIT 50)zC-Reaktives Protein (CRP)zBlutsenkungsreaktion miniiSED
LeukozytenNeutrophileLymphozyten
MonozythenThrombozytenFerritin
FibrinogenzD-DimerzFaktor VIIIzCholesterin gesamtzLDL-CholesterinzHDL-CholesterinTriglycerideHomocystein	KreatininzeGFR (Niere)zAlbumin/KreatininProteinBlutErythrozytenz
ALAT (GPT)z
ASAT (GOT)GGTzVitamin D (25-OH)zVitamin B12 (Active)u	   FolsäurezHLA-B51dater   categoryz: 	parameterr   r?   rW   r   z	Symptom: symptomz (
schwergradzn/a)z;    )r\   r   z\W+rb   z!
<section class='chart-card'><h3>z"</h3><div class='muted'>Referenz: z</div><canvas id='z9' height='120'></canvas></section>
<script>makeLabChart('z', r   F)ensure_asciiz);</script>
apple_z!</h3><div class='muted'>Einheit: r   z; Zeitraum: r   z bis r   z; Aggregation: r   SummeDurchschnittz  pro Tag/Woche</div><canvas id='z:' height='110'></canvas></section>
<script>makeLineChart('r   r   <tr><td>	</td><td>r   r   r   r   r   
</td></tr>c              3     K   | ]?  \  }}d t        j                  t        |             dt        j                  |       d A yw)z#<div class='card'><div class='num'>z</div><div>z</div></div>NrN   rO   r5   )r   r   vs      r1   r   zmain.<locals>.<genexpr>   sJ       S{{|~9$++c!f:M9NkZ^ZeZefgZhYiiuv  Ss   AAc              3  &  K   | ]  }d |d    dt        |       dt        j                  t        |d                dt        j                  t        |d                dt        j                  t        |d   xs d             d|d    d  y	w)
r  idr  	kategoriestatusreview_statusrW   text_lenr   NrR   rN   rO   r5   r   r   s     r1   r   zmain.<locals>.<genexpr>   s      {  qr!D')HQK=	$++VYZ[\gZhViJjIkktuy  vA  vA  BE  FG  HP  FQ  BR  vS  uT  T]  ^b  ^i  ^i  jm  no  p  n@  nF  DF  jG  ^H  ]I  IR  ST  U_  S`  Ra  ak  l  {s   BBc              3     K   | ];  }d |d    dt        |       dt        j                  t        |d                d = yw)r  r%  r  r'  r   Nr*  r+  s     r1   r   zmain.<locals>.<genexpr>   sL       K|}XagYi}IdkkZ]^_`h^iZjNkMllvw  Ks   AAc              3  H  K   | ]  }d t        j                  t        |d                dt        j                  t        |d                dt        j                  t        |d                dt        j                  t        |d   xs	 |d   xs d             d	  y	w)
r  r  r  r  r  r?   notesrW   r   Nr"  r+  s     r1   r   zmain.<locals>.<genexpr>   s      s  ab8DKKAfI$?#@	$++VYZ[\fZgVhJiIjjstxtt  AD  EF  GR  ES  AT  uU  tV  V_  `d  `k  `k  lo  pq  ry  pz  pN  ~  @G  ~H  pN  LN  lO  `P  _Q  Q[  \  ss   B B"ic              3  "  K   | ]  }d t        j                  t        |d                dt        j                  t        |d                dt        j                  t        |d   xs d      dz   t        |d   xs d      z          d	  y
w)r  r   z</td><td>Symptom</td><td>r  r  r  rW   r   notizenr   Nr"  r+  s     r1   r   zmain.<locals>.<genexpr>   s       s  _`Xdkk#aj/&B%CC\]a]h]hilmnoxmyiz]{\|  }F  GK  GR  GR  SV  WX  Ye  Wf  Wl  jl  Sm  ps  Ss  vy  z{  |E  zF  zL  JL  vM  SM  GN  FO  OY  Z  ss   BBc              3    K   | ]  }d t        j                  t        |d                dt        j                  t        |d   xs d             dt        j                  t        |d                dt        j                  t        |d   xs d             dt        j                  t        |d   xs d             dt        j                  t        |d	   xs d             d
  yw)r  
start_dater  end_dateoffen
event_typer   rW   severityr.  r   Nr"  r+  s     r1   r   zmain.<locals>.<genexpr>   s      P  CDHT[[Q|_1E%F$GyQUQ\Q\]`abcmanayry]zQ{P|  }F  GK  GR  GR  SV  WX  Ye  Wf  Sg  Gh  Fi  ir  sw  s~  s~  B  CD  EL  CM  CS  QS  T  sU  rV  V_  `d  `k  `k  lo  pq  r|  p}  pC  AC  lD  `E  _F  FO  PT  P[  P[  \_  `a  bi  `j  `p  np  \q  Pr  Os  s}  ~  Ps   C)C+zj<tr><td colspan='6'>Noch keine Zeitraum-Events erfasst. Beispiel: Aphte von Start- bis Enddatum.</td></tr>plan_adherence_scorenegative_hitszkonform/unklarc              3     K   | ]`  }d |d    d|d   ddt        j                  t        |d   xs d             dt        j                  t        |d   xs d             d	 b y	w)
r  r   r  r7  z.0fr8  rW   positive_hitsr   Nr"  r+  s     r1   r   zmain.<locals>.<genexpr>   s       t  VWx'
|9Q?U=VWZ<[[deiepepqtuv  xG  vH  vN  LN  rO  fP  eQ  QZ  [_  [f  [f  gj  kl  m|  k}  kC  AC  gD  [E  ZF  FP  Q  ts   A&A(zarztbericht_aktuell.pdfz<a class='button' href='file://u)   ' target='_blank'>Lokales PDF öffnen</a>z3<span class='muted'>Noch kein PDF generiert.</span>drive_uploadwebViewLinkfile
webViewUrlz <a class='button' href='u1   ' target='_blank'>PDF in Google Drive öffnen</a>z%Y-%m-%d %H:%Mzhealth_dashboard.htmla  <!doctype html><html lang='de'><head><meta charset='utf-8'><title>JARVIS Health Dashboard v3.1</title>
<script src='https://cdn.jsdelivr.net/npm/chart.js@4.5.1/dist/chart.umd.min.js'></script>
<script>
function makeLabChart(id, label, labels, data, rmin, rmax, events) {
  const clean = data.filter(v => v !== null); const maxData = Math.max(...clean); const minData = Math.min(...clean);
  const datasets = [{label: label, data: data, borderColor:'#1f4e78', backgroundColor:'#1f4e78', pointRadius:4, tension:.25}];
  if (rmin !== null && rmax !== null) { datasets.push({label:'Ref min', data: labels.map(_=>rmin), borderColor:'rgba(34,197,94,.25)', pointRadius:0, borderWidth:1}); datasets.push({label:'Referenzbereich', data: labels.map(_=>rmax), borderColor:'rgba(34,197,94,.7)', backgroundColor:'rgba(34,197,94,.12)', pointRadius:0, borderWidth:1, fill:'-1'}); }
  else if (rmax !== null) { datasets.push({label:'Ref max '+rmax, data:labels.map(_=>rmax), borderColor:'#22c55e', borderDash:[6,4], pointRadius:0, borderWidth:2}); }
  else if (rmin !== null) { datasets.push({label:'Ref min '+rmin, data:labels.map(_=>rmin), borderColor:'#22c55e', borderDash:[6,4], pointRadius:0, borderWidth:2}); }
  if (events.length) { const eventData = labels.map(d => events.find(e => e.x === d) ? maxData * 1.08 : null); datasets.push({label:'Health Event', data:eventData, borderColor:'rgba(239,68,68,.0)', backgroundColor:'#ef4444', pointStyle:'triangle', pointRadius:7, showLine:false}); }
  new Chart(document.getElementById(id), {type:'line', data:{labels:labels, datasets:datasets}, options:{responsive:true, maintainAspectRatio:false, interaction:{mode:'index',intersect:false}, plugins:{tooltip:{callbacks:{afterBody:(items)=>{ const lab=items[0]?.label; const ev=events.find(e=>e.x===lab); return ev ? ['Event: '+ev.label] : []; }}}}, scales:{y:{suggestedMin: Math.min(minData, rmin ?? minData)*0.9, suggestedMax: Math.max(maxData, rmax ?? maxData)*1.15}, x:{ticks:{maxRotation:45,minRotation:45, autoSkip:true, maxTicksLimit:18}}} } });
}
function makeLineChart(id, label, labels, data, unit) { new Chart(document.getElementById(id), {type:'line', data:{labels:labels, datasets:[{label:label+' ('+unit+')', data:data, borderColor:'#7c3aed', backgroundColor:'rgba(124,58,237,.12)', fill:true, pointRadius:2, tension:.25}]}, options:{responsive:true, maintainAspectRatio:false, interaction:{mode:'index',intersect:false}, plugins:{legend:{display:true}}, scales:{x:{ticks:{maxRotation:45,minRotation:45, autoSkip:true, maxTicksLimit:18}}}} }); }
function makeBarChart(id, labels, data, hits) { new Chart(document.getElementById(id), {type:'bar', data:{labels:labels, datasets:[{label:'Plan-Treue %', data:data, backgroundColor:data.map(v=>v>=80?'#22c55e':v>=60?'#f59e0b':'#ef4444')}]}, options:{responsive:true, maintainAspectRatio:false, plugins:{tooltip:{callbacks:{afterLabel:(ctx)=>'Hinweise: '+hits[ctx.dataIndex]}}}, scales:{y:{min:0,max:100},x:{ticks:{autoSkip:true,maxTicksLimit:18}}}} }); }
</script>
<style>body{font-family:Arial,sans-serif;margin:24px;background:#f6f8fb;color:#1f2937}a{color:#1f4e78}.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:12px}.card,.chart-card{background:white;border-radius:12px;padding:16px;box-shadow:0 2px 8px #0001;margin-bottom:18px}.num{font-size:30px;font-weight:700;color:#1f4e78}table{border-collapse:collapse;width:100%;background:white;margin-bottom:18px}td,th{border:1px solid #ddd;padding:6px;vertical-align:top}th{background:#1f4e78;color:white}canvas{background:white;border-radius:12px;margin-bottom:12px;width:100% !important;max-height:360px}.muted{color:#6b7280;font-size:.9em;margin-bottom:8px}.warn{background:#fff7ed;border-left:4px solid #f97316;padding:10px;border-radius:8px}.button{display:inline-block;background:#1f4e78;color:white!important;text-decoration:none;padding:10px 14px;border-radius:8px;margin:4px 8px 4px 0}</style></head><body>
<h1>JARVIS Health Dashboard v3.1</h1><p>Generiert: u   </p>
<div class='warn'><b>Neu:</b> Apple-Health-Jahresdaten sind integriert. PDF-Arztbericht kann über das Generator-Skript aktualisiert und über Google Drive geöffnet werden.</div>
<h2>Arztbericht PDF</h2><section class='card'><p>z6</p><p class='muted'>Aktualisieren per: <code>python3 z./scripts/generate_doctor_report.py && python3 zb/scripts/health_pipeline.py dashboard</code></p></section>
<h2>Systemstatus</h2><div class='grid'>u   </div>
<h2>Apple Health Trends</h2><table><tr><th>Metrik</th><th>Zeitraum</th><th>Records</th><th>letzter Wert</th><th>Ø</th><th>Min</th><th>Max</th></tr>z</table>u+   <p>Keine Apple-Health-Daten verfügbar.</p>z=
<h2>Labortrends mit Referenzband & Health-Event-Markern</h2>u$   <p>Keine Labortrends verfügbar.</p>u   
<h2>Ernährungsplan-Konsequenz</h2><section class='chart-card'><canvas id='nutrition_adherence' height='110'></canvas></section><script>makeBarChart('nutrition_adherence', zj);</script>
<table><tr><th>Datum</th><th>Score</th><th>erkannte Risiken</th><th>positive Treffer</th></tr>u   </table>
<h2>Health Event Periods / Zeiträume</h2><table><tr><th>Start</th><th>Ende</th><th>Typ</th><th>Label</th><th>Schweregrad</th><th>Notizen</th></tr>zj</table>
<h2>Laborberichte / Original-PDFs</h2><table><tr><th>ID</th><th>Original</th><th>Status</th></tr>z</table>
<h2>Klinische Events, Medikamente & Symptome</h2><table><tr><th>Datum</th><th>Kategorie</th><th>Parameter/Symptom</th><th>Wert/Notiz</th></tr>z</table>
<h2>Letzte Dokumente</h2><table><tr><th>ID</th><th>Datei</th><th>Kategorie</th><th>Status</th><th>Review</th><th>Volltext-Zeichen</th></tr>z</table>
</body></html>r   r   zHINSERT INTO report_runs(report_type, output_path, summary) VALUES(?,?,?)dashboard_v31z)Dashboard v3.1 mit Apple Health generiert)&r   mkdirr   r   r;   r   r   r2   r   r   r   APPLE_CHARTSr   closer   r5   rH   rZ   getr]   r?   r   rc   resubrN   rO   r   dumpsr   r  r   nowstrftimer9   
write_textr   print)8countslabsdates_paramsmatrix_catsrefsr0   docslab_docseventssymptomsperiodsnutrition_featuresr   _labelr   apple
key_paramsevent_by_dater   chartsrA   rJ   r   r#  rb   r   r   event_pointsr`   ra   cidapple_charts
apple_rowsr   r   cardsdoc_rowslab_doc_rows
event_rowssymptom_rowsperiod_rows	nf_labels	nf_scoresnf_hitsnutrition_rowsmeta	pdf_localpdf_link
drive_linkuprQ   rG  out	html_texts8                                                           r1   mainrr     sy   MM$M.[F:M:O:V:V:X 3 56^`DBF.*>RQSUWY[]_L`'E7FE4AAII  h  i  j		  #R  S  Taii !  
 		  #P  Q  Rqyy  "c  d  e7:S_``;O664a66``		J +6d*;M sc!F)nSb)*11Qz]O2anEUUVWXY`WaWgegVh2i2o2o2qrs lc!G*ocr*+22Yq|nBqQ]OgbgNhhi3jkl F  	/A

Aq6"AS\-QAGG-.	/  $%1!%%"#da##V\sQR`aer`ra$))M!4D*Eds*KLssdhhqk*
dffVS!$ !!%Q 00RSWS^S^_c_g_ghikp_qSrRs  tF  GJ  FK Ke3tzz!}oR

60B/C2djjQUFVEWWYZ^ZdZdeiZjYkkmnrnxnxy}n~m  @B  CG  CM  CM  NZ  in  Co  Bp p 	$ LJ+ 	gtIIfV44 !!!%U!3 44UVZVaVabcdjbkVlUmmyz{  }D  {E  zF  FK  LM  NT  LU  KV  Ve  qu  y~  q~  fm  DR  eS  Ss  tw  sx xuC

5 12"TZZ(5L4MRPTPZPZ[\]c[dPeOffhimisistuv|t}i~h @ 	 	HT[[%7$8	!G*USTU[S\R]]fghipgqfrr{|}  G  }H  |I  IJ  KO  KV  KV  WX  Y_  W`  Ka  Jb  bk  lm  ns  lt  ku  u~  @  AF  G  ~H  HQ  RS  TY  RZ  Q[  [e  f  	g	g GG  S  DJ  DP  DP  DR  S  SEww  {  vz  {  {H77  K  BJ  K  KL  s  fl  mp  mq  fr  s  sJ77  s  dl  mp  mq  dr  s  sL''  P  HO  P  P  @  T@K%7878I84FGq)*GIG?QR!q!5%55RGRWW  t  [m  nq  nr  [s  t  tN"$D33I |E  |L  |L  |N0S^1L0MMvw  TIHJXXn%+ff]#drvvfb'9'='=m'LdPRPVPVWcPd4T[[5E4FFwxJ
,,.
!
!"2
3C
+
+C  4   585! 92!$ 3;%$ =G<%$ H~%$ C  ~D%$ Dr%$ sw  rx%$x(%& ).w'&/U'( VX  V]  V]  ^h  Vi  Uj)( jr)( su  sz  sz  {G  sH  sy  Ly  rz)(z=)* >@WWV_=vPv<w+*xm+, nr  nx  nx  yB  nC  mD-, DF-, GK  GQ  GQ  R[  G\  F]-, ]_-, `d  `j  `j  kr  AF  `G  _H-,H_-. `n^n/.oT/0 U`  Ta10ab12 coao32pO34 PZ  O[54 \h  [i54iL56 MU  LV76V7I: NN9wN/A		dgvx{|  yA  Cn  go  p  rs  rz  rz  r|  ~  ~E  ~E  ~G	#JO a		. &#s8 9GRsI   4Ba `=$a >aa%	a%/a%6a*a/a4=a a__main__)returnsqlite3.Connection)r>   r   rt  zPath | None)rI   sqlite3.Rowrt  
str | None)rI   rv  rt  r5   )r\   r   rt  zfloat | None)r_   rw  rt  z!tuple[float | None, float | None])r   r5   rt  zdict[str, Any])r0   ru  rt  zlist[sqlite3.Row])r0   ru  r   r5   r   r5   rt  dict[str, Any] | None)rt  rx  )rt  None)3__doc__
__future__r   rN   r   r6   rD  r+   collectionsr   r   pathlibr   
statisticsr   typingr   homer9   r-   r   sysr7   insertr5   health_pipeliner   r   r   r   r   apple_health_analyticsr   r   r   r   r   apple_canonical_summaryrA  r2   rB   rK   rR   r]   rc   r   r   r   r  rr  __name__r   r3   r1   <module>r     s    #   	 	  #    tyy{Y)L8	

 
 3ti'( ) q q O  O-W 
v,T"	_yv zF r3   