+
    %ð·jÔ(  ã                   ób  € R t ^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RI	t	^ RI
t
^ RIt]P                  ! ]4      P                  4       P                   t]P$                  P'                  ^ ]! ]4      4       ^ RIt^ RIt^ RIt]P                   R,          R,          R,          tRt ! R R4      t ! R R	]]
P6                  4      t ! R
 R]
P6                  4      t]
P<                  ! ]P?                  4       R4       ! R R]]
P6                  4      4       t ]!R8X  d   ]
PD                  ! 4        R# R# )ul   Tests for the æµ�è§ˆå™¨ vs æœ�åŠ¡ç«¯ page's server side:  python3 -m unittest scripts/test_compute_bridge.pyNÚtargetÚreleaseÚcomputeaa  #!/usr/bin/env python3
import json, sys, time
args = sys.argv[1:]
if args[0] == 'gomoku':
    print(json.dumps({"x": 7, "y": 7, "score": 0, "nodes": 1, "ms": 0.1, "threads": int(args[3]), "side": 1}), flush=True)
    sys.exit(0)
if args[0] == 'bench':
    if args[1] == 'sudoku' and args[2] == '999':
        time.sleep(30)          # never finishes in time
    print(json.dumps({"task": args[1], "size": int(args[2]), "digest": "fake", "compute_ms": 1.5}), flush=True)
else:
    w, h = int(args[1]), int(args[2])
    print(json.dumps({"type": "start", "w": w, "h": h}), flush=True)
    for y in range(0, h, 16):
        print(json.dumps({"type": "band", "y": y, "rows": min(16, h - y), "thread": 0, "ms": 1, "data": ""}), flush=True)
        time.sleep(0.05 if h > 100 else 0)
    print(json.dumps({"type": "done", "ms": 2, "threads": 1, "bands": 1}), flush=True)
c                   ón   a € ] tR t^*t o Rt]R 4       t]R 4       t]R	R l4       tR t	R
R lt
R tRtV tR# )ÚHarnessNc                ó|  € \         P                  ! 4       V n        \        P                  ! V P                  P
                  4      R ,          pVP                  \        P                  ! R. /4      RR7       V P                  f{   \        P                  ! V P                  P
                  4      R,          pVP                  \        P                  R\        P                  4      RR7       VP                  R4       TpMV P                  p\        P                   ! V^ 4      V n        \$        P&                  ! W0P"                  P(                  ^R7      V n        \,        P.                  ! ^ V P"                  R	R
V P*                  R7      V n        V P0                  P2                  ^,          ;V n        V P"                  n        \6        P8                  ! V P0                  P:                  R
R7      P=                  4        V P?                  RRR7      ^,          P?                  RR4      PA                  R4      ^ ,          V n!        R# )zmcp.config.jsonÚserverszutf-8)ÚencodingNr   z/usr/bin/env python3ií  ©Útimeoutú	127.0.0.1T)ÚhostÚquietr   )r   Údaemonz/www/server-compute/F©Úcookiez
Set-CookieÚ Ú;)"ÚtempfileÚTemporaryDirectoryÚtmpÚpathlibÚPathÚnameÚ
write_textÚjsonÚdumpsÚBINARYÚFAKEÚreplaceÚsysÚ
executableÚchmodÚ
mcp_bridgeÚBridgeÚbridgeÚcompute_bridgeÚComputeBridgeÚ	authorizer   ÚserveÚmake_serverÚhttpdÚserver_addressÚportÚ	threadingÚThreadÚserve_foreverÚstartÚgetÚsplitr   )ÚclsÚconfigÚfakeÚbinarys   &   Ú3/work/data/stt/webtt/scripts/test_compute_bridge.pyÚ
setUpClassÚHarness.setUpClass-   s„  € ä×-Ò-Ó/ˆŒÜ—’˜cŸg™gŸl™lÓ+Ð.?Õ?ˆØ×Ñœ$Ÿ*š* i° _Ó5ÀÐÔHØ�:‰:ÒÜ—<’< §¡§¡Ó-°	Õ9ˆDØ�O‰OœDŸL™LÐ)?ÄÇÁÓPÐ[bˆOÔcØ�J‰J�uÔØ‰Fà—Z‘ZˆFÜ×&Ò& v¨qÓ1ˆŒ
Ü$×2Ò2°6¿:¹:×;OÑ;OÐYZÔ[ˆŒÜ×%Ò% a¨¯©¸+ÈTÐ[^×[fÑ[fÔgˆŒ	Ø%(§Y¡Y×%=Ñ%=¸aÕ%@Ð@ˆŒ�3—:‘:”?Ü×Ò §	¡	× 7Ñ 7ÀÔE×KÑKÔMØ—W‘WÐ3¸E�WÓBÀ1ÕE×IÑIÈ,ÐXZÓ[×aÑaÐbeÓfÐghÕiˆŽ
ó    c                ó¢   € V P                   P                  4        V P                  P                  4        V P                  P	                  4        R # )N)r+   Úshutdownr%   r   Úcleanup)r4   s   &r8   ÚtearDownClassÚHarness.tearDownClass@   s0   € à�	‰	×ÑÔØ�
‰
×ÑÔØ�‰�‰Ör;   c                óö  € \         P                  P                  R V P                  ^R7      pRRV P                   2/pV'       d   V P                  VR&   RpVe*   \
        P                  ! V4      P                  4       pRVR&   VP                  W1WvR7       VP                  4       pVP                  4       P                  4       p	VP                  4        VP                  \        VP                  4       4      V	3# )	r   r
   ÚHostú
localhost:ÚCookieNzapplication/jsonúContent-Type)ÚbodyÚheaders)ÚhttpÚclientÚHTTPConnectionr-   r   r   r   ÚencodeÚrequestÚgetresponseÚreadÚdecodeÚcloseÚstatusÚdictÚ
getheaders)
r4   Úpathr   ÚmethodrF   ÚconnrG   ÚdataÚrespÚtexts
   &&&&&     r8   r2   ÚHarness.getF   sË   € ä�{‰{×)Ñ)¨+°s·x±xÈÐ)ÓLˆØ˜Z¨¯© zÐ2Ð3ˆßØ #§
¡
ˆG�HÑØˆØÒÜ—:’:˜dÓ#×*Ñ*Ó,ˆDØ&8ˆG�NÑ#Ø�‰�V¨ˆÔ>Ø×ÑÓ!ˆØ�y‰y‹{×!Ñ!Ó#ˆØ�
‰
ŒØ�{‰{œD §¡Ó!2Ó3°TÐ9Ð9r;   c                óh   € V P                  R RRVRV/R7      w  r4pV\        P                  ! V4      3# )z/api/compute/benchÚPOSTÚtaskÚsize©rU   rF   ©r2   r   Úloads)Úselfr]   r^   rQ   Ú_rY   s   &&&   r8   ÚbenchÚHarness.benchV   s;   € ØŸ(™(Ð#7ÀÈfÐVZÐ\bÐdhÐMi˜(Ój‰ˆ�4Ø”t—z’z $Ó'Ð'Ð'r;   c           
     ól   € V P                  R RRVRVRV/R7      w  rEpV\        P                  ! V4      3# )z/api/compute/gomokur\   ÚboardÚdepthÚthreadsr_   r`   )rb   rg   rh   ri   rQ   rc   rY   s   &&&&   r8   ÚgomokuÚHarness.gomokuZ   sL   € ØŸ(™(Ð#8ÀÈwÐX]Ð_fÐhmÐoxð  {Bð  OC˜(ó  D‰ˆ�4Ø”t—z’z $Ó'Ð'Ð'r;   c                ó(  € V P                  R \        P                  P                  V4      ,           4      w  r#pVP	                  4        Uu. uF8  qUP                  R4      '       g   K  \        P                  ! VR,          4      NK:  	  ppW#V3# u upi )z/api/compute/render?zdata: :é   NN)r2   ÚurllibÚparseÚ	urlencodeÚ
splitlinesÚ
startswithr   ra   )rb   ÚparamsrQ   rG   rY   ÚlÚeventss   &,     r8   ÚrenderÚHarness.render^   sr   € Ø $§¡Ð)?Ä&Ç,Á,×BXÑBXÐY_ÓB`Õ)`Ó aÑˆ˜Ø-1¯_©_Ô->ÓYÑ->¨Ç,Á,Èx×BXÔ#”$—*’*˜Q˜r�UÖ#Ñ->ˆÐYØ Ð&Ð&ùò Zs   ÁBÁ(!B© )TÚGETN)é   )Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__r   Úclassmethodr9   r?   r2   rd   rj   rv   Ú__static_attributes__Ú__classdictcell__©Ú__classdict__s   @r8   r   r   *   sZ   ø‡ € Ø€Fàñjó ðjð$ ñó ðð
 ó:ó ð:ò(ô(÷'ð 'r;   r   c                   óV   a € ] tR t^dt o R tR tR tR tR tR t	R t
R tR	 tR
tV tR# )ÚFakeBinaryTestc                ób  € V P                  V P                  P                  R 4      4       V P                  RV P                  P                  4       R,           R4       V P                  V P                  RRR7      ^ ,          R4       V P                  V P                  R4      ^ ,          ^È4       R# )	z
mcp_token=z
Path=/api;r   z"the token reaches /api/compute tooú/api/compute/infoFr   i“  N)Ú
assertTruer   rr   ÚassertInr%   Úcookie_headerÚassertEqualr2   )rb   s   &r8   Ú3test_access_needs_the_same_token_as_the_mcp_consoleÚBFakeBinaryTest.test_access_needs_the_same_token_as_the_mcp_consolee   s‚   € Ø�‰˜Ÿ™×.Ñ.¨|Ó<Ô=Ø�‰�l D§K¡K×$=Ñ$=Ó$?À#Õ$EÐGkÔlØ×Ñ˜Ÿ™Ð"5¸e˜ÓDÀQÕGÈÔMØ×Ñ˜Ÿ™Ð"5Ó6°qÕ9¸3Ö?r;   c                óB  € \         P                  ! V P                  R 4      ^,          4      pV P                  VR,          4       V P	                  VR,          \
        P                  ! 4       4       V P	                  VR,          R,          \        P                  4       R# )r‡   Ú	availableÚcoresÚlimitsÚmax_mibN)	r   ra   r2   rˆ   r‹   ÚosÚ	cpu_countr&   ÚMAX_MIB)rb   Úinfos   & r8   Ú/test_info_reports_availability_cores_and_limitsÚ>FakeBinaryTest.test_info_reports_availability_cores_and_limitsk   si   € Ü�zŠz˜$Ÿ(™(Ð#6Ó7¸Õ:Ó;ˆØ�‰˜˜[Õ)Ô*Ø×Ñ˜˜g�¬¯ª«Ô7Ø×Ñ˜˜h�¨	Õ2´N×4JÑ4JÖKr;   c                óæ   € V P                  R ^4      w  rV P                  V^È4       V P                  VR,          VR,          VR,          3R4       V P                  VR,          VR,          4       R# )Úsha256r]   r^   ÚdigestÚ	server_msÚ
compute_msN)rš   é   r6   )rd   r‹   ÚassertGreaterEqual)rb   rQ   Úresults   &  r8   Ú9test_bench_returns_the_programs_result_and_the_round_tripÚHFakeBinaryTest.test_bench_returns_the_programs_result_and_the_round_tripq   sc   € ØŸ™ H¨aÓ0‰ˆØ×Ñ˜ Ô%Ø×Ñ˜& �.¨&°­.¸&ÀÕ:JÐKÐMbÔcØ×Ñ  {Õ 3°V¸LÕ5IÖJr;   c                ó  € R RR^/R RR^ /R RR\         P                  ^,           /R RR\         P                  ^,           /R RRR/R RRR/3 F8  pV P                  VR ,          VR,          4      w  r#V P	                  VRV4       K:  	  R^ R	^
R
^R^ R^/RRR	^
R
^R^ R^/R^
R	^
R
RR^ R^/R^
R	^
R
^R^R^/R^
R	^
R
^R^ R^ /R^
R	^
R
^R^ RR/RRR	^
R
^R^ R^/3 F-  pV P	                  V P
                  ! R/ VB ^ ,          RV4       K/  	  R# )r]   Úrmr^   rš   ÚsudokuÚ1Té�  ÚwÚhÚsppÚsceneri   iÐ  éç  é'  ÚxNrx   )r&   r•   Ú
MAX_ROUNDSrd   r‹   rv   )rb   rF   rQ   rc   rs   s   &    r8   Ú6test_bad_requests_are_refused_before_starting_anythingÚEFakeBinaryTest.test_bad_requests_are_refused_before_starting_anythingw   sâ  € Ø˜d F¨AÐ.°¸À6È1Ð0MÐPVÐX`ÐbhÔjx÷  kAñ  kAð  DEõ  kEð  PFØ˜h¨´×0IÑ0IÈAÕ0MÐNÐQWÐYaÐciÐknÐPoÐrxð  {Cð  EKð  MQð  rRóSˆDàŸ
™
 4¨¥<°°fµÓ>‰IˆFØ×Ñ˜V S¨$Ö/ñSð ˜Q  R¨°°7¸A¸yÈ!ÐLÈsÐTXÐZ]Ð_aÐchÐjkÐmtÐvwð  zCð  EFð  OGØ˜R  b¨%°°g¸qÀ)ÈQÐOÐRUÐWYÐ[^Ð`bÐdiÐklÐnuÐwxð  {Dð  FGð  RHØ˜R  b¨%°°G¸QÀ	È1ÐMÐPSÐUWÐY\Ð^`ÐbgÐijÐlsÐuvð  yBð  DJð  PKØ˜S # r¨5°!°W¸aÀÈAÐNóPˆFð ×Ñ˜TŸ[š[Ñ2¨6Ñ2°1Õ5°s¸FÖCó	Pr;   c                óò  € V P                  R^^4      w  rV P                  WR,          VR,          3R4       V P                  VR,          ^ 4       R	R
RRRR .^á,          ^.pV F=  pV P                  V P                  V^4      ^ ,          R\        V4      R,          4       K?  	  R\        P
                  ^,           ^3RRR3 F0  w  rVV P                  V P                  RWV4      ^ ,          RWV34       K2  	  R# )Ú0r®   ri   rœ   r§   :Né   NNÚá000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)éÈ   é   é   Úà00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Úá300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Úá220000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Úá111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Úá111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111)é    rz   )rm   r¾   )rm   r­   )Ú6rz   )rj   r‹   rŸ   Ústrr&   ÚMAX_GOMOKU_DEPTH)rb   rQ   r    Úbadrg   rh   ri   s   &      r8   Ú0test_gomoku_passes_the_board_and_checks_it_firstÚ?FakeBinaryTest.test_gomoku_passes_the_board_and_checks_it_first‚   sï   € ØŸ™ Y°°1Ó5‰ˆØ×Ñ˜&¨¥+¨v°iÕ/@ÐAÀ;ÔOØ×Ñ  {Õ 3°QÔ7Ø˜/Ð+;Ð=NÐPYÐ\_Ð[`ÐcfÕ[fÐhjÐkˆÛˆEØ×Ñ˜TŸ[™[¨°Ó2°1Õ5°s¼CÀ»JÀs½OÖLñ à%¬×(GÑ(GÈ!Õ(KÈQÐ'OÐQWÐYdÐfnÓo‰NˆEØ×Ñ˜TŸ[™[¨°EÓCÀAÕFÈÈeÐM]Ö^ó pr;   c                óÔ   € \         P                  ! 4       pV P                  R R4      w  r#V P                  VR4       V P	                  \         P                  ! 4       V,
          ^
4       R# )r¥   r¬   iø  N)ÚtimeÚ	monotonicrd   r‹   Ú
assertLess)rb   Út0rQ   r    s   &   r8   Ú(test_slow_jobs_are_killed_at_the_timeoutÚ7FakeBinaryTest.test_slow_jobs_are_killed_at_the_timeoutŒ   sJ   € Ü�^Š^ÓˆØŸ™ H¨cÓ2‰ˆØ×Ñ˜ Ô%Ø�‰œŸšÓ(¨2Õ-¨rÖ2r;   c                ó  € V P                  ^(^(^^ ^R7      w  rpV P                  V^È4       V P                  VR,          P                  R4      4       T P                  V Uu. uF  qDR,          NK  	  up. RO4       R# u upi )é(   ©r¨   r©   rª   r«   ri   rE   ztext/event-streamÚtypeN)r1   ÚbandrÐ   rÐ   Údone)rv   r‹   rˆ   rr   )rb   rQ   rG   ru   Úes   &    r8   Útest_render_streams_eventsÚ)FakeBinaryTest.test_render_streams_events’   st   € Ø"&§+¡+°°b¸aÀqÐRS +Ó"TÑˆ˜Ø×Ñ˜ Ô%Ø�‰˜ Õ/×:Ñ:Ð;NÓOÔPØ×Ñ©VÓ4©V¨˜FŸ)˜)©VÑ4Ò6_Ö`ùÒ4s   Á"A?c                óØ  a a€ . oVV 3R  lp\        \        P                  4       Uu. uF  p\        P                  ! VR7      NK  	  ppV F  pVP                  4        K  	  \        P                  ! R4       S P                  S P                  R^4      ^ ,          RR4       V F  pVP                  4        K  	  S P                  S P                  R^4      ^ ,          ^ÈR4       R# u upi )c                  óX   <€ S P                  SP                  R R4      ^ ,          4       R# )r¥   r¬   N)Úappendrd   )Úresultsrb   s   €€r8   ÚslowÚ>FakeBinaryTest.test_at_most_max_jobs_run_at_once.<locals>.slowš   s   ø€ Ø�N‰N˜4Ÿ:™: h°Ó4°QÕ7Ö8r;   )r   g      à?rš   i­  Úbusyz
free againN)Úranger&   ÚMAX_JOBSr.   r/   r1   rÆ   Úsleepr‹   rd   Újoin)rb   rÙ   rc   ÚjobsÚjrØ   s   f    @r8   Ú!test_at_most_max_jobs_run_at_onceÚ0FakeBinaryTest.test_at_most_max_jobs_run_at_once˜   s´   ù€ Øˆö	9ä7<¼^×=TÑ=TÔ7UÓVÑ7U°!”	× Ò ¨×-Ñ7UˆÐVÛˆAØ�G‰GŽIñ ä�
Š
�3ŒØ×Ñ˜Ÿ™ H¨aÓ0°Õ3°S¸&ÔAÛˆAØ�F‰FŽHñ à×Ñ˜Ÿ™ H¨aÓ0°Õ3°S¸,ÖGùò Ws   § C'c                ó<  € \         P                  P                  R V P                  ^R7      pVP	                  RRRRV P                   2RV P
                  /R7       VP                  4       pVP                  4        VP                  4        \        P                  ! 4       ^,           pV P                  P                  '       d3   \        P                  ! 4       V8  d   \        P                  ! R4       KN  V P                  V P                  P                  ^ 4       R	# )
r   r
   ry   z6/api/compute/render?w=40&h=720&spp=1&scene=0&threads=1rB   rC   rD   )rG   gš™™™™™©?N)rH   rI   rJ   r-   rL   r   rM   ÚreadlinerP   rÆ   rÇ   r   ÚrunningrÞ   r‹   )rb   rV   rX   Údeadlines   &   r8   Ú0test_closing_the_render_stream_stops_the_programÚ?FakeBinaryTest.test_closing_the_render_stream_stops_the_program¥   sÈ   € Ü�{‰{×)Ñ)¨+°t·y±yÈ"Ð)ÓMˆØ�‰�UÐTØ$¨
°4·9±9°+Ð&>ÀÈ$Ï+É+ÐVð 	ô 	Xà×ÑÓ!ˆØ�‰ŒØ�
‰
ŒÜ—>’>Ó# aÕ'ˆØ�l‰l×"×"Ð"¤t§~¢~Ó'7¸(Ô'BÜ�JŠJ�tÖØ×Ñ˜Ÿ™×-Ñ-¨qÖ1r;   rx   N)r{   r|   r}   r~   rŒ   r—   r¡   r°   rÃ   rÊ   rÓ   râ   rè   r€   r�   r‚   s   @r8   r…   r…   d   s>   ø‡ € ò@òLòKò	Dò_ò3òaòH÷
2ð 
2r;   r…   c                   ó&   a € ] tR t^²t o R tRtV tR# )ÚMissingBinaryTestc                óà   € \         P                  ! \        P                  ! R 4      R 4      pVP	                  4       pV P                  VR,          4       V P                  RVR,          4       R# )z/nonexistent/computec                 ó   € R # )Úlocalrx   )r©   s   &r8   Ú<lambda>ÚBMissingBinaryTest.test_info_says_how_to_build_it.<locals>.<lambda>´   s   € ÑY`r;   r�   z cargo build --release -p computeÚhintN)r&   r'   r   r   r–   ÚassertFalser‰   )rb   Úcr–   s   &  r8   Útest_info_says_how_to_build_itÚ0MissingBinaryTest.test_info_says_how_to_build_it³   sP   € Ü×(Ò(¬¯ªÐ6LÓ)MÑO`ÓaˆØ�v‰v‹xˆØ×Ñ˜˜kÕ*Ô+Ø�‰Ð8¸$¸v½,ÖGr;   rx   N)r{   r|   r}   r~   rô   r€   r�   r‚   s   @r8   rë   rë   ²   s   ø‡ € ÷Hð Hr;   rë   z0build it first: cargo build --release -p computec                   ó6   a € ] tR t^ºt o ]tR tR tR tRt	V t
R# )ÚRealBinaryTestc           
     ó  € ^ RI pV P                  R^4      w  r#V P                  V^È4       . ROpR\        4       re\	        V4      R	8  dy   WU^,          R,          ,          pWU^,	          ,          pWU^,          R,          ,          pYdV^,	          ,          P                  4       V^,          ^ 8X  d   RMR,           ,          pKˆ  V P                  VR,          VP                  \        VRR	 4      4      P                  4       4       R# )
r¾   Nrš   i‘ôE%l   ÿÿ ó   
ó    r›   )ÚcoreÚpageÚrowsÚloopÚpixelÚhashÚtileÚframeÚrustÚthreadÚqueueÚblockÚlightÚchunkÚwasmÚbytei   )	Úhashlibrd   r‹   Ú	bytearrayÚlenrK   rš   ÚbytesÚ	hexdigest)rb   r  rQ   r    ÚwordsÚstateÚouts   &      r8   Ú$test_bench_digest_is_the_real_sha256Ú3RealBinaryTest.test_bench_digest_is_the_real_sha256¾   sÑ   € ÛØŸ™ H¨aÓ0‰ˆØ×Ñ˜ Ô%òWˆà¤£ˆsÜ�#‹h˜Ô Ø˜r•k ZÕ/Õ/ˆEØ˜b•[Õ ˆEØ˜q•j JÕ.Õ.ˆEØ˜ "�Õ%×,Ñ,Ó.¸5À3½;È!Ô;K±%ÐQUÕVÕVŠCØ×Ñ˜ Õ)¨7¯>©>¼%ÀÀHÀWÀÓ:NÓ+O×+YÑ+YÓ+[Ö\r;   c                óB  € R .^á,          pRRRuV^p&   V^€&   V^q&   V P                  RP                  V4      ^^4      w  r#V P                  V^È4       V P                  VR,          ^4       V P                  WR,          ^,          VR,          ,           ,          R R4       R# )	r³   r¦   Ú2r   ÚsideÚyr®   zan empty cellN)rj   rß   r‹   )rb   rg   rQ   Úms   &   r8   Ú%test_gomoku_answers_with_a_legal_moveÚ4RealBinaryTest.test_gomoku_answers_with_a_legal_moveÍ   s’   € Ø�˜•ˆØBEÀsÈCÐ?ˆˆjÑ˜5 Ñ,¨e°JÑ.?Ø—K‘K §¡¨£°°1Ó5‰	ˆØ×Ñ˜ Ô%Ø×Ñ˜˜6� AÔ&Ø×Ñ˜ �v¨�{¨Q¨s­VÕ3Õ4°c¸?ÖKr;   c                ó*  € V P                  ^@^(^^^R7      w  rpV Uu. uF  qDR,          R8X  g   K  VNK  	  ppV P                  \        R V 4       4      \        \	        ^(4      4      4       V P                  VR,          R,          ^4       R# u upi )é@   rÎ   rÏ   rÐ   c              3   ó‚   "  € T F5  p\        VR ,          VR ,          VR,          ,           4       F  q"x € K  	  K7  	  R# 5i)r  rý   N)rÜ   )Ú.0ÚbÚrs   &  r8   Ú	<genexpr>Ú>RealBinaryTest.test_render_covers_every_row.<locals>.<genexpr>Ø   s4   é € Ð\©5 a¼%ÀÀ#ÅÈÈ#ÍÐQRÐSYÕQZÕHZÖ:[°Q¤Ñ:[¡«5ùs   ‚=?ri   Néÿÿÿÿ)rv   r‹   ÚsortedÚlistrÜ   )rb   rQ   rc   ru   rÒ   Úbandss   &     r8   Útest_render_covers_every_rowÚ+RealBinaryTest.test_render_covers_every_rowÕ   s„   € Ø ŸK™K¨"°¸ÀÈA˜KÓNÑˆ�6Ù"Ó:™F�q¨¥i°6Ñ&9—�™FˆÐ:Ø×ÑœÑ\©5Ó\Ó\Ô^bÔchÐikÓclÓ^mÔnØ×Ñ˜ � IÕ.°Ö2ùò ;s
   žB²Brx   N)r{   r|   r}   r~   ÚREALr   r  r  r(  r€   r�   r‚   s   @r8   r÷   r÷   º   s    ø‡ € à€Fò]òL÷3ð 3r;   r÷   Ú__main__)#Ú__doc__Úhttp.clientrH   r   r“   r   r    r   r.   rÆ   ÚunittestÚurllib.parsern   r   Ú__file__ÚresolveÚparentÚHERErT   ÚinsertrÀ   r&   r#   r)   r*  r   r   ÚTestCaser…   rë   Ú
skipUnlessÚexistsr÷   r{   Úmainrx   r;   r8   Ú<module>r9     s  ðÙ rÛ Û Û 	Û Û 
Û Û Û Û Û à‡|‚|�HÓ×%Ñ%Ó'×.Ñ.€Ø ‡�‡��‘3�t“9Ô Û Û Û à‡{�{�XÕ 	Õ)¨IÕ5€ð€÷(7'ñ 7'ôtK2�W˜h×/Ñ/ô K2ô\H˜×)Ñ)ô Hð 
×Ò�T—[‘[“]Ð$VÓWô3�W˜h×/Ñ/ó 3ó Xð3ðB ˆzÔØ‡M‚M†Oñ r;   