
    ^jq                     L   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Zd dlmZm	Z	 d dl
mZmZ d dlmZm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 d dlmZ 	 d dl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$ d dl%m&Z& d dl'm(Z(m)Z)m*Z*m+Z+m,Z, d dl-m.Z. dddZ/ e0ejb                  ejd                  z         Z3 e0ejb                  ejh                  z   ejd                  z   dz         Z5ddiddiddiddiddiddiddidZ6dZ7ddjq                  e6js                                dZ: G d  d!      Z; G d" d#      Z<d$e=dz  d%efd&Z>d'e?e=   dz  d%e@fd(ZAd3d)e=dz  d%e?e@   fd*ZBd+e=d,e?e@   d-e@d%e=fd.ZCd%e=fd/ZDeEd0k(  r
 e<d12       yy# e$ r Y Dw xY w)4    N)AsyncIterator	Awaitable)	AnnotatedAny)urljoinurlparse)AsyncInferenceClientChatCompletionStreamOutput)GenerationConfig)is_rich_availableWindows)filesize)Console)Live)Markdown)	BarColumnProgressProgressColumn
TextColumnTimeElapsedColumn)Text	localhosti@  )hostnameportz .!\"#$%&'()*+,\-/:<=>?@[]^_`{|}~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?z$Which number is larger, 9.9 or 9.11?)llamacode
helicopternumbersbirdssocksnumbers2a  

**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 (set generation settings, save chat, etc.)
- **!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_ID}/chat_{DATETIME}.yaml` or `{SAVE_NAME}` if provided
- **!exit**: closes the interface
c                       e Zd ZdededefdZdeee      deeee	z  dz  f   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dedefdZddefdZdefdZdefdZy)RichInterfacemodel_iduser_idbase_urlc                 L    t               | _        || _        || _        || _        y N)r   _consoler%   r&   r'   )selfr%   r&   r'   s       `/var/www/ramen.bs-engineer-server.com/venv/lib/python3.12/site-packages/transformers/cli/chat.py__init__zRichInterface.__init__k   s     	      streamreturnNc           	      P  K   | j                   j                  d| j                   d       t        | j                   d      5 }d}d}t	        j                         }d }| d {   2 3 d {   }|j
                  d   j                  j                  }t        |j
                  d   d|      }t        |dd       }	|	t        |	d	|      }|set        j                  d
