Ë
    f^(hE  ã                   óÀ  — d dl Z d dlmZmZ d dlZd dlmZ d dlm	c m
Z d dlm	c mZ d dlmZ d dlmZ d dlmZmZmZ d dlmZmZ d dlmZ d dlmZmZmZ d d	lm Z  ejB                  jD                  Z"d
gZ#e jH                  d„ «       Z%de&e df   de'de'fd„Z(de&e df   dedefd„Z)dejT                  jV                  de&e,df   de-e.e,f   defd„Z/d„ Z0dejT                  jV                  de&e,df   de-e.e,f   de,fd„Z1dejT                  jV                  de&e,df   de-e.e,f   de,fd„Z2dededee   dee   de'de'd ejf                  d!e'ded"e'de&eef   fd#„Z4dejT                  jV                  de&e,df   de-e.e,f   de,fd$„Z5d%edededee   de'de'd&ed ejf                  d!e'ded"e'defd'„Z6dejT                  jV                  de&e,df   de-e.e,f   de,fd(„Z7e"j`                  jp                  e1e"jr                  jp                  e2e"jt                  jp                  e5e"jv                  jp                  e5e"jx                  jp                  e7e"jz                  jp                  e7iZ>d)„ Z?d*„ Z@y)+é    N)ÚcastÚOptional)ÚTensor)Ú
DeviceMesh)ÚDTensorÚ	ReplicateÚShard)ÚDTensorSpecÚ
TensorMeta)Ú_MaskPartial)Ú	_skip_dimÚ	ReductionÚreplicate_reduction_dims)Ú	PlacementÚloss_parallelc               #   ó<   K  — t        «        d–— t        «        y­w)a„  
    A context manager that enables loss parallelism, where efficient parallelized loss computation
    can be performed when the input is sharded on the class dimension. Currently only the cross-entropy
    loss is supported.

    Within this context manager, one can use :func:`~torch.nn.functional.cross_entropy` or
    :class:`~torch.nn.CrossEntropyLoss` as usual, with the following assumptions on the input parameters.
    The corresponding ``backward()`` call, if any, also needs to happen under this context manager.

    Args:
        input (:class:`DTensor`):
            Input logits. Assumed to be sharded on the class dimension.
        target (Union[:class:`torch.Tensor`, :class:`DTensor`]):
            Must be ground truth class indices (class probabilities currently not supported).
            Assumed to be replicated across the ``DeviceMesh``.
        weight (Union[:class:`torch.Tensor`, :class:`DTensor`], optional):
            If given, assumed to be replicated across the ``DeviceMesh``.
        label_smoothing:
            Currently not supported.

    Returns:
        A replicated :class:`DTensor`.

    Example:
        A sharded DTensor is manually created here to showcase the usage.
        In practice, it is usually the output of a TP module.

        >>> # xdoctest: +SKIP("distributed")
        >>> from torch.distributed.tensor.parallel import loss_parallel
        >>> from torch.distributed.device_mesh import init_device_mesh
        >>> ...
        >>> device_mesh = init_device_mesh("cuda", (8,))
        >>> input = torch.randn(4, 16, device="cuda", requires_grad=True)
        >>> dist_input = distribute_tensor(input, device_mesh, placements=[Shard(1)])
        >>> target = torch.randint(16, (4,), device="cuda")
        >>> with loss_parallel():
        >>>     loss = F.cross_entropy(dist_input, target, reduction="mean")
        >>>     loss.backward()
        >>> ...
    N)Ú_enable_custom_loss_opsÚ_disable_custom_loss_ops© ó    úd/var/www/skyplay_api_hub/venv/lib/python3.12/site-packages/torch/distributed/tensor/parallel/loss.pyr   r      s   è ø€ ôT Ôã	äÕùs   ‚Ú
placements.ÚdimÚreturnc                 ó|   — t        | «      dk(  st        d«      ‚| d   j                  |«      st        d|› d�«      ‚y)Né   zLCurrently loss_parallel() only supports input on one-dimensional DeviceMesh.r   zUloss_parallel() should be enabled only when the input tensor is sharded on dimension ú.)ÚlenÚ
ValueErrorÚis_shard)r   r   s     r   Ú_find_all_reduce_mesh_dimr!   P   sS   € Üˆz‹?˜aÒÜØZó
ð 	
ð �a‰=×!Ñ! #Ô&ÜØcÐdgÐchÐhiÐjó
ð 	
ð r   Úmeshc                 ó  — t        | t        «      r-| j                  |k(  r| S t        d|› d| j                  › d�«      ‚t        | t        j
                  «      rt        j                  | ||d¬«      S t        dt        | «      › �«      ‚)Nz	Expected z	 but got r   F)Údevice_meshr   Ú	run_checkzUnsupported type )	Ú
