
    حim                     z   d Z ddlZddlZddlZddlZddlZddlZej                  j                  dej                  j                  ej                  j                  e                   ddlmZ ddlmZmZmZ ddlmZmZmZmZ ej                  j                  dej                  j                  e             	 ddlmZmZmZ dZd
Zi ddg ddddg ddddg ddddg ddddg ddddg ddddg d dd!d"g d#dd$d%d&d'gdd(d)d&d'gdd*d+d&d'gdd,d-d&d'gdd.d/d&d'gdd0d1d&gdd2d3d&gdd4d5g dd6d7g d8dd9d:d;gdiZg d<Zd=ee e f   fd>Z! G d? d@      Z"dA Z#dIdBe"dCee    fdDZ$dIdBe"dCee    fdEZ%dBe"fdFZ&dG Z'e(dHk(  r e) e'              yy# e$ r dZ ed	       Y w xY w)JaT  
The Odds API Enhanced Fetcher

Unified fetcher for odds, player props, and historical data from The Odds API.
Tracks quota usage and handles all sports/markets.

Usage:
    python theoddsapi_enhanced_fetcher.py --live              # Live odds for all sports
    python theoddsapi_enhanced_fetcher.py --props             # Player props for upcoming games
    python theoddsapi_enhanced_fetcher.py --scores            # Live scores
    python theoddsapi_enhanced_fetcher.py --events            # Event list (free)
    python theoddsapi_enhanced_fetcher.py --quota             # Check quota status
    N)normalize_to_full)datetimetimezone	timedelta)OptionalDictListTuple)log_ingestion_startlog_ingestion_completeprocess_odds_for_gameTFzLWarning: unified_odds_ingestion not available, writing to legacy tables onlyzhttps://api.the-odds-api.com/v4nbabasketball_nba)player_pointsplayer_reboundsplayer_assistsplayer_threesplayer_points_rebounds_assistsplayer_double_doubleplayer_blocksplayer_stealsplayer_blocks_stealsplayer_turnoversplayer_points_reboundsplayer_points_assistsplayer_rebounds_assistsplayer_field_goalsplayer_frees_madeplayer_frees_attemptsplayer_first_basketplayer_first_team_basketplayer_triple_doubleplayer_method_of_first_basket)keyprop_marketsnflamericanfootball_nfl)player_pass_tdsplayer_pass_ydsplayer_rush_ydsplayer_reception_ydsplayer_receptionsplayer_anytime_tdplayer_pass_attemptsplayer_pass_completionsplayer_pass_interceptionsplayer_pass_longest_completionplayer_pass_rush_ydsplayer_pass_rush_reception_tdsplayer_pass_rush_reception_ydsplayer_reception_tdsplayer_rush_attemptsplayer_rush_tdsplayer_sacksplayer_solo_tacklesplayer_tackles_assistsplayer_1st_tdplayer_last_tdplayer_tds_overplayer_kicking_pointsr   player_patsplayer_defensive_interceptionsplayer_rush_longestplayer_reception_longestnhlicehockey_nhl)
player_goalsplayer_shots_on_goalplayer_goal_scorer_anytimer   player_power_play_pointsr   player_blocked_shotsplayer_total_savesplayer_goal_scorer_firstplayer_goal_scorer_lastmlbbaseball_mlb)batter_home_runspitcher_strikeoutsbatter_hits_runs_rbisbatter_hitsbatter_total_basesbatter_rbisbatter_runs_scoredbatter_singlesbatter_doublesbatter_walksbatter_strikeoutsbatter_stolen_basespitcher_record_a_winpitcher_hits_allowedncaabbasketball_ncaab)r   r   r   r   r   r   ncaafamericanfootball_ncaaf)r(   r*   r-   r)   r+   r,   wnbabasketball_wnba)r   r   r   r   epl
soccer_epl)rG   player_first_goal_scorerplayer_shots_on_targetplayer_shotsr   
bundesligasoccer_germany_bundesligarG   rf   serieasoccer_italy_serie_alaligasoccer_spain_la_ligaligue1soccer_france_ligue_oneuclsoccer_uefa_champs_leagueuelsoccer_uefa_europa_leaguemlssoccer_usa_mlsmmamma_mixed_martial_artsaflaussierules_afl)player_disposalsplayer_goals_scored_overplayer_fantasy_pointsnrlrugbyleague_nrlplayer_try_scorer_anytime)h2hspreadstotalsreturnc                  n   d} d}d}	 t        | d      5 }|D ]  }|j                  d      rE|j                  dd      d   j                         j                  d      j                  d      d	   }Y|j                  d
      sk|j                  dd      d   j                         j                  d      } 	 ddd       |xs2 t
        j                  j                  dd      j                  d      d	   }|xs t
        j                  j                  d      }||fS # 1 sw Y   fxY w# t        $ r Y tw xY w)z'Load database URL and API key from .envz/var/www/html/eventheodds/.envNrzSPORTS_DATABASE_URL==   "?r   zTHE_ODDS_API_KEY=SPORTS_DATABASE_URL THE_ODDS_API_KEY)open
