From 4ace989d53dc6c9e497315a031b823e04b232623 Mon Sep 17 00:00:00 2001 From: Martin Ger Date: Mon, 2 Oct 2017 10:34:59 +0200 Subject: [PATCH] added http client support --- Makefile | 2 +- README.md | 3 +- SCRIPTING.md | 44 +++- firmware/0x00000.bin | Bin 40240 -> 40864 bytes firmware/0x10000.bin | Bin 237156 -> 240564 bytes httpclient/httpclient.c | 525 ++++++++++++++++++++++++++++++++++++++++ httpclient/httpclient.h | 53 ++++ scripts/script.http | 16 ++ user/lang.c | 119 ++++++++- user/lang.h | 5 +- user/user_config.h | 14 +- user/user_main.c | 8 +- 12 files changed, 764 insertions(+), 25 deletions(-) create mode 100644 httpclient/httpclient.c create mode 100644 httpclient/httpclient.h create mode 100644 scripts/script.http diff --git a/Makefile b/Makefile index 7dc7a38..b4edfba 100644 --- a/Makefile +++ b/Makefile @@ -33,7 +33,7 @@ ESPPORT ?= /dev/ttyUSB0 TARGET = app # which modules (subdirectories) of the project to include in compiling -MODULES = driver user mqtt ntp easygpio pwm +MODULES = driver user mqtt ntp easygpio pwm httpclient #EXTRA_INCDIR = $(BUILD_AREA)/esp-open-sdk/esp-open-lwip/include include EXTRA_INCDIR = include diff --git a/README.md b/README.md index 8488cd0..7480aba 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,7 @@ By default the "remote" MQTT client is disabled. It can be enabled by setting th - publish [local|remote] [topic] [data]: this publishes a topic (mainly for testing) # Scripting -The esp_uMQTT_broker comes with a build-in scripting engine. A script enables the ESP not just to act as a passive broker but to react on events (publications and timing events), to send out its own items and handle local I/O. Details on syntax and semantics of the scripting language can be found here: https://github.com/martin-ger/esp_mqtt/blob/master/SCRIPTING.md . Examples of scripts are in the "scripts" directory +The esp_uMQTT_broker comes with a build-in scripting engine. A script enables the ESP not just to act as a passive broker but to react on events (publications and timing events), to send out its own items and handle local I/O. Details on syntax and semantics of the scripting language can be found here: https://github.com/martin-ger/esp_mqtt/blob/master/SCRIPTING.md . Examples of scripts are in the "scripts" directory. The script specific CLI commands are: @@ -231,4 +231,5 @@ The *MqttConnectCallback* function does a similar check for the connection, but - eadf for esp8266_easygpio (https://github.com/eadf/esp8266_easygpio ) - Stefan Brüns for ESP8266_new_pwm (https://github.com/StefanBruens/ESP8266_new_pwm ) - Ian Craggs for mqtt_topic +- Martin d'Allens for esphttpclient - many others contributing to open software (for the ESP8266) diff --git a/SCRIPTING.md b/SCRIPTING.md index fe47ff0..b39703a 100644 --- a/SCRIPTING.md +++ b/SCRIPTING.md @@ -2,10 +2,12 @@ The scripting language of the esp_uMQTT_broker is stricly event based. It mainly consists of "on _event_ do _action_" clauses. An event can be: - the reception of an MQTT item, -- the sucessful connection to an external MQTT broker, +- the sucessful connection to an external MQTT broker, +- the sucessful connect to the WiFi network - an expiring timer, - a predefined time-of-day, -- a GPIO interrupt, and +- a GPIO interrupt, +- an HTTP response, and - the initialization of the system. An action can be a sequence of: @@ -27,17 +29,20 @@ In general, scripts conform to the following BNF: ::= init | + wificonnect | mqttconnect | timer | clock | gpio_interrupt (pullup|nopullup) | - topic (local|remote) + topic (local|remote) | + http_response ::= publish (local|remote) [retained] | subscribe (local|remote) | unsubscribe (local|remote) | settimer | setvar ($[any ASCII]* | @) = | + http_get | gpio_pinmode (input|output) [pullup] | gpio_out | gpio_pwm | @@ -46,12 +51,13 @@ In general, scripts conform to the following BNF: system | - ::= | () | not () + ::= | | () | not () := '=' | '>' | gte | str_ge | str_gte | '+' | '-' | '*' | '|' | div := | | # | $[any ASCII]* | @ | - gpio_in() | $this_item | $this_data | $this_gpio | $timestamp | $weekday + gpio_in() | $this_item | $this_data | $this_gpio | + $this_http_code | $this_http_body | $timestamp | $weekday := "[any ASCII]*" | [any ASCII]* @@ -77,6 +83,11 @@ init ``` This event happens once after restart of the script. All "config" parameters are applied, but typically WiFi is not yet up and no external nodes are connected. This is typically the clause where the initalization of variables and timers as well as subscriptions to topics on the local broker take place. +``` +wificonnect +``` +This event happens each time, the esp_uMQTT_broker (re-)connects as client to the WiFi and has received an IP address. + ``` mqttconnect ``` @@ -102,6 +113,11 @@ gpio_interrupt (pullup|nopullup) ``` This event happens when the GPIO pin with the given number generates an interrupt. An interrupt happens on each state change, i.e. a 0-1-0 sequence will cause two events. Use the special variable _$this_gpio_ to access the actual state of the pin. This variable is only defined inside the "on topic" clause. The interrupt mechanism uses a 50ms delay for debouncing the input. This means this event is suitable for switches, not for high-frequency signals. The "pullup" or "nopullup" defines whether the input pin is free floating or internally pulled to high level. +``` +http_response +``` +This event happens when an HTTP-request has been sent with "http_get" and a response arrives. The actual body of the response can be accessed in the actions via the special variable _$this_http_body_, the HTTP return code via the special variable _$this_http_code_. These variables are only defined inside the "on http_response" clause. + # Action ``` publish (local|remote) [retained] @@ -128,6 +144,11 @@ Currently the interpreter is configured for a maximum of 10 variables, with a si Flash variables can also be used for storing config parameters or handing them over from the CLI to a script. They can be set with the "set @[num] _value_" on the CLI and the written values can then be picked up by a script to read e.g. config parameters like DNS names, IPs, node IDs or username/password. +``` +http_get +``` +Sends an HTTP request to the URL given in the expression. + ``` gpio_pinmode (input|output) [pullup] ``` @@ -146,7 +167,7 @@ Defines the GPIO pin num as PWM output and sets the PWM duty cycle to the given ``` system ``` -Executes the given expression as if it has been issued on the CLI. Useful e.g. for cnditional "save", "lock" or "set" commands. +Executes the given expression as if it has been issued on the CLI. Useful e.g. for "save", "lock" or "reset" commands. ``` print | @@ -180,9 +201,13 @@ gpio_in() Reads the current boolean input value of the given GPIO pin. This pin has to be defined as input before using the "gpio_pinmode" action. ``` -$this_item | $this_data | $this_gpio | $timestamp | $weekday +$this_item | $this_data | $this_gpio | $timestamp | $weekday | $this_http_body | $this_http_code ``` -Special variables: $this_topic and $this_data are only defined in "on topic" clauses and contain the current topic and its data. $this_gpio contains the state of the GPIO in an "on gpio_interrupt" clause and $timestamp contains the current time of day in "hh:mm:ss" format. If no NTP sync happened the time will be reported as "99:99:99". The variable "$weekday" returns the day of week as three letters ("Mon","Tue",...). +Special variables: +$this_topic and $this_data are only defined in "on topic" clauses and contain the current topic and its data. +$this_gpio contains the state of the GPIO in an "on gpio_interrupt" clause. +$timestamp contains the current time of day in "hh:mm:ss" format. If no NTP sync happened the time will be reported as "99:99:99". $weekday returns the day of week as three letters ("Mon","Tue",...). +$this_http_body and $this_http_code are only defined inside the "on http_response" clause and contain the body of an HTTP response and the HTTP return code. # Operators Operators are used to combine values and expressions. @@ -202,6 +227,9 @@ These operators are the arithmetical operations. CAUTION: arithmetical preceeden ``` This operator concatenates the left and the right operator as strings. Useful e.g. in "print" actions or when putting together MQTT topics. +# Comments +Comments start with a ’%' anywhere in a line and reach until the end of this line. + # Sample Here is a demo of a script to give you an idea of the power of the scripting feature. This script controls a Sonoff switch module. It connects to a remote MQTT broker and in parallel offers locally its own. The device has a number stored in the variable $device_number. On both brokers it subscribes to a topic named '/martinshome/switch/($device_number)/command', where it receives commands, and it publishes the topic '/martinshome/switch/($device_number)/status' with the current state of the switch relay. It understands the commands 'on','off', 'toggle', and 'blink'. Blinking is realized via a timer event. Local status is stored in the two variables $relay_status and $blink (blinking on/off). The 'on gpio_interrupt' clause reacts on pressing the pushbutton of the Sonoff and simply toggles the switch (and stops blinking). The last two 'on clock' clauses implement a daily on and off period: diff --git a/firmware/0x00000.bin b/firmware/0x00000.bin index 9cc7476a5dce6ae991396b41c65cd274f9d4f8fa..621548a0fa6a7051e04660ef90d9889187d3cd1e 100644 GIT binary patch delta 6299 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 L2fk6^VjTT9sa9%$ diff --git a/firmware/0x10000.bin b/firmware/0x10000.bin index 26f874d840fa31b73a6e1dc808ac201ea8cc9ce7..2d6f031e8dab7c4d73b398050b805085a7dfe29e 100644 GIT binary patch delta 57688 zcmagG4O~=37chQjcJBguclmTxK;3&m*cDc|t0tQ0?#3b-q+k-77E4B2luA}s)*`xu zieHRnAJ&6pW`+5ISx=b)vg=2nNPee({W_x=6;{yf~7xpU5( zIdkUBnKN_u@;=p`GpgWOD?JnD0QlbpX!lIGus&FWvj(mo5tr*I3gfRyf^garF4%_# z>N$3AsHG|-nd7fWmSd3|7B5Sj9Q`5HFbo%huF$7tX%OoPs=X-L-we}pj&0G0gDt8s ze-u(1q-YM5_Fne>$CXbF_AHYaDFnjIHF?oY<_Y?zCOfy)sv@qK0hXa3t>+V zav~TEp@OmhJScxqAAYb~5ae3ycv@e*sqX+JGy$KyB!$$r1t9dR8&u(+L1&n&!P119 zN^+XZ#!XwuaOJPKWeZWMPKPj`c_sjowit8+{zFC5p(@1VJ|oWu#tcn?w{wDcW83m* z<8?>_?K&&gp@3kvJFp?d@^Fylhd}a8phjl@HjtbRjKPlMlT8as&zn~W>&kixLXD_4s}d zVQl=2yxM>8;5H~~0bq(4ri(sHqKz(i%Hes}UcI~jYY6Y@UmZ7aGV*t9RO&g)$4c^6 zc&6&K;Lm$GkaO74K`w-6Pe};FJmZ~-AWCdy?12M(1wfmD7qrY0^#3SZ)Bpdf=ZG3m zy)?oP^{D{~2LUt2lIrrva1=fj(o}J4Dq$2Ly^iKc`ZtNGcqO~XU8-48G@dJaj`hU zVI2O`urT{M?O%*dYGC#5pKdsZJnAhVD2luMrWnl4e068y=#Z4td9hHWDCr?Ku za4m6)I})=2-qvp+A4Z)Ib4&@$4^eW0{bQBoTNOXQ%V7*8rO|WxbU`QD0PdDlcSMKC z`kVzz)BDv?#oxylpj1COJm{Th<6$tZ@qkd& z36>A0{02xn?^X{Vu10uoH%U!M3Tx)M5P#7-JREkqV9sCYs4hBf2aENs6Mz) zDcJ3JfSq0BuhDamM5ZJyLl?-;Nl#;ohm0KalA=!pXxr`TZDZOHe*aGOhYx>^aPlBB zIXM9v1oCF`JdHCPX4Q81Q_?1>7f3<{Dy(1%Q=YfihjW;%3McaM@!^X>L`{7e<|M#r zfF+PG0$6^hdh&QP!Z~-znh9UbvT2~Titw6vjXiR(_4X}}HJ|om~u9rLh z9lr2*SD_!1-#?)gHTuU4!1+lm`wCQ-yn5ruVX9Hf!}B9msPz`s$kkIBK?Ad37$L@V z<}Gk%}NNcw9}kDLPx@< z3B%Swy^0^Bj7_pAV;avJuV?W_|Jo>H^fcbsrwDuvcwYn1_72IP_6<5nA|E#feWzWx zUjm&__hA-%vrQ>YxF5(c-ziD!bc15DN}8~(l!Rvsy1UR`6DLjJJ>JDoL~s6G!!Uf0O@cWxdbM}a^!f5fX1P<1MXgz1x9M6SWmPM0+PfUKoa#${&2QN#{ zA&Jtl|04I_b$IjH^;eg6Eexqmq^l;gt~A;R1Hf;V0z@vaue;7ktm&5o*bfB2SR9ANuGalFRHKRXN^Dsi{pcgi}XRpHZptmM0ARLHhWp0 zsULVIRD*PXRuRKfZ{tE0+5J?E@&fcGrNT2oUIrd3x$@K$oTVZUJslIi5BQ2-=b7*U zR4~GGA3R+EkwN6ur(;wNFfhBJO4@qQge{+wFP|3hj3=qcv0MYL_?%#CK6Zajp10-&`zHh$gMMa=EyF=F z!-9+hsxMl{d>Uygo!}5ytEjv8%hSx z&%-N+lH&Q#<7Gq1&G`@EqM;;a!9#e-(CVia9L3l&n+$vTO_@cfsNVMST!fczCLyov zRvd<|)|Zl_uZW5d1g+9>kf2w=HT!|+UY#^(y})51gHgyCZKP$dM}ZmsgoFxy2Ss&U zBWqvH;wSSCa-ZtBPrK`3T;2yr0vYcD$~!?muNedSP&(<1{SWf!YeQ}Jz6z}=DN`t5 z#zflv75lK`I@^eakMCQqv&ooad6+`Wr#`E3yuzM1D+x-bp%`Qo3cD8I1?-7s73P1I z44+;#S1?%>2;HRo_~x0Hi*#swXJnAEyrN=Va7~>xrgnX|>121ab!g2v4W}fxUYmix z3nr5nuTe||U6F4izb>As$bn?VHZuP85=8+dmv19SUw@UgzocOEh~9iGiHUP8$)Pu8q z9iDsOxeq}8A^2wiHIUZAGY#sGgy-Y%Oo!)Oc+P_7Vt`TrW*bZmc+P?HZSdR!Py=uh zpuBP_wpvI(+vr>ciXSn$KTds=5kYcMO!l&%EbB^ifJ#nG^knfX(`0=OM^n<|W@}N| zh(x2jY>RkQ(g)hFO3ogJDcmfLjt$J?iz4##ti^wX!n&r2W5haI;}0qI4ym#Ye^R#K zj3&$aj#$oQ>QMP_NF`sYnYzfVLN(Ka^Xi+Xwk>*ozA;*p zn+p{~X~pgisF-#9$grWbYVM-E3?}Yo#Kl9OkWoc(wsyBxepJxnIKg_$ty5_gM~jpE zBN7ZUG)BpVj$xfYGK^`7CrLg!0W0i`SPI-hFDGH{*zSl4#Vf#B=IpR4fE-e(Xecc3V2n%PPr`tZpHB) zt&CC}!-!8vZ3!?AD;@JFy{dA4S}(CIAm(sNC5sr|LVKO^Pp`2K_;S7koz{ChtrFjN zYh_f_g_u!{U_=XL(gq~wP?GyFKfz0Kw`ino*=r@|)6jFHRGTcB1x6ev!7Qc1>TyBh zh)VG|V^VvBXeM^YE8^&0_SjrXOI?T9Cs~@PWY`I;P6f%5i45OQ(y2-;&@q47u^r>Z zVUo=|n)X=~t)ba8zgHW8MQ0y|_BY#0XE(z>!U``jl+Y-Kms3I`80#E2=!>sM@sEt& zIKqIDy1Gw?Jemm%A~ji`%cLj0TOBTh*vy1?@%RycW-`{nHZWKBx=l+OrEur zqPy<_dLCa|`;iOqD;^3SD`xnC`*5fg%Jtk46{@Exoif#LAR~^TYA-ulENE$m(U0^M zv`l_4=51{-m;mWE^sT-p{xL)6kr{|ENVUA`5nMv zfC~U!00TAwEZU+`7Qh^U#Q-~lCEJ8DNNfVA0;mBf-)uAyx7Pwc z)^2^YQHHHknyneF*7PK~8+#W7n5ZQ$BJl*(@?_~ERts{z+{1;Y!E1B9#~8ItqgezC zM^zR-suQN}re;e7D;|RRtVfoUEgAWhsgP7ZM~FTiLJ|8S{Ahe<>8&Yzn5}(2OGqSA9yJ{ z4g)cJsayOAD6=%9x=5mTtcc0 zrs;ThTtbp!w1A!G7{g|N^Je*2n>g8&bpqKpf*A8Lb|y07NO#11A&QCJIuQ(BZj2_+ znqrBS^7xdpR;|jdjLE}_fv7~uz(13YHokSR_`0N5Ks`saw_dZiUKUmaq7rDA5nq-f z^p>TP8<+G!qQN8ZW^)u{s6csETMD~F4qMnT%}A1%xX6&sxRvT>jQrsaD%<7>EW?U3 zd=mJMN?@^@f5Qd5XtDUTr1_(Q9|Eh8c`i;Oz+3zRjhTM@)&0=ERATUT%2}cvQ49R;#P!WUy9o9%jDTnu2QR z0@GJ8^C^4HocIXT1cMH}Il~x+Gx;x%7bnowadi18{v$8nh1h;qF2?(GVmolfzUUUy zU0Rv=kaS*112tr;=n%f(wt;t&&csOy2XJdT4cySN{FV{*Q~}u_No^i@>7rY_>h2xP zhB|AbD=xth!_aY@%ZLxTpf56D_aA28rOYO&R>OLek}V64#P1lw_%c@x-r8@>`c*C= zfQfxyt?&oo^po^9IXjp3l%9t1#C#tBX=F|5dGo~HDocTDW zvI?LQm_y4qGNM9)#TcYiY)xfZ2^uZtQ!f-+x42+3ZTVSbXkA%vIm{OEV~|5^v>!J) zm1P(ku+ibs%K_PfB*0YXdAPCb$GfxvTMeAp?g0j#q7A*pm~MGA!aAd{v)CM#+y{0` z{(w|&wNzSD?0UAGw*a;_pps9qUh!zM)|sw&^!~|xa;NXKOrUR*RN4Tj5h3UT@|Pv^ zzk0Ozo$^sOK7o!{Ri5LVT&(d>3t=yZp|NDS#Y;UfV5dCio70p~u$~TMrW-;TFklZ$ zB{LY)3og1ifiX&F#0C$Hm*t)ZtWg$cT?m#WyHdeF<4VF238RHR;!ck}6Z+wNl)3a% zPfK&KFq~-;iUga$py`)jz+#Fy@ki*bWeV-BnGthAbFUYRmw}0`d7Styyt8M}cMmgZ zs)fJxoCmKfB5Q%LbB1gZc8*{;GCBl1Mdn0xPeekJvZXbc|H|{%2rUN9M62#V6YBB+ zr;f4wBo|9O8nY&d*RacNE_m1(%RM@Ev%YfF%f$kpMBkzkO?HbbJwSd5 zB|pyX+~N`6@eG9?8)>f;)K5=m_y#YwaNK!H^4fam7_gqCtaQLA&Bw5L0~iUA0+0?c z3t%ch4nQuzb=dN8LxW(WytB?4QY-b4bEUeWXFcjVzon8(>wlp+iFMh+ z!LGJvh0SuB#IA@NTr!mrf9=t$*q=S>!ceU;;wGx1ORcHZCAPZAf)#@8xJO;wcj+%c z?0We>#6&MK6|5S1l_O4?jh%52NEhpYu)V=kYEv6Ld_qs$Q(CMUTA{@=))vqALu)AE z3>=Ab)|T2P?pBIno~c7Mj#xlfL?R%crR5%eDt0I*ekti$OAIYnBel4rN6${O%~;DG z@}${v)~egx{2mvHUCG<3Tsoy;(lU0hC%gQ<;ht)*S4uRDM715E81ZM#Z;Hc;>uYI3)mQ? z;$KwwfU^nqM}RY9tu1f9pJQ7u7T{ny>Nl`90WmZ+?6KPW-OhnNtkkuP7)@J((Y1f( zfp%H}qvP&B7|(jskXy_R^@q>;D-18mp!I0dq~zAgKZ9& zp#p$K080Qad;*(#c$NV)fFr#Lo?Q?-+6K=WfU5uu)X@Tr1V{&%1F!&~6rc=X6TlXL zeE{_UEdX}`Tmb(60z7cCb2jtF$bWfk6QZHO2#^C%0I&pL9l!->bSFHwK*fFVYyh|p zAcqiJ5I{6QB0w6zEPzD-@2`P?S2V;#Ds#Oa`Fpjq?zdVuv|Ay5wb6~6t?wqbEYfl% zb7Y|Q2{`p>na#Vqw=D2znlt{pb?Q!Fwr&yo=`dxlEz=1->|0ZXfPZ2)zvOGI0fEAlC+K zO(d`BiTI7O04Dcg-~lT>z=lf7KwQED7Ay@O+P4YFP#I>f49cqH#)30GGxJ52qo|j) zB*X!IgS9kvM=&_ibW1YRQ zLyfo|r-E~0ay98S>=Pb!vw!w*CiNcX8`_|=4Iw4%Sm2jkZ|6Uzomc0v>?pZ7+}nHh zCiK?6-35UG=zSJ%2LW8CMOChnz6`(4i;#s`gIwfY;7-8nzu>ja{-sNN)Q7ShYG0!= z`@&`5i_N?}i(g*Im-3VEa0<2*mHZ6H4_+R@kck7mJZ5;*0_Cx!p_j4OdKt6F$whxJ zWA@8HlHKAGM?7H6@;fd1lrm=HpYP?&u9b^DJzmZ%m+1S=E;052V{8i)IsWA`^UFbC z2Hp<4X`}Hj$J%$uO15K0?CjAiEtQ@|Tyh9|HMisoEDoS!Z1$*kEBS5ry+gb^iHoE9 zo61xDjZ3ik#`!;^{I$oc!_IFg6&Q{@uZN+ukB601-Z0o%j`?}M!BDKj{KJ%aP{K&L z*x2J$!c)Mf$FEU` zcsRe;23w(BC@ZwCM(3#OAXrzz%R+uN$cF!SJJ+Ai!QC==@92???FL3dX_BNgCnd)uX)(Cus zeLCIPPiUWKyF?vm41{Y}L2eTi*=M=w8L(>?~y#U)FbMM=^G48BuaW zAR`-Oq1cF+_>_s|Z#29N#!XNlb-O~~OAVErxen>&iDD5@b9A}|>k3Mxoi*^w4AvD5 zzl&{dSfI1$u$9mYL3#WNj?GF9OqS~v+~q9mbE}cw%K*OuIx0Tam1R~zPlbvgRQ@aU z)WEOMO^d|3M-(zfya==`8FXk~MrV~}vs2-upWz0XzU>6*f{9M)nkfhZLhEh;<|aY> z8G=-n$+Z4+q-JBdP30TB)TfYo_*7W%V6po9wpUwO`(c^5m+>6mcZ22!qlXsLKX1r=|{oQG!Oa(||klH}wR}{0g9)^!TtSP6lVi zAUEigZqb-I&RaeuOufa3uhF47>E74M-|YJDN%tHBUYKwkQ4O)3z(JWB@WncO>zKmL zsDB+zxo+q*&2>9uY{@VGxOV3m@mZ=l$KC3>&=cpne1?-Qk61B{;UA)UjbR?spxSEm zE_Iwiw?Q`}F(}}3yK(9YCQ0c!$gk{7!&}2fWv=MVvw`NaOsra=m%XJ>un=m$4@}2` zexyRXOrC;yu0O=%hdn#7yxj=}`S^mCqhYEoiQ+)FH!`)Fb-ICmgCR)?VFuV#{}#L5 zEaLlmrM=z_QP@Y}x)}G6B8a&j3I++nTccnGu{>45I;M~44>>wfYDwUSv9=VdO8a11 zu5o+<(V=ed8vO*Qj=jHY;aykeU6(i*S}SdOVi^svWWyUrKWZcezBE~pp|t!hOMR!; z4wNur7?s!eZgq2C-VS4MA;h=3_7xr74mEJ#{D5Kj-#Q)$j-`^DK)(Ml%685-ASEjp zwI`hK@0}A^<{&b0o0ltlI<#%!=wgTBsI0kAj@3*fVjBctGL-ho^mQMXUdcVeg|RI% zb-9{W)p)ChaWdG@>Xqoa3ouKjfnGHn+Mx^h72YXRY#rpyhl~)b-sE z?F*oyo5S#5cKp|H_n~w(g&NRd7>w6;bK*Lv>rl|TGho=WqvR%cN2a?&E8iM2Jdb6b z+t>&Ex!xhBfyrlMNqY&5ux#MgVx_3ArEJImT`?K<(bFS@LJOmlliMHlvpGRDh5Tx8 zuS>=={AFO{4~UHoW-?nlIHiGQMsM_o!)b$z84bE~@%*URkK0rGLkvziL;VuV*HQ;X zU5;TLX5W^HnZ7Z8h>meb50DirTwr8ChJN-@REGC@sN9ZG17W&w6AqYd=IFPLLNWU8 zEEF{*F0zl6JHq8!jt1dHh%N@&JKWIg0dTN2TU-ly%SLxuv6gELjNS2=LP;gPh6-YL$b`3;b#fs`G4#kn+3+zlblQkSAl66er-xf_D%ME-HKZ82=$N&(6M z=)>4j4Oex>IMWJ<_37UOL+e9=P?_PHN>DG0$af>4a0W#~8>t zR=FV{(kzciNJcXEHdP39h zxYgyJECf5SWY!VtwdJ9yZ8TB@TbfCfWxKm9?_o)+gvEjpPf?s!w<3&T%8ErJeSgvI zrjFSTtT-c~GgPEnWxf!GPSRwWN&MxOQK-?$^np$VQ+xK7meVx1p+)@!D2QN5e3RYQnqYsj=q{W{t!AW9Aze)I;=c`rm}P{~~~>!J?Rn$D%`JLk#g z`CH36^|CPvad{{A-aOf2m3X1+bs0OPxY`zex(yJW5(F?(Lc(bF{#Si7 zZqX!}{TCqVy@kYB*WCg-U?&5_xA3M8Yf2}#ZH2-L^)RrJO>r!pugl<1)-w!y_5t2< zdbsD+oi@JY*16!k&5w&c(upA*0pby!eEhG$w!iN>T=z}GI{6*t{JJIBe+$xVr! z@F%{r4){HN2KW^}zXzcvnfT*9`12e5u{8Z3z1;&%v_V*;yfV=nVOZI2eFs}tHCtD- zT1z>6JEXI=@Lp;plNMMuGENT{)n>3hsyXVo49X!+jC+SMHI|Dxyax zQb~byu~i0lkgIlE3f!5$cW^QDSX0Bj%s)E3!oJ$!753$hF>=QNsS(?sD&O4CHmDah zK&%SMJki0W0?rTjGEez%&iHVe0muG>lnPfJ+y5CJ7*W-K4*_n~y-cSM_plH5 zAZ_p4|HZXRH$!S$@)RUz^Uz6~sF!fm1d}+0;qpw|I=E>qaO5u+cXV+0oJ{<(W1vj@ zq63Ctmygb%K>vk@t!Fc@nz}$)G;qy~-c~uejW{>Q*t~wM8>YTLCx`GbhxSu8^z zk{nZph@FsR(}$3ft>Z#0;X`1yw+aRNF&8p8PJq?<!7wj@KzgGOj2XifLTR$nTiAzu@p(ix z9UtHgv{O^3(PGNlz7WUsA<)JW_;aF5N)k3j>EY5qvJ#D<^UoW`hUGa~333}rOE|3K z{@dQPZ6o2^gnlu-@8X5{k!7vouk@=Ao@8zd(?|BcDbsE$YZgz^7yWySHfb+x%F<$W z2ojG;umwQDqTaWT|2|E0U#!IM{6)U`;(1)~7vaBr0cX-jINA2) zG&G91zD$bx@gz_L^Bza_M$||*FzB&>W>J#5co5ItOXP{Kbc(w>dE?1oQu5U>{K-kO z`>SC#8O6xSd=Y1`$y|g0Dm;QBy>AlctCIsz*(Jyb3F^6GPUiD@utZk<3IXyC+U41p zs%L~SBNN4XS)boOS%r#x2>o+1XJ$bcElkzNz}Gd3aHAIiMfj=@0KV{|OJsJ{kgyvmENCnv@ZU>aLL^RS#u+Pf5WE<6GV?zK+n}r=TD?5TuDx zyp6{XT#UHDHwxP)QjvV^t-s|z^?#%Fg@SNsJ&B}m*Q&a<@kR#bLK4i0C0~%@?L%!2 zS_g!v)NzqGLzx_?Q=J;rUf5$9d(6utg7_j_R&qF`_so5|#;a|t5Xh)QSbZRJ z(h3$msu@ss51@0{`fne&MUHKI#uwjxe`5e{JjMD$ZLw4qZb;|%Umywk3$vhaKH*I(h!bZ-`ofl zzin!|+kPBn9j6zv3>9zv`LFGU3Y#74iD_Rf-nNE3zt0qrd;*&0Wd6JKvVX2|GK~BS zIHXuZocnZm|Ig(1J~N6SBY)IbyZ!`|RVUDub(6~w9|B5v>k8mE)N#*1fV)6&bPl4S zhPwE;?CWm0L>=-Ue~7>Kr_UV2aRUkvn=8sTHJp#P9F!W`X}{q>9=&sgeDmX|Fnik| z_WlD0#vgcro7bKnHE`i|$o}wtn<>Y1LZv6G&K1A~0wvmXf;_gL$GiR{3-?E;8NirZ z1NWZ~^2U~W-dMB-J_gxOD)+})?5%_7krHgesZ1QsLE=rCV1F7U-hcx&$KgSdzjN?0 z9D8999DoQFJHbvZpzY}jF5-sW@G%|wtcj=&^ndJGuiV1)Do}P%^%rQ?XO6G-en7|M z9^j3a;m(w|+tkK4Vs&Ldp>6?siq?j3qgr4rvcaZ>f0CCEBqpbOODkXo57VZX)p-rO%PZrYxUMkCM^e|<3~QA5F*5fs@s{SWDWFSxDQ1r2o>VP z%9_0hI+9p3-aPODLO&s1-TNx+pXy-tqk78%|0#n&1ROm2BfW1a3LracruD79O#9QY z0Nn-Q)Q-aJ55!WNDPvz8L_VmEvdw`3NCD6QxK>9SYrt7N3~+&_0X6|F0GI_Z4j>ZX zZW(+_1yBP}1+Wfa2|x}&3V;iydo(;bfUZ^1#`jCX<$>oOfDHge0CE_BoK?|%jY*J+ z1_)Y3QtJeK>^OP8E@nXeao`#(`P0EA<1v#nB?G!NY$(bk+v=k6H^<4by0Licank3Y zh%f&_k`Jch=3j{Y;5fYaI5~LmA(?&EAmTb`L^DWoeMEScms*xEU*MvgZV*R8#Dx%k zmIOEG3+sm?KeD+#9E~CS>JxCy338+U1r$PNI3|Enf8dD02ac0kM?Y*oLC!j2L$4kK z&R|>owdBl0{Cy9)e2j!Rv+(g_B;UyoT1}fWM>2U^62tRhH8Vdwe6d1}@q*DBlts2U zHTc_O#Obu)&yEr0p_qYr-uheO!&8L$p{4SwR=_Pv(jYBKKNOEw9wToY8iI?Dk&h0I ziyK4h3iHD@l|v<1^$;C+LqeDk$@B)HAbP_u_n^7Q2tF(hev-1vO*70FO8gk`f1vv^ zr~&@)%O3PN$vkX86Up+!Bhgs$@59s3P@+5%g(8V~WHA1`iDVvm1$Q)(!$*eTn~mh! zkvx2=kz^blgmarn!ORU)qx0qIJ!jrVIwq^3SWT<3H`u{*zN+=&O1gjei{${ zO4(1EKI3Y6;~tpw7lO&&pGFPMx-2epMb>2mb}PWI0o)t7Gvs6>7Tm)pgj^UO2`Irq5LnB=@)6X%nofed`>?D>1Y^+?==yj zad`L%(BslK=_GFo*mYzxd|SG-d*Ka?DnQ2?Kf|vcC&9;_3pok3&QgsBpjXJ5C1m9> z9)EI)Y(JJbL`|m;7YWfey%IzoLbK}j5ZHyo(Fm*}u4Ak4-@lU;$43QT{2ksUE7j$2 zJrte)oirX#RVGroXfwUjT2C}h1Nv}Yn+fN^U(mG>^(VPa3!lBEhr0CuxObr5RkzS81hQ zhxTQf{$GbS5ol`x7Mx)~x-I82yTyQoGy-rDlhHpL2IRGxo@xa%q(ZmpP1v-+%-OBO zqD?c%(w~PsEdZh@Ny0SvR&@ZRTR`w(OXx7Q=n*AzF7uj+?U48mDGdqbj5xWqrY=|$ zUqk;k)YLQtPi}w>FGAl_sYNbBw&q`w=(REq~ zSIvb+t>vCno97joWh)g~?gNosqLq3@_Ulh%_NiD^0rV~R6mKjIg-?slkn&S;xaKEv z;8Z{5_q1{nr%ULHa#WB@r}|~TMfGGHY$@~z1ssL+rFbc_8dfk9gLZq{zaXV?aNh=P z_2$k=8A`4n%~#PptXG!7kr3K}UCK0IEE$cHJNQUq+#2>+60nhW&b#4))%}D+0!0WA z8{s0aP8l1?!-D!;99_R)iG3l?(k7)skcht{W!{lsH>tF|ANgN9nLX>s*QW>JZ;q12 z)1wtz)`OOp301a)c<)3jwDNL#;@R0!h+&D?Wdmd~`nYi9NK?|2CjrI(y=3ZP%`l zTBG;Ft&^bcu#yLeu-nUrgJYM3b{v7az2ADGn}5*EKVOA1%mNU}7J%gdi@vB<{jwFS z{J(_h5AYq7ReeF~E>7&b@-W;_5(GG!7(l{)P4qu;2*~iSA13L)Cb8R~-u3DgzXl={ zLq7Ozm5n-)LBz|*5uUmfnmSF@b@Vrt4D4*ZQ#+1MCh%68`Fj$YM!Ta|mSC_N94ho} zrv6LV48yp};TFqf-dOVoZ=8CKH(rIjcfMUS1uVQFJ7Vn?H3rQ^dG;p?8zniOlAOC5 zem9`(Jw3PNP6ph;s)2y~Z10|4PGzF?g%OZ9o$M|5P%N#|o9^+ZGrZ|8AA=Bwphn>? z%{d1#40GE7d&K0x$U4+Xm9G&;vK+R};F2M7p^JnKOFJ#r#k=9#%n03(q(RzvE@ceX z##5(IsN>K!uS|}5{k)0@@rc*Y`!qs4OfODtju4cQWtF@`LVanIsfhZ{_9r7S?^nkw z{wtPJ2Ga0P>~-R7hx5(_pN+o;{_73AZ??cu8er${(?Nq(kDBXy)KF-Qcfp>*)UnKq z(8h~|?sxaohG0U(|DSFmM~4*P>=oWP5{6*_q!R%uyu+|gybn8tf$i4*a1qCCL)aQo zXAN()4mkXxeM1EO5K-w^2jB7Prs$s5&DYsz4WUQSM4M`a zU`=q%7<4UI{7Et=gtXQMEso4e2+d0f0*0I&1}-uKmsQh&_`)khn8hH)mhl?6#bJlj zfOwghLZvsKO3yYZ5c9ORJXNw%k=0`=2e~SGmsrdZuy^e^*LY&Im@UX_MMnzOywhGAH;#C0ub5wIEek z?t;-ws$&o-55AC>3i~VGc2z<}6vwGz^eha3lVg%*r4=9*RW@xw66z~tsD>q=J~V$m zp)WW?aBQcYC5F;IcxO)ctaAnb_h+Guza&Y1h+&H0X={LvECC%T1=s`W4e;CqV57It z&JJUY^#kadSQBvjpYs46Qtytrnpb<@qkb$(`_u)@-;yALXvOGp%5N$MP8^(ud>RQK zeR3Pnhd)DMRkQXf*x*CczevJx7G0zYKzoS|W?9-(j|w?2Y39_xDxni+X6xmYgOjw1x;ShxpCf9; zH>S_9(l#1dZqT)b$r!?@$#4OTd5bHrZ^^3fT=&*8_;xJfnFZ?>?HzhKd!R>=$HYBj zmLd4a%Vq-2{lFCe%@Z5sP!jjdIN9h8Az2E>Q1M&h^q^VGM!zdJD^Og1j;YMf`Q83X zdOaBSquia_Ur1wuIlqtnxDO3GevAABZW>HoRP1OfDq8f;Sk_$M1dd;#J*fEbfh@-X zCEH9iwv7`85JtJ6L zEuq!k2_)w5ajnU!nX%xKuJo1!=kRX~zdwDkbq4?1ZtVO<$`KdyHcs}&(5nlnNQ*`?hDvy)pa|aYp9cHD%5W3}06AvK*co^VK_uzK?gsf8Li42i~WeE z;qosnf8SdUx8@@jBW-M1vA2-;3ccxdkhU?dNF;?0~q;PyQ0>zOl5bygL!(RtH|!2;OJ zr5uwkUC*-R(&9`VcP(;3tj5-!9?7nk=2~^*^a}eriR&j$@aW=Ut`@+RjRh20*E^f} zpv+5>t_;GiuvN9Jj(}CW$bb@)#3g$shK^{c1Wy}faF%i@HGo-SjwLGoG}r{R(g`$D zVYTE>O6VP$0aGB$;2djdXKnxE6Hs^lJD8U>07jUni2zBk87Qx4f>RJqQD-%@TN4_w z*&6MZnJbngD}>rGY#q^T6k;^Q#t*ZhGs5gRfAxSY2Ew-9Df3+{MhVvhHsSU=|HLz$`rv6 zTzb65mRB2;!Ri&sT$VL9&#Fbu)GFuk+AKbn!!xrXC|amwGJlW+e&~YP#LUMO^3gh! ztjdkiw9VJBEfVHOfN<(~Lo+Y7@`>$y!iT}sy?POTnx}0xd_t6=2oTxp5A;U^66F9~ z;09h_|4grE0%tw+bsLlZ}8&IUue_lE<%07q{pKo!8YFUguqWALVWa^%uOcuhS)tplI1 zd?mI>tj)(n;XZ8d`u{ibv{xSVa|BjYzslXbBK!@JCGZAR?xh=SQjePD(G> zK~$F`GXf}CJ(q;odLWvFU?&=Exg_O>U`Ia|b`tGUueS#KB={XGm?I4o164aP^ZfO7 za9!<^*WIFpcJkWgVagw9lC5W)-BQH{^7UnnjZK$B%w9>|* zj|LoqvJ9nO1%io|BQ?z`Fk>94nQDOxxN=l~P|#d5Xj;{kikPV9I3-^#p$};*mx>)# zKblp~U!UWcD}OJ91+!zhAgPPxnJH2h%k;l8f!`*H=EV+9&hKKvF>j}wyc zVZLfz)gKYe!m5LKVi4-0g@?tfnf|bago8b9km8EOzYk7`gRH&Mug^{p>vsU#pjTJ= zPq6QiD>x=UtbgJo8qj^A0)7ue&bLcw6YZlDGnTUw_yy<#n(h5j8upCDUzd^)BK1W6 zN5%-YNq%*6G6(ygrDxYW{*e1G^nO(j8V4h9xhVH3Y7qnfd}WTwWceQ&ocI;l`Ukie zUy<{F%#&OGgah`8e_HX>D)Qx@GZhtWU?3NgK35;Yi?$QN|918O;#QT=RFZ#f5bG2*-j|c#mfuD@pAq5~D zKlTCx9v(Qy=FLf{p$M)+GQ+_lxZYu|T!c1Kfs_^Ue@W=b zK}cGc)QeZ8ERu9h7-}D-2iUrT7Jc{_u6PBq$7-_^^ZUf5r9DfOMqW zk`z=(vi}ky9q)0scR2vDHK7Q8-y?PeE*ZmcYK}GaJ4iPCrL&EtlpG`B%UJY>6Ox=@ zXO-77EkDEOLm^3#8hwp@9d`o*g|ti|p(rU5?rB)oav4B$P&_jO?_>WZd70eG_|e(P9UA?e9cb(L9a61mLdt) z&+s?{54dbXOZgkrHO@GimC=BhgCz6%VBA$l7G4icuA{GE*Jh{~$c1tJcAb?XKdgL` zK|j)Rp<<4GBv`w;jHBQypsSQ+@DdIOpXINL=yDyYz20B5y_bTy0>S(~D8atdFqJ{u zyzM$AJL$R}X_Nc(wb?4e5G>j3sk7o{eMl|qXlkwjG1tWxjnkaj`5FvJniCq~irHT| zPz(#rz0T;bXe!Vdq=N=@go9g5zX${x`35`>A!6=*N1brybL+5J$ zLn#<#(l`E%%$Vqy5z#z7{6kCXi1lVa{9-Lxd~>SoJ1mf&Zi;wM74h8cuU}OUY&YwR zObs4wgIIUnC$fH^)S zCmqf-nx@yx6hHyd(*H07)w*d%OZ*tUKe|VgP;|%lG*ryCzBHN&Lq|F|diMd4T@|#mA1b41d9G zvID-@CH)UR^FR11hCI_YFeUnse}m94HIWGlXh5~J4*!va_IoQgn7Pr1T83ZW0~(q> z=1i{AdPB<1)y!*Pr{NOJEX?;TSP=AjgN4+z4G>#^8Eq89NWV!^8!Q7p8~C+50QomC zO1ZkJFEoR^W{H1WLYwPI!0p)RjkF<7a2%DO7L4G_ebvht$8E_F&n1qD=36Cnpq4y- z`_W)a3Ve_-7S8>TOXg3XL9f)2owviX+p4_AmVeC+%8M%)Y#s@}UnE!=^a3R;E_5dy zJo9^~;~iN;vlbaP-}Q?BS#R%xeSuJj$udkEFwbZhCg{Crpm_IE>X%tr|7~4<@GZ(#02i~cnQ36Y;4BAx}`ej~~%<&vd#;GZqNew84 zBJh``H296hqsB?mXkjf`+dks)4ysIx8@K^QuW4Ryux_Gum1FZ_isr@77-v6;?57c& zSBkwWW6Yed{c^wJUv`TxyUm|&K#$e{HY_BGz;Fc!;T4$0uWl#mI|e+ahD^RQI(#H$ z?XY;(bTzZf+Ph@)7bWDbB_G{M#KreWTL1ndM);%2rmP_u9$Nt|D=e?O3Ptqo|i2Ib2FMQgy^e^|^LtMY2 ze9gQ=XgYm`X40F|dPb3?`Z#(0 z{uE>(NA3?nc5?0h!?Mq^e`dZZy`KEmGX}H!Nw_N(_xwm6aYY9m zp%T!daW8xI`_KXMnrqOovirR8F7R0&z%a8|!5FC!j75Heu^u4BUof`0dHAI|!8mn0 z+3y;KKR!V2xhzxds}O%q;+|pQxzH`1rS5A9CC@+af=CMFmU(kXg5U3foXwl-=N6l2 zZizQ{Op1KObWGw#A#E*L>4qyb?ilnMIqsg=@03SpMYCxwt+kikCl8P~&#-a!S2@Az z55b}j?~5PZH-BzJg+KbF4_EmO6$7*(x=hqSiz4l5OG_6PKi)U%@jmbq9GL-~WW8tF z5O$O&X=(a$j(rg?{mI2={P>o?*1Q6-djoTp^6P7eOfsQxVv)3Po$Dp3e|(?&@bez^ z95!ai`=%J9mVqId3QFhuF;Z|aQ5+orp1CjLgJhQ!8=v#wE&NnzBz*}s_rHv?WRoNx zw&|~TX5ia}w)XjyO z!v+9XQ%pXd7_0N$_fV{HUpM>`$#j95EAOI#zU}7b2*zh2I$Dja;&UZ`0;6@5lwhsBxJcmnICL$5y zJ4iyJJ6W@*O#D2yrUPrpZZ$h{usU4I}$iy5Ftz% zjtZzM!7Wg_37Plf#$E7hI!}e|ho5PIVm@TQIOV<r#eO$7~91#Os)$^dC14m7ytpHUR4_z;5n)8{d{8 zwe2{)_6sY#R|uh&ZmFypw$P}XVhR;SmKY`}9d-(^9HODLjC;lK^#oIDk2alS0^+^i zOOP&IGtcxK>zDa)_tdPQ8R^;vIFr5%VVooAiWf&Qui?R%F|gi2`#~GMBHI`$N1--0as2f>b?a8I_M}MeeYGfx?#+@V?!A=k$}r4e6cUBXlD$F+ znMuq%Eg824W2YD)OJxc(8Oe;X%Qlv=RMsrr-}BsJ-k<;X|9JH3zRr1_eR-beeoVn@ zh)5JxBNj1=C@FabVMp%_B!bZ8ig31wYHA{+q+`mbZ~y-gQfql}kqeH)w}z1w+6UN6 z2JXpev#dA;<;N)~MI!~p7k3i{HN%QiP&^{_ueWgN?P9r*M+B2gvvn2MEtG#52mtDG zJHk&*wMVzGlJr6W{Slo1#TkypnE4fub^D}Lw^d1c)8Ax{k|I|GR5Wd+#>lnw2q(0Kr5RJJ}Q zNqvJ%2q!JOYPtHriPS%Fo*A@qw)#*LYEP~!H6hyg&?Wr?DJ|F>!#!r;#=a`T-_4+h zPyeP)rPUaea2(wE=qU}yR6XjOmUv5JOb~W3hd>rsgcHo6zttJez*E*V!0Tgp#2ma> z*{@h_4hjfC;<-5anKzZXdez&!Ekah7oqoL{Z!bBXv&)V%joe*CEm`c{cX1pfXiuP4 z4$gKdZ>dCSpr1lNv!a_Q$#9Y!TKmgBe7yb6@c2o|%!Xi6Hubj&`Nb02o}lbiiY8Jr zlpL0DQu4bZJRk?(>mvW79foRiu3Q=Kq(D%;HNPm~r>-{WIc*Y1B z(yzFi#HpSKyeXgQr?JP-%@SPPlA9VBvWt$9|3Mfa(#npJ@s`A#55I^HrSA(R<3DKt)b|#5OoxHTGBe%d>qeMLTJkx zK0iL!GaZVF_Wb!g~q5#j2qOTSB2A38oi{B)iGDK_>%nR2=o-8u&oSiVbe&j$4 zh#yYCX;PMXYUs(7G{y3P*&sj~A)ly=hvcS9lEVKNHy2*iPrDr_@lhgXH>! zBK0^#B$&JYom@CZ9Ik}#-;Imb|L@+QDNwCDI&uyD`q%}n5f%LdyQo356Nb(-D>e{= z0iGJ?p;`JdgD})t;-?Pb{WRKT8*0)v)Z{RwWrNC!M(#CSIYMor#Y65)Xh3BRDj7w; zfs04*o(S!j^>MVf1}Do{-q6%RA9MR*2Ww~+tDy-SM^Aj?#Bsmn+$rk`UN2G3y*^gd zDc|x#Ow$35@W@aTetw8fI*Ry(M>L(X0*y__j}q%(U85%sRWThrVc!^~#};&E&4?U) z6!%$!(kvj%PUG_pUb2SvErX6y&!zEY9L-2+v+7V%T^b2hk&HW5hju(&8vbhoEkTCn zw&2^YY@6&(DZ9LY7>m_+lr3-E(V5+GV5FyG1IUN7O|Z*_)do8G7Np_Vw%}na`&1Wa zNirF(vW3=c_Ho>63$9Kcd^D;9W*+ij>6Z-369#B~6t9t{Rj)hzi*koS8%6v^&XZw; z+uZ!$!MjI2GWH(6GDw0l+JOWDYK@Z4Ah>uGL+rql{eBcMr(--ZnNhKxkHV3m{@CO~x&UbP3GQ5PErKv`~(3vGo0aw=9t#}QQW zX!zAY|I?ot;5Qx&0_|}_kV*eQ$%I^wNxcOqH>R3W9uu61pV+)?VIG+VUIgM9QfW*Tjp}NOQO?558+fLAe zH7ml8PTRmT0uuNdH%Yo-oGhDi z_3Hh^UVe+;Hiu|dc^F?ehc2w_8g_62Z#r&AxPS+ne;DVxz;~W`#;VH?1;sxYZ|Y+g zvd@m64P=xP&S3*>6~VL~+q=S-EbcHabA za8!7#34KE-ylTe>a?91*i9?tg@(Ewlj|s&zYnAkv?xh}jqjO96!e#amAI|4xij)%a zA|(`?A9IX*rCoj+7q^6P`N-2$sP=XtUTX=Gbh%J{%0~#a4+v1HM+hZ<7V7qF@B0(q zu%iWKkpXN9v9%jGJIeV=AVyG*K<2|~%p~%cLJV^Q&(3H02V(J*{7jfBP1Z3UCK2UN z4~-OcDG!S5jPes?{m|D=qxk~!+@Py{NCo$A(vEDrl&rT|WOgAwaf4y(`$E*Vfn8a``6^-GVchHv zzAW!B{^m|uHy*}k?%>SU97eO&AbDrM7 zTT0l?UjKrtBuHa@52BL?e8Fn=7f$hjqb9DSBkVMN(n+x_+)k5~Mp6`d6co-Z3~mD_ zfz{+=gAa^gLIIBOh0bQeI^qf;X8Xc$cCH8?`9k-v?i5gq?hHyQ9W>h~fq?mhIrfQT z?7)>bG+0zt8DPl)dX+1=@XFu%ZRBOGaSM=485Z&{qP5vuTA0c$M1z@H*SyXr=?>Ln zw+c@dlOFv*Q>(lJ5L+Z#j<-Y0(75J59=5|;YIpUnJUT-ToV z=AKflZ4X=6(o)0@poB0y(g8Zyq!c!tOrnYMi-Y)@KFP>L0g zOjm>p1Het*?U!-G6_LINF*g7fF^hw!RMFadeiDOK;3qRL(!M@`(^Sxw{d)j6sKD2% z=4isRgJcX7dGi4Np@Kiy&I9j>Yld;4%>M_9pL zoxnDopbdL`0*7{j(X62u_fpvFWw9tHEQV}N5*{7N4I*s`ZPiCQUc*cY7wIF*Kiv?1 zu>jw7f^56}1rVH1gSOxSbt!UZ0p@fDcXqTGk9CG<`MM+FuMMfo3b1V#2xChQ;LI*C z(s?$QRYXKDAKgIfP5>5O}!DAo22a7%svq_ix%^b7TZ!j{5=;U)eXGSaELB1}bK|=Jf z;B}tP{hUfjKO=z8vuJtQ?~3;Dsv~|oR-Ms;KacZiEYXUW7?$JXCLd_w5JVby2g`$n z=<)G>q}`&+T`(Eo(5H6F8{3%-`Hk&d{JEWu#)j_Z(M=6~y%){8f=9CczlIUdHF`#y zbse4Sagg4@H57CmE)nmsh03Ht81V0&qOwF8W@soJ9iP22w0=(fvPaa|~n}~wX zDqjOHFo1lI8^QBp>Uljo@EuLz5~JSS(F=Y?+QbcC-4#U$swKU+#?Wa3=HIf zqcDaCxcY}Kw+O!C0W$TD9_HbbV;t^Xyi6$P^@PV5V!S42p7nxXdC*KrgVfo_jTch^ z1OKbw4+#6Og7XkUfl*C0RDzCwN_U`f_*6qSui-+t0rv1x=LFBqJR1zV`8#oSqL(Om zL&RTUxv?QzczkN8VO`kz%(G#Tmyea*pqc+7os>W{^KnM$j1po#{0sQP4i-)u?jOwHLGlHHP#8CCkXim|nE&7v|&I zUhu@`1j(=^ePkonTaDjppo8O-e99Lk{TUx^$6uoU3_p#P8t@*tg^z}$j}txU=qP<8 zPLvB`G*h$@&HpF<*#E>gr+7b8-ikr_lEi{@4@g;A~fdh#>7z2neCoK_btrBqoHus zrhb^DIY>PBFTap9uEQ~}FNB&|JbY?W5{J+F(xJ8k_lAMD*&h$&*0)u7H4Lt?-wO*1 z`+)^Gbo)}$q(_Q^JVFqJakS19Sk)i2Y|~zBHUQd#3HBKP!-utcFeh9ttVp8aj*p*7 zU6k}mWbykeI6wGr9{6~Finn_p4yXAU!RLp^)2jM+7yZghv_}o$hYhMZ_+$X2SRAGm zK+_*yh_eO~mij$53?#R#1NLIjAZXoh(aWewmm_3fM|)Z2Uon)VzNHB&h)X#WDGzrr zB9&Ig?A0vNtTfVm@fIPW%U(q(pT?**l_VIV7ec25RUGOEfu_^nl$sPw8w5cJAWhS1 z`gNn<^YkmGHb0cmW2bQ?a&h`2)rHPGZ{K}ivIv_EhRLj8H>M1xg}fYh52n+`e;58W z7^2wkdkVV_fdGI(IAtj4*t#0rI~4p}D(;ITsQb;S`)9Sq1Z0Zq#l(^^d$4XO3}o3m zQ4>xm+D@Dp4y~<(JrR1tN>90Afo^D`fBu}W_>bfwfg=Q>?n^jn<;;^74|TdA+(U6B zt@J@Sc_cCN#;wO6N5URvy9)=6g62$j9ivCVS8UtQSUL)(c+R;iXkN;Rp~)2OL^YK` z8d~GQ@;bfI&YxJRvxn(8^efOQ{&=m6w7)&(?hW$@8@b!x6=~~Cx<+PY$wt&Gv>RWm ziV6$90&}oRvu{xDHmFPNzyW{#8pgpp^coG_UO zkxM-NdOR`)CORqiP{qFCU9}^XVX9!6Kk<$Cpn5EHaI!akS=}{tWMo)^@r$?zXN?7w z`=~qQ=sHm7lS?4SH;~gEACo^C7Vo9IBy_4${BN@f*;{SG=M$3B@;Y&o|H(tnuo3v|Yg;~@t2;HL4=*X$y}z-hJkcszW~!nb4J3DAM{ z*^YB2P?_j3TWZQA}L>S}ply^@KZTX!AqO59PirGnn+jwOL{yPy| zTixbg+uDkEQxrgJsyMKi7^DHxV&cPG{TY?f)aZBAqG%|D-pD3_KXk!>N#F(Tal|AT z1TApOBq(I+9XKWiMnWhaiU9?j!@px_pwwtO8HPKydO?G!ZZmRmuDT0Nvht4OR`Y!QAXfsEZ&pN*{B zEtKldJ~g?}5rboCj@DyLEQG=`+!qU8PD%Hu%Ei8C^cnm#TRizp$;hqvFcy4i5j(_z zS{7ATqS=c5;-EE*!pU(Es`&e++=MBdrD3gUM2HLszj#x(cY$tr>)f+->mcDgo{uB; zRS^Cg2c1||4N6lXA}EVC`$B41byrY+BzZ3vVV{%TFrBM~f;>L%{H*t}KAru>Ux0Z( z@fZ-lP|9)lRDx=B22CYkpNi(wh_0@r_Dmzrdihq2p9U>p9Il)OU0MECET0DLY_@Hs z+*eudNrUB&+5>2q1_K}f2TTVyO$Psze%l~bG$=e4i^E{4G2)ovjq%Jhdbm*BlxuvI zZQ^ZJ?l%=umikm|Hz}>pM<1nj@)rDgI=DMH+>|pu0NH#1-0r~BJp6k)!L9r1gKz_wqQUa5kkdV3YRAWNh=m@p@OWL_>;ewQVhjs zR4|Xnh(AI8U$|=q`~|}>btc?!xBM@mRdGs%F{!L6X^+2f!7Nb2d)zmRW_}f3nFYPr zhZ<}#o2a9{wYXt6v^GtDUh*p*pACK4)5~a<1QXavJ;o)$C>EKAr;{L^WmcUy|HVH35O;5H@xAY@@Iw-DepxGigTj4I%5hZE-|Kfz6Bc=K!Ezr z|B1cDL!p-pBgVZVZn>i|-&JFZPbJfYj9Um{0X=BrrSz({ZA2A65Q8*jM3fxpsziM> z9khYul1+4?!c^Z~mB#l|*5c)b&|SLoyr9hkMG@~)!K4Sdwwrn9+Wgbh%Sr#Fir8rp zwC$c?LU&#a_-`1cy1$4=qH&Fw0Qd&Rz1$XIQv%4wEAT)3d4tbtQXqF1$hYQW(R$ z@^JN1_={z1!k9GJ5s-XY62ijzROr;gVe|13g)fIJ2oje?+UluU5#E(4!|jOY%HN|a zWjDz!7HZQ8AMnh6pu^3fz=VyqL;ze3cG;Jp-sg21ERZFXHG%+xG^VFwVpT zQV|!p!L91<#*%h8ZW*opxmdUi0-fTXMzy)0(nv>4y05J=sE%*MhGo#jttdy7C4A)T zUhSPSAo{CeNk7yrc&P~q2tSyE;Thn;cIDvg41y>>wSF=9?yWzY-J9<%7Avs z*J&`qhDw^zMUp1#2t5Z#*`=SPnJ`e&teq)os_6-uC25`%NSf{8lE!YFq^YA0IMJ^) z{hH7t2(3*GhJ6NkENNF$r|4X1yr7p{oF$0Psvy2zBRr~zm%?AhS1sVD3G=AZ2)KDU zY-c_jvEK^9{MzQ=+!Zjh{f&(Y!bYC7&G(VlHqrpoyROX-s(--5Q;giC6Lt6T^Oc-0j?(N5ps>Te-j+5eJ-ikWE6vDfkLx-~Xd z3iTS>eo9Rs#|h|Q$=ie`-+_{?--O=Z5jgv9Q{mw6z!KQC8vH7Y*f*nVab6Y-Xj}D{ z^4vdakD=5sNwN=+=psUc;klt34ZrB1{b-2%Ncym}lvJnjc@~USI{iy2ne^_{#(YPV z%Zd%O!m{m^DxiZ?MB!I#z27`>%yWfVFu1d(d*!>w7{mW)}ARfetzFD;$l` zlEG}8vmSKt7K_%y8q?_)!!KgQ1{m7$#6!vB8NZasNY%oZ7v}Fmgh6*~y%E}g3j1z^P?o#_zuQQM{wci9k-06&OnheX@Zu364@5_@+qzQaQ!5vUA|SVK z9DO4T0$cbKPvj7_FKocaInWV`3R`c2iNI$4fayPikNN5QDSIJ*1OD<3KJL;Ie)ZfRFELFKh*2{|20wM@#6%I^2*4mth6Y_zBd^|NFw9e}Z`ctx?)as8{h? z9JQ6uq^|2QWh+c@xdeeF5z!_Re}{F0v#ul@`zoy-W1(@Ez+pQ<%4=^H>L zT5KoK^!Hlqu${2n5jc7~Y=u+EcEC0>%|?>yZp6JiKndSrzRo#@ymWk_x@uNvpRfI`1Ncwlj9#1)g2}&U5z1oC{PKsf19z@~1QlDbzlP z68$HDr;Bu+8#$_^>xHODdjfuDP=l*?!8c%zwY!MH4Chh4n`Awg)}VSf%wkWnamQ|0 zN?mHd2gZPeI!F!iv#x2?(30_G5d&D<5u|NJ|ZQFWZbqNav{Gk zEFT_&(}p{I^K(v!xHQ7+a%BBoqBKGekluh2mmPo^$#GfKfOOJ4Yk1aXzZFd8L5*Zj zr#AhEi9FcErzfbU@Y50$sUxVdH;c;EdG+nDqu-MfCo3pMf7I1S1wcn_rfp$3eAR+fxaqB^7>(+jQN^NYfN8M+z zA&n>Q7i?dR{~ja~&mBE}fmLj978d*h-Q_dC*M2Z4du8FPUkLB(jeQOo5&f(~5X{W8 z@cbe0Z}sszsw~PUUAgUcBfn0PLKEr@Z4$%7FRnq?LRic$eutY1p+mEowc!E0 zh-0S^5~IVz8Qv}gPkHa}RWbU=A=zksm{!d%=zkbmxGug*iL$*n{fCuCZ%Tb+NEn9W z4uezA)o19le`;3#3%l zQ;!9QL4uX|*I}Zc{jvTqbg}z^PlqVpt~XrByiwaikD4Rk$}+R?>m#&L@5!yYH~q zQJ9*%{=l(fS!v9G$jfc#BGmIEo_ZhjK zY)tW~*%Nsvy~JQ5tgpfLMc{0D^|Ueo(sQ&Hj~)Y6i_~vZ$7E9>i9VJ3B)hC6jshjdREEpf zqU<>3H(QPB-w9J;i8oR#gH(|mGw;!w@u@df(Y?A?6k6J&VgIKj%; z@9@@f2scgoO?4GJo*-(BK;8)g853~f326T1*x$ri1Z8IvtTOT~Kk=JK{wB&O-t1Gn zw&m^c_vLD`rqT;^5Rq%skewgIJn-kWCOF=XF|Urcn{1xG*>FcAB)HZ93bD!=$P=Qt5iQ&Z9$(9zDT`F2GY#sJ4{gRwjLTFQwNT#54R-`dF|mNkF{pLgPbKtDc3I8RB3EB`Q@3BMfqHWd^+ z!rw-&eVAZ02BdFi4A5d#aWWmjC7VbMCQ)#U5?V$GEp&pbTA)Lv6;UM)Je$v$5o*(> z7KX#0Jj!>>?mMJ$o%f|WN^NW=oafPDW26b*K4X~V?VM$<@@s6_THZ367tzMskCk6F z_zZH6dM!y_yu&e&e41yZeu_TS$;ohv2hR>NyI_cRqoSNkUr3TSPud5LHKz0#qst3{ zBRoJ(2*#wB8_g*n@<~qr%^=#C)f#yEF|gm5#6~omJf^(b7}pJUHN~0F9c1=^&Tj#0 zeg$h*u@VixLL@t|5~Io>`-`;JZ{+rwi-R139K)bnkFKUo4uEQCEq^2pC;6L(UT&l} zBkVU7G-TFTOhSB)fa~u>Ig;Z*fyOd?QWIrjDfcTPeEc*=`oi^?FnN+$D)&t-o%s zI!@YZaOYceCrc5Fif<_$sbZDkg45t-b#9~7uU|sUx5}rPxcf9rb4V+Dsk2=j?PSAj zvz=3fNW%*BI|GW=KN#~3T`3#;F3B#ywnr z22{xfd}MXDQ@lN`()zvTMyYWY=>i?j7Tm=K>4@**2_kH#M3gm*NP7{o^@X$af}pu$ zn)pt2{k%_(?x%-jq}ff9b$e-6ZV>H4BdE@oG-5h^gVO3xI!Q>mjYSG2zpR54Qed|w zoo-E_oqC|{h$suXGjEEwhfJn>P1Pzp8sIx#n^Hx#P8K@7@%reMnHYB#T#`e!y^M^@ zj53?z?af_`mu-CE9ATbHmc$NoE;ovh=PTO!NDJko@UtpX!Yx^}BG~54Xc)rVFU18q zM>$CPieMXEZVdG2am+8!*RFzGNa%87X+sa-aiJPvU@4E84q6_*!Jg=XZ6v=yU2dX} z1L$~MQ+NjSq>#uRdBg>#tA*O{R^U&+K}UHxN~LyCw+e6l1}M+tt)(A z``f}ld`l$y1rB0!ng`qZyn#Eb(Cv3(^jYGN--(rBk%=+C6CvTd0yBPx4#}@pQhI7a zP?X#xhh)dP++ylEuz@!&#{@+ zyv&nS=C!6c?jTW@dkX&MVHeT5DlU+lY<^Y_G5t%@$g6O01$ZUD{YP{N2GKKuj0)D& ziV<9y>4h}aUhGYZC}}^u^tWEAN}F$*p^FI*yPa@%`Gs)}iEZ*D&einu@+B**Vt?!S z=;EmIhfyKqB#hVRZ{28&zJmu+*RNbGpQ64li}q2d9W`RJQl*{0we}2FDeb$iC5f(` zF`2y9p=79ajm-3Q8M1T4LaWZgF6W?imkBHAbYy;7pKNorjXF0-ATvliz7j)Cg#|AH z0s^{8EhUNvD;}w>F|;`tq};w7SDgb_F?YG>=@U^l$3(e#ITnz6P)jEQK^fnY(fII>6C^TvSs=Srj2aw}s{8~19#y##v?-{0TkTdm8Y+AiDW&juebwADEKlx5eAW6*4zL`QtJ?_!kUe zr?XIY36`+SYjMRTsA5$saO~d@$6TneziHNXtUw~1yW31%3qib`D5Xn&eLD8P4BncO z42mE#AZb@GaYCZ9g*baMOFXTg>#$OSblwBE2ywofw4RQ?2d4w8nlo%*_8YIkE*>7UHn_x9@L&O@7l zn1PnppryQ(u_;Rs{jWiP_HG%@y#^kv!!rEw8u+?;E~6$%N});X&*DvDju3faS;;x9 zz6O%}J^q<`b?Q8=`pb=hPkMhhm!aZ15zuAW^ExPO>WhrW#5tab7&dX&p-1xVG`WTe zRb)V@E`C3v_dlw;jfoENMCC6G&L-sRp0u?IXB;g+bvng{7SXYB<{z#*ULDMom1$?g z&qP>gD|(2`tRv}Lb`33#j?bK)c4#>L-dA}{)VgIwMIqY2{wk*&Hsy1sR zB}n6~z`)0h-b0$1>69iTmYReoE{l-GnosONZW-yKb~=(^KJP<$~-zbTUo& zm2=6IYcoJHb|8zF&!nxDjVdNlTSI!+ard{Ob)*w0IS4ZA7bLgw=oAI)o@*JsGThn65L8HJ{+7Jlg;t(kV;ao5wuHqw)!zD+6p2)6OUbyLf?r125Ia0_(hBsr13L5G zmCN$4=yWSQF=!BO`}1~L5z=HDYGVAK)3&wqy> zLD%~*-FL^58|=2F!QUjJeNX1TXy}AyU1nKnXP#I4&Cw897&m9=56v>SrM_N;`S+n2 zDNvoh4~cB&672pDeB*j_+49sc9X)8Fc03=FOE$OHqsZxty|x1$_y@MJvcvfG1JK!o zFQNI7{5z%X_z0D&aMuI4$=0pHl@CcNwK50qJcNbpT^dF{0*#eLS>jO3Y=y-I{bJnx z2<9-E3wl4M7N;!1uO5SfK+F8cM24p=$GpeT#ns<_^iwre*QV!K$G(uF~OVza*EqbLm`&9r#_F_Yq;tX!?Dvs2!U^h$Ts+9)@Zd+{R<}#V z_aET{lkLU&2I$`UI$y4_DxU;#!Y&Ce^H4DG5GPmuO2J_Un9W=lBB|5IN*noS^&f#v zsn_w~!;;3_JpG!K??*B{%UbmPJJz0klY(u5xw8d}us<*_HYf!XfT@@!1-Aej(%g?{ zCwJI#xGHfqw03)#^obi8Z(It5n86}ezU>0NhS?EI4nXvCeW}V0{{H1LN8sl{)pP9bvO%f7Lq>_!cLWnUT zQ7#$x((7cC@Toj1j0}VAs*Rq3`k5#c2emQiX3E;bSR7!=+Okf`m}JU&smk8d`FEy- zT-x4#TPx2uQW&CjdK&q-7ec1iDefqkzeOk)4Y`^7u<)w+_`sC)v#2DNgEiYmsP|v1#=hoM+BP(Z@f{iG7i?h=#|9M%@>}YE_HUF+|Qr zvc-!EH_KTYU|kmB84I?OIW5BBmh8JW`)Al`a-9~4<}^(8C7aAGQm^E8O*p&yQT{o0 zJ9i#2=xnZB=r<3otmwj;eGBoC6+0}qn@4phyUxQMB285PWq6i0QozdjI#c3V*oH5k zA0f-moCt|rEbgm~EL;|4<{Is67HnNM$UtHcn>399R?Nq4)~ws4y>p4jlNsTeq^?k$ zm8mBrok_TyDvvZWx)RKfrS?0(9IOf)EVnyYa?9Bm%m1dpQVYkz4Lml;l4K1{d*4#| zfk(+L6-LDd3(Nic50Xsrnl%f6XDHgR0Cs8t_OxN4wz8^P-vw!M6K98KtX131Md6$N-)c7ezt#MJ<87G=GVyy`TFH?Mu*{Zq@lHER z)yQg@a~)Na7FrW}f&=;LN0D>~l=e#aInx^^P(BYOJ2um5$pRWPRi7g5-8qovd=b-F~CK%z9aBM;a;hnXf8q&XIvT67%|5$$V**}YvmquDtMOyks zKFY5zc`B>TnB#AH!}Od9T$_U~4oq^|F^3w+UDk<9VHuoLrfuOsWsmZXt^8;caZc^TVYE42%64c6#IaA(fCDpLB7;a*ITN@5HH|5IUcl zBRZ%{6lD|dkYbmpbJ3@`$r4LkqDmB#A!I;TewR4KcVYfs!mR3aM5;O zs$LTX@+Sz!7IcDdlIU&(jhwE^h|pNji*j@l9(QJK2lyKE*c;&d&L$H+meZU?TgXm74|Nd2Et1g6g(7inInC({QK@n`tpx?x9iZnRW-Bb73w7 ziT-h65*xP}EnQhppQS@QG{kwN))1fYPNWI9{JSA5IWYUF>6w9aV#Ik$6=5)F9>%*e zkFU4Q7Cm(O{b_zcWV7<8*=oH>m7Y7Nt{$`|q#X>XAXBxZ#x+O|`iXvx<$)&Z>@rbY z9PfsB9{HKaWE5AXY{qA<%$Y^aAsar{+BS-hbA?)D<*kMA9ka1x3tFXfNkQ zd4-G)9vU~|!OWpwo!+3%jfv3D`P?^U0LHs9rzu5z#gHQm)eAnxg*-&+nr4aDiBWPn zDsFaSTvC$_9^s^llg1WFUTxGez0S)w!mDi>`)~LUQ*Bv39vV3BWpQok>uUaWL0xEXLFW0a?3-sJB%v(#S#AC-pCM{iNjwBcxlRlG)0B~b26Yl%bZ7p}1KN3L;^;As zH)Ncc%6x?I&{^2LHS0x+I$ySC{uzn?=&lTOvsR1(Q0RS&I!XZt9J>mixbVyCXrb?lf9`9 zx%ITsc_2AGyZ4j>3nJA?tVhEqP6#GV<{GZYOu{}6OO)4-i*`)6!3a|vjh$6pK28(d zdjk)s{=%C|)^hwG$D^D11PcmjKUr%Bo2sK6{7j_Mfi#~FW>P6W5Tp#V2PH2NP93)# zSk))%jP`Okzs8VP{#s4CtKr9vD|GvZ_R)V8p$^GXPjIlViAubpkIu0Uc=*L`~UN_6>;23t?t9mEpoei+=oLctvEAirn1jGGOAX1*!j-n-|T3f zX?Pe(ek7VBuz(QX=USKpb#%5D;M3btaheDrgyFZ%@|MNkJKZc}bj3 z+WEXgk?>#!W_dEnebu5TI$fn9C`acR6lDSy%1LYO+68h)YWKitAy#@aSLLW=wbGQB z-s)3!V6~9Sl`BUie$=^{sP#3?@BN{)L`yH`?|gj5_Wu52c3USmD?*O4r#PkE|3J1B zgS?n$#J(AcZOGU;s*RJIob*|vCOMT=eo#I>Ci*N7C-ghp&4fj=zLNt>U?%r$tKpll zG}458C<9@L^K8$t>!sw^BuE86^ZCr*I0H{nxjuC>csK2X#W2#F;4weT6O}GG zI%dAmS+G~C76sK(;rHfamM@VgPAhT0FVT{367g?ew#30>VU*cI=N~}%ZlN*Vp7|Kp zmW8p6^YKty7UcI8pH9`_M74*h+QWXt5`lbLhgh<7f+#0$>1@p+^zVu6(+x3`{c#Ih zv}3K_*9PTCHWTqi%a@%&AecPrY#BR@N#pxvG8yJ)75y(cIcY0PZ>iIqKR1~&Lp zqrRMhE!wk|9o_gkPzehM`1_fH3lF$OsOBULvQ~R!s0Vq9j({9+IhQ^riv<$uB|yI! zIJrFwvI^z}OBF8AZ3gZpW#GYWc*IlYTyUpK*G^p#Mq1nx)-$Qp3!d_Qqq?wQKzpj> zF%OWi#WA;E!XTTxwi$VYJt4+eiNh_bgoLNQ&|(I9c3_>XY(G^Z&cF#BSg_ScK2YQ? z7TzV|?hZ_2#zksbuduEI0m##d=pMlOHVZtuqlBz1EWrGZD`_fB*hLqI&ck^Dj2se- z!m|OaJ114lRP4DJo*2yNjyT;DSQ(GRubjcA#p7%>`jWGZ z$Xo_)Cya)6VxtJ0N&GsPXho2+O}w{vcYboGWg5ytXePXjXzTj~-t__R2y-@t=REMA zyMwzgl90DhD!tk3T-Jg!@J5u}S&%h%c*%XHjJlPz6*KJ($5nt9TPfW*7o!E5S96}%dq$Rl}+(V<> zJRJ{oVqdfyZ!FWAUs+)aUp5B9$dQcB(^D-j(mC0*4AcZJrf***pt>{Dv^+nZN_V^Z zuytK)tB3BRtsWcd&bt))SwhToT-BNFVDsi+P#3nkyX$ndzvuS;%+aQVGgz-O)H;$Ih-?PUls!4372`r(S?#H8P5bNM751O4ejMDn53Qpmjt}KnkPs7RGi09RB8d`N{>)C~AxUDC@u$r!_GMN^#)eeDW9?ZPmUrgnLL063LCbu*&nXeF%H~1UT zk?842(qCV8dn)?%WIb8`=@{3Od0R$LwSZE;0r2x8%<0M8+Kwhe1ujdXY8rjWNDd6% zb7m9h`B+1|;cO)lft%y;PEQu-6grhs60#ym1IkoyC317QbP@XYVl9US(YSp0Kz2QY ziGclS93`W#l#+WqTFYA+p=aFjR80(MUm5zDFgQ_0((+3Fk9VpmfI83FIM) z;0WQ%^LITpxj|f{`S_t1YtgnM0d7sBRLb8H=$Z;zURB1>>4Y90Mv?nv9(0o@e6^W&B+eo>#Vqn>ck8}?> zzY;S7U_w0FY3Y#Kn26z8*4@VMBVoitJv8AB2JO~3+@NJqta30mXqnE!cJEff+nTF1O?{ig+K6V3Icm@pY4|4qWxIs&M|M|?(C){M@gv#%o+ z-#9_gD~_ycs0c=L)R&LH4^5hV&SLEwgXpLXic|MV;b65at0A(EI}r~}Nj*MC^?WK( zSBV}UiS-p9&#hI}9v_t}<8VQ5=9?^$=`v9e9Gxex(<>WfeQxrr49J--7or&FLFw9< zrqT0PSw=&dmZwR3`9EnWyS8d7wM#Oc0@iWSIwvYtQY=vSnUc9UOqbcG*i-=XIBK1z zzmT@HAuX5}5mJMmeVCg=5Opzyx~iu~t+&&@iN%OMtdm#LjVKrw?QG!>qIsfrTu9Z8 z)RT8JtV&qJfS!k?7&Ds1H=2*1Z7G4Q*MYex;TQkIhLaT5H>3yZX!oiLLRUDTwHWxn)v zFJ0+mJW5vbjD*2neMQSHxiRnwnx*kzdbJ^BvH(BF$~BTu6|J^WZH>i^ANCUp(zD@99{`wEt9{EC4);Mjik~!w0&k9o|M8x<8sc3W#SsOG=O;B3PI0` z=a@U1tLDxn-L2k&wr-BaLHM1g3tt#ZG*^iIXFgU*kExQL17#xnWN`*^<|R6i3$4*K z;D_nS8P){!2tJ&(m$%9~$9C(@vwdJ6M?2Mi?rqk%CFW|hFAd?7VlgX}xg_u6^?)>W zv5=E3WJL!hIrlTq6IOe-m$%3~sfVyO{P-UCwo=bAgq6ZJsO(I{s1mN^zjU?ESEdn=YEHvgz$ z`-UAwFns|o=*xNx5sf>olDNEQS9eXI>j9TYWRpH8mNJBlG{_T1=;dNmS@|~DED@VS6ao&^6izDv1lH~6l`29`i8MLtrBN-4VTU@@}&z( z^g7#xrG9^8{^}D+$La*ApHUdxkBtSEI|DcMXZP94DY$e1TjUlyg{r0ro&E>2S!gBD z;llSpqen9tutR4GmO5uQkB;9b=@BtEENfjYsLz zl{fjQ+wuhd57@UxpHQWz%8*?#r1viH? zm+o_TA!d%k>!Eg}c}9t*@QAXf2C^NZ&OkH|a!LA+ycI@P5FN=OKYvW9#JX@6*lY~V z-EHNq7=jhDYYj%+sA33qi(u;HG|xwiY5SBVE|!~RWhnl?w!Q?a$zyvwbB7>HSjD&@ zCLbY&RT8(LAP_-OK?D?0kxf=bKt*d?t3U-es-ixxZLL2*tZQ5K*`}@5;({w$r7mdI zs$HH{+p1NoR>=QOu=bsI{yFD6ndQ!YXXehGd+*fvPNT_FQP9>wdzwVfG`eO{>OkSK zl6+w=gMSpk!NSAh|2#J(f3<4ip0n*ced|?axjlMOx~l|0lC}l`0)cPsKdTGgzq%1* zwobA=j$c9Ge7u_o-GY2Xd=(cZ*-x{kP>T>D1OBqdDTYLFMP5Cop*{(G+#2Qxt()dw zBG;8Me-$(2V_p*B@Sg?vUJ`hE?-RIJC2kdIJ-)0aGHl5lVFJ7PG^|_2{4-dWe7u|l z+Q=rG-=u($rWXp+<`W5a`2x!nFUEFY*;Ub>g4tgV`Lh&cN2ctx+N`|X%E2$FKKzAg zb2Iz403*gh5BZ}!Vs~KrIPkU8&ZJZ7sPr;yPlKYOy=r6*x~{#p|pz1hqo1W^V<|X>o(`%`tcwXxt@*(ox?7w$XWXC z*P&lB^osguF8fqW_N(amc-_xzxcN=z=R3VIq<9%OV(K= z%7qrHc!xe2UeuPPI2RTtTCsB$alrdhD~>QrKGsZt?(j4pcTRvo(k_wI6r`b~VG3!S zcpHgceR?hhX~;4QEwO|0P@V!`Lv}X4F%f#=%@jcBM(TbOq1^GQqKA8lk;EMu0JQ<4Y(zhDi9e3CMABLntPrsC{Gn2Q{97?exL9PzAeHKKBL_cDg$&Yza+yN?B`?4MQ(%NPy7=z#n%278yY0%Y z_rbySnurYg&eJ}&ivD-eccTsKr_g<3Z7yD!0s~-mF1n>b*RTVkL+#Wg+1G3+l;~nB zkZ#0A2ea;?A>b_6MvT^u9VSfWmFH5({FW+vp?zU+mNV*|oHU|;Wd-uNX$O9R)9nQ?h8yOG*nfWMX!h9fsfZ9yK zj?KqEGoct<@-aV)4mXxO+?oYL{O{*chSkm0ABQ>b2qYTep77hbT?x1yDQuMOkUADy znM}0>ou?85?Y?yrzn|GoylI0i*i|T}+SL4>gPW!jOGC2-A5Mi~a54u6WfQ~vKn|Xp zLFiDH4TUfx4}Z&s;?7Rl^ejkgf=u;DY60ocAIvr%OLD*ij@V;W4vgv+vFY#C`3@Cw zTya^gylQi9Ob*`8p>CZXzS!nGU>nhvKs=Vbj)Q_^#-O+l#;y0|ChD)&3uUDe9GLJv!gUTk6(nK_}G z$+1~DqYzB&4DKqVF$~4~B6R#z^q4^`HEL)636 zMen+g)>mqA{XDq2aC8<0oC=_`Nff)3Ms6ViCOqGEc)D3VXFEIu7Hh*!cX;SLW2!A< zCxnljb;d(i*`elpbaHPJK_rV8Med*5kL&6BN-v7BQ(I3}wBK}`XX(Ube)>8bWss7G zjc-DJz*s^GaW{QKNI!(APXi%^)IwXqJzB&lhvYprf$UT$Rc~!3j++l-)fpXV^eV&C zHp(amsa_)tdl-EMKQfs?Hk8u;To=6zc^MQ(IR<9##Ps6nf!KeT9%UX9PZkns~GUa?rQ#|<} zkX{k9YgayWa8=W-m4cN{p|nE%p>p?k(^t};)+U0gN%0ktrEV1cP8UURZt2y)6jb{EyX46IBPNdrdm&^ zRyNpPCe?Ei03iaOBy8ve7I8#nBJtO+Qq5&cz>$TNiEewj&sCnXkj4HwMFR=MMu^_6 zaFf~9nAs@7bokYs4*;akoKDRH}uI-J=X-_IwURKFUbH_T1giVL9;E@$1rdGQNy;g!5 zZcoBXDJ4-A<{VJHVaN{H*B@CPQO4189bRq%M zgOC3(cB2-{MS}2tKCLRbf;GgR$+^f#CEUg(j6eclICZ+k1SqWxfS2k?sj20k{?yySft#Gow| z4{o6Qo6_yrz5!-HOR9KdPSx14T@V`=YGt(lR6h)3^5^YZcPq#H<7BM;fN0G7oABrd zM6Yc~#@io&k)B~tZzK{vWCDh7gx#Q?fDbpqh^}2k_u6)nDL-IRKzBnBGkM9`>1jCj z|DYMJCZks^OS9M-F(ivl)E56p74yos}j>{rDFFVA>qSrjZfv%`gc1OhCI2VV+8} z+dD$pR%3TkRR86hDOETRF2ZlN``?>OAJ1$z2C9!J1-kw@=ZWYt@|BW}<1GmCPXO}B&w3A1>T=A`GYQ1Q_wH19;Z5e;MYPxGHeE=C zyN}1Tk4Z?Vqyeiwrv8334ljI6EEk_7^V5%MGKVh{?bSt&9!eYGV&RsWRmKELxkz~E zqC~jMtw0IJOmZ&}?&$$m_nYJJOOj=FD-dC$)ru%XvzC-)bH<_DZg>O-(y`MXXtK?q z%0+C$mOXF{EaPzZzv*ytGXd@P!nDY0(JmqCuA;n`T0JCDNA4=CJJQ;Ux2e;lKAnoP9PGF*+-|Og&tMd|Ct#GBczk;EMl&1(Sf7b`UqS(7%dzE4*uWlP@jhBfzbD%#`ykzM+A5WC zPFWT!|27_7_XCZ`82oBKiJHF1z)Slfy?d`QRHuL^p;%Fyamg_2(&}FGACmFC>lqmT z6%=>%i@y~9$c{a^|9hE=sjg86Z}=f0D;_U=MN_0ij&B@*Va^p9l*g~a>Yfw(A`VX- zfNz{OwH|Z#JgyLn*oE=91R^y%hYU#Cpc!oFgz5 zYUOz42n;pogvPqe*_DW|fJQq@cntZ!rvHpBbPkqV!hi9QQOP7}K<*c$)gD`qqnf|~ zmq+7*CL&LI#ADb|&<$}FWhqR<37u>sXDrhOL6usjMvHjtu}+pyuq-h_W=bF%|D>X9 zBVc{Y)vGMzk;P-}QCgs$kHG^+X~B%eKaYZT;4HCJ6O~zRsl0zlKixv)V&|scFA>pk zMf61&^EXALl#=a2tNAZef{mhqT^NH&$6&mN)M}-=rPgaudG~y-Aw~Y^Jnlb6$0^TP zymJh84|IQ-yV_FON_pzF7PfGD{kyl?MbllzejO%#^AZ*#5$fv zS5(KL-0RDwU_V1WI}TM>R4HQEQ#p0&&p(3 z39?%Wq}dotU{a=BUu%i1wN!4uq;MuNxpPl8dfpGJ)tNS!ShL8;c&?}5A`dq8>>qND zZas7f>}VV=KSiVTbsTOx1r;8xqY3Wm&6_zEVQQ^o(Zk>#yvnpWdgv@?Fut ze(iGc&lZa8i5_oQKC5I&seeG(Yi{&tr|7Xa;_yH-^=@$--ff1^F27s1W@mkSThmIB z180hf7b>BngYdU8kW-*Tzd?xT6~{(Qq$4f3vkM*N`e-eIBo#rV(E| z3LVbC$e!h+sO0&?TNDpq->!SQTfBfBL6ljEEf$@Dci{Dr*meeD!EH2-{sz2s_M(Nl zv}a)FzCor(I_&%_klycm8R{;cblS9@Sw>;aHz2vhit7GNA&$L*hrWRslQ)R&jstx` zyE?LMNE9o{BtKaWVCzIgY?nShU5R2@(*YHxP#fD=o&X_wjC=#yV(Hi-{I6)JQbL^) znw-`3xa=$~@Z&GxM`xj@?O8%4*;YJr7BmYlkE9e;a+!R>d99%b-OW}epVvxmk$=1( zwfCs*e{AAhfJ{I>{ES3L>CcZOpOB_H##wQD|j#FBL2gidrGDTiA4(V zm{ea6U9XOb5(g=%#$LKEtdjs!INvC8JKJ8Xi!Z3z-~SL}BCw}qJ;!O8K_p&MGcR@7 zYrZ3N@$8wv6On2pOr_|Qbjc-?0JXf!u^0(m?vYrUu zu_#@FByf(!*Dlfgw28%ymxzV=+i3HnOC)#@@?MO{M=sO4_R^|)Xd?*w_4&kW`Gc(y zF{hn-UORiXw2IU*W19}PP-F&0-e=V@=CsQ|Y!H`GSa5}i=vyPv^E=3e<0Em=cci#9 zdK6B)O610XQMl_W_`CRx+PO<|w;ANFrRh~P67O6EZzr!&Re#Zrd6w{Rk=)$l8e}mj z*@g?Q)A`jn0zbJ98rOkh6iMdskktZwSv3A|9eixhQOWx*d>(-jPhpkqE}B=3+wkI32-Gi*sP}ueWsQxZSCy-b4zIi4j@aY> z+}!y$lVYcGucP6Jr6s^meaF&rnr?3WqBozz{?DKV)}KSW=a2(uhhp(_s#w!dT>qRF zQojiN`8mu3#|X^$3ogQia5TOE|E?`2YbO)qNYc-QA90Hvx%i5^28kxer{QaSyKH!nGm0~~OE8%J$9szz68pCl5=kuX9 z9DQu~1(+6&FKqZ0x_M}j^K&pb3}3V5iOdI2+H!-B4V{*abA?&d8?WADCP4zV9U-4e z)~KwNZn}h-)t$HxgU%7=7(4zKgW;hV?Z6S-Lh-r-AI`o{F%EF%lWjFr)Vv88{~_qKMj z{}Q=h`tI3>^^y>r?ZQLczX>6q9n-D$ z?QCV$-q?l*TzF4-97fN?@ol+>22+2MqOjo5k_n0q#^=p7A?Mx_#%k>XZ*NqVb$YP) z_4yAUy2$K$UG3Xx=sf)oMY5nqHYCJ46vORhorby!3n>&f@MRcbP@Pew3ib=?DKUKr z-f`s;)DA{xH?GkgDf&Ccvjg1r4lM!tM2k94)K=7$D1cxG^CUNZm9aGQpw7I7$s_F& zyh72r3ttEOL-E5d{A0Mk4U?6;FFhuQiQuQqb4~SyR2bs-EK9Mm$bnC`R zV-@4O@ukYyqRF}hg^j^eZZZMgUYmH6C;rxr$1B{280rEP(F)s{(+hEAcRs{lwp|k; z2|a^KLVF=hcknN|B?(ioxkkz+OmPiNwN+#uh|MzMC*67U!dwwZVe0_J4{?9{OTABAVC($bXV~f3RXMoLei8&0$`8{|Myc3T1dhjHe7mkrV`D-vK z-27!vPK(^8LD=HShbVHz7%V5=etFFx?B0uO+$M>Te<%{y?Kq|v@9h;Qf=!2>DI4r* z0Us%RiH9C2n`lb2;UT!Z7gs^qVEm{Tq1Vhoc(NA{7&SxGDopV!#5ggXNHNbzVSDGb ztP!%|4@ntClA4*6DU-k5qO5;TuHl)HQQGby7~#bOx{MXU zzE<|St(@*_;}pz31k1g6&w(l$DA7ZDd%9&1{C8Ui8G9kRN&n0eu(zk=>&AwN)lCo+v~s$I`6h#tBIQc=#%EJJNAXNd!_K*c9OLjWF9(O_n5M}wOC z2PJk?L@EE&A|3Riv;Vs&<+Mm9PimJF>4H|ekLWz`P}nTHVm9b+buWVi!`(;box zJ=*T8peL0BJoNo2`ZOCXq6xS!`OdIG!lxikqIj3giphjM^@%gMcsAhv3H(Ol&Rw+~ zl@PlQX{#6+8DPt1_Xgo3iHAX9f9&VY=c=C#pq!+DO#QF)yy(B!W8u}`X(y&q{W`h< zc`yJ^dh^K;9)^81+yp^kI9`Q;GJs9+V0vD^1tKoa3C><$)O4hYx~N1M!VM{GHBQ ztewGSt#nlpYD0$*LqF`H<1<_riwJ{SDIHV>*sw(d5q10oRQAU#Umgoz3?k(O{t37Z z#7sY~2b+Po){pn;{9Kg&c}?}cFh{95lGJUV48Svfyer%vfdBF18t)$c37`!~lS85R zXftijW1b>pcp{Z$XHxfI*9TybKkpxMR^+7XB~+0#(VZ;Dx!%m4%LR3#1!!>3& zyq_JjHkVMei_|>TcQ-pc0N?lLemx%cBftm$d9k?2H!*NX^G_t0Pu#ne>|Q_o-kj~=yU|az21;_hgVE`fAYowGGz>{6KiHu3) zVI%Pd=dsQG@L2$#>tZW<>lzS4n>6}D^Kd~R9}R;B;Hf~aaSjxP2yCMUe4)p-K;Fys zpqRtSEzd}y{%4EqQ2_b{aZmVAk1;{K4i@O~ZV(l^YCgL6 z9}atiu=8M^39iF&?qHq<%fieT2lGP!!}R!G7;Ue+s7YZwu}^wm%0&MQO~QEBYmLOw znksUY3O&STQALMXMs@boxaljFHQ&}(e@8JNSYCK zrutI$TtG^Nnax>>tl=jtv}cDo$JDWZ2b;eO=X4CP1mLuEz5uf$`Em#h#s`ty%WH3d z$U#98uh~or7DcHES*{ZTMli2n3^dUocM;)nPIm*0k<2|9(@i`Jp7q7UCfeA~PQXVd zLWs+KF>)BM58Wl&rdVVw*CkBuH(6pkg+FFyenLb_Wa98C#st%_G+hEMsE5+oW)Wws z(Io`fd?&H`zSuj8&xFS9xH^glz=LLNjN((_cYpMW<|`nyFMb-$`@!A>^POlS*u1Wb z#?#_YmI`P#Ug_}Z49z<7T?)ccBX~8K{IPWe4~8v4=nz9_r0#G2Acps5u7d^m=O9cOMcJ(EXa0ES{=? z;D!KS8q$^`h&E+IqL+Uw>B!Bfj&}(^+Q~7F^?tW5#puK4mY1Z99Uig!dK4$|@pA z0u!72kgObE4-X7t#PNVan9DblfoUS zxTRK6XF0PRkyFdT&^C|`dR|;fbT)0F2VcTFk^6vf4=2*knLPWf5sFTMBIa{nJUW>V zw7o&J-2Lqcsk95caSDA?c_6IuHK(NV6lS}Nm|0uv@v|vB8e-0v+otg84AOkev~nrI zM@A&z6i${g3T9re`(^iu8vF8R2T6GNq1yE{+)}#-+CR-c*~##)YPKPMHv36LNou+NjzH8_;nOAP$Mmrx z>i5E14jOfdeo2f%1~KPmL729yyL4!%AwWZD^KKsksO;LTkk$G2#nIVZ8+=ft@zv8C zUv$8;2?1jy35hNiaEfgGf4p^ip}T0(kmez2A+qv5SeH#?yv2_Ist@V(`e51=d$Zjl zmwd&{FDzNMA@oAPpr2Jc^UA;Vu4(bE(A`|^d#k#ew!0HC0ofG|L6ZFoOE5bw z!05Rm84_U)5%Qk!gL7bVh_CLV;Tb{>1;jh{~EL*0i+1g8I<#2HMr%ZNh1 z<&E+}o&t-!F};whA%FVpf;V!)e6odqcIm9boFZL*PG)w_ ztl7TS(EQTUlJwc7nWb}PTm55;XO*gQX3Z*|rSh3giN+_!stRVSii%5BG2_OKRZ+P3 zPwI%3$&!*{t&y2?GZz*VW@Z)UI624?b7q$m7tPL5l@=GP3X6;KR63t*Ux)t&eg*qq z8N3P`Su{7ZupnDCm#SG%T%;-}>L|`MCpR}|mTGo>@tnf!qCTantQ^&t@v*U@aY;#e zuWIrtqo^@Ss@%+i!klbX?%yq18?WzQ)YteTNoSXex@qrH@eOu%_6? zA}n)O-anmUwy)w{StkKcKXdQJ{8MM!(COY0pHDYm`4^vS>+DI}b2s{ge2IsHIc)>~ cnW-MVL7UZ^ng~XTY+imMgZcAGhL^to2VQ~qpa1{> delta 54137 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� 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�jiJr2+SSeQQD+?@_vJ@0#h7(e@ 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 wrote this file. As long as you retain + * this notice you can do whatever you want with this stuff. If we meet some day, + * and you think this stuff is worth it, you can buy me a beer in return. + * ---------------------------------------------------------------------------- + */ + +// FIXME: sprintf->snprintf everywhere. + +#include "osapi.h" +#include "user_interface.h" +#include "espconn.h" +#include "mem.h" +#include "limits.h" +#include "httpclient.h" + + +// Debug output. +#if 0 +#define PRINTF(...) os_printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +// Internal state. +typedef struct { + char * path; + int port; + char * post_data; + char * headers; + char * hostname; + char * buffer; + int buffer_size; + bool secure; + http_callback user_callback; +} request_args; + +static char * ICACHE_FLASH_ATTR esp_strdup(const char * str) +{ + if (str == NULL) { + return NULL; + } + char * new_str = (char *)os_malloc(os_strlen(str) + 1); // 1 for null character + if (new_str == NULL) { + os_printf("esp_strdup: malloc error"); + return NULL; + } + os_strcpy(new_str, str); + return new_str; +} + +static int ICACHE_FLASH_ATTR +esp_isupper(char c) +{ + return (c >= 'A' && c <= 'Z'); +} + +static int ICACHE_FLASH_ATTR +esp_isalpha(char c) +{ + return ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')); +} + + +static int ICACHE_FLASH_ATTR +esp_isspace(char c) +{ + return (c == ' ' || c == '\t' || c == '\n' || c == '\12'); +} + +static int ICACHE_FLASH_ATTR +esp_isdigit(char c) +{ + return (c >= '0' && c <= '9'); +} + +/* + * Convert a string to a long integer. + * + * Ignores `locale' stuff. Assumes that the upper and lower case + * alphabets and digits are each contiguous. + */ +static long ICACHE_FLASH_ATTR +esp_strtol(const char *nptr, char **endptr, int base) +{ + const char *s = nptr; + unsigned long acc; + int c; + unsigned long cutoff; + int neg = 0, any, cutlim; + + /* + * Skip white space and pick up leading +/- sign if any. + * If base is 0, allow 0x for hex and 0 for octal, else + * assume decimal; if base is already 16, allow 0x. + */ + do { + c = *s++; + } while (esp_isspace(c)); + if (c == '-') { + neg = 1; + c = *s++; + } else if (c == '+') + c = *s++; + if ((base == 0 || base == 16) && + c == '0' && (*s == 'x' || *s == 'X')) { + c = s[1]; + s += 2; + base = 16; + } else if ((base == 0 || base == 2) && + c == '0' && (*s == 'b' || *s == 'B')) { + c = s[1]; + s += 2; + base = 2; + } + if (base == 0) + base = c == '0' ? 8 : 10; + + /* + * Compute the cutoff value between legal numbers and illegal + * numbers. That is the largest legal value, divided by the + * base. An input number that is greater than this value, if + * followed by a legal input character, is too big. One that + * is equal to this value may be valid or not; the limit + * between valid and invalid numbers is then based on the last + * digit. For instance, if the range for longs is + * [-2147483648..2147483647] and the input base is 10, + * cutoff will be set to 214748364 and cutlim to either + * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated + * a value > 214748364, or equal but the next digit is > 7 (or 8), + * the number is too big, and we will return a range error. + * + * Set any if any `digits' consumed; make it negative to indicate + * overflow. + */ + cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX; + cutlim = cutoff % (unsigned long)base; + cutoff /= (unsigned long)base; + for (acc = 0, any = 0;; c = *s++) { + if (esp_isdigit(c)) + c -= '0'; + else if (esp_isalpha(c)) + c -= esp_isupper(c) ? 'A' - 10 : 'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) + any = -1; + else { + any = 1; + acc *= base; + acc += c; + } + } + if (any < 0) { + acc = neg ? LONG_MIN : LONG_MAX; +// errno = ERANGE; + } else if (neg) + acc = -acc; + if (endptr != 0) + *endptr = (char *)(any ? s - 1 : nptr); + return (acc); +} + +static int ICACHE_FLASH_ATTR chunked_decode(char * chunked, int size) +{ + char *src = chunked; + char *end = chunked + size; + int i, dst = 0; + + do + { + //[chunk-size] + i = esp_strtol(src, (char **) NULL, 16); + PRINTF("Chunk Size:%d\r\n", i); + if (i <= 0) + break; + //[chunk-size-end-ptr] + src = (char *)os_strstr(src, "\r\n") + 2; + //[chunk-data] + os_memmove(&chunked[dst], src, i); + src += i + 2; /* CRLF */ + dst += i; + } while (src < end); + + // + //footer CRLF + // + + /* decoded size */ + return dst; +} + +static void ICACHE_FLASH_ATTR receive_callback(void * arg, char * buf, unsigned short len) +{ + struct espconn * conn = (struct espconn *)arg; + request_args * req = (request_args *)conn->reverse; + + if (req->buffer == NULL) { + return; + } + + // Let's do the equivalent of a realloc(). + const int new_size = req->buffer_size + len; + char * new_buffer; + if (new_size > BUFFER_SIZE_MAX || NULL == (new_buffer = (char *)os_malloc(new_size))) { + os_printf("Response too long (%d)\n", new_size); + req->buffer[0] = '\0'; // Discard the buffer to avoid using an incomplete response. + if (req->secure) +#ifdef HTTPCS + espconn_secure_disconnect(conn); +#else + os_printf("SSL not available\r\n"); +#endif + else + espconn_disconnect(conn); + return; // The disconnect callback will be called. + } + + os_memcpy(new_buffer, req->buffer, req->buffer_size); + os_memcpy(new_buffer + req->buffer_size - 1 /*overwrite the null character*/, buf, len); // Append new data. + new_buffer[new_size - 1] = '\0'; // Make sure there is an end of string. + + os_free(req->buffer); + req->buffer = new_buffer; + req->buffer_size = new_size; +} + +static void ICACHE_FLASH_ATTR sent_callback(void * arg) +{ + struct espconn * conn = (struct espconn *)arg; + request_args * req = (request_args *)conn->reverse; + + if (req->post_data == NULL) { + PRINTF("All sent\n"); + } + else { + // The headers were sent, now send the contents. + PRINTF("Sending request body\n"); + if (req->secure) +#ifdef HTTPCS + espconn_secure_sent(conn, (uint8_t *)req->post_data, strlen(req->post_data)); +#else + os_printf("SSL not available\r\n"); +#endif + else + espconn_sent(conn, (uint8_t *)req->post_data, strlen(req->post_data)); + os_free(req->post_data); + req->post_data = NULL; + } +} + +static void ICACHE_FLASH_ATTR connect_callback(void * arg) +{ + PRINTF("Connected\n"); + struct espconn * conn = (struct espconn *)arg; + request_args * req = (request_args *)conn->reverse; + + espconn_regist_recvcb(conn, receive_callback); + espconn_regist_sentcb(conn, sent_callback); + + const char * method = "GET"; + char post_headers[32] = ""; + + if (req->post_data != NULL) { // If there is data this is a POST request. + method = "POST"; + os_sprintf(post_headers, "Content-Length: %d\r\n", strlen(req->post_data)); + } + + char buf[69 + strlen(method) + strlen(req->path) + strlen(req->hostname) + + strlen(req->headers) + strlen(post_headers)]; + int len = os_sprintf(buf, + "%s %s HTTP/1.1\r\n" + "Host: %s:%d\r\n" + "Connection: close\r\n" + "User-Agent: ESP8266\r\n" + "%s" + "%s" + "\r\n", + method, req->path, req->hostname, req->port, req->headers, post_headers); + + if (req->secure) +#ifdef HTTPCS + espconn_secure_sent(conn, (uint8_t *)buf, len); +#else + os_printf("SSL not available\r\n"); +#endif + else + espconn_sent(conn, (uint8_t *)buf, len); + os_free(req->headers); + req->headers = NULL; + PRINTF("Sending request header\n"); +} + +static void ICACHE_FLASH_ATTR disconnect_callback(void * arg) +{ + PRINTF("Disconnected\n"); + struct espconn *conn = (struct espconn *)arg; + + if(conn == NULL) { + return; + } + + if(conn->reverse != NULL) { + request_args * req = (request_args *)conn->reverse; + int http_status = -1; + int body_size = 0; + char * body = ""; + if (req->buffer == NULL) { + os_printf("Buffer shouldn't be NULL\n"); + } + else if (req->buffer[0] != '\0') { + // FIXME: make sure this is not a partial response, using the Content-Length header. + + const char * version10 = "HTTP/1.0 "; + const char * version11 = "HTTP/1.1 "; + if (os_strncmp(req->buffer, version10, strlen(version10)) != 0 + && os_strncmp(req->buffer, version11, strlen(version11)) != 0) { + os_printf("Invalid version in %s\n", req->buffer); + } + else { + http_status = atoi(req->buffer + strlen(version10)); + /* find body and zero terminate headers */ + body = (char *)os_strstr(req->buffer, "\r\n\r\n") + 2; + *body++ = '\0'; + *body++ = '\0'; + + body_size = req->buffer_size - (body - req->buffer); + + if(os_strstr(req->buffer, "Transfer-Encoding: chunked")) + { + body_size = chunked_decode(body, body_size); + body[body_size] = '\0'; + } + } + } + + if (req->user_callback != NULL) { // Callback is optional. + req->user_callback(body, http_status, req->buffer, body_size); + } + + os_free(req->buffer); + os_free(req->hostname); + os_free(req->path); + os_free(req); + } + espconn_delete(conn); + if(conn->proto.tcp != NULL) { + os_free(conn->proto.tcp); + } + os_free(conn); +} + +static void ICACHE_FLASH_ATTR error_callback(void *arg, sint8 errType) +{ + PRINTF("Disconnected with error\n"); + disconnect_callback(arg); +} + +static void ICACHE_FLASH_ATTR dns_callback(const char * hostname, ip_addr_t * addr, void * arg) +{ + request_args * req = (request_args *)arg; + + if (addr == NULL) { + os_printf("DNS failed for %s\n", hostname); + if (req->user_callback != NULL) { + req->user_callback("", -1, "", 0); + } + os_free(req->buffer); + os_free(req->post_data); + os_free(req->headers); + os_free(req->path); + os_free(req->hostname); + os_free(req); + } + else { + PRINTF("DNS found %s " IPSTR "\n", hostname, IP2STR(addr)); + + struct espconn * conn = (struct espconn *)os_malloc(sizeof(struct espconn)); + conn->type = ESPCONN_TCP; + conn->state = ESPCONN_NONE; + conn->proto.tcp = (esp_tcp *)os_malloc(sizeof(esp_tcp)); + conn->proto.tcp->local_port = espconn_port(); + conn->proto.tcp->remote_port = req->port; + conn->reverse = req; + + os_memcpy(conn->proto.tcp->remote_ip, addr, 4); + + espconn_regist_connectcb(conn, connect_callback); + espconn_regist_disconcb(conn, disconnect_callback); + espconn_regist_reconcb(conn, error_callback); + + if (req->secure) { +#ifdef HTTPCS + espconn_secure_set_size(ESPCONN_CLIENT,5120); // set SSL buffer size + espconn_secure_connect(conn); +#else + os_printf("SSL not available\r\n"); +#endif + } else { + espconn_connect(conn); + } + } +} + +void ICACHE_FLASH_ATTR http_raw_request(const char * hostname, int port, bool secure, const char * path, const char * post_data, const char * headers, http_callback user_callback) +{ + PRINTF("DNS request\n"); + + request_args * req = (request_args *)os_malloc(sizeof(request_args)); + req->hostname = esp_strdup(hostname); + req->path = esp_strdup(path); + req->port = port; + req->secure = secure; + req->headers = esp_strdup(headers); + req->post_data = esp_strdup(post_data); + req->buffer_size = 1; + req->buffer = (char *)os_malloc(1); + req->buffer[0] = '\0'; // Empty string. + req->user_callback = user_callback; + + ip_addr_t addr; + err_t error = espconn_gethostbyname((struct espconn *)req, // It seems we don't need a real espconn pointer here. + hostname, &addr, dns_callback); + + if (error == ESPCONN_INPROGRESS) { + PRINTF("DNS pending\n"); + } + else if (error == ESPCONN_OK) { + // Already in the local names table (or hostname was an IP address), execute the callback ourselves. + dns_callback(hostname, &addr, req); + } + else { + if (error == ESPCONN_ARG) { + os_printf("DNS arg error %s\n", hostname); + } + else { + os_printf("DNS error code %d\n", error); + } + dns_callback(hostname, NULL, req); // Handle all DNS errors the same way. + } +} + +/* + * Parse an URL of the form http://host:port/path + * can be a hostname or an IP address + * is optional + */ +void ICACHE_FLASH_ATTR http_post(const char * url, const char * post_data, const char * headers, http_callback user_callback) +{ + // FIXME: handle HTTP auth with http://user:pass@host/ + // FIXME: get rid of the #anchor part if present. + + char hostname[128] = ""; + int port = 80; + bool secure = false; + + bool is_http = os_strncmp(url, "http://", strlen("http://")) == 0; + bool is_https = os_strncmp(url, "https://", strlen("https://")) == 0; + + if (is_http) + url += strlen("http://"); // Get rid of the protocol. + else if (is_https) { + port = 443; + secure = true; + url += strlen("https://"); // Get rid of the protocol. + } else { + os_printf("URL is not HTTP or HTTPS %s\n", url); + return; + } + + char * path = os_strchr(url, '/'); + if (path == NULL) { + path = os_strchr(url, '\0'); // Pointer to end of string. + } + + char * colon = os_strchr(url, ':'); + if (colon > path) { + colon = NULL; // Limit the search to characters before the path. + } + + if (colon == NULL) { // The port is not present. + os_memcpy(hostname, url, path - url); + hostname[path - url] = '\0'; + } + else { + port = atoi(colon + 1); + if (port == 0) { + os_printf("Port error %s\n", url); + return; + } + + os_memcpy(hostname, url, colon - url); + hostname[colon - url] = '\0'; + } + + + if (path[0] == '\0') { // Empty path is not allowed. + path = "/"; + } + + PRINTF("hostname=%s\n", hostname); + PRINTF("port=%d\n", port); + PRINTF("path=%s\n", path); + http_raw_request(hostname, port, secure, path, post_data, headers, user_callback); +} + +void ICACHE_FLASH_ATTR http_get(const char * url, const char * headers, http_callback user_callback) +{ + http_post(url, NULL, headers, user_callback); +} + +void ICACHE_FLASH_ATTR http_callback_example(char * response_body, int http_status, char * response_headers, int body_size) +{ + os_printf("http_status=%d\n", http_status); + if (http_status != HTTP_STATUS_GENERIC_ERROR) { + os_printf("strlen(headers)=%d\n", strlen(response_headers)); + os_printf("body_size=%d\n", body_size); + os_printf("body=%s\n", response_body); // FIXME: this does not handle binary data. + } +} + diff --git a/httpclient/httpclient.h b/httpclient/httpclient.h new file mode 100644 index 0000000..89b8e6b --- /dev/null +++ b/httpclient/httpclient.h @@ -0,0 +1,53 @@ +/* + * ---------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * Martin d'Allens wrote this file. As long as you retain + * this notice you can do whatever you want with this stuff. If we meet some day, + * and you think this stuff is worth it, you can buy me a beer in return. + * ---------------------------------------------------------------------------- + */ + +#ifndef HTTPCLIENT_H +#define HTTPCLIENT_H + +//#include // This can remove some warnings depending on your project setup. It is safe to remove this line. + +#define HTTP_STATUS_GENERIC_ERROR -1 // In case of TCP or DNS error the callback is called with this status. +#define BUFFER_SIZE_MAX 5000 // Size of http responses that will cause an error. + +/* + * "full_response" is a string containing all response headers and the response body. + * "response_body and "http_status" are extracted from "full_response" for convenience. + * + * A successful request corresponds to an HTTP status code of 200 (OK). + * More info at http://en.wikipedia.org/wiki/List_of_HTTP_status_codes + */ +typedef void (* http_callback)(char * response_body, int http_status, char * response_headers, int body_size); + +/* + * Download a web page from its URL. + * Try: + * http_get("http://wtfismyip.com/text", http_callback_example); + */ +void ICACHE_FLASH_ATTR http_get(const char * url, const char * headers, http_callback user_callback); + +/* + * Post data to a web form. + * The data should be encoded as application/x-www-form-urlencoded. + * Try: + * http_post("http://httpbin.org/post", "first_word=hello&second_word=world", http_callback_example); + */ +void ICACHE_FLASH_ATTR http_post(const char * url, const char * post_data, const char * headers, http_callback user_callback); + +/* + * Call this function to skip URL parsing if the arguments are already in separate variables. + */ +void ICACHE_FLASH_ATTR http_raw_request(const char * hostname, int port, bool secure, const char * path, const char * post_data, const char * headers, http_callback user_callback); + +/* + * Output on the UART. + */ +void ICACHE_FLASH_ATTR http_callback_example(char * response_body, int http_status, char * response_headers, int body_size); + +#endif + diff --git a/scripts/script.http b/scripts/script.http new file mode 100644 index 0000000..8e55d43 --- /dev/null +++ b/scripts/script.http @@ -0,0 +1,16 @@ +% Config params, overwrite any previous settings from the commandline +% Nothing here + +% Now the events, checked whenever something happens + +on wificonnect +do + println "get http://wtfismyip.com/text" + http_get "http://wtfismyip.com/text" + +on http_response +do + println "return code: " | $this_http_code + println $this_http_body + + diff --git a/user/lang.c b/user/lang.c index e5b2dda..c5928f4 100644 --- a/user/lang.c +++ b/user/lang.c @@ -56,16 +56,24 @@ char **my_token; int max_token; bool script_enabled = false; bool in_topic_statement; -bool in_gpio_statement; Interpreter_Status interpreter_status; char *interpreter_topic; char *interpreter_data; int interpreter_data_len; int interpreter_timer; char *interpreter_timestamp; +int ts_counter; +#ifdef GPIO +bool in_gpio_statement; int interpreter_gpio; int interpreter_gpioval; -int ts_counter; +#endif +#ifdef HTTPC +bool in_http_statement; +int interpreter_http_status; + +void interpreter_http_reply(char *response_body, int http_status, char *response_headers, int body_size); +#endif static os_timer_t timers[MAX_TIMERS]; var_entry_t vars[MAX_VARS]; @@ -164,7 +172,7 @@ void ICACHE_FLASH_ATTR inttimer_func(void *arg){ } // Interrupt handler - this function will be executed on any edge of a GPIO -LOCAL void gpio_intr_handler(void *arg) +LOCAL void gpio_intr_handler(void *arg) { gpio_entry_t *my_gpio_entry = (gpio_entry_t *)arg; @@ -442,7 +450,13 @@ int ICACHE_FLASH_ATTR parse_statement(int next_token) { while ((next_token = syn_chk ? next_token : search_token(next_token, "on")) < max_token) { - in_topic_statement = in_gpio_statement = false; + in_topic_statement = false; +#ifdef GPIO + in_gpio_statement = false; +#endif +#ifdef HTTPC + in_http_statement = false; +#endif if (is_token(next_token, "on")) { lang_debug("statement on\r\n"); @@ -489,7 +503,16 @@ int ICACHE_FLASH_ATTR parse_event(int next_token, bool * happend) { *happend = (interpreter_status == MQTT_CLIENT_CONNECT); if (*happend) - lang_log("on init\r\n"); + lang_log("on mqttconnect\r\n"); + return next_token + 1; + } + + if (is_token(next_token, "wificonnect")) { + lang_debug("event wificonnect\r\n"); + + *happend = (interpreter_status == WIFI_CONNECT); + if (*happend) + lang_log("on wificonnect\r\n"); return next_token + 1; } @@ -587,8 +610,18 @@ int ICACHE_FLASH_ATTR parse_event(int next_token, bool * happend) { lang_log("on clock %s\r\n", my_token[next_token + 1]); return next_token + 2; } +#ifdef HTTPC + if (is_token(next_token, "http_response")) { + lang_debug("event http_response\r\n"); + in_http_statement = true; - return syntax_error(next_token, "'init', 'mqttconnect', 'topic', 'gpio_interrupt', 'clock', or 'timer' expected"); + *happend = (interpreter_status == HTTP_RESPONSE); + if (*happend) + lang_log("on http_response\r\n"); + return next_token + 1; + } +#endif + return syntax_error(next_token, "'init', 'mqttconnect', 'topic', 'gpio_interrupt', 'clock', 'http_response', or 'timer' expected"); } int ICACHE_FLASH_ATTR parse_action(int next_token, bool doit) { @@ -879,6 +912,21 @@ int ICACHE_FLASH_ATTR parse_action(int next_token, bool doit) { } } } +#ifdef HTTPC + else if (is_token(next_token, "http_get")) { + len_check(2); + + char *url_data; + int url_len; + Value_Type url_type; + if ((next_token = parse_expression(next_token + 1, &url_data, &url_len, &url_type, doit)) == -1) + return -1; + + if (doit) { + http_get(url_data, "", interpreter_http_reply); + } + } +#endif #ifdef GPIO else if (is_token(next_token, "gpio_pinmode")) { len_check(2); @@ -1182,6 +1230,32 @@ int ICACHE_FLASH_ATTR parse_value(int next_token, char **data, int *data_len, Va return next_token + 1; } #endif +#ifdef HTTPC + else if (is_token(next_token, "$this_http_body")) { + lang_debug("val $this_http_body\r\n"); + + if (!in_http_statement) + return syntax_error(next_token, "undefined $this_http_body"); + *data = interpreter_data; + *data_len = interpreter_data_len; + *data_type = STRING_T; + return next_token + 1; + } + + else if (is_token(next_token, "$this_http_code")) { + static char codebuf[4]; + lang_debug("val $this_http_code\r\n"); + + if (!in_http_statement) + return syntax_error(next_token, "undefined $this_http_code"); + + os_sprintf(codebuf, "%3d", interpreter_http_status); + *data = codebuf; + *data_len = os_strlen(codebuf); + *data_type = STRING_T; + return next_token + 1; + } +#endif #ifdef NTP else if (is_token(next_token, "$timestamp")) { lang_debug("val $timestamp\r\n"); @@ -1330,11 +1404,23 @@ int ICACHE_FLASH_ATTR interpreter_init() { return ret_val; } -int ICACHE_FLASH_ATTR interpreter_reconnect(void) { +int ICACHE_FLASH_ATTR interpreter_wifi_connect(void) { if (!script_enabled) return -1; - lang_debug("interpreter_init_reconnect\r\n"); + lang_debug("interpreter_wifi_connect\r\n"); + + interpreter_status = WIFI_CONNECT; + interpreter_topic = interpreter_data = ""; + interpreter_data_len = 0; + return parse_statement(0); +} + +int ICACHE_FLASH_ATTR interpreter_mqtt_connect(void) { + if (!script_enabled) + return -1; + + lang_debug("interpreter_mqtt_connect\r\n"); interpreter_status = MQTT_CLIENT_CONNECT; interpreter_topic = interpreter_data = ""; @@ -1360,3 +1446,20 @@ int ICACHE_FLASH_ATTR interpreter_topic_received(const char *topic, const char * return parse_statement(0); } +#ifdef HTTPC +void ICACHE_FLASH_ATTR interpreter_http_reply(char *response_body, int http_status, char *response_headers, int body_size) { + if (!script_enabled) + return; + + lang_debug("interpreter_http_reply\r\n"); + + interpreter_status = HTTP_RESPONSE; + interpreter_topic = response_headers; + interpreter_http_status = http_status; + interpreter_data = response_body; + interpreter_data_len = body_size; + + parse_statement(0); +} +#endif + diff --git a/user/lang.h b/user/lang.h index b0d2b18..3523f49 100644 --- a/user/lang.h +++ b/user/lang.h @@ -4,7 +4,7 @@ #include "mqtt_server.h" -typedef enum {SYNTAX_CHECK, CONFIG, INIT, MQTT_CLIENT_CONNECT, TOPIC_LOCAL, TOPIC_REMOTE, TIMER, GPIO_INT, CLOCK} Interpreter_Status; +typedef enum {SYNTAX_CHECK, CONFIG, INIT, MQTT_CLIENT_CONNECT, WIFI_CONNECT, TOPIC_LOCAL, TOPIC_REMOTE, TIMER, GPIO_INT, CLOCK, HTTP_RESPONSE} Interpreter_Status; typedef enum {STRING_T, DATA_T} Value_Type; typedef struct _var_entry_t { @@ -40,7 +40,8 @@ extern bool script_enabled; int interpreter_syntax_check(); int interpreter_config(); int interpreter_init(); -int interpreter_reconnect(void); +int interpreter_mqtt_connect(void); +int interpreter_wifi_connect(void); int interpreter_topic_received(const char *topic, const char *data, int data_len, bool local); void init_timestamps(uint8_t *curr_time); diff --git a/user/user_config.h b/user/user_config.h index ed83e22..237b34a 100644 --- a/user/user_config.h +++ b/user/user_config.h @@ -13,10 +13,11 @@ // Here the MQTT stuff // +// // Define this if you want to have it work as a MQTT client -#define MQTT_CLIENT 1 - -// Define this if you need SSL for the *MQTT client* +// Define MQTT_SSL_ENABLE if you need SSL for the *MQTT client* +// +#define MQTT_CLIENT 1 //#define MQTT_SSL_ENABLE 1 #define MQTT_BUF_SIZE 1024 @@ -59,6 +60,13 @@ // #define NTP 1 +// +// Define this if you want to have HTTP client support. +// Define HTTPCS if you want to have additional HTTPS support. +// +#define HTTPC 1 +//#define HTTPCS 1 + // // Define this if you want to have mDNS support in scripts. // diff --git a/user/user_main.c b/user/user_main.c index d2f098a..10c5038 100644 --- a/user/user_main.c +++ b/user/user_main.c @@ -106,7 +106,7 @@ static void ICACHE_FLASH_ATTR mqttConnectedCb(uint32_t * args) { MQTT_Client *client = (MQTT_Client *) args; mqtt_connected = true; #ifdef SCRIPTED - interpreter_reconnect(); + interpreter_mqtt_connect(); #endif os_printf("MQTT client connected\r\n"); } @@ -1260,7 +1260,7 @@ static void ICACHE_FLASH_ATTR user_procTask(os_event_t * events) { switch (events->sig) { case SIG_START_SERVER: - // Anything else to do here, when the repeater has received its IP? + // Anything else to do here, when the broker has received its IP? break; #ifdef SCRIPTED case SIG_TOPIC_RECEIVED: @@ -1366,6 +1366,10 @@ void wifi_handle_event_cb(System_Event_t * evt) { my_ip = evt->event_info.got_ip.ip; connected = true; +#ifdef SCRIPTED + interpreter_wifi_connect(); +#endif + #ifdef MQTT_CLIENT if (mqtt_enabled) MQTT_Connect(&mqttClient);