,_ГddlmZddlZddlZddlZddlZddlZddlmZddl m Z ejd e dZGddeZej(d k(r#ddlZddlZddlZGd d eZGd d eZnHej(dk(rddlZddlZddlZGdd eZn!edj=ej.GddeZGddeZ GddeZ!GddeZ"GddeZ#Gdde#Z$GddeZ%Gdd eZ&Gd!d"eZ'e e!e"d#Z(ee#e$e%e&e'd$Z)d%Z*Gd&d'eZ+d*d(Z,e-d)k(re,yy#e $reZ eZY&wxYw)+)absolute_importN)comports) hexlify_codecc8|dk(rtjSdS)Nhexlify)r getregentrycs 7/usr/lib/python3/dist-packages/serial/tools/miniterm.pyr si-335Tcrt|}|dkrdjtd|zSt|S)z)generate a readable description for a key z Ctrl+{:c}@)ordformatrepr) character ascii_codes r key_descriptionr!s6YJB!!#c(Z"788Ir cFeZdZdZdZdZdZdZdZdZ dZ d Z d Z y ) ConsoleBasez8OS abstraction for console (input/output codec, no echo)ctjdk\r tjj|_ntj|_tj|_yN)r)sys version_infostdoutbuffer byte_outputoutputselfs r __init__zConsoleBase.__init__.s9   v %"zz00D "zzD jj r cy)z.Set console to read single characters, no echoNr"s r setupzConsoleBase.setup5r cy)z Restore default console settingsNr&r"s r cleanupzConsoleBase.cleanup8r(r cy)z"Read a single key from the consoleNr&r"s r getkeyzConsoleBase.getkey;sr cn|jj||jjy)zWrite bytes (already encoded)N)r writeflush)r# byte_strings r write_byteszConsoleBase.write_bytes?s( {+  r cn|jj||jjy)z Write stringN)r!r.r/r#texts r r.zConsoleBase.writeDs$ $ r cy)zCancel getkey operationNr&r"s r cancelzConsoleBase.cancelIr(r c&|j|SN)r*r"s r __enter__zConsoleBase.__enter__Ps  r c$|jyr8)r')r#argskwargss r __exit__zConsoleBase.__exit__Ts  r N) __name__ __module__ __qualname____doc__r$r'r*r,r1r.r6r9r=r&r r rr+s2B!=/!  &r rntc"eZdZdZdZdZdZy)Outz$file-like wrapper that uses os.writec||_yr8)fd)r#rFs r r$z Out.__init__`s DGr cyr8r&r"s r r/z Out.flushcs r cDtj|j|yr8)osr.rF)r#ss r r.z Out.writefs HHTWWa r N)r>r?r@rAr$r/r.r&r r rDrD]s2   !r rDc deZdZddddddddd d d Zd d ddddddddd ZfdZdZdZdZxZ S)ConsolezbOPzbOQzbORzbOSzb[15~zb[17~zb[18~zb[19~zb[20~zb[21~) ;<=>?rABCDzzzzzzz[2~z[3~z[5~z[6~) HPKMGORSIQctt| tjj j |_tjj j|_ tjj jdtjj jdtjdk(r>ttjj!dddkDr d}ddlm}t'|ds$tj(|j*|_tjj j.}tjj j0}tjj j2}|j+}||d tj4||j6|zdk(r#||d |j6|z||_t;j<d t?t@jBjEd |_#t;j<d t?t@jHjEd t@_$|jFt@_!d |jF_%y) Ni10.iZ)rLPDWORDUTF-8replace)&superrLr$ctypeswindllkernel32GetConsoleOutputCP _saved_ocp GetConsoleCP _saved_icpSetConsoleOutputCP SetConsoleCPplatformreleaseintversionsplitctypes.wintypeswintypeshasattrPOINTERDWORDreSetConsoleModeGetConsoleMode GetStdHandlebyrefvalue _saved_cmcodecs getwriterrDrrfilenor!stderrencoding)r#"ENABLE_VIRTUAL_TERMINAL_PROCESSINGryr}r~rmode __class__s r r$zConsole.__init__s '4 ) +$mm44GGIDO$mm44AACDO MM " " 5 5e < MM " " / / 6!T)c(2B2B2D2J2J32OPQ2R.SV[.[5;22x3'-~~hnn'EH$!'!7!7!F!F!'!7!7!F!F%}}55BB ~~'|C0&,,t2DEJJ!CCI"<#4djjCe6ef%)DN3&**73C 8I8I8K4LiXDK2))'23szz7H7H7J3KYWCJCJ#*DKK r ctjjj|jtjjj |j  tjjjtjjjd|jy#t$rYywxYw)Nrf) rjrkrlrqrnrrrpr}rrAttributeErrorr"s r __del__zConsole.__del__s MM " " 5 5doo F MM " " / / @  &&55fmm6L6L6Y6YZ]6^`d`n`no!  s(AC CCc6 tj}|tdk(r tdS|tdus |tdur@ tj}|tdur|j|S|j|S|S#t $rYnwxYw)N r)msvcrtgetwchunichrfncodesnavcodesKeyError)r#zcodes r r,zConsole.getkeysMMOr ?!":%&)^qF4L'8%}}q >#'<<#55#'==#66H$s /B :B BBctjjj}tjjj |dddy)Nrr)rjrkrlGetConsoleWindowuser32 PostMessageA)r#hwnds r r6zConsole.cancels:==))::r?r@rrr$rr,r6 __classcell__rs@r rLrLisd     +6  " Dr rLposixc6eZdZfdZdZdZdZdZxZS)rLctt| tjj |_tj|j |_ tj|jtjdkrGtjtjj tj|_ytj|_yr)rirLr$rstdinrrFtermios tcgetattroldatexitregisterr*rr getreaderr enc_stdin)r#rs r r$zConsole.__init__s '4 ) +ii&&(DG((1DH OODLL )&(!E!1!1#))2D2D!Ecii!P!$r cttj|j}|dtjztjztj z|d<d|dtj <d|dtj<tj|jtj|y)Nrr) rrrFICANONECHOISIGVMINVTIME tcsetattrTCSANOW)r#news r r'z Console.setups##DGG,CVw~~o- = MCF#$CF7<< $%CF7== !   dggw r?r@r$r'r,r6r*rrs@r rLrLs + =   9 Dr z9Sorry no implementation for your platform ({}) available.c"eZdZdZdZdZdZy) Transformz&do-nothing: forward all data unchangedc|S)ztext received from serial portr&r3s r rxz Transform.rx r c|S)ztext to be sent to serial portr&r3s r txz Transform.txrr c|S)z(text to be sent but displayed on consoler&r3s r echozTransform.echorr N)r>r?r@rArrrr&r r rrs0r rceZdZdZdZy)CRLFzENTER sends CR+LFc&|jddS)N  rhr3s r rzCRLF.txs||D&))r N)r>r?r@rArr&r r rrs *r rceZdZdZdZdZy)CRzENTER sends CRc&|jddS)N rrr3s r rzCR.rx||D$''r c&|jddS)Nrrrr3s r rzCR.txrr Nr>r?r@rArrr&r r rrs((r rceZdZdZy)LFzENTER sends LFN)r>r?r@rAr&r r rrsr rcleZdZdZededDZejddddZeZ y) NoTerminalz0remove typical terminal control codes from inputc#FK|]}t|dvs|d|zfyw)  $N)r.0xs r zNoTerminal.s$]qR\A\Avz?]s! !r!$%$)rc8|j|jSr8) translateREPLACEMENT_MAPr3s r rz NoTerminal.rxs~~d2233r N) r>r?r@rAdictrangerupdaterrr&r r rr s>:]E"I]]O  4 Dr rcdeZdZdZededDZejddddy) NoControlsz%Remove all control codes, incl. CR+LFc#*K|] }|d|zf yw)rNr&rs r rzNoControls.s>qAvz?>sri#$rr)rrrN)r>r?r@rArrrrr&r r rrs5/>E"I>>O  r rceZdZdZdZeZy) PrintablezMShow decimal code for all non-ASCII characters and replace most control codesc Vg}|D]}d|cxkrdksn|dvr|j|&|dkr'|jtdt|zR|jddj t|D|jddj |S)N rrc3PK|]}tdt|zdz  yw)i 0N)rr)rds r rzPrintable.rx..2s"U!Q" 45Us$&z{:d})appendrrextendrjoin)r#r4rr s r rz Printable.rx*s  Aa & AO SQ01Uv}}SQRV?TUU  wwqzr N)r>r?r@rArrr&r r rr'sW  Dr rc"eZdZdZdZdZdZy)Colorizez,Apply different colors for received and echoc d|_d|_y)Nzz) input_color echo_colorr"s r r$zColorize.__init__<s%$r c |j|zSr8)rr3s r rz Colorize.rxAs$&&r c |j|zSr8)rr3s r rz Colorize.echoDs%%r N)r>r?r@rAr$rrr&r r rr9s6% '&r rceZdZdZdZdZy)DebugIOzPrint what is sent and receivedctjjdj|tjj |S)Nz [RX:{!r}] rrr.rr/r3s r rz DebugIO.rxK4 --d34  r ctjjdj|tjj |S)Nz [TX:{!r}] rr3s r rz DebugIO.txPrr Nrr&r r rrHs) r r)crlfcrlf)directdefault nocontrol printablecolorizedebugctjjdg}tt t dD]J\}\}}}tjjdj ||||j|L td} t|dz }d|cxkrt|ks"ntjjdQ ||}|S#t$rY|SwxYw)z Show a list of ports and ask the user for a choice. To make selection easier on systems with long device names, also allow the input of an index. z --- Available ports: rz--- {:2}: {:20} {!r} z#--- Enter port index or full name: rz--- Invalid index! ) rrr. enumeratesortedrrr raw_inputrulen ValueError)portsnportdeschwidindexs r ask_for_portrks JJ/0 E!*6(*+=q!A D$ 188D$GH T >? IME*E *   !78+ r9r:writertransmitter_threadr<r=r%r'r"s r r=zMiniterm.starts^  "+"2"2$++D"Q)-& %%' r cd|_y)zset flag to stop worker threadsFN)r/r"s r stopz Miniterm.stops  r c|jj|sKt|jdr|jj |j jyy)z$wait for worker threads to terminater@N)rDrrzr&r@r1)r# transmit_onlys r rz Miniterm.joinsL $$&t{{M2 '')  % % 'r c8|jjyr8)r&closer"s r rJzMiniterm.closes r ct|jg|jDcgc] }t| c}z}|Dcgc] }| c}|_t t |j|_ycc}wcc}w)zFtake list of transformation classes and instantiate them for rx and txN)EOL_TRANSFORMATIONSr*r+TRANSFORMATIONStx_transformationslistreversedrx_transformations)r#ftransformationsts r r,zMiniterm.update_transformationssq.txx89FJll=TAB>MQ=O=TT0?"@113"@"&x0G0G'H"I=T"@s A5A:cR||_tj|||_y)zset encoding for received dataN)r(rgetincrementaldecoderr2r#rerrorss r set_rx_encodingzMiniterm.set_rx_encodings#&@&66x@Hr cR||_tj|||_y)z!set encoding for transmitted dataN)r)rgetincrementalencoder tx_encoderrWs r set_tx_encodingzMiniterm.set_tx_encodings#'@&66x@Hr ctjjdj|jtjjdj|jj rdnd|jj rdnd|jjrdnd tjjdj|jjrdnd|jjrdnd|jjrdnd|jjrdndtjjdj|jjrdndtjjdj|jjrdndtjjd j|jtjjd j|j tjjd j|j"j%tjjd jd j'|j(y#tj$rYwxYw)z$Write current settings to sys.stderrzK --- Settings: {p.name} {p.baudrate},{p.bytesize},{p.parity},{p.stopbits} pz&--- RTS: {:8} DTR: {:8} BREAK: {:8} activeinactivez---- CTS: {:8} DSR: {:8} RI: {:8} CD: {:8} z--- software flow control: {} z--- hardware flow control: {} --- serial input encoding: {} --- serial output encoding: {} z --- EOL: {} --- filters: {} rN)rrr.rr&rtsdtrbreak_conditionctsdsrricdSerialExceptionxonxoffrtsctsr(r)r*upperrr+r"s r dump_port_settingszMiniterm.dump_port_settingss hookkp  BIIXjXj44X*G H  JJ  MTT![[__*![[__*![[^^![[^^ > ? :AAdkkNaNa(gqrs :AAdkkN`N`(fpqr :AA$BUBUVW ;BB4CWCWXY //0@AB ,33CHHT\\4JKL%%   s3BKK%$K%cJ |jr|jr|jj|jjxsd}|r|j r|j j|nX|jj|}|jD]}|j|}|j j||jr|jryyyy#tj$r#d|_|j jwxYw)zloop and copy serial->consolerFN)r/r0r&r in_waitingr'r%r1r2decoderQrr.rmr6)r#datar4transformations r r;zMiniterm.readers **!3!3{{'' (>(>(C!Dxx 006#55d;.2.E.E;N#1#4#4T#:D; **40**!3!3*!3*%% DJ LL   !  s C%C,,6D"cd} |jr" |jj}|jsy|r|j |d}n||j k(rd}n||j k(r|jy|}|jD]}|j|}|jj|jj||jr?|}|jD]}|j|}|jj||jr!yy#t$rd}YwxYw#d|_xYw)z Loop and copy console->serial until self.exit_character character is found. When self.menu_character is found, interpret the next key locally. FTN)r/r%r,KeyboardInterrupthandle_menu_keyr.r-rFrNrr&r.r\encoder)r# menu_activer r4rv echo_texts r rCzMiniterm.writers<   ** ++-Azz((+"'K$---"&K$---IIKD*.*A*A7-0067KK%%doo&<&|j_|j3y'|dvr0tj@|j_!|j3y'|dvr0tjD|j_!|j3y'|dvr0tjF|j_!|j3y'|dvr0tjH|j_!|j3y'|dvr0tjJ|j_!|j3y'|dk(r0tjL|j_'|j3y'|dk(r0tjP|j_'|j3y'|d k(r0tjR|j_'|j3y'|d!vr%|d"k(|j_*|j3y'|d#vr%|d$k(|j_+|j3y'|d%vr|jYy'tjjd&jt[|y')(z"Implement a simple menu / settingszhH?z--- RTS {} --- rarbz--- DTR {} --- z--- BREAK {} --- z--- local echo {} ---  rrz--- EOL: {} ---  pPzZbB87eEoOmMsSnN123xXXrRr\qQz!--- unknown menu character {} -- N).r.r-r&r.r\r{rr% upload_filerr get_help_textrfrrgrh change_filterrOrLrr*rrpr,change_encodingrq change_port suspend_portchange_baudrate EIGHTBITSbytesize SEVENBITS PARITY_EVENparity PARITY_ODD PARITY_MARK PARITY_SPACE PARITY_NONE STOPBITS_ONEstopbits STOPBITS_TWOSTOPBITS_ONE_POINT_FIVErnrorFr)r#r modesr*s r rzzMiniterm.handle_menu_key's ## #qD,?,?'? KK  doo44Q7 8yy ""1% &[     )^ JJ  T//1 2 &["&++//1DKKO JJ  /664;;??xc dXbc d &["&++//1DKKO JJ  /664;;??xc dXbc d &[.2kk.I.I*IDKK ' JJ  188T[[E`E`q rfpq r &[ II DI JJ  6==$))hd eYcd e &[    &[,-E++dhh'!+Cc%j SzDH JJ  0778HI J  ' ' ) &[  " &[  # # %$Y     $Y     $Y  " #X#)#3#3DKK  # # % #X#)#3#3DKK  # # % $Y!'!3!3DKK   # # % $Y!'!2!2DKK   # # % $Y!'!3!3DKK   # # % $Y!'!4!4DKK   # # % $Y!'!3!3DKK   # # % #X#)#6#6DKK  # # % #X#)#6#6DKK  # # % #X#)#A#ADKK  # # % $Y#$8DKK   # # % $Y"#s(DKK   # # % $Y IIK JJ  AHHYZI[\ ]r cztjjdtjj|j5tj j jd}|r t|d5}tjjdj| |jd}|snU|jj||jjtjjdi dddtjjdj|dddy#1swY@xYw#t$r9}tjjd j||Yd}~Rd}~wwxYw#1swYyxYw) z,Ask user for filenname and send its contentsz --- File to upload: rrbz--- Sending file {} --- irbNz --- File {} sent --- z"--- ERROR opening file {}: {} --- ) rrr.r/r%rreadlinerstripopenrrr&IOError)r#filenamerRblockes r rzMiniterm.upload_file}s\ 12  \\ `yy))+226:H `h- 2 (()D)K)KH)UV"$%FF4LE#( % KK--e4 KK--/JJ,,S1#!& 2JJ$$%?%F%Fx%PQ ` ` 2 2`JJ$$%J%Q%QRZ\]%^__` ` `sI 0F1; E,BE !6E, E) %E,, F.5/F)$F1)F..F11F:c dtjjdtjjdjdt t j Dtjjdjdj|j|j5tjjjj}dddrV|D]:}|t vs tjjdj|n||_|jtjjdjdj|jy#1swYxYw) zchange the i/o transformationsz --- Available Filters: rc3FK|]\}}dj||yw)z--- {:<10} = {.__doc__}Nrrkvs r rz)Miniterm.change_filter..s)#91 ( . .q! 4#9!z$ --- Enter new filter name(s) [{}]: rNz--- unknown filter: {!r} re)rrr.rrrMitemsrr+r%rrlowerrwr,)r# new_filtersrRs r rzMiniterm.change_filters8 56 #94467#99 : @GGQUQ]Q]H^_` \\ ?)),,.446<<>K ?   .O+JJ$$%A%H%H%KL . + ++- ,33CHHT\\4JKL ? ?s ;F&&F/ctjjdj|j|j 5tj jj}dddr8 tj||j||j|tjjdj|jtjjdj|jy#1swYxYw#t$r1tjjdj|YwxYw)z"change encoding on the serial portz# --- Enter new encoding name [{}]: Nz--- invalid encoding name: {} rcrd)rrr.rr(r%rrstriprlookuprYr] LookupErrorr))r# new_encodings r rzMiniterm.change_encodings ?FFtGZGZ[\ \\ 899--/557L 8  3 l+$$\2$$\2 :AA$BUBUVW ;BB4CWCWXY 8 8  Y   !B!I!I,!WX Ys-D%=D1%D.17E+*E+c@tjjdtjj|j5|j j } ttjjj|j _|jdddy#t$rI}tjjdj|||j _Yd}~Vd}~wwxYw#1swYyxYw)zchange the baudratez --- Baudrate: z#--- ERROR setting baudrate: {} --- N)rrr.r/r%r&baudraterurrrrqrr)r#backuprs r rzMiniterm.change_baudrates +,  \\ *[[))F *'*399+=+=+?+E+E+G'H $ '') * * .   !G!N!Nq!QR'- $$ .  * *s7 D"AB?&D? D?D D DDDc|j5 t}dddrC||jjk7r(|j |jj } tj|d}|j||jj|_ |jj|_ |j|jj|_ |jj||_tjj!dj#|jj|j'yyy#t$rd}Y]wxYw#1swYcxYw#t$$rH}tjj!dj#|jYd}~~d}~wwxYw)z;Have a conversation with the user to change the serial portNT) do_not_openz--- Port changed to: {} --- z#--- ERROR opening new port: {} --- )r%rryr&rrAgetSettingsDictserial_for_urlapplySettingsDictrfrgrrhrJrrr.r Exceptionr>)r#rsettings new_serialrs r rzMiniterm.change_portsf \\  #~  DDKK,,,    {{224H [#224TJ ,,X6!% !% !-1[[-H-H *  !!#(    !@!G!G HXHX!YZ    +-4%    $ #   !G!N!Nq!QR  "" #sAE: E()B F( E73E:6E77E::F G>GGc|j|jjtjj dj |jjd}|jjstjj dj t|j|jj}||jk(r|jn9|dvrd}n2 |jj|jjs|r|j!y|j#tjj d j |jjy#t$r8}tjj dj |Yd}~d}~wwxYw) zl open port temporarily, allow reconnect, exit and port change to get out of the loop z --- Port closed: {} --- FzC--- Quit: {exit} | p: port change | any other key to reconnect --- )exitrTz--- ERROR opening port: {} --- Nz--- Port opened: {} --- )rAr&rJrrr.rris_openrr-r%r,rFrrrr>)r#do_change_portrrs r rzMiniterm.suspend_portsj   6==dkk>N>NOP++%% JJ  cjj$T%8%89k; < ##%AD''' d!% O   "++%%         JJ  8?? @P@PQ R O   !C!J!J1!MNN Os F G!).GG!cHdjttddt|jt|j tdtdtdtdtdtd td td td  S)zreturn the help textab --- pySerial ({version}) - miniterm - help --- --- {exit:8} Exit program (alias {menu} Q) --- {menu:8} Menu escape key, followed by: --- Menu keys: --- {menu:7} Send the menu character itself to remote --- {exit:7} Send the exit character itself to remote --- {info:7} Show info --- {upload:7} Upload file (prompt will be shown) --- {repr:7} encoding --- {filter:7} edit filters --- Toggles: --- {rts:7} RTS {dtr:7} DTR {brk:7} BREAK --- {echo:7} echo {eol:7} EOL --- --- Port settings ({menu} followed by the following): --- p change port --- 7 8 set data bits --- N E O S M change parity (None, Even, Odd, Space, Mark) --- 1 2 3 set stop bits (1, 2, 1.5) --- b change baud rate --- x X disable/enable software flow control --- r R disable/enable hardware flow control VERSIONzunknown versionrrrrrrrrr) rvrmenurfrgbrkrinfouploadrfilterr*)rgetattrr&rr-r.r"s r rzMiniterm.get_help_texts0 F769.?@ 3 34 3 34v&v&v&''!&)'!&)v& (1# (r N)Fr r&)Fr)r>r?r@rAr$r>rAr=rFrrJr,rYr]rqr;rCrzrrrrrrrr&r r r!r!s| $%$(JI I M2&$LT^l`,M&Z *!<S>&(r r!c ddl}|jd}|jddd||jd dtd | |j d }|jd gdddd|jdddd|jdddd|jdtd||jdtd||jdd d!d"d#$|jd%dd&d|j d'}|jd(d)dd*d|jd+d,d-d.d/0|jd1d2d3d4d5g6|jd7gd8d9d:d;|jd}|jd?td@dAdBC|jdDtd@dEdFC|j dG}|jdHdIddJd|jdKddLd|j }|j |jk(r|jdM|jrdN|jvrtjjdOtjjdPjdQttj!DtjjdPtj"dR|j}ndSg} |j$|j$dTk(r. t'|_|j$s|jdU t+j,|j$|j.|j0|j2|j4d#W} t7| dXsdR| _|j:Y|j<s.G qwwyr z*set parity, one of {N E O S M}, default: Nr)choicesrrrz--rtscts store_truez)enable RTS/CTS flow control (default off)F)actionrrz --xonxoffz*enable software flow control (default off)z--rtsz2set initial RTS line state (possible values: 0, 1))rrrz--dtrz2set initial DTR line state (possible values: 0, 1)z--non-exclusive exclusive store_falsez disable locking for native portsT)destrrrz--askz"ask again for port when open failsz data handlingz-ez--echozenable local echo (default off)z --encodingserial_port_encodingCODECzXset the encoding for the serial port (e.g. hexlify, Latin1, UTF-8), default: %(default)srg)rmetavarrrz-fz--filterrNAMEzadd text transformation)rrrrz--eol)rrrc"|jSr8rr s r r zmain..rr zend of line moderz--rawz)Do no apply any encodings/transformationshotkeysz --exit-charNUMzWUnicode of special character that is used to exit the application, default: %(default)sr#)rrrrz --menu-charz_Unicode code of special character that is used to control miniterm (menu), default: %(default)sr$ diagnosticsz-qz--quietzsuppress non-error messagesz --developzshow Python traceback on errorz.--exit-char can not be the same as --menu-charrzAvailable filters: rc3FK|]\}}dj||yw)z{:<10} = {.__doc__}Nrrs r rzmain..s)'=Aq&,,Q2'=rrr-zport is not givenz"user aborted and port is not given)rrornrr@z--- forcing DTR {} rarbz--- forcing RTS {} zcould not open port {!r}: {} )rr*r+zP--- Miniterm on {p.name} {p.baudrate},{p.bytesize},{p.parity},{p.stopbits} --- r_z6--- Quit: {} | Menu: {} | Help: {} followed by {} --- z --- exit --- )6argparseArgumentParser add_argumentruadd_argument_group parse_args menu_char exit_charerrorrrrr.rrrMrrrrryr&rrrrornrztimeoutrgquietrrf isinstanceSerialrrrmdevelopaskr!rr*rrr-r.r'rYrr]rr=rJ) default_portdefault_baudrate default_rts default_dtrrparsergroupr;r+r4rminiterms r mainr -s  $ $O%QF  7     2 "  % %o 6E ) 9   8    9     A     A     /   1   % %o 6E  h .    # g   j &  $    8   % %i 0E   f    n   % %m 4E  i *    -     D ~~' EF {{ T[[ JJ  3 4 JJ  TYY'="?#8#8#:;'== > JJ  T " HHQK+++  99  S 0 6(N yyLL!45# $33  {{{{  "O?M:*+'xx#zzJJ$$%;%B%Btxx8]g%hi&*hh#xx#zzJJ$$%;%B%Btxx8]g%hi&*hh#/6==9,0NN)  "  YY HHNN  H %T^^4H$T^^4H88HL T667 T667 :: lssoot  RYY H33 4 H33 4 H33 4 F # % &  NN  d :: +, MMO NNO% C   & AB C@%% JJ  =DDTYYPQR S||88   K N    s>Z E%[']9[[]A/]  ] ]"!]"__main__)Ni%NN). __future__rrrIrr9r&serial.tools.list_portsr serial.toolsrrr NameErrorinputchrrrobjectrr8rrjrsrDrLrrrNotImplementedErrorrrrrrrrrrrrLrMrr!r r>r&r r rs'  ,&QR *&*Z77d? !f !RD+RDhWWD+D> CJJ3<<X ZZ  *9*((       $ &y & i &    2c(vc(R aH zFmI FsE E$#E$