startswithsplitstripFileNotFoundErrorosenvironget)env_pathdb_urlapi_keyflines        @/var/www/html/eventheodds/scripts/theoddsapi_enhanced_fetcher.pyload_configr      s*   /HFG(C  	GA G??#9:!ZZQ/288:@@EKKCPQRSF__%89"jja0399;AA#FG	G	G Nrzz~~&;R@FFsKANF;(:;G7?	G 	G  s/   D( A-D4D7D( D%!D( (	D43D4c                      e Zd ZdedefdZddededee   fdZdefd	Z	d
ede
e   fdZ	 	 dd
edede
e   de
e   de
e   f
dZ	 dd
ededede
e   dee   f
dZdd
edede
e   fdZ	 dd
ededede
e   dee   f
dZy)TheOddsAPIFetcherr   r   c                 n    || _         || _        t        j                         | _        d| _        d | _        y )Nr   )r   r   requestsSessionsession
quota_usedquota_remaining)selfr   r   s      r   __init__zTheOddsAPIFetcher.__init__   s/    '')#    Nendpointparamsr   c           
      D   |i }| j                   |d<   t         | }d}t        d|dz         D ]+  }	 | j                  j	                  ||d      }t        |j                  j	                  dd            | _        t        |j                  j	                  d	d            | _        t        |j                  j	                  d
d            }|j                  dk(  rt        d        y|j                  dk(  rt        d|         y|j                  dk(  rt        d        y|j                  dk7  rt        d|j                           y|j                         c S  y# t        j                  j                  t        j                  j                  t        j                  j                   f$ rP}||k  r/t        d| d| d|        ddl}	|	j%                  d       Y d}~t        d| d|        Y d}~ yd}~wt&        $ r}t        d|        Y d}~ yd}~ww xY w)zCMake API request and track quota. Retries once after 5s on timeout.NapiKey   r      )r   timeoutzx-requests-usedr   zx-requests-remainingzx-requests-lasti  zERROR: Invalid API keyi  zINFO: No data for i  zERROR: Quota exceeded   zERROR: API returned z3WARNING: Request timeout/connection error (attempt /z), retrying in 5s:    zERROR: Request failed after z attempts: zERROR: Request failed: )r   BASE_URLranger   r   intheadersr   r   status_codeprintjsonr   
exceptionsConnectTimeoutReadTimeoutConnectionErrortimesleep	Exception)
r   r   r   urlmax_attemptsattemptresp	last_coster   s
             r   _requestzTheOddsAPIFetcher._request   s   >F<<x
8*%Qq 01 $	G#||''FB'G #&dll&6&67H!&L"M'*4<<+;+;<RTU+V'W$ 0 01BA FG	##s*24##s*.xj9:##s*13##s*01A1A0BCDyy{"-$	0 ''66''33''779 	 \)OPWyXYZfYggz{|z}~JJqM4\N+aSQR /s34sC   B1E'EE"'EEAH/.G:#G::HHHc                     | j                  d       | j                  | j                  | j                  | j                  xs dz   dS )zCheck current quota status/sports/r   )used	remainingtotal)r   r   r   )r   s    r   check_quotazTheOddsAPIFetcher.check_quota   sA     	j!OO--__(<(<(AB
 	
r   	sport_keyc                 8    | j                  d| d      }|xs g S )z&Get events for a sport (FREE endpoint)r   z/eventsr   )r   r   eventss      r   
get_eventszTheOddsAPIFetcher.get_events   s#    )G<=|r   regionsmarkets	event_idsc                     |t         }|dj                  |      dd}|rdj                  |      |d<   | j                  d| d|      }|xs g S )zGet odds for a sport,american)r   r   
oddsFormateventIdsr   /oddsCORE_MARKETSjoinr   )r   r   r   r   r   r   oddss          r   get_oddszTheOddsAPIFetcher.get_odds   sd     ?"G xx($
 !$)!4F:}}x	{%8&Azrr   event_idc                 j    |dd}|rdj                  |      |d<   | j                  d| d| d|      S )z4Get detailed odds for a single event including propsr   )r   r   r   r   r   z/events/r   )r   r   )r   r   r   r   r   r   s         r   get_event_oddsz TheOddsAPIFetcher.get_event_odds  sI     $

  # 1F9}}x	{(8*EJFSSr   	days_fromc                 R    i }|dkD  r||d<   | j                  d| d|      }|xs g S )z$Get scores for live and recent gamesr   daysFromr   z/scoresr   )r   r   r   r   scoress        r   
