Files
automtu/__pycache__/main.cpython-313.pyc

84 lines
17 KiB
Plaintext
Raw Normal View History

<EFBFBD>
<00><><EFBFBD>h#0<00><00><><00>SrSSKrSSKrSSKrSSKrSSKrSSKrSSKrSSKrSr Sr
Sr Sr Sr SrS rS
rSS jrS \S \4SjrSrSSjrSSjrS \S \4SjrS \S \\4SjrSr\S:Xa\"5 gg)u<>
wg_mtu_auto.py — Auto-detect egress IF, optionally probe Path MTU to one or more targets,
compute the correct WireGuard MTU, and apply it.
Examples:
sudo ./main.py
sudo ./main.py --force-egress-mtu 1452
sudo ./main.py --pmtu-target 46.4.224.77 --pmtu-target 2a01:4f8:2201:4695::2
sudo ./main.py --pmtu-target 46.4.224.77,2a01:4f8:2201:4695::2 --pmtu-policy min
sudo ./main.py --prefer-wg-egress --auto-pmtu-from-wg
./main.py --dry-run
<EFBFBD>Nc<00><><00>[R"US[R[RSS9RR 5$)NFT)<04>check<63>stdout<75>stderr<72>text)<06>
subprocess<EFBFBD>run<75>PIPE<50>DEVNULLr<00>strip<69><01>cmds <20>Y/home/kevinveenbirkenbach/Repositories/github.com/kevinveenbirkenbach/wg-mtu-auto/main.pyr r s4<00><00> <15>><3E>><3E> <0B>5<EFBFBD><1A><1F><1F><1A>9K<39>9K<39>RV<52> <06> <0C>f<EFBFBD>U<EFBFBD>U<EFBFBD>W<EFBFBD><15>c<00>z<00>[R"U[R[RS9R$)N)rr)rr r <00>
returncoder s r<00>rcr s'<00><00> <15>><3E>><3E>#<23>j<EFBFBD>&8<>&8<><1A>AS<41>AS<41> T<> _<> _<>_rc<00>P<00>[R"SU35R5$)N<>/sys/class/net/)<03>pathlib<69>Path<74>exists)<01>ifaces r<00> exists_ifacer$s!<00><00> <12><<3C><<3C>/<2F>%<25><17>1<> 2<> 9<> 9<> ;<3B>;rc<00><><00>[SUS3S5n[UR5R55sSSS5 $!,(df  g=f)Nrz/mtu<74>r)<04>open<65>int<6E>readr )r<00>fs r<00>read_mtur!(s8<00><00> <0A><0F><05>w<EFBFBD>d<EFBFBD>+<2B>S<EFBFBD> 1<>Q<EFBFBD><12>1<EFBFBD>6<EFBFBD>6<EFBFBD>8<EFBFBD>><3E>><3E>#<23>$<24>
2<EFBFBD> 1<> 1<>s <00>'A<03>
Ac <00><><00>U(a[SUSU35 g[R"SSSS[U5SU/SS 9 g)
Nz"[wg-mtu] DRY-RUN: ip link set mtu z dev <20>ip<69>link<6E>set<65>mtu<74>devT)r)<04>printrr <00>str)rr&<00>drys r<00>set_mtur+-s=<00><00>
<EFBFBD> <0A>2<>3<EFBFBD>%<25>u<EFBFBD>U<EFBFBD>G<EFBFBD>D<>E<><12><0E><0E><04>f<EFBFBD>e<EFBFBD>U<EFBFBD>C<EFBFBD><03>H<EFBFBD>e<EFBFBD>U<EFBFBD>K<>SW<53>Xrc<00><><00>U(dI[R"5S:wa/[S[RS9 [R
"S5 ggg)Nrz;[wg-mtu][ERROR] Please run as root (sudo) or use --dry-run.<2E><01>file<6C>)<06>os<6F>geteuidr(<00>sysr<00>exit)r*s r<00> require_rootr44s6<00><00> <0E>2<EFBFBD>:<3A>:<3A><<3C>1<EFBFBD>$<24> <0A>K<>RU<52>R\<5C>R\<5C>]<5D> <0B><08><08><11> <0B>%<25>3rc<00><><00>[[R"U5[R5$![a SU;s$f=f)N<>:)<05>
isinstance<EFBFBD> ipaddress<73>
ip_address<EFBFBD> IPv6Address<73>
ValueError)<01>addrs r<00>is_ipv6r=:s><00><00><1B><19>)<29>.<2E>.<2E>t<EFBFBD>4<>i<EFBFBD>6K<36>6K<36>L<>L<><4C> <15><1B><12>d<EFBFBD>{<7B><1A><1B>s<00>-0<00>A<03>Ac<00><><00>/n/SQ/SQ4H6n[U5nU(dMURUR55 M8 U$)N)r#z-4<>route<74>show<6F>default)r#<00>-6r?r@rA)r <00>extend<6E>
splitlines)<03>linesr<00>outs r<00>default_route_linesrGDs@<00><00> <0E>E<EFBFBD>8<>:b<>c<><03><11>#<23>h<EFBFBD><03> <0E>3<EFBFBD> <11>L<EFBFBD>L<EFBFBD><13><1E><1E>)<29> *<2A>d<01> <11>Lrc<00><<00>/n[5HCn[R"SU5nU(dM#URUR S55 ME U(dZ/SQ/SQ4HNn[ U5n[R"SU5nU(dM.URUR S55 MP /nUH_nU(aUS:Xd[ U5(dM"U(a[R"SU5(aMGXv;dMNURU5 Ma U$)Nz \bdev\s+(\S+)r/)r#r?<00>getz1.1.1.1)r#rBr?rIz2606:4700:4700::1111<31>loz ^(wg|tun)\d*$)rG<00>re<72>search<63>append<6E>groupr r<00>match)<08>
ignore_vpn<EFBFBD>devs<76>line<6E>mrrF<00>uniq<69>ds r<00>get_default_ifacesrVMs<><00><00> <0A>D<EFBFBD>#<23>%<25><04> <0E>I<EFBFBD>I<EFBFBD>&<26><04> -<2D><01> <0C>1<EFBFBD> <10>K<EFBFBD>K<EFBFBD><01><07><07><01>
<EFBFBD> #<23>&<26>
<10>5<>7k<37>l<>C<EFBFBD><15>c<EFBFBD>(<28>C<EFBFBD><12> <09> <09>*<2A>C<EFBFBD>0<>A<EFBFBD><10>q<EFBFBD><14> <0B> <0B>A<EFBFBD>G<EFBFBD>G<EFBFBD>A<EFBFBD>J<EFBFBD>'<27> m<01>
<0E>D<EFBFBD> <11><01><10>A<EFBFBD><14>I<EFBFBD>\<5C>!<21>_<EFBFBD>_<EFBFBD> <14> <15>"<22>(<28>(<28>#3<>Q<EFBFBD>7<>7<> <14> <0C>=<3D> <10>K<EFBFBD>K<EFBFBD><01>N<EFBFBD> <12> <10>Kr<00>wg_if<69>returnc<00>>^<00>[U4Sj[555$)Nc3<00><>># <00>UH4n[R"S[R"T5S3U5v<00> M6 g7f)z\bdev\s+z\bN)rKrL<00>escape)<03>.0rRrWs <20>r<00> <genexpr><3E>'wg_default_is_active.<locals>.<genexpr>gs4<00><><00><00>c<>Mb<4D>T<EFBFBD>r<EFBFBD>y<EFBFBD>y<EFBFBD>H<EFBFBD>R<EFBFBD>Y<EFBFBD>Y<EFBFBD>u<EFBFBD>%5<>$6<>b<EFBFBD>9<>4<EFBFBD>@<40>@<40>Mb<4D>s<00><?)<02>anyrG<00>rWs`r<00>wg_default_is_activeraes<00><><00> <0E>c<>M`<60>Mb<4D>c<> c<>crc<00><><00>SSSSSS[U5S[[S[[U5555/ n[ U5(aUR SS 5 [ X1/-5S
:H$) N<>pingz-M<>doz-c<>1z-sz-Wr/rBr)r)<00>maxr<00>roundr=<00>insertr)<04>payload<61>target<65> timeout_s<5F>bases r<00>ping_okrmlsb<00><00> <12>D<EFBFBD>$<24><04>c<EFBFBD>4<EFBFBD><13>W<EFBFBD><1C>t<EFBFBD>S<EFBFBD><13>Q<EFBFBD>PS<50>TY<54>Zc<5A>Td<54>Pe<50>If<49>Eg<45> h<>D<EFBFBD><0E>v<EFBFBD><EFBFBD><EFBFBD> <0C> <0B> <0B>A<EFBFBD>t<EFBFBD><1C> <0A>d<EFBFBD>X<EFBFBD>o<EFBFBD> <1E>!<21> #<23>#rc<00><00>[U5(aSOSn[XU5(dSHn[XPU5(dMUn O gXSp<>nXg::a,Xg-S-n [X<>U5(aU nU S-nOU S-
nXg::aM,UbX<>-$S$)zBinary-search the largest payload that passes with DF. Return Path MTU (payload + hdr) or None.
Header: +28 (IPv4), +48 (IPv6).<2E>0<00>)i<>i<>itN<>r/)r=rm)
rj<00>
lo_payload<EFBFBD>
hi_payload<EFBFBD>timeout<75>hdr<64>prJ<00>hi<68>best<73>mids
r<00>
probe_pmturzss<><00><00><18><06><0F><0F>"<22>R<EFBFBD>C<EFBFBD> <12>:<3A>w<EFBFBD> /<2F> /<2F>#<23>A<EFBFBD><16>q<EFBFBD>'<27>*<2A>*<2A><1E>
<EFBFBD><15>$<24>
<18><1D>4<EFBFBD>D<EFBFBD>B<EFBFBD>
<0C>(<28><11>w<EFBFBD>1<EFBFBD>n<EFBFBD><03> <12>3<EFBFBD><07> (<28> (<28><16>D<EFBFBD><14>q<EFBFBD><17>B<EFBFBD><14>q<EFBFBD><17>B<EFBFBD> <0A>(<28> <20>+<2B>D<EFBFBD>J<EFBFBD>5<><14>5rc<00><><00>U(d [S5eUS:Xa [U5$US:Xa [U5$US:Xa([[R
"[ U555$[SU35e)Nzno PMTUs to choose from<6F>minrf<00>medianzunknown policy )r;r|rfr<00>
statisticsr}<00>sorted)<02>pmtus<75>policys r<00>choose_effectiver<65><00>sg<00><00> <10><18>2<>3<>3<> <0A><15><EFBFBD><12>5<EFBFBD>z<EFBFBD><19> <0A><15><EFBFBD><12>5<EFBFBD>z<EFBFBD><19> <0A><18><19><12>:<3A>$<24>$<24>V<EFBFBD>E<EFBFBD>]<5D>3<>4<>4<>
<14><EFBFBD>v<EFBFBD>h<EFBFBD>/<2F>
0<EFBFBD>0rc<00>F<00>[U5(dg[SSU/5S:H$)NF<4E>wgr@r)rrr`s r<00> wg_is_activer<65><00>s'<00><00> <17><05> <1E> <1E><14> <0A>t<EFBFBD>V<EFBFBD>U<EFBFBD>#<23> $<24><01> )<29>)rc<00><><00>/n[SSUS/5nUR5HynUR5R5n[ U5S:<3A>dM2USS:wdM=USnUR SS5S nURS
5nUR U5 M{ U(d<>[SS U/5nU(a[R"S U[RS 9HWnURS5R5nUR SS5S RS
5nUR U5 MY /n UH$n
U
(dM X<>;dMU R U
5 M& U $)u@Return list of peer endpoints (hostnames/IPs) port stripped.r<>r@<00> endpointsrq<00><><EFBFBD><EFBFBD><EFBFBD>z(none)r6r/rz[]<5D>showconfz^Endpoint\s*=\s*(.+)$)<01>flags) r rDr <00>split<69>len<65>rsplitrMrK<00>finditer<65> MULTILINErN) rW<00>targetsrFrR<00>parts<74>ep<65>host<73>confrS<00>cleaned<65>ts r<00>wg_peer_endpointsr<73><00>s5<00><00><10>G<EFBFBD> <0E>t<EFBFBD>V<EFBFBD>U<EFBFBD>K<EFBFBD>0<>
1<EFBFBD>C<EFBFBD><13><0E><0E> <20><04><14>
<EFBFBD>
<EFBFBD> <0C>"<22>"<22>$<24><05> <0E>u<EFBFBD>:<3A><11>?<3F>u<EFBFBD>R<EFBFBD>y<EFBFBD>H<EFBFBD>4<><16>r<EFBFBD><19>B<EFBFBD><15>9<EFBFBD>9<EFBFBD>S<EFBFBD>!<21>$<24>Q<EFBFBD>'<27>D<EFBFBD><17>:<3A>:<3A>d<EFBFBD>#<23>D<EFBFBD> <13>N<EFBFBD>N<EFBFBD>4<EFBFBD> <20>!<21> <13><12>D<EFBFBD>*<2A>e<EFBFBD>,<2C>-<2D><04> <0F><17>[<5B>[<5B>!9<>4<EFBFBD>r<EFBFBD>|<7C>|<7C>T<><01><16>W<EFBFBD>W<EFBFBD>Q<EFBFBD>Z<EFBFBD>%<25>%<25>'<27><02><19>y<EFBFBD>y<EFBFBD><13>a<EFBFBD>(<28><11>+<2B>1<>1<>$<24>7<><04><17><0E><0E>t<EFBFBD>$<24>U<01> <11>G<EFBFBD> <14><01> <0C>1<EFBFBD><11>!<21> <13>N<EFBFBD>N<EFBFBD>1<EFBFBD> <1D><15> <13>Nrc <00>L<00>[R"SS9nURSSS9 URSSSS 9 URS
SS S 9 URS [RR S S5SS9 URS[ [ [RR SS55SS9 URS[ [ [RR SS55SS9 URSSSS 9 URS[SSS9 URS [ S!S"S9 URS#[ S$S%S9 URS&/S'QS(S)S*9 URS+SS,S 9 URS-[ S.S/9 URS0[ S1S/9 UR5n[UR5 UR(a URnO<>UR(+n[US29nUR(a{[UR5(aa[!UR5(aGURU;aUR#UR5 UR%S3UR5 U(aUS3OSnU(d.['S4[(R*S59 [(R,"S65 [/U5(d2['S7US83[(R*S59 [(R,"S95 ['S:U35 UR(a(X!R:Xa['S;URS<35 URU:Xa@[UR5(d&['S=URS>3[(R*S59 UR0(aH['S?UR0S@U35 [3X!R0UR5 UR0nO [5U5n['SAU35 /nUR6(ahUR6HXnUR9UR;SB5Vs/sH)o<>R=5(dMUR=5PM+ sn5 MZ UR>(a<>[UR5(aW[AUR5n U (a/['SCSDRCU 535 UR9U 5 O%['SE5 O['SFURSG35 U(a[E[FRIU55nUn
U(a<>/n ['SHSDRCU5SIURJSJ35 UHbn [MX<>RNURPURR5n ['SKU SLU (aU OSM35 U (dMQU RUU 5 Md U (a<[WX<>RJ5n['SNURJSOU35 [YX^5n
O ['SP5 [[UR\X<>R^-
5n['SQURSRUSSUR^STUR\SJ3 5 UR`bxUR`UR\:aD['SUUR`SVUR\SWUR\SX35 UR\Ul0UR`n['SYU35 [/UR5(a<[3URX<>R5 ['SZURS[U35 O['S\URS]35 ['S^US_US`U
SDURSaU3
5 gs snf)bNzWCompute/apply WireGuard MTU based on egress MTU and optional multi-target PMTU probing.)<01> descriptionz --egress-ifz5Explicit egress interface (auto-detected if omitted).)<01>helpz--prefer-wg-egress<73>
store_truezXAllow/consider wg* as egress and prefer it if default route uses wg (default: disabled).)<02>actionr<6E>z--auto-pmtu-from-wgzOAutomatically add WireGuard peer endpoints as PMTU targets (default: disabled).z--wg-if<69>WG_IF<49>wg0z(WireGuard interface name (default: wg0).)rAr<>z --wg-overhead<61> WG_OVERHEAD<41>80z/Bytes of WG overhead to subtract (default: 80).)<03>typerAr<>z--wg-min<69>WG_MIN<49>1280z'Minimum allowed WG MTU (default: 1280).z --pmtu-targetrMzQTarget hostname/IP to probe PMTU. Can be given multiple times OR comma-separated.z--pmtu-timeout<75><00>?z0Timeout (seconds) per ping probe (default: 1.0).z--pmtu-min-payload<61><64>z4Lower bound payload for PMTU search (default: 1200).z--pmtu-max-payload<61><64>z>Upper bound payload for PMTU search (default: 1472 ~ 1500-28).z --pmtu-policy)r|r}rfr|zDHow to choose effective PMTU across multiple targets (default: min).)<03>choicesrAr<>z --dry-runz&Show actions without applying changes.z --set-wg-mtuzTForce a specific MTU to apply on the WireGuard interface (overrides computed value).)r<>r<>z--force-egress-mtuz?Force this MTU on the egress interface before computing wg MTU.)rPrzD[wg-mtu][ERROR] Could not detect egress interface (use --egress-if).r-rqz[wg-mtu][ERROR] Interface z does not exist.<2E>z$[wg-mtu] Detected egress interface: z#[wg-mtu] Using WireGuard interface z as egress basis.z[wg-mtu][WARN] z0 selected as egress but WireGuard is not active.z[wg-mtu] Forcing egress MTU z on z[wg-mtu] Egress base MTU: <20>,z7[wg-mtu] Auto-added WG peer endpoints as PMTU targets: z, zB[wg-mtu] INFO: No WG peer endpoints discovered (wg show/showconf).z[wg-mtu] INFO: z3 is not active; skipping auto PMTU targets from WG.z[wg-mtu] Probing Path MTU for: z (policy=<3D>)z [wg-mtu] - z: z probe failedz#[wg-mtu] Selected Path MTU (policy=z): zE[wg-mtu] WARNING: All PMTU probes failed. Falling back to egress MTU.z[wg-mtu] Computed z MTU: z (overhead=z, min=z[wg-mtu][WARN] --set-wg-mtu z is below wg-min z; clamping to <20>.z+[wg-mtu] Forcing WireGuard MTU (override): z[wg-mtu] Applied: z MTU z[wg-mtu] NOTE: zA not present yet. Start WireGuard first, then re-run this script.z[wg-mtu] Done. Summary: egress=z mtu=z, effective_mtu=z_mtu=)1<>argparse<73>ArgumentParser<65> add_argumentr0<00>environrIr<00>float<61>
parse_argsr4<00>dry_run<75> egress_if<69>prefer_wg_egressrVr<>rWra<00>removerhr(r2rr3r<00>force_egress_mtur+r!<00> pmtu_targetrCr<>r <00>auto_pmtu_from_wgr<67><00>join<69>list<73>dict<63>fromkeys<79> pmtu_policyrz<00>pmtu_min_payload<61>pmtu_max_payload<61> pmtu_timeoutrMr<>r|rf<00>wg_min<69> wg_overhead<61>
set_wg_mtu)<10>ap<61>args<67>egressrP<00>cands<64>base_mtu<74> pmtu_targets<74>item<65>x<>
wg_targets<EFBFBD> effective_mtu<74>goodr<64>rv<00>chosen<65>wg_mtus r<00>mainr<6E><00>su<00><00> <11> <20> <20>.G<02>
H<02>B<EFBFBD><06>O<EFBFBD>O<EFBFBD>M<EFBFBD>(_<>O<EFBFBD>`<60><06>O<EFBFBD>O<EFBFBD>(<28><1C>s<><14>u<01><06>O<EFBFBD>O<EFBFBD>)<29>,<2C>j<><14>l<01><06>O<EFBFBD>O<EFBFBD>I<EFBFBD>r<EFBFBD>z<EFBFBD>z<EFBFBD>~<7E>~<7E>g<EFBFBD>u<EFBFBD>'E<>Lv<4C>O<EFBFBD>w<><06>O<EFBFBD>O<EFBFBD>O<EFBFBD>#<23>s<EFBFBD>2<EFBFBD>:<3A>:<3A>><3E>><3E>-<2D>Y]<5D>;^<5E>7_<37>gX<02>O<EFBFBD>Y<02><06>O<EFBFBD>O<EFBFBD>J<EFBFBD>S<EFBFBD>#<23>b<EFBFBD>j<EFBFBD>j<EFBFBD>n<EFBFBD>n<EFBFBD>X<EFBFBD>v<EFBFBD>6V<36>2W<32>_H<02>O<EFBFBD>I<02><06>O<EFBFBD>O<EFBFBD>O<EFBFBD>H<EFBFBD><O<02>O<EFBFBD>P<02><06>O<EFBFBD>O<EFBFBD>$<24>5<EFBFBD>#<23>Dv<44>O<EFBFBD>w<><06>O<EFBFBD>O<EFBFBD>(<28>s<EFBFBD>D<EFBFBD>G}<7D>O<EFBFBD>~<7E><06>O<EFBFBD>O<EFBFBD>(<28>s<EFBFBD>D<EFBFBD>HH<02>O<EFBFBD>I<02><06>O<EFBFBD>O<EFBFBD>O<EFBFBD>-E<>u<EFBFBD>_<><14>a<01><06>O<EFBFBD>O<EFBFBD>K<EFBFBD> <0C>;c<>O<EFBFBD>d<><06>O<EFBFBD>O<EFBFBD>N<EFBFBD><13>4J<02>O<EFBFBD>K<02><06>O<EFBFBD>O<EFBFBD>(<28>s<EFBFBD>9z<39>O<EFBFBD>{<7B> <0A>=<3D>=<3D>?<3F>D<EFBFBD><10><14><1C><1C><1E> <0C>~<7E>~<7E><15><1E><1E><06><1D>.<2E>.<2E>.<2E>
<EFBFBD>"<22>j<EFBFBD>9<><05> <0F> <20> <20>\<5C>$<24>*<2A>*<2A>%=<3D>%=<3D>BV<42>W[<5B>Wa<57>Wa<57>Bb<42>Bb<42><13>z<EFBFBD>z<EFBFBD>U<EFBFBD>"<22><15> <0C> <0C>T<EFBFBD>Z<EFBFBD>Z<EFBFBD>(<28> <11>L<EFBFBD>L<EFBFBD><11>D<EFBFBD>J<EFBFBD>J<EFBFBD> '<27>"<22><15>q<EFBFBD><18><04><06> <11> <0A>T<>[^<5E>[e<>[e<>f<> <0B><08><08><11> <0B> <17><06> <1F> <1F> <0A>*<2A>6<EFBFBD>(<28>2B<32>C<>#<23>*<2A>*<2A>U<> <0B><08><08><11> <0B> <09> 0<><16><08>
9<EFBFBD>:<3A> <0C><1C><1C><16>:<3A>:<3A>!5<> <0A>3<>D<EFBFBD>J<EFBFBD>J<EFBFBD><<3C>?P<>Q<>R<> <0B>z<EFBFBD>z<EFBFBD>V<EFBFBD><1B>L<EFBFBD><14><1A><1A>$<<3C>$<<3C> <0A><0F><04>
<EFBFBD>
<EFBFBD>|<7C>+[<5B>\<5C>cf<63>cm<63>cm<63>n<> <0B><1C><1C> <0A>,<2C>T<EFBFBD>-B<>-B<>,C<>4<EFBFBD><06>x<EFBFBD>P<>Q<><0F><06>-<2D>-<2D>t<EFBFBD>|<7C>|<7C><<3C><17>(<28>(<28><08><1B>F<EFBFBD>#<23><08> <09> &<26>x<EFBFBD>j<EFBFBD>
1<EFBFBD>2<><16>L<EFBFBD> <0B><17><17><18>$<24>$<24>D<EFBFBD> <18> <1F> <1F>D<EFBFBD>J<EFBFBD>J<EFBFBD>s<EFBFBD>O<EFBFBD> Q<>O<EFBFBD>q<EFBFBD>w<EFBFBD>w<EFBFBD>y<EFBFBD><19><11><17><17><19>O<EFBFBD> Q<> R<>%<25> <0C><1D><1D> <17><04>
<EFBFBD>
<EFBFBD> #<23> #<23>*<2A>4<EFBFBD>:<3A>:<3A>6<>J<EFBFBD><19><15>O<>PT<50>PY<50>PY<50>Zd<5A>Pe<50>Of<4F>g<>h<><1C>#<23>#<23>J<EFBFBD>/<2F><15>Z<>[<5B> <11>O<EFBFBD>D<EFBFBD>J<EFBFBD>J<EFBFBD><<3C>/b<>c<> d<><14><1B>D<EFBFBD>M<EFBFBD>M<EFBFBD>,<2C>7<>8<> <0C><1D>M<EFBFBD><13><11><04> <0A>/<2F><04> <09> <09>,<2C>0G<30>/H<> <09>RV<52>Rb<52>Rb<52>Qc<51>cd<63>e<>f<><1D>A<EFBFBD><1A>1<EFBFBD>3<>3<>T<EFBFBD>5J<35>5J<35>D<EFBFBD>L]<5D>L]<5D>^<5E>A<EFBFBD> <11>L<EFBFBD><11><03>2<EFBFBD>1<EFBFBD>a<EFBFBD>.<2E>%A<>B<> C<><10>q<EFBFBD><14> <0B> <0B>A<EFBFBD><0E> <1E>
<10>%<25>d<EFBFBD>,<<3C>,<<3C>=<3D>F<EFBFBD> <11>7<><04>8H<38>8H<38>7I<37><13>V<EFBFBD>H<EFBFBD>U<> V<><1F><08>1<>M<EFBFBD> <11>Y<> Z<><11><14><1B><1B>m<EFBFBD>.><3E>.><3E>><3E> ?<3F>F<EFBFBD> <09> <1E>t<EFBFBD>z<EFBFBD>z<EFBFBD>l<EFBFBD>&<26><16><08> <0C>T<EFBFBD>EU<45>EU<45>DV<44>V\<5C>]a<>]h<>]h<>\i<>ij<69>
k<EFBFBD>l<> <0C><EFBFBD><EFBFBD>"<22> <0F>?<3F>?<3F>T<EFBFBD>[<5B>[<5B> (<28> <11>0<><14><1F><1F>0A<30>AR<41>SW<53>S^<5E>S^<5E>R_<52>_m<5F>nr<6E>ny<6E>ny<6E>mz<6D>z{<7B>|<7C> }<7D>"<22>k<EFBFBD>k<EFBFBD>D<EFBFBD>O<EFBFBD><15><1F><1F><06> <0A>;<3B>F<EFBFBD>8<EFBFBD>D<>E<><14>D<EFBFBD>J<EFBFBD>J<EFBFBD><1F><1F><0F><04>
<EFBFBD>
<EFBFBD>F<EFBFBD>L<EFBFBD>L<EFBFBD>1<> <0A>"<22>4<EFBFBD>:<3A>:<3A>,<2C>e<EFBFBD>F<EFBFBD>8<EFBFBD><<3C>=<3D> <0A><0F><04>
<EFBFBD>
<EFBFBD>|<7C>+l<>m<>n<> <09> +<2B>F<EFBFBD>8<EFBFBD>5<EFBFBD><18>
<EFBFBD>BR<EFBFBD>S`<60>Ra<52>ac<61>dh<64>dn<64>dn<64>co<63>ot<6F>u{<7B>t|<7C>
}<7D>~<7E><>k!Rs <00> ^!
<EFBFBD>%^!
<EFBFBD>__main__)T)r<>r<>r<>)r|)<1D>__doc__r<5F>r8r0rrKr~rr2r rrr!r+r4r=rGrVr)<00>boolrarmrzr<>r<>r<>r<>r<><00>__name__<5F>rr<00><module>r<>s<><00><01> <04><10><10> <09><0E> <09><11><11>
<EFBFBD>
<15> `<01><<3C>%<25>
Y<01><14> <1B><11><10>0d<01><03>d<01><04>d<01>$<24>6<>. 1<>*<2A><03>*<2A><04>*<2A> <13>S<EFBFBD><13>T<EFBFBD>#<23>Y<EFBFBD><13>Fv<01>r <0C>z<EFBFBD><19><08>F<EFBFBD>r