
    Uhw|                        d dl Z d dlZd dlZd dlZd dlZd dlZd dlmZmZ d dl	m
Z
mZ d dlmZ d dlmZ d dlZd dlmZmZ ddlmZ  ej,                         d	k7  rd dlZ e       rd d
lmZ d dlmZ d dlmZ  e       rd dlZd dlm Z m!Z!m"Z"m#Z#m$Z$  e%ejL                  ejN                  z         Z( e%ejL                  ejR                  z   ejN                  z   dz         Z*ddiddiddiddiddiddidZ+dZ,ddj[                  e+j]                                dZ/g dZ0 G d d      Z1e
 G d d             Z2d efd!Z3 G d" d#e      Z4y)$    N)ArgumentParser	Namespace)	dataclassfield)Thread)Optional)is_rich_availableis_torch_available   )BaseTransformersCLICommandWindows)Console)Live)Markdown)AutoModelForCausalLMAutoTokenizerBitsAndBytesConfigGenerationConfigTextIteratorStreamerz .!\"#$%&'()*+,\-/:<=>?@[]^_`{|}~textz5There is a Llama in my lawn, how can I get rid of it?zyWrite a Python function that integrates any Python function f(x) numerically over an arbitrary interval [x_start, x_end].z4How many helicopters can a human eat in one sitting?z4Count to 10 but skip every number ending with an 'e'zWhy aren't birds real?z2Why is it important to eat socks after meditating?)llamacode
helicopternumbersbirdssocksaa  

**TRANSFORMERS CHAT INTERFACE**

Chat interface to try out a model. Besides chatting with the model, here are some basic commands:
- **!help**: shows all available commands
- **!status**: shows the current status of the model and generation settings
- **!clear**: clears the current conversation and starts a new one
- **!exit**: closes the interface
am  

**TRANSFORMERS CHAT INTERFACE HELP**

Full command list:
- **!help**: shows this help message
- **!clear**: clears the current conversation and starts a new one
- **!status**: shows the current status of the model and generation settings
- **!example {NAME}**: loads example named `{NAME}` from the config and uses it as the user input.
Available example names: `z`, `a%  `
- **!set {ARG_1}={VALUE_1} {ARG_2}={VALUE_2}** ...: changes the system prompt or generation settings (multiple
settings are separated by a space). Accepts the same flags and format as the `generate_flags` CLI argument.
If you're a new user, check this basic flag guide: https://huggingface.co/docs/transformers/llm_tutorial#common-options
- **!save {SAVE_NAME} (optional)**: saves the current chat and settings to file by default to
`./chat_history/{MODEL_NAME}/chat_{DATETIME}.yaml` or `{SAVE_NAME}` if provided
- **!exit**: closes the interface
)	)max_new_tokens   r   )	do_sampleTr   )	num_beamsr   r    )temperature      ?r!   )top_k2   r#   )top_pr"   r%   )repetition_penaltyr"   r&   )
eos_tokensNeos_token_id)eos_token_idsNr(   c                       e Zd Zddee   dee   fdZdedefdZdefdZd	 Z	d
efdZ
d
edefdZddefdZdededefdZy)RichInterfaceN
model_name	user_namec                 f    t               | _        |d| _        n|| _        |d| _        y || _        y )N	assistantuser)r   _consoler,   r-   )selfr,   r-   s      l/var/www/catia.catastroantioquia-mas.com/valormas/lib/python3.12/site-packages/transformers/commands/chat.py__init__zRichInterface.__init__x   s3    	)DO(DO#DN&DN    output_streamreturnc                 X   d}| j                   j                  d| j                   d       t        | j                   d      5 }t	        |      D ]  \  }}|r|dk(  r||z  }g }|j                         D ]G  }|j                  |       |j                  d      r|j                  d       7|j                  d	       I t        dj                  |      j                         d
      }|j                  |        	 ddd       | j                   j                          |S # 1 sw Y   %xY w)zRStream output from a role, and return the generated text after it's done steaming. z[bold blue]<z>:   )consolerefresh_per_secondr   z```
z  
zgithub-dark)
code_themeN)r1   printr,   r   	enumerate
splitlinesappend
startswithr   joinstripupdate)	r2   r6   r   liveioutputslineslinemarkdowns	            r3   stream_outputzRichInterface.stream_output   s   
 l4??*;2>?$--A> 	&$'6 &
