
    i!\                        S r SSKrSSKrSSKrSSKrSSKrSSKrSSKrSSKrSSK	J	r	J
r
Jr  SSKJr  \R                  " S5      r0 SS_SS_S	S
_SS_SS_SS_SS_SS_SS_SS_SS_SS_SS_SS _S!S"_S#S$_S%S&_0 S'S(_S)S*_S+S,_S-S._S/S0_S1S2_S3S4_S5S6_S7S8_S9S:_S;S<_S=S>_S?S@_SASB_SCSD_SESF_SGSH_ESISJSKSLSMSNSOSPSQSRSSSTSUSVSW.ErSXSYSZS[S\S]S^S_.r " S` Sa5      rSb\Sc\4Sd jrg)ea  
Health Connect ZIP ingestion pipeline.

Parses the Health Connect export SQLite database from a zip file
and updates dashboard-data.json with:
  - Weight (latest morning reading)
  - Body fat (latest reading)
  - Blood pressure (latest reading)
  - Sleep (last night: duration, stages, HRV)
  - Exercise (recent sessions: type, duration, calories)
  - Steps (daily total)
  - Resting heart rate

Bill drops a Health Connect zip into Google Drive each morning between 7-8 AM.
The scheduler watches for new files and auto-ingests.
    N)datetimedate	timedelta)Pathzhealth-connectOther   	Badminton   Baseball   Biking   Boxing
   Cricket   Dancing   Fencing   zFootball (American)   zFootball (Australian)   zFrisbee Disc   Golf   zGuided Breathing   
Gymnastics   Handball   Walking   HIIT   Hiking   z
Ice Hockey   zIce Skating   zMartial Arts   Paddling    Paragliding!   Pilates"   Racquetball#   zRock Climbing$   zRoller Hockey%   Rowing&   Rugby'   Running(   Sailing)   zScuba Diving*   Skating+   SkiingSnowboardingzStrength Training
StretchingSurfingzSwimming (Open Water)zSwimming (Pool)zTable TennisTennis
Volleyball
Elliptical
Wheelchairz
Water PoloYogazStair Climbing),   -   .   /   0   1   2   3   4   5   8   9   :   ;   unknownawakesleeping
out_of_bedlightdeeprem)r      r      r
   r      c                       \ rS rSrSrS\4S jrS rS rS r	S r
S	 rSS
 jrS rSS jrS rS rSS jrSS jrSS jrS rSrg)HealthConnectParser<   z=Parse a Health Connect export zip and extract health metrics.zip_pathc                 ,    Xl         S U l        S U l        g N)rc   db_pathtemp_dir)selfrc   s     5/Users/bsyrros/clawd/whatsapp-agent/health_connect.py__init__HealthConnectParser.__init__?   s         c                    [         R                  " 5       U l         [        R                  " U R
                  S5       nUR                  U R                  5        SSS5        [        R                  " U R                  5       HJ  nUR                  S5      (       d  M  [        R                   R#                  U R                  U5      U l          O   U R$                  (       d  ['        S5      eU $ ! , (       d  f       N= f! [        R                   a  nS[        U5      ;   a  [        R                  SU 35        [        R                  R                  n S [        R                  l        [        R                  " U R
                  S5       nUR                  U R                  5        SSS5        O! , (       d  f       O= fU[        R                  l         SnAGN{! U[        R                  l        f = fe SnAff = f)z7Extract the SQLite DB from the zip to a temp directory.rNz
Bad CRC-32u4   CRC mismatch in zip — retrying without CRC check: c                     g re    )rh   datas     ri   <lambda>/HealthConnectParser.__enter__.<locals>.<lambda>Q   s    rl   z.dbz'No .db file found in Health Connect zip)tempfilemkdtemprg   zipfileZipFilerc   
extractall
BadZipFilestrloggerwarning
ZipExtFile_update_crcoslistdirendswithpathjoinrf   FileNotFoundError)rh   zfe_orig_update_crcfs        ri   	__enter__HealthConnectParser.__enter__D   s^    ((*	4dmm, 5" DMM*Azz%  !ww||DMM1= + ||#$MNN/ 54!! 	s1v% !UVWUXYZ#*#5#5#A#A F5LG&&2 <dmm4 =<< 6FG&&225EG&&2	se   !C> C-C> -
C;7C> ;C> >G<AG77GF0'	G0
F>	:GG7G33G77G<c                 f    U R                   (       a   [        R                  " U R                   SS9  gg)zCleanup temp directory.T)ignore_errorsN)rg   shutilrmtree)rh   argss     ri   __exit__HealthConnectParser.__exit__a   s     ==MM$--t< rl   c                    [        U S5      (       a   [        R                  " U R                  5      $ [        R                  " U R                  5      n UR	                  S5        SU l        U$ ! [        R                   aA    UR                  5         [        R                  S5        U R                  5       nSU l        Us $ f = f)N_db_verified)SELECT 1 FROM weight_record_table LIMIT 1Tu,   DB appears malformed — attempting recovery)hasattrsqlite3connectrf   executer   DatabaseErrorcloser{   r|   _recover_db)rh   conn	recovereds      ri   _connectHealthConnectParser._connectf   s    4((??4<<00t||,		LLDE $DK$$ 	JJLNNIJ((*I $D	s   A- -ACCc                    U R                   S-   nU R                   nSSKn UR                  SU R                   S/SSSS9nUR                  (       Ga  [	        UR                  5      S	:  Ga  UR                  SU/UR                  SSSS
9n[
        R                  R                  U5      (       a  [
        R                  R                  U5      S:  a  Xl         [        R                  " U R                   5      nUR                  S5        UR                  5         [        R                  S[
        R                  R                  U5      S S35        [        R                  " U R                   5      $  UR                  SUS/SSSS9nUR                  (       Ga  [	        UR                  5      S	:  Ga  UR                  SU/UR                  SSSS
9n[
        R                  R                  U5      (       a  [
        R                  R                  U5      S:  a  Xl         [        R                  " U R                   5      nUR                  S5        UR                  5         [        R                  S[
        R                  R                  U5      S S35        [        R                  " U R                   5      $ [        R)                  S5        X l         [        R                  " U R                   5      $ ! UR                  [         [        R"                  4 a]  n[        R%                  SU 35        [
        R                  R                  U5      (       a  [
        R&                  " U5         SnAGNSnAff = f! UR                  [         [        R"                  4 a]  n[        R%                  SU 35        [
        R                  R                  U5      (       a  [
        R&                  " U5         SnAGN=SnAff = f)z
Recover a malformed SQLite DB.
Strategy 1: sqlite3 CLI .recover (most robust for page-level corruption)
Strategy 2: sqlite3 CLI .dump + rebuild
Strategy 3: Python-level PRAGMA integrity_check + connect anyway
z
.recoveredr   Nr   z.recoverTrb   )capture_outputtexttimeout  )inputr   r   r   i r   zDB recovered via .recover (,z bytes)zStrategy 1 (.recover) failed: z.dumpzDB recovered via .dump (zStrategy 2 (.dump) failed: uG   DB recovery failed — proceeding with original (some queries may fail))rf   
subprocessrunstdoutlenr   r   existsgetsizer   r   r   r   r{   infoTimeoutExpiredr   r   debugremover|   )	rh   recovered_pathoriginal_pathr   recoverrebuild	test_connr   dumps	            ri   r   HealthConnectParser._recover_dbw   s    4	* nnDLL*5#$ % G ~~~#gnn"5"<$../!..DRT )  77>>.11bggoon6UX^6^#1L ' =I%%&QROO%KK"=bggoon>]^_=``g hi"??4<<88	*>>M73#$ " D {{{s4;;/$6$../++dr )  77>>.11bggoon6UX^6^#1L ' =I%%&QROO%KK":277??>;Z[\:]]d ef"??4<<88 	`a$t||,,? ))+<g>S>ST 	*LL9!=>ww~~n--		.)	*. ))+<g>S>ST 	*LL6qc:;ww~~n--		.)	*s3   EK1 1EM6 1%M3AM..M36%O8AO33O8c                 V   U R                  5       nUR                  5       nUR                  S5        UR                  5       nUR	                  5         U(       aQ  [
        R                  " US   S-  5      n[        US   S-  S5      nUR                  5       UR                  S5      US.$ g)	z9Get the most recent weight reading. Returns dict or None.zi
            SELECT time, weight FROM weight_record_table
            ORDER BY time DESC LIMIT 1
        r   r   r]   xY|@%Y-%m-%d)	timestampr   lbsN