get_scoreszTheOddsAPIFetcher.get_scores  s;    q=!*F:)G<fE|r   datec                 j    |t         }||dj                  |      dd}| j                  d| d|      S )z+Get historical odds at a specific timestampr   r   )r   r   r   r   z/historical/sports/r   r   )r   r   r   r   r   r   s         r   get_historical_oddsz%TheOddsAPIFetcher.get_historical_odds'  sI     ?"G xx($	
 }}29+UCVLLr   N)usNN)r   N)r   )__name__
__module____qualname__strr   dictr   r   r   r   r	   r   r   r   r   r   r    r   r   r   r      s7   $ $S $- -d -htn -^
T 
C DJ 
 7;CG#  s)7;CyLPQUJ& BFT Ts T #T59#YTJRSW.TC C T
  FJMS M M$'M9=cMNVW[nMr   r   c                 ~   | j                         }|j                  d       |j                         s"	 |j                  d       | j                          |j                  d       |j                  d       |j                  d       | j                          |j                          y#  | j	                          Y hxY w)z%Ensure required database tables existz
        SELECT column_name FROM information_schema.columns
        WHERE table_name = 'OddsSnapshot' AND column_name = 'theoddsapiEventId'
    zFALTER TABLE "OddsSnapshot" ADD COLUMN "theoddsapiEventId" VARCHAR(100)z
        CREATE INDEX IF NOT EXISTS idx_odds_snapshot_toapi_event
        ON "OddsSnapshot"(league, "theoddsapiEventId", "snapshotAt")
    a  
        CREATE TABLE IF NOT EXISTS "PropSnapshot" (
            id SERIAL PRIMARY KEY,
            league VARCHAR(20),
            "theoddsapiEventId" VARCHAR(100),
            "gameDate" TIMESTAMP,
            "homeTeam" VARCHAR(100),
            "awayTeam" VARCHAR(100),
            bookmaker VARCHAR(50),
            "marketType" VARCHAR(50),
            "playerName" VARCHAR(100),
            "propLine" DOUBLE PRECISION,
            "overPrice" INTEGER,
            "underPrice" INTEGER,
            "capturedAt" TIMESTAMP DEFAULT NOW(),
            source VARCHAR(50) DEFAULT 'theoddsapi',
            "createdAt" TIMESTAMP DEFAULT NOW()
        )
    z
        CREATE INDEX IF NOT EXISTS idx_prop_snapshot_event
        ON "PropSnapshot"(league, "theoddsapiEventId", "playerName", "capturedAt")
    N)cursorexecutefetchonecommitrollbackclose)conncurs     r   ensure_tablesr   7  s    
