o
    ei                     @   s^  d Z ddlZddlmZ ddlmZmZ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mZmZmZmZmZmZ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*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8 ddl9m:Z: e!;e<Z=G dd de)Z>G dd de8Z?G dd de(Z@G dd de3ZAG dd de7ZBG dd de5ZCG dd de*ZDe G d d! d!eZEG d"d# d#e6ZFG d$d% d%e/ZGG d&d' d'e.ZHG d(d) d)e4ZIG d*d+ d+e+ZJG d,d- d-e-ZKG d.d/ d/e1ZLG d0d1 d1e,ZMG d2d3 d3e2ZNG d4d5 d5e0ZOg d6ZPdS )7zPyTorch ERNIE model.    N)BCEWithLogitsLossCrossEntropyLossMSELoss   )initialization)CacheDynamicCacheEncoderDecoderCache)create_bidirectional_maskcreate_causal_mask),BaseModelOutputWithPoolingAndCrossAttentions!CausalLMOutputWithCrossAttentionsMaskedLMOutputMultipleChoiceModelOutputNextSentencePredictorOutputQuestionAnsweringModelOutputSequenceClassifierOutputTokenClassifierOutput)PreTrainedModel)Unpack)TransformersKwargsauto_docstringlogging)can_return_tuplemerge_with_config_defaults)capture_outputs   )BertCrossAttentionBertEmbeddingsBertEncoderBertForMaskedLMBertForMultipleChoiceBertForNextSentencePredictionBertForPreTrainingBertForPreTrainingOutputBertForQuestionAnsweringBertForSequenceClassificationBertForTokenClassification	BertLayerBertLMHeadModelBertLMPredictionHead	BertModel
BertPoolerBertSelfAttention   )ErnieConfigc                       st   e Zd ZdZ fddZ						ddejdB dejdB dejdB d	ejdB d
ejdB dedej	fddZ
  ZS )ErnieEmbeddingszGConstruct the embeddings from word, position and token_type embeddings.c                    s4   t  | |j| _|jrt|j|j| _d S d S )N)super__init__use_task_idnn	Embeddingtask_type_vocab_sizehidden_sizetask_type_embeddings)selfconfig	__class__ e/home/ubuntu/transcripts/venv/lib/python3.10/site-packages/transformers/models/ernie/modular_ernie.pyr2   B   s
   zErnieEmbeddings.__init__Nr   	input_idstoken_type_idstask_type_idsposition_idsinputs_embedspast_key_values_lengthreturnc                 C   s6  |d ur	|  }n|  d d }|\}}	|d u r&| jd d ||	| f }|d u rSt| drH| j|jd d}
tj|
d|d}
|
||	}ntj|tj	| jj
d}|d u r\| |}| |}||j
}|| }| |}|| }| jr|d u rtj|tj	| jj
d}| |}||7 }| |}| |}|S )Nr@   r   r.   )dimindex)dtypedevice)sizerB   hasattrr@   expandshapetorchgatherzeroslongrJ   word_embeddingstoken_type_embeddingstoposition_embeddingsr3   r8   	LayerNormdropout)r9   r?   r@   rA   rB   rC   rD   input_shape
batch_size
seq_lengthbuffered_token_type_idsrT   
embeddingsrV   r8   r=   r=   r>   forwardI   s6   	







zErnieEmbeddings.forward)NNNNNr   )__name__
__module____qualname____doc__r2   rO   
LongTensorFloatTensorintTensorr^   __classcell__r=   r=   r;   r>   r0   ?   s0    	r0   c                   @      e Zd ZdS )ErnieSelfAttentionNr_   r`   ra   r=   r=   r=   r>   ri          ri   c                   @   rh   )ErnieCrossAttentionNrj   r=   r=   r=   r>   rl      rk   rl   c                   @   rh   )
ErnieLayerNrj   r=   r=   r=   r>   rm      rk   rm   c                   @   rh   )ErniePoolerNrj   r=   r=   r=   r>   rn      rk   rn   c                   @   rh   )ErnieLMPredictionHeadNrj   r=   r=   r=   r>   ro      rk   ro   c                   @   rh   )ErnieEncoderNrj   r=   r=   r=   r>   rp      rk   rp   c                       sL   e Zd ZeZdZdZdZdZdZ	dZ
eeedZe  fddZ  ZS )ErniePreTrainedModelernieT)hidden_states
attentionscross_attentionsc                    sf   t  | t|trt|j dS t|tr1t|j	t
|j	jd d t|j dS dS )zInitialize the weightsrF   )r.   rF   N)r1   _init_weights
isinstancero   initzeros_biasr0   copy_rB   rO   arangerN   rM   r@   )r9   moduler;   r=   r>   rv      s   

"z"ErniePreTrainedModel._init_weights)r_   r`   ra   r/   config_classbase_model_prefixsupports_gradient_checkpointing_supports_flash_attn_supports_sdpa_supports_flex_attn_supports_attention_backendrm   ri   rl   _can_record_outputsrO   no_gradrv   rg   r=   r=   r;   r>   rq      s    rq   c                       s   e Zd ZdgZd fdd	Zeee											ddej	dB dej	dB dej	dB d	ej	dB d
ej	dB dej	dB dej	dB dej	dB de
dB dedB dej	dB dee deej	 eB fddZdd Z  ZS )
ErnieModelrm   Tc                    sL   t  | | || _d| _t|| _t|| _|rt|nd | _	| 
  d S )NF)r1   r2   r:   gradient_checkpointingr0   r]   rp   encoderrn   pooler	post_init)r9   r:   add_pooling_layerr;   r=   r>   r2      s   

