+
    –°³j”D  ã                   óv  € R t ^ RIt^ RIHt ^ RIHt ^ RIHtHtH	t	H
t
HtHtHt ^ RIHt  ! R R]4      tRR R	 llt ! R
 R4      t]P&                  ]! RR4      ]P(                  ]! RR4      ]P*                  ]! RR4      ]P,                  ]! RR^4      ]P.                  ]! RR^4      /tR R ltRR R lltR# )z¡
This visualizer requires matplotlib to be installed.

Example usage:

ops = get_schedule_ops("InterleavedZeroBubble", 4, 8)
visualize_schedule(ops, "test.png")
N)Ú
NamedTuple)Úmock)Ú_ActionÚ_ComputationTypeÚ_PipelineScheduleÚ_PipelineScheduleRuntimeÚget_schedule_classÚPipelineScheduleMultiÚPipelineScheduleSingle)ÚPipelineStagec                   ó,   a € ] tR t^t o V 3R ltRtV tR# )ÚOpKeyc                ó>   <€ V ^8„  d   Qh/ S[ ;R&   S[;R&   S[ ;R&   # )é   Ústage_indexÚcomputation_typeÚmicrobatch_index)Úintr   )ÚformatÚ__classdict__s   "€Úr/home/luca/screen-checking/.venv/lib/python3.14/site-packages/torch/distributed/pipelining/_schedule_visualizer.pyÚ__annotate__ÚOpKey.__annotate__   s(   ø‡ ‚ ÙÑñ á&Ñ&ñ ñ Ñò ó    © N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__annotate_func__Ú__static_attributes__Ú__classdictcell__©r   s   @r   r   r      s   ø‡ ‡ „ r   r   c                óì   € V ^8„  d   QhR\         \        \        ,          ,          R\        R\        R\        R,          R\        R\        R\        R	\
        \
        \        R,          ,          ,          /# )
r   ÚscheduleÚ	pp_degreeÚnum_microbatchesÚnum_stages_per_rankNÚadd_spacingÚ
with_commsÚdefer_pp_recvÚreturn)ÚstrÚtyper   r   ÚboolÚlistr   )r   s   "r   r   r   "   s   € ÷ Zñ ZÜ”DÔ*Õ+Õ+ðZäðZô ðZô ˜t�ð	Zô
 ðZô ðZô ðZô 
Œ$Œw˜�~Õ
ÕñZr   c                ó®  € V'       d   V'       d   \        R4      h\        V \        4      '       d   \        V 4      pM'\	        V \
        4      '       d   T pM\        RV  24      h\        P                  ! \        RR7      p^ Vn	        Wn
        RVn        \	        V\        4      '       d,   Vf   ^pV^8X  g   \        RV 24      hTp	W1,          V	n        Mo\	        V\        4      '       dL   Vf   ^pV^8¼  g   \        RV 24      h\!        V4       U
u. uF  q¨NK  	  p	p
V	 F  pW1,          Vn        K  	  M\        RV 24      hV! W’4      pVP"                  f   \        R4      h. pV'       dg   \%        W’VR	7      pVP'                  VP"                  4       \!        V4       F.  pVP)                  \+        VP,                  V,          4      4       K0  	  M4\!        V4       F%  pVP)                  VP"                  V,          4       K'  	  V'       d4   V UUu. uF  qÿ Uu. uF  pVf   K	  VNK  	  upNK  	  ppp\/        V4      pV# u up
i u upi u uppi )
aR  
Get all actions for a given schedule, pp_degree, and num_microbatches. The actions are returned in a list of lists
where each inner list represents a rank and each element in the inner list represents an action.

The schedule can be specified as a string which is passed into get_schedule_class() or a _PipelineSchedule instance.

Args:
    defer_pp_recv: If True, RECV ops are deferred to right before the consuming
        compute op. If False (default), RECV ops are placed as early as possible to
        overlap P2P communication with computation. Only takes effect when with_comms=True.
z2Cannot add spacing and view comms at the same timezInvalid schedule: T)ÚinstanceNz*Expected num_stages_per_rank to be 1, got z'Expected num_stages_per_rank >= 2, got z&Expected pipeline_order to not be None)r*   )Ú
ValueErrorÚ
isinstancer,   r   Ú
issubclassr   r   Úcreate_autospecr   Ú
group_rankÚ
group_sizeÚsubmodr
   ÚAssertionErrorÚ