++-C KK  	 <<>	KK`aKKM KK  	 KK  	( KK  	
 	KKMIIKG	MMOs   !B( (B<fetcherleaguesc                 2   |g d}|j                         }d}dddd}t        dd        t        d       t        dt        j                  t        j
                        j                                 t        d        |D ]M  }t        j                  |      }|s|d	   }| j                  |      }	|	st        |j                          d
       Qt        d|j                          dt        |	       d       |	D ]  }
|
j                  d      }t        |
j                  dd      |      }t        |
j                  dd      |      }|
j                  d      }d}|r&	 t        j                  |j                  dd            }|
j                  dg       D ]  }|j                  d	d      }dx}}dx}}dx}}d}dx}}|j                  dg       D ]e  }|j                  d	      }|j                  dg       }|dk(  rT|D ]N  }|j                  d      |k(  r|j                  d      })|j                  d      |k(  s>|j                  d      }P |dk(  rv|D ]p  }|j                  d      |k(  r#|j                  d      }|j                  d      }:|j                  d      |k(  sO|j                  d      }|j                  d      }r |dk(  s|D ]_  }|j                  d      dk(  r#|j                  d      }|j                  d      }:|j                  d      dk(  sO|j                  d      }a h |j                  d ||||||||||||||||f       |d!z  } t         so|ssg }|
j                  dg       D ]  }|j                  d	d      }i } |j                  dg       D ]  }|j                  d	      }|j                  dg       }|dk(  redx}!}"|D ]N  }|j                  d      |k(  r|j                  d      }!)|j                  d      |k(  s>|j                  d      }"P |!s|"s|!|"d"| d<   |dk(  rydx}#x}$}%|D ]_  }|j                  d      |k(  r#|j                  d      }#|j                  d      }$:|j                  d      |k(  sO|j                  d      }%a |#|#|$|%d#| d<   |dk(  sdx}&x}'}(|D ]_  }|j                  d      dk(  r#|j                  d      }&|j                  d      }':|j                  d      dk(  sO|j                  d      }(a |&|&|'|(d#| d<    | s|j#                  || d$        |s`	 t%        ||||||d%| d&d'(	      })|d)xx   |)j                  d)d      z  cc<   |d*xx   |)j                  d*d      z  cc<   |d+xx   |)j                  d+d      z  cc<    P |j)                          |j+                          t        dd        t        d-| d.       t         rt        d/|d)    d0|d*    d1|d+    d2       t        d3| j,                   d4| j.                   d5       t        d        |S #  Y xY w# t&        $ r}*t        d,| d|*        Y d}*~*d}*~*ww xY w)6z Capture live odds for all sportsN)r   r&   rC   r   )createdupdated	snapshots
<============================================================zCAPTURING LIVE ODDSTime: r$   : No events:  eventsid	home_teamr   	away_teamcommence_timeZ+00:00
bookmakersunknownr   outcomesr   namepricer   pointr   OverUnderaQ  
                    INSERT INTO "OddsSnapshot" (
                        league, "theoddsapiEventId", "externalGameId", "gameDate",
                        "homeTeam", "awayTeam", bookmaker, "snapshotType", "snapshotAt",
                        "moneylineHome", "moneylineAway",
                        "spreadHome", "spreadAway", "spreadHomeOdds", "spreadAwayOdds",
                        total, "totalOverOdds", "totalUnderOdds", source
                    ) VALUES (
                        %s, %s, %s, %s, %s, %s, %s, 'live', NOW(),
                        %s, %s, %s, %s, %s, %s, %s, %s, %s, 'theoddsapi'
                    )
                    ON CONFLICT (league, "externalGameId", "snapshotAt", source, bookmaker)
                    DO UPDATE SET
                        "moneylineHome" = EXCLUDED."moneylineHome",
                        "moneylineAway" = EXCLUDED."moneylineAway",
                        "spreadHome" = EXCLUDED."spreadHome",
                        "spreadAway" = EXCLUDED."spreadAway",
                        "spreadHomeOdds" = EXCLUDED."spreadHomeOdds",
                        "spreadAwayOdds" = EXCLUDED."spreadAwayOdds",
                        total = EXCLUDED.total,
                        "totalOverOdds" = EXCLUDED."totalOverOdds",
                        "totalUnderOdds" = EXCLUDED."totalUnderOdds"
                r   )	home_odds	away_odds)r   r  r  )	bookmakerr   ztheoddsapi:
theoddsapiT)external_game_idsourcecreate_snapshotsr   r   r  z$  Warning: unified schema error for 
CAPTURED: z odds records (legacy)z	UNIFIED: z
 created, z
 updated, z
 snapshotsQUOTA:  used, 
 remaining)r   r   r   nowr   utc	isoformatSPORTSr   r   upperlenr   fromisoformatreplacer   UNIFIED_SCHEMA_AVAILABLEappendr   r   r   r   r   r   )+r   r   r   r   total_capturedunified_statsleaguesport_configr   r   eventr   homeawaycommencecommence_dtbook	book_nameml_homeml_awayspread_homespread_awayspread_home_oddsspread_away_odds