zErnieModel.__init__Nr?   attention_maskr@   rA   rB   rC   encoder_hidden_statesencoder_attention_maskpast_key_values	use_cachecache_positionkwargsrE   c              
   K   s  | j jr|
dur
|
n| j j}
nd}
| jr | jr |
r td d}
|
rA|	du rA|dus.| j jr;tt	| j dt	| j dnt	| j d}	|durM|durMt
d|dur\| || | }n|duri| dd }nt
d|\}}|durx|jn|j}|	dur|	 nd}|du rtj||| |d	}| j||||||d
}| j||||||	d\}}| j|f||||	|
||d|}|d }| jdur| |nd}t|||jdS )  
        task_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
            Task type embedding is a special embedding to represent the characteristic of different tasks, such as
            word-aware pre-training task, structure-aware pre-training task and semantic-aware pre-training task. We
            assign a `task_type_id` to each task and the `task_type_id` is in the range `[0,
            config.task_type_vocab_size-1]
        NFzZ`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`...)r:   zDYou cannot specify both input_ids and inputs_embeds at the same timerF   z5You have to specify either input_ids or inputs_embedsr   )rJ   )r?   rB   r@   rA   rC   rD   )r   r   embedding_outputr   r   r   )r   r   r   r   r   r   rB   )last_hidden_statepooler_outputr   )r:   
is_decoderr   r   trainingloggerwarning_onceis_encoder_decoderr	   r   
ValueError%warn_if_padding_and_no_attention_maskrK   rJ   get_seq_lengthrO   r|   r]   _create_attention_masksr   r   r   r   )r9   r?   r   r@   rA   rB   rC   r   r   r   r   r   r   rY   rZ   r[   rJ   rD   r   encoder_outputssequence_outputpooled_outputr=   r=   r>   r^      s~   



		zErnieModel.forwardc                 C   sP   | j jrt| j ||||d}nt| j ||d}|d ur$t| j |||d}||fS )N)r:   rC   r   r   r   )r:   rC   r   )r:   rC   r   r   )r:   r   r   r
   )r9   r   r   r   r   r   r   r=   r=   r>   r   &  s*   	z"ErnieModel._create_attention_masks)T)NNNNNNNNNNN)r_   r`   ra   _no_split_modulesr2   r   r   r   rO   rf   r   boolr   r   tupler   r^   r   rg   r=   r=   r;   r>   r      sZ    	