r   cursorr   fetchoner   r   fromtimestampround	isoformatstrftime)rh   r   crowdtr   s         ri   get_latest_weight%HealthConnectParser.get_latest_weight   s    }}KKM			  	 jjl

''A6BA(!,C!#Z9PY\]]rl   c                    U R                  5       nUR                  5       n[        [        R                  " 5       [        US9-
  R                  5       S-  5      nUR                  SU45        UR                  5       nUR                  5         0 nU HG  u  px[        R                  " US-  5      n	U	R                  S5      n
X;  d  M6  [        US-  S5      Xj'   MI     U$ )zJGet daily weight readings (first reading of each day) for the last N days.daysr   zo
            SELECT time, weight FROM weight_record_table
            WHERE time > ? ORDER BY time ASC
        r   r   r]   r   r   intr   nowr   r   r   fetchallr   r   r   r   )rh   r   r   r   cutoffrowsdailytsgramsr   day_keys              ri   get_weight_series%HealthConnectParser.get_weight_series   s    }}KKMhllnyd';;FFH4OP			  Y	 zz|

 IB''T	2Bkk*-G#!&uw!:	  rl   c                 ,   U R                  5       nUR                  5       nUR                  S5        UR                  5       nUR	                  5         U(       a<  [
        R                  " US   S-  5      nUR                  5       [        US   S5      S.$ g)z(Get the most recent body fat percentage.zo
            SELECT time, percentage FROM body_fat_record_table
            ORDER BY time DESC LIMIT 1
        r   r   r]   )r   
