From 23635def8b654097178f73ed1b57fc50965142d5 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Wed, 21 Apr 2021 07:51:32 -0700 Subject: [PATCH] add ufw to docs --- README.md | 3 +- docs/parsers/ping.md | 1 - docs/parsers/ufw.md | 302 +++++++++++++++++++++++++++++++++++++++++++ docs/utils.md | 4 +- jc/man/jc.1.gz | Bin 2062 -> 2068 bytes man/jc.1.gz | Bin 2062 -> 2068 bytes 6 files changed, 306 insertions(+), 4 deletions(-) create mode 100644 docs/parsers/ufw.md diff --git a/README.md b/README.md index d9c49018..584f2ed3 100644 --- a/README.md +++ b/README.md @@ -102,7 +102,7 @@ pip3 install jc | FreeBSD | `portsnap fetch update && cd /usr/ports/textproc/py-jc && make install clean` | | Ansible filter plugin | `ansible-galaxy collection install community.general` | -> For more packages and binaries, see https://kellyjonbrazil.github.io/jc-packaging/. +> For more packages and binaries, see the [jc packaging](https://kellyjonbrazil.github.io/jc-packaging/) site. ## Usage `jc` accepts piped input from `STDIN` and outputs a JSON representation of the previous command's output to `STDOUT`. @@ -182,6 +182,7 @@ The JSON output can be compact (default) or pretty formatted with the `-p` optio - `--timedatectl` enables the `timedatectl status` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/timedatectl)) - `--tracepath` enables the `tracepath` and `tracepath6` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/tracepath)) - `--traceroute` enables the `traceroute` and `traceroute6` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/traceroute)) +- `--ufw` enables the `ufw status` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/ufw)) - `--uname` enables the `uname -a` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/uname)) - `--upower` enables the `upower` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/upower)) - `--uptime` enables the `uptime` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/uptime)) diff --git a/docs/parsers/ping.md b/docs/parsers/ping.md index 3e7db2b5..fe0c0bc6 100644 --- a/docs/parsers/ping.md +++ b/docs/parsers/ping.md @@ -97,7 +97,6 @@ Examples: ] } - $ ping -c 3 -p ff cnn.com | jc --ping -p -r { "destination_ip": "151.101.129.67", diff --git a/docs/parsers/ufw.md b/docs/parsers/ufw.md new file mode 100644 index 00000000..750c7026 --- /dev/null +++ b/docs/parsers/ufw.md @@ -0,0 +1,302 @@ +[Home](https://kellyjonbrazil.github.io/jc/) + +# jc.parsers.ufw +jc - JSON CLI output utility `ufw status` command output parser + +Usage (cli): + + $ ufw status | jc --ufw + + or + + $ jc ufw status + +Usage (module): + + import jc.parsers.ufw + result = jc.parsers.ufw.parse(ufw_command_output) + +Schema: + + { + "status": string, + "logging": string, + "logging_level": string, + "default": string, + "new_profiles": string, + "rules": [ + { + "action": string, + "action_direction": string, # null if blank + "index": integer, # null if blank + "network_protocol": string, + "to_ip": string, + "to_ip_prefix": integer, + "to_interface": string, + "to_transport": string, # null if to_service is set + "to_start_port": integer, # null if to_service is set + "to_end_port": integer, # null if to_service is set + "to_service": string, # null if any above are set + "from_ip": string, + "from_ip_prefix": integer, + "from_interface": string, + "from_transport": string, # null if from_service is set + "from_start_port": integer, # null if from_service is set + "from_end_port": integer, # null if from_service is set + "from_service": string, # null if any above are set + } + ] + } + +Examples: + + $ ufw status verbose numbered | jc --ufw -p + { + "status": "active", + "logging": "on", + "logging_level": "low", + "default": "deny (incoming), allow (outgoing), deny (routed)", + "new_profiles": "skip", + "rules": [ + { + "action": "ALLOW", + "action_direction": "IN", + "index": 1, + "network_protocol": "ipv4", + "to_interface": "any", + "to_transport": "tcp", + "to_start_port": 22, + "to_end_port": 22, + "to_service": null, + "to_ip": "0.0.0.0", + "to_ip_prefix": "0", + "from_ip": "0.0.0.0", + "from_ip_prefix": "0", + "from_interface": "any", + "from_transport": "any", + "from_start_port": 0, + "from_end_port": 65535, + "from_service": null + }, + { + "action": "ALLOW", + "action_direction": "IN", + "index": 2, + "network_protocol": "ipv6", + "to_interface": "any", + "to_transport": "tcp", + "to_start_port": 22, + "to_end_port": 22, + "to_service": null, + "to_ip": "::", + "to_ip_prefix": "0", + "from_ip": "::", + "from_ip_prefix": "0", + "from_interface": "any", + "from_transport": "any", + "from_start_port": 0, + "from_end_port": 65535, + "from_service": null + }, + { + "action": "ALLOW", + "action_direction": "IN", + "index": 3, + "network_protocol": "ipv4", + "to_interface": "any", + "to_transport": null, + "to_service": "Apache Full", + "to_start_port": null, + "to_end_port": null, + "to_ip": "0.0.0.0", + "to_ip_prefix": "0", + "from_ip": "0.0.0.0", + "from_ip_prefix": "0", + "from_interface": "any", + "from_transport": "any", + "from_start_port": 0, + "from_end_port": 65535, + "from_service": null + }, + { + "action": "ALLOW", + "action_direction": "IN", + "index": 4, + "network_protocol": "ipv6", + "to_interface": "any", + "to_ip": "2405:204:7449:49fc:f09a:6f4a:bc93:1955", + "to_ip_prefix": "128", + "to_transport": "any", + "to_start_port": 0, + "to_end_port": 65535, + "to_service": null, + "from_ip": "::", + "from_ip_prefix": "0", + "from_interface": "any", + "from_transport": "any", + "from_start_port": 0, + "from_end_port": 65535, + "from_service": null + }, + { + "action": "ALLOW", + "action_direction": "IN", + "index": 5, + "network_protocol": "ipv4", + "to_interface": "en0", + "to_ip": "10.10.10.10", + "to_ip_prefix": "32", + "to_transport": "any", + "to_start_port": 0, + "to_end_port": 65535, + "to_service": null, + "from_ip": "0.0.0.0", + "from_ip_prefix": "0", + "from_interface": "any", + "from_transport": "any", + "from_start_port": 0, + "from_end_port": 65535, + "from_service": null + } + ] + } + + $ ufw status verbose numbered | jc --ufw -p -r + { + "status": "active", + "logging": "on", + "logging_level": "low", + "default": "deny (incoming), allow (outgoing), deny (routed)", + "new_profiles": "skip", + "rules": [ + { + "action": "ALLOW", + "action_direction": "IN", + "index": "1", + "network_protocol": "ipv4", + "to_interface": "any", + "to_transport": "tcp", + "to_start_port": "22", + "to_end_port": "22", + "to_service": null, + "to_ip": "0.0.0.0", + "to_ip_prefix": "0", + "from_ip": "0.0.0.0", + "from_ip_prefix": "0", + "from_interface": "any", + "from_transport": "any", + "from_start_port": "0", + "from_end_port": "65535", + "from_service": null + }, + { + "action": "ALLOW", + "action_direction": "IN", + "index": "2", + "network_protocol": "ipv6", + "to_interface": "any", + "to_transport": "tcp", + "to_start_port": "22", + "to_end_port": "22", + "to_service": null, + "to_ip": "::", + "to_ip_prefix": "0", + "from_ip": "::", + "from_ip_prefix": "0", + "from_interface": "any", + "from_transport": "any", + "from_start_port": "0", + "from_end_port": "65535", + "from_service": null + }, + { + "action": "ALLOW", + "action_direction": "IN", + "index": "3", + "network_protocol": "ipv4", + "to_interface": "any", + "to_transport": null, + "to_service": "Apache Full", + "to_start_port": null, + "to_end_port": null, + "to_ip": "0.0.0.0", + "to_ip_prefix": "0", + "from_ip": "0.0.0.0", + "from_ip_prefix": "0", + "from_interface": "any", + "from_transport": "any", + "from_start_port": "0", + "from_end_port": "65535", + "from_service": null + }, + { + "action": "ALLOW", + "action_direction": "IN", + "index": "4", + "network_protocol": "ipv6", + "to_interface": "any", + "to_ip": "2405:204:7449:49fc:f09a:6f4a:bc93:1955", + "to_ip_prefix": "128", + "to_transport": "any", + "to_start_port": "0", + "to_end_port": "65535", + "to_service": null, + "from_ip": "::", + "from_ip_prefix": "0", + "from_interface": "any", + "from_transport": "any", + "from_start_port": "0", + "from_end_port": "65535", + "from_service": null + }, + { + "action": "ALLOW", + "action_direction": "IN", + "index": "5", + "network_protocol": "ipv4", + "to_interface": "en0", + "to_ip": "10.10.10.10", + "to_ip_prefix": "32", + "to_transport": "any", + "to_start_port": "0", + "to_end_port": "65535", + "to_service": null, + "from_ip": "0.0.0.0", + "from_ip_prefix": "0", + "from_interface": "any", + "from_transport": "any", + "from_start_port": "0", + "from_end_port": "65535", + "from_service": null + } + ] + } + + +## info +```python +info() +``` +Provides parser metadata (version, author, etc.) + +## parse +```python +parse(data, raw=False, quiet=False) +``` + +Main text parsing function + +Parameters: + + data: (string) text data to parse + raw: (boolean) output preprocessed JSON if True + quiet: (boolean) suppress warning messages if True + +Returns: + + Dictionary. Raw or processed structured data. + +## Parser Information +Compatibility: linux + +Version 1.0 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/utils.md b/docs/utils.md index e245fd8c..1cac00ed 100644 --- a/docs/utils.md +++ b/docs/utils.md @@ -74,7 +74,7 @@ Returns: convert_to_int(value) ``` -Converts string input to integer by stripping all non-numeric characters +Converts string and float input to int. Strips all non-numeric characters from strings. Parameters: @@ -90,7 +90,7 @@ Returns: convert_to_float(value) ``` -Converts string input to float by stripping all non-numeric characters +Converts string and int input to float. Strips all non-numeric characters from strings. Parameters: diff --git a/jc/man/jc.1.gz b/jc/man/jc.1.gz index d860a611e53e602cfe3e64ecfcb42ecaff3b921e..3ceb719e859e2b709804f30494fa9c446a522498 100644 GIT binary patch literal 2068 zcmV+v2#@$#2no#>O`jrYc)jmQ_|}($*)zAi8F=(ex?+$-9stPNq^AW;db% ztCZ!us7c-`l^Mp1grzbQp{+|{NJ;c{HeW=OC>YPD)6wjb{TH2CjBcZ=TlU9%v7F3j z(Vsz}G$>okn3=k;{P`k4%e(K)O9!O$@+unNPUsV&{x9cP3Kj)7QfO9kZDg@#vS23G zvb1J^PVzVwK(kVoB7u*nHq|O;cj?Dyc{!Qgr3=#POo9b+g=tZ0VFXOWN>!jI=ogGV zNmUsZs~kK_{$d(et@0Y@pO&CbL-RwM&9FVQd4C@Hx?H2?!yndc&r+=5~F1~C!`x};%i@TwTF z)0wj3V)ub(k{gIB2Z2IaW~#DOXzty>t(jlRVDK?mK)8iA7s22*3gGK7J-gF|8m2R!-2-dx0j!yClQvP_~6=z4m^X62pFQkkHNbmO|gV>n)0H z1+g8G@Rg^p?8vm`dc*XH6jYNZvq^{b5;7qZ&fkXVQM(Nd96?TE%M$U#{(%2vEdFHp zp!~QMm;b)#z;`K>n+_>`u315(rTy^WuoFkd(gTblbkwEo#PdaUXxrn#yLH%Fqn!G*A}!5!SwJp#7;?$AK6u;;kMi^n$EXSm}#QoMv>MsOtj z`XKppj~!WtneJy`%H&>xUQ^?=Jf{O&G9Kr*1a@yGSE zw|pAswCQnrmj(SPU}_UvcT7667j8w~l5pG`g~IINP>z;1>@Nu|4dx{cM#Yc9zFkR` zzNDopq@{EFO^RfZs+JaHyTz=`T_z1HqlYV53~{7i25)9f#9KVW#jSc=wVK1Dh+B8) z?l`|0cl^(9(6ZkNd$z5I26_}#smpfweUtlD!F|k#Vj=Irmul;8QjY9{@7BbT-Eil7 zPhHu@4i)#nHZFPKw;TAJ)5?FD-n?EGYVJT^N5?35vt0#)1ws8g(!b+c@*HLP3f2#w zl&AD4c5mHxZ5WmQM64>fOjChnwC*b&KeAH-Ac7w1@N``%Blds;MU;#ik(Ewt!|-fD zf4}+VCLR8gm#DbPo5%Tq8oCaC&Eg8~mw3I+ls4>1a(cvr&fmu0#`Bx`ZG=IACx?VrAO?dyaV_!AHeky)BAMln z)JCba%Qt3V>uabb32a4;y@)5gZW(N=p!rl~ncCvGo5@8G?2P>5?~kI!#rj4*|MLv_ zt3z;ERhv{-=G8wyGU*y^*FNyyy3%H9Jr{HEj9^H%uN8Fi z8VOA80`7wCCFl_F8=17W;%};zTY|yPVe*uOa8tuV!Xo2JLPe0rJ`;kvoZ2-U2@DTY z19vDWJr>pvd{QanS-Ig*2!xig>*qokv~_JO&N8UW-~?;?;BrVo71c7?XT1Li4!brc z7Cqit$HT<&rOWk~zg+&xK5_`~ilIiUEEwnLDVc%DV+Dn|>P|^e~grr{(qh z7M{-;EW$_4|06SY`iR_vDpth*Yn^kMp~-hau(7r@7sKHi7NuI@;P4O)JHr=(`Qq#C yWtEkgwDn04#n)^)oLmJUc^5Lo$(0m_*^Owx zYQ=J1)Ff|}$_(R0%2qNHp{+|{NJ;#4I-AGiI2g?)li~D|{TH2?4{zhETlU9nz8KG@ z@t;AUG$>okgqgaq{P`k4%e(K)O9!O$@+uzPj_DJk{x9d)3M>k4q|mJ7+Q?$fWWh|L zWob=>PVyuXK(kVoB888rcBNI$?p7b;#pQTKZABWfS&4p`MoGyHssR|t$~+gTn#Ec{Ei{V506R zlJ1G>6w?YKVCe)My%%Ugyh}2y4rN<-wv~2+L8Y7hJJMjDP<9l5e%(q6u|o!s=$=Zt za==v&Os*YHuKR%619cBDm#Iip>K$#k9-;Da9cE4fNET*2c(=}J)eRE`t?51db^~$6 z35i4>v{(!6!ASPNweXsO=z*Fh_6EWx17h!A4~Df?Rk?=~+XXipo~mt2zzuYWY`EDF z9*J(>5#f)VCy(Il^gd62#1nW12N5ttfgjPkBTb2fbh`3!x#N1wOJkL;ort4*1eCF6 zzZS%Htc1@zeQ8IoTCO)tk4Ql|c|09=ST7+GGU5Dfm>#v;(7+YsB(^LSPwWr)PbT6| zh9A16AJozrL!uk{NGI$!Q4c=ztP-zJBICy0CrJ2&jO4Ogf94#?Odkwx1&;)(51gyi zgMsP;tCh#9o@AP4T<%kK^i1PgnvOMG~2(|v?Hz9Ym-NM-~_ z!tW1~KlRv=Wtd67wZJfB`bEsfry>+Vrbom@LD>@pkOKV$NmLKG%){^QK?EcNx*LC- zKYP=saZZ~ar*~1%9|EQ}iFMbcBYWXiAELN(e1=(&fD{~h~gUaZ^QWgUo>6gKmS+n9Tp5f+JJ+4~Kp(x_k zUAjBYAI2U3(;KwxPr{yU>!E=jMODH58W6=o-h(gI*1wD#*$3aPu_L?T?&S64iEZLg zNe^t}f&qTJfzLVZ&Lw24)k?+jDi~MDv0I;^>v}I%UbdrW%&~J153nHDso-z z`mPP5RGx}u1&?D&n2h#u$&*KRN&rMq;SHteQW>!a94MmT+K8-lVjG5c1^WBVZ#U`i zkG51LRo)ca2Wsf4m#ac08>rfw&OjSMZ&N6qt;HHz7WM@UU1;AcDJ;$k$|9)k4cl^E zz|CXYNQx`Xx2&~5?eFvqftefZ3gGe9IXUeL|1btC}Sh zychAgnkjAAljKyCgU(+^-$t{W*=>xA0wsimsty-}J#j7Z4HmJ*8Y`#@@mcKA#M>NznXCWtrOIxSPpE5bTWn^B<3*#?AUhKL6_s`K{9FjxVZw z2^-q5&Vpxy;P;KtqM0w(;sU3z%pg#}{WD~=NE>nuWlPa8wLq^LZV3)Ibk5fpCJmd^ zyx42t^-e^~^~N69azibPZs5SK8#=P?RqcInBS)UN!L~o!jkHb%;vD!?taz2t6&(DG zeXD1lmzg-jri~G{>G*hYwRBq$?HndgNeB-$Y$R+l?j&RcdF(SGsB5WR1ChW`Xc~AELF%!v zf8di^F`kth4v9c$nYjKeEQ7YL4aHdoc^RBwZ690=DafK)ru&HZAHiYQmc*pTTl;tz zI6if`e({&fU)V+ikQ~Y7JQz z5~yo*w>nsCcjHhfOsLy^sKpB)=mm{V?&nvoz9Su*#$wYyql+G9GW@i-p4~z@oWUl1 z)cij(W2cYEJ*Z+y{J+;Zml>LT7X%w?OLH+8tYK5CB@PY_(Qq<+BACs;-j08{UIZgm s)|6-1Y4VPJcz^!)5dZkV+D0L^pwur6>=v7h7tC}21HsX8nywfC0P6|yoB#j- diff --git a/man/jc.1.gz b/man/jc.1.gz index d860a611e53e602cfe3e64ecfcb42ecaff3b921e..3ceb719e859e2b709804f30494fa9c446a522498 100644 GIT binary patch literal 2068 zcmV+v2#@$#2no#>O`jrYc)jmQ_|}($*)zAi8F=(ex?+$-9stPNq^AW;db% ztCZ!us7c-`l^Mp1grzbQp{+|{NJ;c{HeW=OC>YPD)6wjb{TH2CjBcZ=TlU9%v7F3j z(Vsz}G$>okn3=k;{P`k4%e(K)O9!O$@+unNPUsV&{x9cP3Kj)7QfO9kZDg@#vS23G zvb1J^PVzVwK(kVoB7u*nHq|O;cj?Dyc{!Qgr3=#POo9b+g=tZ0VFXOWN>!jI=ogGV zNmUsZs~kK_{$d(et@0Y@pO&CbL-RwM&9FVQd4C@Hx?H2?!yndc&r+=5~F1~C!`x};%i@TwTF z)0wj3V)ub(k{gIB2Z2IaW~#DOXzty>t(jlRVDK?mK)8iA7s22*3gGK7J-gF|8m2R!-2-dx0j!yClQvP_~6=z4m^X62pFQkkHNbmO|gV>n)0H z1+g8G@Rg^p?8vm`dc*XH6jYNZvq^{b5;7qZ&fkXVQM(Nd96?TE%M$U#{(%2vEdFHp zp!~QMm;b)#z;`K>n+_>`u315(rTy^WuoFkd(gTblbkwEo#PdaUXxrn#yLH%Fqn!G*A}!5!SwJp#7;?$AK6u;;kMi^n$EXSm}#QoMv>MsOtj z`XKppj~!WtneJy`%H&>xUQ^?=Jf{O&G9Kr*1a@yGSE zw|pAswCQnrmj(SPU}_UvcT7667j8w~l5pG`g~IINP>z;1>@Nu|4dx{cM#Yc9zFkR` zzNDopq@{EFO^RfZs+JaHyTz=`T_z1HqlYV53~{7i25)9f#9KVW#jSc=wVK1Dh+B8) z?l`|0cl^(9(6ZkNd$z5I26_}#smpfweUtlD!F|k#Vj=Irmul;8QjY9{@7BbT-Eil7 zPhHu@4i)#nHZFPKw;TAJ)5?FD-n?EGYVJT^N5?35vt0#)1ws8g(!b+c@*HLP3f2#w zl&AD4c5mHxZ5WmQM64>fOjChnwC*b&KeAH-Ac7w1@N``%Blds;MU;#ik(Ewt!|-fD zf4}+VCLR8gm#DbPo5%Tq8oCaC&Eg8~mw3I+ls4>1a(cvr&fmu0#`Bx`ZG=IACx?VrAO?dyaV_!AHeky)BAMln z)JCba%Qt3V>uabb32a4;y@)5gZW(N=p!rl~ncCvGo5@8G?2P>5?~kI!#rj4*|MLv_ zt3z;ERhv{-=G8wyGU*y^*FNyyy3%H9Jr{HEj9^H%uN8Fi z8VOA80`7wCCFl_F8=17W;%};zTY|yPVe*uOa8tuV!Xo2JLPe0rJ`;kvoZ2-U2@DTY z19vDWJr>pvd{QanS-Ig*2!xig>*qokv~_JO&N8UW-~?;?;BrVo71c7?XT1Li4!brc z7Cqit$HT<&rOWk~zg+&xK5_`~ilIiUEEwnLDVc%DV+Dn|>P|^e~grr{(qh z7M{-;EW$_4|06SY`iR_vDpth*Yn^kMp~-hau(7r@7sKHi7NuI@;P4O)JHr=(`Qq#C yWtEkgwDn04#n)^)oLmJUc^5Lo$(0m_*^Owx zYQ=J1)Ff|}$_(R0%2qNHp{+|{NJ;#4I-AGiI2g?)li~D|{TH2?4{zhETlU9nz8KG@ z@t;AUG$>okgqgaq{P`k4%e(K)O9!O$@+uzPj_DJk{x9d)3M>k4q|mJ7+Q?$fWWh|L zWob=>PVyuXK(kVoB888rcBNI$?p7b;#pQTKZABWfS&4p`MoGyHssR|t$~+gTn#Ec{Ei{V506R zlJ1G>6w?YKVCe)My%%Ugyh}2y4rN<-wv~2+L8Y7hJJMjDP<9l5e%(q6u|o!s=$=Zt za==v&Os*YHuKR%619cBDm#Iip>K$#k9-;Da9cE4fNET*2c(=}J)eRE`t?51db^~$6 z35i4>v{(!6!ASPNweXsO=z*Fh_6EWx17h!A4~Df?Rk?=~+XXipo~mt2zzuYWY`EDF z9*J(>5#f)VCy(Il^gd62#1nW12N5ttfgjPkBTb2fbh`3!x#N1wOJkL;ort4*1eCF6 zzZS%Htc1@zeQ8IoTCO)tk4Ql|c|09=ST7+GGU5Dfm>#v;(7+YsB(^LSPwWr)PbT6| zh9A16AJozrL!uk{NGI$!Q4c=ztP-zJBICy0CrJ2&jO4Ogf94#?Odkwx1&;)(51gyi zgMsP;tCh#9o@AP4T<%kK^i1PgnvOMG~2(|v?Hz9Ym-NM-~_ z!tW1~KlRv=Wtd67wZJfB`bEsfry>+Vrbom@LD>@pkOKV$NmLKG%){^QK?EcNx*LC- zKYP=saZZ~ar*~1%9|EQ}iFMbcBYWXiAELN(e1=(&fD{~h~gUaZ^QWgUo>6gKmS+n9Tp5f+JJ+4~Kp(x_k zUAjBYAI2U3(;KwxPr{yU>!E=jMODH58W6=o-h(gI*1wD#*$3aPu_L?T?&S64iEZLg zNe^t}f&qTJfzLVZ&Lw24)k?+jDi~MDv0I;^>v}I%UbdrW%&~J153nHDso-z z`mPP5RGx}u1&?D&n2h#u$&*KRN&rMq;SHteQW>!a94MmT+K8-lVjG5c1^WBVZ#U`i zkG51LRo)ca2Wsf4m#ac08>rfw&OjSMZ&N6qt;HHz7WM@UU1;AcDJ;$k$|9)k4cl^E zz|CXYNQx`Xx2&~5?eFvqftefZ3gGe9IXUeL|1btC}Sh zychAgnkjAAljKyCgU(+^-$t{W*=>xA0wsimsty-}J#j7Z4HmJ*8Y`#@@mcKA#M>NznXCWtrOIxSPpE5bTWn^B<3*#?AUhKL6_s`K{9FjxVZw z2^-q5&Vpxy;P;KtqM0w(;sU3z%pg#}{WD~=NE>nuWlPa8wLq^LZV3)Ibk5fpCJmd^ zyx42t^-e^~^~N69azibPZs5SK8#=P?RqcInBS)UN!L~o!jkHb%;vD!?taz2t6&(DG zeXD1lmzg-jri~G{>G*hYwRBq$?HndgNeB-$Y$R+l?j&RcdF(SGsB5WR1ChW`Xc~AELF%!v zf8di^F`kth4v9c$nYjKeEQ7YL4aHdoc^RBwZ690=DafK)ru&HZAHiYQmc*pTTl;tz zI6if`e({&fU)V+ikQ~Y7JQz z5~yo*w>nsCcjHhfOsLy^sKpB)=mm{V?&nvoz9Su*#$wYyql+G9GW@i-p4~z@oWUl1 z)cij(W2cYEJ*Z+y{J+;Zml>LT7X%w?OLH+8tYK5CB@PY_(Qq<+BACs;-j08{UIZgm s)|6-1Y4VPJcz^!)5dZkV+D0L^pwur6>=v7h7tC}21HsX8nywfC0P6|yoB#j-