br   c                   @   rh   )ErnieForPreTrainingOutputNrj   r=   r=   r=   r>   r   I  rk   r   c                   @   s   e Zd ZdddZee								ddejdB dejdB dejdB dejdB d	ejdB d
ejdB dejdB dejdB dee	 de
ej eB fddZdS )ErnieForPreTrainingcls.predictions.bias'ernie.embeddings.word_embeddings.weightzcls.predictions.decoder.biaszcls.predictions.decoder.weightNr?   r   r@   rA   rB   rC   labelsnext_sentence_labelr   rE   c	              	   K   s   | j |f|||||dd|	}
|
dd \}}| ||\}}d}|durK|durKt }||d| jj|d}||dd|d}|| }t||||
j|
jdS )a:  
        task_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
            Task type embedding is a special embedding to represent the characteristic of different tasks, such as
            word-aware pre-training task, structure-aware pre-training task and semantic-aware pre-training task. We
            assign a `task_type_id` to each task and the `task_type_id` is in the range `[0,
            config.task_type_vocab_size-1]
        labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
            Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ...,
            config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked),
            the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`
        next_sentence_label (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
            Labels for computing the next sequence prediction (classification) loss. Input should be a sequence
            pair (see `input_ids` docstring) Indices should be in `[0, 1]`:

            - 0 indicates sequence B is a continuation of sequence A,
            - 1 indicates sequence B is a random sequence.

        Example:

        ```python
        >>> from transformers import AutoTokenizer, ErnieForPreTraining
        >>> import torch

        >>> tokenizer = AutoTokenizer.from_pretrained("nghuyong/ernie-1.0-base-zh")
        >>> model = ErnieForPreTraining.from_pretrained("nghuyong/ernie-1.0-base-zh")

        >>> inputs = tokenizer("Hello, my dog is cute", return_tensors="pt")
        >>> outputs = model(**inputs)

        >>> prediction_logits = outputs.prediction_logits
        >>> seq_relationship_logits = outputs.seq_relationship_logits
        ```
        Tr   r@   rA   rB   rC   return_dictNr   rF   )lossprediction_logitsseq_relationship_logitsrs   rt   )	rr   clsr   viewr:   
vocab_sizer   rs   rt   )r9   r?   r   r@   rA   rB   rC   r   r   r   outputsr   r   prediction_scoresseq_relationship_score
total_lossloss_fctmasked_lm_lossnext_sentence_lossr=   r=   r>   r^   S  s6   /zErnieForPreTraining.forwardNNNNNNNN)r_   r`   ra   _tied_weights_keysr   r   rO   rf   r   r   r   r   r^   r=   r=   r=   r>   r   M  sF    	
r   c                "   @   s   e Zd Zee													ddejdB dejdB dejdB dejdB dejdB dejdB d	ejdB d
ejdB dejdB deej dB dedB dejdB de	ejB de
e deej eB fddZdS )ErnieForCausalLMNr   r?   r   r@   rA   rB   rC   r   r   r   r   r   r   logits_to_keepr   rE   c                 K   s   |	durd}| j |f||||||||
||dd|}|j}t|tr)t| dn|}| |dd|ddf }d}|	durM| jd||	| jjd|}t	|||j
|j|j|jdS )a  
        task_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
            Task type embedding is a special embedding to represent the characteristic of different tasks, such as
            word-aware pre-training task, structure-aware pre-training task and semantic-aware pre-training task. We
            assign a `task_type_id` to each task and the `task_type_id` is in the range `[0,
            config.task_type_vocab_size-1]
        labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
            Labels for computing the left-to-right language modeling loss (next word prediction). Indices should be in
            `[-100, 0, ..., config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are
            ignored (masked), the loss is only computed for the tokens with labels n `[0, ..., config.vocab_size]`
        NFT)r   r@   rA   rB   rC   r   r   r   r   r   r   )logitsr   r   )r   r   r   rs   rt   ru   r=   )rr   r   rw   re   slicer   loss_functionr:   r   r   r   rs   rt   ru   )r9   r?   r   r@   rA   rB   rC   r   r   r   r   r   r   r   r   r   rs   slice_indicesr   r   r=   r=   r>   r^     sB   zErnieForCausalLM.forward)NNNNNNNNNNNNr   )r_   r`   ra   r   r   rO   rf   listr   re   r   r   r   r   r^   r=   r=   r=   r>   r     s^    	
r   c                   @   s   e Zd ZdddZee									ddejdB dejdB dejdB dejdB d	ejdB d
ejdB dejdB dejdB dejdB dee	 de
ej eB fddZdS )ErnieForMaskedLMr   r   r   Nr?   r   r@   rA   rB   rC   r   r   r   r   rE   c
                 K   sx   | j |f|||||||dd|
}|d }| |}d}|	dur2t }||d| jj|	d}t|||j|jdS )as  
        task_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
            Task type embedding is a special embedding to represent the characteristic of different tasks, such as
            word-aware pre-training task, structure-aware pre-training task and semantic-aware pre-training task. We
            assign a `task_type_id` to each task and the `task_type_id` is in the range `[0,
            config.task_type_vocab_size-1]
        labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
            Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ...,
            config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the
            loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`
        T)r   r@   rA   rB   rC   r   r   r   r   NrF   r   r   rs   rt   )	rr   r   r   r   r:   r   r   rs   rt   )r9   r?   r   r@   rA   rB   rC   r   r   r   r   r   r   r   r   r   r=   r=   r>   r^     s4   