isinstancer   r   ÚRuntimeErrorÚtorchr   Ú
from_localÚ	TypeErrorÚtype)Útensorr   r"   s      r   Ú_cast_to_dtensorr-   \   s†   € ô �&œ'Ô"Ø×Ñ 
Ò*ØˆMä ¨:¨,°iÀ×@QÑ@QÐ?RÐRSÐTÓUÐUÜ	�FœEŸL™LÔ	)Ü×!Ñ!Ø °Àuô
ð 	
ô Ð+¬D°«L¨>Ð:Ó;Ð;r   Úop_callÚargsÚkwargsc                 ó(  — t         j                  j                  | ||«      }t         j                  j                  j	                  |j
                  «      }t        |t        «      r|S t        |t        «      r|d   S t        dt        |«      › d�«      ‚)Nr   zUnexpected tensor meta type: r   )r   Ú_op_dispatcherÚunwrap_to_op_infoÚsharding_propagatorÚ_propagate_tensor_metaÚschemar&   r   Útupler'   r+   )r.   r/   r0   Úop_infoÚtensor_metas        r   r5   r5   l   s‚   € ô
 ×$Ñ$×6Ñ6°wÀÀfÓM€GÜ×(Ñ(×<Ñ<×SÑSØ�‰ó€Kô �+œzÔ*ØÐÜ	�K¤Ô	'Ø˜1‰~ÐäÐ:¼4ÀÓ;LÐ:MÈQÐOÓPÐPr   c                 óô  — |r| j                   t        j                  k(  sJ ‚t        j                  | t        j
                  j                  ¬«      \  }}| j                  |t        j                  ¬«      } | j                  «       dk(  r| }nYt        j                  | |d¬«      }t        j                  |t        j                  j                  j                   ||f¬«      }| |z
  }t        j"                  t        j$                  |«      |d¬«      }	t        j                  |	t        j                  j&                  j                   ||f¬«      }	t        j(                  |	«      }
||
z
  }|s|j                  |«      }|S )N)Útype_promotion_kind)ÚdtypeÚmemory_formatr   T)Úkeepdim)ÚreduceOpÚgroup)r<   r(   ÚhalfÚutilsÚelementwise_dtypesÚELEMENTWISE_TYPE_PROMOTION_KINDÚDEFAULTÚtoÚcontiguous_formatÚnumelÚamaxÚfuncolÚ
all_reduceÚc10dÚReduceOpÚMAXÚnameÚsumÚexpÚSUMÚlog)Úxr   Úhalf_to_floatr"   Úmesh_dimÚcomputation_dtypeÚresult_dtypeÚshiftedÚx_maxÚshifted_sumexpÚshifted_logsumexpÚresults               r   Ú_log_softmaxr^      s1  € ÙØ�w‰wœ%Ÿ*™*Ò$Ð$Ð$Ü&+×&>Ñ&>Ø	œu×DÑD×LÑLô'Ñ#Ð�|ð 	
�‰Ð$´E×4KÑ4KˆÓL€AØ‡w�wƒy�A‚~Ø‰ä—
‘
˜1˜c¨4Ô0ˆÜ×!Ñ!ØœDŸM™M×-Ñ-×2Ñ2¸4ÀÐ:Jô
ˆð �e‘)ˆÜ—Y‘YœuŸy™y¨Ó1°3ÀÔE€NÜ×&Ñ&Ø¤§¡×!2Ñ!2×!7Ñ!7ÀÀhÐ?Oô€Nô Ÿ	™	 .Ó1ÐØÐ(Ñ(€FÙØ—‘˜<Ó(ˆØ€Mr   c                 óŒ  — t        t        |d   «      }t        t        |d   «      }t        t        |d   «      }|j                  }t        |j                  |«      }t        | ||«      }t        |j                  |||j                  |«      }	t        |j                  |j                  |¬«      }
t        |	|
|	j                  ¬«      S )Nr   r   é   ©r9   ©Úrequires_grad)r   r   ÚintÚboolÚ_specr!   r   r5   r^   Ú_local_tensorr"   r
   rc   )r.   r/   r0   rT   r   rU   ÚspecrV   Úoutput_tensor_metaÚresÚres_specs              r   Ú_log_softmax_handlerrl   ™   s¯   € ô
 	ŒW�d˜1‘gÓ€AÜ