percentageN)	r   r   r   r   r   r   r   r   r   )rh   r   r   r   r   s        ri   get_latest_body_fat'HealthConnectParser.get_latest_body_fat   sy    }}KKM			  	 jjl

''A6B!#uSVQ?OPPrl   c                    U R                  5       nUR                  5       n[        [        R                  " 5       [        US9-
  R                  5       S-  5      nUR                  SU45        UR                  5       nUR                  5         0 nU HD  u  px[        R                  " US-  5      n	U	R                  S5      n
X;  d  M6  [        US5      Xj'   MF     U$ )z0Get daily body fat readings for the last N days.r   r   zu
            SELECT time, percentage FROM body_fat_record_table
            WHERE time > ? ORDER BY time ASC
        r   r]   r   )rh   r   r   r   r   r   r   r   pctr   r   s              ri   get_body_fat_series'HealthConnectParser.get_body_fat_series   s    }}KKMhllnyd';;FFH4OP			  Y	 zz|

GB''T	2Bkk*-G#!&sA	 
 rl   c                    U R                  5       nUR                  5       nUR                  S5        UR                  5       nUR	                  5         U(       a  [
        R                  " US   S-  5      n[        US   5      n[        US   5      nUS:  a	  US:  a  SnO US	:  a	  US:  a  S
nOUS:  d  US:  a  SnOSnUR                  5       UR                  S5      UUUS.$ g)zGet the most recent BP reading.z
            SELECT time, systolic, diastolic
            FROM blood_pressure_record_table
            ORDER BY time DESC LIMIT 1
        r   r   r]   r   x   P   normal   elevated   Z   zhigh-stage1zhigh-stage2r   )r   r   systolic	diastolicstatusNr   )rh   r   r   r   r   sys_valdia_valr   s           ri   get_latest_blood_pressure-HealthConnectParser.get_latest_blood_pressure  s    }}KKM			  	
 jjl

''A6BCFmGCFmG}2!37R<#3'B,&&\\^J/#$   rl   c                    U R                  5       nUR                  5       nUR                  S5        UR                  5       nU(       d  UR	                  5         gUu  pEpgp[
        R                  " U=(       d    US-  5      n