zErnieForMaskedLM.forward)	NNNNNNNNN)r_   r`   ra   r   r   r   rO   rf   r   r   r   r   r^   r=   r=   r=   r>   r     sL    	
r   c                   @      e Zd Zee							ddejdB dejdB dejdB dejdB dejdB dejdB dejdB d	ee d
e	ej e
B fddZdS )ErnieForNextSentencePredictionNr?   r   r@   rA   rB   rC   r   r   rE   c              	   K   sp   | j |f|||||dd|}	|	d }
| |
}d}|dur.t }||dd|d}t|||	j|	jdS )a  
        task_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
            Task type embedding is a special embedding to represent the characteristic of different tasks, such as
            word-aware pre-training task, structure-aware pre-training task and semantic-aware pre-training task. We
            assign a `task_type_id` to each task and the `task_type_id` is in the range `[0,
            config.task_type_vocab_size-1]
        labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
            Labels for computing the next sequence prediction (classification) loss. Input should be a sequence pair
            (see `input_ids` docstring). Indices should be in `[0, 1]`:

            - 0 indicates sequence B is a continuation of sequence A,
            - 1 indicates sequence B is a random sequence.

        Example:

        ```python
        >>> from transformers import AutoTokenizer, ErnieForNextSentencePrediction
        >>> import torch

        >>> tokenizer = AutoTokenizer.from_pretrained("nghuyong/ernie-1.0-base-zh")
        >>> model = ErnieForNextSentencePrediction.from_pretrained("nghuyong/ernie-1.0-base-zh")

        >>> prompt = "In Italy, pizza served in formal settings, such as at a restaurant, is presented unsliced."
        >>> next_sentence = "The sky is blue due to the shorter wavelength of blue light."
        >>> encoding = tokenizer(prompt, next_sentence, return_tensors="pt")

        >>> outputs = model(**encoding, labels=torch.LongTensor([1]))
        >>> logits = outputs.logits
        >>> assert logits[0, 0] < logits[0, 1]  # next sentence was random
        ```
        Tr   r.   NrF   r   r   )rr   r   r   r   r   rs   rt   )r9   r?   r   r@   rA   rB   rC   r   r   r   r   seq_relationship_scoresr   r   r=   r=   r>   r^   #  s0   -
z&ErnieForNextSentencePrediction.forwardNNNNNNN)r_   r`   ra   r   r   rO   rf   r   r   r   r   r^   r=   r=   r=   r>   r   "  :    	
r   c                   @   r   )ErnieForSequenceClassificationNr?   r   r@   rA   rB   rC   r   r   rE   c              	   K   s6  | j |f|||||dd|}	|	d }
| |
}
| |
}d}|dur| jjdu rN| jdkr4d| j_n| jdkrJ|jtjksE|jtj	krJd| j_nd| j_| jjdkrlt
 }| jdkrf|| | }n+|||}n%| jjdkrt }||d| j|d}n| jjdkrt }|||}t|||	j|	jd	S )
a^  
        task_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
            Task type embedding is a special embedding to represent the characteristic of different tasks, such as
            word-aware pre-training task, structure-aware pre-training task and semantic-aware pre-training task. We
            assign a `task_type_id` to each task and the `task_type_id` is in the range `[0,
            config.task_type_vocab_size-1]
        labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
            Labels for computing the sequence classification/regression loss. Indices should be in `[0, ...,
            config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If
            `config.num_labels > 1` a classification loss is computed (Cross-Entropy).
        Tr   r.   N
regressionsingle_label_classificationmulti_label_classificationrF   r   )rr   rX   
classifierr:   problem_type
num_labelsrI   rO   rR   re   r   squeezer   r   r   r   rs   rt   )r9   r?   r   r@   rA   rB   rC   r   r   r   r   r   r   r   r=   r=   r>   r^   m  sP   



"


z&ErnieForSequenceClassification.forwardr   )r_   r`   ra   r   r   rO   rf   r   r   r   r   r^   r=   r=   r=   r>   r   l  r   r   c                   @   r   )ErnieForMultipleChoiceNr?   r   r@   rA   rB   rC   r   r   rE   c              	   K   s2  |dur	|j d n|j d }	|dur|d|dnd}|dur*|d|dnd}|dur9|d|dnd}|durH|d|dnd}|dur[|d|d|dnd}| j|f|||||dd|}
|
d }| |}| |}|d|	}d}|durt }|||}t|||
j|
j	dS )a9	  
        input_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`):
            Indices of input sequence tokens in the vocabulary.

            Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and
            [`PreTrainedTokenizer.__call__`] for details.

            [What are input IDs?](../glossary#input-ids)
        token_type_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`, *optional*):
            Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0,
            1]`:

            - 0 corresponds to a *sentence A* token,
            - 1 corresponds to a *sentence B* token.

            [What are token type IDs?](../glossary#token-type-ids)
        task_type_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`, *optional*):
            Task type embedding is a special embedding to represent the characteristic of different tasks, such as
            word-aware pre-training task, structure-aware pre-training task and semantic-aware pre-training task. We
            assign a `task_type_id` to each task and the `task_type_id` is in the range `[0,
            config.task_type_vocab_size-1]
        position_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`, *optional*):
            Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0,
            config.max_position_embeddings - 1]`.

            [What are position IDs?](../glossary#position-ids)
        inputs_embeds (`torch.FloatTensor` of shape `(batch_size, num_choices, sequence_length, hidden_size)`, *optional*):
            Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This
            is useful if you want more control over how to convert `input_ids` indices into associated vectors than the
            model's internal embedding lookup matrix.
        labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
            Labels for computing the multiple choice classification loss. Indices should be in `[0, ...,
            num_choices-1]` where `num_choices` is the size of the second dimension of the input tensors. (See
            `input_ids` above)
        Nr.   rF   Tr   r   )
rN   r   rK   rr   rX   r   r   r   rs   rt   )r9   r?   r   r@   rA   rB   rC   r   r   num_choicesr   r   r   reshaped_logitsr   r   r=   r=   r>   r^     sF   0


zErnieForMultipleChoice.forwardr   )r_   r`   ra   r   r   rO   rf   r   r   r   r   r^   r=   r=   r=   r>   r     r   r   c                   @   r   )ErnieForTokenClassificationNr?   r   r@   rA   rB   rC   r   r   rE   c              	   K   s|   | j |f|||||dd|}	|	d }
| |
}
| |
}d}|dur4t }||d| j|d}t|||	j|	jdS )a  
        task_type_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
            Task type embedding is a special embedding to represent the characteristic of different tasks, such as
            word-aware pre-training task, structure-aware pre-training task and semantic-aware pre-training task. We
            assign a `task_type_id` to each task and the `task_type_id` is in the range `[0,
            config.task_type_vocab_size-1]
        labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
            Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`.
        Tr   r   NrF   r   )	rr   rX   r   r   r   r   r   rs   rt   )r9   r?   r   r@   rA   rB   rC   r   r   r   r   r   r   r   r=   r=   r>   r^     s2   

z#ErnieForTokenClassification.forwardr   )r_   r`   ra   r   r   rO   rf   r   r   r   r   r^   r=   r=   r=   r>   r     r   r   c                   @   s   e Zd Zee								ddejdB dejdB dejdB dejdB dejdB dejdB dejdB d	ejdB d
ee de	ej e
B fddZdS )ErnieForQuestionAnsweringNr?   r   r@   rA   rB   rC   start_positionsend_positionsr   rE   c	              	   K   s
  | j |f|||||dd|	}
|
d }| |}|jddd\}}|d }|d }d}|durz|durzt| dkrG|d}t| dkrT|d}|d}|d|}|d|}t|d}|||}|||}|| d	 }t	||||
j
|
jd
S )r   Tr   r   r.   rF   )rG   N)ignore_indexr   )r   start_logits
end_logitsrs   rt   )rr   
qa_outputssplitr   
contiguouslenrK   clampr   r   rs   rt   )r9   r?   r   r@   rA   rB   rC   r   r   r   r   r   r   r   r   r   ignored_indexr   
start_lossend_lossr=   r=   r>   r^   D  sJ   






z!ErnieForQuestionAnswering.forwardr   )r_   r`   ra   r   r   rO   rf   r   r   r   r   r^   r=   r=   r=   r>   r   C  s@    	
r   )
r   r   r   r   r   r   r   r   r   rq   )Qrb   rO   torch.nnr4   r   r   r    r   rx   cache_utilsr   r   r	   masking_utilsr
   r   modeling_outputsr   r   r   r   r   r   r   r   modeling_utilsr   processing_utilsr   utilsr   r   r   utils.genericr   r   utils.output_capturingr   bert.modeling_bertr   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   configuration_ernier/   
get_loggerr_   r   r0   ri   rl   rm   rn   ro   rp   rq   r   r   r   r   r   r   r   r   r   r   __all__r=   r=   r=   r>   <module>   sJ   (
L
@ SE=JH[4B