Œs�D˜‘GÓ
€CÜœ˜t A™wÓ'€Mà�7‰7€DÜ(¨¯©¸#Ó>€Hä/°¸¸vÓFÐä
�q—‘¨¨]¸D¿I¹IÀxÓ
P€CäØ�	‰	Ø�‰Ø&ô€Hô ØØØ×'Ñ'ôð r   c                 ó„   — t        t        |d   «      }t        t        j                  |d   «      }|j	                  |«      S )Nr   é   )r   r   r(   r<   rF   )r.   r/   r0   Úgrad_outputÚinput_dtypes        r   Ú_log_softmax_backward_handlerrq   ¸   s7   € ô
 ”w  Q¡Ó(€KÜ”u—{‘{ D¨¡GÓ,€KØ�>‰>˜+Ó&Ð&r   rT   ÚtargetÚweightÚlocal_weightÚ	reductionÚignore_indexÚinput_shapeÚchannel_dimrV   c
                 óP  ‡‡— | j                  «       ŠdŠ‰dk  rdŠdt        dt        fˆˆfd„}
|� |
|«      }|€J ‚ |
|«      }| |z  } t        j                  ||k7  |d«      }|j	                  ‰«      }t        |‰¬«      }|j                  |||	«      }t        j                  | ‰|«      }|j                  |||	«      }|j                  ‰«       }t        j                  ||k7  |d«      }|t        j                  j                  k(  r‰dkD  r| j                  dd	«      }||fS |�|t        | j                  «      }d
|‰<   j!                  |«      }t        j                  |‰|«      j                  ‰«      }t        j                  ||k7  |d«      }|j#                  «       }n"||k7  j#                  «       j%                  | «      }|t        j&                  j                  k(  r|j#                  «       }||fS |t        j(                  j                  k(  r|j#                  «       |z  }||fS )Nr   r`   r   rs   r   c                 ól   •— ‰dkD  r+dg‰z  }| j                   d   |‰<   | j                  |«      }|S | }|S )Nr   r   )ÚshapeÚview)rs   r{   Úwrx   Ún_dimss      €€r   Ú_weight_viewz'_nll_loss_forward.<locals>._weight_viewÕ   sQ   ø€ Ø�AŠ:àðàñˆEð "(§¡¨a¡ˆE�+ÑØ—‘˜EÓ"ˆAð ˆð ˆAØˆr   ©Úoffset_shapeÚ
offset_dimr   g        éÿÿÿÿ)r   r   r(   ÚwhereÚ	unsqueezer   Ú_partition_valueÚgatherÚ_reduce_valueÚsqueezer   ÚNONEÚvalueÚnew_fullÚlistr{   ÚexpandrP   rF   rR   ÚMEAN)rT   rr   rs   rt   ru   rv   rw   rx   r"   rV   r   r}   Úlocal_wÚsafe_targetÚsafe_target_Úpartial_placementÚsafe_target_partial_Úresult_partialÚresult_reducedr]   Útotal_weightÚ	new_shapeÚwsumr~   s          `               @r   Ú_nll_loss_forwardrš   Ä   s  ù€ ð �U‰U‹W€FØ€KØ�‚zØˆð	œVð 	¬ö 	ð ÐÙ˜Ó ˆØÐ'Ð'Ð'Ù˜|Ó,ˆØ�‰KˆÜ—+‘+˜f¨Ñ4°f¸aÓ@€KØ×(Ñ(¨Ó5€Lô %°+È+ÔVÐØ,×=Ñ=Ø�d˜HóÐô —\‘\ ! [Ð2FÓG€Nà&×4Ñ4°^ÀTÈ8ÓT€NØ×$Ñ$ [Ó1Ð1€Fä�[‰[˜ <Ñ/°¸Ó;€Fà”I—N‘N×(Ñ(Ò(¨V°aªZØ—z‘z " cÓ*ˆØ�|Ð#Ð#àÐÜ˜Ÿ™“Mˆ	Ø!#ˆ	�+ÑØ�H‰H�YÓˆÜ�|‰|˜A˜{¨LÓ9×AÑAÀ+ÓNˆÜ�{‰{˜6 \Ñ1°4¸Ó;ˆØ—x‘x“z‰à ,Ñ.×3Ñ3Ó5×8Ñ8¸Ó;ˆð ”I—M‘M×'Ñ'Ò'Ø—‘“ˆð �<ÐÐð 
”i—n‘n×*Ñ*Ò	*Ø—‘“ Ñ,ˆà�<ÐÐr   c                 ó²  — t        t        |d   «      }|d   }|d   }t        t        |d   «      }t        t        |d   «      }|j                  «       dk\  rdnd}|j                  }	t        |	j                  |«      }
t        t        |	j                  |g«      |«      }t        «       f|	j                  j                  z  }t        |||	j                  «      }d }|�¬t        |||	j                  «      }t        |	j                  j                  «      D �cg c]  }||
k(  rt        d«      n	t        «       ‘Œ }}|j                  |	j                  |«      j                   }|j"                  d   |j                   j"                  |   k(  sJ ‚|t$        j&                  j(                  k(  r|}n|}t+        |«      }||c|d<   |d<   t-        | t/        |«      |«      }t1        |j                   |j                   |�|j                   nd ||||j"                  ||	j                  |
«
      \  }}t3        |	j                  ||¬«      }t        |||j4                  ¬«      |fS c c}w )Nr   r   r`   rn   é   ra   rb   )r   r   rd   r   rf   r!   r   r   r   r   r"   Úndimr-   Úranger	   Úredistributerg   r{   r   rŠ   r‹   r�   r5   r7   rš   r
   rc   )r.   r/   r0   rT   rr   rs   ru   rv   rx   rh   rV   Útarget_placementsÚall_replicate_placementsrt   ÚiÚsharded_placementsÚoutput_placementsri   r]   r—   Úout_specs                        r   Ú_nll_loss_forward_handlerr¦     s>  € ô
 	ŒW�d˜1‘gÓ€AØ�!‰W€FØ�!‰W€FÜ”S˜$˜q™'Ó"€IÜœ˜T !™WÓ%€Là—u‘u“w !’|‘!¨€KØ�7‰7€DÜ(¨¯©¸+ÓF€Hô "Ü  §¡°;°-Ó@À+óÐô !*£˜~°·	±	·±Ñ>ÐÜ˜fÐ&7¸¿¹ÓC€FØ€LØÐÜ! &Ð*BÀDÇIÁIÓNˆô
 AFÀdÇiÁiÇnÁnÓ@Uö
Ø;<˜˜XšŒE�!ŒH¬9«;Ñ6ð
Ðð 
ð ×*Ñ*¨4¯9©9Ð6HÓI×WÑWˆØ×!Ñ! !Ñ$¨¯©×(=Ñ(=¸kÑ(JÒJÐJÐJà”I—N‘N×(Ñ(Ò(Ø-Ñà4Ðô �‹:€DØ˜vÐ€Dˆ�GˆT�!‰WÜ/°¼¸t»ÀfÓMÐä,Ø	�‰Ø×ÑØ &Ð 2ˆ×Ò¸ØØØØ	�‰ØØ�	‰	ØóÑ€FˆLô ˜4Ÿ9™9Ð&7ÐEWÔX€Hô 	ØØØ ×.Ñ.ô	
ð
 	ðð ùò=
s   Ä!Iro   r—   c                 ó¢  — |j                  «       dk  rdnd}|t        j                  j                  k(  r| |z  } |j	                  |«      }t        j                  ||k7  |d«      }t        j                  |«      }t        ||¬«      }|j                  |«      j                  «       }|j                  ||	|
«      }|j                  j                  €J ‚|j                  j                  j                  |j                  «      dz
  }t        j                   |j"                  d   |j$                  ¬«      }|j                  «       dk(  r|||<   n€|j                  «       dk(  r||||f<   ne|j'                  |d«      }|j"                  }|j)                  d|j"                  |   «      }||||f<   |j+                  |«      j'                  |d«      }|j                  «       | j                  «       cxkD  rdkD  rn n| j	                  |«      } |��t-        |j                  «       «      D �cg c]  }d‘Œ }}|j"                  d   ||<   |j)                  |«      }t/        |j"                  «      }d||<   |j1                  |«      }t        j2                  |||«      }| |z  } t        j                  ||k7  | d«      } |t        j4                  |«      z   | z  S c c}w )Nr`   r   r   r€   g      ð?)Údevicerƒ   )r   r   r�   r‹   r…   r(   r„   Ú
zeros_liker   r‰   Úflattenr†   Úmask_bufferÚdatarF   r<   Úaranger{   r¨   Ú	transposeÚreshaper|   rž   r�   rŽ   r‡   rQ   )ro   rT   rr   rs   ru   rv   r—   rw   rx   r"   rV   r‘   Ú
grad_inputr“   Úmasked_safe_targetÚgrad_updateÚ	arange_1dÚgrad_input_tÚintermidate_shapeÚgrad_input_2dÚ_r˜   r}   Úw_targets                           r   Ú"_nll_loss_and_log_softmax_backwardr¹   X  s‘  € ð —u‘u“w ’{‘!¨€KØ”I—N‘N×(Ñ(Ò(Ø! LÑ0ˆà×Ñ˜kÓ*€FÜ—+‘+˜f¨Ñ4°f¸aÓ@€KÜ×!Ñ! !Ó$€Jô %°+È+ÔVÐØ×%Ñ% kÓ2×:Ñ:Ó<€KØ*×;Ñ;¸KÈÈxÓXÐà×(Ñ(×-Ñ-Ð9Ð9Ð9Ø#×/Ñ/×4Ñ4×7Ñ7¸
×8HÑ8HÓIÈCÑO€KÜ—‘Ø× Ñ  Ñ#Ð,>×,EÑ,Eô€Ið
 	‡u�uƒw�!‚|Ø)4ˆ