[
        R                  " U	=(       d    US-  5      nXe-
  S-  nUR                  SU45        UR                  5       nSSSSS.nU H:  u  nnnUU-
  S-  n[        R                  US	5      nUU;   d  M-  UU==   U-  ss'   M<     UR                  S
XV45        UR                  5       S   nUR	                  5         U
R                  S5      U
R                  S5      UR                  S5      [        US5      U=(       d    S[        US   5      [        US   5      [        US   5      [        US   5      S.U(       a  [        US5      S.$ SS.$ )z4Get last night's sleep session with stage breakdown.z
            SELECT row_id, start_time, end_time, title,
                   local_date_time_start_time, local_date_time_end_time
            FROM sleep_session_record_table
            ORDER BY start_time DESC LIMIT 1
        Nr   6 z
            SELECT stage_start_time, stage_end_time, stage_type
            FROM sleep_stages_table
            WHERE parent_key = ?
        r   )rW   rZ   r[   r\   `  rV   z
            SELECT AVG(heart_rate_variability_millis)
            FROM heart_rate_variability_rmssd_record_table
            WHERE time BETWEEN ? AND ?
        r   %H:%Mr]   Unknownr[   r\   rZ   rW   )deep_minrem_min	light_min	awake_min)r   bedtime	wake_timetotal_hourssourcestagesavg_hrv)r   r   r   r   r   r   r   r   SLEEP_STAGESgetr   r   )rh   r   r   sessionrow_idstart_msend_mstitlelocal_start_mslocal_end_msstartendr   r   stage_minutess_starts_ends_typemins
stage_namer   s                        ri   get_last_sleep"HealthConnectParser.get_last_sleep)  s   }}KKM 	
		  	 **,JJLHOE&&&(B(d'JK$$l&<f%DE(G3 	
		  Y		
 "#a1E&,"GUFGOu,D%))&)<J]*j)T1)	 '- 	
		  		!
 **,q/

 NN:.~~g.g. a0(y!-"78 u!56"=#9:"=#9:	 -4uWa(
 	
 :>
 	
rl   c                    U R                  5       nUR                  5       n[        [        R                  " 5       [        US9-
  R                  5       S-  5      nUR                  SU45        UR                  5       nUR                  5         0 nU HS  u  px[        R                  " US-  5      n	U	R                  S5      n
X-
  S-  nX;  d
  XU
   :  d  ME  [        US5      Xj'   MU     U$ )z)Get sleep duration for the last N nights.r   r   z
            SELECT start_time, end_time
            FROM sleep_session_record_table
            WHERE start_time > ?
            ORDER BY start_time ASC
        r   r   r]   r   )rh   r   r   r   r   r   nightlyr  r  r   nighthourss               ri   get_sleep_series$HealthConnectParser.get_sleep_seriesi  s    }}KKMhllnyd';;FFH4OP			 
 Y	 zz|

  $H''48BKK
+E&'1E#uu~'=!&ua !% rl   c           	      \   U R                  5       nUR                  5       n[        [        R                  " 5       [        US9-
  R                  5       S-  5      nUR                  SU45        UR                  5       nUR                  5         / nU H  u  pxpn[        R                  " US-  5      n[        X-
  S-  5      n[        R                  U	SU	 35      nU
(       a  U
OUnUS:  a  U	S:X  a  Mb  UR                  UR                  S5      UR                  S	5      UUUS
.5        M     U$ )z+Get exercise sessions from the last N days.r   r   z
            SELECT start_time, end_time, exercise_type, title, notes
            FROM exercise_session_record_table
            WHERE start_time > ?
            ORDER BY start_time DESC
        r   zType r   r    r   r   )r   timetypenameduration_min)r   r   r   r   r   r   r   r   r   r   r   r   EXERCISE_TYPESr   appendr   )rh   r   r   r   r   r   sessionsr  r  ex_typer  notesr   r  
type_labelr  s                   ri   get_recent_exercises(HealthConnectParser.get_recent_exercises  s   }}KKMhllnyd';;FFH4OP			 
 Y	 zz|

7;3Hge''48B &"3u!<=L'++GuWI5FGJ "5zD aGrMOOJ/G," ,  8<( rl   c                    U R                  5       nUR                  5       n[        [        R                  " 5       [        US9-
  R                  5       S-  5      nUR                  SU45        UR                  5       nUR                  5         0 nU HD  u  px[        R                  " US-  5      R                  S5      n	UR                  U	S5      U-   Xi'   MF     U$ )z*Get daily step totals for the last N days.r   r   zg
            SELECT start_time, count FROM steps_record_table
            WHERE start_time > ?
        r   r   )r   r   r   r   r   r   r   r   r   r   r   r   r   )
rh   r   r   r   r   r   r   r   countr   s
             ri   get_daily_steps#HealthConnectParser.get_daily_steps  s    }}KKMhllnyd';;FFH4OP			  Y	 zz|

IB,,R$Y7@@LG"YYw2U:EN  rl   c                 l  ^  [         R                  " 5       R                  5       [        R                  R                  T R                  5      S.nSU 4S j4SU 4S j4SU 4S j4SU 4S	 j4S
U 4S j4SU 4S j4SU 4S j4SU 4S j4SU 4S j4/	nU H  u  p4 U" 5       nU(       a  XQU'   M  M     U Vs/ s H  owS;  d  M
  UPM     nn[        R                  S[        U5       SSR                  U5       35        U$ ! [         a&  n[        R                  SU SU 35         SnAM  SnAff = fs  snf )u   
Extract all health metrics into a single dict.
Each metric is extracted independently — if one table is corrupt,
the rest still get pulled.
)exported_atsource_fileweightc                  $   > T R                  5       $ re   )r   rh   s   ri   rr   1HealthConnectParser.extract_all.<locals>.<lambda>  s    t'='='?rl   weight_seriesc                  &   > T R                  S5      $ N   )r   r-  s   ri   rr   r.    s    t'='=b'Arl   body_fatc                  $   > T R                  5       $ re   )r   r-  s   ri   rr   r.    s    t'?'?'Arl   body_fat_seriesc                  &   > T R                  S5      $ r1  )r   r-  s   ri   rr   r.    s    t'?'?'Crl   blood_pressurec                  $   > T R                  5       $ re   )r   r-  s   ri   rr   r.    s    t'E'E'Grl   sleepc                  $   > T R                  5       $ re   )r  r-  s   ri   rr   r.    s    t':':'<rl   sleep_seriesc                  &   > T R                  S5      $ )Nr   )r  r-  s   ri   rr   r.    s    t'<'<R'@rl   	exercisesc                  &   > T R                  S5      $ N   )r"  r-  s   ri   rr   r.    s    t'@'@'Crl   stepsc                  &   > T R                  S5      $ r?  )r&  r-  s   ri   rr   r.    s    t';';A'>rl   zFailed to extract z: Nz
Extracted z
 metrics: z, )r   r   r   r   r   basenamerc   	Exceptionr{   r|   r   r   r   )	rh   result
extractorskeyfnvalr   k	extracteds	   `        ri   extract_allHealthConnectParser.extract_all  s7    $<<>33577++DMM:
 ?@ABABCDGH<=@ACD>?


 "GC@d"%3K  " !'R13Q*QQ	RjY 0
499Y;O:PQR  @!3C51#>??@ Ss$   C>4	D1D1>
D.D))D.)r   rf   rg   rc   N)r2  )r   )r@  )__name__
__module____qualname____firstlineno____doc__rz   rj   r   r   r   r   r   r   r   r   r   r  r  r"  r&  rL  __static_attributes__rp   rl   ri   ra   ra   <   s[    G 
:=
">-D 0,F>
@8#N*"rl   ra   rc   returnc                 p  ^^	 [         R                  SU  35        [        U 5       nUR                  5       m	SSS5        / mUU	4S jnUR	                  U5        [        UR                  5      R                  S-  nUR                  SS9  US[        R                  " 5       R                  5        S3-  n[        US	5       n[        R                  " T	US
[        S9  SSS5        SSR!                  S T 5       5      -   n[         R                  U5        U$ ! , (       d  f       N= f! , (       d  f       NQ= f)zV
Ingest a Health Connect zip file and update the dashboard.
Returns a summary string.
z!Ingesting Health Connect export: Nc           	        > ST;   Ga  TS   nU S   S   nUS   n[        X2-
  S5      U S   S'   X0S   S'   [        R                  " US   5      R                  S5      U S   S'   [        R
                  " 5       R                  5       U S	'   S
T;   ab  [        TS
   R                  5       5      n[        U5      S:  a7  USS  U S   S'   USS  n[        [        U5      [        U5      -  S5      U S   S'   U S   R                  SS5      nU S   R                  SS5      n[        SSS5      n[        [        R                  " 5       U-
  R                  S-  S5      n	Xc-
  n
[        X-  S5      nXS   S'   X7-
  nUS:  a  [        X-  5      OSU S   S'   TR                  SU SU S   S   S S35        ST;   av  TS   nU S   S   nUS    n[        X2-
  S5      U S   S'   X0S   S'   S!T;   a.  [        TS!   R                  5       5      nU(       a  USS  U S   S'   TR                  S"U S#35        S$T;   aN  TS$   nUS%   U S&   S%'   US'   U S&   S''   US(   U S&   S('   US	   U S&   S	'   TR                  S)US%    S*US'    35        S+T;   aF  TS+   U S+'   S,T;   a  TS,   U S+   S-'   TR                  S.TS+   S/    S0TS+   S1    S2TS+   S3    S35        S4T;   a  TS4   S S5 [        R
                  " 5       R                  5       S6.U S7'   TS4    Vs/ s H  oS8   US9   :w  d  M  UPM     nnU(       a+  TR                  S:[        TS4   5       S;US   S8    S35        O!TR                  S:[        TS4   5       S<35        S=T;   a  TS=   [        R
                  " 5       R                  5       S>.U S='   TS=   R                  [        R
                  " 5       R                  5       S5      nU(       a  TR                  S?US@ SA35        g g g s  snf )BNr+  currentr   r]   deltaVsLastr   z%B %-dlastWeighInr   r/  r@  i	series30diavg7dbaselineg     n@goal   i  r   pacer   i  etaWeekszWeight: z lb (z+.1f)r3  bodyFatr   r5  z
Body fat: %r7  r   bloodPressurer   r   zBP: /r9  r;  	series14dzSleep: r   zh (r   -r   r=  r   )recentupdatedexerciser  r  z
Exercise: z sessions (latest: z	 sessionsrA  )r   ri  zSteps: r   z today)r   r   fromisoformatr   r   todayr   listvaluesr   sumr   maxr   r   r  )	dashboardwoldnew_valseries_valueslast7r\  r]  baseline_dateweekslostr_  	remainingbfbpr   namedtoday_stepschangesrq   s                     ri   updater&ingest_health_connect.<locals>.updater  s    tXAH%i0ChG16w}a1HIh.-4h	*191G1G+1W1`1`ai1jIh. $

 6 6 8If $& $T/%:%A%A%C D}%*7DST7JIh'4)"#.E38Uc%j9PRS3TIh'0 !*..z5AHX&**637D$T1a0M-7==A1EE%Dq)D*.h'IIMPQeI4D.EWZIh
+NNXgYeIh4G4VW[3\\]^_ j!BI&y1C&G27q2IIi /.5i + D( $T*;%<%C%C%E F 8Ecd8KIi(5NNZy23 t#&'B57
^Io&z268oIo&{335h<Io&x013FIo&v.NNT"Z.!12k?2CDE d?!%gIg%26~2F	'";/NNWT']=%A$B#d7mT]F^E__`aefmanoza{`||}~ ${+CR0::<113%Ij! !%[ 1L 11vY!F)5KQ 1ELC[0A,B+CCVW\]^W_`fWgVhhijkC[0A,B+C9MN d?g::<113"Ig w-++DJJL,B,B,DaHKQv>?   Ms   O=O=zhealth-snapshotsT)exist_okzhealth-z.jsonrr  r   )indentdefaultz Health Connect import complete:

c              3   ,   #    U  H
  nS U 3v   M     g7f)u     • Nrp   ).0r   s     ri   	<genexpr>(ingest_health_connect.<locals>.<genexpr>T  s     =\T[qqclT[s   )r{   r   ra   rL  _read_and_writer   	file_pathparentmkdirr   rl  r   openjsonr   rz   r   )
rc   dashboard_managerparserr  snapshot_dirsnapshot_pathr   summaryr  rq   s
           @@ri   ingest_health_connectr    s   
 KK3H:>?	X	&&!!# 
' GV@p %%g. )334;;>PPL% WTZZ\-C-C-E,Fe#LLM	mS	!Q		$!S1 
" 2DII=\T[=\4\\G
KKNS 
'	&H 
"	!s   D D'
D$'
D5)rR  r   rer  r   rv   r   rt   loggingr   r   r   pathlibr   	getLoggerr{   r  r   ra   rz   r  rp   rl   ri   <module>r     s7  " 
 	       . . 			+	,w; !:/0(xY "I/19   "#: 	 F	 %'(:	
 
 *
 '))  H !,  > 
  	 } ')/  X (*7 	 y #%n 	 x &4.~l,F%. WFug gTpC ps prl   