total_line	over_odds
under_oddsmarket
market_keyr  obookmaker_odds_listmarkets_datah_oddsa_oddss_lines_homes_awayt_linet_overt_underresultr   s+                                              r   capture_live_oddsrM  j  s   '
++-CN !aa@M	Bvh-	
 	F8<<-779:
;<	VH \Vzz&) '		*V\\^$K016<<>""SYKw78 N	VEyyH$UYY{B%?HD$UYY{B%?HDyy1HK"*"8"89I9I#x9X"YK 		,3 D$ HHUI6	 %)(',00k6:: #3!
)--	J"hhy"5 <F!'E!2J%zz*b9H!U*!) 9A uuV}4*+%%.!"v$!6*+%%.	9 $y0!) BA uuV}4./eeGn3455> 0!"v$!6./eeGn3455> 0B $x/!) <A uuV}6-.UU7^
,-EE'N	!"v'!9-.UU7^
<+<:  . Hh$	W.>@P	:-: !#ID$N (K&(#!IIlB7 )fD $	 :I#%L"&((9b"9 "u%+ZZ%6
#)::j"#=%..22FV%- <#$55=D#8-.UU7^F%&UU6]d%:-.UU7^F	<
  &DJY_6`U 3'947;;F;Vf%- <#$55=D#8-.UU7^F-.UU7^F%&UU6]d%:-.UU7^F<  &1CIX^ms:tY 7'838<<F<Vg%- =#$55=F#:-.UU7^F-.UU7^F%&UU6]g%=./eeGnG=  &1BHW]ls9tX 6E"uH $+22Wc3deS)fV 'V!6 &+tT//:8*-E#/-1" &i0FJJy!4LL0%i0FJJy!4LL0%k2fjja6PP2YN	V\V| 	KKMIIK	Bvh-	J~&&<
=>	-	23:mI>V=WWabop{b|a}  ~H  I  	J	GG&&'ww/F/F.Gz
RS	VHaD % V DXJbQRPSTUUVs%   "%Y) A.Y1)Y.1	Z:ZZc                    |ddg}|j                         }d}t        dd        t        d       t        dt        j                  t        j
                        j                                 t        d        |D ]  }t        j                  |      }|s|d	   }|d
   }| j                  |      }	|	st        |j                          d       Vt        j                  t        j
                        }
g }|	D ]h  }|j                  d      }|s	 t        j                  |j                  dd            }|
|cxk  r|
t        d      z   k  rn n|j                  |       j t        d|j                          dt        |       d       |dd D ]  }|j                  d      }t!        |j                  dd      |      }t!        |j                  dd      |      }|j                  d      }d}|r&	 t        j                  |j                  dd            }| j#                  |||      }|s|j                  dg       D ]  }|j                  d	d      }|j                  dg       D ]  }|j                  d	      }|j%                  d      s&|j                  dg       D ]  }|j                  d|j                  dd            }|j                  d       }|j                  d!      }|j                  dd      j'                         }|j|d"k(  r|nd}|d#k(  r|nd}|j)                  d$|||||||||||f       |d%z  }     |j+                          |j-                          t        dd        t        d&| d'       t        d(| j.                   d)| j0                   d*       t        d        |S #  Y xY w#  Y xY w)+z'Capture player props for upcoming gamesNr   r&   r   r  r  zCAPTURING PLAYER PROPSr  r$   r%   r  r  r  r     )hoursr  z upcoming games (next 24h)
   r  r	  r   r
  )r   r  r  r   player_r  descriptionr  r  r  overundera  
                            INSERT INTO "PropSnapshot" (
                                league, "theoddsapiEventId", "gameDate", "homeTeam", "awayTeam",
                                bookmaker, "marketType", "playerName", "propLine",
                                "overPrice", "underPrice", "capturedAt"
                            ) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, date_trunc('minute', NOW()))
                            ON CONFLICT DO NOTHING
                        r   r  z prop recordsr  r  r   )r   r   r   r!  r   r"  r#  r$  r   r   r%  r'  r(  r   r*  r&  r   r   r   lowerr   r   r   r   r   )r   r   r   r   r+  r-  r.  r   r%   r   r!  upcoming_eventsr/  r2  r3  r   r0  r1  
event_oddsr4  r5  r?  r@  outcomeplayer_name	prop_liner  outcome_type
over_priceunder_prices                                 r   capture_player_propsr_  #  s   %.
++-CN	Bvh-	
"#	F8<<-779:
;<	VH S,zz&) '	#N3 ##I.V\\^$K01 ll8<<( 	Eyy1H"*"8"89I9I#x9X"YK[D31D+DD'..u5	 	6<<>""S%9$::TUV$Sb) 5	,EyyH$UYY{B%?HD$UYY{B%?HDyy1HK"*"8"89I9I#x9X"YK
 !//	8\/ZJ"|R8 ", HHUI6	"hhy"5 ,F!'E!2J%00; #)::j"#= ,&-kk-VUWAX&Y$+KK$8	 'G 4'.{{62'>'D'D'F %,$.:f.DU$
/;w/FeD % #Hk4%z;	& '!+3,,",'5	,=S,j 	KKMIIK	Bvh-	J~&m
45	GG&&'ww/F/F.Gz
RS	VHIs   AO 6%O OOc                 8   | j                         }t        dd        t        d       t        d        t        d|d   d       t        d|d   d       t        d	|d
   d       t        |d
   rd|d   |d
   z  dz  ddnd       t        d        y)zDisplay quota statusr  r  zTHE ODDS API QUOTA STATUSzUsed:      r   r   zRemaining: r   zTotal:     r   zUsage:     d   z.2f%zN/AN)r   r   )r   quotas     r   
show_quotard    s    !E	Bvh-	
%&	VH	Kfa(
)*	Kk*1-
./	Kgq)
*+	uW~Kfg6<SA
C[`a	VHr   c                     t        j                  d      } | j                  ddd       | j                  ddd       | j                  d	dd
       | j                  ddd       | j                  ddd       | j                  dt        dd       | j	                         }t               \  }}|st        d       y|st        d       yt        ||      }|j                  j                  d      D cg c]  }|j                          }}t        |j                  |j                  |j                  |j                  g      sd|_        |j                   rt#        |       |j                  r|D ]~  }t$        j'                  |      }|s|j)                  |d         }	t        d|j+                          dt-        |	       d       |	d d D ]  }