Ð%Ò&Ø	
�‰‹�AŠØ4?ˆ
�9Ð0Ð0Ò1à!×+Ñ+¨K¸Ó<ˆØ(×.Ñ.ÐØ$×,Ñ,¨R°·±¸Ñ1EÓFˆØ7Bˆ�iÐ!3Ð3Ñ4Ø"×'Ñ'Ð(9Ó:×DÑDÀ[ÐRTÓUˆ
à‡~�~Ó˜+Ÿ/™/Ó+Ô/¨aÕ/Ø!×+Ñ+¨KÓ8ˆàÐÜ % a§e¡e£g£Ö/˜1’QÐ/ˆ	Ð/Ø!'§¡¨a¡ˆ	�+ÑØ—‘ 	Ó*ˆô ˜Ÿ™“Mˆ	Ø!#ˆ	�+ÑØ�M‰M˜)Ó$ˆÜ—<‘<  ;°Ó7ˆØ! HÑ,ˆä—+‘+˜f¨Ñ4°kÀ1ÓE€Kð œŸ™ 1›Ñ%¨Ñ4Ð4ùò# 0s   È"	Kc                 óÖ  — t        t        |d   «      }t        t        |d   «      }|d   }|d   }t        t        |d   «      }t        t        |d   «      }t        t        |d   «      }	|j	                  «       dk\  rdnd}
|j
                  }t        |j                  |