num_stagesr	   ÚrangeÚpipeline_orderr   Ú_prepare_schedule_with_commsÚappendr/   Úpipeline_order_with_commsÚadd_schedule_op_spacing)r$   r%   r&   r'   r(   r)   r*   Úschedule_classÚmock_pipeline_stageÚstagesÚ_ÚstageÚschedule_instanceÚall_actionsÚruntimeÚrankÚactions   &&&&&&&          r   Úget_schedule_opsrK   "   s]  € ÷( —zÜÐMÓNÐNä�(œC× Ò Ü+¨HÓ5‰Ü	�HÔ/×	0Ò	0Ø!‰äÐ-¨h¨ZÐ8Ó9Ð9ô ×.Ò.¬}ÀtÔLÐà%&ÐÔ"Ø%.Ô"Ø!%ÐÔô �.Ô"8×9Ò9ØÒ&Ø"#ÐØ" aÔ'Ü Ø<Ð=PÐ<QÐRóð ð %ˆØ/Õ;ˆÕÜ	�NÔ$9×	:Ò	:ØÒ&Ø"#ÐØ" aÔ'Ü Ø9Ð:MÐ9NÐOóð ô 05Ð5HÔ/IÓJÑ/I¨!Ò%Ñ/IˆÐJÛˆEØ2Õ>ˆEÖò ô Ð-¨nÐ-=Ð>Ó?Ð?ñ ' vÓ@ÐØ×'Ñ'Ò/ÜÐEÓFÐFð /1€KßÜ*Ø°Mô
ˆð 	×,Ñ,Ð->×-MÑ-MÔNÜ˜)Ö$ˆDØ×Ñœt G×$EÑ$EÀdÕ$KÓLÖMò %ô ˜)Ö$ˆDØ×ÑÐ0×?Ñ?ÀÕEÖFñ %÷ ñ KVô
ÙJUÀ$ $Ó=¡$˜¨&�VˆV¡$Ô=É+ð 	ñ 
ô .¨kÓ:ˆð ÐùòI Kùò> >ùó
s$   Ä
IÈIÈIÈ*IÈ0IÉIc                   ó6   a € ] tR t^t o RV 3R lR lltRtV tR# )Ú_ComputationTypeVisualc                ó,   <€ V ^8„  d   QhRS[ RS[ RS[/# )r   ÚcolorÚtextÚwidth)r,   r   )r   r   s   "€r   r   Ú#_ComputationTypeVisual.__annotate__€   s)   ø€ ÷ ñ áðñ ðñ ñ	r   c                ó*   € Wn         W0n        W n        R # ©N)rO   rQ   rP   )ÚselfrO   rP   rQ   s   &&&&r   Ú__init__Ú_ComputationTypeVisual.__init__€   s   € ð Œ
ØŒ
ØŽ	r   )rO   rP   rQ   N)Ú é   )r   r   r   r   rV   r    r!   r"   s   @r   rM   rM      s   ø‡ € ÷÷ ð r   rM   ÚblueÚForwardÚtealzBackward InputÚgreenzBackward WeightÚorangezFull BackwardÚpurplezOverlap F+Bc                ó¤   € V ^8„  d   QhR\         \         \        R,          ,          ,          R\         \         \        R,          ,          ,          /# )r   r$   Nr+   )r/   r   )r   s   "r   r   r   ™   s<   € ÷ Cñ CÜ”4œ $�Õ'Õ(ðCä	Œ$Œw˜�~Õ
ÕñCr   c                ód  aaaaaa€ V '       g   V # \        R V  4       4      ^,           o\        V 4      p\        V4       Uu. uF  p. NK  	  upoV  Uu. uF  p\        P                  ! V4      NK  	  pp/ oR V3R lloR V3R lloR VVV3R lloR VV3R	 llp^ p^ p\
        P                  \        V4      ^ 4      pV'       EdX   \        R
V 24       \        V4       Fž  w  ršV
'       g   K  WI,          p
V
^ ,          p\        RV	 RV: 24       Vf-   SV	,          P                  R4       V
P                  4        ^ pKb  WhV	,          8¼  g   Kq  S! W¶4      '       g   K�  V! W¹V4      W‰&   V
P                  4        ^ pK   	  \        V4       F*  p	WhV	,          8¼  g   K  SV	,          P                  R4       K,  	  V U
u. uF  qª'       g   K  V
NK  	  pp
V^,          pV^,          pV\        R \        P                  4        4       4      8”  g   EKU  \        R4      hS# u upi u upi u up
i )ah  
Add spacing to the schedule based on dependencies between ranks.

Before adding an operation to the list, this function checks if there are
dependencies from other ranks. If there are dependencies (other ranks have
not finished processing the required microbatch), it adds None instead.

For example, Forward microbatch 0 on rank 1 depends on rank 0 processing
Forward microbatch 0 first.

Args:
    schedule: The original schedule as a list of lists where each inner list
             represents a rank and each element represents an action.

Returns:
    A new schedule with proper spacing based on dependencies.
c              3   óX   "  € T F   pV F  pVf   K	  VP                   x € K  	  K"  	  R # 5irT   )r   )Ú.0Úrank_actionsrJ   s   &  r   Ú	<genexpr>Ú*add_schedule_op_spacing.<locals>.<genexpr>±   s/   é € ð 
á (�Û&�Øô ˆF×Öá&ñ Û (ùs   ‚*’*c                ó<   € V ^8„  d   QhR\         R\        R\        /# )r   Údependency_keyÚtimestepr+   )r   r   r.   )r   s   "r   r   Ú-add_schedule_op_spacing.<locals>.__annotate__Á   s!   € ÷ 
ñ 
¬Eð 
¼Sð 
ÄTñ 
r   c                ó6   <€ V S9   ;'       d    VSV ,          8¬  # )zDCheck if a dependency operation has completed by the given timestep.r   )rh   ri   Úscheduled_opss   &&€r   Úis_dependency_readyÚ4add_schedule_op_spacing.<locals>.is_dependency_readyÁ   s)   ø€ ð ˜mÑ+÷ :ð :Ø˜M¨.Õ9Ñ9ð	
r   c                óF   € V ^8„  d   QhR\         R\        \        ,          /# )r   rJ   r+   )r   r/   r   )r   s   "r   r   rj   È   s"   € ÷ 'Eñ 'E¤ð 'E¬T´%­[ñ 'Er   c                ó  <€ V P                   pV P                  pV P                  pVf   \        RV  R24      hV^ 8X  d   V\        P
                  8X  d   . # VS^,
          8X  dI   V\        P                  \        P                  39   d$   \        V^,
          \        P
                  V4      .# V\        P
                  8X  d$   \        V^,
          \        P
                  V4      .# V\        P                  \        P                  39   dE   \        V^,           \        P                  V4      \        V^,           \        P                  V4      .# V\        P                  8X  d   \        V\        P                  V4      .# \        RV 24      h)z+Get the list of dependencies for an action.úAction ú has None microbatch_indexúUnknown computation type: )r   r   r   r9   r   ÚFORWARDÚFULL_BACKWARDÚBACKWARD_INPUTr   ÚBACKWARD_WEIGHTÚRuntimeError)rJ   Ú	stage_idxÚ	comp_typeÚmb_idxr:   s   &   €r   Úget_dependenciesÚ1add_schedule_op_spacing.<locals>.get_dependenciesÈ   sm  ø€ à×&Ñ&ˆ	Ø×+Ñ+ˆ	Ø×(Ñ(ˆð Š>Ü  7¨6¨(Ð2LÐ!MÓNÐNð ˜Œ>˜iÔ+;×+CÑ+CÔCØˆIð ˜
 Q�Ô&¨9Ü×*Ñ*Ü×+Ñ+ð9
ô ,
ô ˜) a�-Ô)9×)AÑ)AÀ6ÓJÐKÐKð Ô(×0Ñ0Ô0Ü˜) a�-Ô)9×)AÑ)AÀ6ÓJÐKÐKð Ü×*Ñ*Ü×+Ñ+ð
ô 
ô
 �i !•mÔ%5×%CÑ%CÀVÓLÜ�i !•mÔ%5×%DÑ%DÀfÓMðð ð Ô(×8Ñ8Ô8Ü˜)Ô%5×%DÑ%DÀfÓMÐNÐNäÐ7¸	°{ÐCÓDÐDr   c                ó<   € V ^8„  d   QhR\         R\        R\        /# )r   rJ   ri   r+   )r   r   r.   )r   s   "r   r   rj   ñ   s&   € ÷ Wñ W¤ð W´3ð W¼4ñ Wr   c                óè  <a€ V P                   \        P                  \        P                  \        P                  39   dE   S! V 4      p\
        ;QJ d     VV3R lV 4       F  '       g   K   R# 	  R# ! VV3R lV 4       4      # V P                   \        P                  8X  dE   S! V 4      p\        ;QJ d     VV3R lV 4       F  '       d   K   R# 	  R# ! VV3R lV 4       4      # V P                   \        P                  8X  dV   V P                  f   \        RV  R24      h. pV P                   F  pVP                  S! VS4      4       K  	  \        V4      # \        RV P                    24      h)zBCheck if an action is ready to be scheduled at the given timestep.c              3   ó6   <"  € T F  pS! VS4      x € K  	  R # 5irT   r   ©rc   Údeprm   ri   s   & €€r   re   ÚCadd_schedule_op_spacing.<locals>.is_action_ready.<locals>.<genexpr>ú   ó   øé € ÐRÁ\¸cÑ*¨3°×9Ð9Ã\ùó   ƒTFc              3   ó6   <"  € T F  pS! VS4      x € K  	  R # 5irT   r   r�   s   & €€r   re   rƒ   þ   r„   r…   úOVERLAP_F_B action ú has None sub_actionsrs   )r   r   ru   rv   rw   Úanyrt   ÚallÚOVERLAP_F_BÚsub_actionsr9   r>   rx   )rJ   ri   ÚdependenciesÚdep_listÚ
sub_actionr|   Úis_action_readyrm   s   &f   €€€r   r�   Ú0add_schedule_op_spacing.<locals>.is_action_readyñ   s9  ù€ ð ×"Ñ"Ü×*Ñ*Ü×+Ñ+Ü×,Ñ,ð'
ô 
ñ
 ,¨FÓ3ˆLß“3ÕRÁ\ÓR—3”3ÐR’3ÐR�3ÕRÁ\ÓRÓRÐRà×$Ñ$Ô(8×(@Ñ(@Ô@Ù+¨FÓ3ˆLß“3ÕRÁ\ÓR—3”3ÐR’3ÐR�3ÕRÁ\ÓRÓRÐRØ×$Ñ$Ô(8×(DÑ(DÔDØ×!Ñ!Ò)Ü$Ø)¨&¨Ð1FÐGóð ð $&ˆHØ$×0Ô0�
Ø—‘¡°
¸HÓ EÖFñ 1ä�x“=Ð äÐ!;¸F×<SÑ<SÐ;TÐUÓVÐVr   c                óH   € V ^8„  d   QhR\         R\        R\        R\        /# )r   rJ   rI   ri   r+   )r   r   )r   s   "r   r   rj     s(   € ÷ %ñ %¤ð %¬sð %¼cð %Äcñ %r   c                ó”  <€ S
V,          P                  V 4       V P                  p\        V,          P                  pW$,           pV\        P
                  8X  d¯   V P                  f   \        RV  R24      h^ pV P                   F}  pVP                  f   \        RV R24      h\        VP                  ,          P                  pWh,          pW&,           S	\        VP                  VP                  VP                  4      &   K  	  V# V P                  f   \        RV  R24      hVS	\        V P                  W0P                  4      &   V# )z.Schedule an action and return completion time.r‡   rˆ   zSub-action rr   rq   )r>   r   Úaction_type_to_color_mappingrQ   r   r‹   rŒ   r9   r   r   r   )rJ   rI   ri   rz   Ú	comp_timeÚcompletion_timeÚcumulative_timer�   Úsub_comp_timerl   Úspaced_schedules   &&&      €€r   Úschedule_actionÚ0add_schedule_op_spacing.<locals>.schedule_action  s_  ø€ à˜Õ×$Ñ$ VÔ,Ø×+Ñ+ˆ	Ü0°Õ;×AÑAˆ	Ø"Õ.ˆàÔ(×4Ñ4Ô4à×!Ñ!Ò)Ü$Ø)¨&¨Ð1FÐGóð ð  ˆOØ$×0Ô0�
Ø×.Ñ.Ò6Ü(Ø% j \Ð1KÐLóð ô !=Ø×/Ñ/õ!ç‘%ð ð  Õ0�ð Õ.ð ÜØ"×.Ñ.Ø"×3Ñ3Ø"×3Ñ3óóñ 1ð. Ðð ×&Ñ&Ò.Ü$ w¨v¨hÐ6PÐ%QÓRÐRð  ð Ü�f×(Ñ(¨)×5LÑ5LÓMñð Ðr   zCurrent timestep: zRank: z	, action=Nc              3   ó8   "  € T F  qP                   x € K  	  R # 5irT   )rQ   )rc   Úvisuals   & r   re   rf   W  s   é € ð ,
Ù'L˜V�LŽLÓ'Lùó   ‚z2No progress made in scheduling - possible deadlock)ÚmaxÚlenr;   ÚcollectionsÚdequeÚdictÚfromkeysÚprintÚ	enumerater>   Úpopleftr”   Úvaluesrx   )r$   Ú	num_ranksrD   ÚopsÚrank_opsrš   Úcurrent_timestepÚtimesteps_without_progressÚrank_completion_timesrI   Úop_queuerJ   r|   r�   rm   r:   rl   r™   s   &           @@@@@@r   r@   r@   ™   s=  ý€ ÷( Øˆô 	ñ 
á (ó
ó 	
ð õ	ð ô �H“€IÜ?DÀYÔ?OÓ2PÑ?O¸!³2Ñ?OÑ2P€OÙ2:Ó;±(¨3”×!Ò! #Ö&±(€HÐ;ð ')€M÷
ð 
÷'Eð 'E÷RWò W÷4%ñ %ðP ÐØ!"ÐÜ ŸM™M¬%°	Ó*:¸AÓ>Ðß
ˆ(ÜÐ"Ð#3Ð"4Ð5Ô6ä'¨Ö1‰NˆDßÙà•~ˆHØ˜a•[ˆFÜ�F˜4˜& 
 6¡)Ð,Ô-ØŠ~Ø Õ%×,Ñ,¨TÔ2Ø× Ñ Ô"Ø-.Ò*Ø!¸4Õ%@Ö@Á_Ø÷Fô Fñ />ØÐ"2ó/Ð%Ñ+ð × Ñ Ô"Ø-.Ò*ñ% 2ô* ˜)Ö$ˆDØ¸Õ#>Ö>Ø Õ%×,Ñ,¨TÖ2ñ %ñ
 .6ÓB©X »—H�H©XˆÐBØ˜AÕÐØ" aÕ'Ð"à%¬ñ ,
Ü'C×'JÑ'JÔ'Ló,
ó )
÷ 
ô ÐSÓTÐTàÐùòC 3QùÚ;ùòn Cs   ÁH#ÁH(Ç	H-ÇH-c                ó|   € V ^8„  d   QhR\         \         \        R,          ,          ,          R\        R,          RR/# )r   r$   NÚfilenamer+   )r/   r   r,   )r   s   "r   r   r   _  s=   € ÷ hñ hÜ”4œ $�Õ'Õ(ðhä�D�jðhð 
ñhr   c                óð  € ^ RI Hp ^ RIHp RVP                  R&   \        V 4      p\        R V  4       4      pVP                  V^,           V^,           3R7      w  rgRp\        WT4      ^,           p	\        4       p
\        V 4       EF  w  r¼^ pV EF  pVeð   \        P                  VP                  \        R4      4      pV
P                  VP                  4       VP                   pVP"                  pVP$                  e   ^pRpM^pRpV! WÔV,
          ^,
          3V^VRVR	7      pVP'                  V4       VP)                  VV^,          ,           WK,
          ^,
          R
,           \+        V4      RRV	RVR7       VV,          pM	V^,          p\        W�4      pEK  	  EK  	  VP-                  RV^,           4       VP/                  RVR
,           4       TP1                  \3        V4       Uu. uF  q´V,
          R
,
          NK  	  up4       TP5                  \3        V4       Uu. uF  pRV 2NK
  	  upV	R7       VP7                  . 4       VP9                  R4       V
 Uu. uF;  pV! R^^\        V,          P                   R\        V,          P(                  R7      NK=  	  ppVP;                  VRV	R7       V'       d   VP=                  VRR7       R# VP?                  4        R# u upi u upi u upi )aM  
Visualize the schedule using matplotlib.
The schedule is a list of lists where each inner list represents a rank and each element in the inner list represents an action.
The actions are represented as rectangles with different colors based on their computation type.
The filename is optional and if provided, the plot will be saved to that file.

Args:
    schedule: The schedule to visualize.
    filename: The filename to save the plot to. If not provided, the plot will be displayed.
    add_schedule_spacing: If True, add spacing to the schedule based on dependencies between ranks.

N)Ú	RectanglezDejaVu Sanszfont.familyc              3   ó8   "  € T F  p\        V4      x € K  	  R # 5irT   )r    )rc   rI   s   & r   re   Ú%visualize_schedule.<locals>.<genexpr>w  s   é € Ð5©H D”c˜$—i�i«Hùrž   )ÚfigsizeÚblackÚnormal)Ú	facecolorÚ	edgecolorÚ	linewidthg      à?ÚcenterÚwhite)ÚhaÚvaÚfontsizerO   ÚweightzRank )rÀ   F)r¹   rº   Úlabelzupper right)ÚhandlesÚlocrÀ   Útight)Úbbox_incheséÿÿÿÿg      à¿)é    rÈ   ) Úmatplotlib.pyplotÚpyplotÚmatplotlib.patchesr³   ÚrcParamsr    rŸ   ÚsubplotsÚminÚsetr¦   r”   Úgetr   rM   ÚaddrO   rQ   rŒ   Ú	add_patchrP   r,   Úset_xlimÚset_ylimÚ
set_yticksr;   Úset_yticklabelsÚset_xticklabelsÚgridÚlegendÚsavefigÚshow)r$   r±   Úpltr³   r©   Úmax_actionsÚfigÚaxÚmax_draw_positionÚ	font_sizeÚused_computationÚrank_idxÚactionsÚdraw_positionrJ   Úcomp_type_colorrO   rQ   r»   Útext_weightÚrectÚirz   Úlegend_elementss   &&                      r   Úvisualize_schedulerë   _  sÞ  € õ" $Ý,ð 	ð ‡L�L�Ñô �H“€IÜÑ5©HÓ5Ó5€Kð �l‰l K°!¥O°YÀµ]Ð#CˆlÓD�G€CØÐä�KÓ+¨aÕ/€IÜ“uÐÜ& x×0ÑˆØˆÜˆFØÒ!Ü">×"BÑ"BØ×+Ñ+Ô-CÀGÓ-Ló#�ð !×$Ñ$ V×%<Ñ%<Ô=Ø'×-Ñ-�Ø'×-Ñ-�ð ×%Ñ%Ò1Ø !�IØ"*‘Kà !�IØ"*�Kñ !Ø"°Õ$8¸1Õ$<Ð=ØØØ#Ø%Ø'ô�ð —‘˜TÔ"ð —‘Ø! E¨A¥IÕ-ØÕ(¨1Õ,¨sÕ2Ü˜“KØØØ&Ø!Ø&ð ô 	ð  Õ&‘à Õ"�Ü #Ð$5Ó EÓôW ñ 1ð\ ‡K�K�Ð'¨!Õ+Ô,Ø‡K�K��i #•oÔ&à‡M�M¼eÀIÔ>NÓOÑ>N°(˜xÕ'¨#×-Ð-Ñ>NÑOÔPØ×Ñ¬U°9Ô-=Ó>Ñ-=¨˜% ˜s›Ñ-=Ñ>ÈÐÔSØ×Ñ�rÔð ‡G�GˆE„Nñ *ó
ñ *ˆIñ 	ØØØÜ2°9Õ=×CÑCØÜ.¨yÕ9×>Ñ>÷	
ñ *ð ð 
ð ‡I�I�o¨=À9€IÔMçØ�‰�H¨'ˆÖ2à�‰Ž
ùò/ PùÚ>ùò
s   Ç/K)È&K.É#AK3)NFFFrT   )Ú__doc__r¡   Útypingr   Úunittestr   Ú&torch.distributed.pipelining.schedulesr   r   r   r   r   r	   r
   Ú"torch.distributed.pipelining.stager   r   rK   rM   rt   rv   rw   ru   r‹   r”   r@   rë   r   r   r   Ú<module>rñ      sÓ   ðñó Ý Ý ÷÷ ñ õ =ôˆJô ÷Z÷z	ñ 	ð ×ÑÑ4°V¸YÓGØ×#Ñ#Ñ%;¸FÐDTÓ%UØ×$Ñ$Ñ&<ØÐ"ó'ð ×"Ñ"Ñ$:Ø�/ 1ó%ð × Ñ Ñ"8¸À=ÐRSÓ"Tð
 Ð õC÷Lhñ hr   