d|      }||z  }g }
|j                         D ]G  }|
j                  |       |j                  d      r|
j                  d       7|
j                  d       I t        dj                  |
      j!                         d      }|j#                  |d       7 !7 6 	 d d d        n# 1 sw Y   nxY wt	        j                         z
  }|dkD  rKdkD  rF||z  }| j                   j                          | j                   j                  d| d|dd|dd       | j                   j                          fS w)Nz[bold blue]<z>:   )consolerefresh_per_second r   finish_reasonusagecompletion_tokensz<(/*)(\w*)>z\<\1\2\>z```
z  
zgithub-dark)
code_themeT)refreshz[dim]z tokens in z.1fzs (z tok/s)[/dim])r*   printr%   r   timechoicesdeltacontentgetattrresub
splitlinesappend
startswithr   joinstripupdate)r+   r/   liver   r8   
start_timer6   tokenoutputsr7   lineslinemarkdownelapsedtok_per_secs                  r,   stream_outputzRichInterface.stream_outputq   s	     	l4==/<=$--A> .	4$D !J(,M%+| )4 )4e--*0088 'a(8/= Yw5$(/7JL](^% &&gF  OO- -DLL&u- T*V,- $BGGEN$8$8$:}U Hd3S  , )4|.	4 .	4 .	4` ))+
*Q;,q0+g5KMM!MM%(9':+gc]RUVabeUffs tu]""sP   AH& F#F$F(F
,F-F
0DFF

F	H&FBH&c                     | j                   j                  d| j                   d      }| j                   j                          |S )z!Gets user input from the console.[bold red]<z>:
)r*   inputr&   r<   )r+   rV   s     r,   rV   zRichInterface.input   s8    ##k$,,t$DEr.   c                 8    | j                   j                          y)zClears the console.N)r*   clear)r+   s    r,   rX   zRichInterface.clear   s    r.   r   c                     | j                   j                  d| j                   d|        | j                   j                          y)z%Prints a user message to the console.rU   z>:[/ bold red]
N)r*   r<   r&   )r+   r   s     r,   print_user_messagez RichInterface.print_user_message   s6    k$,,7GvNOr.   colorc                 z    | j                   j                  d| d|        | j                   j                          y)z,Prints text in a given color to the console.z[bold ]N)r*   r<   )r+   r   r[   s      r,   print_colorzRichInterface.print_color   s1    fUG1TF34r.   messagedefaultc                     |rdnd}| j                   j                  d| d| d      }| j                   j                          |j                         j	                         }|s|S |dv S )zFDisplays a yes/no prompt to the user, returning True for confirmation.zY/nzy/Nz[bold yellow]z (z): >   yyes)r*   rV   r<   rH   lower)r+   r_   r`   default_hintresponses        r,   confirmzRichInterface.confirm   sf     'uU==&&wir,s'ST>>#))+N<''r.   minimalc                     | j                   j                  t        |rt        nt                     | j                   j                          y)z'Prints the help message to the console.N)r*   r<   r   HELP_STRING_MINIMALHELP_STRING)r+   rh   s     r,   
print_helpzRichInterface.print_help   s.    HG%8UVr.   modelc           
         t        j                  | j                  j                  d       ddid      }|j	                           G d dt
              }dd	d
dd| j                  j                  t              dz   dz   k\  fd}t        t        d      t        d       |       t               | j                        }|j                   |d      d       }d}t        || j                  d      5  |j                         D ]  }|r|j!                  d      st#        j$                  |dd        }	|	j'                  d      }
|
dk(  r|	j'                  dd      } n|
dk(  rt)        |	j'                  dd            |
d k(  s|	j'                  d!      }|	j'                  d"      } ||      }|r2|d#k(  rd$nd%}|j+                  |||d&   |j'                  d'      |(       |j+                  ||d)d *        d d d        |r)| j                  j-                  t/        d+ d,             n(| j                  j-                  t/        d+ d-             | j                  j-                          y # 1 sw Y   wxY w).N/z/load_modelrm   T)jsonr/   c                       e Zd Zd Zy)3RichInterface.print_model_load.<locals>.StatsColumnc                    |j                   st        d      S |j                  j                  d      dk(  rt	        j
                  t        |j                              }t	        j
                  t        |j                               }|j                  r,dt	        j
                  t        |j                               dnd}|j                  6dt        |j                  dz         dt        |j                  dz        d}nd}t        | d	| | | d
      S t        t        |j                         d	t        |j                                S )Nr5   unitbytesz  z/s<   :02dro   zprogress.download)style)
totalr   fieldsgetr   decimalint	completedspeedtime_remaining)r+   taskdonetotr   etas         r,   renderz:RichInterface.print_model_load.<locals>.StatsColumn.render   s   zz8O;;??6*g5#++C,?@D"**3tzz?;CJN**b!1!1#djj/!B C2FZ\E**6 "3t':':b'@#A"B!CH[H[^`H`DabeCfg 4&#ugcU ;CVWWs4>>231S_4EFGGr.   N)__name__
__module____qualname__r    r.   r,   StatsColumnrr      s    Hr.   r   zLoading processorzLoading configzDownloading fileszLoading into memory)	processorconfigdownloadweights   F   c                 >    j                  | |       }r d| S |S )Nu     →  )r|   )	stage_key
stage_textrm   show_model_prefixstage_labelss     r,   _labelz.RichInterface.print_model_load.<locals>._label   s/    %)))Y?J 
|44r.   z[bold]{task.description}(   )	bar_width)r3   r   )rz   F)r3   	transients   data:    statusreadycachederrorr_   zUnknown errorloadingstageprogressr   ru   itemscurrentrz   )descriptionr   rz   rt   r   )r   r   rz   z_*z was already loaded.*_z is warm.*_)requestspostr'   rstripraise_for_statusr   r*   widthlenr   r   r   r   add_taskr   
iter_linesrF   rp   loadsr|   RuntimeErrorrI   r<   r   )r+   rm   rf   r   r   r   task_idr   rO   eventr   r   proglabelrt   r   r   s    `             @@r,   print_model_loadzRichInterface.print_model_load   sd   ==DMM$8$8$=#>k!JRY[`Qajno!!#	H. 	H& -&+,	
 !MM//3u:>B3FF	 12#MMM
 ##F;$7t#D(DMMTB 	] ++- ]4??9#=

48,8,W$"YYx7FW$&uyyO'LMMY&!IIg.E 99Z0D"5ME*/:*=w7 #$y/Y]YaYabiYjqu (  !UaW[\1]	]6 MM2eW4J)K LMMM2eWK)@ AB?	] 	]s   <BI7A5I77J r   c                     | j                   j                  d| j                   d       | j                   j                  d|        | j                   j                          y)zFPrints the status of the model and generation settings to the console.z[bold blue]Model: r9   z[bold blue]N)r*   r<   r%   )r+   r   s     r,   print_statuszRichInterface.print_status%  sK    0rBCk&23r.   )F)r   r   r   strr-   r   r   r
   tupler   rS   rV   rX   rZ   r^   boolrg   rl   r   r   r   r   r.   r,   r$   r$   j   s    ! !s !c !;#.H IJ;#	sC#I$$	%;#zs s 
 C 

(s 
(T 
(d 
($ 
Pc Pd#3 r.   r$   c                   N   e Zd ZdZded    ded    ddddddfdee ej                  d	
      f   deedz   ej                  d
      f   dee	e   dz   ej                  d
      f   deedz   ej                  d
      f   deedz   ej                  d
      f   dee ej                  d
      f   deedz   ej                  d
      f   deedz   ej                  d
      f   ddfdZed        Zdededeeeeef   f   ded e	e   dee	e   ef   fd!Zd" Zy)#Chat(Chat with a model from the command line.zhttp://r   rw   r   Nz./chat_history/r%   z9ID of the model to use (e.g. 'HuggingFaceTB/SmolLM3-3B').)helpr'   z7Base url to connect to (e.g. http://localhost:8000/v1).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 <base_url> <model_id> 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userzKUsername to display in chat interface. Defaults to the current user's name.system_promptzSystem prompt.save_folderzFolder to save chat history.examples_pathz"Path to a yaml file with examples.generation_configzPath 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.r0   c	                    || _         t        | j                         }	|	j                  t        d   k(  r1|	j                  t        d   k(  r| j                  | j                          || _        || _        || _        t        |      }
|
j                  dd        |
j                  d	i t        |       |
| _        ||| j                  j                         d| _        ||n	t               | _        |r/t#        |      5 }t%        j&                  |      | _        ddd       nt*        | _        t-               st/        d      t1        j2                  | j5                                y# 1 sw Y   BxY w)
r   r   r   T   )	do_samplemax_new_tokens)r'   r%   r   NzHYou need to install rich to use the chat interface. (`pip install rich`)r   )r'   r   r   DEFAULT_HTTP_ENDPOINTr   check_healthr%   r   r   load_generation_configrI   parse_generate_flagsr   to_dictsettingsget_usernamer   openyaml	safe_loadexamplesDEFAULT_EXAMPLESr   ImportErrorasynciorun
_inner_run)r+   r%   r'   r   r   r   r   r   r   parsedr   fs               r,   r-   zChat.__init__1  s:   F !$--(??3J??FKKShioSpDpdmm, *& ((9:S9=,^<=%-8t{{ObObOde !,D,.	 m$ 2 $q 12 2 -DM !"hii 	DOO%&2 2s   <E$$E-c                     t        | dz   d      }	 t        j                  |      }|j                  dk7  rt	        d|  d|j                   d      	 y	# t        j
                  $ r t	        d|  d      w xY w)
Nro   health   zThe server running on z returned status code z on health check (/health).zNo server currently running on z. To run a local server, please run `transformers serve` in aseparate shell. Find more information here: https://huggingface.co/docs/transformers/servingT)r   httpxr|   status_code
ValueErrorConnectError)url
health_urloutputs      r,   r   zChat.check_healthw  s    S3Y1

	YYz*F!!S( ,SE1GHZHZG[[vw  )  !! 	1# 7o p 	s   A A #A6
user_input	interfacer   r   chatc                    d}|dk(  r't        | j                        }|j                          nV|dk(  r|j                          n?|j	                  d      rt        |j                               dk  r|j                         }t        |      dk(  r|d   nKt        j                  j                  | j                  | j                  dt        j                  d       d	      }t        ||| j                  
       |j!                  d| dd       nr|j	                  d      rd|dd j#                         }	|	j                         }	|	D ]   }
d|
vs|j!                  d|
 dd        n  |j$                  d"i t'        |	       n|j	                  d      rt        |j                               dk(  r|j                         d   }||v rD|j                          g }|j)                  ||   d          |j+                  d||   d   d       nud| dt-        |j/                                d}|j!                  |d       nA|dk(  r|j1                  |       n)d}|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).
        T!clear!help!save      chat_%Y-%m-%d_%H-%M-%S.jsonfilenamer   r   Chat saved to !greenr   r[   !setr2   N=(Invalid flag format, missing `=` after `;`. Please use the format `arg_1=value_1 arg_2=value_2 ...`.red!exampler   r   roler@   Example * not found in list of available examples: .!statusr   F'/' is not a valid command. Showing help message.r   )new_chat_historyr   rX   rl   rF   r   splitospathrG   r   r%   r=   strftime	save_chatr   r^   rH   rI   r   rZ   rE   listkeysr   )r+   r   r   r   r   r   valid_commandsplit_inputr   new_generate_flagsflagexample_nameexample_errors                r,   handle_non_exit_user_commandsz"Chat.handle_non_exit_user_commands  s    !#D$6$67DOO7"  """7+J4D4D4F0G!0K$**,K {#q( AWW\\$"2"2DMMU4==YlKmJnnsCtu 
 xdT]]K!!z'C7!S""6* ",AB!5!5!7!3!9!9!;* Jd?))Ftf MA A $ *  J I 45G HI"":.3z7G7G7I3Ja3O%++-a0Lx'!,,Xl-CF-KLV8Nv8VWX |n,VW[\d\i\i\kWlVmmno  %%=%F9$""&"1 "M!!:,6e'fns!t  "]F**r.   c           	      
	  K   t        | j                  | j                  | j                        }|j	                          t        | j                        }|j                  d       |j                  | j                         | j                  }t        | j                        4 d {   }d }	 	 ||}d }|j                  |       n|j                         }|dk(  rnh|dk(  r&t        | j                        }|j	                          \|dk(  r|j                          r|j                  d      rt        |j                               d	k  r|j                         }t        |      d	k(  r|d
   nKt         j"                  j%                  | j&                  | j                  dt)        j*                  d       d      }t-        ||| j.                         |j1                  d| dd       ?|j                  d      rd|dd  j3                         }	|	j                         }	|	D ]  }
d|
vs|j1                  d|
 dd        n  |j4                  d,i t7        |	       |j                  d      rt        |j                               d	k(  r|j                         d
   }|| j8                  v rX|j	                          g }|j                  | j8                  |   d          |j;                  d| j8                  |   d   d       nd| dt=        | j8                  j?                                d}|j1                  |d       ng|d k(  r|jA                  |!       |j                  d      r)|j1                  d"| d#d       |j                          |j;                  d|d       |jC                         | j                  d$}|jE                  |d| j                  |%      }|jG                  |       d {   \  }}|j;                  d&|d       |d'k(  r'|j1                  d(d)       |jI                  d*      rd+}d d d       d {    y 7 7 ]# tJ        $ r Y !w xY w7 # 1 d {  7  sw Y   y xY ww)-N)r%   r&   r'   T)rh   )r'   z!exitr   r   r   r   r   r   r   r   r   r   r   r   r   r   r2   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  )r   rm   )r/   rm   
extra_body	assistantlengthz2Generation stopped after reaching the token limit.yellowzContinue generating?u'   Please continue. Do not repeat text.”r   )&r$   r%   r   r'   rX   r  r   rl   r   r   r	   rZ   rV   rF   r   r  r  r  rG   r   r=   r	  r
  r   r^   rH   rI   r   r   rE   r  r  r   to_json_stringchat_completionrS   rg   KeyboardInterrupt)r+   r   r   r   clientpending_user_inputr   r  r   r  r  r  r  r  r/   model_outputr6   s                    r,   r   zChat._inner_run  s    !4==$))VZVcVcd	 2 23 	T*""4==1'? i	 i	6-1f)5%7
-1*!44Z@%.__%6
 "W,#x//0B0BC!) #w.!,,. #..w7C
@P@P@R<SVW<W&0&6&6&8  #;/14 (N!# $ 0 0$--5WjIkHllqAr" ! "8$W!--^H:Q3OW^-_ #..v6 .8^-A-A-C*-?-E-E-G*$6 VD"$ ) 5 5*RSWRX YM )M +0 !6 !" !&V *FMMU,@AS,TU #..z:s:CSCSCU?VZ[?['1'7'7'9!'<'4==8%OO-#%D%88|9TU[9\] KKDMMR^D_`fDg(hi.6|nDnostx  uB  uB  uG  uG  uI  pJ  oK  KL  -MM%11}E1R#y0!..f.= #..s3!--#$ZL0_!`hm .  ",,.  V
$KL .4-B-B-D!%"J
 $33#"mm#-	 4 F 9B8O8OPV8W2W/L-KK NO$0!--.bdlm$,,-CD1Z.$K i	 i	 i	~ 3X ) Qi	 i	 i	 i	s   B%R'Q(R+Q.0-QQ.*Q	Q.
QQ. CQ+Q.-=Q+5Q Q."C;QQ.8QQ.A$Q=Q>AQQ.RQ,RQ	Q)&Q.(Q))Q.,R.R 4Q75R <R)r   r   r   __doc__r   r   r   typerArgumentr  Optionr-   staticmethodr   r$   dictr   r   r  r   r   r.   r,   r   r   ,  s   2 +J78:OPV:W9XY 
 TXYjhl AD'C5p!qqrD' $J,eff
D' "IENN[	
D'& $JELLkln
'D'. !t\U\\?O-P!PQ/D'0 sLELL6T$UUV1D'2 !t\U\\?c-d!de3D'6 %$JELL g
7D'B 
CD'L   H+H+ !H+ sDcN*+	H+
 !H+ 4jH+ 
tDz++	,H+Ttr.   r   r   r0   c                     | 
t               S d| v rTt        j                  j                  |       }t        j                  j	                  |       }t        j
                  ||      S t        j
                  |       S )Nr   )r   r  r  dirnamebasenamefrom_pretrained)r   r&  r   s      r,   r   r   I  sg     !!##''//"3477##$56//BB//0ABBr.   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sr0   c                 f    | j                  d      } | j                  ddd      j                         S )N-r   r5   r   )removeprefixreplaceisdigit)r/  s    r,   	is_numberz'parse_generate_flags.<locals>.is_numberg  s,    NN3yyb!$,,..r.   z, z: {}z"null"z"true"r+  z"false"r,  z"[[z]"r]   rw   zFailed to convert `generate_flags` into a valid JSON object.
`generate_flags` = {generate_flags}
Converted JSON string = {generate_flags_string})r   r  r   rd   r   r   rG   r3  rp   r   JSONDecodeErrorr   )r   r  generate_flags_as_dictkvr5  generate_flags_stringprocessed_generate_flagss           r,   r   r   U  sC   ^!4!9	
 ^llUYcDJJsOA$66<djjoa>PPll
 KaJfJfJhBF!Q	%661779A=  KaJfJfJhi$!Qa1;A=ii/S /T /
 RhQmQmQopAa11QCq1Dpp
 !II?U?[?[?]&^tq!!Bqc{&^_  "77#= 299(FK199(FK199)WM199$D199$D 299#sC
#'::.C#D  $#W m j q
 '_"  
@
 	

s)   4G  /G%GGG
)G G<r   c                     | rd| dgS g S )z Returns a new chat conversation.systemr   r   )r   s    r,   r  r    s    =JX-89RPRRr.   r   r   r   c                     t        j                  t         j                  j                  |       d       t	        | d      5 }t        j                  ||d|d       ddd       t         j                  j                  |       S # 1 sw Y   (xY w)z!Saves the chat history to a file.T)exist_okw)r   chat_historyr2   )indentN)r  makedirsr  r&  r   rp   dumpabspath)r   r   r   r   s       r,   r
  r
    sj    KK)D9	h	 M		x>!LM77??8$$M Ms   BBc                      t        j                         dk(  rt        j                         S t	        j
                  t        j                               j                  S )z)Returns the username of the current user.r   )platformr@  r  getloginpwdgetpwuidgetuidpw_namer   r.   r,   r   r     s8    I%{{}||BIIK(000r.   __main__z meta-llama/Llama-3.2-3b-Instruct)r%   r)   )Fr   rp   r  rJ  rB   stringr=   collections.abcr   r   typingr   r   urllib.parser   r   r   r   r   r   huggingface_hubr	   r
   transformersr   transformers.utilsr   readliner   r@  rL  richr   rich.consoler   	rich.liver   rich.markdownr   rich.progressr   r   r   r   r   	rich.textr   r   setascii_letters
whitespaceALLOWED_KEY_CHARSdigitsALLOWED_VALUE_CHARSr   rj   rG   r  rk   r$   r   r   r   r  r$  r   r  r
  r   r   r   r.   r,   <module>re     s     	  	   4 ! *     L ) 0	
 8??	!$&``%0$? ,,v/@/@@A 
6==(6+<+<<?bb 
 MN) QRNO./JK?@  	 	 ";;'7'<'<'>?@ A& DZ Zz	CcDj 	C=M 	C3$cT)9 3$d 3$lSC$J S$t* S
% %4: % %# %1c 1 z45 w  		s   F F#"F#