«      }t        t        |j                  |
g«      |
«      }t        «       f|j                  j                  z  }t        |||j                  «      }|�t        |||j                  «      }t        |«      }||c|d<   |d<   t        |	||j                  «      |d<   t        | t!        |«      |«      }t#        |j$                  |j$                  |j$                  |�|j$                  nd |||	|j&                  |
|j                  |«      }t)        |j                  |j                  |¬«      }t        |||j*                  ¬	«      S )
Nr   r   r`   rn   rœ   é   é   ra   rb   )r   r   rd   r   r   rf   r!   r   r   r   r   r"   r�   r-   r�   r5   r7   r¹   rg   r{   r
   rc   )r.   r/   r0   ro   rT   rr   rs   ru   rv   r—   rx   rh   rV   r    r¡   ri   r]   r¥   s                     r   Ú_nll_loss_backward_handlerr½   �  sÊ  € ô
 ”w  Q¡Ó(€KÜŒW�d˜1‘gÓ€AØ�!‰W€FØ�!‰W€FÜ”S˜$˜q™'Ó"€IÜœ˜T !™WÓ%€LÜœ  Q¡Ó(€Là—u‘u“w !’|‘!¨€KØ�7‰7€DÜ(¨¯©¸+ÓF€Hô "Ü  §¡°;°-Ó@À+óÐô !*£˜~°·	±	·±Ñ>ÐÜ˜fÐ&7¸¿¹ÓC€FØÐÜ! &Ð*BÀDÇIÁIÓNˆô �‹:€DØ˜vÐ€Dˆ�GˆT�!‰WÜ˜|Ð-EÀtÇyÁyÓQ€Dˆ�GÜ/°¼¸t»ÀfÓMÐä/Ø×!Ñ!Ø	�‰Ø×ÑØ &Ð 2ˆ×Ò¸ØØØØ	�‰ØØ�	‰	Øó€Fô Ø�	‰	Ø�‰Ø&ô€Hô ØØØ×*Ñ*ôð r   c                  ó^   — t         j                  j                  j                  t        «       y ©N)r   r2   Ú_custom_op_handlersÚupdateÚcustomized_loss_opsr   r   r   r   r   â  s   € Ü×Ñ×.Ñ.×5Ñ5Ô6IÕJr   c                  ól   — t         D ]+  } t        j                  j                  j	                  | «       Œ- y r¿   )rÂ   r   r2   rÀ   Úpop)Ú	custom_ops    r   r   r   æ  s-   € Ü(ò Bˆ	Ü×Ñ×2Ñ2×6Ñ6°yÕAñBr   )AÚ
contextlibÚtypingr   r   r(   Útorch._prims_commonÚ_prims_commonrB   Ú)torch.distributed._functional_collectivesÚdistributedÚ_functional_collectivesrJ   Ú"torch.distributed.distributed_c10dÚdistributed_c10drL   r   Útorch.distributed.device_meshr   Útorch.distributed.tensorr   r   r	   Ú&torch.distributed.tensor._dtensor_specr
   r   Ú,torch.distributed.tensor._ops._embedding_opsr   Ú'torch.distributed.tensor._ops._math_opsr   r   r   Ú(torch.distributed.tensor.placement_typesr   ÚopsÚatenÚ__all__Úcontextmanagerr   r7   rd   r!   r-   Ú_opsÚ
OpOverloadÚobjectÚdictÚstrr5   r^   rl   rq   ÚSizerš   r¦   r¹   r½   ÚdefaultÚ_log_softmax_backward_dataÚnll_loss_forwardÚnll_loss2d_forwardÚnll_loss_backwardÚnll_loss2d_backwardrÂ   r   r   r   r   r   ú<module>rå      sÌ  ðó ß !ã Ý #ß :Ð :ß 1Ð 1Ý Ý 4ß >Ñ >ß JÝ E÷ñ õ
 ?ð ‡y�y‡~�~€ð Ð
€ð ×Ññ-ó ð-ðd	¨%°	¸3°Ñ*?ð 	Àcð 	Ècó 	ð<Ø˜i¨˜nÑ-ð<Ø5?ð<àó<ð QØ�Z‰Z×"Ñ"ðQà
�˜�Ñ
ðQð ��f�ÑðQð ó	Qò&ð4Ø�Z‰Z×"Ñ"ðà
�˜�Ñ
ðð ��f�Ñðð ó	ð>'Ø�Z‰Z×"Ñ"ð'à
�˜�Ñ
ð'ð ��f�Ñð'ð ó	'ðF ØðF àðF ð �VÑðF ð ˜6Ñ"ð	F ð
 ðF ð ðF ð —‘ðF ð ðF ð ðF ð ðF ð ˆ6�6ˆ>ÑóF ðRAØ�Z‰Z×"Ñ"ðAà
�˜�Ñ
ðAð ��f�ÑðAð ó	AðVB5ØðB5àðB5ð ðB5ð �VÑð	B5ð
 ðB5ð ðB5ð ðB5ð —‘ðB5ð ðB5ð ðB5ð ðB5ð óB5ðJ8Ø�Z‰Z×"Ñ"ð8à
�˜�Ñ
ð8ð ��f�Ñð8ð ó	8ðx 	×Ñ×ÑÐ3Ø×#Ñ#×+Ñ+Ð-JØ×Ñ×!Ñ!Ð#<Ø×Ñ×#Ñ#Ð%>Ø×Ñ×"Ñ"Ð$>Ø×Ñ×$Ñ$Ð&@ðÐ òKóBr   