From a7b690f209be1d69865bdab28a392d421e91c089 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8F=91=E6=98=8E=E6=8E=A7?= <30631809+bilibilifmk@users.noreply.github.com> Date: Sat, 6 Jun 2020 02:46:35 +0800 Subject: [PATCH] v1.0.1 --- README.md | 97 ++++++++++ examples/demo/data/config.html | 1 + examples/demo/data/index.html | 179 +++++++++++++++++++ examples/demo/demo.ino | 56 ++++++ img/flash.jpg | Bin 0 -> 38104 bytes img/index.jpg | Bin 0 -> 101287 bytes img/ptlink.png | Bin 0 -> 35187 bytes img/wx1.jpg | Bin 0 -> 12570 bytes img/wx2.jpg | Bin 0 -> 11113 bytes img/wxxcx.jpg | Bin 0 -> 286605 bytes keywords.txt | 6 + library.properties | 9 + wifi_link_tool.h | 313 +++++++++++++++++++++++++++++++++ 13 files changed, 661 insertions(+) create mode 100644 README.md create mode 100644 examples/demo/data/config.html create mode 100644 examples/demo/data/index.html create mode 100644 examples/demo/demo.ino create mode 100644 img/flash.jpg create mode 100644 img/index.jpg create mode 100644 img/ptlink.png create mode 100644 img/wx1.jpg create mode 100644 img/wx2.jpg create mode 100644 img/wxxcx.jpg create mode 100644 keywords.txt create mode 100644 library.properties create mode 100644 wifi_link_tool.h diff --git a/README.md b/README.md new file mode 100644 index 0000000..02fdd9b --- /dev/null +++ b/README.md @@ -0,0 +1,97 @@ +# wifi_link_tool +这是一个为esp8266设计的通用配网库 +该库免费提供 使用请注明出处 允许毕业设计使用本库 +## 当前版本v1.0.1 开源协议:GPL3.0 +**** +# 配套视频:https://www.bilibili.com/video/BV1ye411x7Xr/ +![img](/img/index.jpg) +**** +## 普通配网流程 1.链接WiFi 2.自动弹出配网或打开浏览器访问6.6.6.6 3.输入WiFi密码 +## 微信小程序配网 使用微信扫描二维码 打开小程序 点击通用设备配网 输入WiFi密码 +**** +# 关于配网操作 +* 默认情况下 下拉gpio0(nodemcu D3可以按flash按键)5秒 重置已有配网 第一次使用该库请重置一次或用官方工具擦除flash +* 默认情况下 状态指示灯gpio02(nodemcu D4) 也就是12f的板载led +* 指示灯常亮 未链接网络 处于未配置 或 无法链接网络 +* 指示灯闪烁 正在抹除配置 +* 指示灯熄灭 联网正常 + +# 微信小程序配网 +## 使用微信扫一扫进行加载小程序 + +![image](/img/wxxcx.jpg) + +## 小程页面 +![image](/img/wx1.jpg) +![image](/img/wx2.jpg) +点击通用设备配网 即可弹出配网 如未弹出请检查文件系统是否上传成功! +点击设备列表可搜索局域网中可被搜索的设备 + +# 普通配网 +## 扫描二维码直接链接或手动链接 SSID:wifi_link_tool +### 该二维码支持国内大部分手机相机 (例如使用miui相机) +![image](/img/ptlink.png) +链接成功后 会弹出配网web 如为弹出 请检查设备支持性(安卓4.4.4以上大部分支持 ios 11+)和文件系统是否上传成功! + +# 安装库wif link tool 库 +## 安装库本身 +* 请保证已经安装了 arduino esp8266 sdk (已在V2.5.0测试) +* 在github上下载本库 +* 打开arduino 项目—>加载库—>添加.zip库 —>选择刚才下载的zip导入 (手动库安装目录Arduino\libraries\WiFi_link_tool) + +## 安装文件系统 +* 下载文件系统上传工具 [工具地址](https://github.com/esp8266/arduino-esp8266fs-plugin/releases) +* 导入工具参考目录 ******/tools/ESP8266FS/tool/esp8266fs.jar +* 重启arduino + +## 测试库 +* 打开测试demo 文件—>示例—>wifi_link_tool—>demo +* 选择串口及波特率 +* 选择合适的flash size +![image](/img/flash.jpj) +* 点击验证 验证库是否能正常编译 +* 检查文件系统上传工具 工具下会显示 ESP8266 sketch Data Upload 证明安装成功 +* 上传文件系统 工具 —>ESP8266 sketch Data Upload + +# 库基础配置及api +* 配置设备 +在setup中配置设备io名称 + rstb=D3; + //重置io + stateled=D4; + //指示灯io + Hostname = "ESP8266"; + //设备名称 允许中文名称 不建议太长 + wxscan=true; + //是否被小程序发现设备 开启意味该设备具有后台 true开启 false关闭 +* load()函数 加载启动等 必须存在 + +* pant()函数 维持系统正常运行 请保证在loop 函数的第一行 保证系统稳定性 + +* 局域网中获得设备名称API(用来配合网关或设备通信) +该api以集成进库中 +作用 获得设备设备名称 方便设备联动 +请求方法 http get 返回类型 String +地址 http://x.x.x.x/opera?opera=sb + +* 自定义http get请求 +语法: webServer.on("/<请求地址>", <处理函数>); +请写在setup函数中 load函数之后 +处理函数请自定义一个新函数 +请参考demo中get请求处理 + +* 自定义添加web +默认情况 库自动添加 config.html(配网web) index.html(设备主页) +将自定义的html 放入Data目录下(将demo另存为 在另存目录就会出现data目录) +语法: webServer.on("/<请求地址>", <加载函数>); +请写在setup函数中 load函数之后 +加载函数 语法 void <加载函数>(){File file = SPIFFS.open("/<自定义html文件名>", "r"); webServer.streamFile(file, "text/html");file.close(); } +请参考demo中加载多个web + + + + + + +## 测试环境 sdk版本:2.5.0 arduino版本1.8.8 + diff --git a/examples/demo/data/config.html b/examples/demo/data/config.html new file mode 100644 index 0000000..07a6423 --- /dev/null +++ b/examples/demo/data/config.html @@ -0,0 +1 @@ +
正在连接
Nb7x`Z!Eqn^v9ng6W8g)YnJ_R`R+IIF*+7q63YYD!awUaQ5MPhtjd_Z z+Z9>3BFUe61zA3XtPig7w*(n}OArPU7776M&k+m+BnBoHyE>E@IynWKxEhCTRN4Wxr5U0pPX1;An)$aMtP9T zeZ)fFG<`XJx8s8s=WbG@777Vn4v$VQ|NS(3StpGvvx~-_$xUHUy?Xbrq<9zk7A7xr zBDFo0JfR#|CXFk#JdxV&;vugZI#eIAI;_U5CYuq2Sf#CmqxL6N9oB-AQWt5(M4^v3 zp(FA8C5$5oRCj4Qh^6kAc5Vf_%qU1pZ&9quQYSw2#LICiy=;3=cl%)u%6Yba&o^s| zb>48FXKV8V2DhJ!*L$kh+)%>20@s*n;G2h_GlTd=1sXDNdW(j)g36@42YcF!Gp2CG zZc(W-*R{Y)+h(&_zx0PKyidQoQw|*f0R;&O0}l@k4FwPR+NZA*0s{(@f*p&JLtGtN z%-lURwWJxHoQji6Lc>FCaPc!Xn?+h!%O16)re%8R&=(+B%JbmwqbyiaNNV=^aoVA( zUw}P_;WGbVEmMkwY0SN!x^!`ia0HkE@)>#_o(btt@T@3fl43 <&Ov4<8MM5UB~_yvUKFtx@khA!~Uu~IO1OVAZwp72^wrL z*d >?_6f*A=kE0@}U z?hy?{%-aSk-a1!kRsC=Veh+0>VZcQ)Fs|Du!nq<|BRg~QyZ2i>X1*u5ZV%q)*v CxC*c>MqIz^7+BhNo8Ew!ZXD8;B71qfw5MN@%XS+oGEAhO( z7;3i``RzT`D5qn$Tt^)E7aHG7%z>=-)RL(s6`MKhY(E Mo`@No@t3JzJCN<`|y zts{Nrf2a&@_R!ho;J1CDhmb`|{$BJ8P;_36hyo0%TAmquDB;e>-?wgB9}>V~gl);D zJ)1@$j|739D$Dtz_kNl+10S)tNw)ET=f63x=T8t;5;I^Miwa~9`(_||H`Jc7zB)62 z02(`Y+Dl_;ZgQhU@5nQBQR9#i8;1hF$4!1=i)^!xSBh~_V0N-jV_j@fvB5t5C}hs7 z-qV%9aWe125~jHh#5kH!-3oY7a0c33rwFYkX3P}iyiRAj^iG1w!$Zq6iL$d)>X_`9 z? e*s3epNk)I>{WbM0I6GQE3B++gxlwN%q)FaNvEprl{Jf@ z`SZ}?@gLh@4^NJX2H{Zl1K(6Y^I`f8)xOU9KSZr7h7B=SyY|SI;>bT~M|KP3jXzB# z?`5x9h%Mk9`>`R(N;gq_Vkl?d<0$a22st$23yj};L@WAGAmK_^Eg^>cPOdFdyzy|C z`<)S6n6?ZYe-h0J{FuCW0}c~95Sn|qmPYnlmI)wWn*@Vl){8AL4^T*+X)+~|?Y80% z7}T+^dVFUL7&7CJN><^Y{HpCQ)E)ahxoGdCuBJfw_L%NkB&dwVi(OPJ$cmQzrrahd z=NEweR@wJRTk12)3+{5ycwSkkbVbH}vz`AH`&O=J$NnDI1ZND 7acJONXXvTD zBw 3#{n$)7Myu?j{XNr!Zr(_mRri-4#zf;2NzUp6-`{3^0 (VfC|Wwdz&G~HPlZEtgIZOevM!%-K5vW6_BOoiS1 z3v@h-~>h7c_3P9 z?^Zg_l}6t6Z4aC`<$%i<{@#|=1D^>6eZnx=uYwz5ae}aVxsdRTl|1W+aSB)Sv=#M8 zX}gIe1mALyzej0(^=MF=x_$ZF2E3x4;7Djnxw}KJ-Fw&}-~-akX>S$@U)5FtJpoCV zPQLkGFqT8Qxu$vZC5sIlq~R0m$UYTR&M%j9MYf7^1s|@+_h{Himwf#N$hlPlb_-Lg zST!*+TUPTx)kEKXmVsT}p!imFHOO@ew2LWSzZGH29_OxK4XkJ5J!+A#3rbeJYn!}5 z`SCQUbVMlIQyclwZKp~Ls=9rJ5i0Q);Iu{rfp>kgP;%3u z&tFy+c}2G+LwGrd<7y-y$L4(=kxIT;WrF!~ZK}V~!c9s$Z!Oqw%BN>Nd>2R34Ue9s z@Mh7_JNTiNbv_uzdgEqq@yGBZnW%;(_Ueg?M(O#d`+QL@LdF$ pkTaQ{^n|whr`<6F(e?fN()QYXV?i2o*tm!dt7z;`12`Hx(;~9@}=wN>o@ZMZ o?f%NFJH8|Y?`ZxKT tC>Bu6ovK >$B=HV^zaBzhe-JZ5a|`VFR%z rB z!g~@?_wmL!>-u%{75|1FD(ypG+Vjy;nDS245tuI64LsshppA-ER}nWbG>v>Xrtm%E ziIct)_vm}Mcxc?HaWUzp1HtJ@;nR+#_=dchc>{_t>d7(R<_pG3&452zsM;yMHPY)U z0i-EkH?~95iJxKW(}tfOW)~>a*2} 8Fa?Kfh?xMRy#CSFG_^^WOu2xwjAr?Ij+eI G+!Xa&1dd zk Q3;eBO5u$f+5T>OMMpci(uQ1V$5;SaJI2)au#t`A$Wv?8N_%w!mxdeo-lgY_ z$d1(^ND0UYFWLn4#h}|;Be8=hhphAryXw6DHi);#pS3nOSGz}#4^Z;`WDg_#kITB* zfcAT+A`WGdey$r~C=0e#^sKBxs$b{zwFUn&5VyIv+ X9ZPrf7`RyfwlKi zIjenndo28_)9^m64+Ug~X!U~9qYuk5-SQ!ndEvcf<4|1b%Z=W`MN$taKP0YB6E9*? zyWHWbG>w!1!>z_>kn*9kG1Wll326LW`3kIEVl(rl$0_1FSh-V)z`SfYnz~(qDR*lJ z7nGT3tF~MR??7F%@LX{?N}LwfIjs7cVVh+^YENywZ*yx3%&2(CBZu*lp+F$kyW$qF zC>k!THZulyfM+c$9?8;=ou%WN2VWr8tJ+d8X)gqy00`H|Nz0#(xK(Q3@)AGers!~; zraJQjXU4y^7!|BILtC5(nz|o!YnGm0XC)Xo$0SuNzdM7 +K? zr3ZIzOn;topM+e4Yj59cexRzTR-R?yZ8>APOc2yYoF`piv)uSGl>%SE2Q}_@CF0O% z`;PreB&cG6bxM7}GE}N1&%ihzd8ITRkQ4v5cu~2d6P@bKadg1&Q)I)$>pf`OQ%!%N z(a6jA{Iau<^+4g_XAw;pO^l9<0AZF2g0>#*u)G}$<=%b;<-}G}ggL>8;s^Drr+jD^ zrNyN{#XRpi>&-f6-Vf)L+}a&I8*QTQjB-FCdpBT YN #BluRLh|jA^3k5PtAMs#_9+uC7|C%%Kp~C0Ny#~v zkBE~kcZ~fw=OZ&^fTqEmY@-wV=KJ}_g(B<*|9s+2Fn6$9o>)^<`_ZQS{3Ao#H1pyT zOPY5acahT4N(Tb*(Y ~5!V?R+x7ys0jyw(V~#LF#F&sF{24xv3I>vu5mA@z zdIDD%QD#w^K-tk&zT9jXGcHQjy}||`RBwq>+S!OcV|`x$);+|esD_VOQO#Qy XpK`43)s%ZM=*`;leuF6cEf!u E9vR1H>wFg#PlA{JOz zr;afgR|S+*6iOD`mQZN=X$00ZYP=+kX3A?a&JBU6&KQiX4x0;LXJH6aoiP-au4^ZS zD#G1oXGeDs>&QIxxQ9ECmc%W|?HI#x?3ya>?;$Db{`H >HB*PAFE1buGlUKPuGL_o19NDnpcae%KW}kPQ=p?{+X4=n? zf7`oyqjiS2yJ?+64*p)V#SA1sFBaU03Lzq(TjJ-FU=36+4 j1P1HGdvmjMGntzKD<<=-meI>M+$s7n z|ErG*s~sOq)6UU< SG&o)06PXtU&qG^RkY8*$M#VnVhjG9Y>P zTn{s@n7K`?R-J==GN|^Dya_nStvca5J>IFq(b)G2aU;fF;fAu(+x7B`Tj6#A6M>wQ zX(mq;o={WP2EVG}uCQY?h78x^3a=RIC0MVMrc~?nB^nvd)=Y XF1d!;yB**xkK76en>u^FH?dkYhKn(xXHsE%%|2TK#yeu5_*##QjP~fr zO_ f;K#rn%3#Na`sM#g!6zSK0a+2Y;$PX2I7((ySHIR2Uy_WK>mjO??qS# z$dH?iXE!<-r2CgX4B(qiJKI5|e5q{A%jGNpUs`>8r!8iK8E9`rqB{|E`~_ivP^#6D z83U+{$7LhMLck^YGyhcwfQPXhZzZPQsi<8pR*e($;{3!qIt|Sz64eN=5w1hOG_nly zKOJV!s%>+FLcZPa=B&Am;&j~%?`@#a 7fQb~s#U#=j~&*!p7hXNK4KjqnT7PBoxTg5-HgecJembf1TBg! z4P_d1nHM&m*L>3J9-^6TYi~W;%yrOlsqg_KyCoG@Uz`~*If$MwGu*t-+rpOzA!ij< zNxoEmi^`?-7-mIWg(p7l;~r4CyTaW$yyD)*vx&2bjhy2%$A4Ro0D9p47Bi9r!@eTJ z<-lFwlCOFbSIkS8{fK>G@Y|FNX$vq x4xJ{26dQC&5oo1wSSLS{{nfL@QFaoU z^PIcL`GVko7I!FY&`(vKwQmGdl>g}VBi(`F^DO(lOiIMwc@zX%e$}AH2!&(IQQ-+4 z2cP8U(m;)am1LS--IdE=jXyjthjU>!rwLd80-RUJ)vpE-c7@It*-xX1DyHLRkyt-i zA1qf#%X5?1MbfIU0d~Skl&_$NjXY=wOC@E1-H7$jQ1^7A(rRoxyZbz0?tuac BQzFBrHU95YF$3 zpDPxV(G=71$D>p{XrvY4myAOasOlXraE0q_M9KMoeq(&|Wbop$kF!#xHIT>dTz@vJ z;Uq~+*;I(Q2G1)vt7Xa1pD_*JJO{0MSLrBFp#fNp)TwP4i8nvy*sb^C?H_UEls}5Y z{^XgPxEP)42|p(cb#?b@kbeQl2{YFBIl7dBkgrRgo{iUYeyq(MAS@)m9%{)LomN`L zewOaEASU!%AwuDK7mdY|->Z|8_`1Mh^d61OmBkw59~~{p)8&d$^-kF& P|WCQ02A%>K<9`LX|oh_y5BKJ2KG2u0mmC1M7e>* zE(FtajjVgsz~&f}170%6Xq*8Z>%-vdku|as%KGzTu8Ig+9JuBEb89f@% z*j ~CsduEt=0!iyB+?W6QNR5(_n6Dk*5EDih|@(D_uLqUax|Fl{lt1O)& z#g=I6Q>neA=DxF 7uf6uMqHMbHUe%E? zR0Xual0FQh*JCvPqolP5{e$y*k8j==TK94A^{8@V_B^D-;PvCXeR&m#r)AV>a^xY< z@xIu^y|qt>@R>vS8AZOg|U?!%~5>*8~Xa9G-4s0+Lmt#B6nuCw%^ z{eKW?qVTu5BbGVvouLx=LHWqtGidd0 SP?@>U&>>g8xDlX4%FwGg-}IcNKBw1d*D*VtZzC5fg$eBbZKXs2-x} z8<$*E8Bp_nU~6KqHQ|9(<=GkZsQ07Byf=W+s91Ow_dvC18RQin *{L%@hZkKcxwIE`W z4#DT2q4E)MqXkgU2DKjEiBGL}!e|s@&~%b6KmW)X*pLT5>eb z3&a;-()4fm)Fe0uvMmUFfl?c4(gID8b0>K(oG17%xf~JhcM%e^;k~WoFGXrS(I&@G zaDz*_`$3s*+cx$0i9(}!_UR9*zZe^Ddrq(eJ$8T0Bg=(_KNTsiq8H*yfpEv4OcIGN zb%*ME#$SVKu!O#_*YY wus)r6+neVFE61CO44Dqg J1=g zX=cN5&re9BHL(@%V;w^=lCgJ>;YI ~^H#_u)A8?buIXWo11|$Z!k7}csIU-dQdjX?Yyj_Oi zVE)=ZSb%{-19)7RTjkdCJFD-ZKdS;0^7-S1WelxcbH)c@`@?vL$)aDX8-;4B3L!p} zT9Q6h*?PNanwLp`#bzSGFL&=?Pip_6#3_qscVHl}RE^(yD9p~-9e}75wloqn1k6$H z5xZp(5`_T5w;#O47}dH^`F%fU9mYv_r?oStF>nwefxM(X{8L{v*LnpO%MD6Y%qD}7 zio%9{NGDwNk|W-$ETX38;a!S2lnq8s2O$7DCgK|~aV}q8G^Bf@dn4`7JyfuO>@K&! zQg tE9j)cIqU~EaqUJKiaF9PZy|1(^ zQ*U)7WmtY+J%N{NR$CAjW6ow@6w^{3zr=JvlXAvYFuT9~1!%eT$Zz=t*fg)&CBCxt zm%|eE*M@|sZjgVqtKUHdIHgNTNur-!ce(Y;vW2w2V9of7t_v&Xk8Puq;71S>UyRT9 z-7y=mrn$CZR=1aF=XDh_%%xLHpj4SWgtI`8yd@uBsWO|{qZbl>e9_F_t!Uqwq0&MX zW&}Ut$@AXK>3l38u%hY_g=k!jW ^X+}uB!9jtzp|CSgmwQ}$w x0rjb3@g-wa)vn1#tZ(| zx4IXS*|)(>e&KSo?1+V|%fA4<^|**DgkX7cS%TfDw0d2s1F!dL;YVLN+oROe9PugY z2Uw^br4+n4W@U+D3eFl54AY=_DdooF_^>G1-T6G-?gR|mB$M@Y4HMVA4 vU0gkX1XIZlO-bISSZxUYX{l-?||KOZ$>vVit;#W$y6LTdb~dhe8Yul5)F z9%$Q4>ob zAtM)`N~Q26o*IfIRuEBYy{irjQo5w-Y~<3oUoCN3dR>}p>5#wI8qH$@Z=f0n8yk(} z`tGLBz7n$N6Jn`8ihbzK4yrH|HPog!zQsjlse}(uzdHcg+Jle{ zB0%!p2><`yfG`ue>sakr^!57-CiK@IfS@3uVP8Kn`s+7w2n+xPySTc!d+Hal(30lG z&* k9He0j~0r=%7eL+`A9b!IQhlYBS1S}=snKH|H%jY zLpw95u5^)k7bO`Ie?WZg?gPBdvSF;>GR9~(BAJ#BG^dvv($Gp(6?EiM{9}~>d{=D| z%mX{O3m$cs+M}9T%gWgKdM`$t1Y8rQfzRhJ@X}%R P|v)j+bdnoQ8 zQ|$&;5#r%XeM_TD-_s0)WQO+6-)T@{f->7OB>i(!`#|Ani7d$&Gjl#Tg|(EB0DL+c z>@rrx65rM!98BDsnGj5?-GwlaCVWcRIP(*jLiyCF01o+EL>jSHIZJ)3W2sOLb2=_2 zd*1O1?1_A?KEJZ%NDXvO96Z!Wm&Gup$S=STq$DiKyMnkz?EzPm{mjq}48|6u(0XPp z&W$tkQYZRdOnt{0DO*7ums~3WJ!6cy($H!bnRw(I5@z`{c~u_)vi*bntJ>EKXHvL@ zUw~jmXazugL}oCzsHML>wt|%o=H)I7>=CVtOK-iBQ-zyblbWuG#mcg)3cA&s+TbsN zGX3v5L+?aCEyDX|)zc$O5pz1IL8vp$BA6qzrOhxKa%GgnFm5`3$V9DvRWmu&F}i82 zG=1k{5#-?LnL2_h#(0!TEc3Yjc-H1#d_J&OsT)S3&%#e;@!fW1d5MXEjWL3&gZ_W0 zETj^o<8Rv;^3giTT% DVB8$bCbP;O(1`g pjhw{X?5t)!Dp-2!-Wh4S_Re^@w-r3!mi~nn|iSNAd8(pEsIk!S5%=6 zOq=EedWGuAAkK6-D=!hU>1QTcg?a&+1}O=gUz9*sz_d1@E$2HRw*Xe#M_ z+47%A_QOJnOk8Yn!ib~jS0%9(vg;T!ZN$hKvB#ENiDIW00>y_q5$Tiqq_z3fOAUT| z-ZFSjd=CSkkl>p4;}@WQv{p77VM!qk)`I05;n=QClz3Z*!)FtDmh_)-njhZ3evw#V zr 8b5 ppgI2D`!lpTgb*3OiT6)_^!(z$P~PWEF`sjQJKWL`9ONLmm~D zT>Ok&$LM5LnA-9oYM{g8i7iG5@=9vR8luHnu0kziu&80YveYz|Uk-0E#*QcBF3T^# zU5#YqV{+~CnXlXTenP|H=ohr=?PtAFNZ2>(w}-W<&kNy>u2K?Z1m2R!#~vs8eA+2h z@Cajwi-tJxR5{XIp%SiHM(@26lkhG{X-(&-Z-QG2l&c+EG542YLC~F(kHxDs(i_Jn zWdjflUYtE+21wKr`qYob>(Iv0(^zAm%^_gzP8u^Q%#>14&|jjrh@8KEq1o2Bu70c4 zTVuS!dj8H!v8Uqyvkcw820b;P`Q_8eiwjGj%qJ)~hKwTKJEzff`UBH58GI`dFZ|Zh z2mM_B9?3+8i`ld1BZ+6|D KY)3g?msOV`UR`Isp3Ckrxnb*bk&;*hY zY*V*XnI`xH(DU$nxv{D#YMe<>?+EQBVvM*Lcv?qnC;L_S>`TXx=F(+$<+6~%O^8AD zn57vU3g~g%GguIF;lqJ{aUlfqYJGQ>hCzuniY g#sOA=G^PZ@Ei!CM0WO&^ z%n #jF5)(Un9xIEJM(cw)9FqUj0unKnT6WJ{`}f2G-caWtEcDDA z9~On2VrDy;MJ}a~(Wb8MH2!68<^mKf&l&gfyEh1|x3`}^8OEEccmCFgOW`x`63=(` zhv1E*Wki~pJ?y@rcw@5T9Vi--=dcoi#VS*K34S=Uf)z0g M }JncTETmf#7bz-7O)y56RAc-}k%cJm2}}-sihL{dCt_C0*TBt7^^a zRljE83Q>rD;#kehR*!F$l$HG58f;A(CxL$I=6E9TYXJNzf#sRs>$g}>r?wcd7{l(v z)Dae=X?>=^?WbvukT$<=EzZIUAo0ZLngddYSdqVpu8{(eeGJe-IW;lAWb*ce5p6|} z*AiRDX;yAp8UTqZoNqqGNa9M3f|cmGhh*{k{K{>_YY5#v#qEZ?HJ)|29xbE>Z 0l~ySQ%O!Kj3FS&*DM-IELP< zN8BC!+NUIgMn~5I*OVw$n-%IFyTBPpLE!G%XQl_v_+*dckN5#;tFg>Z;nVtCz+Zr_ z59~j(xi~&<{u)nj(&03@YJuo|5s1noBViMtyL$4mgVV|;e%8-r9UF}(9f;_1&vquH zfAFlcEcKvZ{r`-)qn4g?=@leFg~+VtG9q~7-g0_w!{mc0 6ESVDj0LN-LBHBBY4FczVHtXNJe zsO(;Fjbr>c90CI%w20hi^WZ#-{%@G#&;=>QsB6)DPR5^|J)d>wwtr8R= TdP#V6HAh#ftj5dWLAnh_4I%J$Bp~9n5vPO8)V_d>`!PdHGmBl-w34 zJ}Ejzw6lAMKL6~hmx*)0VA?BV7AcE8VBlENKq9Vpa)^^SdsRrRNVrN>c~KA%CdU+x zvUz~qS)%fagmeY|X8osDPaMYfsQIz(=gCV4X;ZUCSX?b5TH*s)v^(}^9BK7UZbl-; z*_IV&<;s$l*I`4`mPjq1L@Ui`r@XkOGGl_W{1--rs35KZn%_A!bO!(h?=bC?`m(w5 zsd4c96 %K-})4`s>p6 *%4lqpJzW1sq3@S$Mxac-e3DP&*>0Y5qY)7p>9mi!kC5%XI) zEy44xm#sM~c(M712UvpfNk6B1TXWmvO12x>->IzSX+=G~37d@z6)3tbh=3Kok}k%% zHVc0flb}b7#J(@iP?MJ<&7m@xknDgNsRrGr&TE7r*pc9ZBABQoQ767ju_y|m>i=%B z?;&uOqZf699PcZFuGuv|E$3nnnq`!38M5@MLlsjTbSy}k*RCIHrXW-t0_o)P(psjC zQX_W3b5gOF9frMD4_WdQtaxGUJzg=U=TuQAC gLSm0H?0lUmN5`p z_&5rFJYmssZew8K!eH}$u7nytag-S{j>cJ8ih`?X(vH>{jDybnljRDKW^K!WPc7Do zDd&K0Z9n|zd6q-zruo%;#S2`6109$mok0w1h@|UQFAcA9dEtfDM}+q#drq&|=5%&i z{mr{?rdr+i wK6U#z N?uY2FYYvNC7