t        d|
d    d|
d     d!|
d"           !  |j                  s|j                  rbt/        j0                  |      }t3        |       |j                  rt5        |||       |j                  rt7        |||       |j9                          y#c c}w )$NzThe Odds API Enhanced Fetcher)rS  z--live
store_truezCapture live odds)actionhelpz--propszCapture player propsz--scoreszCapture scoresz--eventszList eventsz--quotazCheck quotaz	--leaguesznba,nfl,nhl,mlb,ncaab,ncaafzComma-separated leagues)typedefaultrh  z&ERROR: THE_ODDS_API_KEY not configuredr   z)ERROR: SPORTS_DATABASE_URL not configuredr   Tr$   r  r  r  r   z  r
  z @ r	  z - r  r   )argparseArgumentParseradd_argumentr   
parse_argsr   r   r   r   r   r   anylivepropsr   r   rc  rd  r$  r   r   r%  r&  psycopg2connectr   rM  r_  r   )parserargsr   r   r   lr   r-  r.  r   r   r   s               r   mainrw    s<   $$1PQF
<OP
	,=ST

<>NO

<mL
	,]K
#7T[tuD!mOFG679:0G"&,,"4"4S"9:Qqwwy:G: 		4::t{{DKK@A
zz7{{ 	[F!::f-L ++L,?@6<<>*"S[MAB [ABq~.c!K.1AQEWDXYZ[	[ yyDJJ'd99gtW5:: $8

= ;s   6I.__main__r   )*__doc__rk  r   rr  r   r   syspathinsertdirnameabspath__file__
team_namesr   r   r   r   typingr   r   r	   r
   lib.unified_odds_ingestionr   r   r   r)  ImportErrorr   r   r$  r   r   r   r   r   rM  r_  rd  rw  r   exitr   r   r   <module>r     s7       	 
 277??277??8#<= > ( 2 2 . . 277??8, -Z   $
 -t
		
t
 
%
t
: 

;t
L 

	Mt
` !
at
n '
ot
~  
t
J 

Kt
X *57OPYt
` %57OPat
h %57OPit
p (57OPqt
x 
*57OPyt
@ 
*56At
H 
56It
P 
'Qt
X 
 aYt
` 
 45at
n ,U38_ ,{M {M|0fv0 vc vrj"3 jDI jZ) 4n zL g  Z$	
XYZs   ;F( (F:9F: