ó
    ¹Õ.j�:  ã                  óB  • S r SSKJr  SSKrSSKJr  SSKJrJr  SSK	J
r
Jr  SSKJrJrJrJrJrJrJr  \rSS jr " S	 S
5      rSS jr\" S5      rSS jr S       SS jjrSS jrSS jrSSS jjr " S S\
5      r  " S S5      r!   S          S!S jjr"g)"uè  Vision+grid (Set-of-Mark) table-isolation approaches for the QUE-245 spike.

All approaches are Camelot-independent: they read the rendered page (with a
labeled grid overlaid) and report discrete grid IDs, which deterministic
geometry maps back to coordinates and snaps to the text layer. They differ
only in what the vision model is asked to bound:

  A "data-grid"   â€” the current production prompt: bound the data table
                    (header + aligned data cells); ignore page furniture.
  B "anatomy"     â€” bound the FULL table: title/caption + units line +
                    every column-header row (incl. spanning headers) + the
                    row-label stub column + all body/subtotal/total rows +
                    footnotes attached to the table. Separate stacked
                    tables; keep a single gapped table whole.

The grid readout, geometry, and text-layer tightening are shared, so an
A-vs-B difference is attributable to the instruction, not the machinery.
é    )ÚannotationsN)ÚPath)ÚListÚOptional)Ú	BaseModelÚField)ÚGridFlagÚGridFlagResultÚLocatedTableÚbuild_promptÚcolumn_labelsÚflags_to_locatedÚoverlay_gridc                óŽ   • [        U5      S   nSU  SU  SU SU S[        R                  " [        R                  " 5       SS9 S	3$ )
Néÿÿÿÿz$The page image has a grid overlaid: z+ numbered horizontal rows (1 at the
top to z2 at the bottom, labeled on BOTH side margins) and z$ lettered
columns (A at the left to u0   at the right, labeled on the top and bottom
margins), with thin gridlines.

WHAT COUNTS AS A TABLE: a block where values are arranged in a GRID â€” the same
two or more columns line up vertically across multiple rows. These are tables.
The following are NOT tables, even when they contain dollar amounts or numbers,
and must never be flagged: a bulleted or numbered list; a single column of
figures; a heading followed by prose sentences; a paragraph. If the numbers do
not line up into repeating vertical columns, it is not a table.

Find every TABLE on the page and report the grid region that bounds each one
COMPLETELY. Bound the WHOLE table, including all of its parts:

- TITLE / CAPTION: the table's heading line(s) and any units line directly
  above the columns (e.g. "Condensed Consolidated Statements of Income",
  "(In millions)", "(UNAUDITED)"). Include them in the region.
- COLUMN HEADERS: every header row, including multi-level / spanning headers
  (a label like "Three Months Ended" that sits above several sub-columns, with
  the period and year rows beneath it). Include all header levels.
- ROW LABELS (the stub column): the left-hand column of row names. The region's
  LEFT edge must include it â€” do not start at the first number.
- BODY: every data row, including subtotal and total rows. Never cut a table
  off partway; blank lines inside a table do NOT end it.
- FOOTNOTES: short notes tied to the table by a marker (e.g. "(1)", "(2)")
  sitting just below it. Include them inside that table's region. Footnotes are
  NEVER a table of their own â€” never report them as a separate table.

Counting tables â€” judge by what you see, not by repeated text:
- Two tables stacked vertically are separate ONLY when each has its own
  title/caption and its own column-header block. Report them separately.
- One table may have section sub-headings inside it (e.g. "Cash flows from
  operating activities:", "Current assets:") and blank lines between sections.
  These do NOT start a new table â€” keep the whole thing as ONE region.
- Repeated "$" signs or a repeated subtotal style inside one table do NOT make
  a new table. When unsure, prefer ONE region over splitting.
Do NOT merge two genuinely separate tables, and do NOT split one table.

Exclude page furniture (running header timestamp, page number, document URL)
and free-standing prose paragraphs / lists that are not a table.

For each table, in reading order (top-to-bottom, then left-to-right), report:
- ordinal (1 = first)
- title (its visible caption, else a one-line summary of its columns)
- row_start: printed row number at the TOP of the title line (one row ABOVE the
  column headers when a title/caption is present) â€” include the title row
- row_end: printed row number at the BOTTOM-most part (last total, or footnote)
- col_start: printed column LETTER at the left edge, INCLUDING the row labels
- col_end: printed column LETTER at the right edge (last data column)

Read the printed labels off the grid â€” do not estimate coordinates.

Return ONLY a JSON object conforming to this schema (no prose, no code fences):

é   )ÚindentÚ
)r   ÚjsonÚdumpsr
   Úmodel_json_schema)ÚrowsÚcolsÚlasts      Ú7/home/mande/repo/quber/experiments/que245/approaches.pyÚanatomy_promptr   .   si   € Ü˜Ó˜rÑ"€Dð%Ø%) Fð +Ø€vÐ?À¸vð FØ˜&ð 5!ôj ‡‚ŒN×,Ò,Ó.°qÑ9Ð :ð ;ðq9ð 9ó    c                  óZ   • \ rS rSrSr      S               SS jjrS	S jrSrg)
