PNG  IHDRX cHRMz&u0`:pQ<bKGD pHYsodtIME MeqIDATxw]Wug^Qd˶ 6`!N:!@xI~)%7%@Bh&`lnjVF29gΨ4E$|>cɚ{gk= %,a KX%,a KX%,a KX%,a KX%,a KX%,a KX%, b` ǟzeאfp]<!SJmɤY޲ڿ,%c ~ع9VH.!Ͳz&QynֺTkRR.BLHi٪:l;@(!MԴ=žI,:o&N'Kù\vRmJ雵֫AWic H@" !: Cé||]k-Ha oݜ:y F())u]aG7*JV@J415p=sZH!=!DRʯvɱh~V\}v/GKY$n]"X"}t@ xS76^[bw4dsce)2dU0 CkMa-U5tvLƀ~mlMwfGE/-]7XAƟ`׮g ewxwC4\[~7@O-Q( a*XGƒ{ ՟}$_y3tĐƤatgvێi|K=uVyrŲlLӪuܿzwk$m87k( `múcE)"@rK( z4$D; 2kW=Xb$V[Ru819קR~qloѱDyįݎ*mxw]y5e4K@ЃI0A D@"BDk_)N\8͜9dz"fK0zɿvM /.:2O{ Nb=M=7>??Zuo32 DLD@D| &+֎C #B8ַ`bOb $D#ͮҪtx]%`ES`Ru[=¾!@Od37LJ0!OIR4m]GZRJu$‡c=%~s@6SKy?CeIh:[vR@Lh | (BhAMy=݃  G"'wzn޺~8ԽSh ~T*A:xR[ܹ?X[uKL_=fDȊ؂p0}7=D$Ekq!/t.*2ʼnDbŞ}DijYaȲ(""6HA;:LzxQ‘(SQQ}*PL*fc\s `/d'QXW, e`#kPGZuŞuO{{wm[&NBTiiI0bukcA9<4@SӊH*؎4U/'2U5.(9JuDfrޱtycU%j(:RUbArLֺN)udA':uGQN"-"Is.*+k@ `Ojs@yU/ H:l;@yyTn}_yw!VkRJ4P)~y#)r,D =ě"Q]ci'%HI4ZL0"MJy 8A{ aN<8D"1#IJi >XjX֔#@>-{vN!8tRݻ^)N_╗FJEk]CT՟ YP:_|H1@ CBk]yKYp|og?*dGvzنzӴzjֺNkC~AbZƷ`.H)=!QͷVTT(| u78y֮}|[8-Vjp%2JPk[}ԉaH8Wpqhwr:vWª<}l77_~{s۴V+RCģ%WRZ\AqHifɤL36: #F:p]Bq/z{0CU6ݳEv_^k7'>sq*+kH%a`0ԣisqにtү04gVgW΂iJiS'3w.w}l6MC2uԯ|>JF5`fV5m`Y**Db1FKNttu]4ccsQNnex/87+}xaUW9y>ͯ骵G{䩓Գ3+vU}~jJ.NFRD7<aJDB1#ҳgSb,+CS?/ VG J?|?,2#M9}B)MiE+G`-wo߫V`fio(}S^4e~V4bHOYb"b#E)dda:'?}׮4繏`{7Z"uny-?ǹ;0MKx{:_pÚmFמ:F " .LFQLG)Q8qN q¯¯3wOvxDb\. BKD9_NN &L:4D{mm o^tֽ:q!ƥ}K+<"m78N< ywsard5+вz~mnG)=}lYݧNj'QJS{S :UYS-952?&O-:W}(!6Mk4+>A>j+i|<<|;ر^߉=HE|V#F)Emm#}/"y GII웻Jі94+v뾧xu~5C95~ūH>c@덉pʃ1/4-A2G%7>m;–Y,cyyaln" ?ƻ!ʪ<{~h~i y.zZB̃/,雋SiC/JFMmBH&&FAbϓO^tubbb_hZ{_QZ-sύodFgO(6]TJA˯#`۶ɟ( %$&+V'~hiYy>922 Wp74Zkq+Ovn錄c>8~GqܲcWꂎz@"1A.}T)uiW4="jJ2W7mU/N0gcqܗOO}?9/wìXžΏ0 >֩(V^Rh32!Hj5`;O28؇2#ݕf3 ?sJd8NJ@7O0 b־?lldщ̡&|9C.8RTWwxWy46ah嘦mh٤&l zCy!PY?: CJyв]dm4ǜҐR޻RլhX{FƯanшQI@x' ao(kUUuxW_Ñ줮[w8 FRJ(8˼)_mQ _!RJhm=!cVmm ?sFOnll6Qk}alY}; "baӌ~M0w,Ggw2W:G/k2%R,_=u`WU R.9T"v,<\Ik޽/2110Ӿxc0gyC&Ny޽JҢrV6N ``یeA16"J³+Rj*;BϜkZPJaÍ<Jyw:NP8/D$ 011z֊Ⱳ3ι֘k1V_"h!JPIΣ'ɜ* aEAd:ݺ>y<}Lp&PlRfTb1]o .2EW\ͮ]38؋rTJsǏP@芎sF\> P^+dYJLbJ C-xϐn> ι$nj,;Ǖa FU *择|h ~izť3ᤓ`K'-f tL7JK+vf2)V'-sFuB4i+m+@My=O҈0"|Yxoj,3]:cо3 $#uŘ%Y"y죯LebqtҢVzq¼X)~>4L׶m~[1_k?kxֺQ`\ |ٛY4Ѯr!)N9{56(iNq}O()Em]=F&u?$HypWUeB\k]JɩSع9 Zqg4ZĊo oMcjZBU]B\TUd34ݝ~:7ڶSUsB0Z3srx 7`:5xcx !qZA!;%͚7&P H<WL!džOb5kF)xor^aujƍ7 Ǡ8/p^(L>ὴ-B,{ۇWzֺ^k]3\EE@7>lYBȝR.oHnXO/}sB|.i@ɥDB4tcm,@ӣgdtJ!lH$_vN166L__'Z)y&kH;:,Y7=J 9cG) V\hjiE;gya~%ks_nC~Er er)muuMg2;֫R)Md) ,¶ 2-wr#F7<-BBn~_(o=KO㭇[Xv eN_SMgSҐ BS헃D%g_N:/pe -wkG*9yYSZS.9cREL !k}<4_Xs#FmҶ:7R$i,fi!~' # !6/S6y@kZkZcX)%5V4P]VGYq%H1!;e1MV<!ϐHO021Dp= HMs~~a)ަu7G^];git!Frl]H/L$=AeUvZE4P\.,xi {-~p?2b#amXAHq)MWǾI_r`S Hz&|{ +ʖ_= (YS(_g0a03M`I&'9vl?MM+m~}*xT۲(fY*V4x@29s{DaY"toGNTO+xCAO~4Ϳ;p`Ѫ:>Ҵ7K 3}+0 387x\)a"/E>qpWB=1 ¨"MP(\xp߫́A3+J] n[ʼnӼaTbZUWb={~2ooKױӰp(CS\S筐R*JغV&&"FA}J>G֐p1ٸbk7 ŘH$JoN <8s^yk_[;gy-;߉DV{c B yce% aJhDȶ 2IdйIB/^n0tNtџdcKj4϶v~- CBcgqx9= PJ) dMsjpYB] GD4RDWX +h{y`,3ꊕ$`zj*N^TP4L:Iz9~6s) Ga:?y*J~?OrMwP\](21sZUD ?ܟQ5Q%ggW6QdO+\@ ̪X'GxN @'4=ˋ+*VwN ne_|(/BDfj5(Dq<*tNt1х!MV.C0 32b#?n0pzj#!38}޴o1KovCJ`8ŗ_"]] rDUy޲@ Ȗ-;xџ'^Y`zEd?0„ DAL18IS]VGq\4o !swV7ˣι%4FѮ~}6)OgS[~Q vcYbL!wG3 7띸*E Pql8=jT\꘿I(z<[6OrR8ºC~ډ]=rNl[g|v TMTղb-o}OrP^Q]<98S¤!k)G(Vkwyqyr޽Nv`N/e p/~NAOk \I:G6]4+K;j$R:Mi #*[AȚT,ʰ,;N{HZTGMoּy) ]%dHء9Պ䠬|<45,\=[bƟ8QXeB3- &dҩ^{>/86bXmZ]]yޚN[(WAHL$YAgDKp=5GHjU&99v簪C0vygln*P)9^͞}lMuiH!̍#DoRBn9l@ xA/_v=ȺT{7Yt2N"4!YN`ae >Q<XMydEB`VU}u]嫇.%e^ánE87Mu\t`cP=AD/G)sI"@MP;)]%fH9'FNsj1pVhY&9=0pfuJ&gޤx+k:!r˭wkl03׼Ku C &ѓYt{.O.zҏ z}/tf_wEp2gvX)GN#I ݭ߽v/ .& и(ZF{e"=V!{zW`, ]+LGz"(UJp|j( #V4, 8B 0 9OkRrlɱl94)'VH9=9W|>PS['G(*I1==C<5"Pg+x'K5EMd؞Af8lG ?D FtoB[je?{k3zQ vZ;%Ɠ,]E>KZ+T/ EJxOZ1i #T<@ I}q9/t'zi(EMqw`mYkU6;[t4DPeckeM;H}_g pMww}k6#H㶏+b8雡Sxp)&C $@'b,fPߑt$RbJ'vznuS ~8='72_`{q纶|Q)Xk}cPz9p7O:'|G~8wx(a 0QCko|0ASD>Ip=4Q, d|F8RcU"/KM opKle M3#i0c%<7׿p&pZq[TR"BpqauIp$ 8~Ĩ!8Սx\ւdT>>Z40ks7 z2IQ}ItԀ<-%S⍤};zIb$I 5K}Q͙D8UguWE$Jh )cu4N tZl+[]M4k8֦Zeq֮M7uIqG 1==tLtR,ƜSrHYt&QP윯Lg' I,3@P'}'R˪e/%-Auv·ñ\> vDJzlӾNv5:|K/Jb6KI9)Zh*ZAi`?S {aiVDԲuy5W7pWeQJk֤#5&V<̺@/GH?^τZL|IJNvI:'P=Ϛt"¨=cud S Q.Ki0 !cJy;LJR;G{BJy޺[^8fK6)=yʊ+(k|&xQ2`L?Ȓ2@Mf 0C`6-%pKpm')c$׻K5[J*U[/#hH!6acB JA _|uMvDyk y)6OPYjœ50VT K}cǻP[ $:]4MEA.y)|B)cf-A?(e|lɉ#P9V)[9t.EiQPDѠ3ϴ;E:+Օ t ȥ~|_N2,ZJLt4! %ա]u {+=p.GhNcŞQI?Nd'yeh n7zi1DB)1S | S#ًZs2|Ɛy$F SxeX{7Vl.Src3E℃Q>b6G ўYCmtկ~=K0f(=LrAS GN'ɹ9<\!a`)֕y[uՍ[09` 9 +57ts6}b4{oqd+J5fa/,97J#6yν99mRWxJyѡyu_TJc`~W>l^q#Ts#2"nD1%fS)FU w{ܯ R{ ˎ󅃏џDsZSQS;LV;7 Od1&1n$ N /.q3~eNɪ]E#oM~}v֯FڦwyZ=<<>Xo稯lfMFV6p02|*=tV!c~]fa5Y^Q_WN|Vs 0ҘދU97OI'N2'8N֭fgg-}V%y]U4 峧p*91#9U kCac_AFңĪy뚇Y_AiuYyTTYЗ-(!JFLt›17uTozc. S;7A&&<ԋ5y;Ro+:' *eYJkWR[@F %SHWP 72k4 qLd'J "zB6{AC0ƁA6U.'F3:Ȅ(9ΜL;D]m8ڥ9}dU "v!;*13Rg^fJyShyy5auA?ɩGHRjo^]׽S)Fm\toy 4WQS@mE#%5ʈfFYDX ~D5Ϡ9tE9So_aU4?Ѽm%&c{n>.KW1Tlb}:j uGi(JgcYj0qn+>) %\!4{LaJso d||u//P_y7iRJ߬nHOy) l+@$($VFIQ9%EeKʈU. ia&FY̒mZ=)+qqoQn >L!qCiDB;Y<%} OgBxB!ØuG)WG9y(Ą{_yesuZmZZey'Wg#C~1Cev@0D $a@˲(.._GimA:uyw֬%;@!JkQVM_Ow:P.s\)ot- ˹"`B,e CRtaEUP<0'}r3[>?G8xU~Nqu;Wm8\RIkբ^5@k+5(By'L&'gBJ3ݶ!/㮻w҅ yqPWUg<e"Qy*167΃sJ\oz]T*UQ<\FԎ`HaNmڜ6DysCask8wP8y9``GJ9lF\G g's Nn͵MLN֪u$| /|7=]O)6s !ĴAKh]q_ap $HH'\1jB^s\|- W1:=6lJBqjY^LsPk""`]w)󭃈,(HC ?䔨Y$Sʣ{4Z+0NvQkhol6C.婧/u]FwiVjZka&%6\F*Ny#8O,22+|Db~d ~Çwc N:FuuCe&oZ(l;@ee-+Wn`44AMK➝2BRՈt7g*1gph9N) *"TF*R(#'88pm=}X]u[i7bEc|\~EMn}P瘊J)K.0i1M6=7'_\kaZ(Th{K*GJyytw"IO-PWJk)..axӝ47"89Cc7ĐBiZx 7m!fy|ϿF9CbȩV 9V-՛^pV̌ɄS#Bv4-@]Vxt-Z, &ֺ*diؠ2^VXbs֔Ìl.jQ]Y[47gj=幽ex)A0ip׳ W2[ᎇhuE^~q흙L} #-b۸oFJ_QP3r6jr+"nfzRJTUqoaۍ /$d8Mx'ݓ= OՃ| )$2mcM*cЙj}f };n YG w0Ia!1Q.oYfr]DyISaP}"dIӗթO67jqR ҊƐƈaɤGG|h;t]䗖oSv|iZqX)oalv;۩meEJ\!8=$4QU4Xo&VEĊ YS^E#d,yX_> ۘ-e\ "Wa6uLĜZi`aD9.% w~mB(02G[6y.773a7 /=o7D)$Z 66 $bY^\CuP. (x'"J60׿Y:Oi;F{w佩b+\Yi`TDWa~|VH)8q/=9!g߆2Y)?ND)%?Ǐ`k/sn:;O299yB=a[Ng 3˲N}vLNy;*?x?~L&=xyӴ~}q{qE*IQ^^ͧvü{Huu=R|>JyUlZV, B~/YF!Y\u_ݼF{_C)LD]m {H 0ihhadd nUkf3oٺCvE\)QJi+֥@tDJkB$1!Đr0XQ|q?d2) Ӣ_}qv-< FŊ߫%roppVBwü~JidY4:}L6M7f٬F "?71<2#?Jyy4뷢<_a7_=Q E=S1И/9{+93֮E{ǂw{))?maÆm(uLE#lïZ  ~d];+]h j?!|$F}*"4(v'8s<ŏUkm7^7no1w2ؗ}TrͿEk>p'8OB7d7R(A 9.*Mi^ͳ; eeUwS+C)uO@ =Sy]` }l8^ZzRXj[^iUɺ$tj))<sbDJfg=Pk_{xaKo1:-uyG0M ԃ\0Lvuy'ȱc2Ji AdyVgVh!{]/&}}ċJ#%d !+87<;qN޼Nفl|1N:8ya  8}k¾+-$4FiZYÔXk*I&'@iI99)HSh4+2G:tGhS^繿 Kتm0 вDk}֚+QT4;sC}rՅE,8CX-e~>G&'9xpW,%Fh,Ry56Y–hW-(v_,? ; qrBk4-V7HQ;ˇ^Gv1JVV%,ik;D_W!))+BoS4QsTM;gt+ndS-~:11Sgv!0qRVh!"Ȋ(̦Yl.]PQWgٳE'`%W1{ndΗBk|Ž7ʒR~,lnoa&:ü$ 3<a[CBݮwt"o\ePJ=Hz"_c^Z.#ˆ*x z̝grY]tdkP*:97YľXyBkD4N.C_[;F9`8& !AMO c `@BA& Ost\-\NX+Xp < !bj3C&QL+*&kAQ=04}cC!9~820G'PC9xa!w&bo_1 Sw"ܱ V )Yl3+ס2KoXOx]"`^WOy :3GO0g;%Yv㐫(R/r (s } u B &FeYZh0y> =2<Ϟc/ -u= c&׭,.0"g"7 6T!vl#sc>{u/Oh Bᾈ)۴74]x7 gMӒ"d]U)}" v4co[ ɡs 5Gg=XR14?5A}D "b{0$L .\4y{_fe:kVS\\O]c^W52LSBDM! C3Dhr̦RtArx4&agaN3Cf<Ԉp4~ B'"1@.b_/xQ} _߃҉/gٓ2Qkqp0շpZ2fԫYz< 4L.Cyυι1t@鎫Fe sYfsF}^ V}N<_`p)alٶ "(XEAVZ<)2},:Ir*#m_YӼ R%a||EƼIJ,,+f"96r/}0jE/)s)cjW#w'Sʯ5<66lj$a~3Kʛy 2:cZ:Yh))+a߭K::N,Q F'qB]={.]h85C9cr=}*rk?vwV렵ٸW Rs%}rNAkDv|uFLBkWY YkX מ|)1!$#3%y?pF<@<Rr0}: }\J [5FRxY<9"SQdE(Q*Qʻ)q1E0B_O24[U'],lOb ]~WjHޏTQ5Syu wq)xnw8~)c 쫬gٲߠ H% k5dƝk> kEj,0% b"vi2Wس_CuK)K{n|>t{P1򨾜j>'kEkƗBg*H%'_aY6Bn!TL&ɌOb{c`'d^{t\i^[uɐ[}q0lM˕G:‚4kb祔c^:?bpg… +37stH:0}en6x˟%/<]BL&* 5&fK9Mq)/iyqtA%kUe[ڛKN]Ě^,"`/ s[EQQm?|XJ߅92m]G.E΃ח U*Cn.j_)Tѧj̿30ڇ!A0=͜ar I3$C^-9#|pk!)?7.x9 @OO;WƝZBFU keZ75F6Tc6"ZȚs2y/1 ʵ:u4xa`C>6Rb/Yм)^=+~uRd`/|_8xbB0?Ft||Z\##|K 0>>zxv8۴吅q 8ĥ)"6>~\8:qM}#͚'ĉ#p\׶ l#bA?)|g g9|8jP(cr,BwV (WliVxxᡁ@0Okn;ɥh$_ckCgriv}>=wGzβ KkBɛ[˪ !J)h&k2%07δt}!d<9;I&0wV/ v 0<H}L&8ob%Hi|޶o&h1L|u֦y~󛱢8fٲUsւ)0oiFx2}X[zVYr_;N(w]_4B@OanC?gĦx>мgx>ΛToZoOMp>40>V Oy V9iq!4 LN,ˢu{jsz]|"R޻&'ƚ{53ўFu(<٪9:΋]B;)B>1::8;~)Yt|0(pw2N%&X,URBK)3\zz&}ax4;ǟ(tLNg{N|Ǽ\G#C9g$^\}p?556]/RP.90 k,U8/u776s ʪ_01چ|\N 0VV*3H鴃J7iI!wG_^ypl}r*jɤSR 5QN@ iZ#1ٰy;_\3\BQQ x:WJv츟ٯ$"@6 S#qe딇(/P( Dy~TOϻ<4:-+F`0||;Xl-"uw$Цi󼕝mKʩorz"mϺ$F:~E'ҐvD\y?Rr8_He@ e~O,T.(ފR*cY^m|cVR[8 JҡSm!ΆԨb)RHG{?MpqrmN>߶Y)\p,d#xۆWY*,l6]v0h15M˙MS8+EdI='LBJIH7_9{Caз*Lq,dt >+~ّeʏ?xԕ4bBAŚjﵫ!'\Ը$WNvKO}ӽmSşذqsOy?\[,d@'73'j%kOe`1.g2"e =YIzS2|zŐƄa\U,dP;jhhhaxǶ?КZ՚.q SE+XrbOu%\GتX(H,N^~]JyEZQKceTQ]VGYqnah;y$cQahT&QPZ*iZ8UQQM.qo/T\7X"u?Mttl2Xq(IoW{R^ ux*SYJ! 4S.Jy~ BROS[V|žKNɛP(L6V^|cR7i7nZW1Fd@ Ara{詑|(T*dN]Ko?s=@ |_EvF]׍kR)eBJc" MUUbY6`~V޴dJKß&~'d3i WWWWWW
Current Directory: /opt/imunify360/venv/lib/python3.11/site-packages/lxml
Viewing File: /opt/imunify360/venv/lib/python3.11/site-packages/lxml/readonlytree.pxi
# read-only tree implementation @cython.internal cdef class _ReadOnlyProxy: u"A read-only proxy class suitable for PIs/Comments (for internal use only!)." cdef bint _free_after_use cdef xmlNode* _c_node cdef _ReadOnlyProxy _source_proxy cdef list _dependent_proxies def __cinit__(self): self._c_node = NULL self._free_after_use = 0 cdef int _assertNode(self) except -1: u"""This is our way of saying: this proxy is invalid! """ if not self._c_node: raise ReferenceError("Proxy invalidated!") return 0 cdef int _raise_unsupported_type(self) except -1: raise TypeError(f"Unsupported node type: {self._c_node.type}") cdef void free_after_use(self): u"""Should the xmlNode* be freed when releasing the proxy? """ self._free_after_use = 1 @property def tag(self): """Element tag """ self._assertNode() if self._c_node.type == tree.XML_ELEMENT_NODE: return _namespacedName(self._c_node) elif self._c_node.type == tree.XML_PI_NODE: return ProcessingInstruction elif self._c_node.type == tree.XML_COMMENT_NODE: return Comment elif self._c_node.type == tree.XML_ENTITY_REF_NODE: return Entity else: self._raise_unsupported_type() @property def text(self): """Text before the first subelement. This is either a string or the value None, if there was no text. """ self._assertNode() if self._c_node.type == tree.XML_ELEMENT_NODE: return _collectText(self._c_node.children) elif self._c_node.type in (tree.XML_PI_NODE, tree.XML_COMMENT_NODE): if self._c_node.content is NULL: return '' else: return funicode(self._c_node.content) elif self._c_node.type == tree.XML_ENTITY_REF_NODE: return f'&{funicode(self._c_node.name)};' else: self._raise_unsupported_type() @property def tail(self): """Text after this element's end tag, but before the next sibling element's start tag. This is either a string or the value None, if there was no text. """ self._assertNode() return _collectText(self._c_node.next) @property def sourceline(self): """Original line number as found by the parser or None if unknown. """ cdef long line self._assertNode() line = tree.xmlGetLineNo(self._c_node) if line > 0: return line else: return None def __repr__(self): self._assertNode() if self._c_node.type == tree.XML_ELEMENT_NODE: return "<Element %s at 0x%x>" % (strrepr(self.tag), id(self)) elif self._c_node.type == tree.XML_COMMENT_NODE: return "<!--%s-->" % strrepr(self.text) elif self._c_node.type == tree.XML_ENTITY_NODE: return "&%s;" % strrepr(funicode(self._c_node.name)) elif self._c_node.type == tree.XML_PI_NODE: text = self.text if text: return "<?%s %s?>" % (strrepr(self.target), text) else: return "<?%s?>" % strrepr(self.target) else: self._raise_unsupported_type() def __getitem__(self, x): u"""Returns the subelement at the given position or the requested slice. """ cdef xmlNode* c_node = NULL cdef Py_ssize_t step = 0, slicelength = 0 cdef Py_ssize_t c, i cdef _node_to_node_function next_element cdef list result self._assertNode() if isinstance(x, slice): # slicing if _isFullSlice(<slice>x): return _collectChildren(self) _findChildSlice(<slice>x, self._c_node, &c_node, &step, &slicelength) if c_node is NULL: return [] if step > 0: next_element = _nextElement else: step = -step next_element = _previousElement result = [] c = 0 while c_node is not NULL and c < slicelength: result.append(_newReadOnlyProxy(self._source_proxy, c_node)) result.append(_elementFactory(self._doc, c_node)) c = c + 1 for i from 0 <= i < step: c_node = next_element(c_node) return result else: # indexing c_node = _findChild(self._c_node, x) if c_node is NULL: raise IndexError, u"list index out of range" return _newReadOnlyProxy(self._source_proxy, c_node) def __len__(self): u"""Returns the number of subelements. """ cdef Py_ssize_t c cdef xmlNode* c_node self._assertNode() c = 0 c_node = self._c_node.children while c_node is not NULL: if tree._isElement(c_node): c = c + 1 c_node = c_node.next return c def __nonzero__(self): cdef xmlNode* c_node self._assertNode() c_node = _findChildBackwards(self._c_node, 0) return c_node != NULL def __deepcopy__(self, memo): u"__deepcopy__(self, memo)" return self.__copy__() cpdef __copy__(self): u"__copy__(self)" cdef xmlDoc* c_doc cdef xmlNode* c_node cdef _Document new_doc if self._c_node is NULL: return self c_doc = _copyDocRoot(self._c_node.doc, self._c_node) # recursive new_doc = _documentFactory(c_doc, None) root = new_doc.getroot() if root is not None: return root # Comment/PI c_node = c_doc.children while c_node is not NULL and c_node.type != self._c_node.type: c_node = c_node.next if c_node is NULL: return None return _elementFactory(new_doc, c_node) def __iter__(self): return iter(self.getchildren()) def iterchildren(self, tag=None, *, reversed=False): u"""iterchildren(self, tag=None, reversed=False) Iterate over the children of this element. """ children = self.getchildren() if tag is not None and tag != '*': children = [ el for el in children if el.tag == tag ] if reversed: children = children[::-1] return iter(children) cpdef getchildren(self): u"""Returns all subelements. The elements are returned in document order. """ cdef xmlNode* c_node cdef list result self._assertNode() result = [] c_node = self._c_node.children while c_node is not NULL: if tree._isElement(c_node): result.append(_newReadOnlyProxy(self._source_proxy, c_node)) c_node = c_node.next return result def getparent(self): u"""Returns the parent of this element or None for the root element. """ cdef xmlNode* c_parent self._assertNode() c_parent = self._c_node.parent if c_parent is NULL or not tree._isElement(c_parent): return None else: return _newReadOnlyProxy(self._source_proxy, c_parent) def getnext(self): u"""Returns the following sibling of this element or None. """ cdef xmlNode* c_node self._assertNode() c_node = _nextElement(self._c_node) if c_node is not NULL: return _newReadOnlyProxy(self._source_proxy, c_node) return None def getprevious(self): u"""Returns the preceding sibling of this element or None. """ cdef xmlNode* c_node self._assertNode() c_node = _previousElement(self._c_node) if c_node is not NULL: return _newReadOnlyProxy(self._source_proxy, c_node) return None @cython.final @cython.internal cdef class _ReadOnlyPIProxy(_ReadOnlyProxy): """A read-only proxy for processing instructions (for internal use only!)""" @property def target(self): self._assertNode() return funicode(self._c_node.name) @cython.final @cython.internal cdef class _ReadOnlyEntityProxy(_ReadOnlyProxy): """A read-only proxy for entity references (for internal use only!)""" property name: def __get__(self): return funicode(self._c_node.name) def __set__(self, value): value_utf = _utf8(value) if u'&' in value or u';' in value: raise ValueError(f"Invalid entity name '{value}'") tree.xmlNodeSetName(self._c_node, _xcstr(value_utf)) @property def text(self): return f'&{funicode(self._c_node.name)};' @cython.internal cdef class _ReadOnlyElementProxy(_ReadOnlyProxy): """The main read-only Element proxy class (for internal use only!).""" @property def attrib(self): self._assertNode() return dict(_collectAttributes(self._c_node, 3)) @property def prefix(self): """Namespace prefix or None. """ self._assertNode() if self._c_node.ns is not NULL: if self._c_node.ns.prefix is not NULL: return funicode(self._c_node.ns.prefix) return None @property def nsmap(self): """Namespace prefix->URI mapping known in the context of this Element. This includes all namespace declarations of the parents. Note that changing the returned dict has no effect on the Element. """ self._assertNode() return _build_nsmap(self._c_node) def get(self, key, default=None): u"""Gets an element attribute. """ self._assertNode() return _getNodeAttributeValue(self._c_node, key, default) def keys(self): u"""Gets a list of attribute names. The names are returned in an arbitrary order (just like for an ordinary Python dictionary). """ self._assertNode() return _collectAttributes(self._c_node, 1) def values(self): u"""Gets element attributes, as a sequence. The attributes are returned in an arbitrary order. """ self._assertNode() return _collectAttributes(self._c_node, 2) def items(self): u"""Gets element attributes, as a sequence. The attributes are returned in an arbitrary order. """ self._assertNode() return _collectAttributes(self._c_node, 3) cdef _ReadOnlyProxy _newReadOnlyProxy( _ReadOnlyProxy source_proxy, xmlNode* c_node): cdef _ReadOnlyProxy el if c_node.type == tree.XML_ELEMENT_NODE: el = _ReadOnlyElementProxy.__new__(_ReadOnlyElementProxy) elif c_node.type == tree.XML_PI_NODE: el = _ReadOnlyPIProxy.__new__(_ReadOnlyPIProxy) elif c_node.type in (tree.XML_COMMENT_NODE, tree.XML_ENTITY_REF_NODE): el = _ReadOnlyProxy.__new__(_ReadOnlyProxy) else: raise TypeError(f"Unsupported element type: {c_node.type}") el._c_node = c_node _initReadOnlyProxy(el, source_proxy) return el cdef inline _initReadOnlyProxy(_ReadOnlyProxy el, _ReadOnlyProxy source_proxy): if source_proxy is None: el._source_proxy = el el._dependent_proxies = [el] else: el._source_proxy = source_proxy source_proxy._dependent_proxies.append(el) cdef _freeReadOnlyProxies(_ReadOnlyProxy sourceProxy): cdef xmlNode* c_node cdef _ReadOnlyProxy el if sourceProxy is None: return if sourceProxy._dependent_proxies is None: return for el in sourceProxy._dependent_proxies: c_node = el._c_node el._c_node = NULL if el._free_after_use: tree.xmlFreeNode(c_node) del sourceProxy._dependent_proxies[:] # opaque wrapper around non-element nodes, e.g. the document node # # This class does not imply any restrictions on modifiability or # read-only status of the node, so use with caution. @cython.internal cdef class _OpaqueNodeWrapper: cdef tree.xmlNode* _c_node def __init__(self): raise TypeError, u"This type cannot be instantiated from Python" @cython.final @cython.internal cdef class _OpaqueDocumentWrapper(_OpaqueNodeWrapper): cdef int _assertNode(self) except -1: u"""This is our way of saying: this proxy is invalid! """ assert self._c_node is not NULL, u"Proxy invalidated!" return 0 cpdef append(self, other_element): u"""Append a copy of an Element to the list of children. """ cdef xmlNode* c_next cdef xmlNode* c_node self._assertNode() c_node = _roNodeOf(other_element) if c_node.type == tree.XML_ELEMENT_NODE: if tree.xmlDocGetRootElement(<tree.xmlDoc*>self._c_node) is not NULL: raise ValueError, u"cannot append, document already has a root element" elif c_node.type not in (tree.XML_PI_NODE, tree.XML_COMMENT_NODE): raise TypeError, f"unsupported element type for top-level node: {c_node.type}" c_node = _copyNodeToDoc(c_node, <tree.xmlDoc*>self._c_node) c_next = c_node.next tree.xmlAddChild(self._c_node, c_node) _moveTail(c_next, c_node) def extend(self, elements): u"""Append a copy of all Elements from a sequence to the list of children. """ self._assertNode() for element in elements: self.append(element) cdef _OpaqueNodeWrapper _newOpaqueAppendOnlyNodeWrapper(xmlNode* c_node): cdef _OpaqueNodeWrapper node if c_node.type in (tree.XML_DOCUMENT_NODE, tree.XML_HTML_DOCUMENT_NODE): node = _OpaqueDocumentWrapper.__new__(_OpaqueDocumentWrapper) else: node = _OpaqueNodeWrapper.__new__(_OpaqueNodeWrapper) node._c_node = c_node return node # element proxies that allow restricted modification @cython.internal cdef class _ModifyContentOnlyProxy(_ReadOnlyProxy): u"""A read-only proxy that allows changing the text content. """ property text: def __get__(self): self._assertNode() if self._c_node.content is NULL: return '' else: return funicode(self._c_node.content) def __set__(self, value): cdef tree.xmlDict* c_dict self._assertNode() if value is None: c_text = <const_xmlChar*>NULL else: value = _utf8(value) c_text = _xcstr(value) tree.xmlNodeSetContent(self._c_node, c_text) @cython.final @cython.internal cdef class _ModifyContentOnlyPIProxy(_ModifyContentOnlyProxy): """A read-only proxy that allows changing the text/target content of a processing instruction. """ property target: def __get__(self): self._assertNode() return funicode(self._c_node.name) def __set__(self, value): self._assertNode() value = _utf8(value) c_text = _xcstr(value) tree.xmlNodeSetName(self._c_node, c_text) @cython.final @cython.internal cdef class _ModifyContentOnlyEntityProxy(_ModifyContentOnlyProxy): "A read-only proxy for entity references (for internal use only!)" property name: def __get__(self): return funicode(self._c_node.name) def __set__(self, value): value = _utf8(value) assert u'&' not in value and u';' not in value, \ f"Invalid entity name '{value}'" c_text = _xcstr(value) tree.xmlNodeSetName(self._c_node, c_text) @cython.final @cython.internal cdef class _AppendOnlyElementProxy(_ReadOnlyElementProxy): u"""A read-only element that allows adding children and changing the text content (i.e. everything that adds to the subtree). """ cpdef append(self, other_element): u"""Append a copy of an Element to the list of children. """ cdef xmlNode* c_next cdef xmlNode* c_node self._assertNode() c_node = _roNodeOf(other_element) c_node = _copyNodeToDoc(c_node, self._c_node.doc) c_next = c_node.next tree.xmlAddChild(self._c_node, c_node) _moveTail(c_next, c_node) def extend(self, elements): u"""Append a copy of all Elements from a sequence to the list of children. """ self._assertNode() for element in elements: self.append(element) property text: """Text before the first subelement. This is either a string or the value None, if there was no text. """ def __get__(self): self._assertNode() return _collectText(self._c_node.children) def __set__(self, value): self._assertNode() if isinstance(value, QName): value = _resolveQNameText(self, value).decode('utf8') _setNodeText(self._c_node, value) cdef _ReadOnlyProxy _newAppendOnlyProxy( _ReadOnlyProxy source_proxy, xmlNode* c_node): cdef _ReadOnlyProxy el if c_node.type == tree.XML_ELEMENT_NODE: el = _AppendOnlyElementProxy.__new__(_AppendOnlyElementProxy) elif c_node.type == tree.XML_PI_NODE: el = _ModifyContentOnlyPIProxy.__new__(_ModifyContentOnlyPIProxy) elif c_node.type == tree.XML_COMMENT_NODE: el = _ModifyContentOnlyProxy.__new__(_ModifyContentOnlyProxy) else: raise TypeError(f"Unsupported element type: {c_node.type}") el._c_node = c_node _initReadOnlyProxy(el, source_proxy) return el cdef xmlNode* _roNodeOf(element) except NULL: cdef xmlNode* c_node if isinstance(element, _Element): c_node = (<_Element>element)._c_node elif isinstance(element, _ReadOnlyProxy): c_node = (<_ReadOnlyProxy>element)._c_node elif isinstance(element, _OpaqueNodeWrapper): c_node = (<_OpaqueNodeWrapper>element)._c_node else: raise TypeError, f"invalid argument type {type(element)}" if c_node is NULL: raise TypeError, u"invalid element" return c_node cdef xmlNode* _nonRoNodeOf(element) except NULL: cdef xmlNode* c_node if isinstance(element, _Element): c_node = (<_Element>element)._c_node elif isinstance(element, _AppendOnlyElementProxy): c_node = (<_AppendOnlyElementProxy>element)._c_node elif isinstance(element, _OpaqueNodeWrapper): c_node = (<_OpaqueNodeWrapper>element)._c_node else: raise TypeError, f"invalid argument type {type(element)}" if c_node is NULL: raise TypeError, u"invalid element" return c_node