7!q&  OO- -DLL&u- T*V,- $BGGEN$8$8$:}UH%5&	&: 	=	& 	&s   B8D  D)c                     | j                   j                  d| j                   d      }| j                   j                          |S )z!Gets user input from the console.[bold red]<z>:
)r1   inputr-   r?   )r2   rP   s     r3   rP   zRichInterface.input   s9    ##k$..1A$FGr5   c                 8    | j                   j                          y)zClears the console.N)r1   clear)r2   s    r3   rR   zRichInterface.clear   s    r5   r   c                     | j                   j                  d| j                   d|        | j                   j                          y)z%Prints a user message to the console.rO   z>:[/ bold red]
N)r1   r?   r-   )r2   r   s     r3   print_user_messagez RichInterface.print_user_message   s7    k$..)99I$PQr5   colorc                 z    | j                   j                  d| d|        | j                   j                          y)z,Prints text in a given color to the console.z[bold ]Nr1   r?   )r2   r   rU   s      r3   print_colorzRichInterface.print_color   s1    fUG1TF34r5   minimalc                     | j                   j                  t        |rt        nt                     | j                   j                          y)z'Prints the help message to the console.N)r1   r?   r   HELP_STRING_MINIMALHELP_STRING)r2   rZ   s     r3   
print_helpzRichInterface.print_help   s.    HG%8UVr5   generation_configmodel_kwargsc                     | j                   j                  d| d       |r| j                   j                  d|        | j                   j                  d|        | j                   j                          y)zFPrints the status of the model and generation settings to the console.z[bold blue]Model: r=   z[bold blue]Model kwargs: z[bold blue]NrX   )r2   r,   r_   r`   s       r3   print_statuszRichInterface.print_status   sf    0B?@MM";L> JKk*;)<=>r5   )NN)F)__name__
__module____qualname__r   strr4   r   rM   rP   rR   rT   rY   boolr^   r   dictrb    r5   r3   r+   r+   w   s    	'8C= 	'HSM 	'%+? %C %Ns s 
 C 
$ 
s ?O _c r5   r+   c                      e Zd ZU dZ edddi      Zee   ed<    edddi      Z	ee   ed<    eddd	i      Z
ee   ed
<    edddi      Zeed<    edddi      Zee   ed<    edddi      Zee   ed<    edddi      Zeed<    edddi      Zeed<    edddi      Zeed<    edddi      Zeed<    edddi      Zeed <    eddd!i      Zeed"<    eddd#i      Zeed$<    eddd%i      Zee   ed&<    eddd'i      Zee   ed(<    ed)dd*i      Zeed+<    ed,dd-i      Zeed.<    ed/d0g d1d2      Zee   ed3<    ed4dd5i      Zeed6<    eddd7i      Zee   ed8<    ed4dd9i      Zeed:<    ed4dd;i      Z eed<<    ed=d>d?d=gd2      Z!eed@<    ed4ddAi      Z"eedB<   y)CChatArgumentsz
    Arguments for the chat CLI.

    See the metadata arg for each argument's description -- the medatata will be printed with
    `transformers chat --help`
    Nhelpz_Name of the pre-trained model. The positional argument will take precedence if both are passed.)defaultmetadatamodel_name_or_pathzKUsername to display in chat interface. Defaults to the current user's name.r0   zSystem prompt.system_promptz./chat_history/zFolder to save chat history.save_folderz"Path to a yaml file with examples.examples_pathzPath to a local generation config file or to a HuggingFace repo containing a `generation_config.json` file. Other generation settings passed as CLI arguments will be applied on top of this generation config.r_   r   z%Maximum number of tokens to generate.r   Tz,Whether to sample outputs during generation.r   r   z Number of beams for beam search.r    r"   z%Temperature parameter for generation.r!   r$   zValue of k for top-k sampling.r#   z Value of p for nucleus sampling.r%   zRepetition penalty.r&   zNEOS tokens to stop the generation. If multiple they should be comma separated.r'   zQEOS token IDs to stop the generation. If multiple they should be comma separated.r)   mainzLSpecific model version to use (can be a branch name, tag name or commit id).model_revisioncpuzDevice to use for inference.deviceautozOverride the default `torch.dtype` and load the model under this dtype. If `'auto'` is passed, the dtype will be automatically derived from the model's weights.)rw   bfloat16float16float32)rl   choicestorch_dtypeFz2Whether to trust remote code when loading a model.trust_remote_codezWhich attention implementation to use; you can run --attn_implementation=flash_attention_2, in which case you must install this manually by running `pip install flash-attn --no-build-isolation`.attn_implementationzIWhether to use 8 bit precision for the base model - works only with LoRA.load_in_8bitzIWhether to use 4 bit precision for the base model - works only with LoRA.load_in_4bitnf4zQuantization type.fp4bnb_4bit_quant_typez#Whether to use nested quantization.use_bnb_nested_quant)#rc   rd   re   __doc__r   ro   r   rf   __annotations__r0   rp   rq   rr   r_   r   intr   rg   r    r!   floatr#   r%   r&   r'   r)   rt   rv   r|   r}   r~   r   r   r   r   ri   r5   r3   rk   rk      s    ).u
)   ghD(3-  $)IY@Z#[M8C=[%6&JhAijKj#(Im@n#oM8C=o (-1
	(x} 	  v?f6ghNChDF<j3klItl18Z/[\Is\sf>e5fgKgrV5U,VWE3W8Z/[\E5\ %cVEZ<[ \\ %jk!J  $)mn$M8C=   hiNC  9W0XYFCY!&PA
"K#  $)] ^t  */ r
*#  efL$  efL$   %UFZhmotgu=vww!&uHm?n!o$or5   rk   argsc                     t        |       S )z;
    Factory function used to chat with a local model.
    )ChatCommand)r   s    r3   chat_command_factoryr   %  s     tr5   c                      e Zd Zedefd       Zd ZdedefdZede	fd       Z
ed ded	ee	   de	fd
       Zed dee	   dee   fd       Zdee	   defdZdededeeef   fdZededee	   dee	   deeee   f   fd       Zededed   fd       Zdedeeef   fdZde	dededee	ee	e	f   f   dededee   deee   eef   fdZd Zy)!r   parserc                     t         f}| j                  d|      }|j                  d      }|j                  dt        dd       |j                  dt        dd	d
       |j                  t               y)z
        Register this command to argparse so it's available for the transformer-cli

        Args:
            parser: Root parser to register command-specific arguments
        chat)dataclass_typeszPositional argumentsmodel_name_or_path_positionalNzName of the pre-trained model.)typerm   rl   generate_flagsa  Flags to pass to `generate`, using a space as a separator between flags. Accepts booleans, numbers, and lists of integers, more advanced parameterization should be set through --generation-config. Example: `transformers chat <model_repo> max_new_tokens=100 do_sample=False eos_token_id=[1,2]`. If you're a new user, check this basic flag guide: https://huggingface.co/docs/transformers/llm_tutorial#common-options*)r   rm   rl   nargs)func)rk   
add_parseradd_argument_groupadd_argumentrf   set_defaultsr   )r   r   chat_parsergroups       r3   register_subcommandzChatCommand.register_subcommand-  s     )*'''P../EF+#tJj 	 	
 	J
  	 	
 	  &: ;r5   c                 4    | j                  |      }|| _        y N)_handle_deprecated_argsr   )r2   r   s     r3   r4   zChatCommand.__init__J  s    ++D1	r5   r   r7   c           
         d}|j                   xs |j                  |_         |j                   t        d      |j                  d}t        j                  dt
               t        D ]>  \  }}}t        ||      }||k7  sd}t        j                  d| d| d| dt
               @ |rt        d	       t                |S )
z
        Handles deprecated arguments and their deprecation cycle. To be removed after we fully migrated to the new
        args.
        FzOne of the following must be provided:
- The positional argument containing the model repo, e.g. `transformers chat <model_repo>`
- the optional --model_name_or_path argument, containing the model repo (deprecated)TzThe --model_name_or_path argument is deprecated will be removed in v4.54.0. Use the positional argument instead, e.g. `transformers chat <model_repo>`.zThe --a.   argument is deprecated will be removed in v4.54.0. There are two alternative solutions to specify this generation option: 
1. Pass `--generation-config <path_to_file/Hub repo>` to specify a generation config.
2. Pass `generate` flags through positional arguments, e.g. `transformers chat <model_repo> =`z
(Press enter to continue))
r   ro   
ValueErrorwarningswarnFutureWarning_DEPRECATION_MAPgetattrr?   rP   )r2   r   has_warningsdeprecated_argdefault_valuenew_argvalues          r3   r   z#ChatCommand._handle_deprecated_argsN  s    
  .2-O-O-jSWSjSj*--5i 
 $$0LMMK 7G 	2NM7D.1E%#^, -s iqq	*
 "		 /0Gr5   c                      t        j                         dk(  rt        j                         S t	        j
                  t        j                               j                  S )z)Returns the username of the current user.r   )platformsystemosgetloginpwdgetpwuidgetuidpw_nameri   r5   r3   get_usernamezChatCommand.get_usernamey  s:     ??	);;= <<		,444r5   Nfilenamec                    i }t        |      |d<   | |d<   |j                  }|Gt        j                  d      }|j                   d| d}t
        j                  j                  ||      }t        j                  t
        j                  j                  |      d       t        |d	      5 }t        j                  ||d
       ddd       t
        j                  j                  |      S # 1 sw Y   (xY w)z!Saves the chat history to a file.settingschat_historyNz%Y-%m-%d_%H-%M-%Sz/chat_.jsonT)exist_okwr:   )indent)varsrq   timestrftimer   r   pathrD   makedirsdirnameopenjsondumpabspath)r   r   r   output_dictfoldertime_strfs          r3   	save_chatzChatCommand.save_chat  s     "&t*J&*N#!!}}%89H<<=VH:USHww||FH5H
BGGOOH-=(C  	0AIIk1Q/	0wwx((	0 	0s   +C++C4rp   c                     | g }|S d| dg}|S )zClears the chat history.r   rolecontentri   )rp   r   s     r3   clear_chat_historyzChatCommand.clear_chat_history  s*      D  &-@ADr5   r   c           	         t        |      dk(  ri S |D ci c]/  }d|j                  d      d   z   dz   |j                  d      d   1 }}|j                         D ci c]*  \  }}||j                         dv r|j                         n|, }}}|j                         D ci c]  \  }}||dk(  rdn| }}}dt        d	t
        fd
}|j                         D ci c]  \  }}| ||      sd| dn| }}}dj                  |j                         D cg c]  \  }}| d|  c}}      }d|z   dz   }|j                  dd      }|j                  dd      }|j                  dd      }|j                  dd      }|j                  dd      }|j                  dd      }	 t        j                  |      }|S c c}w c c}}w c c}}w c c}}w c c}}w # t        j                  $ r t        d      w xY w)zUParses the generate flags from the user input into a dictionary of `generate` kwargs.r   "r   r   )truefalseNonenullsr7   c                 D    | j                  ddd      j                         S )N.r9   r   )replaceisdigit)r   s    r3   	is_numberz3ChatCommand.parse_generate_flags.<locals>.is_number  s    99S"a(0022r5   z, z: {}z"null"z"true"r   z"false"r   z"[[z]"rW   :zFailed to convert `generate_flags` into a valid JSON object.
`generate_flags` = {generate_flags}
Converted JSON string = {generate_flags_string})lensplititemslowerrf   rg   rD   r   r   loadsJSONDecodeErrorr   )	r2   r   flaggenerate_flags_as_dictkvr   generate_flags_stringprocessed_generate_flagss	            r3   parse_generate_flagsz ChatCommand.parse_generate_flags  s@   ~!#I
 bp!pY]#

3(:":S"@$**S/RSBT"T!p!p
 OeNjNjNl"
FJaAAGGI)::qwwyA"
 "
 OeNjNjNl!mda!qF{V"A!m!m	3 	3 	3 VlUqUqUs!tTQPQ!Yq\q1Xq"H!t!t
 !%		CYC_C_Ca*b41aaS1#;*b c !$&; ;c A !6 = =h O 5 = =h O 5 = =i Q 5 = =dC H 5 = =dC H !6 = =c3 G	'+zz2G'H$ ('S "q"
 "n "u
 +c" ## 	D 	s)   4F>/G#G	GG
'G G:	tokenizerc           
         |j                   t               }| j                  ||j                  |j                        \  }}|j
                  |j                  |j                  |j                  |j                  |j                  |j                  ||d	} |j                  di | nd|j                   v rit        j                  j                  |j                         }t        j                  j!                  |j                         }t        j"                  ||      }nt        j"                  |j                         }| j%                  |j&                        }	 |j                  di |	}
||
fS )zj
        Returns a GenerationConfig object holding the generation parameters for the CLI command.
        )	r   r   r    r!   r#   r%   r&   pad_token_idr(   r   ri   )r_   r   parse_eos_tokensr'   r)   r   r   r    r!   r#   r%   r&   rF   r   r   r   basenamefrom_pretrainedr   r   )r2   r   r   r_   r   r)   deprecated_kwargsr   r   parsed_generate_flagsr`   s              r3   get_generation_parameterizationz+ChatCommand.get_generation_parameterization  sB    !!) 0 2*.*?*?	4??\`\n\n*o'L-"&"5"5!^^!^^#//&*&=&= , -
! %$$9'89 $000''//$*@*@A77++D,B,BC$4$D$DWh$W!$4$D$DTE[E[$\! !% 9 9$:M:M N/(//H2GH !,..r5   r'   r)   c                    | j                   | j                  }n| j                   }g }|/|j                  | j                  |j	                  d                   |7|j                  |j	                  d      D cg c]  }t        |       c}       t        |      dk(  r|j                  | j                         ||fS c c}w )z:Retrieves the pad token ID and all possible EOS token IDs.,r   )r   r(   extendconvert_tokens_to_idsr   r   r   rB   )r   r'   r)   r   all_eos_token_idstoken_ids         r3   r   zChatCommand.parse_eos_tokens  s    
 !!)$11L$11L!$$Y%D%DZEUEUVYEZ%[\$$$MDWDWX[D\%]c(m%]^ !Q&$$Y%;%;<... &^s   9B?
model_argsr   c                     | j                   r:t        d| j                  | j                  | j                  | j                        }|S | j
                  rt        d      }|S d }|S )NT)r   bnb_4bit_compute_dtyper   bnb_4bit_use_double_quantbnb_4bit_quant_storage)r   )r   r   r|   r   r   r   )r  quantization_configs     r3   get_quantization_configz#ChatCommand.get_quantization_config  st    """4!'1'='=$.$B$B*4*I*I'1'='=# #" $$"4!# #" #'""r5   c                    t        j                  |j                  |j                  |j                        }|j
                  dv r|j
                  nt        t        |j
                        }| j                  |      }|j                  |j                  |d|d}t        j                  |j                  fd|j                  i|}t        |dd       |j                  |j                        }||fS )N)revisionr}   )rw   Nrw   )r
  r~   r|   
device_mapr  r}   hf_device_map)r   r   r   rt   r}   r|   r   torchr  r~   r   torv   )r2   r   r   r|   r  r`   models          r3   load_model_and_tokenizerz$ChatCommand.load_model_and_tokenizer&  s    !11..(("44
	 +/*:*:n*Ld&&RYZ_aeaqaqRr"::4@++#'#;#;& #6
 %44..
BFBXBX
\h
 5/408HHT[[)Eir5   
user_input	interfaceexamplesr_   r`   r   c                    |dk(  r-| j                  |j                        }|j                          n-|dk(  r|j                          n|j	                  d      rnt        |j                               dk  rR|j                         }t        |      dk(  r|d   }	nd}	| j                  |||	      }	|j                  d|	 dd	
       n|j	                  d      r|dd j                         }
|
j                         }
|
D ]   }d|vs|j                  d| dd
        n? | j                  |
      } |j                  di |} |j                  di | n|j	                  d      rt        |j                               dk(  r|j                         d   }||v rD|j                          g }|j                  ||   d          |j                  d||   d   d       nd| dt        |j                                d}|j                  |d
       nK|dk(  r|j!                  |j"                  ||       n'|j                  d| dd
       |j                          |||fS )z
        Handles all user commands except for `!exit`. May update the chat history (e.g. reset it) or the
        generation config (e.g. set a new flag).
        z!clearz!helpz!save   r   NzChat saved in !green)r   rU   z!setr:   r   z(Invalid flag format, missing `=` after `z;`. Please use the format `arg_1=value_1 arg_2=value_2 ...`.red!exampler   r0   r   zExample z* not found in list of available examples: r   z!status)r,   r_   r`   'z/' is not a valid command. Showing help message.ri   )r   rp   rR   r^   rC   r   r   r   rY   rE   r   rF   rT   rB   listkeysrb   r   )r2   r  r   r  r  r_   r`   r   split_inputr   new_generate_flagsr   parsed_new_generate_flagsnew_model_kwargsexample_nameexample_errors                   r3   handle_non_exit_user_commandsz)ChatCommand.handle_non_exit_user_commandsA  s    !**4+=+=>DOO7"  """7+J4D4D4F0G!0K$**,K;1$&q>~~dD(;H!!z'C7!S""6* ",AB!5!5!7!3!9!9!;* 8d?))Ftf MA A $ *  8 -1,E,EFX,Y)#;#4#;#;#X>W#X ###7&67"":.3z7G7G7I3Ja3O%++-a0Lx'!,,Xl-CF-KLV8Nv8VWX |n,VW[\d\i\i\kWlVmmno  %%=%F9$""=="3) #  !!:,6e'fns!t  "&44r5   c           	         t               st        d      t               st        d      | j                  }|j                  t
        }n3t        |j                        5 }t        j                  |      }d d d        |j                  | j                         }n|j                  }| j                  |      \  }}t        |dd      }| j                  ||      \  }}	t        |j                  |      }
|
j!                          | j#                  |j$                        }|
j'                  d       	 	 |
j)                         }|j+                  d      r4|dk(  ry | j-                  |||
||	|	      \  }}}	|j+                  d
      sW|j/                  d|d       |j1                  |dd      j3                  |j4                        }t7        j8                  |      }||||d|	}t;        |j<                  |      }|j?                          |
jA                  |      }|jC                          |j/                  d|d       # 1 sw Y   xY w# tD        $ r Y y w xY w)NzHYou need to install rich to use the chat interface. (`pip install rich`)zJYou need to install torch to use the chat interface. (`pip install torch`)T)skip_special_tokensskip_prompt)r,   r-   )rZ   r  z!exit)r  r   r  r  r_   r`   r   r  r0   r   pt)return_tensorsadd_generation_prompt)inputsattention_maskstreamerr_   )targetkwargsr/   )#r	   ImportErrorr
   r   rr   DEFAULT_EXAMPLESr   yaml	safe_loadr0   r   r  r   r   r+   r   rR   r   rp   r^   rP   rC   r#  rB   apply_chat_templater  rv   r  	ones_liker   generatestartrM   rD   KeyboardInterrupt)r2   r   r  r   r0   r  r   generation_streamerr_   r`   r  r   r  r*  r+  generation_kwargsthreadmodel_outputs                     r3   runzChatCommand.run  s\    "hii!#jkkyy%'Hd(() -Q>>!,- 99$$&D99D88>y29RVdhi*.*N*NtU^*_'<!T-O-O[_`	&&t'9'9: 	T*+&__.
 ((-!W,@D@b@b'1!%&/%-.?)5!% Ac A=/ &00< KKJ GH"66tDhl6mppLL "'!8$&4 3):	%
 #%!  u~~>OP(667JK[\JKS %- -z % s+   I3&I -I B;I I	IIr   )rc   rd   re   staticmethodr   r   r4   rk   r   rf   r   r   r   r  rh   r   r   r   tupler   r   r   r   r  r   r  r+   r#  r<  ri   r5   r3   r   r   ,  s   <N < <8'M 'm 'V 5# 5 5 )m )x} )PS ) )$ (3- 4:  1(49 1( 1(f%/!%/.;%/	%	&%/N / /.6sm/LTUXM/	sDI~	/ /0 #M #hG[>\ # #& ]  uEY[hEh?i  6N5N5 N5 !	N5
 sDcN*+N5 ,N5 N5 4jN5 
tDz+T1	2N5dHr5   r   )5r   r   r   stringr   r   argparser   r   dataclassesr   r   	threadingr   typingr   r1  transformers.utilsr	   r
   r9   r   r   r   rich.consoler   	rich.liver   rich.markdownr   r  transformersr   r   r   r   r   setascii_letters
whitespaceALLOWED_KEY_CHARSdigitsALLOWED_VALUE_CHARSr0  r\   rD   r  r]   r   r+   rk   r   r   ri   r5   r3   <module>rO     s}     	     . (    D ( 8??	!$&  ,,v/@/@@A 
6==(6+<+<<?bb 
 MN) QRNO./JK 	 	 ";;'7'<'<'>?@ A&
 R Rj Up Up Uppy o, or5   