ÚFlexGridLocatoréo   a  A GridLocator whose prompt and model are parameters.

Mirrors PydanticAIGridLocator's auth + decoding, but lets the spike swap
the instruction (data-grid vs anatomy) and the model tier (haiku@temp0
vs a higher tier with no temperature pin) without forking the class.
c                ó|  • SSK Jn  SSKJn	  SSKJn
  U
" 5       R                  nUR                  nUR                  nU(       a  SSK	J
n  U" X,5      nO*U(       a  SSKJn  SSKJn  U" UU" US9S	9nO[        S
5      eX l        X@l        XPl        X`l        Xpl        Xl        Uc  S OU	" US9nU" U[,        UUS9U l        g )Nr   )ÚAgent)ÚModelSettings)Úget_settings)Úmake_oauth_anthropic_model)ÚAnthropicModel)ÚAnthropicProvider)Úapi_key)Úproviderz6No ANTHROPIC_AUTH_TOKEN / ANTHROPIC_API_KEY available.)Útemperature)Úoutput_typeÚsystem_promptÚmodel_settings)Úpydantic_air"   Úpydantic_ai.settingsr#   Úquber.settingsr$   ÚllmÚanthropic_auth_tokenÚanthropic_api_keyÚquber.agents._oauth_gater%   Úpydantic_ai.models.anthropicr&   Úpydantic_ai.providers.anthropicr'   ÚRuntimeErrorÚmodelr   r   ÚsnapÚpad_ptsr,   r
   Úagent)Úselfr,   r8   r*   r   r   r9   r:   r"   r#   r$   r1   ÚauthÚkeyr%   Úanthr&   r'   Úmss                      r   Ú__init__ÚFlexGridLocator.__init__w   sª   € õ 	&Ý6å/á‹n× Ñ ˆØ×'Ñ'ˆØ×#Ñ#ˆÞÝKá-¨eÓ:‰DÞÝCÝIá! %Ñ2CÈCÑ2PÑQ‰DäÐWÓXÐXàŒ
ØŒ	ØŒ	ØŒ	ØŒØ*ÔØ Ñ(‰T©mÈÑ.TˆÙ˜4¬^È=ÐikÑlˆ�
r   c              ƒ  óì  #   • SS K nSS KnSSKJn  SSKJn  UR                  SS9 n[        U5      S-  n	[        [        U5      X�R                  U R                  5        U" U	R                  5       SS9n
U R                  R                  S	U
/5      I S h  v•N nUR                  U[        U5      U5      I S h  v•N u  pÍnS S S 5        [        WR                   R"                  WWWU R                  U R                  5      nU R$                  S
:”  a$  ['        XüXÐR$                  5      n[)        XþXÍ5      nU$ U R*                  (       a  [)        XþXÍ5      n[-        XþXÍ5      nU$  NÊ N¨! , (       d  f       N©= f7f)Nr   )ÚBinaryContent)Ú
page_wordszque245-grid-)Úprefixzgridded.pngz	image/png)ÚdataÚ
media_typezFlag the tables using the grid.ç        )ÚasyncioÚtempfiler.   rD   Úquber.agents.completenessrE   ÚTemporaryDirectoryr   r   r   r   Ú
read_bytesr;   ÚrunÚ	to_threadr   ÚoutputÚtablesr:   Ú	pad_boxesÚdeclash_stackedr9   Úsnap_titles)r<   Ú
page_imageÚsourceÚpagerJ   rK   rD   rE   ÚtmpÚgriddedÚimageÚresultÚpage_wÚpage_hÚwordsÚlocateds                   r   ÚlocateÚFlexGridLocator.locatež   s7  é € ÛÛå-å8à×(Ñ(°Ð(Ñ?À3Ü˜3“i -Ñ/ˆGÜœ˜jÓ)¨7·I±I¸t¿y¹yÔIÙ! w×'9Ñ'9Ó';ÈÑTˆEØŸ:™:Ÿ>™>Ð+LÈeÐ*TÓU×UˆFØ*1×*;Ñ*;¸JÌÈVËÐVZÓ*[×$[Ñ!ˆF˜E÷ @ô # 6§=¡=×#7Ñ#7¸ÀÈÐPT×PYÑPYÐ[_×[dÑ[dÓeˆØ�<‰<˜#ÓÜ °¿¹ÓFˆGÜ% g°fÓEˆGð ˆð �Y�YÜ% g°fÓEˆGÜ! '°&ÓAˆGØˆñ VÙ$[÷ @Õ?üsB   ‚$E4¦A.E#ÂEÂ#E#Â8E!Â9E#Ã BE4ÅE#Å!E#Å#
E1Å-E4)r;   r   r8   r:   r   r9   r,   N)úclaude-haiku-4-5-20251001rI   é   é   FrI   )r,   Ústrr8   rf   r*   úOptional[float]r   Úintr   rh   r9   Úboolr:   ÚfloatÚreturnÚNone)rV   r   rW   r   rX   rh   rk   zList[LocatedTable]©Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__rA   ra   Ú__static_attributes__© r   r   r   r   o   s}   † ñð 1Ø'*ØØØØð%màð%mð ð%mð %ð	%mð
 ð%mð ð%mð ð%mð ð%mð 
õ%m÷Nr   r   c                ó®  • U  Vs/ s H;  o3S   US   -   S-  U:  d  M  [        US   5      R                  5       (       d  M9  UPM=     nnUR                  S S9  / n/ SpvU HT  nUS   US   -   S-  nUb  [        X‡-
  5      S::  a  UR	                  U5        Uc  UOUnM?  UR	                  U5        U/UpvMV     U(       a  UR	                  U5        U$ s  snf )	zBCluster words whose center sits above `top_pts` into visual lines.é   é   ç       @é   c                ó   • U S   U S   -   S-  $ )Nrv   rw   rx   rt   )Úws    r   Ú<lambda>Ú_lines_above.<locals>.<lambda>¼   s   € ˜q ™t a¨¡d™{¨cÒ1r   ©r>   Ng      @)rf   ÚstripÚsortÚabsÚappend)	r_   Útop_ptsr^   r{   ÚaboveÚlinesÚcurÚcycÚycs	            r   Ú_lines_abover‰   ¹   sÓ   € áÓUš�1 A¡$¨¨1©¡+°Ñ!4°wÑ!>‹QÄ3ÀqÈÁtÃ9Ç?Á?×CT�Q™€EÐUØ	‡J�JÑ2€JÑ3Ø€EØ�4ˆÛˆØ�‰d�Q�q‘T‰k˜SÑ ˆØ‰;œ#˜b™h›-¨3Ó.Ø�J‰J�qŒMØ™‘"¨ŠCà�L‰L˜ÔØ�s˜B’ñ ö Ø�‰�SÔØ€Lùò Vs   …CžCÁCu   0123456789.,()%-$ â€”â€“c                óÂ   • SnU  HV  n[        US   5      R                  5       n[        S U 5       5      (       d  M8  [        S U 5       5      (       d  MQ  US-  nMX     U$ )z<Words in a line that read as numbers ($, %, parens, digits).r   ry   c              3  ó@   #   • U  H  oR                  5       v •  M     g 7f©N)Úisdigit©Ú.0Úcs     r   Ú	<genexpr>Ú&_numeric_word_count.<locals>.<genexpr>Ô   s   é € Ð&¢A˜q�y‰y�{ˆ{¢Aùs   ‚c              3  ó2   #   • U  H  o[         ;   v •  M     g 7frŒ   )Ú_NUM_OKrŽ   s     r   r‘   r’   Ô   s   é € Ð.GÂQÀ´G®|ÂQùs   ‚rv   )rf   r   ÚanyÚall)ÚlineÚnr{   Úts       r   Ú_numeric_word_countrš   Ï   sV   € à	€AÛˆÜ��!‘‹I�O‰OÓˆÜÑ&¡AÓ&×&Ó&¬3Ñ.GÁQÓ.G×+GÓ+GØ�‰FŠAñ ð €Hr   c                ór  • U u  pgp‰Xs-  n
X†-
  U-  n[        [        XU5      5       Hˆ  n[        S U 5       5      n[        S U 5       5      n[        S U 5       5      n[        S U 5       5      nXôS-   ::  a    O7U
U-
  nUU:”  d  US:  a    O$Xí-
  SU-  :”  a    O[	        U5      S:¼  a    OUn
MŠ     XjU-  X‰4$ )	u  Extend a box upward to capture a short caption/title line or two.

Conservative by construction. Walking the lines directly above the box
top, nearest first, a line is pulled in only when it is ALL of: close
(gap <= max_gap_pts ~ one line), above the `ceiling` (the bottom of the
table directly above â€” never climb into it), short (< 70% of the table
width), and not a data row (fewer than 3 numeric words). The first line
that fails any test stops the walk. A no-op when the model already
bounded the title. Returns a normalized box.
c              3  ó*   #   • U  H	  oS    v •  M     g7f)r   Nrt   ©r�   r{   s     r   r‘   Ú"extend_to_title.<locals>.<genexpr>ï   ó   é € Ð%¢˜1�A–$¢ùó   ‚c              3  ó*   #   • U  H	  oS    v •  M     g7f)r   Nrt   r�   s     r   r‘   rž   ð   rŸ   r    c              3  ó*   #   • U  H	  oS    v •  M     g7f)rv   Nrt   r�   s     r   r‘   rž   ñ   rŸ   r    c              3  ó*   #   • U  H	  oS    v •  M     g7f©rw   Nrt   r�   s     r   r‘   rž   ò   rŸ   r    ç      ð?g       Àgffffffæ?rw   )Úreversedr‰   ÚminÚmaxrš   )Úregionr_   r]   r^   Úceiling_ptsÚmax_gap_ptsÚx0Úy0Úx1Úy1Úcur_topÚtable_wr—   Úlx0Úlx1ÚltyÚlbyÚgaps                     r   Úextend_to_titler·   Ù   sÖ   € ð$ �N€BˆBØ‰k€GØ‰w˜&Ñ €GÜœ e°fÓ=Ö>ˆÜÑ%¡Ó%Ó%ˆÜÑ%¡Ó%Ó%ˆÜÑ%¡Ó%Ó%ˆÜÑ%¡Ó%Ó%ˆØ Ñ#Ó#ÙØ˜‰mˆØ�Ó  d£
ÙØ‰I˜ ™Ó'ÙÜ˜tÓ$¨Ó)ÙØŠñ ?ð ˜&Ñ  "Ð)Ð)r   c                ó>  • [        U S S9n0 nSnU H9  nXe[        U5      '   [        UR                  S   UR                  S   5      U-  nM;     / nU  HF  n[	        UR                  XX5[        U5         5      n	UR                  UR                  SU	0S95        MH     U$ )z>Title-extend each box, never crossing into the table above it.c                óN   • [        U R                  S   U R                  S   5      $ ©Nrv   rw   ©r§   r©   ©r™   s    r   r|   Úsnap_titles.<locals>.<lambda>  ó   € ¬#¨a¯h©h°q©k¸1¿8¹8ÀA¹;Ô*Gr   r~   rI   rv   rw   r©   ©Úupdate)ÚsortedÚidr¨   r©   r·   r‚   Ú
model_copy)
r`   r_   r]   r^   ÚorderÚceilingsÚprev_bottomr™   ÚoutÚ
new_regions
             r   rU   rU      sž   € ä�7Ñ GÑH€EØ€HØ€KÛˆØ%”�A“‰Ü˜!Ÿ(™( 1™+ q§x¡x°¡{Ó3°fÑ<Šñ ð €CÛˆÜ$ Q§X¡X¨u¸fÌrÐRSËuÁoÓVˆ
Ø�
‰
�1—<‘<¨°*Ð'=�<Ð>Ö?ñ ð €Jr   c           	     óô   • X1-  X2-  pT/ nU  Hh  nUR                   u  p‰p«[        SX„-
  5      [        SX•-
  5      [        SX¤-   5      [        SXµ-   5      4nUR                  UR	                  SU0S95        Mj     U$ )aI  Grow every box by a fixed pad on all sides (clamped to the page).

For a guidance box, slight over-inclusion is safe and clipping is not, so
a dumb symmetric pad covers residual sub-grid-row edge misses without any
content-dependent heuristic. Overlaps it creates between stacked tables
are resolved by a following declash pass.
rI   r¥   r©   r¿   )r©   r¨   r§   r‚   rÃ   )r`   r]   r^   r:   ÚpxÚpyrÇ   r™   r¬   r­   r®   r¯   Úrs                r   rS   rS     s�   € ð Ñ˜wÑ/ˆØ
€CÛˆØŸ™‰ˆ�Ü��b‘gÓ¤ C¨©Ó 1´3°s¸B¹GÓ3DÄcÈ#ÈrÉwÓFWÐXˆØ�
‰
�1—<‘<¨°! }�<Ð5Ö6ñ ð €Jr   c                óŠ  • [        U S S9nU Vs0 s H"  n[        U5      [        UR                  5      _M$     nn[	        XUSS 5       GH+  u  p‰U[        U5         n
[        U
S   U
S   5      U-  [        U
S   U
S   5      U-  pË[        U	R                  S   U	R                  S   5      U-  nXÍU-
  ::  a  Mp  [        U
S   U
S   5      U-  n[        U
S   U
S   5      U-  nU Vs/ s HL  nUUS   US   -   S-  s=:  a  US	-
  :  d  M!  O  M%  US-
  US   US   -   S-  s=::  a  US-   ::  d  MF  O  MJ  UPMN     nn[        [        S
 U 5       US9U5      nU
S   X³-  U
S   UU-  /U[        U5      '   GM.     / nU  H8  nUR                  UR                  S[        U[        U5         5      0S95        M:     U$ s  snf s  snf )u³  Remove vertical overlap between stacked table boxes at their seam.

When an upper box's bottom runs into a lower box's top (grid quantization
plus title-snap can pull the lower table's title into the upper box), pull
the upper box's bottom UP to its own last row of text â€” the last word that
sits above the lower box's top. The model already decided these are two
tables; this only cleans the shared edge, it never merges or splits.
c                óN   • [        U R                  S   U R                  S   5      $ rº   r»   r¼   s    r   r|   Ú!declash_stacked.<locals>.<lambda>)  r¾   r   r~   rv   Nrw   r   r   rx   g      à?c              3  ó*   #   • U  H	  oS    v •  M     g7fr¤   rt   r�   s     r   r‘   Ú"declash_stacked.<locals>.<genexpr>7  s   é € Ð-ª A˜Qž4ªùr    )Údefaultr©   r¿   )
rÁ   rÂ   Úlistr©   Úzipr§   r¨   r‚   rÃ   Útuple)r`   r_   r]   r^   Úmin_gap_ptsrÄ   r™   Úregion_by_idÚupperÚlowerÚurÚu_topÚu_botÚseamÚux0Úux1r{   ÚselÚnew_botrÇ   s                       r   rT   rT      s÷  € ô �7Ñ GÑH€EÙ38Ó9²5¨a”B�q“Eœ4 §¡›>Ò)±5€LÐ9Ü˜E¨¨ 9×-‰ˆØœ"˜U›)Ñ$ˆÜ˜2˜a™5 " Q¡%Ó(¨6Ñ1´3°r¸!±u¸bÀ¹eÓ3DÀvÑ3MˆuÜ�5—<‘< ‘? E§L¡L°¡OÓ4°vÑ=ˆØ˜;Ñ&Ó&ÙÜ�"�Q‘%˜˜A™Ó &Ñ(ˆÜ�"�Q‘%˜˜A™Ó &Ñ(ˆáó
Ú�!Ø˜˜!™˜q ™t™ sÑ*Õ7¨T°C©ZÑ7ó Ù7ñ Ø<?À!¹GÈÈ!ÉÈqÐQRÉtÉÐWZÑGZÕ<eÐ^aÐdeÑ^eÑ<eó Ù<eõ ‘uð 	ð 
ô ”cÑ-©Ó-°tÑ<¸dÓCˆØ#% a¡5¨%©.¸"¸Q¹%ÀÈ6ÑAQÐ"Rˆ”R˜“YÔñ .ð €CÛˆØ�
‰
�1—<‘<¨´%¸ÄRÈÃUÑ8KÓ2LÐ'M�<ÐNÖOñ à€Jùò% :ùò
s#   �)F;Ã' G ÄG ÄG Ä0G Ä4G c                  ó    • \ rS rSr% S\S'   Srg)Ú_Regioni?  rÕ   r©   rt   N)rn   ro   rp   rq   Ú__annotations__rs   rt   r   r   rã   rã   ?  s   ‡ Ø†Mr   rã   c                  ó0   • \ rS rSrSrSSS jjrS	S jrSrg)
ÚRawVisionLocatoriC  u>  The continuous-coordinate baseline: the production table detector.

Asks the vision model for each table's bbox directly (no grid, no text
snap). This is the path the QUE-241 evidence found unreliable â€” boxes
drift, clip, and merge. Included so the grid approaches are measured
against the thing they would replace.
c                ó&   • SSK Jn  U" XS9U l        g )Nr   )ÚPydanticAITableDetector©r8   r*   )Úquber.agents.detectorrè   Údet)r<   r8   r*   rè   s       r   rA   ÚRawVisionLocator.__init__L  s   € ÝAá*°ÑPˆ�r   c              ƒ  óú   #   • U R                   R                  [        U5      5      I S h  v•N nUR                   Vs/ s H-  oUR                  c  M  [        [        UR                  5      S9PM/     sn$  NIs  snf 7f)N)r©   )rë   Údetectr   rR   Úbboxrã   rÕ   )r<   rV   rW   rX   Úresr™   s         r   ra   ÚRawVisionLocator.locateQ  sT   é € Ø—H‘H—O‘O¤D¨Ó$4Ó5×5ˆØ7:·z²zÓX²z°!ÇVÁVÓ-”œu Q§V¡V›}Ô-±zÑXÐXñ 6ùÚXùs&   ‚(A;ªA4«A;½A6Á A6Á1A;Á6A;)rë   N)rc   rI   )r*   rg   )rV   r   rW   r   rX   rh   rm   rt   r   r   ræ   ræ   C  s   † ñöQ÷
Yr   ræ   c           
     óÒ   • U S:X  a	  [        XS9$ SnU S:X  a  [        X45      nO9U S;   a$  [        X45      nU=(       d    U S:H  nU S:X  a  UOSnO[        SU < 35      e[	        X�X#UXWS	9$ )
NÚrawré   rI   z	data-grid)Úanatomyúanatomy-snapúanatomy-padrõ   rö   zunknown approach )r8   r*   r   r   r9   r:   )ræ   Úbuild_data_grid_promptr   Ú
ValueErrorr   )	Úapproachr8   r*   r   r   r9   r:   ÚpadÚprompts	            r   Úmake_locatorrü   V  sˆ   € ð �5ÓÜ eÑEÐEØ
€CØ�;ÓÜ'¨Ó3‰Ø	Ð?Ó	?Ü Ó+ˆØ×1�x >Ñ1ˆØ! ]Ó2‰g¸‰äÐ,¨X©LÐ9Ó:Ð:Ü˜6¸KÐY]Ø $ñ3ð 3r   )r   rh   r   rh   rk   rf   )rƒ   rj   r^   rj   )rk   rh   )g      0@)r]   rj   r^   rj   rª   rj   r«   rj   )r]   rj   r^   rj   )r]   rj   r^   rj   r:   rj   )rx   )r]   rj   r^   rj   rÖ   rj   )rc   rI   rd   re   Fg      @)rù   rf   r8   rf   r*   rg   r   rh   r   rh   r9   ri   r:   rj   )#rr   Ú
__future__r   r   Úpathlibr   Útypingr   r   Úpydanticr   r   Úquber.agents.grid_locatorr	   r
   r   r   r÷   r   r   r   ÚDATA_GRID_PROMPTr   r   r‰   Úsetr”   rš   r·   rU   rS   rT   rã   ræ   rü   rt   r   r   Ú<module>r     sï   ðñõ& #ã Ý ß !ç %÷÷ ñ ð *Ð ô;÷BDñ DôTñ& Ð(Ó
)€ôð  ð$*ð ð$*ð ð	$*ð
 ð$*ð õ$*ôNôö"ô>ˆiô ÷Yñ Yð& .IØQSØ69ð3Ø-ð3Ø;>ð3ØKNð3àð3à.3ö3r   