pH{$  UVS= u  ߿5 Vtj/S5t@أ,  , (0v6vP)e[^@(#) $Header: inet.c,v 1.10 96/03/16 13:13:54 van Exp $ (LBL)UUum_1t R%]R躍t@]Ð1]US=8ouhS(Sv8o8o]UWVS]SawùLoLoI 10tI10tI0I.NˍAe[^_]UWSEP0P%SW%Be[_]UWSEPv%=tCjjURZà t-0;PO%NjPWAEPWe[_]@(#) $Header: tonetab.c,v 1.2 96/03/16 13:12:54 van Exp $ (LBL)                 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%3))33))33))33))33))33))33))33))33))33))33))33))33))33))33))33))3@(#) $Header: adpcm.c,v 1.2 96/03/16 13:12:45 van Exp $ (LBL)UWVSEUz4duEUJUuE\mFu)E}E}tٍ}~EUЃ}t )Á~} M<$y1X~XdU}t%E$ Eu Fu uM }uEU ufVe[^_]UWVSE}7_X~X dE}}tU}?}Eu$y1X~XЃʅt) ց~} dƊ\o} G} M}9}f7_e[^_]@(#) $Header: lpc.c,v 1.8 96/04/23 00:23:03 van Exp $ (LBL)-DT!@m@q= ףp?HzG?Q|a?@ƿ?@?UVSu1ېPoS $$ZC~$-lU]E48$k]$CZM]E<E]E@DLPTFFF 1ېDDDhDlC ~dže[^]@?@?333333?CC?UTWVS1P0uU\mR$pٝمPoFu 8L4H DP<@ TLTP@C=^11~@~捵1ۍH0)߉19}  A9C~H1DŽDŽ@~مHZ9}-)ل +A9|ٜ9}#)،؄ٜA9|Ƀ@m$*rٝD$DžDŽDŽDŽF~Dž ٕٝ ٜٜ@~Vԉ/?1ۍH0)މ19}  A9C!~1لHEuى A ~؍ل*Dx،*LٝمS$-ٝمɉˍ R $Q$$)Q $ٝمٝمصHÈ@r'=ȁu>È@s, ٝȁB#Džȁ҉ȁ1Po ٜ`@=~㍵`1ۍ4)߉19}  A9C ~41DŽDŽ@ ~م4Z9}-)ل +A9|ٜ9}#)،؄ٜA9|Ƀ@ m$mٝمٕمٽ ٭<$ZY٭u fٽ ٭<$ZY٭V1 ٽ ٭$Z٭} T8@ ~ؿPoqP~pP󥍥[^_]p@`@n@T@d@A@UHWVS}M uT!P<$ݝAP<$ݝEE1\!UD P<$C ~݅E@td!l!$kܽݝFDTPTC ~E@tX݅E@tDt!ݝ݅fݝDݨdݜC ~QDžDžDžDžDŽDŽC ~D@u dž1ېD@u6۽۽"|!P<$ۭۭQu6ٽ ٭ۖ٭H VPB`݄P܄ݜP\hHVh!ٽ ٭$X٭%\oG܅܅C݅݅^DݨTݬDTC ~ꍥ[^_]@(#) $Header: tkStripchart.c,v 1.7 96/03/16 13:13:59 van Exp $ (LBL)Widthwidth-widthUserbitsuserbits-userbitsUpup-upTitletitle-titleTickcolor-tickcolorTextcolor-textcolor1Stripwidthstripwidth-stripwidthStripreliefstriprelief-stripreliefStripcolor-stripcolorStripborderwidthstripborderwidth-stripborderwidthHtickshticks-hticksAutoscaleautoscale-autoscaletrueShowticksshowticks-showticksflatReliefrelief-relief11Numticksnumticks-numticks40Numstripsnumstrips-numstrips0Minmin-min1000Maxmax-max500Intervalinterval-interval80Heightheight-heightfalseGuaranteedrawingguaranteedrawing-guaranteedrawing*-Helvetica-Bold-R-Normal-*-120-*Fontfont-fontstripcolor-fgDatadata-dataCursorcursor-cursorRescaleCommandrescale_command-rescale_commandCommandcommand-command3BorderWidth-borderwidth-bgborderWidth-bd#ffe4c4background-background#b0b0b0tickcolor-alttickcolortextcolor-alttextcolorWhiteForegroundaltstripcolor-altstripcolorBlack#b03060Backgroundaltbackground-altbackground pathName ?options?"wrong # args: should be "StripchartUWVSU} }jh(MPh(WojMAPRW9ƃth)V`DhjpÉ3{ShD3hPN jSh*@,PWO jEPEPSW(u@,1P:e[^_] option ?arg arg ...?"configureget get"%gset set value"startstopresetswapcoloursreplacecolours": must be configure, get, set, reset, start or stopbad option "U WVS]uE}$jh)Ph(M QmVUS0ЍxWh*Rua}u jj}u*jCPVh́PM QVE:jCPEPVM QEWh*CPq uJ}tjh *Ph(V4F<\S\Sh&*M PUWh)*CP uj}tjh-*Ph(pEPCPM QwQ tE_EUPRV2 =Wh9*CP葢 u*džVWh?*CPQ udžWhD*CP! u*F4F`j>V WhJ*CP uV bWhV*CP象 uCPEPV 'jhe*CPh*M QGkEVTEe[^_]US]ǃtSCP҃$St78t2PCP~O u!tSh-P ]]US]t Pq C t P葥t P~Ct Pnt P[t Pp t P] t PJ CV1e[^_]UVS]1ɋt8tAClpHpLS҃C,PC0C(RPCPP%e[^]U(WVSuM~}1ۋt8tCNlMIH}OLMǃ>MtAPP?EPEPPP0ӉHPRMQUy}}]ڋEMI@M)ȃ9}E))؉Љ]jEPE}@)ljPMQQ}GPP9?0U؉HPRMA>EPSFtP}GPPv8t5$dž9^4|OSV!C9^4}SuI@,PCPG tSh$1y h4.SNZuHCR )‰Й{(9C0t0C0SU VSuE E 5E$j h4۽۽ۭ}U Um$XmP $ۭ$jh4۽nۭFH D@uF@E@twV@VHtSF8HP$u$$$Rh5SK$SFP*G ظ 1[^]UWVS}w4E9w0tG؋]SWe[^_]UUt?t6u-M zdtRZ]ÐRh$1 ]UEP H PHPpHpPxHxjjjP@PR]UWVS]} uC PPPCPwCPȚPPCP[ CpPP&CxPPjVWSCPe[^_]UWVS}OlqHqLE HG(OL1ҋt;tB։|GDO(GHݝG@ݝ} E 9G0jO,QVPQvVP7݅݅D@uDžA݅E OtBЉ|f|ffXu w,XG8H||XfXfKxfL0xE M 9O86w8VPO|QvVP;FO$Qw VPQVP|WIQVPL[^_]UWVSu>FlPHPLF(FE1ɋt8tAыFTN(])ˋF0HN,RSQPR]SjjWE PGPPP5e[^_]UE@@#Eg@@ܺ@ vT2]UWVSu}Fу?ЉF9sFF@)9r>SU RDPFPVE PV@C?9r11ۉ)PE PDPe[^_]UVSu] jCPEPC? 7w8x)‰PhLSjEPSjSV$jXjSye[^]UXWVSE Urz}R Uj@P}}WM!#E Mxj!#E MċUV ډ!ى! Mȋ}9p $׉!! M̍1ν!! MЍ|!! Mԍ*ƇG ډ!ى! M؍9F0׉!! M܍1F!! Mؘi!! M䍔D ډ!ى! M荼9[׉!! M썴1\!! M"k!! Mq ډU!҉U! E8CyU׉}!׉! E0!Iu!M#M Ečb%E!؉! E؍@@ ډ!! M}9QZ^&׉!ى! M1Ƕ!! Mԍ]/!ى! M荔SD ډ!! M9׉!ى! MЍ1!! M䍜!!ى! M7 ډ!! M̍9 ׉!ى! M1ZE!! M!ى! Mȍ ډ!! M܍9og׉!ى! M1L*11EԍB911Eq ډ11E썼8"am׉11E0 811EčD꾤11EЍK ډ11E܍8`K׉11E荴0p11E~(11E' ډ11E̍80׉11E؍011E䍜911E ډ11E8|׉11Eȍ0eV 1ED") 1E܍*C ډ 1E8#׉ 1Eԍ09 1EY[e 1E̍ ډ 1E荼8}׉ 1Eč0] 1EO~o 1E, ډ 1E؍8C׉ 1E0N 1EЍ~S 1E썔5: ډU 1Eȍ8*׉} 1E䍴0ӆUrz}z j@jURe[^_]UVS]u19s+M DADAD9r؍e[^]UWVSu 119Mv21D D ŠD ‹}C9MwЍe[^_]UVSu] M19s 2B9re[^]US]M U19s @9r]]UE]UVSÉэ J ʍ J JS))ȅe[^]@(#) $Header: vat-gsm.c,v 1.4 96/03/16 13:12:54 van Exp $ (LBL)UWVS]f0f]u4f8f]Eu fE\mffFu f+UfEf]ff)ljЉ ))@Ӊ ))ЉEyA| ZEH)=w);0 }Eȿ=wDž}@u%@E=wEUBЍ@)ÉfEufuMY]֘=v~fMf]uf04]8e[^_]UWVSE }$HSP]SuVS]SSV]S1$Dž 6+8P+@PWh$SS]S D+P+(P+0Ph]So1Ƀ0MO=v~ Ћ$fKA'~ƒP$P PF2}@<fEf$ Ћ]CUE$?ˆCUfEf$ˆCUE$fEf$ˆCUE$ŠE$ˆC@f8f$ˆC8($f0f$ˆC0E$ŠE$fEf$ˆCUE$ŠE$ˆCUE$fEf$ˆCUE$ŠE$fEf$ˆCUE$ŠE$ˆCBf:f$ˆC:*$f2f$ˆC2E$ŠE$fEf$ˆCUE$ŠE$ˆCUE$fEf$ˆCUE$ŠE$fEf$ˆCUE$ŠE$ˆCDff$ˆC>.$f6f$ˆC6E$ŠE$fEf$ˆCUE$ŠE$ˆCUE$fEf$ˆC]UE$ŠE$fEf$ˆUE$ŠE$ˆS [^_]UWVS} ]ffҍBЍ@=v~ ȉ‹]]]C] =v\~T%\o]Nb]fe[^_]UxWVS]M< _fff C%f f f?f"Cff$fff&C%f f&ff(fff*C%f f*ff, ff.CfffffC%f ffffffC%f ffffffffC%f fff ffCfffffffC%f ffffffffC%f fff ffCƒ Љ% ‰C%f  ‰ƒ Љ> ЉC % ЉfffffffC%f fff ffCfffffffC%f ffffffffC%f fff ffCfffffC%f ffffffC%f ffffffffC%f fff ffCfffffffC%f ffffffffC%f fff ffCƒ Љ% ‰C%f  ‰ƒ Љ> ЉC % Љfffffff C%f f ff ffCfffffffC%f ffffffffC%f fffff1ۍM1QW]P]PMQWQ]P]P}WfDž(򋍌fOfUpA'~ԃ(C`0SpP PMQ^} WSMQ|[^_]US]hjS\fǃp(]]US]hjS\fǃp(]]sessionaudio/rtpvideo/rtpUE }t)|~u]Ð1]UE wE$HXhXhXxXhXxXhXxXhX]Ð1]U=tdH Q@PADЃjUE@H QHPALЉ]UUBH RQ8PA<Љ]UUBH RQ0PA4Љ]@?UVS]SSCrC rC`P]Cdhs[hClCpP@Cths[xC|CtPsV9ǃ8sǃǃǃǃǃǃǃǃǃǃǃ`@ǃdhJ7݃܋UYEu ] EݛP$uu$d  YE}U Um$XmPVo؍e[^]UVS]u CrC rP6ǃ8sjPCpCthsjPC`CdhsjPCQC PjCPVSe[^]UVS] jEPuu7\މe[^]Bad-RTP-versionBad-RTPv1-optionsBad-Payload-FormatBad-RTP-ExtensionRuntsCrypt-Bad-LengthCrypt-Bad-P-BitCrypt-Ctrl-Bad-LengthCrypt-Ctrl-Bad-P-BitUVSuU Ph[RO'‹Ph[R;'‹Ph[R''ƒ$Ph[R'‹Ph[R&ƒFlX,t(CPh[R&ƒ CPh \R&ƒ F|t,X,t%CPh\R&ƒ CPh3\R&JЍe[^]activelocal-addr-heuristicstatsnb%unfnpnsnameemailrandom-srciddata-netctrl-netmax-bandwidthconfiddata-bandwidthmtuloopback @?UWVSEU} Qp1]uRh8p8]uP=PURupM]u,UR]SܛU1,pS]u,][<PhV]UR"ܛ]pY]u UB8Ep\]tp_]uE}vUB@} Vpb]u@Pj$pg]u@PjRv#1pm] u<@PPURPhV]]S!ܛ1pz] u<@PƋU`UR{jF P]SzUrl1qp] u<@PƋ]pSzjF PSzUr|1'p]u<@Ps4]]]ݛ1p]u@P U1p]u@P_ 1}p]u@P/ ]C1Gp] u@P UB\1P] SURne[^_]USE] X$PlJ PA0RA4Ћ]]UWVSu EMt&0KEF؈FSRVrމe[^_]UWVS}]hʁU fCBu SjVWxƃ4t)8t"EEP@t,w tDt t&4Sj-SURSj SQVWƃ+} )߉fH%P U fBKx FKye[^_]UEjPb]UEjPB]Mb??@UUUUUU?@?UHWVS=}}}}W}WEjURUMUM}W8O]Cۆu'][XRhԆ]Cކu]STRhԆ]Cu']S$R;PuV]Cu]SRPhԆ[]Cu]S RPhԆ+]Cu']RhuV_ܛ2]C uW]S0U=ܛ:URPWj W/DžuF uW]S8U=ܛ:UR?PWj Wd/DžOGuF u']uFu]S uF u]ǃuF) uG]S0K4~ȍ ȍ  ) U4]C6]Rh3R8 ܛ uF;uN]SRuR]SOܛuF6u']SR[uF]CS:u]CR蚤uFuK]C;u2SRS RP]S uVR]Se[^_]grayout %sembolden %sUEU 9tAt%Phhܛ迨]ÐPh'hܛ蚨]UE@P@T@X@\@`@d@h@l@0@4@8@<@@@D]srctabUS]hS讟C xCCCCC C$C(hjC,P%؋]]localgen-initgen-nextkeep-sitessite-drop-timedeletecreate-localUWVSE Uu|rzu]Jr u ]C3r (]K(tJܛAC(8r u#BP]C1ruBP]C ǐru|BPStP]SR댃u[r uGjjBPU'+VSƋUB P]PV]SC$ܛ1RP]Sşe[^_]US] C 11,U9t P9Xu@]]US]M URQQh8PC$PS@S$RSv jUR8UMUMC$P8H<]]UVS]u CFsV 11%T,Vt,Ce[^]USE]  11ځD,t9Xt@򐐐1]]UWVS}u VWÃu>9uuURVWà u%URURVh8pPSW؍e[^_]U WVSu f}VMQ&ÃMQVMQ à u%MQVVh8PiSMQ׉SHsL)M=vOSLfw~ CH=HCHCPCTCXC`C\ }~SL?f9C/M9K$tS{@u9s0jEPUt )s8t )MK$SjS0{Pu{Xu׉+CL?SHsL)M=vNSLfw~ CH<HCHCPCTCXC`C\ }~SL?f9CtfCCh1 ؍e[^_]UWVS}u _M9K$u9{@uFjEP苾UC0t )ȃ~C8t)‰Ѓ[벐tPVU^0щMt FCƐFe[^_]UUE B xPR ]Uxjh]Uh]$0Ď/0D/0$0/`UWVSMfu yL։)=vLQLfw~ AH8HAHAPATAXA`A\ ~QL?f9AtfA1Ahe[^_]UMfE ƒ?f9QuAh]ÐfQ1]UE@$]UE@]UE@]UE@]U]UEU ]UEU P|]UEU Px]UEU Pt]UEU Pp]UEU Pl]UUE BH]UUE Bd]UUE B`]UEU P\]UEU PP]UEU PT]UEU PX]UE]UE@|]UE@x]UE@t]UE@p]UE@h]UE@l]UE@d]UE@`]UE@L]UUBH% BL]UEPL+PHЉ]UE@\]UE@P]UE@T]UE@X]UE]UUE ]UE]UUE ]UE]UUE ]UUE B ]UE@ ]UUE B]UE@]UUE B$]UE@$]UUE ]UE@(]UE@,]UE@]UE0]UE8]UUE B,]UUE B(]USMU ZA8Y<]]UEuP]USMU ZA0Y4]]USMU ZA@YD]]UE@]UUE B]UE@]UE@]UVSu] jV-F Ș^Fe[^]US]jSCPXbC,P;C(C0C @C4C8C1H#~ ttW(B@|XuzPt}u u ~(ttpG,@ E+G8=v2O(q uڋu F9v+V)Ћu PuF8PF<ЃW(J u FPA8RA<Ћuw8Gh}uG(H Q0PA4ЉESuVjG,Pbe[^_]US]SCTCC,C$<C jEP/EC@ECDCEjSF P  }$h:F PtiF FF PhdEhWEjEPj jF P! }F PiF FF -jPVjjj{F}hHjbfEhȘEj]SFP}h:jbf}h芘EjSFPw{}hXjcbEjEPj jFP!}hi`j)bhEjEPj jFP}h'ja^Fe[^_]UVS]u ClC | PgC| P}gVSe[^]GroupIPC sendUEU HfPPfP@ U@|jRQPO} hb]UWVS]u }WC Pz0PVSe[^_]UMU AQ]GroupIPC: recvUWVS]jhsVC PXǃ}hkx[C9CtRCU[t8MKt!SWFPFPFPBPB Ѓϐe[^_]`UE ]UE@]UVS]u C;| SStSʶe[^]UEM UPhpRjQ PN ]US]|jP˅ PUO ]]UUE JPARAЉ]`usage: vat [-aAcdEjJkLMnrRsSv] [-C conf] [-D dump] [-f format] [-F device] [-g geometry] [-d display] [-I chan] [-K key] [-N name] [-K key ] [-t ttl] [-u script] [-U socket] [-X res=val] dest/port[/fmt/ttl] UhhHlj]usageUjjj) 搐U{UhjYhj~YhjoYhj`Yadioshavefont01gethostnameversionU}u1hERctEP‰UDPhEPC hyhEPeC iDPhEPHC LhhEP-C 1hhEPC hhaEPB h.hEPB DPhEPB DPhEPB D8/~RD89HhhEPqB hhEP[B DPh EPDB DPhEP(B /DP}EEPDPEPA XZ9E~f}~`ZU EE+Z~7ZU BRhhHl; jO>h@EPNBEEuhPhHljJOEPh@EP.A hsEPM?}h|EP7?m11]Ujhܞjh̞Vjh?jhjhUhh>hh̞hܞT0/0x/0$/d0/0/UWVS]u }hPO1e[^_US]h<S@C 4]UVSu] F 4SV@e[^U WVS]u }%EUUEPEEPEPhEPL1e[^_US]h0S?C \]UVSu] F \SV+@e[^UWVS]u }yEUUth,EPfEPEGP9EEPEPEP PV' E}t.,PEP1e[^_US]h#S>C ]UVSu] F SV3?e[^UWVS]u }Xi1e[^_US]hS>C ]UVSu] F SV>e[^UWVS]u }1e[^_US]hS>C ]UVSu] F SV[>e[^UEU PUUB UUB UWVS]u }uuWVP) e[^_UEU UU UU Uܛ UMU Ȱu#l_u 1 UVSu] tVg!څuk#T4u 1 e[^@(#) $Header: main.cc,v 1.48 96/05/03 06:27:20 van Exp $ (LBL)US]jS<C @CCfCfCCC C$C(C,؋]]UUE B @PR%<]addrinterfaceportttlismulticast0cryptUWVSU E]Ep#tPp( t]C,1PR]S<e[^_]fcntl: F_SETFLUS]jjS PjSuhMjF]]US]=uSCSP\E]]sendUWVS}u ]EjSVP`|}G0=t=3t*AujSVG$P*|h6e[^_]UVSu] N,tQ EPSB(PB,ЉÃ V F$PEPSB@PBDЍe[^]UWVS11MA 9}YTF9|9}RUU=1M9q ~$A\SPWUoB FUؐЍe[^_]sendmsgUVS]u {,tVYS PPB(PB,[jVC$P }G0=t=3t*AujVC$PhTe[^]recvfromUWVSu] U}MEEPEPjRSQ\ƒ}&=0#t hS.E~(t9FufFf9Eu1Ѝe[^_]UWVS]u}{,tX95} VS C PWVPBHPBLЋS,J MM QPPMA0RA4 S C PWVM QBHPBLЍe[^_]U]8X/hUE@,]UE@(]UE@]UE@]UE@]UE@]UE@$]UE@ ]networkipcloseaddrinterfaceport%dttlismulticast10loopbackopenU WVSU} :r#u]S1ܛEr)u]C$r. u]CPP]SF[뗐r8u]CP?w%"r@u]CPh=]Sc5rD (]CPh%R=uPܛ} uZrT BPrEjEPj j]C$P`}C(} r]urBPUƋUB PDr%Pv%EUBP%rP]SV]SJ}ܛR ܛPR] S]Se[^_]UWVSuUEM NfVFPWQVF$|D]SVSWM QVuF |EFfEfFF01F$PEe[^_]US]C$|PDC PDC C$1]]getsocknameUVS]u jjV謸FEEPVC$P7}hFfFe[^]US]j<+C0~"S0C$P=DCPCPCPSC$]]socketSO_REUSEADDRSO_REUSEPORTbindIP_ADD_MEMBERSHIPSO_RCVBUFU$WVS} fUfUjjjmVà }h<j=SEjuVjhSp} hCEjVhhSB}hPjJ=jjuVEfUfUW蝋%=~}jVSb }+EjVSK }h] j<}EjEPj jS薹}dhbj<UBEjVS޺ }h]jf<fE}jVSJU E@juVhhS}+EjVhhS} ht,؍e[^_]connectIP_MULTICAST_TTLSO_SNDBUFUWVSf}jjjDTƃ }h<j;Vjjj]SQEf}U UjSVRT}huj>;U R裉%=EjEPj jV}}u UB(} }| EEEEjEPj jV茷}hj:E@j]ShhVS}+EjShhV2} hqe[^_]Uhhj2h]h/hUSE h PUt1j4蝐ÃSC x؋]]UUE B xPR]UE@]UWVSu} FKxT VARAЃKytV5e[^_]UUM ~*L]USM] 19Yt&9}&B9\uDB9 ]]UVSuKxT VARAЃKye[^]UE]UEE tP<]U]U]tT$siteFontvat: couldn't find font: %s screenfixedvat: couldn't find screen or fixed font blackforegroundwhitebackgroundhighlightColorgraydisabledColorUWVS}] ujW)*G GGGGG G$G(G,G0G4GHGLGP_TwXܛ=;hhܛ)SGTPܛPuoShhHlhGTPܛPwu?h!GTPܛPW uh'hHllj5hPhVV(PGXP3hahgV^(PGXPy3hahrV<(PGXPW3$hhV(PGXP23jjjGXP4؛BLG8BHG tot+e PPE)P)PMQ3MQH}<Л PPE)P)PWMQM Q~MYDPPM)ىMQ)WMQMQM QxMyLt5MQV]SWMQMQM Q*vSVMQWMQMQM Qve[^_]UWVSuN4MFTE=VHțF0HPQjjPWMQ&}SWMQVn,FPFPF$PF PSWMQȟV0JRF4HPRjțPWMQ_u8F,PF(PF0PF4Pjj؛PFT@PWMQhe[^_]UWVS]u CP蟇0ЍPSP7CVPISe[^_]UWVS]u CPO0PCVPIe[^_]UEH<H8ȍPЃ‰Љ]U`WVSuM UE}PRQEP]SFXP,.SEPWFTPke[^_]UWVSuE U}MN4~0F(V,N0N F0+F8F$M9 | 9=3})!M =FTt PS2FTPRWMQ@PSuqțtIPSy̛PSmЛPSaԛPSU PSFPS:XFXxPPPSVțPPPSVk̛(PPPSVJЛPPPSV,ԛ(PPPSVPPPPSVțPPPSV̛(PPPSVЛPPPSVzԛ(PPPSV^PPPSVE‰ěe[^_]UEx`t@d(P]US]S BPBS]]U WVS]ChC4ECPCTC{LCHCHMCHTЙ{HƉs@C@K@KHKDSЙ{@E؉E1K@MEE9E}`M}$KHM1uM}C@Hus+uMC0tKLQVWEPR6{LE룐MKP{Te[^_]UE@@@D@P@T]UWVS]u K49KD})u V>CLChGKș{@EC@HE)MSLREPSTRCPPVaSLSTCl{`tCdC(Pe[^_]UEH Q(PA,Љ]UWVSuFl~4^~@~QNTF)PFP)RQ@PFXPVBPPVvFHFLN)Ã~8SFP)PVTF)PSRjFXPVBPP vFEVRU1ې9}$F0 t QdC搐F@E~CVDU9~9I^ؙ}ȋE)FLVLVHRQ)RQv\uVEPURme[^_]siteboxVatUWVSuE jjjhDPV:%F(PF,F F8h/&‰V0N8PjR觢F4F<F@FDFLFHF`FdhVhܛUhghܛDSWjV'F\ SSjV'FXe[^_]UWVSuVFPj\3P2NjV4F0U RPnuO4ؐ^uǐ1e[^_]UVSEU pt6|4©tP:jukD5uFŐ[t6|4©tPiukD5uCŐSVBe[^]US]C4S0h$jPRICd]]US]{dtSCh{htC PR@SCl{ltC P(R@,Ћ]]createsitessortremovekeep-sortedwhichover-buttonUWVS} EpRu6UR}V]Sq6uܛ01UrYu)][4ShPlܛ뭐Ep_UBd(R} ]sdu?CPUR2tA jPR@ Ѓ]ChGEpk uPRV]K`Cd(S} 6EpwuoPRVVƋ][ SHV]{LNjKș{@E}sHu}b9{4Y[0HHܛ]4/ :0/UE PjpJyP ]UVSu ]MU E PPE)PE)PQSV.ne[^]UWU0HPRP}]UE@4]UVS]u C,C jC(PpC ;VS;e[^]UE@]UE@]confbusUWVS}u jW|j_S蝻GG GG VhwP GSPe[^_]UVS]u CC KtAjPR@ ЃC PwVSIe[^]focus %s%s %s {%s}UWVS}]~jMy tauPPhWngs<>u<19};€t kD6t!C䐐WMPA Ph hܛe[^_]handlersendUWVS]U Eu|pu8pC Pv0PnvC VP091@pu@PjCP 1PRSe[^_]Uh4h> ]$0/UE PPPj$uPC]audioUWVSu] V蚂F(0F0F XƆSW70@F8PuV8V诎e[^_]US]{<| S SS]]vat: socketvat: audio connectUS]{<|RSjjj5‰S< }hnj7PPR6 }50=tt h,CwS0e[^]U,WVSu}WU O9r)ʋ}ӋE9)щ)UG0]ԉu\E$؉E}9}}}ԋ7%}8 Ȋ\o%8 \o ‰%8 \o ‰%8 \o ‹}ԉEE3u]ԉu$؉E쐋}9}}}ԋ7u% Њ\o% \o % \o % \o }ԉEE(u}}G0]ԉu\EE$؉E}9}}}ԋ7%}8 Ȋ\o%8 \o ‰%8 \o ‰%8 \o ‹}ԉEE3]ԉu܋E$؉E؋}9}}܋}ԋ7u% Њ\o% \o % \o % \o }ԉEE(e[^_]UE@(]UVS]u C(;t SctSie[^]US]E ShP(P ]]UEHQPAЉ]US]t P9 ]].AUjEP*(ME]'`UUE PR4]@@UU)} }M Mm$XmPR]UE@*]UVS]u C*;t SstS2he[^]US];uSh)% ]]UEHQPAЉ]US];tSh)! ]]h)`UE@@ PP]UEPF P]UEU ܛ]UWVS]u 0ҋ{)9s$SVWl)WSQ{+BPfVWB)WS'Wfe[^_]tkerror "%s: %s"UWVSu] SP[ tJ0~ ҉ЍDNPfSF Ph+W9VWP[ W.fe[^_]bailing in Tcl::eval UWVSu^0؉F9rh+hHl"ISV)^e[^_]%s: "%s": %s UUM PQB Ph,hHlj%s.%sUWVS]u }C ©tPHQk4CVC @Phd,C@PTj=WCPCPe[^_]UWVS]u }C ©tPPk4CVC @Phd,C@PTj)WCPCPe[^_]UVS]u C ©tPlPk4CC @PC@P&CPVCPft8u1e[^]_o%dU VSuE F 5FuPh-]SS؃ PVF5e[^]UVS]u C 5ܛt PRL 9t P9Xu@CP2ctS!ce[^]UVSܛt<jSh/PPJ S B PB$Ѓ[ϐe[^]U]UWVS]u tܛtRPL Pwb0PbVP$ ܛt#jSh/PRI S B PB$Ѝe[^_]USUMEZ PQCRCЋ]]%s: "%s" (%s): no such method (%s)requires additional argsUWVSPh/SQ0Ѝ\u 8_u"xouuVtPRh/SEQPh/S4Q 0Ѝ\} ~uFPh/SQh/SPܛe[^_]U]UStC PR@Ѓ[u]]UVSutVPKPt[u؍e[^]UWVS]u CP?`0P_CVP"e[^_]deletedelete: bad argsdelete: no such objectUE} tܛ1]Ë@P'uܛ1]ÐA jPR@ 1]newcreate: bad argsUE Uu11tܛO2]ÐBPBPCt ܛ1]UUE Bp5BЉ]%s/%sUPWVS5}txFPMQc#uTFM QPR@ ЉÃt8} t"M QMQh2WoNWMQS6됐1e[^_]UME UA A ȉ]UWVS} t3C9~1!9uPhܛ[u͉4e[^_]US1ېStC𐐐]]UUE B 5PR]UUE B H5PR]U 5jhH5jh~]UhܛSh1hH5hK2h 5]T40d2/t401/`D.0$0/US]hK2SC 5؋]]US]h1SC H5؋]]UE]US]E PUEPE PCPd_ Sw]US]E HMEPE PCP$_ S]winfo depth .1UWVS]}uU RSC ;CCC C$jU RPܛP+Cu;URP6utVWCP E Sh:PCPCP/h6hܛܛ06ƒS؍e[^_]@USU7M }E Em$[m~}1ۋu"jj]`PRBPP<]]vat: cannot lookup color: %s (trying %s) vat: cannot lookup color: %s UWVS}u ]VPGPܛP蟮uDSVh&8hHlgSGPܛPwuShP8hHl@je[^_]A??UWVSu M]UFDFtF tF }t }~< @}txttCSSP$8]E9Eu79Eu* $WF0F ؍e[^_]blackwhiteU`WVSuE}th9PVN 1ۅth:WV. 1PSU REP]SVSEPFPe[^_]U]U]UWVS]} ދ t-t;tFF WP@R@DЃF$$up~ ujF VV{$tT:W 9SuG$9Ct:SG$CS B8PB8=:DF0</=>8=:CF0</=>8=:`US]h/DSC D؋]]UWVS]}uE U$RPC+E)PMQVWM Q9@e[^_]UUE B ;PR]UUE B ;PR]UUE B ;PRe]UWVSu]^SJSxJSpJËURU RRWV URU RURSVSWV( WJS}Je[^_]UWVSuvPIË}PIE1҃u9V~}DB9Wu 6}uu 61Eu}9w19,u?}u D ‹E)Ƌ} B9~ u9) l}B9~ɋu\19}uD} B9~u}DuL\؋]EEASH}WHe[^_]UWVSE u1DA}9O1ɉË}9O~<9})ȋ}׋} B9|V4$AȐe[^_]US]CLJx؋]]UE@LJxE tPH]U WVS]jEP] M ɋUu4V+uEEȾd1NjM ȍe[^_]UEHQPAЉ]II0JUE]Ux]US]jS9CP,CQC PCC8C<C@CDCHCLCPCTCXC\ jjCPMiC(؋]]UWVS} 5t j09F^È%P$fF|P$fFf|W$F@F^F,e[^_]USMU EPRQ[Ë t hE‰S,S ؋]]UWVS} }} ww}wMbP?UVS]u {PulVS]jEPlNMEE[HVShNM}U Um$XmPCPCP {Tt CX0sTsXe[^]ư>MbP?UVSujEPTOME]^TtaFTSVFH^HSVEnH\O}E Em$Zm~RFPAFPe[^]UVSu~PtFPFPFFTtPV؃쐐FTe[^]UVS]u |C(PFPRS\C VP(R@,VSrVS e[^]UE P,t ]Q0$0/`QlOư>UjEP QME]UE@]U]UfEf|]UVS]u CQC PjCP0VS}e[^]no clientdata for rate varư>-q=UWVS]u߅uQd 4VMQMQM QTuM $PtjxR۽h Sۭh~x)ы|+SQR $Q$È@t+SR$u*KQEu xW|WtO$WR]Sp.VSMQMQM QTƀt SJ>1\[^_]%gusage: rate_variable varname filter_constrate_variable: invalid filter constantUWVSE }u w ,tܛSSGP@]]t]Eu!ܛSkj,=E[CCCVCPShRjaGPܛPUWƃ tS<e[^_]UUE B `UPR=]U`Ujh]rate_variableUh-Uh`U]T0S/US]E PS3C `U؋]]encoderpcmUS]jSC WCC؋]]transmitterUWVS]U Eu,pU u@PC1PRSe[^_]UWVS}] 9_th1UډWjSGPf p@ UP UPPGPe[^_]UhUh8@W]DWW0V/dVUE hUP'uj):P[]Ð1]UUE B WPR]encoderlpcUS]SC X~8[}9E~@~  M)9~[}[C…}P9~9M~MM}tE}9E}EE+EE}|%u}98|u9}}u}싆9~ًU)ʅ~VtB~<[}9E~@~  M)9~[}[C…}P9~9M~MME+Eȋu_}uu+uGw}E+E+yډ)ыuu+u}})׉Ћueu~Ee[^_]nullUh\hh^pdh\htB|d]dee0^/e^eg0^/`^]0^/`^USE hMdPt1!h+ÃSkC d؋]]U]UUE B dPR]USE h\Pt1!h~+ÃSC d؋]]USMU] T]]UUM D]UWVSu] }HQDPAPSVY|WURPPTe[^_]UE1ҋt @(x<|BЉ]UUE B dPR]UE]decoderlpcUS]SC hhjPL؋]]U WVS]M1Ut @(x<|FAbDžى9s<P{fEPSV萹}ƃ9wōUHQDPAP} WUR|WSPUP>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^________________________________````````````````aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccddddddddddddddddeeeeeeeeeeeeeeeeffffffffffffffffgggggggggggggggghhhhhhhhhhhhhhhhiiiiiiiiiiiiiiiijjjjjjjjjjjjjjjjkkkkkkkkkkkkkkkkllllllllllllllllmmmmmmmmmmmmmmmmnnnnnnnnnnnnnnnnooooooooooooooooppppppppqqqqqqqqrrrrrrrrssssssssttttttttuuuuuuuuvvvvvvvvwwwwwwwwxxxxxxxxyyyyyyyyzzzzzzzz{{{{{{{{||||||||}}}}}}}}~~~~~~~~  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~M>6/+'# M>6/+'# M>6/+'# M>6/+'# M>6/+'# M>6/+'# M>6/+'# M>6/+'# M>6/+'#!  M>6/+'%#!  M>6/+)'%#!  M>6/-+)'%#!  M>62/-+)'%#!  M>:62/-+)'%#! ME>:62/-+)'%#! [ME>:62/-+)'%#! [ME>:62/-+)'%#!  [ME>:62/-+)'%#"!  [ME>:62/-+)'%$#"!  [ME>:62/-+)'&%$#"!  [ME>:62/-+)('&%$#"!  [ME>:62/-+*)('&%$#"!  [ME>:62/-,+*)('&%$#"!  [ME>:62/.-,+*)('&%$#"!  [ME>:620/.-,+*)('&%$#"!  [ME>:6420/.-,+*)('&%$#""!!  [ME>:86420/.-,+*)('&%$$##""!!  E><:86420/.-,+*)('&&%%$$##""!!  [MEA><:86420/.-,+*)((''&&%%$$##""!!!  [MIEA><:86420/.-,+**))((''&&%%$$###""""!!!!  [SMIEA><:86420/.-,,++**))((''&&%%%$$$$####""""!!!!!!  g[SMIEA><:86420/..--,,++**))(('''&&&&%%%%$$$$######""""""""!!!!!!!!!!!!   g[SMIEA><:86420//..--,,++**))(((''''&&&&%%%%$$$$$$########""""""""""""!!!!!!!!!!!!!!!!!!!!!!!!!  !!!!!!!!!!!!!!!!!!!!!!!!g[SMIEA><:864210//..--,,++**)))((((''''&&&&%%%%%%$$$$$$$$############"""""""""""""""""""""""""  !!!!!!!!!!!!""""""""""""""""""""""""g[SMIEA><:8643210//..--,,++***))))((((''''&&&&&&%%%%%%%%$$$$$$$$$$$$#########################  !!!!!!!!""""""""""""########################g[SMIEA><:86543210//..--,,+++****))))((((''''''&&&&&&&&%%%%%%%%%%%%$$$$$$$$$$$$$$$$$$$$$$$$$  !!!!!!""""""""############$$$$$$$$$$$$$$$$$$$$$$$$g[SMIEA><:876543210//..--,,,++++****))))((((((''''''''&&&&&&&&&&&&%%%%%%%%%%%%%%%%%%%%%%%%%  !!!!""""""########$$$$$$$$$$$$%%%%%%%%%%%%%%%%%%%%%%%%g[SMIEA><:9876543210//..---,,,,++++****))))))((((((((''''''''''''&&&&&&&&&&&&&&&&&&&&&&&&&  !!!!""""######$$$$$$$$%%%%%%%%%%%%&&&&&&&&&&&&&&&&&&&&&&&&g[SMIEA><;:9876543210//...----,,,,++++******))))))))(((((((((((('''''''''''''''''''''''''  !!!!""""####$$$$$$%%%%%%%%&&&&&&&&&&&&''''''''''''''''''''''''g[SMIEA>=<;:9876543210///....----,,,,++++++********))))))))))))(((((((((((((((((((((((((  !!!""""####$$$$%%%%%%&&&&&&&&''''''''''''((((((((((((((((((((((((g[SMIEA?>=<;:98765432100////....----,,,,,,++++++++************)))))))))))))))))))))))))  !!"""####$$$$%%%%&&&&&&''''''''(((((((((((())))))))))))))))))))))))g[SMIECA?>=<;:9876543221100////....------,,,,,,,,++++++++++++*************************  !!""###$$$$%%%%&&&&''''''(((((((())))))))))))************************g[SMIGECA?>=<;:987654433221100////......--------,,,,,,,,,,,,+++++++++++++++++++++++++  !!""##$$$%%%%&&&&''''(((((())))))))************++++++++++++++++++++++++g[SMKIGECA?>=<;:98766554433221100//////........------------,,,,,,,,,,,,,,,,,,,,,,,,,  !!""##$$%%%&&&&''''(((())))))********++++++++++++,,,,,,,,,,,,,,,,,,,,,,,,g[SOMKIGECA?>=<;:988776655443322110000////////............-------------------------  !!""##$$%%&&&''''(((())))******++++++++,,,,,,,,,,,,------------------------g[WSOMKIGECA?>=<;::99887766554433222211110000////////////.........................  !!""##$$%%&&'''(((())))****++++++,,,,,,,,------------........................g_[WSOMKIGECA?>=<<;;::9988776655444433332222111100000000/////////////////////////  !!""##$$%%&&''((())))****++++,,,,,,--------............////////////////////////og_[WSOMKIGECA?>>==<<;;::9988776666555544443333222222221111111100000000000000000  !!""##$$%%&&''(())))****++++,,,,--------........////////////////0000000000000000og_[WSOMKIGECA??>>==<<;;::99887777666655554444333333332222222211111111111111111  !""##$$%%&&''(()))****++++,,,,------........////////////000000001111111111111111og_[WSOMKIGECA@??>>==<<;;::998888777766665555444444443333333322222222222222222  !""##$$%%&&''(())****++++,,,,----........////////00000000111111112222222222222222og_[WSOMKIGECBA@??>>==<<;;::9999888877776666555555554444444433333333333333333  !"##$$%%&&''(())***++++,,,,----......////////000011111111222222223333333333333333og_[WSOMKIGEDCBA@??>>==<<;;::::999988887777666666665555555544444444444444444  !"##$$%%&&''(())**++++,,,,----....////////0000111122222222333333334444444444444444og_[WSOMKIGFEDCBA@??>>==<<;;;;::::99998888777777776666666655555555555555555  !"#$$%%&&''(())**+++,,,,----....//////00001111222233333333444444445555555555555555og_[WSOMKIHGFEDCBA@??>>==<<<<;;;;::::9999888888887777777766666666666666666  !"#$$%%&&''(())**++,,,,----....////000011112222333344444444555555556666666666666666og_[WSOMKJIHGFEDCBA@??>>====<<<<;;;;::::999999998888888877777777777777777  !"#$%%&&''(())**++,,,----....////00111122223333444455555555666666667777777777777777og_[WSOMLKJIHGFEDCBA@??>>>>====<<<<;;;;::::::::9999999988888888888888888  !"#$%%&&''(())**++,,----....////0011222233334444555566666666777777778888888888888888og_[WSONMLKJIHGFEDCBA@????>>>>====<<<<;;;;;;;;::::::::99999999999999999  !"#$%&&''(())**++,,---....////001122333344445555666677777777888888889999999999999999og_[WSQONMLKJIHGFEDCBAA@@????>>>>====<<<<<<<<;;;;;;;;:::::::::::::::::  !"#$%&&''(())**++,,--....////0011223344445555666677778888888899999999::::::::::::::::og_[WUSQONMLKJIHGFEDCCBBAA@@????>>>>========<<<<<<<<;;;;;;;;;;;;;;;;;  !"#$%&''(())**++,,--...////0011223344555566667777888899999999::::::::;;;;;;;;;;;;;;;;og_[YWUSQONMLKJIHGFEEDDCCBBAA@@????>>>>>>>>========<<<<<<<<<<<<<<<<<  !"#$%&''(())**++,,--..////0011223344556666777788889999::::::::;;;;;;;;<<<<<<<<<<<<<<<>>>>>>>=================  !"#$%&'(())**++,,--..///00112233445566777788889999::::;;;;;;;;<<<<<<<<================ogc_][YWUSQONMLKJIIHHGGFFEEDDCCBBAAAA@@@@????????>>>>>>>>>>>>>>>>>  !"#$%&'(())**++,,--..//001122334455667788889999::::;;;;<<<<<<<<========>>>>>>>>>>>>>>>>okgc_][YWUSQONMLKKJJIIHHGGFFEEDDCCCCBBBBAAAA@@@@?????????????????  !"#$%&'())**++,,--..//011223344556677889999::::;;;;<<<<========>>>>>>>>????????????????wokgc_][YWUSQONMMLLKKJJIIHHGGFFEEEEDDDDCCCCBBBBAAAAAAAA@@@@@@@@@  !"#$%&'())**++,,--..//0122334455667788999::::;;;;<<<<======>>>>>>>>????????????@@@@@@@@wokgc_][YWUSQONNMMLLKKJJIIHHGGFFFFEEEEDDDDCCCCBBBBBBBBAAAAAAAAA  !"#$%&'())**++,,--..//012233445566778899::::;;;;<<<<====>>>>>>>>????????@@@@@@@@AAAAAAAAwokgc_][YWUSQOONNMMLLKKJJIIHHGGGGFFFFEEEEDDDDCCCCCCCCBBBBBBBBB  !"#$%&'())**++,,--..//01233445566778899:::;;;;<<<<====>>>>>>????????@@@@AAAAAAAABBBBBBBBwokgc_][YWUSQPOONNMMLLKKJJIIHHHHGGGGFFFFEEEEDDDDDDDDCCCCCCCCC  !"#$%&'()**++,,--..//01233445566778899::;;;;<<<<====>>>>????????@@@@AAAABBBBBBBBCCCCCCCCwokgc_][YWUSRQPOONNMMLLKKJJIIIIHHHHGGGGFFFFEEEEEEEEDDDDDDDDD  !"#$%&'()**++,,--..//0123445566778899::;;;<<<<====>>>>??????@@@@AAAABBBBCCCCCCCCDDDDDDDDwokgc_][YWUTSRQPOONNMMLLKKJJJJIIIIHHHHGGGGFFFFFFFFEEEEEEEEE  !"#$%&'()**++,,--..//0123445566778899::;;<<<<====>>>>????@@@@AAAABBBBCCCCDDDDDDDDEEEEEEEEwokgc_][YWVUTSRQPOONNMMLLKKKKJJJJIIIIHHHHGGGGGGGGFFFFFFFFF  !"#$%&'()**++,,--..//012345566778899::;;<<<====>>>>????@@AAAABBBBCCCCDDDDEEEEEEEEFFFFFFFFwokgc_][YXWVUTSRQPOONNMMLLLLKKKKJJJJIIIIHHHHHHHHGGGGGGGGG  !"#$%&'()*++,,--..//012345566778899::;;<<====>>>>????@@AABBBBCCCCDDDDEEEEFFFFFFFFGGGGGGGGwokgc_][ZYXWVUTSRQPOONNMMMMLLLLKKKKJJJJIIIIIIIIHHHHHHHHH  !"#$%&'()*++,,--..//01234566778899::;;<<===>>>>????@@AABBCCCCDDDDEEEEFFFFGGGGGGGGHHHHHHHHwokgc_]\[ZYXWVUTSRQPOONNNNMMMMLLLLKKKKJJJJJJJJIIIIIIIII  !"#$%&'()*++,,--..//01234566778899::;;<<==>>>>????@@AABBCCDDDDEEEEFFFFGGGGHHHHHHHHIIIIIIIIwokgc_^]\[ZYXWVUTSRQPOOOONNNNMMMMLLLLKKKKKKKKJJJJJJJJJ  !"#$%&'()*++,,--..//0123456778899::;;<<==>>>????@@AABBCCDDEEEEFFFFGGGGHHHHIIIIIIIIJJJJJJJJwokgca_^]\[ZYXWVUTSRQQPPOOOONNNNMMMMLLLLLLLLKKKKKKKKK  !"#$%&'()*+,,--..//0123456778899::;;<<==>>????@@AABBCCDDEEFFFFGGGGHHHHIIIIJJJJJJJJKKKKKKKKwokgeca_^]\[ZYXWVUTSSRRQQPPOOOONNNNMMMMMMMMLLLLLLLLL  !"#$%&'()*+,,--..//012345678899::;;<<==>>???@@AABBCCDDEEFFGGGGHHHHIIIIJJJJKKKKKKKKLLLLLLLLwokigeca_^]\[ZYXWVUUTTSSRRQQPPOOOONNNNNNNNMMMMMMMMM  !"#$%&'()*+,,--..//012345678899::;;<<==>>??@@AABBCCDDEEFFGGHHHHIIIIJJJJKKKKLLLLLLLLMMMMMMMMwomkigeca_^]\[ZYXWWVVUUTTSSRRQQPPOOOOOOOONNNNNNNNN  !"#$%&'()*+,,--..//01234567899::;;<<==>>??@AABBCCDDEEFFGGHHIIIIJJJJKKKKLLLLMMMMMMMMNNNNNNNNwsomkigeca_^]\[ZYYXXWWVVUUTTSSRRQQQQPPPPOOOOOOOOO  !"#$%&'()*+,--..//01234567899::;;<<==>>??@ABBCCDDEEFFGGHHIIJJJJKKKKLLLLMMMMNNNNNNNNOOOOOOOO{wsomkigeca_^]\[[ZZYYXXWWVVUUTTSSSSRRRRQQQQPPPPP  !"#$%&'()*+,--..//01234567899::;;<<==>>??@ABCCDDEEFFGGHHIIJJJKKKKLLLLMMMMNNNNNNOOOOOOOOPPPP{wsomkigeca_^]\\[[ZZYYXXWWVVUUTTTTSSSSRRRRQQQQQ  !"#$%&'()*+,--..//0123456789::;;<<==>>??@ABCCDDEEFFGGHHIIJJKKKKLLLLMMMMNNNNOOOOOOOOPPPPQQQQ{wsomkigeca_^]]\\[[ZZYYXXWWVVUUUUTTTTSSSSRRRRR  !"#$%&'()*+,--..//0123456789::;;<<==>>??@ABCDDEEFFGGHHIIJJKKKLLLLMMMMNNNNOOOOOOPPPPQQQQRRRR{wsomkigeca_^^]]\\[[ZZYYXXWWVVVVUUUUTTTTSSSSS  !"#$%&'()*+,--..//0123456789::;;<<==>>??@ABCDDEEFFGGHHIIJJKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSS{wsomkigeca__^^]]\\[[ZZYYXXWWWWVVVVUUUUTTTTT  !"#$%&'()*+,--..//0123456789::;;<<==>>??@ABCDEEFFGGHHIIJJKKLLLMMMMNNNNOOOOPPQQQQRRRRSSSSTTTT{wsomkigeca`__^^]]\\[[ZZYYXXXXWWWWVVVVUUUUU  !"#$%&'()*+,--..//0123456789:;;<<==>>??@ABCDEEFFGGHHIIJJKKLLMMMMNNNNOOOOPPQQRRRRSSSSTTTTUUUU{wsomkigecba`__^^]]\\[[ZZYYYYXXXXWWWWVVVVV  !"#$%&'()*+,--..//0123456789:;;<<==>>??@ABCDEFFGGHHIIJJKKLLMMMNNNNOOOOPPQQRRSSSSTTTTUUUUVVVV{wsomkigedcba`__^^]]\\[[ZZZZYYYYXXXXWWWWW  !"#$%&'()*+,-..//0123456789:;;<<==>>??@ABCDEFFGGHHIIJJKKLLMMNNNNOOOOPPQQRRSSTTTTUUUUVVVVWWWW{wsomkigfedcba`__^^]]\\[[[[ZZZZYYYYXXXXX  !"#$%&'()*+,-..//0123456789:;;<<==>>??@ABCDEFGGHHIIJJKKLLMMNNNOOOOPPQQRRSSTTUUUUVVVVWWWWXXXX{wsomkihgfedcba`__^^]]\\\\[[[[ZZZZYYYYY  !"#$%&'()*+,-..//0123456789:;<<==>>??@ABCDEFGGHHIIJJKKLLMMNNOOOOPPQQRRSSTTUUVVVVWWWWXXXXYYYY{wsomkjihgfedcba`__^^]]]]\\\\[[[[ZZZZZ  !"#$%&'()*+,-..//0123456789:;<<==>>??@ABCDEFGHHIIJJKKLLMMNNOOOPPQQRRSSTTUUVVWWWWXXXXYYYYZZZZ{wsomlkjihgfedcba`__^^^^]]]]\\\\[[[[[  !"#$%&'()*+,-..//0123456789:;<<==>>??@ABCDEFGHHIIJJKKLLMMNNOOPPQQRRSSTTUUVVWWXXXXYYYYZZZZ[[[[{wsonmlkjihgfedcba`____^^^^]]]]\\\\\  !"#$%&'()*+,-..//0123456789:;<<==>>??@ABCDEFGHIIJJKKLLMMNNOOPQQRRSSTTUUVVWWXXYYYYZZZZ[[[[\\\\{wsqonmlkjihgfedcbaa``____^^^^]]]]]  !"#$%&'()*+,-..//0123456789:;<==>>??@ABCDEFGHIIJJKKLLMMNNOOPQRRSSTTUUVVWWXXYYZZZZ[[[[\\\\]]]]{wusqonmlkjihgfedccbbaa``____^^^^^  !"#$%&'()*+,-..//0123456789:;<==>>??@ABCDEFGHIJJKKLLMMNNOOPQRSSTTUUVVWWXXYYZZ[[[[\\\\]]]]^^^^{ywusqonmlkjihgfeeddccbbaa``_____  !"#$%&'()*+,-.//0123456789:;<==>>??@ABCDEFGHIJJKKLLMMNNOOPQRSTTUUVVWWXXYYZZ[[\\\\]]]]^^^^____}{ywusqonmlkjihggffeeddccbbaa```  !"#$%&'()*+,-.//0123456789:;<==>>??@ABCDEFGHIJJKKLLMMNNOOPQRSTUUVVWWXXYYZZ[[\\\]]]]^^^^____``}{ywusqonmlkjihhggffeeddccbbaaa  !"#$%&'()*+,-.//0123456789:;<==>>??@ABCDEFGHIJKKLLMMNNOOPQRSTUUVVWWXXYYZZ[[\\]]]]^^^^____``aa}{ywusqonmlkjiihhggffeeddccbbb  !"#$%&'()*+,-.//0123456789:;<==>>??@ABCDEFGHIJKKLLMMNNOOPQRSTUVVWWXXYYZZ[[\\]]]^^^^____``aabb}{ywusqonmlkjjiihhggffeeddccc  !"#$%&'()*+,-.//0123456789:;<=>>??@ABCDEFGHIJKKLLMMNNOOPQRSTUVVWWXXYYZZ[[\\]]^^^^____``aabbcc}{ywusqonmlkkjjiihhggffeeddd  !"#$%&'()*+,-.//0123456789:;<=>>??@ABCDEFGHIJKKLLMMNNOOPQRSTUVWWXXYYZZ[[\\]]^^^____``aabbccdd}{ywusqonmllkkjjiihhggffeee  !"#$%&'()*+,-.//0123456789:;<=>>??@ABCDEFGHIJKLLMMNNOOPQRSTUVWWXXYYZZ[[\\]]^^____``aabbccddee}{ywusqonmmllkkjjiihhggfff  !"#$%&'()*+,-.//0123456789:;<=>>??@ABCDEFGHIJKLLMMNNOOPQRSTUVWXXYYZZ[[\\]]^^___``aabbccddeeff}{ywusqonnmmllkkjjiihhggg  !"#$%&'()*+,-.//0123456789:;<=>>??@ABCDEFGHIJKLLMMNNOOPQRSTUVWXXYYZZ[[\\]]^^__``aabbccddeeffgg}{ywusqoonnmmllkkjjiihhh  !"#$%&'()*+,-.//0123456789:;<=>>??@ABCDEFGHIJKLLMMNNOOPQRSTUVWXYYZZ[[\\]]^^__`aabbccddeeffgghh}{ywusqpoonnmmllkkjjiii  !"#$%&'()*+,-.//0123456789:;<=>>??@ABCDEFGHIJKLMMNNOOPQRSTUVWXYYZZ[[\\]]^^__`abbccddeeffgghhii}{ywusrqpoonnmmllkkjjj  !"#$%&'()*+,-.//0123456789:;<=>>??@ABCDEFGHIJKLMMNNOOPQRSTUVWXYZZ[[\\]]^^__`abccddeeffgghhiijj}{ywutsrqpoonnmmllkkk  !"#$%&'()*+,-.//0123456789:;<=>??@ABCDEFGHIJKLMMNNOOPQRSTUVWXYZZ[[\\]]^^__`abcddeeffgghhiijjkk}{ywvutsrqpoonnmmlll  !"#$%&'()*+,-.//0123456789:;<=>??@ABCDEFGHIJKLMMNNOOPQRSTUVWXYZ[[\\]]^^__`abcdeeffgghhiijjkkll}{yxwvutsrqpoonnmmm  !"#$%&'()*+,-.//0123456789:;<=>??@ABCDEFGHIJKLMNNOOPQRSTUVWXYZ[[\\]]^^__`abcdeffgghhiijjkkllmm}{zyxwvutsrqpoonnn  !"#$%&'()*+,-.//0123456789:;<=>??@ABCDEFGHIJKLMNNOOPQRSTUVWXYZ[\\]]^^__`abcdefgghhiijjkkllmmnn}|{zyxwvutsrqpooo  !"#$%&'()*+,-./0123456789:;<=>??@ABCDEFGHIJKLMNNOOPQRSTUVWXYZ[\\]]^^__`abcdefghhiijjkkllmmnnoo~}|{zyxwvutsrqpp  !"#$%&'()*+,-./0123456789:;<=>??@ABCDEFGHIJKLMNNOOPQRSTUVWXYZ[\\]]^^__`abcdefghiijjkkllmmnnoop~}|{zyxwvutsrqq  !"#$%&'()*+,-./0123456789:;<=>??@ABCDEFGHIJKLMNNOOPQRSTUVWXYZ[\]]^^__`abcdefghiijjkkllmmnnoopq~}|{zyxwvutsrr  !"#$%&'()*+,-./0123456789:;<=>??@ABCDEFGHIJKLMNNOOPQRSTUVWXYZ[\]]^^__`abcdefghijjkkllmmnnoopqr~}|{zyxwvutss  !"#$%&'()*+,-./0123456789:;<=>??@ABCDEFGHIJKLMNOOPQRSTUVWXYZ[\]]^^__`abcdefghijjkkllmmnnoopqrs~}|{zyxwvutt  !"#$%&'()*+,-./0123456789:;<=>??@ABCDEFGHIJKLMNOOPQRSTUVWXYZ[\]]^^__`abcdefghijkkllmmnnoopqrst~}|{zyxwvuu  !"#$%&'()*+,-./0123456789:;<=>??@ABCDEFGHIJKLMNOOPQRSTUVWXYZ[\]^^__`abcdefghijkkllmmnnoopqrstu~}|{zyxwvv  !"#$%&'()*+,-./0123456789:;<=>??@ABCDEFGHIJKLMNOOPQRSTUVWXYZ[\]^^__`abcdefghijkllmmnnoopqrstuv~}|{zyxww  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOOPQRSTUVWXYZ[\]^^__`abcdefghijkllmmnnoopqrstuvw~}|{zyxx  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOOPQRSTUVWXYZ[\]^^__`abcdefghijklmmnnoopqrstuvwx~}|{zyy  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOOPQRSTUVWXYZ[\]^__`abcdefghijklmmnnoopqrstuvwxy~}|{zz  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOOPQRSTUVWXYZ[\]^__`abcdefghijklmnnoopqrstuvwxyz~}|{{  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^__`abcdefghijklmnnoopqrstuvwxyz{~}||  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^__`abcdefghijklmnoopqrstuvwxyz{|~}}  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnoopqrstuvwxyz{|}~~  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~;;M;>M;6>M;/6>M;+/6>M;'+/6>M;#'+/6>M;#'+/6>M;#'+/6>M;#'+/6>M;#'+/6>M;#'+/6>M;#'+/6>M;#'+/6>Mž#'+/6>Mž!%)-2:E[ž#'+/6>M[ž!%)-2:EM[ž#'+/6>EM[ž!%)-2:>EM[ž #'+/6:>EM[ž !%)-26:>EM[ž #'+/26:>EM[ž !%)-/26:>EM[ž #'+-/26:>EM[ž !%)+-/26:>EM[ž #')+-/26:>EM[ž !%')+-/26:>EM[ #%')+-/26:>EM[ !#%')+-/26:>EM[ !#%')+-/26:>EM[  "$&(*,.048EM[g  "$&(*,.048EMS[g  "$&(*,.048EIMS[g  "$&(*,.048AEIMS[g  "$&(*,.048<>AEIMS[g !#%')+-/26:<>AEIMS[g  "$&(*,.048:<>AEIMS[g !#%')+-/268:<>AEIMS[g  "$&(*,.0468:<>AEIMS[g !#%')+-/2468:<>AEIMS[g  "$&(*,.02468:<>AEIMS[g !#%')+-/02468:<>AEIMS[g  "$&(*,./13579;=?CGKOW_o  "$&(*,./02468:<>AEIMS[go !#%')+-./13579;=?CGKOW_go !#%')+-./02468:<>AEIMS[_go  "$&(*,-./13579;=?CGKOW[_go  "$&(*,-./02468:<>AEIMSW[_go !#%')+,-./13579;=?CGKOSW[_go !#%')+,-./02468:<>AEIMOSW[_go  "$&(*+,-./13579;=?CGKMOSW[_go  "$&(*+,-./02468:<>AEIKMOSW[_go !#%')*+,-./13579;=?CGIKMOSW[_go !#%')*+,-./02468:<>AEGIKMOSW[_go  "$&()*+,-./13579;=?CEGIKMOSW[_go  "$&()*+,-./02468:<>ACEGIKMOSW[_go !#%'()*+,-./13579;=?ACEGIKMOSW[_go !#%'()*+,-./02468:<>?ACEGIKMOSW[_go !#%'()*+,-./02468:<>?@BDFHJLNQUY]ckw  "$&'()*+,-./13579;=>?ACEGIKMOSW[_gow€  "$&'()*+,-./13579;=>?@BDFHJLNQUY]ckowÀ  "$&'()*+,-./02468:<=>?ACEGIKMOSW[_gkowĀ  "$&'()*+,-./02468:<=>?@BDFHJLNQUY]cgkowŀ !#%&'()*+,-./13579;<=>?ACEGIKMOSW[_cgkowƀ !#%&'()*+,-./13579;<=>?@BDFHJLNQUY]_cgkowǀ !#%&'()*+,-./02468:;<=>?ACEGIKMOSW[]_cgkowȀ !#%&'()*+,-./02468:;<=>?@BDFHJLNQUY[]_cgkowɀ  "$%&'()*+,-./13579:;<=>?ACEGIKMOSWY[]_cgkowʀ  "$%&'()*+,-./13579:;<=>?@BDFHJLNQUWY[]_cgkowˀ  "$%&'()*+,-./024689:;<=>?ACEGIKMOSUWY[]_cgkoẁ  "$%&'()*+,-./024689:;<=>?@BDFHJLNQSUWY[]_cgkoẁ !#$%&'()*+,-./135789:;<=>?ACEGIKMOQSUWY[]_cgkow΀ !#$%&'()*+,-./135789:;<=>?@BDFHJLNOQSUWY[]_cgkowπ !#$%&'()*+,-./0246789:;<=>?ACEGIKMNOQSUWY[]_cgkowЀ !#$%&'()*+,-./0246789:;<=>?ACEGIKMNOPRTVXZ\^aeims{р !#$%&'()*+,-./0246789:;<=>?@BDFHJLMNOQSUWY[]_cgkow{Ҁ !#$%&'()*+,-./0246789:;<=>?@BDFHJLMNOPRTVXZ\^aeimsw{Ӏ  "#$%&'()*+,-./1356789:;<=>?ACEGIKLMNOQSUWY[]_cgkosw{Ԁ  "#$%&'()*+,-./1356789:;<=>?ACEGIKLMNOPRTVXZ\^aeimosw{Հ  "#$%&'()*+,-./1356789:;<=>?@BDFHJKLMNOQSUWY[]_cgkmosw{ր  "#$%&'()*+,-./1356789:;<=>?@BDFHJKLMNOPRTVXZ\^aeikmosw{׀  "#$%&'()*+,-./02456789:;<=>?ACEGIJKLMNOQSUWY[]_cgikmosw{؀  "#$%&'()*+,-./02456789:;<=>?ACEGIJKLMNOPRTVXZ\^aegikmosw{ـ  "#$%&'()*+,-./02456789:;<=>?@BDFHIJKLMNOQSUWY[]_cegikmosw{ڀ  "#$%&'()*+,-./02456789:;<=>?@BDFHIJKLMNOPRTVXZ\^acegikmosw{ۀ !"#$%&'()*+,-./13456789:;<=>?ACEGHIJKLMNOQSUWY[]_acegikmosw{܀ !"#$%&'()*+,-./13456789:;<=>?ACEGHIJKLMNOPRTVXZ\^_acegikmosw{݀ !"#$%&'()*+,-./13456789:;<=>?@BDFGHIJKLMNOQSUWY[]^_acegikmosw{ހ !"#$%&'()*+,-./13456789:;<=>?@BDFGHIJKLMNOPRTVXZ\]^_acegikmosw{߀ !"#$%&'()*+,-./023456789:;<=>?ACEFGHIJKLMNOQSUWY[\]^_acegikmosw{ !"#$%&'()*+,-./023456789:;<=>?ACEFGHIJKLMNOQSUWY[\]^_`bdfhjlnquy}က !"#$%&'()*+,-./023456789:;<=>?ACEFGHIJKLMNOPRTVXZ[\]^_acegikmosw{}  !"#$%&'()*+,-./023456789:;<=>?ACEFGHIJKLMNOPRTVXZ[\]^_`bdfhjlnquy{}  !"#$%&'()*+,-./023456789:;<=>?@BDEFGHIJKLMNOQSUWYZ[\]^_acegikmoswy{}䀀 !"#$%&'()*+,-./023456789:;<=>?@BDEFGHIJKLMNOQSUWYZ[\]^_`bdfhjlnquwy{}倀 !"#$%&'()*+,-./023456789:;<=>?@BDEFGHIJKLMNOPRTVXYZ[\]^_acegikmosuwy{}怀 !"#$%&'()*+,-./023456789:;<=>?@BDEFGHIJKLMNOPRTVXYZ[\]^_`bdfhjlnqsuwy{}瀀  !"#$%&'()*+,-./123456789:;<=>?ACDEFGHIJKLMNOQSUWXYZ[\]^_acegikmoqsuwy{}耀  !"#$%&'()*+,-./123456789:;<=>?ACDEFGHIJKLMNOQSUWXYZ[\]^_`bdfhjlnoqsuwy{}退  !"#$%&'()*+,-./123456789:;<=>?ACDEFGHIJKLMNOPRTVWXYZ[\]^_acegikmnoqsuwy{}ꀀ  !"#$%&'()*+,-./123456789:;<=>?ACDEFGHIJKLMNOPRTVWXYZ[\]^_`bdfhjlmnoqsuwy{}뀀  !"#$%&'()*+,-./123456789:;<=>?@BCDEFGHIJKLMNOQSUVWXYZ[\]^_acegiklmnoqsuwy{}쀀  !"#$%&'()*+,-./123456789:;<=>?@BCDEFGHIJKLMNOQSUVWXYZ[\]^_`bdfhjklmnoqsuwy{}퀀  !"#$%&'()*+,-./123456789:;<=>?@BCDEFGHIJKLMNOPRTUVWXYZ[\]^_acegijklmnoqsuwy{}  !"#$%&'()*+,-./123456789:;<=>?@BCDEFGHIJKLMNOPRTUVWXYZ[\]^_`bdfhijklmnoqsuwy{}  !"#$%&'()*+,-./0123456789:;<=>?ABCDEFGHIJKLMNOQSTUVWXYZ[\]^_aceghijklmnoqsuwy{}  !"#$%&'()*+,-./0123456789:;<=>?ABCDEFGHIJKLMNOQSTUVWXYZ[\]^_aceghijklmnoprtvxz|~񀀁  !"#$%&'()*+,-./0123456789:;<=>?ABCDEFGHIJKLMNOQSTUVWXYZ[\]^_`bdfghijklmnoqsuwy{}~򀀁  !"#$%&'()*+,-./0123456789:;<=>?ABCDEFGHIJKLMNOQSTUVWXYZ[\]^_`bdfghijklmnoprtvxz|}~󀀁  !"#$%&'()*+,-./0123456789:;<=>?ABCDEFGHIJKLMNOPRSTUVWXYZ[\]^_acefghijklmnoqsuwy{|}~􀀁  !"#$%&'()*+,-./0123456789:;<=>?ABCDEFGHIJKLMNOPRSTUVWXYZ[\]^_acefghijklmnoprtvxz{|}~  !"#$%&'()*+,-./0123456789:;<=>?ABCDEFGHIJKLMNOPRSTUVWXYZ[\]^_`bdefghijklmnoqsuwyz{|}~  !"#$%&'()*+,-./0123456789:;<=>?ABCDEFGHIJKLMNOPRSTUVWXYZ[\]^_`bdefghijklmnoprtvxyz{|}~  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOQRSTUVWXYZ[\]^_acdefghijklmnoqsuwxyz{|}~  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOQRSTUVWXYZ[\]^_acdefghijklmnoprtvwxyz{|}~  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOQRSTUVWXYZ[\]^_`bcdefghijklmnoqsuvwxyz{|}~  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOQRSTUVWXYZ[\]^_`bcdefghijklmnoprtuvwxyz{|}~  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_abcdefghijklmnoqstuvwxyz{|}~  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_abcdefghijklmnoprstuvwxyz{|}~  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnoqrstuvwxyz{|}~  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~?@ABCDEFGHIJKLMNNOOPQRSTUVWXYZ[\\]]^^__`abcdefghhiijjkkllmmnnoopqqrrssttuuvvwwxxxyyyyzzzz{{{{||||||}}}}}}}}~~~~~~~~~~~~>>??@ABCDFGHIJKLMMNNOOPQSTUVWXYZ[[\\]]^__`abcdefgghiijjkkllmmnoooppqqrrsttuuvvwwxxxxyyyzzzz{{{{||||||}}}}}}}~~~~~~~~~~~~<==>>?@ABCEFGHIKKLLMNNOOPRSTUVWYYZZ[\\]]^__`abdeefgghhijjkklmmnnoooppqqrssttuvvwwwxxxxyyyzzz{{{{||||||}}}}}}}~~~~~~~~~~~:;<<=>>?@ABDEFHIJJKKLMMNOOPRSTVWXXYZZ[[\]]^__abcddeffghhijjkllmnnnoooopqqrsstuuvvwwwxxxyyyzzz{{{{{||||||}}}}}}~~~~~~~~~~~99:;;<=>>?@ACDFGHHIJKKLMMNOOQRTUVWWXYYZ[[\]^^_`abccdeffghhijkklmmmnnnooopqrrsttuuvvwwwxxxyyyzzz{{{{||||||}}}}}}~~~~~~~~~~7789:;;<=>>?@BCEFGGHIJJKLMMNOPRSTUUVWXXYZ[\\]^__`abbcdeffghiijklllmmnnnooppqrsstuuuvvwwwxxxyyzzz{{{{{|||||}}}}}~~~~~~~~~~~556789::;<=>??ACDDEFGHIIJKLMNOOQRSSTUVWXXYZ[\]^^__`aabcdeffghijkklllmmnnnoopqrrsttuuuvvwwwxxyyzzzz{{{{{||||}}}}}}~~~~~~~~~234567899:;<=>?@ABCDEFGHIIJKLMNOOPQRSTUVWXYZZ[\]^^___`abcdefghijjjkkllmmnnooopqrssttuuuvvwwxxyyzzzzz{{{{||||}}}}}}~~~~~~~~~0123456789:;<=>??@ABCDEFGHIJKLMNNOOPQRSTUVWXYZ[\\]]^^__`abcdefghiijjkkllmmnnoopqrrssttuuvvwwxxyyyzzzz{{{{||||}}}}}}~~~~~~~~.//012346789:;<=>>??@ABDEFGHIJKLMMNNOPQRSTUVWXYZ[\\]]^^__`acdefgghiijjkkllmmnooppqqrssttuuvvwwxyyyyzzzz{{{||||}}}}}}~~~~~~~--../012346789:<<==>??@ABDEFGHJKKLMMNNOOQRSTUWXYZZ[[\]]^^_`abcdefgghhijjkklmmnnooppqqrssttuvvwwxxyyyyzzz{{{||||}}}}}}~~~~~~~+,,-../01235679:;;<<=>>?@ACDEFHIJJKLLMNNOPQRSUVWXYYZ[[\\]^^_`acddeffghhijjkllmnnoooppqqrsstuuvwwxxxyyyzzz{{{||||}}}}}}~~~~~~)*++,--./012457899:;<<=>>?@BCDFGHIIJKKLMNNOPQSTUVWXXYZZ[\]]^__abccdeffghhijkklmmnnnooppqrrsttuvwwwxxxyyyzzz{{||||}}}}}}~~~~~'())*+,--./013467889:;;<=>>?ABDEFGGHIJKKLMNNOPRSTUVWWXYZZ[\]^^_`abbcdeffghiijklmmmnnnooppqrsttuvvwwwxxyyyzzz{{||||}}}}}~~~~~%&'(()*+,--./024556789:;;<=>?@ACDEEFGHIJKKLMNOPQRSTUVVWXYZ[[\]^__`aabcdeffghijklllmmnnnoopqrrstuuvvwwxxxyyzzz{{||||}}}}}~~~~~#$%%&'()*+,-./0123456789:;;<=>?AABCDEFGHIJKLLMNOPQRSTTUVWXYZ[\]^^___`abcdefghijjkkllmmnnooppqrstuuuvvwwxxyyzz{{{||||}}}}~~~~~ !"#$%&'()*+,-./0123456789:;<=>??@ABCDEFGHIJKLMNNOOPQRSTUVWXYZ[\]]^^__`abcdefghijjkkllmmnnoopqrsttuuvvwwxxyyzz{{{||||}}}}~~~~ !"#$%&'()*+-..//012356789:;<=>>??ABCDEFGHIJKMMNNOOPQRSUVWXYZ[\\]]^^__`bcdefghiijjkkllmnnoopqrssttuuvvwxxyyzz{{{||||}}}~~~~ !#$%&')*+,--../012356789;<<=>>??@BCDEFGIJKLLMMNOOPQRTUVWXZZ[[\]]^^_`abcdegghhijjkklmmnnopqqrssttuvvwwxyyzz{{{||||}}}~~~ !#$%'()*+,,-../01245679:;;<==>??@BCDEGHIJKKLMMNOOPQSTUWXYYZ[[\]]^^_`acdeffghhijjkllmnnoppqrrsstuuvwwxyyzz{{{|||}}}~~~ !#$&'))*++,--./01345789::;<<=>??@BCEFHHIJJKLLMNOOQRSUVWXXYZZ[\]]^__abddeffghhijkklmmnooppqrrstuuvwwxyzzz{{{|||}}}~~~ "#%''()**+,--./023567899:;<<=>??ABDFFGHIIJKLLMNOPQSTUVWWXYZZ[\]^^_`bccdeffghiijklmmnnoopqqrsttuvwwxyyzz{{{|||}}~~~!#$%&'(()*+,-../124567789:;<<=>?@BCDEFGHHIJKLMMNOQRSTUVVWXYZ[[\]^_`aabcdefgghijkllmnnooopqrsstuvwxxyyzz{{{||}}~~~ "#$%&&'()*+,-./0233456789:;<=>>?ABCDEFGGHIJKLMNOPQRSTUUVWXYZ[\]^__``abcdefghijkklmmnnoopqqrstuvwxxyyzz{{|||}}~~ !"#$%&'()*+,-./0123456789:;<=>??@ABCDEFGHIJKLMNOOPQRSTUVWXYZ[\]^^__`abcdefghijkllmmnnoopqrstuvwxxyyzz{{||}}~~ !"#$%&'()+,-..//023456789:;<>>??@ABCDEGHIJKLMNNOOPQRSUVWXYZ[\]]^^__`bcdefghijkkllmnnoopqrstuwwxxyyzz{{|}}~~  "#$%&()*+,--.//01345678:;<==>>?@ABCEFGHIJLLMMNOOPQRTUVWXZ[[\]]^^_`abcdfghijjkllmmnnopqrsuvvwxxyyz{{||}~~  !#$%'()++,--../01345689:;<<=>>?@ABDEFGIJKKLMMNOOPRSTUWXYZ[[\]]^^_`acdeghhijjkllmnnopqrtuvvwxxyyz{{|}}~  "#$&'))*+,,-../01346799:;;<=>>?@ACDEGHIJJKLMMNOOQRSUVXXYZZ[\]]^__abdefghiijkklmnnopqstuuvwxxyzz{|}}~ !"$%''()*++,-../02457789::;<=>>?@BCEFGHIIJKLMMNOPQSTVWWXYZ[[\]^^_`bceffghijjklmmnoprstuuvwxxyz{||}~ !#%%&'()**+,-.//134567899:;<=>??ACDEFGHHIJKLMNNOQRTUVVWXYZ[\\]^_`bcdefgghijklmmnoprsttuvwxyzz{|}~  "#$%&'())*+,-./0234567889:;<=>?@BCDEFGGHIJKLMNOPRSTUUVWXYZ[\]^_`abcdefghijkllmnoqrsttuvwxyz{|}~  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~  !"#$%&()*+,-.//012345789:;<=>??@ABCDFGHIJKLMNOOPQRTUVWXYZ[\]^_`abcdefghijlmnoopqrtuvwxyz{|}~ !"#$%'()*+--../012346789:;==>>?@ABCEFGHIJLMMNOOPQSTUVWXZ[\]^^_`abcefghijlmnoopqstuvwxz{|}~ !"#$&'(*+,,--.//1235678:;<<=>>?@ABDEFGIJKLMMNOOPRSTUWXY[\]]^__`bcdeghiklmnnopqstuwxyz|}~ !"#%&()*++,--.//1245689:;;<=>>?@ACDEGHJJKLMMNOOQRTUVXY[[\]]^_`abdeghiklmnnoprstvwyz{}~ !"$&'())*+,--./01346789::;<=>>?@BCEFHIIJKLMMNOPQSTVXYZ[[\]^^_abdeghjklmnnoprsuwxz{}~  "#%&''()*+,--./024567899:;<=>??ACDFGHIIJKLMNNOQRTVWXYZ[\\]^_`bcegijklmnnoqrtvwy{|~ !#$$%&'()*+,-.//134567899:;<=>?@BDEFGHHIJKLMNOPRTVWWXYZ[\]^_`bdegijklmnooqsuwyz|~  !"#$%&'()*+,-./123456789:;<=>?@BCDEFGHIJKLMNOPRTUVWXYZ[\]^_`bdfhijklmnoprtvxz|~  "#$%&'()*+,.//012345789:;<=>?@ABCDFGHIJKLMNOQSTUVWXYZ[\]_`bdfgijklmnoqsuwz|~  !"$%&'(*+,-../012346789:<=>>?@ABCEFGHIKLMNOPRSTUVWYZ[\]_`befghjklmnprtwy{~  !"$%&()*,,-..//1235679:;<=>>?@ABDEFHIJKMNOOPRSTVWXZ[\]_acdfghjklnoqsvy{~  !#$&'(*++,--.//1245789;;<=>>?@ACDFGHJKMMNOOQRTUWXY[\^_acdfghjkmnorux{~  "#%&())*+,--./0134679:;;<=>>?@BCEFHJKLMMNOPRSUVXY[\^_abdfgijlmoqtwz} !"$&''()*+,--./0245789::;<=>??ACDFHIJKLMNOOQSTVXY[]^_abdfgiklnpswz}  "$$%&'()*+,-.//13567899:;<=>?@BDFHIIJKLMNOPRTVXY[]^_`bdfhikmorvy} !"#$%&'()*+,-./13456789:;<=>?@BDFGHIJKLMNOPRTVXZ\]^_`bdfhjlnquy} !"#$%&'()*+-./012346789:;<=>?ADEFGHIJKLMNPRTVXZ\]^_`cegikmptx}  !#$%&'(*+,-./012346789:<=>?ABDEFGHJKLMNORTWYZ[]^_acehjmosx}  !#$%&()*,-../01235679:;<>?@ACDEFHIJLMNORUWYZ[\^_adfilnrw|  !#$&'(*+,--./01245789;<>>?@BCDFGIJKMNPSUWXZ[]^_behkmqw|  "#%&()*+,--./0134689;<=>>?ABDEGHJKMNPSUWXZ[]^`cfilpv| !"$&(()*+,--./024579:;<=>?@ACEFHJKMOQSUVXZ[]_aehkou|  "$%&'()*+,-./013579:;;<=>?ABDFHJLMOQSTVXZ\^_cgjnt{ !#$%&'()*+,-./135789:;<=>?@BDFHJLNOPRTVXZ\^aeims{ !"#$%&'()*+-./0256789:;<=>?BDFHJMNOPRTWY[]_dhlr{  !#$%&')*+,-.02356789;<=>?ADFIKLMOPRUWZ\^bgkqz  !#$%'()*,-.01245679:;=>?BDGIKLMOPSUX[]`ejoz  !#$&')*+-./0134578:;<>?BEHIJLMOQSVY\_cioy  "#%'(*+--./0235689;<>?BFGIJLMOQTWZ]bhny !#$&()+,-../124679;<>@CEGHJLMORVY\`fmx  "$&')*+,-./023579;=>ACEGHJLNPTW[_elx  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""################################################################################################################################################################################################################################################################$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((())))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))****************************************************************************************************************************************************************************************************************************************************************++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------................................................................................................................................................................................................................................................................////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222233333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444445555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555566666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777778888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888899999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<================================================================================================================================>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^________________________________````````````````aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccddddddddddddddddeeeeeeeeeeeeeeeeffffffffffffffffgggggggggggggggghhhhhhhhhhhhhhhhiiiiiiiiiiiiiiiijjjjjjjjjjjjjjjjkkkkkkkkkkkkkkkkllllllllllllllllmmmmmmmmmmmmmmmmnnnnnnnnnnnnnnnnooooooooooooooooppppppppqqqqqqqqrrrrrrrrssssssssttttttttuuuuuuuuvvvvvvvvwwwwwwwwxxxxxxxxyyyyyyyyzzzzzzzz{{{{{{{{||||||||}}}}}}}}~~~~~~~~Uhtjh$] proc tkerror { msg } { global errorInfo V set info $errorInfo if { [string match "no more colors*" $msg] } { puts "$V(app): $msg" return } puts "$V(app)-[version]: tcl runtime error: $msg" puts "stack trace:" puts $info puts \ "Please mail this error message and, if possible, an explanation\ \nof what user-action caused it to $V(app)@ee.lbl.gov." } proc "" args { global errorInfo V set info $errorInfo puts "$V(app)-[version]: null proc called:" puts "stack trace:" puts $info puts \ "Please mail this error message and, if possible, an explanation\ \nof what user-action caused it to $V(app)@ee.lbl.gov." } Uhjh褁] bind Entry { catch { global entryTab if { $entryTab(%W:focus) } { focus %W } } } bind Entry { focus . %W select clear catch { global entryTab set entryTab(%W:focus) 0 set v [%W get] if { [$entryTab(%W:action) %W $v] } { %W delete 0 end %W insert 0 $entryTab(%W:value) } else { set entryTab(%W:value) $v } } } bind Entry { focus . %W select clear %W delete 0 end catch { global entryTab set entryTab(%W:focus) 0 %W insert 0 $entryTab(%W:value) } } bind Entry [bind Entry ] bind Entry { tkEntrySetCursor %W 0 %W delete insert end } Uh`jh8] proc net args { global V eval $V(data-net) $args } proc audio args { global audio eval $audio $args } proc controller args { global V eval $V(controller) $args } proc session args { global V eval $V(session) $args } set title "LBL Visual Audio Tool v[version]" proc mk.meter { w c } { frame $w.$c -borderwidth 1 -relief flat -background black meter $w.$c.meter pack $w.$c.meter -expand 1 -fill y } proc mk.tests { w } { label $w.label -text "Audio Tests" -font [ctitlefont] frame $w.frame -borderwidth 2 -relief sunken frame $w.frame.p1 frame $w.frame.p2 set f [ctrlfont] set p $w.frame.p1 radiobutton $p.none -text none -relief flat -command "audio test 0" \ -anchor w -variable audioTest -font $f -value none $p.none select pack $p.none -fill x if ![audio halfduplex] { radiobutton $p.loop -text "loopback" -relief flat \ -command "audio test 1" -value loopback \ -anchor w -variable audioTest -font $f pack $p.loop -fill x } set p $w.frame.p2 radiobutton $p.t6 -text "-6dBm tone" -relief flat -value t6 \ -command "audio test 2" -anchor w -variable audioTest -font $f radiobutton $p.t0 -text "0dBm tone" -relief flat -value t0 \ -command "audio test 3" -anchor w -variable audioTest -font $f radiobutton $p.tmax -text "max tone" -relief flat -value tmax \ -command "audio test 4" -anchor w -variable audioTest -font $f pack $p.t6 $p.t0 $p.tmax -expand 1 -fill x pack $w.frame.p1 -side left -anchor center pack $w.frame.p2 -side left -expand 1 -fill both pack $w.label -fill x pack $w.frame -fill both -expand 1 global audioTest set audioTest none } proc pri_accept { w pri } { global audioPri V if { $audioPri == 0 } { set V(priority) $pri } return 0 } proc mk.pri { w } { label $w.label -text "Priority" -font [ctitlefont] frame $w.frame -borderwidth 2 -relief sunken set f [ctrlfont] set p $w.frame.inset frame $p -borderwidth 0 pack $p -anchor c radiobutton $p.high -text "high (200)" -relief flat -value 200 \ -variable audioPri -command "set V(priority) 200" -font $f radiobutton $p.med -text "med (100)" -relief flat -value 100 \ -variable audioPri -command "set V(priority) 100" -font $f radiobutton $p.low -text "low (10)" -relief flat -value 10 \ -variable audioPri -command "set V(priority) 10" -font $f frame $p.f radiobutton $p.f.rb -text "" -relief flat -value 0 \ -command "set V(priority) \[$p.f.entry get\]" \ -variable audioPri -font $f entry $p.f.entry -relief raised -borderwidth 1 -font $f -width 8 \ -exportselection 0 global entryTab set entryTab($p.f.entry:action) pri_accept pack $p.f.rb $p.f.entry -side left global V set pri [resource defaultPriority] set V(priority) $pri if { $pri == 10 } { $p.low select } elseif { $pri == 100 } { $p.med select } elseif { $pri == 200 } { $p.high select } else { $p.f.rb select } $p.f.entry insert 0 $pri set entryTab($p.f.entry:value) $pri pack $p.high $p.med $p.low $p.f -expand 1 -fill x pack $w.label $w.frame -expand 1 -fill x } proc mk.oradio { w } { set f [ctrlfont] set labels [audio output names] set i 0 set n [llength $labels] while { $i < $n } { set p $w.p$i frame $p set port [lindex $labels $i] set label $port global omode$i if { $label == "speaker" } { set label "spkr" } label $p.label -text $label -font $f radiobutton $p.mmn -text "" -relief flat -value MikeMutesNet \ -command "audio mode $port mikemutesnet" \ -variable omode$i -font $f radiobutton $p.nmm -text "" -relief flat -value NetMutesMike \ -command "audio mode $port netmutesmike" \ -variable omode$i -font $f radiobutton $p.fd -text "" -relief flat -value FullDuplex \ -command "audio mode $port fullduplex" \ -variable omode$i -font $f pack $p.label $p.mmn $p.nmm $p.fd if { [yesno externalEchoCancel] } { radiobutton $p.ec -text "" -relief flat \ -value EchoCancel \ -command "audio mode $port echocancel" \ -variable omode$i -font $f pack $p.ec } pack $p -side left set omode$i [option get . $port\Mode Vat] eval "audio mode $port \$omode$i" incr i } frame $w.label label $w.label.blank -text "" -font $f label $w.label.mmn -text "Mike mutes net" -font $f label $w.label.nmm -text "Net mutes mike" -font $f label $w.label.fd -text "Full duplex" -font $f pack $w.label.blank $w.label.mmn $w.label.nmm $w.label.fd -anchor w if { [yesno externalEchoCancel] } { label $w.label.ec -text "Ext. Echo Cancel" -font $f pack $w.label.ec -anchor w } pack $w.label -side left } proc init_globals { } { foreach r { autoRaise keepSites sortSites muteNewSites mikeAGC \ speakerAGC meterDisable lectureMode recvOnly } { global $r set $r [yesno $r] } foreach r { audioFormat iconPrefix silenceThresh } { global $r set $r [resource $r] } } proc install_meters {} { global meterDisable spkr_meter mike_meter if $meterDisable { controller output-meter "" controller input-meter "" $spkr_meter set 0. $mike_meter set 0. } else { controller output-meter $spkr_meter controller input-meter $mike_meter } } proc set_silence_thresh {} { global silenceSuppressor silenceThresh if $silenceSuppressor { controller silence-thresh $silenceThresh } else { controller silence-thresh 0 } } proc mk.obuttons { w } { set f [ctrlfont] frame $w.p0 -borderwidth 0 frame $w.p1 -borderwidth 0 pack $w.p0 $w.p1 -side left -fill x -anchor n set p $w.p0 checkbutton $p.ar -text "Autoraise" -relief flat -font $f \ -variable autoRaise global meterDisable checkbutton $p.dm -text "Disable Meters" -relief flat -font $f \ -command install_meters -variable meterDisable checkbutton $p.nss -text "Suppress Silence" -relief flat -font $f \ -command set_silence_thresh -variable silenceSuppressor global silenceSuppressor silenceSuppressorButton set silenceSuppressor 1 set silenceSuppressorButton $p.nss pack $p.ar $p.dm $p.nss -expand 1 -fill x set p $w.p1 global sitebox keepSites sortSites checkbutton $p.mns -text "Mute New Sites" -relief flat -font $f \ -variable muteNewSites global keepSites checkbutton $p.kas -text "Keep All Sites" -relief flat -font $f \ -command {srctab keep-sites $keepSites} -variable keepSites srctab keep-sites $keepSites srctab site-drop-time [resource siteDropTime] checkbutton $p.kss -text "Keep Sites Sorted" -relief flat -font $f \ -command "$sitebox keep-sorted \$sortSites" -variable sortSites $sitebox keep-sorted $sortSites pack $p.mns $p.kas $p.kss -expand 1 -fill x } proc setAGC { w which level } { $w.label configure -text "$level dB" controller agc-$which $level } proc enableAGC { w which } { global doAGC if $doAGC($which) { controller agc-$which [$w.scale get] controller agc-$which-enable 1 $w.scale configure -state normal } else { controller agc-$which-enable 0 $w.scale configure -state disabled } } proc oneagc { w which label } { set f [ctrlfont] checkbutton $w.button -text $label -relief flat -font $f \ -command "enableAGC $w $which" -variable doAGC($which) scale $w.scale -orient horizontal \ -showvalue 0 \ -from -10 -to 10 \ -command "setAGC $w $which" \ -relief groove -borderwidth 2 -width 10 \ -state disabled label $w.label -text "0 dB" -width 5 -font $f pack $w.button $w.scale $w.label -side left pack $w.scale -expand 1 -fill x -pady 3 global AGCbutton set AGCbutton($which) $w.button } proc mk.agc { w } { label $w.label -text "Automatic Gain Control" -font [ctitlefont] frame $w.frame -borderwidth 2 -relief sunken frame $w.frame.spkr -borderwidth 0 frame $w.frame.mike -borderwidth 0 oneagc $w.frame.spkr output Spkr $w.frame.spkr.scale set [option get . speakerAGCLevel Vat] oneagc $w.frame.mike input Mike $w.frame.mike.scale set [option get . mikeAGCLevel Vat] pack $w.frame.spkr $w.frame.mike -fill x pack $w.label $w.frame -expand 1 -fill x pack $w.frame -padx 6 } proc set_ssthresh { w level } { global silenceThresh silenceSuppressor silenceSuppressorButton $w.label configure -text $level set silenceThresh $level set_silence_thresh if !$silenceSuppressor { $silenceSuppressorButton invoke } } proc mk.ssthresh w { set f [ctrlfont] global silenceThresh label $w.button -text "Silence Thresh: " -relief flat -font $f scale $w.scale -orient horizontal \ -showvalue 0 \ -from 10 -to 60 \ -command "set_ssthresh $w" \ -relief groove -borderwidth 2 -width 10 $w.scale set $silenceThresh label $w.label -text $silenceThresh -width 3 -font $f pack $w.button $w.scale $w.label -side left pack $w.scale -expand 1 -fill x -pady 3 } proc mk.omode { w } { label $w.label -text "Output Mode" -font [ctitlefont] frame $w.frame -borderwidth 2 -relief sunken frame $w.frame.radios -borderwidth 0 frame $w.frame.buttons -borderwidth 0 if [audio halfduplex] { foreach i [audio output names] { audio mode $i mikemutesnet } } else { mk.oradio $w.frame.radios } mk.obuttons $w.frame.buttons frame $w.frame.ssthresh pack $w.frame.radios $w.frame.buttons \ -anchor c -pady 4 pack $w.label $w.frame -expand 1 -fill x } proc select_format { fmt blksPerPkt } { global V if [info exists V(encoder)] { delete $V(encoder) } set V(encoder) [new encoder $fmt] if { "$V(encoder)" == "" } { $V(controller) encoder "" return -1 } $V(controller) encoder $V(encoder) $V(encoder) transmitter $V(session) $V(controller) blocks-per-packet $blksPerPkt $V(controller) encoder $V(encoder) return 0 } proc set_lecture_mode v { foreach s [session active] { [$s handler] lecture-mode $v } } proc set_recvonly_mode v { global inputMutebutton if $v { global unmuted if $unmuted($inputMutebutton) { $inputMutebutton invoke } $inputMutebutton configure -state disabled bind all "" bind all "" } else { $inputMutebutton configure -state normal bind all "ptt_press $inputMutebutton" bind all "$inputMutebutton invoke" } } proc mk.me { w } { set f [ctrlfont] frame $w.mode -borderwidth 2 -relief sunken frame $w.mode.inset -borderwidth 0 set p $w.mode.inset checkbutton $p.lec -text "Lecture" \ -command { set_lecture_mode $lectureMode } \ -variable lectureMode -font $f checkbutton $p.ro -text "RecvOnly" \ -command { set_recvonly_mode $recvOnly } \ -variable recvOnly -font $f pack $p.lec $p.ro -fill x pack $p -anchor c pack $p -side left -expand 1 -fill x frame $w.fmt -borderwidth 2 -relief sunken frame $w.fmt.p1 set p $w.fmt.p1 radiobutton $p.pcm -text PCM -font $f -value pcm \ -command { select_format pcm 1 } -variable audioFormat radiobutton $p.pcm2 -text PCM2 -font $f -value pcm2 \ -command { select_format pcm 2 } -variable audioFormat radiobutton $p.pcm4 -text PCM4 -font $f -value pcm4 \ -command { select_format pcm 4 } -variable audioFormat pack $p.pcm $p.pcm2 $p.pcm4 -expand 1 -fill x frame $w.fmt.p2 set p $w.fmt.p2 radiobutton $p.dvi -text DVI -font $f -value dvi \ -command { select_format dvi 1 } -variable audioFormat radiobutton $p.dvi2 -text DVI2 -font $f -value dvi2 \ -command { select_format dvi 2 } -variable audioFormat radiobutton $p.dvi4 -text DVI4 -font $f -value dvi4 \ -command { select_format dvi 4 } -variable audioFormat pack $p.dvi $p.dvi2 $p.dvi4 -expand 1 -fill x frame $w.fmt.p3 set p $w.fmt.p3 radiobutton $p.gsm -text GSM -font $f -value gsm \ -command { select_format gsm 4 } -variable audioFormat radiobutton $p.lpc4 -text LPC4 -font $f -value lpc4 \ -command { select_format lpc 4 } -variable audioFormat pack $p.gsm $p.lpc4 -expand 1 -fill x pack $w.fmt.p1 $w.fmt.p2 $w.fmt.p3 -side left pack $w.mode -side left -expand 1 -fill both pack $w.fmt -side left global audioFormat set ttl [resource defaultTTL] if {$ttl > 160} { $w.fmt.p1.pcm configure -state disabled if {$audioFormat == "pcm"} { set audioFormat pcm2 } if {$ttl > 192} { $w.fmt.p1.pcm2 configure -state disabled $w.fmt.p1.pcm4 configure -state disabled if {[regexp -nocase pcm $audioFormat]} { set audioFormat dvi2 } if {$ttl > 200} { $w.fmt.p2.dvi configure -state disabled $w.fmt.p2.dvi2 configure -state disabled $w.fmt.p2.dvi4 configure -state disabled if {[regexp -nocase dvi $audioFormat]} { set audioFormat gsm } } } } if { [select_format [string range $audioFormat 0 2] \ [string range $audioFormat 3 4]] < 0 } { puts stderr "vat: unknown audio format: $audioFormat" exit 1 } } proc mk.info { w } { global V set net $V(data-net) label $w.label -font [ctrlfont] -text \ "Dest: [$net addr] Port: [$net port] TTL: [$net ttl]" pack $w.label -expand 1 -fill x } proc update_note { w s } { set s [string trim $s] [srctab local] sdes note $s return 0 } proc mk.entries { w } { global sessionKey confName set sessionKey [option get . sessionKey Vat] frame $w.name label $w.name.label -text "Name: " -font [ctrlfont] -anchor e -width 6 mk.entry $w.name updateName [resource rtpName] pack $w.name.label -side left pack $w.name.entry -side left -expand 1 -fill x -pady 2 frame $w.msg label $w.msg.label -text "Note: " -font [ctrlfont] -anchor e -width 6 mk.entry $w.msg update_note "" pack $w.msg.label -side left pack $w.msg.entry -side left -expand 1 -fill x -pady 2 mk.key $w pack $w.name $w.msg $w.key -expand 1 -fill x frame $w.b button $w.b.stats -text "Global Stats" -borderwidth 2 \ -anchor c -font [ctrlfont] -command create_global_window pack $w.b.stats -side left -padx 4 -pady 2 -anchor c pack $w.b -pady 2 -anchor c } proc mk.net { w } { label $w.label -text "Network" -font [ctitlefont] frame $w.frame -borderwidth 0 frame $w.frame.me -borderwidth 0 frame $w.frame.ie -borderwidth 2 -relief sunken frame $w.frame.ie.info -borderwidth 0 frame $w.frame.ie.entries -borderwidth 0 mk.me $w.frame.me mk.info $w.frame.ie.info mk.entries $w.frame.ie.entries pack $w.label $w.frame -expand 1 -fill x pack $w.frame -padx 6 pack $w.frame.ie.info $w.frame.ie.entries -expand 1 -fill x pack $w.frame.me $w.frame.ie -expand 1 -fill x } proc build.menu { } { set w .menu toplevel $w bind $w "focus $w" wm withdraw $w frame $w.tp frame $w.tp.tests frame $w.tp.pri frame $w.omode frame $w.net mk.tests $w.tp.tests mk.pri $w.tp.pri mk.omode $w.omode mk.net $w.net button $w.ok -text " Dismiss " -borderwidth 2 -relief raised \ -command "toggle_window $w" -font [ctitlefont] frame $w.pad -borderwidth 0 -height 6 pack $w.tp.tests -side left -expand 1 -fill both -padx 2 pack $w.tp.pri -side left -expand 1 -fill x -padx 2 pack $w.tp $w.omode $w.net -expand 1 -fill x pack $w.ok -pady 6 -anchor c pack $w.tp -padx 4 pack $w.omode -padx 6 } proc mute_invoke { w which } { global unmuted if $unmuted($w) { audio $which unmute if ![audio have] { audio_demand } } else { audio $which mute } } proc lookup_bitmap { name } { switch -glob $name { mike { return mike } speaker { return speaker } jack { return headphone } lineout2 { return lineout2 } lineout3 { return lineout3 } lineout* { return lineout } linein2 { return linein2 } linein3 { return linein3 } default { return linein } } } proc setPort { which button scale port } { audio $which set $port $button configure -bitmap [lookup_bitmap $port] global gaintab porttab set porttab($which) $port $scale set $gaintab($port) audio $which gain $gaintab($port) } proc changePort { which button scale } { set ports [audio $which names] set n [audio $which current] incr n if { $n >= [llength $ports] } { set n 0 } setPort $which $button $scale [lindex $ports $n] } proc setgain { which level } { audio $which gain $level global gaintab porttab set gaintab($porttab($which)) $level } proc mk.pane { w which bitmap label } { set f [option get . audioFont Vat] frame $w.mute -borderwidth 1 -relief raised checkbutton $w.mute.b -text $label -font $f -relief ridge \ -anchor c \ -command "mute_invoke $w.mute.b $which" \ -variable unmuted($w.mute.b) \ -borderwidth 2 \ -highlightthickness 0 global unmuted set unmuted($w.mute.b) 1 global $which\Mutebutton set $which\Mutebutton $w.mute.b pack $w.mute.b -expand 1 -fill x frame $w.select -borderwidth 2 -relief raised button $w.select.b -bitmap $bitmap -relief flat -borderwidth 2 \ -command "changePort $which $w.select.b $w.frame.scale" \ -height 24 -highlightthickness 1 pack $w.select.b -expand 1 -fill x if { [llength [audio $which names]] <= 1 } { $w.select.b configure -state disabled } frame $w.frame -borderwidth 2 -relief raised meter $w.frame.meter scale $w.frame.scale -orient vertical \ -showvalue 0 \ -from 256 -to 0 \ -command "setgain $which" \ -relief groove -borderwidth 2 -length 200 \ -highlightthickness 0 global $which\Scale $which\PortButton set $which\Scale $w.frame.scale set $which\PortButton $w.select.b pack $w.frame.meter $w.frame.scale -side left -expand 1 -fill y pack $w.mute $w.select -fill x pack $w.frame -expand 1 -fill y } proc invoke_keep_audio {} { global audioHeld if { $audioHeld && ![audio have] } { audio_demand } } proc mk.ab { top } { set w $top.audio frame $w pack $w -expand 1 -fill y frame $w.spkr -borderwidth 0 mk.pane $w.spkr output speaker listen frame $w.mike -borderwidth 0 mk.pane $w.mike input mike talk pack $w.spkr $w.mike -side left -expand 1 -fill y global spkr_meter mike_meter set spkr_meter $w.spkr.frame.meter set mike_meter $w.mike.frame.meter set f [ctrlfont] checkbutton $top.button -text "Keep Audio" -font $f \ -command invoke_keep_audio \ -variable audioHeld -anchor c \ -relief ridge -borderwidth 2 -highlightthickness 0 global keepAudioButton set keepAudioButton $top.button pack $top.button -fill x -side top -anchor c } proc ptt_press { button } { global unmuted if !$unmuted($button) { $button invoke } } proc toggle_mute src { set v [expr ![$src mute]] $src mute $v global src_name $src_name($src) mute $v } proc sb_leftclick {sitebox x y m} { set s [$sitebox which $x $y] if {"$s" != ""} { if [$sitebox over-button $x $y] { toggle_mute $s } else { create_info_menu $s [winfo pointerx $sitebox] \ [winfo pointery $sitebox] } } } proc is_mixer src { return [expr [$src srcid] != [$src ssrc]] } proc delete_source { w x y } { set src [$w which $x $y] if { "$src" != "" && $src != [srctab local] } { srctab delete $src } } proc sb_midclick {w x y m} { set src [$w which $x $y] if {"$src" != ""} { if [is_mixer $src] { set s [getid $src] open_dialog \ "can't do side conversation with $s thru mixer" } else { set fmt [rtp_format $src] if { $fmt == "" } { set fmt pcm2 } global V set csig [$src addr]/[net port] if {$V(sessionType) == "vat"} { set st -n set csig $csig/[resource confid] } else { set st -r } exec vat $st -C [getid $src] $csig/$fmt & } } } proc audio_psetup {} { set s [audio input gain] puts "Vat.[lindex $s 0]Gain: [lindex $s 1]" set s [audio output gain] puts "Vat.[lindex $s 0]Gain: [lindex $s 1]" set s [controller agc-input] if [lindex $s 0] { puts "Vat.mikeAGCLevel: [lindex $s 1]" } set s [controller agc-output] if [lindex $s 0] { puts "Vat.speakerAGCLevel: [lindex $s 1]" } } proc build.bar w { global title label $w.title -text $title -font [ctrlfont] \ -relief flat -justify left -width [string length $title] button $w.quit -text Quit -relief raised \ -font [ctrlfont] -command adios \ -highlightthickness 1 button $w.menu -text Menu -relief raised \ -font [ctrlfont] -highlightthickness 1 \ -command "toggle_window .menu" button $w.help -text Help -relief raised \ -font [ctrlfont] -highlightthickness 1 \ -command "toggle_window .help" pack $w.title -side left -fill both -expand 1 pack $w.menu $w.help $w.quit -side left -pady 1 -padx 1 global title_bar set title_bar $w.title } proc init_gui { } { global audio set dev [resource defaultDevice] if { "$dev" != "" } { set audio [new audio $dev] if { $audio == "" } { puts stderr "vat: no such audio device: $dev" exit 1 } } else { set devices "sun sgi voxware hp pc ibm af" if [yesno useAF] { set devices "af $devices" } foreach d $devices { set audio [new audio $d] if { "$audio" != "" } { break } } } $audio obtain after 5000 audio_timeout init_globals bind . { focus %W } bind . q { adios } bind . { adios } bind . { adios } bind . p audio_psetup bind . P audio_psetup frame .m frame .m.left frame .m.right frame .m.left.sites -relief raised -borderwidth 2 global sitebox set sitebox .m.left.sites.sb new sitebox $sitebox pack .m.left.sites -expand 1 -fill both pack .m.left.sites.sb -expand 1 -fill both set a .m.right frame $a.ab mk.ab $a.ab bind . c purge_sources bind . C purge_sources bind . l list_sources bind . L list_sources bind . o "$sitebox sort" bind . O "$sitebox sort" bind $sitebox <1> "sb_leftclick %W %x %y 0" bind $sitebox "sb_leftclick %W %x %y 1" bind $sitebox <2> "sb_midclick %W %x %y 0" bind $sitebox d "delete_source %W %x %y" global recvOnly if !$recvOnly { global inputMutebutton bind all "ptt_press $inputMutebutton" bind all "$inputMutebutton invoke" } pack $a.ab -expand 1 -fill both pack .m.left -side left -expand 1 -fill both pack .m.right -side left -fill y pack .m -expand 1 -fill both frame .bar -relief ridge -borderwidth 2 build.bar .bar pack .bar -fill x set v [resource geometry] if { $v != "" } { if { [ catch "wm geometry . $v" ] } { puts "vat: bad geometry $v" adios } } wm withdraw . update idletasks global minwidth minheight iconPrefix set minwidth [winfo reqwidth .] set minheight [winfo reqheight .] wm minsize . $minwidth $minheight global mike_meter spkr_meter V if [audio halfduplex] { set duplex half-duplex } else { set duplex full-duplex } set V(controller) [new controller $duplex] install_meters $V(controller) audio $audio update idletasks wm deiconify . bind . { mark_icon "" } rank_init } proc init_tk { } { build.menu audio_indicator_update global keepAudioButton if [yesno keepAudio] { $keepAudioButton invoke } global outputMutebutton inputMutebutton \ inputAGCbutton outputAGCbutton recvOnly if $recvOnly { $inputMutebutton invoke $inputMutebutton configure -state disabled } elseif [yesno mikeMute] { $inputMutebutton invoke } if [yesno speakerMute] { $outputMutebutton invoke } if [yesno mikeAGC] { } if [yesno speakerAGC] { } global gaintab porttab inputScale outputScale global inputPortButton outputPortButton set names [audio input names] foreach port $names { set attr [string tolower $port] set gaintab($port) [option get . $attr\Gain Vat] } if { [llength $names] <= 1 } { $inputPortButton configure -state disabled \ -disabledforeground [option get . foreground Button] } set pname [audio input name [option get . inputPort Vat]] if {[info exists gaintab($pname)] == 0} { set pname [lindex $names 0] } setPort input $inputPortButton $inputScale $pname set names [audio output names] foreach port $names { set attr [string tolower $port] set gaintab($port) [option get . $attr\Gain Vat] audio mode $port [option get . $attr\Mode Vat] } if { [llength $names] <= 1 } { $outputPortButton configure -state disabled \ -disabledforeground [option get . foreground Button] } set pname [audio output name [option get . outputPort Vat]] if {[info exists gaintab($pname)] == 0} { set pname [lindex $names 0] } setPort output $outputPortButton $outputScale $pname } proc ctrlfont { } { return [option get . ctrlFont Vat] } proc ctitlefont { } { return [option get . ctrlTitleFont Vat] } proc build.help { } { create_help_window .help { "Before transmitting audio, adjust the mike \ level so that the output meter peaks around 80% of full scale. Below this\ you are hard to hear and above this your signal is distorted." "To talk, temporarily unmute the mike by depressing\ the right mouse button anywhere in the vat window. The mike is\ live only while the button is depressed. For hands-free operation,\ you can leave the mike active by selecting the ``talk'' button\ above the mike icon. \ If the ``talk'' button is grayed-out, the ``recvOnly'' option is\ probably selected on the ``Menu'' panel." "Mute individual sites by clicking on checkbox next to name." "If your computer supports multiple audio input or output ports, you can select which you want by clicking on mike or speaker icon." "Prevent other vats from taking the audio device\ by clicking on the ``Keep Audio'' button. Different vats will\ cooperate so that only one instance ever has ``Keep Audio'' selected. \ The vat label (at the bottom of the window) is italicized when\ this vat does not have control of the audio." "Get info about a site by\ clicking (and holding) left mouse button over the site name. \ A popup menu lets you select a site description window, RTP and\ decoder statistics windows (various reception statistics for data\ coming from the site), and the `mtrace' (multicast traceroute)\ diagnostic run from the site to you or from you to the site." "In a statistics window (the window you get by selecting either RTP\ or Decoder stats in the site popup menu), clicking the left button\ on a stat name will bring up a stripchart plotting that stat. \ The stat value is plotted every second. \ The horizontal axis has a tickmark (a vertical white\ line plotted *under* the data) every 30 seconds. \ A legend at the bottom of the window gives the vertical axis scale." "If the user interface looks peculiar, you might\ have X resources that conflict with tk. A common problem is\ defining ``*background'' and/or ``*foreground''." "Bugs and suggestions to vat@ee.lbl.gov. Thanks." } } proc register src { if [yesno displayMixers] { create_src_name $src } } proc create_src_name src { global sitebox src_name muteNewSites set src_name($src) [$sitebox create] $src_name($src) text [getid $src] $src_name($src) tag $src if $muteNewSites { toggle_mute $src } } proc unregister src { destroy_rtp_stats $src global sitebox src_name if [info exists src_name($src)] { rank_clear $src $sitebox remove $src_name($src) unset src_name($src) } } proc deactivate src { destroy_decoder_stats $src delete [$src handler] $src handler "" } proc activate src { set decoder [new decoder [rtp_format $src]] if { $decoder == "" } { set decoder [new decoder null] } global V lectureMode $decoder lecture-mode $lectureMode $src handler $decoder $decoder controller $V(controller) } proc dummy args "" proc rank_clear src { global rank if { $rank(2) == "$src" } { set rank(2) dummy } if { $rank(1) == "$src" } { set rank(1) $rank(2) set rank(2) dummy } if { $rank(0) == "$src" } { set rank(0) $rank(1) set rank(1) $rank(2) set rank(2) dummy } } proc rank_touch src { global src_name rank set r [$src_name($src) rank] if { $r == 1 } { set rank(1) $rank(0) set rank(0) $src $src_name($rank(1)) rank 1 } elseif { $r != 0 } { $src_name($rank(2)) rank 3 set rank(2) $rank(1) set rank(1) $rank(0) set rank(0) $src $src_name($rank(2)) rank 2 $src_name($rank(1)) rank 1 } $src_name($rank(0)) rank 0 } proc rank_init {} { global rank src_name set rank(0) dummy set rank(1) dummy set rank(2) dummy set src_name(dummy) dummy } proc set_busy src { global src_name if ![info exists src_name($src)] { create_src_name $src } $src_name($src) highlight 1 rank_touch $src if { ![$src mute] && ![winfo ismapped .] } { mark_icon [resource iconMark] } after 500 "busy_check $src" global V unmuted outputMutebutton if [info exists V(cb)] { set cname [$src sdes cname] if { "$cname" != "" } { $V(cb) send "focus $cname" } } if { ![audio have] && $unmuted($outputMutebutton) } { audio_request } } proc busy_check src { global src_name if [info exists src_name($src)] { set delta [expr [controller ntp-time] - [$src last-data]] if { $delta > 20000 } { $src_name($src) highlight 0 $src clear-busy } else { global unmuted outputMutebutton if { ![audio have] && $unmuted($outputMutebutton) } { audio_request } after 500 "busy_check $src" } } } proc update_source_info src { global src_info src_nickname src_name if ![info exists src_name($src)] { create_src_name $src } set name [$src sdes name] set cname [$src sdes cname] set addr [$src addr] if { $name == "" } { if { $cname == "" } { set src_nickname($src) $addr set info $addr/[rtp_format $src] } else { set src_nickname($src) $cname set info "$addr/[rtp_format $src]" } } elseif [cname_redundant $name $cname] { set src_nickname($src) $name set info $addr/[rtp_format $src] } else { set src_nickname($src) $name set info $cname/[rtp_format $src] } set src_info($src) $cname/[rtp_format $src] set msg [$src sdes text] if { $msg != "" } { set info $msg } set src_info($src) $info if { [$src_name($src) text] != $src_nickname($src) } { $src_name($src) text $src_nickname($src) } } proc grayout src { global src_name if [info exists src_name($src)] { $src_name($src) disable 1 } } proc embolden src { global src_name if [info exists src_name($src)] { $src_name($src) disable 0 } } proc change_format src { deactivate $src activate $src } proc info_text src { set d [$src handler] set fmt [rtp_format $src] if { "$d" != "" } { set n [expr [$d block-size] / 160] if { $n > 1 } { set fmt $fmt/$n } } if { $fmt == "" } { set fmt none } return "format: $fmt" } proc purge_sources {} { srctab gen-init while { 1 } { set src [srctab gen-next] if { $src == "" } { return } if [$src lost] { srctab delete $src } } } proc list_sources {} { srctab gen-init while { 1 } { set src [srctab gen-next] if { $src == "" } { return } if [$src lost] { set lost "*" } else { set lost "" } set fmt "[getid $src] \[[$src addr]/[$src srcid]" if [is_mixer $src] { set fmt "$fmt via [$src ssrc]" } set fmt "$fmt\]" puts $lost$fmt } } Uh%jhȟ ] global font set font(helvetica10) { normal--*-100-75-75-*-*-*-* normal--10-*-*-*-*-*-*-* normal--11-*-*-*-*-*-*-* normal--*-100-*-*-*-*-*-* normal--*-*-*-*-*-*-*-* } set font(helvetica12) { normal--*-120-75-75-*-*-*-* normal--12-*-*-*-*-*-*-* normal--14-*-*-*-*-*-*-* normal--*-120-*-*-*-*-*-* normal--*-*-*-*-*-*-*-* } set font(helvetica14) { normal--*-140-75-75-*-*-*-* normal--14-*-*-*-*-*-*-* normal--*-140-*-*-*-*-*-* normal--*-*-*-*-*-*-*-* } set font(times14) { normal--*-140-75-75-*-*-*-* normal--14-*-*-*-*-*-*-* normal--*-140-*-*-*-*-*-* normal--*-*-*-*-*-*-*-* } proc search_font { foundry style weight points slant } { global font foreach f $font($style$points) { set fname -$foundry-$style-$weight-$slant-$f if [havefont $fname] { return $fname } } puts stderr "vat: can't find $weight $style font (using fixed)" if ![havefont fixed] { puts stderr "vat: can't find fixed font" exit 1 } return $f } proc init_fonts {} { set foundry [option get . foundry Vat] set helv10 [search_font $foundry helvetica medium 10 r] set helv10b [search_font $foundry helvetica bold 10 r] set helv10o [search_font $foundry helvetica bold 10 o] set helv12b [search_font $foundry helvetica bold 12 r] set helv14b [search_font $foundry helvetica bold 14 r] set times14 [search_font $foundry times medium 14 r] option add *Font $helv12b startupFile option add Vat.medfont $helv12b startupFile option add Vat.smallfont $helv10b startupFile option add Vat.helpFont $times14 startupFile option add Vat.entryFont $helv10 startupFile option add Vat.audioFont $helv10 startupFile option add Vat.ctrlTitleFont $helv12b startupFile option add Vat.ctrlFont $helv10b startupFile option add Vat.noAudioFont $helv10o startupFile option add Vat.siteFont $helv12b startupFile option add *Font $helv14b startupFile option add *Radiobutton.font $helv12b 100 } proc init_resources {} { option add *padX 2 option add *padY 2 option add *tearOff 0 tk_setPalette gray80 foreach option [array names tkPalette] { option add *$option $tkPalette($option) 61 } option add *highlightThickness 0 option add *Radiobutton.relief flat startupFile option add *Checkbutton.anchor w startupFile option add *Radiobutton.anchor w startupFile option add *Radiobutton.relief flat startupFile option add *Scale.sliderForeground gray66 startupFile option add *Scale.activeForeground gray80 startupFile option add *Scale.background gray70 startupFile option add Vat.disabledColor gray50 startupFile option add Vat.highlightColor gray95 startupFile option add Vat.infoHighlightColor LightYellow2 startupFile option add *VatVU.foreground black startupFile option add *VatVU.peak gray50 startupFile option add *VatVU.hot firebrick1 startupFile option add *VatVU.hotLevel 90 startupFile if { [winfo depth .] == 1 } { option add *selectBackground black startupFile option add *selectForeground white startupFile option add *activeForeground black startupFile option add *VatVU.background white startupFile option add *VatVU.hot gray50 startupFile option add Vat.highlightColor white startupFile } option add Vat.iconPrefix "" startupFile option add Vat.titleReleased "gray95" startupFile option add Vat.titleHave "#aaaaaa" startupFile option add Vat.titlePinned "black" startupFile option add Vat.mikeGain "32" startupFile option add Vat.lineinGain "180" startupFile option add Vat.linein2Gain "180" startupFile option add Vat.linein3Gain "180" startupFile option add Vat.speakerGain "180" startupFile option add Vat.jackGain "180" startupFile option add Vat.lineoutGain "180" startupFile option add Vat.lineout2Gain "180" startupFile option add Vat.speakerMute "false" startupFile option add Vat.mikeMute "true" startupFile option add Vat.speakerMode "NetMutesMike" startupFile option add Vat.jackMode "FullDuplex" startupFile option add Vat.lineoutMode "NetMutesMike" startupFile option add Vat.lineout2Mode "NetMutesMike" startupFile option add Vat.maxPlayout "6" startupFile option add Vat.lectureMode "false" startupFile option add Vat.useNames "false" startupFile option add Vat.defaultTTL "16" startupFile option add Vat.filterLength "256" startupFile option add Vat.filterMaxTaps "35" startupFile option add Vat.meterDisable "false" startupFile option add Vat.meterStyle "discrete" startupFile option add Vat.inputPort "Mike" startupFile option add Vat.outputPort "Speaker" startupFile option add Vat.audioFormat "pcm2" startupFile option add Vat.mikeAGC "false" startupFile option add Vat.mikeAGCLevel "0" startupFile option add Vat.speakerAGC "false" startupFile option add Vat.speakerAGCLevel "0" startupFile option add Vat.defaultPriority "100" startupFile option add Vat.idleDropTime "20" startupFile option add Vat.autoRaise "true" startupFile option add Vat.externalEchoCancel "false" startupFile option add Vat.silenceThresh "20" startupFile option add Vat.talkThresh "0" startupFile option add Vat.echoThresh "70" startupFile option add Vat.echoSuppressTime "400" startupFile option add Vat.keepSites "false" startupFile option add Vat.muteNewSites "false" startupFile option add Vat.sortSites "true" startupFile option add Vat.compactSites "true" startupFile option add Vat.compressionSlope "0.0625" startupFile option add Vat.key "" startupFile option add Vat.afDevice "-1" startupFile option add Vat.afBlocks "2" startupFile option add Vat.afSoftOuputGain "0" startupFile option add Vat.afSoftInputGain "0" startupFile option add Vat.siteDropTime "300" startupFile option add Vat.audioFileName "/dev/audio" startupFile option add Vat.statTimeConst 0.1 startupFile option add Vat.statsFilter 0.0625 startupFile option add Vat.mtu 1024 startupFile option add Vat.network ip startupFile option add Vat.maxbw -1 startupFile option add Vat.bandwidth 128 startupFile option add Vat.confBusChannel 0 startupFile option add Vat.sessionType vat startupFile option add Vat.foundry adobe startupFile option add Vat.recvOnly false startupFile init_fonts option add Vat.suppressUserName true startupFile option add Vat.sdesList "cname tool email note" catch "option readfile ~/.RTPdefaults startupFile" } Uh=jhԟ] proc smallfont { } { return [resource smallfont] } proc mediumfont { } { return [resource medfont] } proc disfont { } { return [resource disablefont] } set nids 0 proc uniqueID { } { global nids incr nids return $nids } proc isCIF fmt { if { $fmt == "h261" } { return 1 } return 0 } proc toggle_window w { if { ![winfo exists $w] } { build$w } global created$w if { ! [info exists created$w] } { set created$w 1 wm transient $w . update idletasks set x [winfo rootx .] set y [winfo rooty .] incr y [winfo height .] incr y -[winfo reqheight $w] incr y -20 incr x [winfo vrootx .] incr y [winfo vrooty .] if { $y < 0 } { set y 0 } if { $x < 0 } { set x 0 } else { set right [expr [winfo screenwidth .] - \ [winfo reqwidth $w]] if { $x > $right } { set x $right } } wm geometry $w +$x+$y wm deiconify $w } elseif { [winfo ismapped $w] } { wm withdraw $w } else { wm deiconify $w } } proc create_toplevel { w title } { global V if [info exists V(visual)] { toplevel $w -class $V(class) \ -visual $V(visual) -colormap $V(colormap) } else { toplevel $w -class $V(class) } set title [resource iconPrefix]$title wm withdraw $w wm transient $w . wm title $w $title wm iconname $w $title bind $w "focus $w" } proc cname_redundant { name cname } { set ni [string first @ $name] if { $ni < 0 } { return 0 } set ci [string first @ $cname] if { $ci < 0 } { return 0 } if { [string compare \ [string range $name 0 $ni] \ [string range $cname 0 $ci]] == 0 } { return 1 } return 0 } proc open_dialog text { set w .dialog catch "destroy $w" global V create_toplevel $w "$V(app) error" label $w.label -text "$V(app): $text" -font [mediumfont] \ -borderwidth 2 -relief groove button $w.button -text Dismiss -command "destroy $w" -font [mediumfont] pack $w.label -expand 1 -fill x -ipadx 4 -ipady 4 pack $w.button -pady 4 wm withdraw $w update idletasks set x [expr [winfo screenwidth $w]/2 - [winfo reqwidth $w]/2 \ - [winfo vrootx [winfo parent $w]]] set y [expr [winfo screenheight $w]/2 - [winfo reqheight $w]/2 \ - [winfo vrooty [winfo parent $w]]] wm geom $w +$x+$y wm deiconify $w bind $w "focus $w" } proc helpitem { w text } { global helpno set f [resource helpFont] canvas $w.bullet -width 12 -height 12 $w.bullet create oval 6 3 12 9 -fill black message $w.msg -justify left -anchor w -font $f -width 450 -text $text pack $w.bullet -side left -anchor ne -pady 5 pack $w.msg -side left -expand 1 -fill x -anchor nw } proc create_help_window { w items } { global V create_toplevel $w "$V(class) Help" frame $w.frame -borderwidth 0 -relief flat set p $w.frame set n 0 foreach m $items { set h $w.h$n incr n frame $h helpitem $h $m pack $h -expand 1 -fill both } button $w.frame.ok -text " Dismiss " -borderwidth 2 -relief raised \ -command "wm withdraw $w" -font [mediumfont] pack $w.frame.ok -pady 6 -padx 6 -anchor e pack $w.frame -expand 1 -fill both } set current_icon_mark "XXX" proc mark_icon mark { global current_icon_mark if {$mark != $current_icon_mark} { set current_icon_mark $mark global V append mark [resource iconPrefix]$V(confname) wm iconname . $mark } } proc mk.entry { w action text } { entry $w.entry -relief raised -borderwidth 1 -exportselection 1 \ -font [resource entryFont] global entryTab set entryTab($w.entry:action) $action set entryTab($w.entry:value) $text $w.entry insert 0 $text } proc toggleKey w { global V entryTab if $V(encrypt) { crypt_set $entryTab($w.entry:value) } else { crypt_clear } } proc disableKeyEditor w { $w.button configure -state disabled set entryTab($w.entry:value) "" } proc enableKeyEditor w { $w.button configure -state normal } proc updateKey { w key } { set w [winfo parent $w] set key [string trim $key] if { $key == "" } { crypt_clear disableKeyEditor $w } elseif { [crypt_set $key] < 0 } { disableKeyEditor $w } else { enableKeyEditor $w } } proc mk.key w { global V frame $w.key checkbutton $w.key.button -text Key: -relief flat -font [smallfont] \ -command "toggleKey $w.key" -variable V(encrypt) \ -disabledforeground gray40 mk.entry $w.key updateKey [resource sessionKey] if !$V(encrypt) { $w.key.button configure -state disabled } pack $w.key.button -side left pack $w.key.entry -side left -fill x -expand 1 } proc updateName { w name } { set name [string trim $name] if { $name != ""} { [srctab local] sdes name $name return 0 } return -1 } UhNjh] proc get-playout src { set d [$src handler] if { "$d" != "" } { return [expr [$d playout] >> 3] } return 0 } proc create_stat_row { r name width cmd relief } { set f [smallfont] button $r.name -text $name -font $f -anchor w -width $width \ -command $cmd -pady 2 -padx 2 -borderwidth 2 \ -highlightthickness 0 -relief raised label $r.smooth -font $f -anchor e -width 8 \ -relief $relief -borderwidth 1 -pady 1 label $r.diff -font $f -anchor e -width 8 \ -relief $relief -borderwidth 1 -pady 1 label $r.total -font $f -anchor e -width 8 \ -relief ridge -borderwidth 1 -pady 1 pack $r.name -anchor w -fill x -side left -pady 1 -padx 4 pack $r.smooth $r.diff $r.total \ -expand 1 -fill both -anchor e -side left } proc create_stats_panel { w stats } { set f [smallfont] set p $w.f frame $p set top [winfo toplevel $w] set gain [resource statsFilter] global rv_diff rv_smooth rv_list win_src set r $p.legend frame $r label $r.smooth -font $f -anchor c -width 8 -text EWA \ -relief ridge -borderwidth 1 label $r.diff -font $f -anchor c -width 8 -text Delta \ -relief ridge -borderwidth 1 label $r.total -font $f -anchor c -width 8 -text Total \ -relief ridge -borderwidth 1 pack $r.total $r.diff $r.smooth -side right pack $r -anchor e set rv_list($top) $stats set n [llength $stats] set width 10 set i 0 while { $i < $n } { set v [string len [lindex $stats $i]] if { $v > $width } { set width $v } incr i 2 } set src $win_src($top) set i 0 while { $i < $n } { set name [lindex $stats $i] incr i set value [lindex $stats $i] incr i set id [string tolower $name] set r $p.$id frame $r set gen "stat_generator \{$src stats\} $name" set cmd "create_plot_window $src $name \{$gen\}" create_stat_row $r $name $width $cmd ridge pack $r -pady 0 set rv_diff($top:$id) $value set rv_smooth($top:$id) $value rate_variable rv_diff($top:$id) 1.0 "%.1f" rate_variable rv_smooth($top:$id) $gain "%.1f" } if { $src != "session" } { set r $p.playout frame $r set cmd "create_plot_window $src Playout \{get-playout $src\}" create_stat_row $r Playout $width $cmd flat pack $r -pady 0 } global stat_window maxStat set stat_window($top) $p catch "unset maxStat($top)" pack $w.f -anchor c } proc stats_changed { s1 s2 } { set n [llength $s1] if { $n != [llength $s2] } { return 1 } set i 0 while { $i < $n } { if { [lindex $s1 $i] != [lindex $s2 $i] } { return 1 } incr i 2 } return 0 } proc stat_update w { global stat_window rv_diff rv_smooth rv_list \ stat_method win_src set stats [eval $stat_method($w)] if [stats_changed $stats $rv_list($w)] { unset_rvs $w pack forget $w.frame destroy $w.frame frame $w.frame -borderwidth 2 -relief groove create_stats_panel $w.frame $stats pack $w.frame -after $w.title -expand 1 -fill x -anchor center } set p $stat_window($w) set i 0 set n [llength $stats] while { $i < $n } { set id [string tolower [lindex $stats $i]] incr i set cntr [lindex $stats $i] incr i set rv_diff($w:$id) $cntr set rv_smooth($w:$id) $cntr $p.$id.total configure -text $cntr $p.$id.diff configure -text $rv_diff($w:$id) $p.$id.smooth configure -text $rv_smooth($w:$id) } if [winfo exists $p.playout.total] { $p.playout.total configure -text [get-playout $win_src($w)]ms } } proc info_update { w src } { set decoder [$src handler] set fmt [rtp_format $src] if { $fmt == "" } { set fmt "?" } $w.title.info configure -text [info_text $src] set t [$src lastdata] if { $t == "" } { set t "never" } $w.title.timeData configure -text "last data $t" set t [$src lastctrl] if { $t == "" } { set t "never" } $w.title.timeCtrl configure -text "last control $t" foreach sdes [resource sdesList] { $w.title.$sdes configure -text "$sdes: [$src sdes $sdes]" } $w.title.srcid configure -text "srcid: [$src srcid]/[$src addr]" if { [$src srcid] != [$src ssrc] } { if ![winfo exists $w.title.mixer] { label $w.title.mixer -borderwidth 0 \ -font [smallfont] -anchor w pack $w.title.mixer -after $w.title.srcid -fill x } $w.title.mixer configure -text "mixer: [$src ssrc]/[$src addr]" } elseif [winfo exists $w.title.mixer] { pack forget $w.title.mixer destroy $w.title.mixer } set note [$src sdes note] if { $note != "" } { set bg [resource infoHighlightColor] } else { set bg [resource background] } $w.title.note configure -background $bg } proc unset_rvs w { global rv_list rv_diff rv_smooth if [info exists rv_list($w)] { set n [llength $rv_list($w)] for { set i 0 } { $i < $n } { incr i 2 } { set id [string tolower [lindex $rv_list($w) $i]] unset rv_diff($w:$id) rv_smooth($w:$id) } unset rv_list($w) } } proc stat_destroy w { unset_rvs $w destroy $w global stat_method win_src unset stat_method($w) win_src($w) } proc info_destroy { w src } { global info_x info_y set info_x($src) [winfo rootx $w] set info_y($src) [winfo rooty $w] destroy $w } proc create_stats_window { w src titleText method } { if [winfo exists $w] { stat_destroy $w return } create_toplevel $w [getid $src] set f [smallfont] frame $w.title -borderwidth 2 -relief groove label $w.title.main -borderwidth 0 -anchor w -text $titleText label $w.title.name -borderwidth 0 -anchor w \ -textvariable src_nickname($src) frame $w.frame -borderwidth 2 -relief groove global win_src stat_method set stat_method($w) $method set win_src($w) $src create_stats_panel $w.frame [eval $method] pack $w.title.name -anchor w pack $w.title.main -anchor w pack $w.title -fill x pack $w.frame -expand 1 -fill x -anchor center wm geometry $w +[winfo pointerx .]+[winfo pointery .] wm deiconify $w window_timer $w stat_update button $w.dismiss -relief raised -font $f \ -command "stat_destroy $w" -text Dismiss pack $w.dismiss -anchor c -pady 4 } proc create_rtp_window src { create_stats_window .rtp$src $src "RTP Statistics" "$src stats" } proc create_decoder_window src { if { "[$src handler]" != "" } { create_stats_window .decoder$src $src \ "Decoder Statistics" "\[$src handler\] stats" } else { open_dialog "no decoder stats yet" } } proc destroy_decoder_stats src { if [winfo exists .decoder$src] { stat_destroy .decoder$src } } proc destroy_rtp_stats src { if [winfo exists .rtp$src] { stat_destroy .rtp$src } if [winfo exists .info$src] { info_destroy .info$src $src } global rv_plot win_src foreach w [array names rv_plot] { if { "$win_src($w)" == "$src" } { plot_destroy $w } } } proc create_global_window {} { set w .global if [winfo exists $w] { stat_destroy $w return } create_toplevel $w "Session Stats" set f [smallfont] frame $w.title -borderwidth 2 -relief groove label $w.title.main -borderwidth 0 -anchor w \ -text "Global Session Statistics" frame $w.frame -borderwidth 2 -relief groove global stat_method win_src set stat_method($w) "session stats" set win_src($w) session create_stats_panel $w.frame [session stats] pack $w.title.main -anchor w pack $w.title -fill x pack $w.frame -expand 1 -fill x -anchor center wm geometry $w +[winfo pointerx .]+[winfo pointery .] wm deiconify $w window_timer $w stat_update button $w.dismiss -relief raised -font $f \ -command "stat_destroy $w" -text Dismiss pack $w.dismiss -anchor c -pady 4 } proc window_timer { w action } { if ![winfo exists $w] { return } $action $w after 1000 "window_timer $w $action" } proc has_src w { global win_src if [string compare $win_src($w) GLOBAL] { return 1 } else { return 0 } } proc stat_generator { method id } { set stats [eval $method] set k [lsearch -exact $stats $id] return [lindex $stats [expr $k + 1]] } proc plot_get w { global plot_generator set v [eval $plot_generator($w)] return $v } proc plot_update w { global rv_plot set rv_plot($w) [plot_get $w] $w.frame.sc set $rv_plot($w) } proc plot_destroy w { global win_src rv_plot plot_generator unset win_src($w) plot_generator($w) rv_plot($w) destroy $w } proc relabel_stripchart {w min max perDiv} { $w configure -text " range $min to $max, $perDiv/div" } proc create_plot_window { src name generator } { global win_src plot_generator set id [string tolower $name] set w .plot$src$id if [winfo exists $w] { plot_destroy $w return } set win_src($w) $src set plot_generator($w) $generator create_toplevel $w "plot window" catch "wm resizable $w true false" set f [smallfont] frame $w.title -borderwidth 2 -relief groove label $w.title.main -borderwidth 0 -anchor w -text $name frame $w.frame -borderwidth 2 -relief groove stripchart $w.frame.sc -max 200 -min 1 -stripwidth 1 -width 1 \ -autoscale 2 -rescale_command "relabel_stripchart $w.bf.lab" \ -relief groove -striprelief flat -tickcolor gray95 -hticks 30 pack $w.frame.sc -expand 1 -fill both frame $w.brace -width 250 pack $w.brace if [has_src $w] { label $w.title.name -borderwidth 0 -anchor w \ -textvariable src_nickname($src) pack $w.title.name -anchor w } pack $w.title.main -anchor w pack $w.title -fill x pack $w.frame -expand 1 -fill both -anchor center if { "$id" != "playout" } { rate_variable rv_plot($w) 1.0 "%.1f" } wm geometry $w +[winfo pointerx .]+[winfo pointery .] wm deiconify $w window_timer $w plot_update frame $w.bf label $w.bf.lab -borderwidth 0 -font $f -anchor w -text "No data" pack $w.bf.lab -side left -expand 1 -fill x button $w.bf.dismiss -relief raised -font $f -anchor e \ -command "plot_destroy $w" -text Dismiss pack $w.bf.dismiss -side right -pady 4 -padx 4 pack $w.bf -expand 1 -fill x } proc create_info_window src { set w .info$src if [winfo exists $w] { info_destroy $w $src return } create_toplevel $w [getid $src] set f [smallfont] frame $w.title -borderwidth 2 -relief groove label $w.title.name -borderwidth 0 -font $f -anchor w \ -textvariable src_nickname($src) label $w.title.info -borderwidth 0 -font $f -anchor w \ -text [$src addr] label $w.title.timeData -borderwidth 0 -font $f -anchor w label $w.title.timeCtrl -borderwidth 0 -font $f -anchor w frame $w.frame -borderwidth 2 -relief groove pack $w.title.name $w.title.info -fill x foreach sdes [resource sdesList] { label $w.title.$sdes -borderwidth 0 -font $f -anchor w pack $w.title.$sdes -fill x } label $w.title.srcid -borderwidth 0 -font $f -anchor w pack $w.title.srcid -fill x pack $w.title.timeData $w.title.timeCtrl -fill x pack $w.title -fill x set p $w.bot frame $p set m $p.mb.menu menubutton $p.mb -text Stats... -menu $m -relief raised -width 8 \ -font $f menu $m $m add command -label RTP -command "create_rtp_window $src" -font $f $m add command -label Decoder \ -command "create_decoder_window $src" -font $f button $p.dismiss -relief raised -font $f \ -command "info_destroy $w $src" -text Dismiss pack $p.mb -side left -padx 8 pack $p.dismiss -side right -padx 8 pack $p -anchor c -pady 4 -fill x info_update $w $src global info_x info_y if [info exists info_x($src) ] { set x $info_x($src) set y $info_y($src) } else { set x [winfo pointerx .] set y [winfo pointery .] } update idletasks if ![winfo exists $w] { return } set right [expr [winfo screenwidth .] - [winfo reqwidth $w] - 5] if { $x > $right } { set x $right } set bot [expr [winfo screenheight .] - [winfo reqheight $w] - 5] if { $y > $bot } { set y $bot } wm geometry $w +$x+$y wm deiconify $w after 3000 "info_timer $w $src" } proc info_timer { w src } { if ![winfo exists $w] { return } info_update $w $src after 3000 "info_timer $w $src" } proc create_mtrace_window {src dir} { set w .mtrace$src if ![winfo exists $w] { create_toplevel $w "[getid $src] mtrace" set f [smallfont] frame $w.t scrollbar $w.t.yscroll -command "$w.t.text yview" -relief sunken scrollbar $w.t.xscroll -command "$w.t.text xview" -relief sunken \ -orient horiz text $w.t.text -height 24 -width 80 -setgrid true -wrap none \ -font fixed -relief sunken -borderwidth 2 \ -xscrollcommand "$w.t.xscroll set" \ -yscrollcommand "$w.t.yscroll set" pack $w.t.yscroll -side right -fill y pack $w.t.xscroll -side bottom -fill x pack $w.t.text -side left -padx 0 -pady 0 -fill both -expand yes set p $w.b frame $p button $p.dismiss -relief raised -font $f \ -command "destroy $w" -text Dismiss pack $p.dismiss -side right -padx 8 pack $w.t -side top -fill both -expand yes pack $p -side bottom -pady 2 -fill x wm geometry $w +[winfo pointerx .]+[winfo pointery .] wm deiconify $w update idletasks if ![winfo exists $w] { return } } else { $w.t.text yview end } global V if {$dir=="to"} { set cmd "|mtrace [$V(data-net) interface] [$V(data-net) addr] [$src addr]" } else { set cmd "|mtrace [$src addr] [$V(data-net) addr]" } if [catch "open {$cmd} r" fd] { $w.t.text insert end "mtrace error: $fd" return } fconfigure $fd -blocking 0 fileevent $fd readable "read_mtrace $fd $w" } proc read_mtrace {fd w} { if [winfo exists $w] { $w.t.text insert end [read $fd] $w.t.text yview end if [eof $fd] { fileevent $fd readable {} catch "close $fd" } } else { fileevent $fd readable {} catch "close $fd" } } proc build_info_menu {src m} { menu $m set f [smallfont] $m add command -label "Site Info" \ -command "create_info_window $src" -font $f $m add command -label "RTP Stats"\ -command "create_rtp_window $src" -font $f $m add command -label "Decoder Stats" \ -command "create_decoder_window $src" -font $f global V if [$V(data-net) ismulticast] { $m add command -label "Mtrace from" \ -command "create_mtrace_window $src from" -font $f $m add command -label "Mtrace to" \ -command "create_mtrace_window $src to" -font $f } } proc create_info_menu {src x y} { set m .menu$src if ![winfo exists $m] { build_info_menu $src $m } tk_popup $m $x $y } Uhjhذ] set cb_dispatch(audio-demand) audio_someone_demands set cb_dispatch(audio-request) audio_someone_requests set cb_dispatch(audio-release) audio_someone_released set audio_activity 0 proc audio_someone_requests { pid pri } { global audioHeld V unmuted outputMutebutton if { [audio have] && !$audioHeld && ($pri > $V(priority) \ || !$unmuted($outputMutebutton))} { audio_give_it_up $pid } } proc audio_release {} { audio release audio_indicator_update } proc audio_give_it_up pid { global V audio_release $V(devbus) send "audio-release $pid" } proc audio_someone_demands pid { if { [audio have] } { audio_give_it_up $pid } } proc audio_someone_released pid { global V autoRaise if { $pid == [pid] } { audio_grab if $autoRaise { raise . } } } proc reset_source_offsets {} { foreach src [session active] { [$src handler] reset-offset } } proc audio_indicator_update { } { global audioHeld title_bar audio_activity if [audio have] { $title_bar configure -font [ctrlfont] reset_source_offsets } else { $title_bar configure -font [option get . noAudioFont Vat] set audioHeld 0 } set audio_activity [controller unix-time] } proc audio_grab {} { global V audio obtain audio_indicator_update } proc audio_request {} { audio obtain if [audio have] { audio_indicator_update } else { global V $V(devbus) send "audio-request [pid] $V(priority)" } } proc audio_demand {} { audio obtain if [audio have] { audio_indicator_update } else { global V $V(devbus) send "audio-demand [pid]" } } proc audio_timeout {} { global audioHeld audio_activity if { [audio have] && !$audioHeld } { if [controller active] { controller active 0 set audio_activity [controller unix-time] } else { set r [resource idleDropTime] if { $r && [controller unix-time] - $audio_activity > \ $r } { audio_give_it_up 0 } } } after 5000 audio_timeout } Uhjh褩] proc run_resource_dialog { name email } { set w .form global V frame $w frame $w.msg -relief ridge label $w.msg.label -font [mediumfont] -wraplength 4i \ -justify left -text \ "Please specify values for the following X resources. \ These strings will identify you by name and by email address \ in any RTP-based conference. Please use your real name and \ affiliation instead of a ``handle'', e.g., ``Jane Doe (ACME Research)''. \ The values you enter will be saved in ~/.RTPdefaults so you will \ not have to re-enter them. You can either leave this file in place \ or merge the contents with your normal X resources." -relief ridge pack $w.msg.label -padx 6 -pady 6 pack $w.msg -side top foreach i {name email} { frame $w.$i -bd 2 entry $w.$i.entry -relief sunken label $w.$i.label -width 10 -anchor e pack $w.$i.label -side left pack $w.$i.entry -side left -fill x -expand 1 -padx 8 } $w.name.label config -text *rtpName: $w.email.label config -text *rtpEmail: pack $w.msg -pady 10 pack $w.name $w.email -side top -fill x $w.$i.entry insert 0 [email_heursitic] frame $w.buttons button $w.buttons.accept -text Accept -command "set dialogDone 1" button $w.buttons.dismiss -text Quit -command "set dialogDone -1" pack $w.buttons.accept $w.buttons.dismiss \ -side left -expand 1 -padx 20 -pady 10 pack $w.buttons pack $w -padx 10 global dialogDone while { 1 } { set dialogDone 0 focus $w.name.entry tkwait variable dialogDone if { $dialogDone < 0 } { exit 0 } set name [string trim [$w.name.entry get]] if { [string length $name] <= 3 } { open_dialog "please enter a reasonable name" continue } set email [string trim [$w.email.entry get]] if { [string first . $email] < 0 || \ [string first @ $email] < 0 } { open_dialog "email address should have form user@host.domain" continue } break } option add *rtpName "$name" interactive option add *rtpEmail "$email" interactive set f [open ~/.RTPdefaults w+ 0644] puts $f "*rtpName: $name" puts $f "*rtpEmail: $email" close $f pack forget $w destroy $w } Uhjh谡] set rtp_type(0) pcm set rtp_type(1) celp set rtp_type(3) gsm set rtp_type(5) dvi set rtp_type(7) lpc proc vat_main {} { global V set V(class) Vat set V(app) vat set V(media) audio init_local set V(devbus) [new confbus 0] $V(devbus) handler confbusHandler init_confbus init_gui init_network init_tk init_late if { [resource sessionType] == "vat" } { set confid [resource confid] if { $confid == "" } { set confid 0 } session confid $confid $V(session) confid $confid } $V(session) loopback 0 $V(session) data-bandwidth 128 } Uhjh脟] proc net_open_ip { sessionType session dst } { global V set c $V(class) set dst [split $dst /] set n [llength $dst] if { $n < 2 } { warn "must specify both address and port in the form addr/port" exit 1 } else { set addr [lindex $dst 0] set port [lindex $dst 1] if { ![string match \[0-9\]* $port] || $port >= 65536 } { warn "illegal port '$port'" exit 1 } if { $n >= 3 } { if { $sessionType == "vat" } { set confid [lindex $dst 2] if { $n >= 4 } { set fmt [lindex $dst 3] if { $n >= 5 } { set ttl [lindex $dst 4] if { $n > 5 } { usage } } } } else { set fmt [lindex $dst 2] if { $n >= 4 } { set ttl [lindex $dst 3] if { $n > 4 } { usage } } } } if { [info exists fmt] && $fmt != "" } { option add $c.defaultFormat $fmt interactive option add $c.audioFormat $fmt interactive } if [info exists confid] { option add $c.confid $confid interactive } if [info exists ttl] { option add $c.defaultTTL $ttl interactive } } set ttl [resource defaultTTL] if { $ttl < 0 || $ttl > 255 } { warn "invalid ttl ($ttl)" exit 1 } if { $sessionType == "rtp" } { set port [expr $port &~ 1] } set dn [new network ip] $dn open $addr $port $ttl $session data-net $dn if { $sessionType != "nv" } { if { $sessionType == "ivs" } { incr port 2 } else { incr port } set cn [new network ip] $cn open $addr $port $ttl $session ctrl-net $cn set V(ctrl-net) $cn } set V(data-net) $dn set maxbw [resource maxbw] if { $maxbw < 0 } { if { $sessionType == "vat" } { switch [resource audioFormat] { pcm { set maxbw 78 } pcm2 { set maxbw 71 } pcm4 { set maxbw 68 } dvi { set maxbw 46 } dvi2 { set maxbw 39 } dvi4 { set maxbw 36 } gsm { set maxbw 17 } lpc4 { set maxbw 9 } default { set maxbw 71 } } } else { if { $ttl <= 16 || ![in_multicast [$dn addr]] } { set maxbw 3072 } elseif { $ttl <= 64 } { set maxbw 1024 } elseif { $ttl <= 128 } { set maxbw 128 } elseif { $ttl <= 192 } { set maxbw 53 } else { set maxbw 32 } } option add $c.maxbw $maxbw interactive } } proc net_open_atm { sessionType session dst } { global V set dataSAP 4092 set ctrlSAP 4090 set dn [new network atm] if { $dn == "" } { warn "not compiled with ATM support" exit 1 } if { [$dn open $dst $dataSAP 256 64 128 128 2 1] < 0 } { warn "cannot open atm connection to $dst" exit 1 } $session data-net $dn set cn [new network atm] if { [$cn open $dst $ctrlSAP 128 64 24 24 2 1] < 0 } { warn "cannot open atm control connection to $dst" exit 1 } $session ctrl-net $cn set V(ctrl-net) $cn set V(data-net) $dn } proc net_open_rtip { sessionType session dst } { global V set dst [split $dst /] set n [llength $dst] if { $n != 2 } { warn "must specify both address and port (i.e., addr/port) for RTIP" exit 1 } set addr [lindex $dst 0] set port [lindex $dst 1] set dn [new network rtip] if { [$dn open $addr $port [resource rtipXmin] [resource rtipXave] \ [resource rtipI] [resource rtipSmax] [resource rtipD] \ [resource rtipJ] [resource rtipZ] [resource rtipW] \ [resource rtipU] [resource rtipType]] < 0 } { warn "cannot open RTIP connection to $addr/$port" exit 1 } $session data-net $dn $session ctrl-net $dn set V(ctrl-net) $cn set V(data-net) $dn } proc init_network {} { set netType [resource network] if { [info procs net_open_$netType] == "" } { warn "$netType not a recognized network type" exit 1 } set sessionType [resource sessionType] if { $sessionType == "rtpv2" || $sessionType == "vic" } { set sessionType rtp } global V set V(sessionType) $sessionType set V(session) [new session $V(media)/$sessionType] if { $V(session) == "" } { warn "'$sessionType' not a recognized session type" exit 1 } net_open_$netType $sessionType $V(session) [resource defaultHostSpec] $V(session) max-bandwidth [resource maxbw] set key [resource sessionKey] if { $key != "" } { crypt_set $key } } proc in_multicast addr { return [expr ([lindex [split $addr .] 0] & 0xf0) == 0xe0] } proc crypt_format {key sessionType} { if {$sessionType == "vat"} { set fmt VAT } else { set k [string first / $key] if { $k < 0 } { set fmt DES1 } else { set fmt [string range $key 0 [expr $k - 1]] set key [string range $key [expr $k + 1] end] } } return "$fmt $key" } proc crypt_set key { global doEncryption entryTab V set L [crypt_format $key $V(sessionType)] set fmt [lindex $L 0] set key [lindex $L 1] set dc data-crypt:$fmt set cc ctrl-crypt:$fmt if ![info exists V($dc)] { set crypt [new crypt $fmt/data] if { $crypt == "" } { open_dialog "no $fmt enryption support" return -1 } set V($dc) $crypt set V($cc) [new crypt $fmt/ctrl] } if [$V($dc) key $key] { $V($cc) key $key $V(data-net) crypt $V($dc) $V(ctrl-net) crypt $V($cc) set V(encrypt) 1 return 0 } else { open_dialog "your key is cryptographically weak" crypt_clear return -1 } } proc crypt_clear {} { global V $V(data-net) crypt "" $V(ctrl-net) crypt "" set V(encrypt) 0 } Uh̦jȟ] proc rtp_format src { global rtp_type set fmt [$src format] if [info exists rtp_type($fmt)] { return $rtp_type($fmt) } elseif { $fmt < 0 } { return "" } else { return fmt-$fmt } } proc local_fqdn {} { set host [gethostname] if { [string first . $host] < 0 } { return "" } return $host } proc init_local {} { global V set f ~/.$V(app).tcl if [file exists $f] { uplevel #0 "source $f" } set script [resource startupScript] if { $script != "" } { uplevel #0 "source $script" } set name [resource rtpName] if { $name == "" } { set name [resource sessionName] option add *rtpName $name startupFile } set email [resource rtpEmail] if { $name == "" || $email == "" } { run_resource_dialog $name $email } } proc email_heursitic {} { set user [user_heuristic] set addr [local_fqdn] if { $addr == "" } { return "" } return $user@$addr } proc user_heuristic {} { global env if [info exists env(USER)] { set user $env(USER) } elseif [info exists env(LOGNAME)] { set user $env(LOGNAME) } else { catch "set env(USER) [getusername]" if [info exists env(USER)] { return $env(USER) } return "UNKNOWN" } } proc user_hook {} { } proc init_late {} { global V env set net $V(data-net) set srcid [session random-srcid [$net addr]] set src [srctab create-local $srcid [$net interface]] set cname [resource cname] if { $cname == "" } { set interface [$net interface] if { $interface == "0.0.0.0" } { set interface [session local-addr-heuristic] } set cname [user_heuristic]@$interface } $src sdes name [resource rtpName] $src sdes email [resource rtpEmail] $src sdes cname $cname set tool $V(app)-[version] global tcl_platform if {[info exists tcl_platform(os)] && $tcl_platform(os) != "" && \ $tcl_platform(os) != "unix"} { set p $tcl_platform(os) if {$tcl_platform(osVersion) != ""} { set p $p-$tcl_platform(osVersion) } if {$tcl_platform(machine) != ""} { set p $p-$tcl_platform(machine) } set tool "$tool/$p" } $src sdes tool $tool global prefix set prefix [resource iconPrefix] set conf [resource conferenceName] if { $conf == "" } { global V set net $V(data-net) set conf [$net addr]/[$net port] } wm iconname . "$prefix$conf" wm title . $conf set V(confname) [wm title .] set V(useHardwareDecode) [yesno useHardwareDecode] srctab site-drop-time [resource siteDropTime] user_hook } proc warn s { global V puts stderr "$V(app): $s" } proc debug s { if [yesno debug] { warn $s } } proc have what { global V return [info exists V($what)] } proc resource r { global V return [option get . $r $V(class)] } proc yesno attr { set v [resource $attr] if { [string match \[0-9\]* $v] } { return $v } if { $v == "true" || $v == "True" || $v == "t" } { return 1 } return 0 } proc getid src { set name [$src sdes name] if { $name == "" } { set name [$src sdes cname] if { $name == "" } { set name [$src addr] } } return $name } Uhjh(谁] proc confbusHandler { cb msg } { global cb_dispatch if { [llength $msg] < 1 } { debug "bad confbus message: $msg" return } set class [lindex $msg 0] if ![info exists cb_dispatch($class)] { debug "no such confbus method: $class" return } set proc $cb_dispatch($class) set formals [info args $proc] set actuals [lrange $msg 1 end] if { [llength $actuals] != [llength $formals] } { debug "confbus arg mismatch: $class ($formals)/($actuals)" return } eval "$proc $actuals" } proc init_confbus {} { set channel [resource confBusChannel] if { $channel != 0 } { global V set V(cb) [new confbus $channel] $V(cb) handler confbusHandler } } Uhjh4] if {[info commands package] == ""} { error "version mismatch: library\nscripts expect Tcl version 7.5b1 or later but the loaded version is\nonly [info patchlevel]" } package require -exact Tcl 7.5 if [catch {set auto_path $env(TCLLIBPATH)}] { set auto_path "" } if {[lsearch -exact $auto_path [info library]] < 0} { lappend auto_path [info library] } package unknown tclPkgUnknown if {[info commands exec] == ""} { set auto_noexec 1 } set errorCode "" set errorInfo "" proc unknown args { global auto_noexec auto_noload env unknown_pending tcl_interactive global errorCode errorInfo set savedErrorCode $errorCode set savedErrorInfo $errorInfo set name [lindex $args 0] if ![info exists auto_noload] { if [info exists unknown_pending($name)] { unset unknown_pending($name) if {[array size unknown_pending] == 0} { unset unknown_pending } return -code error "self-referential recursion in \"unknown\" for command \"$name\""; } set unknown_pending($name) pending; set ret [catch {auto_load $name} msg] unset unknown_pending($name); if {$ret != 0} { return -code $ret -errorcode $errorCode \ "error while autoloading \"$name\": $msg" } if ![array size unknown_pending] { unset unknown_pending } if $msg { set errorCode $savedErrorCode set errorInfo $savedErrorInfo set code [catch {uplevel $args} msg] if {$code == 1} { set new [split $errorInfo \n] set new [join [lrange $new 0 [expr [llength $new] - 6]] \n] return -code error -errorcode $errorCode \ -errorinfo $new $msg } else { return -code $code $msg } } } if {([info level] == 1) && ([info script] == "") \ && [info exists tcl_interactive] && $tcl_interactive} { if ![info exists auto_noexec] { if [auto_execok $name] { set errorCode $savedErrorCode set errorInfo $savedErrorInfo return [uplevel exec >&@stdout <@stdin $args] } } set errorCode $savedErrorCode set errorInfo $savedErrorInfo if {$name == "!!"} { return [uplevel {history redo}] } if [regexp {^!(.+)$} $name dummy event] { return [uplevel [list history redo $event]] } if [regexp {^\^([^^]*)\^([^^]*)\^?$} $name dummy old new] { return [uplevel [list history substitute $old $new]] } set cmds [info commands $name*] if {[llength $cmds] == 1} { return [uplevel [lreplace $args 0 0 $cmds]] } if {[llength $cmds] != 0} { if {$name == ""} { return -code error "empty command name \"\"" } else { return -code error \ "ambiguous command name \"$name\": [lsort $cmds]" } } } return -code error "invalid command name \"$name\"" } proc auto_load cmd { global auto_index auto_oldpath auto_path env errorInfo errorCode if [info exists auto_index($cmd)] { uplevel #0 $auto_index($cmd) return [expr {[info commands $cmd] != ""}] } if ![info exists auto_path] { return 0 } if [info exists auto_oldpath] { if {$auto_oldpath == $auto_path} { return 0 } } set auto_oldpath $auto_path for {set i [expr [llength $auto_path] - 1]} {$i >= 0} {incr i -1} { set dir [lindex $auto_path $i] set f "" if [catch {set f [open [file join $dir tclIndex]]}] { continue } set error [catch { set id [gets $f] if {$id == "# Tcl autoload index file, version 2.0"} { eval [read $f] } elseif {$id == "# Tcl autoload index file: each line identifies a Tcl"} { while {[gets $f line] >= 0} { if {([string index $line 0] == "#") || ([llength $line] != 2)} { continue } set name [lindex $line 0] set auto_index($name) \ "source [file join $dir [lindex $line 1]]" } } else { error "[file join $dir tclIndex] isn't a proper Tcl index file" } } msg] if {$f != ""} { close $f } if $error { error $msg $errorInfo $errorCode } } if [info exists auto_index($cmd)] { uplevel #0 $auto_index($cmd) if {[info commands $cmd] != ""} { return 1 } } return 0 } if {[string compare $tcl_platform(platform) windows] == 0} { proc auto_execok name { global auto_execs env if [info exists auto_execs($name)] { return $auto_execs($name) } set auto_execs($name) 0 if {[file pathtype $name] != "relative"} { foreach ext {.exe .bat .cmd} { if {[file exists ${name}${ext}] && ![file isdirectory ${name}${ext}]} { set auto_execs($name) 1 } } return $auto_execs($name) } if {! [info exists env(PATH)]} { if [info exists env(Path)] { set path $env(Path) } else { return 0 } } else { set path $env(PATH) } foreach dir [split $path {;}] { if {$dir == ""} { set dir . } foreach ext {.exe .bat .cmd} { set file [file join $dir ${name}${ext}] if {[file exists $file] && ![file isdirectory $file]} { set auto_execs($name) 1 return 1 } } } return 0 } } else { proc auto_execok name { global auto_execs env if [info exists auto_execs($name)] { return $auto_execs($name) } set auto_execs($name) 0 if {[file pathtype $name] != "relative"} { if {[file executable $name] && ![file isdirectory $name]} { set auto_execs($name) 1 } return $auto_execs($name) } foreach dir [split $env(PATH) :] { if {$dir == ""} { set dir . } set file [file join $dir $name] if {[file executable $file] && ![file isdirectory $file]} { set auto_execs($name) 1 return 1 } } return 0 } } proc auto_reset {} { global auto_execs auto_index auto_oldpath foreach p [info procs] { if {[info exists auto_index($p)] && ($p != "unknown") && ![string match auto_* $p]} { rename $p {} } } catch {unset auto_execs} catch {unset auto_index} catch {unset auto_oldpath} } proc auto_mkindex {dir args} { global errorCode errorInfo set oldDir [pwd] cd $dir set dir [pwd] append index "# Tcl autoload index file, version 2.0\n" append index "# This file is generated by the \"auto_mkindex\" command\n" append index "# and sourced to set up indexing information for one or\n" append index "# more commands. Typically each line is a command that\n" append index "# sets an element in the auto_index array, where the\n" append index "# element name is the name of a command and the value is\n" append index "# a script that loads the command.\n\n" if {$args == ""} { set args *.tcl } foreach file [eval glob $args] { set f "" set error [catch { set f [open $file] while {[gets $f line] >= 0} { if [regexp {^proc[ ]+([^ ]*)} $line match procName] { append index "set [list auto_index($procName)]" append index " \[list source \[file join \$dir [list $file]\]\]\n" } } close $f } msg] if $error { set code $errorCode set info $errorInfo catch {close $f} cd $oldDir error $msg $info $code } } set f "" set error [catch { set f [open tclIndex w] puts $f $index nonewline close $f cd $oldDir } msg] if $error { set code $errorCode set info $errorInfo catch {close $f} cd $oldDir error $msg $info $code } } proc pkg_mkIndex {dir args} { global errorCode errorInfo append index "# Tcl package index file, version 1.0\n" append index "# This file is generated by the \"pkg_mkIndex\" command\n" append index "# and sourced either when an application starts up or\n" append index "# by a \"package unknown\" script. It invokes the\n" append index "# \"package ifneeded\" command to set up package-related\n" append index "# information so that packages will be loaded automatically\n" append index "# in response to \"package require\" commands. When this\n" append index "# script is sourced, the variable \$dir must contain the\n" append index "# full path name of this file's directory.\n" set oldDir [pwd] cd $dir foreach file [eval glob $args] { set c [interp create] $c eval [list set file $file] if [catch { $c eval { proc dummy args {} package unknown dummy set origCmds [info commands] set dir "" ;# in case file is pkgIndex.tcl set pkgs "" if [catch {load [file join . $file]}] { if [catch {source $file}] { puts $errorInfo error "can't either load or source $file" } else { set type source } } else { set type load } foreach i [info commands] { set cmds($i) 1 } foreach i $origCmds { catch {unset cmds($i)} } foreach i [package names] { if {([string compare [package provide $i] ""] != 0) && ([string compare $i Tcl] != 0)} { lappend pkgs [list $i [package provide $i]] } } } } msg] { interp delete $c error $msg $errorInfo $errorCode } foreach pkg [$c eval set pkgs] { lappend files($pkg) [list $file [$c eval set type] \ [lsort [$c eval array names cmds]]] } interp delete $c } foreach pkg [lsort [array names files]] { append index "\npackage ifneeded $pkg\ \"tclPkgSetup \$dir [lrange $pkg 0 0] [lrange $pkg 1 1]\ [list $files($pkg)]\"" } set f [open pkgIndex.tcl w] puts $f $index close $f cd $oldDir } proc tclPkgSetup {dir pkg version files} { global auto_index package provide $pkg $version foreach fileInfo $files { set f [lindex $fileInfo 0] set type [lindex $fileInfo 1] foreach cmd [lindex $fileInfo 2] { if {$type == "load"} { set auto_index($cmd) [list load [file join $dir $f] $pkg] } else { set auto_index($cmd) [list source [file join $dir $f]] } } } } proc tclPkgUnknown {name version {exact {}}} { global auto_path if ![info exists auto_path] { return } for {set i [expr [llength $auto_path] - 1]} {$i >= 0} {incr i -1} { set dir [lindex $auto_path $i] set file [file join $dir pkgIndex.tcl] if [file readable $file] { } } } package require -exact Tk 4.1 package require -exact Tcl 7.5 if {[lsearch -exact $auto_path $tk_library] < 0} { lappend auto_path $tk_library } set tk_strictMotif 0 proc tkScreenChanged screen { set disp [file rootname $screen] uplevel #0 upvar #0 tkPriv.$disp tkPriv global tkPriv if [info exists tkPriv] { set tkPriv(screen) $screen return } set tkPriv(afterId) {} set tkPriv(buttons) 0 set tkPriv(buttonWindow) {} set tkPriv(dragging) 0 set tkPriv(focus) {} set tkPriv(grab) {} set tkPriv(initPos) {} set tkPriv(inMenubutton) {} set tkPriv(listboxPrev) {} set tkPriv(mouseMoved) 0 set tkPriv(oldGrab) {} set tkPriv(popup) {} set tkPriv(postedMb) {} set tkPriv(pressX) 0 set tkPriv(pressY) 0 set tkPriv(screen) $screen set tkPriv(selectMode) char set tkPriv(window) {} } tkScreenChanged [winfo screen .] if {$tcl_platform(platform) != "macintosh"} { } bind all {focus [tk_focusNext %W]} bind all {focus [tk_focusPrev %W]} proc tkCancelRepeat {} { global tkPriv after cancel $tkPriv(afterId) set tkPriv(afterId) {} } bind Button {} bind Button { tkButtonEnter %W } bind Button { tkButtonLeave %W } bind Button <1> { tkButtonDown %W } bind Button { tkButtonUp %W } bind Button { tkButtonInvoke %W } bind Checkbutton {} bind Checkbutton { tkButtonEnter %W } bind Checkbutton { tkButtonLeave %W } bind Checkbutton <1> { tkCheckRadioInvoke %W } bind Checkbutton { tkCheckRadioInvoke %W } bind Checkbutton { if !$tk_strictMotif { tkCheckRadioInvoke %W } } bind Radiobutton {} bind Radiobutton { tkButtonEnter %W } bind Radiobutton { tkButtonLeave %W } bind Radiobutton <1> { tkCheckRadioInvoke %W } bind Radiobutton { tkCheckRadioInvoke %W } bind Radiobutton { if !$tk_strictMotif { tkCheckRadioInvoke %W } } proc tkButtonEnter {w} { global tkPriv if {[$w cget -state] != "disabled"} { $w config -state active if {$tkPriv(buttonWindow) == $w} { $w configure -state active -relief sunken } } set tkPriv(window) $w } proc tkButtonLeave w { global tkPriv if {[$w cget -state] != "disabled"} { $w config -state normal } if {$w == $tkPriv(buttonWindow)} { $w configure -relief $tkPriv(relief) } set tkPriv(window) "" } proc tkButtonDown w { global tkPriv set tkPriv(relief) [lindex [$w config -relief] 4] if {[$w cget -state] != "disabled"} { set tkPriv(buttonWindow) $w $w config -relief sunken } } proc tkButtonUp w { global tkPriv if {$w == $tkPriv(buttonWindow)} { set tkPriv(buttonWindow) "" $w config -relief $tkPriv(relief) if {($w == $tkPriv(window)) && ([$w cget -state] != "disabled")} { uplevel #0 [list $w invoke] } } } proc tkButtonInvoke w { if {[$w cget -state] != "disabled"} { set oldRelief [$w cget -relief] set oldState [$w cget -state] $w configure -state active -relief sunken update idletasks after 100 $w configure -state $oldState -relief $oldRelief uplevel #0 [list $w invoke] } } proc tkCheckRadioInvoke w { if {[$w cget -state] != "disabled"} { uplevel #0 [list $w invoke] } } proc tk_dialog {w title text bitmap default args} { global tkPriv catch {destroy $w} toplevel $w -class Dialog wm title $w $title wm iconname $w Dialog wm protocol $w WM_DELETE_WINDOW { } frame $w.bot -relief raised -bd 1 pack $w.bot -side bottom -fill both frame $w.top -relief raised -bd 1 pack $w.top -side top -fill both -expand 1 option add *Dialog.msg.wrapLength 3i widgetDefault label $w.msg -justify left -text $text catch {$w.msg configure -font \ -Adobe-Times-Medium-R-Normal--*-180-*-*-*-*-*-* } pack $w.msg -in $w.top -side right -expand 1 -fill both -padx 3m -pady 3m if {$bitmap != ""} { label $w.bitmap -bitmap $bitmap pack $w.bitmap -in $w.top -side left -padx 3m -pady 3m } set i 0 foreach but $args { button $w.button$i -text $but -command "set tkPriv(button) $i" if {$i == $default} { frame $w.default -relief sunken -bd 1 raise $w.button$i $w.default pack $w.default -in $w.bot -side left -expand 1 -padx 3m -pady 2m pack $w.button$i -in $w.default -padx 2m -pady 2m } else { pack $w.button$i -in $w.bot -side left -expand 1 \ -padx 3m -pady 2m } incr i } if {$default >= 0} { bind $w " $w.button$default configure -state active -relief sunken update idletasks after 100 set tkPriv(button) $default " } wm withdraw $w update idletasks set x [expr [winfo screenwidth $w]/2 - [winfo reqwidth $w]/2 \ - [winfo vrootx [winfo parent $w]]] set y [expr [winfo screenheight $w]/2 - [winfo reqheight $w]/2 \ - [winfo vrooty [winfo parent $w]]] wm geom $w +$x+$y wm deiconify $w set oldFocus [focus] set oldGrab [grab current $w] if {$oldGrab != ""} { set grabStatus [grab status $oldGrab] } grab $w if {$default >= 0} { focus $w.button$default } else { focus $w } tkwait variable tkPriv(button) catch {focus $oldFocus} destroy $w if {$oldGrab != ""} { if {$grabStatus == "global"} { grab -global $oldGrab } else { grab $oldGrab } } return $tkPriv(button) } proc tkEntryClipboardKeysyms {copy cut paste} { bind Entry <$copy> { if {[selection own -displayof %W] == "%W"} { clipboard clear -displayof %W catch { clipboard append -displayof %W [selection get -displayof %W] } } } bind Entry <$cut> { if {[selection own -displayof %W] == "%W"} { clipboard clear -displayof %W catch { clipboard append -displayof %W [selection get -displayof %W] %W delete sel.first sel.last } } } bind Entry <$paste> { catch { %W insert insert [selection get -displayof %W \ -selection CLIPBOARD] } } } bind Entry <1> { tkEntryButton1 %W %x %W selection clear } bind Entry { set tkPriv(x) %x tkEntryMouseSelect %W %x } bind Entry { set tkPriv(selectMode) word tkEntryMouseSelect %W %x catch {%W icursor sel.first} } bind Entry { set tkPriv(selectMode) line tkEntryMouseSelect %W %x %W icursor 0 } bind Entry { set tkPriv(selectMode) char %W selection adjust @%x } bind Entry { set tkPriv(selectMode) word tkEntryMouseSelect %W %x } bind Entry { set tkPriv(selectMode) line tkEntryMouseSelect %W %x } bind Entry { set tkPriv(x) %x tkEntryAutoScan %W } bind Entry { tkCancelRepeat } bind Entry { tkCancelRepeat } bind Entry { %W icursor @%x } bind Entry { if {!$tkPriv(mouseMoved) || $tk_strictMotif} { tkEntryPaste %W %x } } bind Entry { tkEntrySetCursor %W [expr [%W index insert] - 1] } bind Entry { tkEntrySetCursor %W [expr [%W index insert] + 1] } bind Entry { tkEntryKeySelect %W [expr [%W index insert] - 1] tkEntrySeeInsert %W } bind Entry { tkEntryKeySelect %W [expr [%W index insert] + 1] tkEntrySeeInsert %W } bind Entry { tkEntrySetCursor %W \ [string wordstart [%W get] [expr [%W index insert] - 1]] } bind Entry { tkEntrySetCursor %W [string wordend [%W get] [%W index insert]] } bind Entry { tkEntryKeySelect %W \ [string wordstart [%W get] [expr [%W index insert] - 1]] tkEntrySeeInsert %W } bind Entry { tkEntryKeySelect %W [string wordend [%W get] [%W index insert]] tkEntrySeeInsert %W } bind Entry { tkEntrySetCursor %W 0 } bind Entry { tkEntryKeySelect %W 0 tkEntrySeeInsert %W } bind Entry { tkEntrySetCursor %W end } bind Entry { tkEntryKeySelect %W end tkEntrySeeInsert %W } bind Entry { if [%W selection present] { %W delete sel.first sel.last } else { %W delete insert } } bind Entry { tkEntryBackspace %W } bind Entry { %W selection from insert } bind Entry { tkListboxBeginSelect %W [%W index active] } bind Listbox { tkListboxBeginExtend %W [%W index active] } bind Listbox { tkListboxBeginExtend %W [%W index active] } bind Listbox { tkListboxCancel %W } bind Listbox { tkListboxSelectAll %W } bind Listbox { if {[%W cget -selectmode] != "browse"} { %W selection clear 0 end } } bind Listbox <2> { %W scan mark %x %y } bind Listbox { %W scan dragto %x %y } proc tkListboxBeginSelect {w el} { global tkPriv if {[$w cget -selectmode] == "multiple"} { if [$w selection includes $el] { $w selection clear $el } else { $w selection set $el } } else { $w selection clear 0 end $w selection set $el $w selection anchor $el set tkPriv(listboxSelection) {} set tkPriv(listboxPrev) $el } } proc tkListboxMotion {w el} { global tkPriv if {$el == $tkPriv(listboxPrev)} { return } set anchor [$w index anchor] switch [$w cget -selectmode] { browse { $w selection clear 0 end $w selection set $el set tkPriv(listboxPrev) $el } extended { set i $tkPriv(listboxPrev) if [$w selection includes anchor] { $w selection clear $i $el $w selection set anchor $el } else { $w selection clear $i $el $w selection clear anchor $el } while {($i < $el) && ($i < $anchor)} { if {[lsearch $tkPriv(listboxSelection) $i] >= 0} { $w selection set $i } incr i } while {($i > $el) && ($i > $anchor)} { if {[lsearch $tkPriv(listboxSelection) $i] >= 0} { $w selection set $i } incr i -1 } set tkPriv(listboxPrev) $el } } } proc tkListboxBeginExtend {w el} { if {([$w cget -selectmode] == "extended") && [$w selection includes anchor]} { tkListboxMotion $w $el } } proc tkListboxBeginToggle {w el} { global tkPriv if {[$w cget -selectmode] == "extended"} { set tkPriv(listboxSelection) [$w curselection] set tkPriv(listboxPrev) $el $w selection anchor $el if [$w selection includes $el] { $w selection clear $el } else { $w selection set $el } } } proc tkListboxAutoScan {w} { global tkPriv if {![winfo exists $w]} return set x $tkPriv(x) set y $tkPriv(y) if {$y >= [winfo height $w]} { $w yview scroll 1 units } elseif {$y < 0} { $w yview scroll -1 units } elseif {$x >= [winfo width $w]} { $w xview scroll 2 units } elseif {$x < 0} { $w xview scroll -2 units } else { return } tkListboxMotion $w [$w index @$x,$y] set tkPriv(afterId) [after 50 tkListboxAutoScan $w] } proc tkListboxUpDown {w amount} { global tkPriv $w activate [expr [$w index active] + $amount] $w see active switch [$w cget -selectmode] { browse { $w selection clear 0 end $w selection set active } extended { $w selection clear 0 end $w selection set active $w selection anchor active set tkPriv(listboxPrev) [$w index active] set tkPriv(listboxSelection) {} } } } proc tkListboxExtendUpDown {w amount} { if {[$w cget -selectmode] != "extended"} { return } $w activate [expr [$w index active] + $amount] $w see active tkListboxMotion $w [$w index active] } proc tkListboxDataExtend {w el} { set mode [$w cget -selectmode] if {$mode == "extended"} { $w activate $el $w see $el if [$w selection includes anchor] { tkListboxMotion $w $el } } elseif {$mode == "multiple"} { $w activate $el $w see $el } } proc tkListboxCancel w { global tkPriv if {[$w cget -selectmode] != "extended"} { return } set first [$w index anchor] set last $tkPriv(listboxPrev) if {$first > $last} { set tmp $first set first $last set last $tmp } $w selection clear $first $last while {$first <= $last} { if {[lsearch $tkPriv(listboxSelection) $first] >= 0} { $w selection set $first } incr first } } proc tkListboxSelectAll w { set mode [$w cget -selectmode] if {($mode == "single") || ($mode == "browse")} { $w selection clear 0 end $w selection set active } else { $w selection set 0 end } } bind Menubutton {} bind Menubutton { tkMbEnter %W } bind Menubutton { tkMbLeave %W } bind Menubutton <1> { if {$tkPriv(inMenubutton) != ""} { tkMbPost $tkPriv(inMenubutton) %X %Y } } bind Menubutton { tkMbMotion %W up %X %Y } bind Menubutton { tkMbMotion %W down %X %Y } bind Menubutton { tkMbButtonUp %W } bind Menubutton { tkMbPost %W tkMenuFirstEntry [%W cget -menu] } bind Menu {} bind Menu { set tkPriv(window) %W if {"%m" != "NotifyUngrab"} { focus %W } } bind Menu { tkMenuLeave %W %X %Y %s } bind Menu { tkMenuMotion %W %y %s } bind Menu { tkMenuButtonDown %W } bind Menu { tkMenuInvoke %W 1 } bind Menu { tkMenuInvoke %W 0 } bind Menu { tkMenuInvoke %W 0 } bind Menu { tkMenuEscape %W } bind Menu { tkMenuLeftRight %W left } bind Menu { tkMenuLeftRight %W right } bind Menu { tkMenuNextEntry %W -1 } bind Menu { tkMenuNextEntry %W +1 } bind Menu { tkTraverseWithinMenu %W %A } bind all { tkTraverseToMenu %W %A } bind all { tkFirstMenu %W } proc tkMbEnter w { global tkPriv if {$tkPriv(inMenubutton) != ""} { tkMbLeave $tkPriv(inMenubutton) } set tkPriv(inMenubutton) $w if {[$w cget -state] != "disabled"} { $w configure -state active } } proc tkMbLeave w { global tkPriv set tkPriv(inMenubutton) {} if ![winfo exists $w] { return } if {[$w cget -state] == "active"} { $w configure -state normal } } proc tkMbPost {w {x {}} {y {}}} { global tkPriv if {([$w cget -state] == "disabled") || ($w == $tkPriv(postedMb))} { return } set menu [$w cget -menu] if {$menu == ""} { return } if ![string match $w.* $menu] { error "can't post $menu: it isn't a descendant of $w (this is a new requirement in Tk versions 3.0 and later)" } set cur $tkPriv(postedMb) if {$cur != ""} { tkMenuUnpost {} } set tkPriv(cursor) [$w cget -cursor] set tkPriv(relief) [$w cget -relief] $w configure -cursor arrow $w configure -relief raised set tkPriv(postedMb) $w set tkPriv(focus) [focus] $menu activate none if [$w cget -indicatoron] { if {$y == ""} { set x [expr [winfo rootx $w] + [winfo width $w]/2] set y [expr [winfo rooty $w] + [winfo height $w]/2] } tkPostOverPoint $menu $x $y [tkMenuFindName $menu [$w cget -text]] } else { $menu post [winfo rootx $w] [expr [winfo rooty $w]+[winfo height $w]] } focus $menu tkSaveGrabInfo $w grab -global $w } proc tkMenuUnpost menu { global tkPriv set mb $tkPriv(postedMb) catch {focus $tkPriv(focus)} set tkPriv(focus) "" catch { if {$mb != ""} { set menu [$mb cget -menu] $menu unpost set tkPriv(postedMb) {} $mb configure -cursor $tkPriv(cursor) $mb configure -relief $tkPriv(relief) } elseif {$tkPriv(popup) != ""} { $tkPriv(popup) unpost set tkPriv(popup) {} } elseif {[wm overrideredirect $menu]} { while 1 { set parent [winfo parent $menu] if {([winfo class $parent] != "Menu") || ![winfo ismapped $parent]} { break } $parent activate none $parent postcascade none if {![wm overrideredirect $parent]} { break } set menu $parent } $menu unpost } } if {$menu != ""} { catch { set grab [grab current $menu] if {$grab != ""} { grab release $grab } } } if {$tkPriv(oldGrab) != ""} { catch { if {$tkPriv(grabStatus) == "global"} { grab set -global $tkPriv(oldGrab) } else { grab set $tkPriv(oldGrab) } } set tkPriv(oldGrab) "" } } proc tkMbMotion {w upDown rootx rooty} { global tkPriv if {$tkPriv(inMenubutton) == $w} { return } set new [winfo containing $rootx $rooty] if {($new != $tkPriv(inMenubutton)) && (($new == "") || ([winfo toplevel $new] == [winfo toplevel $w]))} { if {$tkPriv(inMenubutton) != ""} { tkMbLeave $tkPriv(inMenubutton) } if {($new != "") && ([winfo class $new] == "Menubutton") && ([$new cget -indicatoron] == 0) && ([$w cget -indicatoron] == 0)} { if {$upDown == "down"} { tkMbPost $new $rootx $rooty } else { tkMbEnter $new } } } } proc tkMbButtonUp w { global tkPriv if {($tkPriv(postedMb) == $w) && ($tkPriv(inMenubutton) == $w)} { tkMenuFirstEntry [$tkPriv(postedMb) cget -menu] } else { tkMenuUnpost {} } } proc tkMenuMotion {menu y state} { global tkPriv if {$menu == $tkPriv(window)} { $menu activate @$y } if {($state & 0x1f00) != 0} { $menu postcascade active } } proc tkMenuButtonDown menu { global tkPriv $menu postcascade active if {$tkPriv(postedMb) != ""} { grab -global $tkPriv(postedMb) } else { while {[wm overrideredirect $menu] && ([winfo class [winfo parent $menu]] == "Menu") && [winfo ismapped [winfo parent $menu]]} { set menu [winfo parent $menu] } if {$menu != [grab current $menu]} { tkSaveGrabInfo $menu } grab -global $menu } } proc tkMenuLeave {menu rootx rooty state} { global tkPriv set tkPriv(window) {} if {[$menu index active] == "none"} { return } if {([$menu type active] == "cascade") && ([winfo containing $rootx $rooty] == [$menu entrycget active -menu])} { return } $menu activate none } proc tkMenuInvoke {w buttonRelease} { global tkPriv if {$buttonRelease && ($tkPriv(window) == "")} { $w postcascade none $w activate none tkMenuUnpost $w return } if {[$w type active] == "cascade"} { $w postcascade active set menu [$w entrycget active -menu] tkMenuFirstEntry $menu } elseif {[$w type active] == "tearoff"} { tkMenuUnpost $w tkTearOffMenu $w } else { tkMenuUnpost $w uplevel #0 [list $w invoke active] } } proc tkMenuEscape menu { if {[winfo class [winfo parent $menu]] != "Menu"} { tkMenuUnpost $menu } else { tkMenuLeftRight $menu -1 } } proc tkMenuLeftRight {menu direction} { global tkPriv if {$direction == "right"} { set count 1 if {[$menu type active] == "cascade"} { $menu postcascade active set m2 [$menu entrycget active -menu] if {$m2 != ""} { tkMenuFirstEntry $m2 } return } } else { set count -1 set m2 [winfo parent $menu] if {[winfo class $m2] == "Menu"} { $menu activate none focus $m2 set tmp [$m2 index active] $m2 activate none $m2 activate $tmp return } } set w $tkPriv(postedMb) if {$w == ""} { return } set buttons [winfo children [winfo parent $w]] set length [llength $buttons] set i [expr [lsearch -exact $buttons $w] + $count] while 1 { while {$i < 0} { incr i $length } while {$i >= $length} { incr i -$length } set mb [lindex $buttons $i] if {([winfo class $mb] == "Menubutton") && ([$mb cget -state] != "disabled") && ([$mb cget -menu] != "") && ([[$mb cget -menu] index last] != "none")} { break } if {$mb == $w} { return } incr i $count } tkMbPost $mb tkMenuFirstEntry [$mb cget -menu] } proc tkMenuNextEntry {menu count} { global tkPriv if {[$menu index last] == "none"} { return } set length [expr [$menu index last]+1] set quitAfter $length set active [$menu index active] if {$active == "none"} { set i 0 } else { set i [expr $active + $count] } while 1 { if {$quitAfter <= 0} { return } while {$i < 0} { incr i $length } while {$i >= $length} { incr i -$length } if {[catch {$menu entrycget $i -state} state] == 0} { if {$state != "disabled"} { break } } if {$i == $active} { return } incr i $count incr quitAfter -1 } $menu activate $i $menu postcascade $i } proc tkMenuFind {w char} { global tkPriv set char [string tolower $char] foreach child [winfo child $w] { switch [winfo class $child] { Menubutton { set char2 [string index [$child cget -text] \ [$child cget -underline]] if {([string compare $char [string tolower $char2]] == 0) || ($char == "")} { if {[$child cget -state] != "disabled"} { return $child } } } Frame { set match [tkMenuFind $child $char] if {$match != ""} { return $match } } } } return {} } proc tkTraverseToMenu {w char} { global tkPriv if {$char == ""} { return } while {[winfo class $w] == "Menu"} { if {$tkPriv(postedMb) == ""} { return } set w [winfo parent $w] } set w [tkMenuFind [winfo toplevel $w] $char] if {$w != ""} { tkMbPost $w tkMenuFirstEntry [$w cget -menu] } } proc tkFirstMenu w { set w [tkMenuFind [winfo toplevel $w] ""] if {$w != ""} { tkMbPost $w tkMenuFirstEntry [$w cget -menu] } } proc tkTraverseWithinMenu {w char} { if {$char == ""} { return } set char [string tolower $char] set last [$w index last] if {$last == "none"} { return } for {set i 0} {$i <= $last} {incr i} { if [catch {set char2 [string index \ [$w entrycget $i -label] \ [$w entrycget $i -underline]]}] { continue } if {[string compare $char [string tolower $char2]] == 0} { if {[$w type $i] == "cascade"} { $w postcascade $i $w activate $i set m2 [$w entrycget $i -menu] if {$m2 != ""} { tkMenuFirstEntry $m2 } } else { tkMenuUnpost $w uplevel #0 [list $w invoke $i] } return } } } proc tkMenuFirstEntry menu { if {$menu == ""} { return } focus $menu if {[$menu index active] != "none"} { return } set last [$menu index last] if {$last == "none"} { return } for {set i 0} {$i <= $last} {incr i} { if {([catch {set state [$menu entrycget $i -state]}] == 0) && ($state != "disabled") && ([$menu type $i] != "tearoff")} { $menu activate $i return } } } proc tkMenuFindName {menu s} { set i "" if {![regexp {^active$|^last$|^none$|^[0-9]|^@} $s]} { catch {set i [$menu index $s]} return $i } set last [$menu index last] if {$last == "none"} { return } for {set i 0} {$i <= $last} {incr i} { if ![catch {$menu entrycget $i -label} label] { if {$label == $s} { return $i } } } return "" } proc tkPostOverPoint {menu x y {entry {}}} { if {$entry != {}} { if {$entry == [$menu index last]} { incr y [expr -([$menu yposition $entry] \ + [winfo reqheight $menu])/2] } else { incr y [expr -([$menu yposition $entry] \ + [$menu yposition [expr $entry+1]])/2] } incr x [expr -[winfo reqwidth $menu]/2] } $menu post $x $y if {($entry != {}) && ([$menu entrycget $entry -state] != "disabled")} { $menu activate $entry } } proc tkSaveGrabInfo w { global tkPriv set tkPriv(oldGrab) [grab current $w] if {$tkPriv(oldGrab) != ""} { set tkPriv(grabStatus) [grab status $tkPriv(oldGrab)] } } proc tk_popup {menu x y {entry {}}} { global tkPriv if {($tkPriv(popup) != "") || ($tkPriv(postedMb) != "")} { tkMenuUnpost {} } tkPostOverPoint $menu $x $y $entry tkSaveGrabInfo $menu grab -global $menu set tkPriv(popup) $menu set tkPriv(focus) [focus] focus $menu } proc tk_setPalette args { global tkPalette if {[llength $args] == 1} { set new(background) [lindex $args 0] } else { array set new $args } if ![info exists new(background)] { error "must specify a background color" } if ![info exists new(foreground)] { set new(foreground) black } set bg [winfo rgb . $new(background)] set fg [winfo rgb . $new(foreground)] set darkerBg [format #%02x%02x%02x [expr (9*[lindex $bg 0])/2560] \ [expr (9*[lindex $bg 1])/2560] [expr (9*[lindex $bg 2])/2560]] foreach i {activeForeground insertBackground selectForeground \ highlightColor} { if ![info exists new($i)] { set new($i) $new(foreground) } } if ![info exists new(disabledForeground)] { set new(disabledForeground) [format #%02x%02x%02x \ [expr (3*[lindex $bg 0] + [lindex $fg 0])/1024] \ [expr (3*[lindex $bg 1] + [lindex $fg 1])/1024] \ [expr (3*[lindex $bg 2] + [lindex $fg 2])/1024]] } if ![info exists new(highlightBackground)] { set new(highlightBackground) $new(background) } if ![info exists new(activeBackground)] { foreach i {0 1 2} { set light($i) [expr [lindex $bg $i]/256] set inc1 [expr ($light($i)*15)/100] set inc2 [expr (255-$light($i))/3] if {$inc1 > $inc2} { incr light($i) $inc1 } else { incr light($i) $inc2 } if {$light($i) > 255} { set light($i) 255 } } set new(activeBackground) [format #%02x%02x%02x $light(0) \ $light(1) $light(2)] } if ![info exists new(selectBackground)] { set new(selectBackground) $darkerBg } if ![info exists new(troughColor)] { set new(troughColor) $darkerBg } if ![info exists new(selectColor)] { set new(selectColor) #b03060 } if ![info exists tkPalette] { checkbutton .c14732 entry .e14732 scrollbar .s14732 set tkPalette(activeBackground) \ [lindex [.c14732 configure -activebackground] 3] set tkPalette(activeForeground) \ [lindex [.c14732 configure -activeforeground] 3] set tkPalette(background) \ [lindex [.c14732 configure -background] 3] set tkPalette(disabledForeground) \ [lindex [.c14732 configure -disabledforeground] 3] set tkPalette(foreground) \ [lindex [.c14732 configure -foreground] 3] set tkPalette(highlightBackground) \ [lindex [.c14732 configure -highlightbackground] 3] set tkPalette(highlightColor) \ [lindex [.c14732 configure -highlightcolor] 3] set tkPalette(insertBackground) \ [lindex [.e14732 configure -insertbackground] 3] set tkPalette(selectColor) \ [lindex [.c14732 configure -selectcolor] 3] set tkPalette(selectBackground) \ [lindex [.e14732 configure -selectbackground] 3] set tkPalette(selectForeground) \ [lindex [.e14732 configure -selectforeground] 3] set tkPalette(troughColor) \ [lindex [.s14732 configure -troughcolor] 3] destroy .c14732 .e14732 .s14732 } tkRecolorTree . new foreach option [array names new] { option add *$option $new($option) widgetDefault } array set tkPalette [array get new] } proc tkRecolorTree {w colors} { global tkPalette upvar $colors c foreach dbOption [array names c] { set option -[string tolower $dbOption] if ![catch {$w cget $option} value] { if {$value == $tkPalette($dbOption)} { $w configure $option $c($dbOption) } } } foreach child [winfo children $w] { tkRecolorTree $child c } } proc tkDarken {color percent} { set l [winfo rgb . $color] set red [expr [lindex $l 0]/256] set green [expr [lindex $l 1]/256] set blue [expr [lindex $l 2]/256] set red [expr ($red*$percent)/100] if {$red > 255} { set red 255 } set green [expr ($green*$percent)/100] if {$green > 255} { set green 255 } set blue [expr ($blue*$percent)/100] if {$blue > 255} { set blue 255 } format #%02x%02x%02x $red $green $blue } proc tk_bisque {} { tk_setPalette activeBackground #e6ceb1 activeForeground black \ background #ffe4c4 disabledForeground #b0b0b0 foreground black \ highlightBackground #ffe4c4 highlightColor black \ insertBackground black selectColor #b03060 \ selectBackground #e6ceb1 selectForeground black \ troughColor #cdb79e } bind Scale { if $tk_strictMotif { set tkPriv(activeBg) [%W cget -activebackground] %W config -activebackground [%W cget -background] } tkScaleActivate %W %x %y } bind Scale { tkScaleActivate %W %x %y } bind Scale { if $tk_strictMotif { %W config -activebackground $tkPriv(activeBg) } if {[%W cget -state] == "active"} { %W configure -state normal } } bind Scale <1> { tkScaleButtonDown %W %x %y } bind Scale { tkScaleDrag %W %x %y } bind Scale { } bind Scale { } bind Scale { tkCancelRepeat tkScaleEndDrag %W tkScaleActivate %W %x %y } bind Scale <2> { tkScaleButton2Down %W %x %y } bind Scale { tkScaleDrag %W %x %y } bind Scale { } bind Scale { } bind Scale { tkCancelRepeat tkScaleEndDrag %W tkScaleActivate %W %x %y } bind Scale { tkScaleControlPress %W %x %y } bind Scale { tkScaleIncrement %W up little noRepeat } bind Scale { tkScaleIncrement %W down little noRepeat } bind Scale { tkScaleIncrement %W up little noRepeat } bind Scale { tkScaleIncrement %W down little noRepeat } bind Scale { tkScaleIncrement %W up big noRepeat } bind Scale { tkScaleIncrement %W down big noRepeat } bind Scale { tkScaleIncrement %W up big noRepeat } bind Scale { tkScaleIncrement %W down big noRepeat } bind Scale { %W set [%W cget -from] } bind Scale { %W set [%W cget -to] } proc tkScaleActivate {w x y} { global tkPriv if {[$w cget -state] == "disabled"} { return; } if {[$w identify $x $y] == "slider"} { $w configure -state active } else { $w configure -state normal } } proc tkScaleButtonDown {w x y} { global tkPriv set tkPriv(dragging) 0 set el [$w identify $x $y] if {$el == "trough1"} { tkScaleIncrement $w up little initial } elseif {$el == "trough2"} { tkScaleIncrement $w down little initial } elseif {$el == "slider"} { set tkPriv(dragging) 1 set tkPriv(initValue) [$w get] set coords [$w coords] set tkPriv(deltaX) [expr $x - [lindex $coords 0]] set tkPriv(deltaY) [expr $y - [lindex $coords 1]] $w configure -sliderrelief sunken } } proc tkScaleDrag {w x y} { global tkPriv if !$tkPriv(dragging) { return } $w set [$w get [expr $x - $tkPriv(deltaX)] \ [expr $y - $tkPriv(deltaY)]] } proc tkScaleEndDrag {w} { global tkPriv set tkPriv(dragging) 0 $w configure -sliderrelief raised } proc tkScaleIncrement {w dir big repeat} { global tkPriv if {![winfo exists $w]} return if {$big == "big"} { set inc [$w cget -bigincrement] if {$inc == 0} { set inc [expr abs([$w cget -to] - [$w cget -from])/10.0] } if {$inc < [$w cget -resolution]} { set inc [$w cget -resolution] } } else { set inc [$w cget -resolution] } if {([$w cget -from] > [$w cget -to]) ^ ($dir == "up")} { set inc [expr -$inc] } $w set [expr [$w get] + $inc] if {$repeat == "again"} { set tkPriv(afterId) [after [$w cget -repeatinterval] \ tkScaleIncrement $w $dir $big again] } elseif {$repeat == "initial"} { set delay [$w cget -repeatdelay] if {$delay > 0} { set tkPriv(afterId) [after $delay \ tkScaleIncrement $w $dir $big again] } } } proc tkScaleControlPress {w x y} { set el [$w identify $x $y] if {$el == "trough1"} { $w set [$w cget -from] } elseif {$el == "trough2"} { $w set [$w cget -to] } } proc tkScaleButton2Down {w x y} { global tkPriv if {[$w cget -state] == "disabled"} { return; } $w configure -state active $w set [$w get $x $y] set tkPriv(dragging) 1 set tkPriv(initValue) [$w get] set coords "$x $y" set tkPriv(deltaX) 0 set tkPriv(deltaY) 0 } proc tkTearOffMenu w { set parent [winfo parent $w] while {([winfo toplevel $parent] != $parent) || ([winfo class $parent] == "Menu")} { set parent [winfo parent $parent] } if {$parent == "."} { set parent "" } for {set i 1} 1 {incr i} { set menu $parent.tearoff$i if ![winfo exists $menu] { break } } tkMenuDup $w $menu $menu configure -transient 0 set parent [winfo parent $w] switch [winfo class $parent] { Menubutton { wm title $menu [$parent cget -text] } Menu { wm title $menu [$parent entrycget active -label] } } $menu configure -tearoff 0 $menu post [winfo x $w] [winfo y $w] bind $menu { set tkPriv(focus) %W } set cmd [$w cget -tearoffcommand] if {$cmd != ""} { uplevel #0 $cmd $w $menu } } proc tkMenuDup {src dst} { set cmd "menu $dst" foreach option [$src configure] { if {[llength $option] == 2} { continue } lappend cmd [lindex $option 0] [lindex $option 4] } eval $cmd set last [$src index last] if {$last == "none"} { return } for {set i [$src cget -tearoff]} {$i <= $last} {incr i} { set cmd "$dst add [$src type $i]" foreach option [$src entryconfigure $i] { lappend cmd [lindex $option 0] [lindex $option 4] } eval $cmd if {[$src type $i] == "cascade"} { tkMenuDup [$src entrycget $i -menu] $dst.m$i $dst entryconfigure $i -menu $dst.m$i } } regsub -all . $src {\\&} quotedSrc regsub -all . $dst {\\&} quotedDst regsub -all $quotedSrc [bindtags $src] $dst x bindtags $dst $x foreach event [bind $src] { regsub -all $quotedSrc [bind $src $event] $dst x bind $dst $event $x } } proc tkTextClipboardKeysyms {copy cut paste} { bind Text <$copy> {tk_textCopy %W} bind Text <$cut> {tk_textCut %W} bind Text <$paste> {tk_textPaste %W} } bind Text <1> { tkTextButton1 %W %x %y %W tag remove sel 0.0 end } bind Text { set tkPriv(x) %x set tkPriv(y) %y tkTextSelectTo %W %x %y } bind Text { set tkPriv(selectMode) word tkTextSelectTo %W %x %y catch {%W mark set insert sel.first} } bind Text { set tkPriv(selectMode) line tkTextSelectTo %W %x %y catch {%W mark set insert sel.first} } bind Text { tkTextResetAnchor %W @%x,%y set tkPriv(selectMode) char tkTextSelectTo %W %x %y } bind Text { set tkPriv(selectMode) word tkTextSelectTo %W %x %y } bind Text { set tkPriv(selectMode) line tkTextSelectTo %W %x %y } bind Text { set tkPriv(x) %x set tkPriv(y) %y tkTextAutoScan %W } bind Text { tkCancelRepeat } bind Text { tkCancelRepeat } bind Text { %W mark set insert @%x,%y } bind Text { if {!$tkPriv(mouseMoved) || $tk_strictMotif} { tkTextPaste %W %x %y } } bind Text { tkTextSetCursor %W insert-1c } bind Text { tkTextSetCursor %W insert+1c } bind Text { tkTextSetCursor %W [tkTextUpDownLine %W -1] } bind Text { tkTextSetCursor %W [tkTextUpDownLine %W 1] } bind Text { tkTextKeySelect %W [%W index {insert - 1c}] } bind Text { tkTextKeySelect %W [%W index {insert + 1c}] } bind Text { tkTextKeySelect %W [tkTextUpDownLine %W -1] } bind Text { tkTextKeySelect %W [tkTextUpDownLine %W 1] } bind Text { tkTextSetCursor %W [%W index {insert - 1c wordstart}] } bind Text { tkTextSetCursor %W [%W index {insert wordend}] } bind Text { tkTextSetCursor %W [tkTextPrevPara %W insert] } bind Text { tkTextSetCursor %W [tkTextNextPara %W insert] } bind Text { tkTextKeySelect %W [%W index {insert - 1c wordstart}] } bind Text { tkTextKeySelect %W [%W index {insert wordend}] } bind Text { tkTextKeySelect %W [tkTextPrevPara %W insert] } bind Text { tkTextKeySelect %W [tkTextNextPara %W insert] } bind Text { tkTextSetCursor %W [tkTextScrollPages %W -1] } bind Text { tkTextKeySelect %W [tkTextScrollPages %W -1] } bind Text { tkTextSetCursor %W [tkTextScrollPages %W 1] } bind Text { tkTextKeySelect %W [tkTextScrollPages %W 1] } bind Text { %W xview scroll -1 page } bind Text { %W xview scroll 1 page } bind Text { tkTextSetCursor %W {insert linestart} } bind Text { tkTextKeySelect %W {insert linestart} } bind Text { tkTextSetCursor %W {insert lineend} } bind Text { tkTextKeySelect %W {insert lineend} } bind Text { tkTextSetCursor %W 1.0 } bind Text { tkTextKeySelect %W 1.0 } bind Text { tkTextSetCursor %W {end - 1 char} } bind Text { tkTextKeySelect %W {end - 1 char} } bind Text { tkTextInsert %W \t focus %W break } bind Text { } bind Text { focus [tk_focusNext %W] } bind Text { focus [tk_focusPrev %W] } bind Text { tkTextInsert %W \t } bind Text { tkTextInsert %W \n } bind Text { if {[%W tag nextrange sel 1.0 end] != ""} { %W delete sel.first sel.last } else { %W delete insert %W see insert } } bind Text { if {[%W tag nextrange sel 1.0 end] != ""} { %W delete sel.first sel.last } elseif [%W compare insert != 1.0] { %W delete insert-1c %W see insert } } bind Text { %W mark set anchor insert } bind Text