PNG  IHDRQgAMA a cHRMz&u0`:pQ<bKGDgmIDATxwUﹻ& ^CX(J I@ "% (** BX +*i"]j(IH{~R)[~>h{}gy)I$Ij .I$I$ʊy@}x.: $I$Ii}VZPC)I$IF ^0ʐJ$I$Q^}{"r=OzI$gRZeC.IOvH eKX $IMpxsk.쒷/&r[޳<v| .I~)@$updYRa$I |M.e JaֶpSYR6j>h%IRز if&uJ)M$I vLi=H;7UJ,],X$I1AҒJ$ XY XzI@GNҥRT)E@;]K*Mw;#5_wOn~\ DC&$(A5 RRFkvIR}l!RytRl;~^ǷJj اy뷦BZJr&ӥ8Pjw~vnv X^(I;4R=P[3]J,]ȏ~:3?[ a&e)`e*P[4]T=Cq6R[ ~ޤrXR Հg(t_HZ-Hg M$ãmL5R uk*`%C-E6/%[t X.{8P9Z.vkXŐKjgKZHg(aK9ڦmKjѺm_ \#$5,)-  61eJ,5m| r'= &ڡd%-]J on Xm|{ RҞe $eڧY XYrԮ-a7RK6h>n$5AVڴi*ֆK)mѦtmr1p| q:흺,)Oi*ֺK)ܬ֦K-5r3>0ԔHjJئEZj,%re~/z%jVMڸmrt)3]J,T K֦OvԒgii*bKiNO~%PW0=dii2tJ9Jݕ{7"I P9JKTbu,%r"6RKU}Ij2HKZXJ,妝 XYrP ެ24c%i^IK|.H,%rb:XRl1X4Pe/`x&P8Pj28Mzsx2r\zRPz4J}yP[g=L) .Q[6RjWgp FIH*-`IMRaK9TXcq*I y[jE>cw%gLRԕiFCj-ďa`#e~I j,%r,)?[gp FI˨mnWX#>mʔ XA DZf9,nKҲzIZXJ,L#kiPz4JZF,I,`61%2s $,VOϚ2/UFJfy7K> X+6 STXIeJILzMfKm LRaK9%|4p9LwJI!`NsiazĔ)%- XMq>pk$-$Q2x#N ؎-QR}ᶦHZډ)J,l#i@yn3LN`;nڔ XuX5pF)m|^0(>BHF9(cզEerJI rg7 4I@z0\JIi䵙RR0s;$s6eJ,`n 䂦0a)S)A 1eJ,堌#635RIgpNHuTH_SԕqVe ` &S)>p;S$魁eKIuX`I4춒o}`m$1":PI<[v9^\pTJjriRŭ P{#{R2,`)e-`mgj~1ϣLKam7&U\j/3mJ,`F;M'䱀 .KR#)yhTq;pcK9(q!w?uRR,n.yw*UXj#\]ɱ(qv2=RqfB#iJmmL<]Y͙#$5 uTU7ӦXR+q,`I}qL'`6Kͷ6r,]0S$- [RKR3oiRE|nӦXR.(i:LDLTJjY%o:)6rxzҒqTJjh㞦I.$YR.ʼnGZ\ֿf:%55 I˼!6dKxm4E"mG_ s? .e*?LRfK9%q#uh$)i3ULRfK9yxm܌bj84$i1U^@Wbm4uJ,ҪA>_Ij?1v32[gLRD96oTaR׿N7%L2 NT,`)7&ƝL*꽙yp_$M2#AS,`)7$rkTA29_Iye"|/0t)$n XT2`YJ;6Jx".e<`$) PI$5V4]29SRI>~=@j]lp2`K9Jaai^" Ԋ29ORI%:XV5]JmN9]H;1UC39NI%Xe78t)a;Oi Ҙ>Xt"~G>_mn:%|~ޅ_+]$o)@ǀ{hgN;IK6G&rp)T2i୦KJuv*T=TOSV>(~D>dm,I*Ɛ:R#ۙNI%D>G.n$o;+#RR!.eU˽TRI28t)1LWϚ>IJa3oFbu&:tJ*(F7y0ZR ^p'Ii L24x| XRI%ۄ>S1]Jy[zL$adB7.eh4%%누>WETf+3IR:I3Xה)3אOۦSRO'ٺ)S}"qOr[B7ϙ.edG)^ETR"RtRݜh0}LFVӦDB^k_JDj\=LS(Iv─aTeZ%eUAM-0;~˃@i|l @S4y72>sX-vA}ϛBI!ݎߨWl*)3{'Y|iSlEڻ(5KtSI$Uv02,~ԩ~x;P4ցCrO%tyn425:KMlD ^4JRxSهF_}شJTS6uj+ﷸk$eZO%G*^V2u3EMj3k%)okI]dT)URKDS 7~m@TJR~荪fT"֛L \sM -0T KfJz+nإKr L&j()[E&I ߴ>e FW_kJR|!O:5/2跌3T-'|zX ryp0JS ~^F>-2< `*%ZFP)bSn"L :)+pʷf(pO3TMW$~>@~ū:TAIsV1}S2<%ޟM?@iT ,Eūoz%i~g|`wS(]oȤ8)$ ntu`өe`6yPl IzMI{ʣzʨ )IZ2= ld:5+請M$-ї;U>_gsY$ÁN5WzWfIZ)-yuXIfp~S*IZdt;t>KūKR|$#LcԀ+2\;kJ`]YǔM1B)UbG"IRߊ<xܾӔJ0Z='Y嵤 Leveg)$znV-º^3Ւof#0Tfk^Zs[*I꯳3{)ˬW4Ւ4 OdpbZRS|*I 55#"&-IvT&/윚Ye:i$ 9{LkuRe[I~_\ؠ%>GL$iY8 9ܕ"S`kS.IlC;Ҏ4x&>u_0JLr<J2(^$5L s=MgV ~,Iju> 7r2)^=G$1:3G< `J3~&IR% 6Tx/rIj3O< ʔ&#f_yXJiގNSz; Tx(i8%#4 ~AS+IjerIUrIj362v885+IjAhK__5X%nV%Iͳ-y|7XV2v4fzo_68"S/I-qbf; LkF)KSM$ Ms>K WNV}^`-큧32ŒVؙGdu,^^m%6~Nn&͓3ŒVZMsRpfEW%IwdǀLm[7W&bIRL@Q|)* i ImsIMmKmyV`i$G+R 0tV'!V)֏28vU7͒vHꦼtxꗞT ;S}7Mf+fIRHNZUkUx5SAJㄌ9MqμAIRi|j5)o*^'<$TwI1hEU^c_j?Е$%d`z cyf,XO IJnTgA UXRD }{H}^S,P5V2\Xx`pZ|Yk:$e ~ @nWL.j+ϝYb퇪bZ BVu)u/IJ_ 1[p.p60bC >|X91P:N\!5qUB}5a5ja `ubcVxYt1N0Zzl4]7­gKj]?4ϻ *[bg$)+À*x쳀ogO$~,5 زUS9 lq3+5mgw@np1sso Ӻ=|N6 /g(Wv7U;zωM=wk,0uTg_`_P`uz?2yI!b`kĸSo+Qx%!\οe|އԁKS-s6pu_(ֿ$i++T8=eY; צP+phxWQv*|p1. ά. XRkIQYP,drZ | B%wP|S5`~́@i޾ E;Չaw{o'Q?%iL{u D?N1BD!owPHReFZ* k_-~{E9b-~P`fE{AܶBJAFO wx6Rox5 K5=WwehS8 (JClJ~ p+Fi;ŗo+:bD#g(C"wA^ r.F8L;dzdIHUX݆ϞXg )IFqem%I4dj&ppT{'{HOx( Rk6^C٫O.)3:s(۳(Z?~ٻ89zmT"PLtw䥈5&b<8GZ-Y&K?e8,`I6e(֍xb83 `rzXj)F=l($Ij 2*(F?h(/9ik:I`m#p3MgLaKjc/U#n5S# m(^)=y=đx8ŬI[U]~SцA4p$-F i(R,7Cx;X=cI>{Km\ o(Tv2vx2qiiDJN,Ҏ!1f 5quBj1!8 rDFd(!WQl,gSkL1Bxg''՞^ǘ;pQ P(c_ IRujg(Wz bs#P­rz> k c&nB=q+ؔXn#r5)co*Ũ+G?7< |PQӣ'G`uOd>%Mctz# Ԫڞ&7CaQ~N'-P.W`Oedp03C!IZcIAMPUۀ5J<\u~+{9(FbbyAeBhOSܳ1 bÈT#ŠyDžs,`5}DC-`̞%r&ڙa87QWWp6e7 Rϫ/oY ꇅ Nܶըtc!LA T7V4Jsū I-0Pxz7QNF_iZgúWkG83 0eWr9 X]㾮݁#Jˢ C}0=3ݱtBi]_ &{{[/o[~ \q鯜00٩|cD3=4B_b RYb$óBRsf&lLX#M*C_L܄:gx)WΘsGSbuL rF$9';\4Ɍq'n[%p.Q`u hNb`eCQyQ|l_C>Lb꟟3hSb #xNxSs^ 88|Mz)}:](vbۢamŖ࿥ 0)Q7@0=?^k(*J}3ibkFn HjB׻NO z x}7p 0tfDX.lwgȔhԾŲ }6g E |LkLZteu+=q\Iv0쮑)QٵpH8/2?Σo>Jvppho~f>%bMM}\//":PTc(v9v!gոQ )UfVG+! 35{=x\2+ki,y$~A1iC6#)vC5^>+gǵ@1Hy٪7u;p psϰu/S <aʸGu'tD1ԝI<pg|6j'p:tպhX{o(7v],*}6a_ wXRk,O]Lܳ~Vo45rp"N5k;m{rZbΦ${#)`(Ŵg,;j%6j.pyYT?}-kBDc3qA`NWQū20/^AZW%NQ MI.X#P#,^Ebc&?XR tAV|Y.1!؅⨉ccww>ivl(JT~ u`ٵDm q)+Ri x/x8cyFO!/*!/&,7<.N,YDŽ&ܑQF1Bz)FPʛ?5d 6`kQձ λc؎%582Y&nD_$Je4>a?! ͨ|ȎWZSsv8 j(I&yj Jb5m?HWp=g}G3#|I,5v珿] H~R3@B[☉9Ox~oMy=J;xUVoj bUsl_35t-(ՃɼRB7U!qc+x4H_Qo֮$[GO<4`&č\GOc[.[*Af%mG/ ňM/r W/Nw~B1U3J?P&Y )`ѓZ1p]^l“W#)lWZilUQu`-m|xĐ,_ƪ|9i:_{*(3Gѧ}UoD+>m_?VPۅ15&}2|/pIOʵ> GZ9cmíتmnz)yߐbD >e}:) r|@R5qVSA10C%E_'^8cR7O;6[eKePGϦX7jb}OTGO^jn*媓7nGMC t,k31Rb (vyܴʭ!iTh8~ZYZp(qsRL ?b}cŨʊGO^!rPJO15MJ[c&~Z`"ѓޔH1C&^|Ш|rʼ,AwĴ?b5)tLU)F| &g٣O]oqSUjy(x<Ϳ3 .FSkoYg2 \_#wj{u'rQ>o;%n|F*O_L"e9umDds?.fuuQbIWz |4\0 sb;OvxOSs; G%T4gFRurj(֍ڑb uԖKDu1MK{1^ q; C=6\8FR艇!%\YÔU| 88m)֓NcLve C6z;o&X x59:q61Z(T7>C?gcļxѐ Z oo-08jہ x,`' ҔOcRlf~`jj".Nv+sM_]Zk g( UOPyεx%pUh2(@il0ݽQXxppx-NS( WO+轾 nFߢ3M<;z)FBZjciu/QoF 7R¥ ZFLF~#ȣߨ^<쩡ݛкvџ))ME>ώx4m#!-m!L;vv#~Y[đKmx9.[,UFS CVkZ +ߟrY٧IZd/ioi$%͝ب_ֶX3ܫhNU ZZgk=]=bbJS[wjU()*I =ώ:}-蹞lUj:1}MWm=̛ _ ¾,8{__m{_PVK^n3esw5ӫh#$-q=A̟> ,^I}P^J$qY~Q[ Xq9{#&T.^GVj__RKpn,b=`żY@^՝;z{paVKkQXj/)y TIc&F;FBG7wg ZZDG!x r_tƢ!}i/V=M/#nB8 XxЫ ^@CR<{䤭YCN)eKOSƟa $&g[i3.C6xrOc8TI;o hH6P&L{@q6[ Gzp^71j(l`J}]e6X☉#͕ ׈$AB1Vjh㭦IRsqFBjwQ_7Xk>y"N=MB0 ,C #o6MRc0|$)ف"1!ixY<B9mx `,tA>)5ػQ?jQ?cn>YZe Tisvh# GMމȇp:ԴVuږ8ɼH]C.5C!UV;F`mbBk LTMvPʍϤj?ԯ/Qr1NB`9s"s TYsz &9S%U԰> {<ؿSMxB|H\3@!U| k']$U+> |HHMLޢ?V9iD!-@x TIî%6Z*9X@HMW#?nN ,oe6?tQwڱ.]-y':mW0#!J82qFjH -`ѓ&M0u Uγmxϵ^-_\])@0Rt.8/?ٰCY]x}=sD3ojަЫNuS%U}ԤwHH>ڗjܷ_3gN q7[q2la*ArǓԖ+p8/RGM ]jacd(JhWko6ڎbj]i5Bj3+3!\j1UZLsLTv8HHmup<>gKMJj0@H%,W΃7R) ">c, xixј^ aܖ>H[i.UIHc U1=yW\=S*GR~)AF=`&2h`DzT󑓶J+?W+}C%P:|0H܆}-<;OC[~o.$~i}~HQ TvXΈr=b}$vizL4:ȰT|4~*!oXQR6Lk+#t/g lԁߖ[Jڶ_N$k*". xsxX7jRVbAAʯKҎU3)zSNN _'s?f)6X!%ssAkʱ>qƷb hg %n ~p1REGMHH=BJiy[<5 ǁJҖgKR*倳e~HUy)Ag,K)`Vw6bRR:qL#\rclK/$sh*$ 6덤 KԖc 3Z9=Ɣ=o>X Ώ"1 )a`SJJ6k(<c e{%kϊP+SL'TcMJWRm ŏ"w)qc ef꒵i?b7b('"2r%~HUS1\<(`1Wx9=8HY9m:X18bgD1u ~|H;K-Uep,, C1 RV.MR5άh,tWO8WC$ XRVsQS]3GJ|12 [vM :k#~tH30Rf-HYݺ-`I9%lIDTm\ S{]9gOڒMNCV\G*2JRŨ;Rҏ^ڽ̱mq1Eu?To3I)y^#jJw^Ńj^vvlB_⋌P4x>0$c>K†Aļ9s_VjTt0l#m>E-,,x,-W)سo&96RE XR.6bXw+)GAEvL)͞K4$p=Ũi_ѱOjb HY/+@θH9޼]Nԥ%n{ &zjT? Ty) s^ULlb,PiTf^<À] 62R^V7)S!nllS6~͝V}-=%* ʻ>G DnK<y&>LPy7'r=Hj 9V`[c"*^8HpcO8bnU`4JȪAƋ#1_\ XϘHPRgik(~G~0DAA_2p|J묭a2\NCr]M_0 ^T%e#vD^%xy-n}-E\3aS%yN!r_{ )sAw ڼp1pEAk~v<:`'ӭ^5 ArXOI驻T (dk)_\ PuA*BY]yB"l\ey hH*tbK)3 IKZ򹞋XjN n *n>k]X_d!ryBH ]*R 0(#'7 %es9??ښFC,ՁQPjARJ\Ρw K#jahgw;2$l*) %Xq5!U᢯6Re] |0[__64ch&_}iL8KEgҎ7 M/\`|.p,~`a=BR?xܐrQ8K XR2M8f ?`sgWS%" Ԉ 7R%$ N}?QL1|-эټwIZ%pvL3Hk>,ImgW7{E xPHx73RA @RS CC !\ȟ5IXR^ZxHл$Q[ŝ40 (>+ _C >BRt<,TrT {O/H+˟Pl6 I B)/VC<6a2~(XwV4gnXR ϱ5ǀHٻ?tw똤Eyxp{#WK qG%5],(0ӈH HZ])ג=K1j&G(FbM@)%I` XRg ʔ KZG(vP,<`[ Kn^ SJRsAʠ5xՅF`0&RbV tx:EaUE/{fi2;.IAwW8/tTxAGOoN?G}l L(n`Zv?pB8K_gI+ܗ #i?ޙ.) p$utc ~DžfՈEo3l/)I-U?aԅ^jxArA ΧX}DmZ@QLےbTXGd.^|xKHR{|ΕW_h] IJ`[G9{).y) 0X YA1]qp?p_k+J*Y@HI>^?gt.06Rn ,` ?);p pSF9ZXLBJPWjgQ|&)7! HjQt<| ؅W5 x W HIzYoVMGP Hjn`+\(dNW)F+IrS[|/a`K|ͻ0Hj{R,Q=\ (F}\WR)AgSG`IsnAR=|8$}G(vC$)s FBJ?]_u XRvύ6z ŨG[36-T9HzpW̞ú Xg큽=7CufzI$)ki^qk-) 0H*N` QZkk]/tnnsI^Gu't=7$ Z;{8^jB% IItRQS7[ϭ3 $_OQJ`7!]W"W,)Iy W AJA;KWG`IY{8k$I$^%9.^(`N|LJ%@$I}ֽp=FB*xN=gI?Q{٥4B)mw $Igc~dZ@G9K X?7)aK%݅K$IZ-`IpC U6$I\0>!9k} Xa IIS0H$I H ?1R.Чj:4~Rw@p$IrA*u}WjWFPJ$I➓/6#! LӾ+ X36x8J |+L;v$Io4301R20M I$-E}@,pS^ޟR[/s¹'0H$IKyfŸfVOπFT*a$I>He~VY/3R/)>d$I>28`Cjw,n@FU*9ttf$I~<;=/4RD~@ X-ѕzἱI$: ԍR a@b X{+Qxuq$IЛzo /~3\8ڒ4BN7$IҀj V]n18H$IYFBj3̵̚ja pp $Is/3R Ӻ-Yj+L;.0ŔI$Av? #!5"aʄj}UKmɽH$IjCYs?h$IDl843.v}m7UiI=&=0Lg0$I4: embe` eQbm0u? $IT!Sƍ'-sv)s#C0:XB2a w I$zbww{."pPzO =Ɔ\[ o($Iaw]`E).Kvi:L*#gР7[$IyGPI=@R 4yR~̮´cg I$I/<tPͽ hDgo 94Z^k盇΄8I56^W$I^0̜N?4*H`237}g+hxoq)SJ@p|` $I%>-hO0eO>\ԣNߌZD6R=K ~n($I$y3D>o4b#px2$yڪtzW~a $I~?x'BwwpH$IZݑnC㧄Pc_9sO gwJ=l1:mKB>Ab<4Lp$Ib o1ZQ@85b̍ S'F,Fe,^I$IjEdù{l4 8Ys_s Z8.x m"+{~?q,Z D!I$ϻ'|XhB)=…']M>5 rgotԎ 獽PH$IjIPhh)n#cÔqA'ug5qwU&rF|1E%I$%]!'3AFD/;Ck_`9 v!ٴtPV;x`'*bQa w I$Ix5 FC3D_~A_#O݆DvV?<qw+I$I{=Z8".#RIYyjǪ=fDl9%M,a8$I$Ywi[7ݍFe$s1ՋBVA?`]#!oz4zjLJo8$I$%@3jAa4(o ;p,,dya=F9ً[LSPH$IJYЉ+3> 5"39aZ<ñh!{TpBGkj}Sp $IlvF.F$I z< '\K*qq.f<2Y!S"-\I$IYwčjF$ w9 \ߪB.1v!Ʊ?+r:^!I$BϹB H"B;L'G[ 4U#5>੐)|#o0aڱ$I>}k&1`U#V?YsV x>{t1[I~D&(I$I/{H0fw"q"y%4 IXyE~M3 8XψL}qE$I[> nD?~sf ]o΁ cT6"?'_Ἣ $I>~.f|'!N?⟩0G KkXZE]ޡ;/&?k OۘH$IRۀwXӨ<7@PnS04aӶp.:@\IWQJ6sS%I$e5ڑv`3:x';wq_vpgHyXZ 3gЂ7{{EuԹn±}$I$8t;b|591nءQ"P6O5i }iR̈́%Q̄p!I䮢]O{H$IRϻ9s֧ a=`- aB\X0"+5"C1Hb?߮3x3&gşggl_hZ^,`5?ߎvĸ%̀M!OZC2#0x LJ0 Gw$I$I}<{Eb+y;iI,`ܚF:5ܛA8-O-|8K7s|#Z8a&><a&/VtbtLʌI$I$I$I$I$I$IRjDD%tEXtdate:create2022-05-31T04:40:26+00:00!Î%tEXtdate:modify2022-05-31T04:40:26+00:00|{2IENDB`Mini Shell

HOME


Mini Shell 1.0
DIR:/proc/self/root/proc/thread-self/root/usr/share/graphviz/lefty/
Upload File :
Current File : //proc/self/root/proc/thread-self/root/usr/share/graphviz/lefty/dotty.lefty
#
# DOTTY
#
dotty = [
    'keys' = [
        'nid'    = 'nid';
        'eid'    = 'eid';
        'gid'    = 'gid';
        'name'   = 'name';
        'attr'   = 'attr';
        'gattr'  = 'graphattr';
        'eattr'  = 'edgeattr';
        'nattr'  = 'nodeattr';
        'edges'  = 'edges';
        'tail'   = 'tail';
        'tport'  = 'tport';
        'head'   = 'head';
        'hport'  = 'hport';
        'pos'    = 'pos';
        'size'   = 'size';
        'rect'   = 'rect';
        'fname'  = 'fontname';
        'fsize'  = 'fontsize';
        'fcolor' = 'fontcolor';
        'dcolor' = 'drawcolor';
        'bcolor' = 'fillcolor';
    ];
    'maps' = [
        'X11' = [
            'fontmap' = [
                'Times-Roman'    = '-*-times-medium-r-*--%d-*-*-*-*-*-*-1';
                'Times-Italic'   = '-*-times-medium-i-*--%d-*-*-*-*-*-*-1';
                'Times-Bold'     = '-*-times-bold-r-*--%d-*-*-*-*-*-*-1';
                'Courier'        = '-*-courier-bold-r-*--%d-*-*-*-*-*-*-1';
                'Courier-Bold'   = '-*-courier-bold-r-*--%d-*-*-*-*-*-*-1';
                'Helvetica'      = (
                     '-*-helvetica-medium-r-normal--%d-*-*-*-p-*-iso8859-1'
                );
                'Helvetica-Bold' = (
                    '-*-helvetica-bold-r-normal--%d-*-*-*-p-*-iso8859-1'
                );
            ];
            'psfontmap' = [
                'Times-Roman'    = 'Times-Roman';
                'Times-Italic'   = 'Times-Italic';
                'Times-Bold'     = 'Times-Bold';
                'Courier'        = 'Courier';
                'Courier-Bold'   = 'Courier-Bold';
                'Helvetica'      = 'Helvetica';
                'Helvetica-Bold' = 'Helvetica-Bold';
            ];
        ];
        'mswin' = [
            'fontmap' = [
                'Times-Roman'    = 'Times New Roman';
                'Times-Italic'   = 'Times New Roman Italic';
                'Times-Bold'     = 'Times New Roman Bold';
                'Courier'        = 'Courier New';
                'Courier-Bold'   = 'Courier New Bold';
                'Helvetica'      = 'Arial';
                'Helvetica-Bold' = 'Arial Bold';
            ];
            'psfontmap' = [
                'Times-Roman'    = 'Times New Roman';
                'Times-Italic'   = 'Times New Roman Italic';
                'Times-Bold'     = 'Times New Roman Bold';
                'Courier'        = 'Courier New';
                'Courier-Bold'   = 'Courier New Bold';
                'Helvetica'      = 'Arial';
                'Helvetica-Bold' = 'Arial Bold';
            ];
        ];
    ];
    'protogt' = [
        'graph' = [
            'graphattr' = [
                'fontsize' = '14';
                'fontname' = 'Times-Roman';
                'fontcolor' = 'black';
            ];
            'nodeattr' = [
                'shape' = 'ellipse';
                'fontsize' = '14';
                'fontname' = 'Times-Roman';
                'fontcolor' = 'black';
                'style' = 'solid';
            ];
            'edgeattr' = [
                'fontsize' = '14';
                'fontname' = 'Times-Roman';
                'fontcolor' = 'black';
                'style' = 'solid';
            ];
            'graphdict' = [];
            'nodedict' = [];
            'graphs' = [];
            'nodes' = [];
            'edges' = [];
            'maxgid' = 0;
            'maxnid' = 0;
            'maxeid' = 0;
            'type' = 'digraph';
        ];
        'layoutmode' = 'sync';
        'lserver' = 'dot';
        'edgehandles' = 1;
        'noundo' = 0;
    ];
    'lservers' = [];
    'mlevel' = 0;
    'graphs' = [];
    'views' = [];
    'protovt' = [
        'normal' = [
            'name' = 'DOTTY';
            'orig' = ['x' = 1; 'y' = 1;];
            'size' = ['x' = 420; 'y' = 520;];
            'wrect' = [
                0 = ['x' = 0; 'y' = 0;];
                1 = ['x' = 400; 'y' = 500;];
            ];
            'vsize' = ['x' = 400; 'y' = 500;];
            'w2v' = 1;
        ];
        'birdseye' = [
            'type' = 'birdseye';
            'name' = 'DOTTY birdseye view';
            'orig' = ['x' = 1; 'y' = 1;];
            'size' = ['x' = 220; 'y' = 260;];
            'wrect' = [
                0 = ['x' = 0; 'y' = 0;];
                1 = ['x' = 200; 'y' = 250;];
            ];
            'vsize' = ['x' = 200; 'y' = 250;];
            'w2v' = 1;
        ];
    ];
    'pagesizes' = [
        '8.5x11' = ['x' =    8; 'y' = 10.5;];
        '11x17'  = ['x' = 10.5; 'y' = 16.5;];
        '36x50'  = ['x' = 35.5; 'y' = 49.5;];
    ];
];
load ('dotty_draw.lefty');
load ('dotty_edit.lefty');
load ('dotty_layout.lefty');
load ('dotty_ui.lefty');
#
# initialization functions
#
dotty.init = function () {
    dotty.fontmap = dotty.maps[getenv ('LEFTYWINSYS')].fontmap;
    dotty.clipgt = dotty.protogt.creategraph (['noundo' = 1;]);
    dotty.inited = 1;
};
dotty.simple = function (file) {
    if (dotty.inited ~= 1)
        dotty.init ();
    dotty.createviewandgraph (file, 'file', null, null);
    txtview ('off');
};
#
# main operations
#
dotty.protogt.creategraph = function (protogt) {
    local gt, id, gtid;

    if (~protogt)
        protogt = dotty.protogt;
    for (gtid = 0; dotty.graphs[gtid]; gtid = gtid + 1)
        ;
    gt = (dotty.graphs[gtid] = []);
    if (protogt.mode ~= 'replace') {
        for (id in dotty.protogt)
            gt[id] = copy (dotty.protogt[id]);
    }
    for (id in protogt)
        gt[id] = copy (protogt[id]);
    gt.gtid = gtid;
    gt.views = [];
    gt.undoarray = ['level' = 0; 'entries' = [];];
    gt.busy = 0;
    return gt;
};
dotty.protogt.copygraph = function (ogt) {
    local gt, gtid, id;

    for (gtid = 0; dotty.graphs[gtid]; gtid = gtid + 1)
        ;
    gt = (dotty.graphs[gtid] = []);
    for (id in ogt)
        gt[id] = copy (ogt[id]);
    gt.gtid = gtid;
    gt.views = [];
    gt.undoarray = ['level' = 0; 'entries' = [];];
    gt.busy = 0;
    return gt;
};
dotty.protogt.destroygraph = function (gt) {
    local vid, vlist;

    if (gt.layoutpending > 0)
        gt.cancellayout (gt);
    for (vid in gt.views)
        vlist[vid] = gt.views[vid];
    for (vid in gt.views)
        gt.destroyview (gt, vlist[vid]);
    remove (gt.gtid, dotty.graphs);
};
dotty.protogt.loadgraph = function (gt, name, type, protograph, layoutflag) {
    local fd, vid, vt, graph, nid, eid, gid;

    if (gt.layoutpending > 0)
        gt.cancellayout (gt);
    if (~name)
        if (~(name = ask ('file name:', 'file', '')))
            return;
    dotty.pushbusy (gt, gt.views);
    dotty.message (1, 'loading');
    if (~protograph)
        protograph = dotty.protogt.graph;
    if (
        ~((fd = dotty.openio (name, type, 'r')) >= 0) |
        ~(graph = readgraph (fd, protograph))
    ) {
        dotty.message (0, 'cannot load graph');
        dotty.popbusy (gt, gt.views);
        return;
    }
    for (vid in gt.views) {
        vt = gt.views[vid];
        vt.colors = [];
        vt.colorn = 2;
    }
    gt.graph = graph;
    gt.name = name;
    gt.type = type;
    gt.undoarray = ['level' = 0; 'entries' = [];];
    if (~(type == 'file' & name == '-'))
        closeio (fd);
    graph.maxgid = tablesize (graph.graphs);
    graph.maxnid = tablesize (graph.nodes);
    graph.maxeid = tablesize (graph.edges);
    for (nid in graph.nodes)
        graph.nodes[nid][dotty.keys.nid] = nid;
    for (eid in graph.edges)
        graph.edges[eid][dotty.keys.eid] = eid;
    for (gid in graph.graphs)
        graph.graphs[gid][dotty.keys.gid] = gid;
    gt.unpackattr (gt);
    if (layoutflag) {
        dotty.message (1, 'generating layout');
        gt.layoutgraph (gt);
    }
    dotty.popbusy (gt, gt.views);
    return gt.graph;
};
dotty.protogt.savegraph = function (gt, name, type) {
    local fd;

    if (~name)
        if (~(name = ask ('file name:', 'file', '')))
            return;
    if (
        ~((fd = dotty.openio (name, type, 'w')) >= 0) |
        ~writegraph (fd, gt.graph, 0)
    ) {
        dotty.message (0, 'cannot save graph');
        return;
    }
    if (~(type == 'file' & name == '-'))
        closeio (fd);
};
dotty.protogt.setgraph = function (gt, graph) {
    local vid, vt, nid, eid, gid;

    if (gt.layoutpending > 0)
        gt.cancellayout (gt);
    for (vid in gt.views) {
        vt = gt.views[vid];
        vt.colors = [];
        vt.colorn = 2;
    }
    gt.graph = copy (graph);
    gt.undoarray = ['level' = 0; 'entries' = [];];
    gt.unpackattr (gt);
    gt.graph.maxgid = tablesize (graph.graphs);
    gt.graph.maxnid = tablesize (graph.nodes);
    gt.graph.maxeid = tablesize (graph.edges);
    for (nid in gt.graph.nodes)
        gt.graph.nodes[nid][dotty.keys.nid] = nid;
    for (eid in gt.graph.edges)
        gt.graph.edges[eid][dotty.keys.eid] = eid;
    for (gid in gt.graph.graphs)
        gt.graph.graphs[gid][dotty.keys.gid] = gid;
    gt.unpackattr (gt);
    dotty.message (1, 'generating layout');
    gt.layoutgraph (gt);
    return gt.graph;
};
dotty.protogt.erasegraph = function (gt, protogt, protovt) {
    local vid, vt;

    if (gt.layoutpending > 0)
        gt.cancellayout (gt);
    for (vid in gt.views) {
        vt = gt.views[vid];
        vt.colors = [];
        vt.colorn = 2;
        clear (vt.canvas);
    }
    if (~protogt)
        protogt = dotty.protogt;
    gt.graph = copy (protogt.graph);
    gt.undoarray = ['level' = 0; 'entries' = [];];
};
dotty.protogt.layoutgraph = function (gt) {
    if (gt.graph.graphattr.xdotversion) {
        gt.unpacklayout (gt, gt.graph);
        gt.setviewsize (gt.views, gt.graph.rect);
        gt.redrawgraph (gt, gt.views);
        return;
    }
    if (gt.layoutmode == 'async') {
        if (~gt.haveinput) {
            gt.startlayout (gt);
            return;
        }
        if (~gt.finishlayout (gt))
            return;
        gt.setviewsize (gt.views, gt.graph.rect);
        gt.redrawgraph (gt, gt.views);
    } else {
        if (~gt.startlayout (gt))
            return;
        else
            while (~gt.finishlayout (gt))
                ;
        gt.setviewsize (gt.views, gt.graph.rect);
        gt.redrawgraph (gt, gt.views);
    }
};
dotty.protogt.createview = function (gt, protovt) {
    local vt, ovt, id, t;

    vt = [];
    vt.colors = [];
    vt.colorn = 2;
    if (~protovt)
        protovt = dotty.protovt.normal;
    if (protovt.mode ~= 'replace') {
        for (id in dotty.protovt[protovt.type])
            vt[id] = copy (dotty.protovt[protovt.type][id]);
    }
    for (id in protovt)
        vt[id] = copy (protovt[id]);
    if (~(vt.parent >= 0)) {
        vt.view = createwidget (-1, [
            'type'   = 'view';
            'name'   = vt.name;
            'origin' = vt.orig;
            'size'   = vt.size;
        ]);
        vt.scroll = createwidget (vt.view, ['type' = 'scroll';]);
    } else {
        vt.view = -1;
        vt.scroll = createwidget (vt.parent, [
            'type' = 'scroll';
            'size' = vt.size;
        ]);
    }
    vt.canvas = createwidget (vt.scroll, [
        'type' = 'canvas';
        'color' = [0 = protovt.bgcolor; 1 = protovt.fgcolor;];
    ]);
    setwidgetattr (vt.canvas, [
        'window' = vt.wrect;
        'viewport' = vt.vsize;
    ]);
    clear (vt.canvas);
    dotty.views[vt.canvas] = vt;
    vt.vtid = vt.canvas;
    vt.gtid = gt.gtid;
    gt.views[vt.vtid] = vt;
    dotty.views[vt.scroll] = vt;
    if (vt.view ~= -1)
        dotty.views[vt.view] = vt;
    if (protovt.colors & tablesize (protovt.colors) > 0) {
        for (id in protovt.colors)
            if (id == '_bgcolor_')
                setwidgetattr (vt.canvas, [
                    'color' = [0 = protovt.colors[id];];
                ]);
            else if (setwidgetattr (vt.canvas, ['color' = [
                protovt.colors[id] = id;
            ];]) ~= 1) {
                t = split (id, ' ');
                if (tablesize (t) ~= 3 | setwidgetattr (vt.canvas, [
                    'color' = [protovt.colors[id] = [
                        'h' = ston (t[0]); 's' = ston (t[1]); 'v' = ston (t[2]);
                    ];];
                ]) ~= 1) {
                    dotty.message (
                        0, concat ('unknown color ', id, ' using #1')
                    );
                }
            }
        vt.colors = copy (protovt.colors);
        vt.colorn = protovt.colorn;
    } else if (tablesize (gt.views) > 1) {
        for (id in gt.views)
            if (gt.views[id] ~= vt)
                break;
        ovt = gt.views[id];
        for (id in ovt.colors)
            if (id == '_bgcolor_')
                setwidgetattr (vt.canvas, ['color' = [0 = ovt.colors[id];];]);
            else if (setwidgetattr (vt.canvas, ['color' = [
                ovt.colors[id] = id;
            ];]) ~= 1) {
                t = split (id, ' ');
                if (tablesize (t) ~= 3 | setwidgetattr (vt.canvas, [
                    'color' = [ovt.colors[id] = [
                        'h' = ston (t[0]); 's' = ston (t[1]); 'v' = ston (t[2]);
                    ];];
                ]) ~= 1) {
                    dotty.message (
                        0, concat ('unknown color ', id, ' using #1')
                    );
                }
            }
        vt.colors = copy (ovt.colors);
        vt.colorn = ovt.colorn;
    }
    if (gt.graph.rect)
        gt.setviewsize ([vt.vtid = vt;], gt.graph.rect);
    gt.drawgraph (gt, [vt.vtid = vt;]);
    for (id in vt.uifuncs)
        if (id == 'closeview')
            widgets[vt.view][id] = vt.uifuncs[id];
        else
            widgets[vt.canvas][id] = vt.uifuncs[id];
    return vt;
};
dotty.protogt.destroyview = function (gt, vt) {
    destroywidget (vt.canvas);
    destroywidget (vt.scroll);
    if (vt.view ~= -1) {
        destroywidget (vt.view);
        remove (vt.view, dotty.views);
    }
    remove (vt.scroll, dotty.views);
    remove (vt.canvas, dotty.views);
    if (vt.gtid >= 0)
        remove (vt.vtid, gt.views);
    if (tablesize (dotty.views) == 0)
        exit ();
};
dotty.protogt.zoom = function (gt, vt, factor, pos) {
    gt.setviewscale ([vt.vtid = vt;], factor);
    if (pos)
        gt.setviewcenter ([vt.vtid = vt;], pos);
    gt.redrawgraph (gt, [vt.vtid = vt;]);
};
dotty.protogt.findnode = function (gt, vt) {
    local key, node, node1, nid;

    if (~(key = ask ('give node name or label')))
        return;
    if (gt.graph.nodedict[key] >= 0)
        node = gt.graph.nodes[gt.graph.nodedict[key]];
    else if (gt.graph.nodedict[ston (key)] >= 0)
        node = gt.graph.nodes[gt.graph.nodedict[ston (key)]];
    else {
        for (nid in gt.graph.nodes) {
            node1 = gt.graph.nodes[nid];
            if (node1.attr.label == key | node1.attr.label == ston (key)) {
                node = node1;
                break;
            }
        }
    }
    if (~node) {
        dotty.message (0, concat ('cannot find node: ', key));
        return;
    }
    gt.setviewcenter ([vt.vtid = vt;], node.pos);
};
dotty.protogt.setattr = function (gt, obj) {
    local kv, t, attr, value, n, i, s;

    if (~(kv = ask ('give attr/value, eg. color=blue')))
        return;
    t = split (kv, '=');
    attr = t[0];
    value = t[1];
    if ((n = tablesize (t)) > 2)
        for (i = 2; i < n; i = i + 1)
            value = concat (value, '=', t[i]);
    # Check for HTML string and convert using lefty convention
    s = split (value, '');
    n = tablesize (s);
    if ((s[0] == '<') & (s[n-1] == '>')) {
        s[0] = '>';
        s[n-1] = '<';
        value = s[0]; 
        for (i = 1; i < n; i = i + 1)
            value = concat (value, s[i]);
    }
    if (
        obj.attr == gt.graph.graphattr |
        obj.attr == gt.graph.edgeattr |
        obj.attr == gt.graph.nodeattr
    ) {
        obj.attr[attr] = value;
        return;
    }
    if (obj.nid >= 0) {
        gt.undrawnode (gt, gt.views, obj);
        obj.attr[attr] = value;
        gt.unpacknodeattr (gt, obj);
        gt.drawnode (gt, gt.views, obj);
    } else if (obj.eid >= 0) {
        gt.undrawedge (gt, gt.views, obj);
        obj.attr[attr] = value;
        gt.unpackedgeattr (gt, obj);
        gt.drawedge (gt, gt.views, obj);
    }
};
dotty.protogt.getattr = function (gt, node) {
    local kv;

    if (~(kv.key = ask ('give attr name')))
        return null;
    if ((kv.val = node.attr[kv.key]))
        return kv;
    return null;
};
#
# utilities
#
dotty.createviewandgraph = function (name, type, protogt, protovt) {
    local vt, gt;

    if (~protogt)
        protogt = dotty.protogt;
    if (protogt.creategraph)
        gt = protogt.creategraph (protogt);
    else
        gt = dotty.protogt.creategraph (protogt);
    vt = gt.createview (gt, protovt);
    if (~protogt.graph)
        protogt.graph = copy (dotty.protogt.graph);
    if (name)
        gt.loadgraph (gt, name, type, protogt.graph, 1);
    return ['gt' = gt; 'vt' = vt;];
};
dotty.openio = function (name, type, mode) {
    local fd;

    if (~name)
        return null;
    if (type == 'file') {
        if (name == '-') {
            if (mode == 'r' | mode == 'r+')
                fd = 0;
            else
                fd = 1;
        } else if (~((fd = openio ('file', name, mode)) >= 0)) {
            dotty.message (0, concat ('cannot open file: ', name));
            return null;
        }
    } else if (type == 'pipe') {
        if (~((fd = openio (
            'pipe', 'ksh', mode, concat ("%e ", name)
        )) >= 0)) {
            dotty.message (0, concat ('cannot run command: ', name));
            return null;
        }
    } else
        return null;
    return fd;
};
dotty.pushbusy = function (gt, views) {
    local vid;

    if (gt.busy == 0)
        for (vid in gt.views)
            setwidgetattr (vid, ['cursor' = 'watch';]);
    gt.busy = gt.busy + 1;
};
dotty.popbusy = function (gt, views) {
    local vid;

    gt.busy = gt.busy - 1;
    if (gt.busy == 0)
        for (vid in gt.views)
            setwidgetattr (vid, ['cursor' = 'default';]);
};
dotty.message = function (level, text) {
    if (level <= dotty.mlevel)
        echo ('dotty.lefty: ', text);
};
#
# printing or saving to file
#
dotty.protogt.printorsave = function (gt, vt, otype, name, mode, ptype) {
    local pr, wrect, vsize, xy, psize, canvas, pscanvas, cid, cname, t;
    local graph, edgehandles, fontmap, eid, edge, nid, node, gid, sgraph;
    local did, draw, i;

    if (~otype)
        if (~(otype = ask ('print to', 'choice', 'file|printer')))
            return;
    if (otype == 'printer') {
        if (~getenv ('TMPDIR'))
            name = concat (getenv ('HOME'), '/.dottyout.ps');
        else
            name = concat (getenv ('TMPDIR'), '/.dottyout.ps', random (10000));
        if (getenv ('LEFTYWINSYS') ~= 'mswin' & ~pr)
            if (~(pr = ask ('printer command', 'string', 'lpr')))
                return;
    }
    if (~name)
        if (~(name = ask ('postscript file', 'file', 'out.ps')))
            return;
    if (~ptype)
        if (~(ptype = ask ('page size', 'choice', '8.5x11|11x17|36x50')))
            return;
    if (~mode)
        if (~(mode = ask ('mode', 'choice', 'portrait|landscape|best fit')))
            return;
    wrect = copy (vt.wrect);
    wrect[0].x = wrect[0].x - 1;
    wrect[1].x = wrect[1].x + 1;
    wrect[0].y = wrect[0].y - 1;
    wrect[1].y = wrect[1].y + 1;
    vsize = copy (vt.vsize);
    if (vsize.x == 0)
        vsize.x = 1;
    if (vsize.y == 0)
        vsize.y = 1;
    xy = vsize.x / vsize.y;
    if (mode == 'best fit') {
        if (xy < 1)
            mode = 'portrait';
        else
            mode = 'landscape';
    }
    psize = dotty.pagesizes[ptype];
    if (mode == 'portrait') {
        if (xy < psize.x / psize.y) {
            vsize.y = psize.y * 300;
            vsize.x = vsize.y * xy;
        } else {
            vsize.x = psize.x * 300;
            vsize.y = vsize.x / xy;
        }
    } else {
        if (xy < psize.y / psize.x) {
            vsize.y = psize.x * 300;
            vsize.x = vsize.y * xy;
        } else {
            vsize.x = psize.y * 300;
            vsize.y = vsize.x / xy;
        }
    }
    if (~((pscanvas = createwidget (-1, [
        'type'   = 'ps';
        'origin' = ['x' = 0; 'y' = 0;];
        'size'   = vsize;
        'mode'   = mode;
        'name'   = name;
    ])) >= 0)) {
        dotty.message (0, 'cannot open printer device');
        return;
    }
    for (cname in vt.colors) {
        cid = vt.colors[cname];
        if (cname == '_bgcolor_')
            setwidgetattr (pscanvas, ['color' = [0 = cid;];]);
        else if (setwidgetattr (pscanvas, ['color' = [cid = cname;];]) ~= 1) {
            t = split (cname, ' ');
            if (tablesize (t) ~= 3 | setwidgetattr (pscanvas, [
                'color' = [cid = [
                    'h' = ston (t[0]); 's' = ston (t[1]); 'v' = ston (t[2]);
                ];];
            ]) ~= 1) {
                dotty.message (
                    0, concat ('unknown color ', cname, ' using #1')
                );
            }
        }
    }
    setwidgetattr (pscanvas, ['window' = wrect;]);
    graph = copy (gt.graph);
    canvas = vt.canvas;
    vt.canvas = pscanvas;
    edgehandles = gt.edgehandles;
    gt.edgehandles = 0;
    fontmap = dotty.maps[getenv ('LEFTYWINSYS')].psfontmap;
    for (eid in graph.edges) {
        edge = graph.edges[eid];
        edge.fontname = fontmap[edge.attr.fontname];
        for (did in edge.draws) {
            if (did == 'ep')
                continue;
            draw = edge.draws[did];
            for (i = 0; draw[i]; i = i + 1)
                if (draw[i].type == 'F')
                    draw[i].fn = fontmap[draw[i].ofn];
        }
        gt.drawedge (gt, [0 = vt;], edge);
    }
    for (nid in graph.nodes) {
        node = graph.nodes[nid];
        node.fontname = fontmap[node.attr.fontname];
        for (did in node.draws) {
            if (did == 'ep')
                continue;
            draw = node.draws[did];
            for (i = 0; draw[i]; i = i + 1)
                if (draw[i].type == 'F')
                    draw[i].fn = fontmap[draw[i].ofn];
        }
        gt.drawnode (gt, [0 = vt;], node);
    }
    for (gid in graph.graphs) {
        sgraph = graph.graphs[gid];
        sgraph.fontname = fontmap[sgraph.graphattr.fontname];
        for (did in sgraph.draws) {
            if (did == 'ep')
                continue;
            draw = sgraph.draws[did];
            for (i = 0; draw[i]; i = i + 1)
                if (draw[i].type == 'F')
                    draw[i].fn = fontmap[draw[i].ofn];
        }
        gt.drawsgraph (gt, [0 = vt;], sgraph);
    }
    graph.fontname = fontmap[graph.graphattr.fontname];
    gt.drawsgraph (gt, [0 = vt;], graph);
    gt.edgehandles = edgehandles;
    vt.canvas = canvas;
    destroywidget (pscanvas);
    if (otype == 'printer' & getenv ('LEFTYWINSYS') ~= 'mswin')
        system (concat (pr, ' ', name, '; rm ',name));
};